diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 29f81d812f3e768fa89638d1f72920dbfd1413a8..0000000000000000000000000000000000000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/README.md b/README.md index 5dd4e70697f662a259fe8a37baed722741ffe4c7..96f6aa151dd484d9c84cd4b53d74e2ba5cc57904 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,148 @@ spring.datasource.password= ``` +模块依赖关系 +admin--->framework--->system | generator | batch--->common
-模块依赖关系 +# 注意事项 +1. 任何方法不要传入null, 不要返回null。 +2. 无法保证不传入null时,方法做判空处理。 +3. 前端传过来的参数可以在DTO上做注解校验,或者设置默认值 +4. service层仅调用自己的mapper,避免调用其他类的mapper,可调用其他类的service。 + +# 已完成功能 V1.0.0 + +## 系统管理 + +### 登录与Session管理 + +- [x] 登录后用户的session中包括用户基本信息和用户角色。 +- [x] 角色—权限、 角色—菜单 统一进行缓存。 权限、菜单发生变动后,清除相关角色的缓存即可 + +### 菜单管理 +- [x] 新增、修改、删除菜单后,清除角色—菜单缓存 +- [ ] 超级管理员获取全部菜单不加缓存 + +### 部门管理 + +- [x] 部门列表查询 +- [x] 添加部门 +- [x] 编辑部门(ancestors、isLock) +- [x] 删除部门 (禁止删除带子部门和带员工的部门) + +### 角色管理 +- [x] 分页查询列表 +- [x] 添加和编辑角色弹窗增加:角色排序、角色禁用 +- [x] 修改把禁用按钮去掉 +- [x] 修改角色基本信息、禁止修改超级管理员 +- [x] 修改角色权限 +- [ ] 修改角色数据权限 +- [x] 删除角色 + +### 用户管理 +- [x] 查询部门树 +- [x] 查询部门数附带每个部门的人数 +- [x] 分页查询用户列表, 除了基本用户信息还包括用户的角色、部门信息 +- [x] 根据部门树查询用户 +- [x] 添加用户 +- [x] 添加用户、用户操作前端页面修改 +- [x] 检查前端按钮权限标识 +- [x] 修改用户 + - [ ] 输入身份证、手机号校验、邮箱、【工号、用户名】规则校验 +- [x] 删除用户 + - [x] 测试联动删除用户所有绑定角色信息 +- [x] 设置用户角色 +- [x] 批量设置角色部门 +- [x] 批量设置角色岗位 +- [x] 编辑用户功能加入岗位和部门编辑 +- [x] 用户信息把岗位信息也联表查询出来 +- [ ] 点击用户名显示用户详情 +- [x] 重置用户密码 +- [x] 用户名需保证唯一、nickname不需要唯一 +- [x] 按用户名/工号/身份证查询时加入limit 1 防止错误数据引发系统故障 +- [ ] 多次输错密码锁定用户几分钟 / 手动解锁用户 +- [ ] 头像上传 + + + +### 字典管理 +若依拉取字典数据是这个页面需要什么就拉取什么,没刷新的话拉取一次就不拉了 +这个geekAdmin是一次性拉取所有字典数据,进入具体页面时不再拉取,刷新就又重新拉取所有字典数据。 +如果字典数据变得特别多,可以优化成若依的方式,不过一般字典数据不是很多,都无所谓,字典数据也可以放入缓存。一次性拉取后,系统更流畅,代码更简洁? + +- [x] 字典类型加一个业务类型字段、 分为系统字典和业务字典 +- [x] 字典类型列表 + - [x] 字典类型对应字段列表 + - [x] 字典添加 + - [x] 字典修改 + - [x] 字典删除 + - [x] 字典锁定 +- [x] 新增字典类型 +- [x] 删除字典类型(逻辑删除,不同步删字典内容) +- [x] 锁定字典类型 +- [x] 字典类型对应的字典列表 + + +### 参数管理 + + + +### 文件管理 + +- [ ] 文件上传、下载 + + +### 岗位管理 +- [x] 自动代码生成,增删改查 + +## 日志管理 + +### 操作日志 + + + +### 登录日志 + + + +## 系统工具 + +### 代码生成 +- [x] 导入表列表查询 +- [ ] 导入表 + - [x] 导入表信息 + - [ ] 导入表的列信息 +- [x] 已导入的表列表查询 + - [x] 编辑 + - [x] 删除 + - [x] 预览 + - [x] 代码生成预览 + - [x] 加入前端代码和SQL的预览 + - [x] 代码生成模板修改 + - [x] 生成代码 + + +- [x] 生成代码配置加一个swagger选项 +- [x] 加一个同步功能,而不是必须重新删除 +- [x] 覆盖生成 +- [ ] 自动插入菜单和按钮,插入菜单和按钮之后,记得更新菜单和按钮的缓存,不然用户感知不到 + + +### 表单构建 + + + + + +## 定时任务 + + + + + + + +## 前台官网 -admin--->framework--->system--->common - --->generator------------->common diff --git a/admin/pom.xml b/admin/pom.xml index c8ac23c825d73d7c8bce538592ef551ea2bcee58..8b9e50a2a4493cf20d7590437cb66cbe37ef9df6 100644 --- a/admin/pom.xml +++ b/admin/pom.xml @@ -45,11 +45,7 @@ framework - - - cn.lycode - generator - + \ No newline at end of file diff --git a/admin/src/test/java/cn/lycode/system/SysUserPostServiceTest.java b/admin/src/test/java/cn/lycode/system/SysUserPostServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2c91814e7bb666d326a7f2b15ec58ad2afc83efb --- /dev/null +++ b/admin/src/test/java/cn/lycode/system/SysUserPostServiceTest.java @@ -0,0 +1,35 @@ +package cn.lycode.system; + +import cn.lycode.system.service.SysUserPostService; +import org.junit.Ignore; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Title: SysUserPostServiceTest + * @Author lyg + * @Date 2024/11/29 17:10 + * @description: + */ +@SpringBootTest +public class SysUserPostServiceTest { + + @Autowired + SysUserPostService sysUserPostService; + + @Test + @Ignore + public void batchAddUserPost(){ + List userIdList = new ArrayList<>(); + userIdList.add(1L); + userIdList.add(14L); + List postIdList = new ArrayList<>(); + postIdList.add(1L); + postIdList.add(2L); + sysUserPostService.batchAddUserPost(userIdList, postIdList); + } +} diff --git a/batch/pom.xml b/batch/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..67a3f1c70592ffa7a87d378fbf0365b68ac3b14e --- /dev/null +++ b/batch/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + cn.lycode + lycode-base + 1.0.0 + + + batch + + + 8 + 8 + UTF-8 + + + + + + org.springframework.boot + spring-boot-starter-batch + + + + cn.lycode + common + + + + + \ No newline at end of file diff --git a/batch/src/main/java/cn/lycode/batch/bean/ExcelData.java b/batch/src/main/java/cn/lycode/batch/bean/ExcelData.java new file mode 100644 index 0000000000000000000000000000000000000000..7ae0a46edb2a2c00e1faa1aeacfa1df9feb471e2 --- /dev/null +++ b/batch/src/main/java/cn/lycode/batch/bean/ExcelData.java @@ -0,0 +1,16 @@ +package cn.lycode.batch.bean; + +import lombok.Data; + +/** + * @Title: ExcelData + * @Author lyg + * @Date 2024/12/11 10:50 + * @description: + */ + +@Data +public class ExcelData { + private String name; + private String remark; +} diff --git a/batch/src/main/java/cn/lycode/batch/bean/TestData.java b/batch/src/main/java/cn/lycode/batch/bean/TestData.java new file mode 100644 index 0000000000000000000000000000000000000000..f6563ac634dda8a65a8866f147681d165273e0fd --- /dev/null +++ b/batch/src/main/java/cn/lycode/batch/bean/TestData.java @@ -0,0 +1,15 @@ +package cn.lycode.batch.bean; + + +import lombok.Data; + +@Data +public class TestData { + + private Long id; + private String name; + private String process; + private String remark; + + +} diff --git a/batch/src/main/java/cn/lycode/batch/config/MyBatchConfig.java b/batch/src/main/java/cn/lycode/batch/config/MyBatchConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..c8e86017875379ee84bd34713bb998cc62934560 --- /dev/null +++ b/batch/src/main/java/cn/lycode/batch/config/MyBatchConfig.java @@ -0,0 +1,211 @@ +package cn.lycode.batch.config; + + +import cn.lycode.batch.bean.TestData; +import cn.lycode.batch.listener.MyJobListener; +import cn.lycode.batch.listener.MyReadListener; +import cn.lycode.batch.listener.MyWriteListener; +import cn.lycode.batch.processor.MyItemProcessor; +import cn.lycode.batch.validator.MyBeanValidator; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.Step; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.support.RunIdIncrementer; +import org.springframework.batch.core.launch.support.SimpleJobLauncher; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.ItemWriter; +import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider; +import org.springframework.batch.item.database.JdbcBatchItemWriter; +import org.springframework.batch.item.file.FlatFileItemReader; +import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; +import org.springframework.batch.item.file.mapping.DefaultLineMapper; +import org.springframework.batch.item.file.transform.DelimitedLineTokenizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; + +@Configuration +@EnableBatchProcessing +public class MyBatchConfig { + + + /** + * JobRepository定义:Job的注册容器以及和数据库打交道(事务管理等) + * @param dataSource + * @param transactionManager + * @return + * @throws Exception + */ + @Bean + public JobRepository myJobRepository(DataSource dataSource, PlatformTransactionManager transactionManager) throws Exception{ + JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean(); + jobRepositoryFactoryBean.setDatabaseType("mysql"); + jobRepositoryFactoryBean.setTransactionManager(transactionManager); + jobRepositoryFactoryBean.setDataSource(dataSource); + return jobRepositoryFactoryBean.getObject(); + } + + + /** + * jobLauncher定义:job的启动器,绑定相关的jobRepository + * @param dataSource + * @param transactionManager + * @return + * @throws Exception + */ + @Bean + public SimpleJobLauncher myJobLauncher(DataSource dataSource, PlatformTransactionManager transactionManager) throws Exception{ + SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); + // 设置jobRepository + jobLauncher.setJobRepository(myJobRepository(dataSource, transactionManager)); + return jobLauncher; + } + + + /** + * 定义job + * @param jobs + * @param myStep + * @return + */ + @Bean + public Job myJob(JobBuilderFactory jobs, Step myStep){ + return jobs.get("myJob") + .incrementer(new RunIdIncrementer()) + .flow(myStep) + .end() + .listener(myJobListener()) + .build(); + } + + + + /** + * 注册job监听器 + * @return + */ + @Bean + public MyJobListener myJobListener(){ + return new MyJobListener(); + } + + + /** + * ItemReader定义:读取文件数据+entirty实体类映射 + * @return + */ + @Bean + public ItemReader reader(){ + // 使用FlatFileItemReader去读cvs文件,一行即一条数据 + FlatFileItemReader reader = new FlatFileItemReader<>(); + // 设置文件处在路径 + reader.setResource(new ClassPathResource("static/testData.csv")); + // entity与csv数据做映射 + reader.setLineMapper(new DefaultLineMapper() { + { + setLineTokenizer(new DelimitedLineTokenizer() { + { + setNames(new String[]{"name","process","remark"}); + } + }); + setFieldSetMapper(new BeanWrapperFieldSetMapper() { + { + setTargetType(TestData.class); + } + }); + } + }); + return reader; + } + + + + + + /** + * 注册ItemProcessor: 处理数据+校验数据 + * @return + */ + @Bean + public ItemProcessor processor(){ + MyItemProcessor myItemProcessor = new MyItemProcessor(); + // 设置校验器 + myItemProcessor.setValidator(myBeanValidator()); + return myItemProcessor; + } + + + /** + * 注册校验器 + * @return + */ + @Bean + public MyBeanValidator myBeanValidator(){ + return new MyBeanValidator(); + } + + + + /** + * ItemWriter定义:指定datasource,设置批量插入sql语句,写入数据库 + * @param dataSource + * @return + */ + @Bean + public ItemWriter writer(DataSource dataSource){ + // 使用jdbcBcatchItemWrite写数据到数据库中 + JdbcBatchItemWriter writer = new JdbcBatchItemWriter<>(); + // 设置有参数的sql语句 + writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider()); + String sql = "insert into batch_test_data "+" (name,process,remark) " + +" values(:name,:process,:remark)"; + writer.setSql(sql); + writer.setDataSource(dataSource); + return writer; + } + + + + /** + * step定义: + * 包括 + * ItemReader 读取 + * ItemProcessor 处理 + * ItemWriter 输出 + * @param stepBuilderFactory + * @param reader + * @param writer + * @param processor + * @return + */ + + @Bean + public Step myStep(StepBuilderFactory stepBuilderFactory, ItemReader reader, + ItemWriter writer, ItemProcessor processor){ + return stepBuilderFactory + .get("myStep") + .chunk(65000) // Chunk的机制(即每次读取一条数据,再处理一条数据,累积到一定数量后再一次性交给writer进行写入操作) + .reader(reader).faultTolerant().retryLimit(3).retry(Exception.class).skip(Exception.class).skipLimit(2) + .listener(new MyReadListener()) + .processor(processor) + .writer(writer).faultTolerant().skip(Exception.class).skipLimit(2) + .listener(new MyWriteListener()) + .build(); + } + + + + + + + + +} diff --git a/batch/src/main/java/cn/lycode/batch/controller/TestController.java b/batch/src/main/java/cn/lycode/batch/controller/TestController.java new file mode 100644 index 0000000000000000000000000000000000000000..0eb8df33c566360fcf6814c231d2f4d9c5a33c03 --- /dev/null +++ b/batch/src/main/java/cn/lycode/batch/controller/TestController.java @@ -0,0 +1,29 @@ +package cn.lycode.batch.controller; + +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.JobParametersInvalidException; +import org.springframework.batch.core.launch.support.SimpleJobLauncher; +import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; +import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException; +import org.springframework.batch.core.repository.JobRestartException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class TestController { + @Autowired + SimpleJobLauncher jobLauncher; + + @Autowired + Job myJob; + + @GetMapping("testJob") + public void testJob() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException { + // 后置参数:使用JobParameters中绑定参数 addLong addString 等方法 + JobParameters jobParameters = new JobParametersBuilder().toJobParameters(); + jobLauncher.run(myJob, jobParameters); + } +} diff --git a/batch/src/main/java/cn/lycode/batch/listener/MyJobListener.java b/batch/src/main/java/cn/lycode/batch/listener/MyJobListener.java new file mode 100644 index 0000000000000000000000000000000000000000..ae4c7ad742fb5b9b595cade0955e0d44944aaf53 --- /dev/null +++ b/batch/src/main/java/cn/lycode/batch/listener/MyJobListener.java @@ -0,0 +1,25 @@ +package cn.lycode.batch.listener; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobExecutionListener; + +/** + * @Author : JCccc + * @Description :监听Job执行情况,实现JobExecutorListener,且在batch配置类里,Job的Bean上绑定该监听器 + **/ + +@Slf4j +public class MyJobListener implements JobExecutionListener { + + + @Override + public void beforeJob(JobExecution jobExecution) { + log.info("job 开始, id={}",jobExecution.getJobId()); + } + + @Override + public void afterJob(JobExecution jobExecution) { + log.info("job 结束, id={}",jobExecution.getJobId()); + } +} diff --git a/batch/src/main/java/cn/lycode/batch/listener/MyReadListener.java b/batch/src/main/java/cn/lycode/batch/listener/MyReadListener.java new file mode 100644 index 0000000000000000000000000000000000000000..9a97e67e0e98e9aa16727e2bd94d888fb65cdfa5 --- /dev/null +++ b/batch/src/main/java/cn/lycode/batch/listener/MyReadListener.java @@ -0,0 +1,29 @@ +package cn.lycode.batch.listener; + +import cn.lycode.batch.bean.TestData; +import lombok.extern.slf4j.Slf4j; +import org.springframework.batch.core.ItemReadListener; + +import static java.lang.String.format; + +@Slf4j +public class MyReadListener implements ItemReadListener { + + + @Override + public void beforeRead() { + } + + @Override + public void afterRead(TestData item) { + } + + @Override + public void onReadError(Exception ex) { + try { + log.info(format("%s%n", ex.getMessage())); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/batch/src/main/java/cn/lycode/batch/listener/MyWriteListener.java b/batch/src/main/java/cn/lycode/batch/listener/MyWriteListener.java new file mode 100644 index 0000000000000000000000000000000000000000..4a6e25dd51da8c575c414164ed4319cc711b0074 --- /dev/null +++ b/batch/src/main/java/cn/lycode/batch/listener/MyWriteListener.java @@ -0,0 +1,33 @@ +package cn.lycode.batch.listener; + +import cn.lycode.batch.bean.TestData; +import lombok.extern.slf4j.Slf4j; +import org.springframework.batch.core.ItemWriteListener; +import java.util.List; +import static java.lang.String.format; + +@Slf4j +public class MyWriteListener implements ItemWriteListener { + + @Override + public void beforeWrite(List items) { + } + + @Override + public void afterWrite(List items) { + } + + @Override + public void onWriteError(Exception exception, List items) { + try { + log.info(format("%s%n", exception.getMessage())); + for (TestData message : items) { + log.info(format("Failed writing BlogInfo : %s", message.toString())); + } + + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/batch/src/main/java/cn/lycode/batch/processor/MyItemProcessor.java b/batch/src/main/java/cn/lycode/batch/processor/MyItemProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..935aabac8907e39045acad2587f8e0cc25a3be30 --- /dev/null +++ b/batch/src/main/java/cn/lycode/batch/processor/MyItemProcessor.java @@ -0,0 +1,25 @@ +package cn.lycode.batch.processor; + +import cn.lycode.batch.bean.TestData; +import org.springframework.batch.item.validator.ValidatingItemProcessor; +import org.springframework.batch.item.validator.ValidationException; + + +public class MyItemProcessor extends ValidatingItemProcessor { + @Override + public TestData process(TestData item) throws ValidationException { + /** + * 需要执行super.process(item)才会调用自定义校验器 + */ + super.process(item); + /** + * 对数据进行简单的处理 + */ + if (item.getName().equals("testBatch1")) { + item.setProcess("testBatch1 处理一下!!!"); + } else { + item.setProcess("未知系列"); + } + return item; + } +} diff --git a/batch/src/main/java/cn/lycode/batch/validator/MyBeanValidator.java b/batch/src/main/java/cn/lycode/batch/validator/MyBeanValidator.java new file mode 100644 index 0000000000000000000000000000000000000000..b9f61009d86ba046202c205bddc04e32ffae6a67 --- /dev/null +++ b/batch/src/main/java/cn/lycode/batch/validator/MyBeanValidator.java @@ -0,0 +1,43 @@ +package cn.lycode.batch.validator; + +import org.springframework.batch.item.validator.ValidationException; +import org.springframework.batch.item.validator.Validator; +import org.springframework.beans.factory.InitializingBean; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.ValidatorFactory; +import java.util.Set; + + +public class MyBeanValidator implements Validator, InitializingBean { + + private javax.validation.Validator validator; + + @Override + public void validate(T value) throws ValidationException { + /** + * 使用Validator的validate方法校验数据 + */ + Set> constraintViolations = + validator.validate(value); + if (constraintViolations.size() > 0) { + StringBuilder message = new StringBuilder(); + for (ConstraintViolation constraintViolation : constraintViolations) { + message.append(constraintViolation.getMessage() + "\n"); + } + throw new ValidationException(message.toString()); + } + } + + /** + * 使用JSR-303的Validator来校验我们的数据,在此进行JSR-303的Validator的初始化 + * @throws Exception + */ + @Override + public void afterPropertiesSet() throws Exception { + ValidatorFactory validatorFactory = + Validation.buildDefaultValidatorFactory(); + validator = validatorFactory.usingContext().getValidator(); + } + +} diff --git a/batch/src/main/resources/application-batch.yml b/batch/src/main/resources/application-batch.yml new file mode 100644 index 0000000000000000000000000000000000000000..1da53a13c8a420f8e2764347703c4a1f2a473d60 --- /dev/null +++ b/batch/src/main/resources/application-batch.yml @@ -0,0 +1,8 @@ +spring: + batch: + job: + #设置为 false -需要jobLaucher.run执行 + enabled: false + jdbc: + initialize-schema: always +# table-prefix: my-batch \ No newline at end of file diff --git a/batch/src/main/resources/static/testData.csv b/batch/src/main/resources/static/testData.csv new file mode 100644 index 0000000000000000000000000000000000000000..d4080ca956f3ae959aa3a1afb0d446c6628853b7 --- /dev/null +++ b/batch/src/main/resources/static/testData.csv @@ -0,0 +1,3 @@ +lyg,,ces +lyg,cdd,ces +testBatch1,ff,d \ No newline at end of file diff --git a/common/src/main/java/cn/lycode/common/enums/ErrorEnum.java b/common/src/main/java/cn/lycode/common/enums/ErrorEnum.java index ce679617ba65b91ff7171b402bc31884e3df6f2a..403d0497a3fcef92a9fc287537494e9cceb88e1f 100644 --- a/common/src/main/java/cn/lycode/common/enums/ErrorEnum.java +++ b/common/src/main/java/cn/lycode/common/enums/ErrorEnum.java @@ -50,6 +50,7 @@ public enum ErrorEnum implements ServiceExceptionCustomAssert { EXIST_DICT("900346", "禁止插入重复字典!"), PARAM_ERROR("900341", "参数错误!"), FORBID_OPERATION("900342", "禁止操作!"), + EXIST_USERNAME("900344", "此用户名已存在!"), SYSTEM_ERROR("900500", "系统错误"); diff --git a/common/src/main/java/cn/lycode/common/event/PermsChangeEvent.java b/common/src/main/java/cn/lycode/common/event/PermsChangeEvent.java deleted file mode 100644 index 7a64a7a50f8829ef212d135bc4aa8db23b839712..0000000000000000000000000000000000000000 --- a/common/src/main/java/cn/lycode/common/event/PermsChangeEvent.java +++ /dev/null @@ -1,11 +0,0 @@ -package cn.lycode.common.event; - -/** - * 权限变更事件(用户角色变更、角色权限变更) - * 由带@EventListener 注解的方法监听此事件 - */ -public class PermsChangeEvent extends BaseEvent { - public PermsChangeEvent(Object source, PermsMeta payload) { - super(source, payload); - } -} diff --git a/common/src/main/java/cn/lycode/common/event/PermsMeta.java b/common/src/main/java/cn/lycode/common/event/PermsMeta.java deleted file mode 100644 index 42412bcf602603a21c5d0959948d8e328fa121ae..0000000000000000000000000000000000000000 --- a/common/src/main/java/cn/lycode/common/event/PermsMeta.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.lycode.common.event; - -import lombok.Data; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@Data -public class PermsMeta { - - public PermsMeta() { - roleFlags = new ArrayList<>(); - } - - public PermsMeta(List roleFlags) { - this.roleFlags = roleFlags; - } - - public PermsMeta(Object roleFlag) { - if (roleFlag != null) { - this.roleFlags = Collections.singletonList(roleFlag); - } - } - - - private List roleFlags; - -} diff --git a/common/src/main/java/cn/lycode/common/event/SessionChangeEvent.java b/common/src/main/java/cn/lycode/common/event/SessionChangeEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..0684adba754537498e2c9eb8eb5de0fe9c592bda --- /dev/null +++ b/common/src/main/java/cn/lycode/common/event/SessionChangeEvent.java @@ -0,0 +1,8 @@ +package cn.lycode.common.event; + +public class SessionChangeEvent extends BaseEvent { + + public SessionChangeEvent(Object source, SessionChangeMeta payload) { + super(source, payload); + } +} diff --git a/common/src/main/java/cn/lycode/common/event/SessionChangeMeta.java b/common/src/main/java/cn/lycode/common/event/SessionChangeMeta.java new file mode 100644 index 0000000000000000000000000000000000000000..2030aa9efb732805596f1330e887f6e0d73ed7dc --- /dev/null +++ b/common/src/main/java/cn/lycode/common/event/SessionChangeMeta.java @@ -0,0 +1,53 @@ +package cn.lycode.common.event; + +import cn.lycode.common.core.domain.AjaxResult; +import cn.lycode.common.enums.ErrorEnum; +import lombok.Data; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Data +public class SessionChangeMeta { + + private List roleFlagList; //变动的角色 + private List userIdList; //变动的用户 + + + public static SessionChangeMeta roleList(List roleFlags) { + ErrorEnum.PARAM_NULL.assertNotNull(roleFlags); + SessionChangeMeta sessionChangeMeta = new SessionChangeMeta(); + sessionChangeMeta.setRoleFlagList(roleFlags); + return sessionChangeMeta; + } + + public static SessionChangeMeta role(Object roleFlag) { + SessionChangeMeta sessionChangeMeta = new SessionChangeMeta(); + if (roleFlag != null) { + sessionChangeMeta.setRoleFlagList(Collections.singletonList(roleFlag)); + } + return sessionChangeMeta; + } + + + public static SessionChangeMeta userList(List userFlags) { + ErrorEnum.PARAM_NULL.assertNotNull(userFlags); + SessionChangeMeta sessionChangeMeta = new SessionChangeMeta(); + sessionChangeMeta.setUserIdList(userFlags); + return sessionChangeMeta; + } + + public static SessionChangeMeta user(Object userFlag) { + SessionChangeMeta sessionChangeMeta = new SessionChangeMeta(); + if (userFlag != null) { + sessionChangeMeta.setUserIdList(Collections.singletonList(userFlag)); + } + return sessionChangeMeta; + } + + private SessionChangeMeta(){ + roleFlagList = new ArrayList<>(); + userIdList = new ArrayList<>(); + } +} diff --git a/framework/pom.xml b/framework/pom.xml index 28cf4ca7b38114f23fd2b5d9dce37536933b8e1d..6e22fb9e999e2140b088fd3a4697f5ed40b29fbb 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -58,7 +58,18 @@ cn.lycode system - 1.0.0 + + + + + cn.lycode + generator + + + + + cn.lycode + batch diff --git a/framework/src/main/java/cn/lycode/framework/constant/FrameworkConstant.java b/framework/src/main/java/cn/lycode/framework/constant/FrameworkConstant.java new file mode 100644 index 0000000000000000000000000000000000000000..31d8a3460d16d40b292637e32c18e32c25dd20c5 --- /dev/null +++ b/framework/src/main/java/cn/lycode/framework/constant/FrameworkConstant.java @@ -0,0 +1,18 @@ +package cn.lycode.framework.constant; + +/** + * @Title: FrameworkConstant + * @Author lyg + * @Date 2024/11/29 16:07 + * @description: + */ +public class FrameworkConstant { + + /** + * session key + */ + public static String SESSION_KEY_PERMS_LIST = "Perms_List"; + public static String SESSION_KEY_MENU_LIST = "Menu_List"; + public static String SESSION_KEY_ROLE_LIST = "Role_List"; + public static String SESSION_KEY_ROLE_PREFIX = "Role_"; +} diff --git a/framework/src/main/java/cn/lycode/framework/event/GlobalEventListener.java b/framework/src/main/java/cn/lycode/framework/event/GlobalEventListener.java index 0ad7d21f72ae7e6f9caab7a181fbb809c908a295..a48b95663d667d73fe2031d98aa323a499972307 100644 --- a/framework/src/main/java/cn/lycode/framework/event/GlobalEventListener.java +++ b/framework/src/main/java/cn/lycode/framework/event/GlobalEventListener.java @@ -2,10 +2,10 @@ package cn.lycode.framework.event; import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.session.SaSessionCustomUtil; -import cn.lycode.common.event.PermsChangeEvent; -import cn.lycode.common.event.PermsMeta; -import cn.lycode.common.utils.SecurityUtils; -import cn.lycode.framework.web.service.SysLoginService; +import cn.dev33.satoken.stp.StpUtil; +import cn.lycode.common.event.SessionChangeMeta; +import cn.lycode.common.event.SessionChangeEvent; +import cn.lycode.framework.constant.FrameworkConstant; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.event.EventListener; @@ -13,6 +13,8 @@ import org.springframework.stereotype.Component; import java.util.List; +import static cn.lycode.framework.constant.FrameworkConstant.SESSION_KEY_ROLE_PREFIX; + /** * @ClassName EventListener 事件监听器 */ @@ -21,17 +23,32 @@ import java.util.List; @Slf4j public class GlobalEventListener { - //监听到 PermsChangeEvent事件就会执行 + /** + * 监听到 PermsChangeEvent事件就会执行 + * 清空缓存的 当前角色对应的菜单列表和权限列表 + * 菜单列表:根据角色菜单表查出的此角色拥有的菜单 + * 权限列表:所有拥有的菜单中的权限标识 + * @param event + */ @EventListener - public void handlePermissionChangeEvent(PermsChangeEvent event) { - PermsMeta permsMeta = event.getPayload(); - log.info("[事件监听]-权限变更, data: {}", permsMeta); - List roleFlags = permsMeta.getRoleFlags(); + public void handleSessionChangeEvent(SessionChangeEvent event) { + SessionChangeMeta sessionChangeMeta = event.getPayload(); + log.info("[事件监听]-权限Session变更, data: {}", sessionChangeMeta); + List roleFlags = sessionChangeMeta.getRoleFlagList(); + for (Object roleFlag : roleFlags) { - SaSession roleSession = SaSessionCustomUtil.getSessionById("role-" + roleFlag); - roleSession.delete("Perms_List"); - roleSession.delete("Menu_List"); + SaSession roleSession = SaSessionCustomUtil.getSessionById(SESSION_KEY_ROLE_PREFIX + roleFlag); + roleSession.delete(FrameworkConstant.SESSION_KEY_PERMS_LIST); + roleSession.delete(FrameworkConstant.SESSION_KEY_MENU_LIST); + } + + List userIdList = sessionChangeMeta.getUserIdList(); + for (Object userId : userIdList) { + SaSession session = StpUtil.getSessionByLoginId(userId); + session.delete(FrameworkConstant.SESSION_KEY_ROLE_LIST); } + } + } diff --git a/framework/src/main/java/cn/lycode/framework/satoken/MySaTokenListener.java b/framework/src/main/java/cn/lycode/framework/satoken/MySaTokenListener.java index 29adfbf2a1b5c957abe0593462cdab25cbc46e61..36d4fb33daddceb2ec7e221ea503a0b521f3dd6e 100644 --- a/framework/src/main/java/cn/lycode/framework/satoken/MySaTokenListener.java +++ b/framework/src/main/java/cn/lycode/framework/satoken/MySaTokenListener.java @@ -3,7 +3,7 @@ package cn.lycode.framework.satoken; import cn.dev33.satoken.listener.SaTokenListener; import cn.dev33.satoken.stp.SaLoginModel; import cn.dev33.satoken.stp.StpUtil; -import cn.lycode.rbac.service.SysUserService; +import cn.lycode.system.service.SysUserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; diff --git a/framework/src/main/java/cn/lycode/framework/satoken/SaTokenConfig.java b/framework/src/main/java/cn/lycode/framework/satoken/SaTokenConfig.java index 0b3e16293a35f254ea918c76bfd1ee320357d229..ba94cf167b91c896790a37cb47865721e27648ce 100644 --- a/framework/src/main/java/cn/lycode/framework/satoken/SaTokenConfig.java +++ b/framework/src/main/java/cn/lycode/framework/satoken/SaTokenConfig.java @@ -27,7 +27,7 @@ public class SaTokenConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // 打开注解鉴权 -// registry.addInterceptor(new SaInterceptor().isAnnotation(true)).addPathPatterns("/**").excludePathPatterns(whitelistProperties.getWhitelist()); + // registry.addInterceptor(new SaInterceptor().isAnnotation(true)).addPathPatterns("/**").excludePathPatterns(whitelistProperties.getWhitelist()); // 注册 Sa-Token 拦截器,打开注解式鉴权功能 registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**").excludePathPatterns(whitelistProperties.getWhitelist());; } diff --git a/framework/src/main/java/cn/lycode/framework/web/controller/SysLoginController.java b/framework/src/main/java/cn/lycode/framework/web/controller/SysLoginController.java index 8cfdc372d108ed3980070c5c019d1698216fb785..4933f464527e0ebceed3b6af07fa1173a461e9aa 100644 --- a/framework/src/main/java/cn/lycode/framework/web/controller/SysLoginController.java +++ b/framework/src/main/java/cn/lycode/framework/web/controller/SysLoginController.java @@ -6,7 +6,7 @@ import cn.lycode.common.core.controller.BaseController; import cn.lycode.common.core.domain.AjaxResult; import cn.lycode.common.core.domain.model.user.LoginBody; import cn.lycode.framework.web.domain.LoginVO; -import cn.lycode.rbac.domain.vo.SysMenuVO; +import cn.lycode.system.domain.vo.SysMenuVO; import cn.lycode.framework.web.service.SysLoginService; import cn.lycode.framework.web.service.SysPermissionService; import lombok.RequiredArgsConstructor; diff --git a/framework/src/main/java/cn/lycode/framework/web/service/SysLoginService.java b/framework/src/main/java/cn/lycode/framework/web/service/SysLoginService.java index caa56978d14510a551a1492ca97ff1dd34f2c4c1..119321d465cbe1118d790255a19983f884ccd601 100644 --- a/framework/src/main/java/cn/lycode/framework/web/service/SysLoginService.java +++ b/framework/src/main/java/cn/lycode/framework/web/service/SysLoginService.java @@ -10,7 +10,7 @@ import cn.lycode.common.core.domain.model.user.LoginUserInfo; import cn.lycode.common.enums.ErrorEnum; import cn.lycode.common.utils.SecurityUtils; import cn.lycode.framework.web.domain.LoginVO; -import cn.lycode.rbac.service.SysUserService; +import cn.lycode.system.service.SysUserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; diff --git a/framework/src/main/java/cn/lycode/framework/web/service/SysPermissionService.java b/framework/src/main/java/cn/lycode/framework/web/service/SysPermissionService.java index 60646fd0183d4fd7fd5e240075f532a07c1ce823..7168bb2342083716d375ae10543b81b0cd96d577 100644 --- a/framework/src/main/java/cn/lycode/framework/web/service/SysPermissionService.java +++ b/framework/src/main/java/cn/lycode/framework/web/service/SysPermissionService.java @@ -4,9 +4,10 @@ import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.session.SaSessionCustomUtil; import cn.dev33.satoken.stp.StpUtil; import cn.lycode.common.constant.Constants; -import cn.lycode.rbac.domain.vo.SysMenuVO; -import cn.lycode.rbac.service.SysMenuService; -import cn.lycode.rbac.service.SysRoleService; +import cn.lycode.framework.constant.FrameworkConstant; +import cn.lycode.system.domain.vo.SysMenuVO; +import cn.lycode.system.service.SysMenuService; +import cn.lycode.system.service.SysRoleService; import cn.lycode.common.utils.SecurityUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -17,9 +18,14 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import static cn.lycode.framework.constant.FrameworkConstant.*; + /** * 用户权限处理 * + * 用户对应角色, 角色对应权限和菜单 + * 每次更新角色的菜单 清除 Perms_List、Menu_List + * 每次更新用户对应的角色,应该清除当前用户的 Role_List * @author lyCode */ @Slf4j @@ -37,7 +43,7 @@ public class SysPermissionService { public Set getRolePermFlag(Long userId) { SaSession session = StpUtil.getSessionByLoginId(userId); //session.get 方法有Sa-token提供缓存 - return session.get("Role_List", () -> { + return session.get(SESSION_KEY_ROLE_LIST, () -> { Set roles = new HashSet(); // 管理员拥有所有权限 if (SecurityUtils.isSuperAdmin(userId)) { @@ -66,9 +72,9 @@ public class SysPermissionService { permissionSet.add(Constants.ALL_PERMISSION); }else { for (String roleFlag : rolePermFlagSet) { - SaSession roleSession = SaSessionCustomUtil.getSessionById("role-" + roleFlag); + SaSession roleSession = SaSessionCustomUtil.getSessionById(SESSION_KEY_ROLE_PREFIX + roleFlag); //roleSession.get 方法有Sa-token提供缓存 - List list = roleSession.get("Perms_List", () -> { + List list = roleSession.get(SESSION_KEY_PERMS_LIST, () -> { return new ArrayList<>(menuService.selectMenuPermsByRoleFlag(roleFlag)); // 从数据库查询这个角色所拥有的权限列表 }); permissionSet.addAll(list); @@ -92,13 +98,12 @@ public class SysPermissionService { Set rolePermFlagSet = getRolePermFlag(loginUserId); SaSession userSession = StpUtil.getSessionByLoginId(loginUserId); if (rolePermFlagSet.contains(Constants.SUPER_ADMIN)) { - //超级管理员拥有所有菜单. - SaSession roleSession = SaSessionCustomUtil.getSessionById("role-" + Constants.SUPER_ADMIN); - sysMenuVOList = roleSession.get("Menu_List", menuService::selectFrontMenuAll); + //超级管理员拥有所有菜单. 且不带缓存,每次刷新都会请求菜单 + sysMenuVOList = menuService.selectFrontMenuAll(); }else { for (String roleFlag : rolePermFlagSet) { //roleSession.get 方法有Sa-token提供缓存 - List list = userSession.get("Menu_List", () -> { + List list = userSession.get(SESSION_KEY_MENU_LIST, () -> { return menuService.selectFrontMenusByRoleName(roleFlag); // 从数据库查询这个角色所拥有的权限列表 }); sysMenuVOList.addAll(list); diff --git a/framework/src/main/java/cn/lycode/framework/web/service/SysRegisterService.java b/framework/src/main/java/cn/lycode/framework/web/service/SysRegisterService.java index 36abe07431acf59bab5635d4012a6c963032f620..b2eb4ddbe2cf9c20e6584a1f73d9c7f0daead67f 100644 --- a/framework/src/main/java/cn/lycode/framework/web/service/SysRegisterService.java +++ b/framework/src/main/java/cn/lycode/framework/web/service/SysRegisterService.java @@ -6,7 +6,7 @@ import cn.lycode.common.constant.UserConstants; import cn.lycode.common.core.domain.model.user.RegisterBody; import cn.lycode.common.utils.SecurityUtils; import cn.lycode.common.utils.StringUtils; -import cn.lycode.rbac.service.SysUserService; +import cn.lycode.system.service.SysUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git "a/generator/src/main/resources/templates/\346\250\241\346\235\277\345\217\230\351\207\217\345\220\215.md" "b/generator/src/main/resources/templates/\346\250\241\346\235\277\345\217\230\351\207\217\345\220\215.md" index 3b417da5c276902bff299c17858b22a575514fec..1e0c708ca7ec663d5c64dcbef2d3ee94e5bdfcc6 100644 --- "a/generator/src/main/resources/templates/\346\250\241\346\235\277\345\217\230\351\207\217\345\220\215.md" +++ "b/generator/src/main/resources/templates/\346\250\241\346\235\277\345\217\230\351\207\217\345\220\215.md" @@ -27,7 +27,7 @@ | idType | String 主键ts类型, eg:number | | hasSort | boolean 列表查询的时候是否引入sort排序 | | **Java类名和包名** | ------------------------------------------------------------------------------------- | -| entityPkg | String, 生成实体类的相对路径,eg:cn.lycode.rbac.domain.entity | +| entityPkg | String, 生成实体类的相对路径,eg:cn.lycode.system.domain.entity | | mapperPkg | String, 生成mapper的相对路径 | | mapperXmlPkg | String, 生成mapper.xml的相对路径 | | servicePkg | String, 生成service的相对路径 | diff --git a/lycode_admin_vue/README.md b/lycode_admin_vue/README.md deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/lycode_admin_vue/env.d.ts b/lycode_admin_vue/env.d.ts index 11f02fe2a0061d6e6e1f271b21da95423b448b32..d8479a52d41040b4be4c6d7e6e5d37e416689392 100644 --- a/lycode_admin_vue/env.d.ts +++ b/lycode_admin_vue/env.d.ts @@ -1 +1,7 @@ /// +declare module '*.vue' { + import type { DefineComponent } from 'vue' + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types + const component: DefineComponent<{}, {}, any> + export default component +} diff --git a/lycode_admin_vue/pnpm-lock.yaml b/lycode_admin_vue/pnpm-lock.yaml index a2ad7e762fb1a3e0d187eff7c59275c027e22522..b65e73eab0f87d22c611bf265b13d5279201036d 100644 --- a/lycode_admin_vue/pnpm-lock.yaml +++ b/lycode_admin_vue/pnpm-lock.yaml @@ -41,6 +41,9 @@ dependencies: sortablejs: specifier: ^1.15.1 version: 1.15.3 + uuid: + specifier: ^10.0.0 + version: 10.0.0 vite-plugin-svg-icons: specifier: ^2.0.1 version: 2.0.1(vite@4.5.3) @@ -70,6 +73,9 @@ devDependencies: '@types/sortablejs': specifier: ^1.15.7 version: 1.15.8 + '@types/uuid': + specifier: ^10.0.0 + version: 10.0.0 '@vitejs/plugin-vue': specifier: ^4.4.0 version: 4.6.2(vite@4.5.3)(vue@3.4.38) @@ -801,6 +807,10 @@ packages: '@types/node': 18.19.48 dev: false + /@types/uuid@10.0.0: + resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} + dev: true + /@types/web-bluetooth@0.0.16: resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} dev: false @@ -4076,6 +4086,11 @@ packages: /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + /uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + dev: false + /vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} diff --git a/lycode_admin_vue/src/api/interface/system/sysDept.ts b/lycode_admin_vue/src/api/interface/system/sysDept.ts index c6d4422ba488da06e6582680e2728b1922350730..a3fc72ba1aea9cf87bcc5e3bf382b793908537d1 100644 --- a/lycode_admin_vue/src/api/interface/system/sysDept.ts +++ b/lycode_admin_vue/src/api/interface/system/sysDept.ts @@ -46,6 +46,6 @@ export namespace ISysDept { export interface DeptSetting { userIds: number[] - deptIds: number[] + deptId: number } } diff --git a/lycode_admin_vue/src/api/interface/system/sysPost.ts b/lycode_admin_vue/src/api/interface/system/sysPost.ts index 9a26de42dfc5e3591239e98e3f28ec2be0d87f94..f6f5566977bc0aa54c1ea4151371563f09faa897 100644 --- a/lycode_admin_vue/src/api/interface/system/sysPost.ts +++ b/lycode_admin_vue/src/api/interface/system/sysPost.ts @@ -27,4 +27,9 @@ export namespace ISysPost { remark?: string } + export interface PostSetting { + userIds: number[] + postIds: number[] + } + } \ No newline at end of file diff --git a/lycode_admin_vue/src/api/interface/system/user.ts b/lycode_admin_vue/src/api/interface/system/user.ts index efe8217f5d07dd04efa328f674e8669335136eb0..255b905100793bfaaf1173a596331a8d9d95f4ce 100644 --- a/lycode_admin_vue/src/api/interface/system/user.ts +++ b/lycode_admin_vue/src/api/interface/system/user.ts @@ -16,36 +16,59 @@ export namespace IUser { export interface Form { id?: number username?: string - pwd?: string - phone: string + personNo: string + deptId: number + postIdList: number[] nickName: string - logo: string - age: number sex: number - idCard: string + mobile: string email: string + idCard: string + birthday: string accountStatusCd: string userTagCd: string - birthday: string + avatar: string } export interface Info { id?: number + deptId: number + personNo: string username: string - phone: string nickName: string - logo: string - age: number - sex: number - idCard: string + userType: string email: string + mobile: string + phone: string + idCard: string + avatar: string + birthday: string + sex: number accountStatusCd: string userTagCd: string - lastLoginTime: string + loginIp: string + loginDate: string createTime: string updateTime: string - delFlag: string - birthday: string + remark: string + dept: DeptInfo + roleList: RoleInfo[] + postList: PostInfo[] + } + + export interface DeptInfo { + id: number + pid: number + deptName: string + leader: string + mobile: string + email: string + } + + export interface PostInfo { + id: number + postCode: string + postName: string } export interface RoleForm { @@ -61,6 +84,7 @@ export namespace IUser { export interface RoleInfo { id: number roleName: string + dataScope: string } export interface PasswordForm { diff --git a/lycode_admin_vue/src/api/modules/system/sysPost.ts b/lycode_admin_vue/src/api/modules/system/sysPost.ts index 7b8801d9f7fa86541a002ff5a87f0be69da3d437..0132ca240e5df02fe5c4851e4d259b18c06f8b6e 100644 --- a/lycode_admin_vue/src/api/modules/system/sysPost.ts +++ b/lycode_admin_vue/src/api/modules/system/sysPost.ts @@ -12,6 +12,10 @@ export const getSysPostListApi = (params: ISysPost.Query) => { return http.get>(ADMIN_MODULE + `/sys-post/list`, params) } +export const getSysPostOptionApi = () => { + return http.get(ADMIN_MODULE + `/sys-post/option`) +} + /** * 添加 * @param params @@ -36,7 +40,7 @@ export const updateSysPostApi = (params: ISysPost.Form) => { * @returns {*} */ export const removeSysPostApi = (params: { ids: number[] }) => { - return http.post(ADMIN_MODULE + `/sys-post/remove`, params) + return http.post(ADMIN_MODULE + `/sys-post/remove`, params) } /** diff --git a/lycode_admin_vue/src/api/modules/system/user.ts b/lycode_admin_vue/src/api/modules/system/user.ts index fcadbc0a71681dddf0e60d2cc6a2e6cceff90cb5..9afd77d466aad4a76df4e7bae3b217ef9944ecff 100644 --- a/lycode_admin_vue/src/api/modules/system/user.ts +++ b/lycode_admin_vue/src/api/modules/system/user.ts @@ -3,6 +3,7 @@ import { ADMIN_MODULE } from '@/api/helper/prefix' import type { IUser } from '@/api/interface/system/user' import type { IPage } from '@/api/interface' import type { ISysDept } from '@/api/interface/system/sysDept' +import type { ISysPost } from '@/api/interface/system/sysPost' /** * 获取用户列表 @@ -28,6 +29,8 @@ export const addUser = (params: IUser.Form) => { * @returns {*} */ export const editUser = (params: IUser.Form) => { + console.log(params); + return http.post(ADMIN_MODULE + `/sys-user/update`, params) } @@ -64,7 +67,7 @@ export const setUserRole = (params: IUser.RoleForm) => { * @returns {*} */ export const changePassword = (params: IUser.PasswordForm) => { - return http.put(ADMIN_MODULE + `/sys-user/password`, params) + return http.post(ADMIN_MODULE + `/sys-user/password`, params) } /** @@ -73,7 +76,7 @@ export const changePassword = (params: IUser.PasswordForm) => { */ export const resetPassword = (params: { id: number }) => { const { id } = params - return http.put(ADMIN_MODULE + `/sys-user/reset/password/${id}`, {}) + return http.post(ADMIN_MODULE + `/sys-user/reset/password/${id}`, {}) } /** @@ -85,7 +88,7 @@ export const getUserinfo = () => { } /** - * 添加 + * 绑定部门 * @param params * @returns {*} */ @@ -93,6 +96,15 @@ export const bindUserDeptApi = (params: ISysDept.DeptSetting) => { return http.post(ADMIN_MODULE + `/sys-user/dept/bind`, params) } +/** + * 绑定岗位 + * @param params + * @returns {*} + */ +export const bindUserPostApi = (params: ISysPost.PostSetting) => { + return http.post(ADMIN_MODULE + `/sys-user/post/bind`, params) +} + /** * 用户部门属性列表 */ diff --git a/lycode_admin_vue/src/views/system/accountManage/components/UserAdd.vue b/lycode_admin_vue/src/views/system/accountManage/components/UserAdd.vue index 27c376b9ca0820af86162ccb3c311d62029b5233..c37bed8c2701667598f841b255a3c75f473125c6 100644 --- a/lycode_admin_vue/src/views/system/accountManage/components/UserAdd.vue +++ b/lycode_admin_vue/src/views/system/accountManage/components/UserAdd.vue @@ -99,11 +99,11 @@ - +