├── .gitattributes ├── LICENSE ├── README.md ├── assets ├── 1715165111235.png ├── 1715165802845.png ├── 1715165829646.png ├── 1715165852027.png ├── 1715165872252.png ├── 1715165892372.png ├── 1715165918252.png └── 1715165938321.png ├── back-me ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── jzm │ │ │ └── backme │ │ │ ├── BackMeApplication.java │ │ │ ├── JzmGenerate.java │ │ │ ├── annotation │ │ │ └── NotEmpty.java │ │ │ ├── config │ │ │ ├── AppConfig.java │ │ │ ├── MybatisPlusConfig.java │ │ │ ├── Swagger2Config.java │ │ │ ├── fisco │ │ │ │ ├── ContractConfig.java │ │ │ │ ├── FiscoConfig.java │ │ │ │ ├── SdkBeanConfig.java │ │ │ │ ├── contract │ │ │ │ │ ├── ContractErrCode.java │ │ │ │ │ ├── ContractException.java │ │ │ │ │ └── ContractResponse.java │ │ │ │ └── service │ │ │ │ │ ├── ContractService.java │ │ │ │ │ └── WeFrontService.java │ │ │ └── redis │ │ │ │ ├── FastJson2JsonRedisSerializer.java │ │ │ │ └── RedisConfig.java │ │ │ ├── constant │ │ │ ├── CacheConstant.java │ │ │ ├── Constant.java │ │ │ ├── HeaderConstant.java │ │ │ ├── HttpStatus.java │ │ │ └── UserConstant.java │ │ │ ├── context │ │ │ └── UserContext.java │ │ │ ├── controller │ │ │ ├── CaptchaController.java │ │ │ ├── ContractController.java │ │ │ ├── HouseController.java │ │ │ ├── LoginController.java │ │ │ ├── PaymentController.java │ │ │ ├── UserController.java │ │ │ └── base │ │ │ │ ├── BaseBaseEntity.java │ │ │ │ └── BaseController.java │ │ │ ├── domain │ │ │ ├── Contract.java │ │ │ ├── House.java │ │ │ ├── Payment.java │ │ │ ├── Role.java │ │ │ ├── User.java │ │ │ ├── UserRole.java │ │ │ └── base │ │ │ │ └── BaseEntity.java │ │ │ ├── exception │ │ │ ├── CustomException.java │ │ │ ├── PermissionException.java │ │ │ └── base │ │ │ │ └── BaseException.java │ │ │ ├── handler │ │ │ └── GlobalExceptionHandler.java │ │ │ ├── interceptor │ │ │ └── TokenInterceptor.java │ │ │ ├── mapper │ │ │ ├── ContractMapper.java │ │ │ ├── HouseMapper.java │ │ │ ├── PaymentMapper.java │ │ │ ├── RoleMapper.java │ │ │ ├── UserMapper.java │ │ │ └── UserRoleMapper.java │ │ │ ├── model │ │ │ ├── AjaxResult.java │ │ │ ├── PageResult.java │ │ │ ├── to │ │ │ │ ├── LoginTo.java │ │ │ │ ├── base │ │ │ │ │ └── BasePageQueryTo.java │ │ │ │ ├── contract │ │ │ │ │ └── ContractQueryTo.java │ │ │ │ ├── house │ │ │ │ │ ├── HouseAddTo.java │ │ │ │ │ ├── HouseDeleteTo.java │ │ │ │ │ ├── HousePassTo.java │ │ │ │ │ └── HouseQueryTo.java │ │ │ │ ├── payment │ │ │ │ │ ├── PaymentAddTo.java │ │ │ │ │ └── PaymentQueryTo.java │ │ │ │ └── user │ │ │ │ │ ├── PassTo.java │ │ │ │ │ ├── UserAddTo.java │ │ │ │ │ ├── UserDeleteTo.java │ │ │ │ │ ├── UserPassTo.java │ │ │ │ │ ├── UserPayMoneyTo.java │ │ │ │ │ ├── UserQueryTo.java │ │ │ │ │ └── UserResTo.java │ │ │ └── vo │ │ │ │ ├── ContractVo.java │ │ │ │ ├── HouseVo.java │ │ │ │ ├── PaymentVo.java │ │ │ │ └── UserVo.java │ │ │ ├── service │ │ │ ├── CaptchaService.java │ │ │ ├── ContractService.java │ │ │ ├── HouseService.java │ │ │ ├── LoginService.java │ │ │ ├── MainContractService.java │ │ │ ├── PaymentService.java │ │ │ ├── RoleService.java │ │ │ ├── UserRoleService.java │ │ │ ├── UserService.java │ │ │ └── impl │ │ │ │ ├── ContractServiceImpl.java │ │ │ │ ├── HouseServiceImpl.java │ │ │ │ ├── PaymentServiceImpl.java │ │ │ │ ├── RoleServiceImpl.java │ │ │ │ ├── UserRoleServiceImpl.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── util │ │ │ ├── Convert.java │ │ │ ├── DateUtil.java │ │ │ ├── NotEmptyUtil.java │ │ │ ├── PageUtil.java │ │ │ ├── ServletUtil.java │ │ │ ├── StringUtil.java │ │ │ ├── TokenUtil.java │ │ │ ├── redis │ │ │ └── RedisCache.java │ │ │ └── user │ │ │ └── UserUtil.java │ └── resources │ │ ├── application-hikari.yml │ │ ├── application-redis.yml │ │ ├── application.yml │ │ ├── conf │ │ ├── ca.crt │ │ ├── sdk.crt │ │ └── sdk.key │ │ └── mapper │ │ ├── ContractMapper.xml │ │ ├── HouseMapper.xml │ │ ├── PaymentMapper.xml │ │ ├── RoleMapper.xml │ │ ├── UserMapper.xml │ │ └── UserRoleMapper.xml │ └── test │ └── java │ └── com │ └── jzm │ └── backme │ ├── BackMeApplicationTests.java │ └── service │ ├── ContractServiceTest.java │ ├── TestServiceTest.java │ └── WebaseFrontServiceTest.java ├── contracts-me ├── MainService.sol ├── Roles.sol ├── data.js └── nine.sql └── nine.sql /.gitattributes: -------------------------------------------------------------------------------- 1 | *.vue linguist-language=java 2 | *.java linguist-language=java 3 | *.css linguist-language=java 4 | *.js linguist-language=java 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 本郡主是喵 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 房屋转租系统 2 | 3 | ## 项目概述 4 | 5 | 一个基于区块链技术的web房屋转租系统。本系统角色分为3个:管理员、租客、房东。基于https://github.com/junzhumiao/goods-manage 6 | 7 | 该系统开发。该系统主要实现了出租房屋、合同发布、签署合同、合同终止、房租缴纳,并结合区块链技术,将实体部分信息上链,实现去中心化存储。从而保证数据防篡改、共识、真实有效。 8 | 9 | ## 项目所涉及技术栈: 10 | 11 | 智能合约:Solidity 12 | 13 | 服务端:SpringBoot、Mybatis-plus、Redis、Fisco-Bcos、Hutool 14 | 15 | 客户端:Vue、axios、Vue-cli、Vuex、Vue-router、Element-UI 16 | 17 | 18 | 19 | ## 项目安装和使用 20 | 21 | 服务端: 22 | 23 | 1.搭建4节点区块链网络(fisco-bcos) 24 | 25 | 2.搭建webase-front 26 | 27 | 3.将contract-me包下的合约部署在webase-front平台 28 | 29 | 30 | 31 | 4.在application.yml更改fisco连接配置、webase-front连接配置,在application-hikari.yml更改MySQL连接配置,运行nice.SQL文件 32 | 33 | 在application-redis.yml更改Redis连接配置 34 | 35 | 客户端: 36 | 37 | 打开front-me项目: 38 | 39 | ``` 40 | # 执行 41 | npm -i 42 | # 再执行 43 | npm run serv 44 | ``` 45 | 46 | ## 项目展示 47 | 48 | ### 登录 49 | 50 | ![1715165111235](assets/1715165111235.png) 51 | 52 | ### 用户管理 53 | 54 | ![1715165802845](assets/1715165802845.png) 55 | 56 | ### 房屋管理 57 | 58 | ![1715165829646](assets/1715165829646.png) 59 | 60 | ### 预发布合同管理 61 | 62 | ![1715165852027](assets/1715165852027.png) 63 | 64 | ### 签署合同管理 65 | 66 | ![1715165872252](assets/1715165872252.png) 67 | 68 | ### 生效合同管理 69 | 70 | ![1715165892372](assets/1715165892372.png) 71 | 72 | ### 缴费管理 73 | 74 | ![1715165918252](assets/1715165918252.png) 75 | 76 | ### 个人中心 77 | 78 | ![1715165938321](assets/1715165938321.png) -------------------------------------------------------------------------------- /assets/1715165111235.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junzhumiao/house-rent/332dbb689f545283988fd4999ade69ddfac34c6e/assets/1715165111235.png -------------------------------------------------------------------------------- /assets/1715165802845.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junzhumiao/house-rent/332dbb689f545283988fd4999ade69ddfac34c6e/assets/1715165802845.png -------------------------------------------------------------------------------- /assets/1715165829646.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junzhumiao/house-rent/332dbb689f545283988fd4999ade69ddfac34c6e/assets/1715165829646.png -------------------------------------------------------------------------------- /assets/1715165852027.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junzhumiao/house-rent/332dbb689f545283988fd4999ade69ddfac34c6e/assets/1715165852027.png -------------------------------------------------------------------------------- /assets/1715165872252.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junzhumiao/house-rent/332dbb689f545283988fd4999ade69ddfac34c6e/assets/1715165872252.png -------------------------------------------------------------------------------- /assets/1715165892372.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junzhumiao/house-rent/332dbb689f545283988fd4999ade69ddfac34c6e/assets/1715165892372.png -------------------------------------------------------------------------------- /assets/1715165918252.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junzhumiao/house-rent/332dbb689f545283988fd4999ade69ddfac34c6e/assets/1715165918252.png -------------------------------------------------------------------------------- /assets/1715165938321.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junzhumiao/house-rent/332dbb689f545283988fd4999ade69ddfac34c6e/assets/1715165938321.png -------------------------------------------------------------------------------- /back-me/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /back-me/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | com.jzm 6 | back-me 7 | 0.0.1-SNAPSHOT 8 | back-me 9 | back-me 10 | 11 | 14 12 | UTF-8 13 | UTF-8 14 | 2.6.13 15 | 16 | 2.7.0 17 | 1.4.7 18 | 2.0.19.graal 19 | 5.7.20 20 | 3.5.3.1 21 | 1.18.26 22 | 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter 27 | 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-web 33 | 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-test 38 | test 39 | 40 | 41 | 42 | com.github.pagehelper 43 | pagehelper-spring-boot-starter 44 | 1.4.7 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-devtools 49 | runtime 50 | true 51 | 52 | 53 | 54 | 55 | cn.hutool 56 | hutool-all 57 | ${hutool-all.version} 58 | 59 | 60 | 61 | 62 | org.projectlombok 63 | lombok 64 | ${lombok} 65 | 66 | 67 | 68 | com.baomidou 69 | mybatis-plus-generator 70 | ${mybatis-plus.version} 71 | 72 | 73 | 74 | com.baomidou 75 | mybatis-plus-boot-starter 76 | ${mybatis-plus.version} 77 | 78 | 79 | org.freemarker 80 | freemarker 81 | 82 | 83 | 84 | com.mysql 85 | mysql-connector-j 86 | 87 | 88 | 89 | com.github.pagehelper 90 | pagehelper-spring-boot-starter 91 | ${pagehelper.boot.version} 92 | 93 | 94 | org.springframework.boot 95 | spring-boot-configuration-processor 96 | true 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | org.springframework.boot 108 | spring-boot-starter-data-redis 109 | 110 | 111 | 112 | com.alibaba.fastjson2 113 | fastjson2 114 | ${fastjson2.version} 115 | 116 | 117 | 118 | org.apache.commons 119 | commons-lang3 120 | 121 | 122 | org.fisco-bcos.java-sdk 123 | fisco-bcos-java-sdk 124 | 2.9.0 125 | 126 | 127 | org.slf4j 128 | slf4j-log4j12 129 | 130 | 131 | 132 | 133 | 134 | io.springfox 135 | springfox-swagger2 136 | ${swagger.version} 137 | 138 | 139 | io.springfox 140 | springfox-swagger-ui 141 | ${swagger.version} 142 | 143 | 144 | 145 | 146 | 147 | org.springframework.boot 148 | spring-boot-dependencies 149 | ${spring-boot.version} 150 | pom 151 | import 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | org.apache.maven.plugins 160 | maven-compiler-plugin 161 | 3.8.1 162 | 163 | 1.8 164 | 1.8 165 | UTF-8 166 | 167 | 168 | 169 | org.springframework.boot 170 | spring-boot-maven-plugin 171 | ${spring-boot.version} 172 | 173 | com.jzm.backme.BackMeApplication 174 | true 175 | 176 | 177 | 178 | repackage 179 | 180 | repackage 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/BackMeApplication.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.context.properties.ConfigurationPropertiesScan; 6 | 7 | @SpringBootApplication(scanBasePackages ={"com.jzm.backme"} ) 8 | @ConfigurationPropertiesScan(basePackages = {"com.jzm.backme"}) 9 | public class BackMeApplication 10 | { 11 | 12 | public static void main(String[] args) 13 | { 14 | SpringApplication.run(BackMeApplication.class, args); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/JzmGenerate.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme; 2 | 3 | import com.baomidou.mybatisplus.generator.FastAutoGenerator; 4 | import com.baomidou.mybatisplus.generator.config.OutputFile; 5 | import com.baomidou.mybatisplus.generator.config.rules.DateType; 6 | import com.baomidou.mybatisplus.generator.config.rules.DbColumnType; 7 | import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; 8 | 9 | import java.sql.Types; 10 | import java.util.Collections; 11 | 12 | public class JzmGenerate 13 | { 14 | 15 | public static void main(String[] args) 16 | { 17 | // 这个字符串,从table 18 | String tabStr = "user_role"; 19 | 20 | String prefix = ""; // 生成要拼接的表前缀,如tb_str、ts_str、tb_1字符串,设置tb_,只会拼接tb_的 21 | String filterPrefix = "";// 过滤表前缀,生成的实体类把前缀忽略 22 | // 格式化之后table字符串 23 | String tableStr = JzmGenerate.tabStrFormat(tabStr, prefix); 24 | 25 | JzmGenerate.generateAll(tableStr, filterPrefix); 26 | } 27 | 28 | /** 29 | * @param tableStr 表格字符串: 如 " sys_user,sys_role " 30 | * @param filterPrefix 过滤表格前缀: 如 sys_ 31 | */ 32 | public static void generateAll(final String tableStr, final String filterPrefix) 33 | { 34 | // 设置url。用户名和密码 35 | FastAutoGenerator.create("jdbc:mysql://localhost:3306/nice?characterEncoding=utf-8&serverTimezone=Asia/Shanghai", 36 | "root", "123456") 37 | .globalConfig(builder -> 38 | { 39 | builder.author("qhx2004") // 设置作者 40 | .enableSwagger() // 开启 swagger 模式,选的话+依赖 41 | .dateType(DateType.TIME_PACK) 42 | .outputDir("C:\\Users\\qhx20\\Desktop\\区块链比赛资料整理\\2023国赛样题\\国9\\代码\\back-me\\src\\main\\java"); 43 | // 指定输出目录 44 | }) 45 | .dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> 46 | { 47 | int typeCode = metaInfo.getJdbcType().TYPE_CODE; 48 | if (typeCode == Types.SMALLINT) 49 | { 50 | // 自定义类型转换 51 | return DbColumnType.INTEGER; 52 | } 53 | return typeRegistry.getColumnType(metaInfo); 54 | 55 | })) 56 | .packageConfig(builder -> 57 | { 58 | builder.parent("com.jzm") // 设置父包名 59 | .entity("domain") 60 | .moduleName("backme") // 设置父包模块名,我这里没有模块名 61 | // C:\Users\qhx20\Desktop\wms\wms-h\src\main\resources 62 | .pathInfo(Collections.singletonMap(OutputFile.xml, "C:\\Users\\qhx20\\Desktop\\区块链比赛资料整理" + 63 | "\\2023国赛样题\\国9\\代码\\back-me\\src\\main\\resources\\mapper")); // 设置mapperXml生成路径 64 | }) 65 | .strategyConfig(builder -> 66 | { 67 | builder.addInclude(tableStr) // 设置需要生成的表名 68 | .addTablePrefix(filterPrefix)// 设置过滤表前缀 69 | // 设置controller 70 | .controllerBuilder().enableRestStyle() // 启用rest风格 71 | // 设置entity实体 72 | .entityBuilder().enableLombok() // 开lomback 73 | .enableFileOverride() // 覆盖已有文件 74 | // 设置service 75 | .serviceBuilder().formatServiceFileName("%sService") // 格式化生成Service.java文件,相当于把I过滤了 76 | // 设置 mapper 77 | .mapperBuilder().enableMapperAnnotation(); // 开启mapper注解 78 | 79 | }) 80 | .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板 81 | .execute(); 82 | } 83 | 84 | 85 | /** 86 | * @param tabStr 表格字符串 : 就是直接从 从客户端软件 show tables; 直接复制粘贴的。 87 | * @param prefix 要格式化的表格字符串前缀,最后会组合到一起。( 如 sys_user、sys_role ) 88 | * @return 89 | */ 90 | public static String tabStrFormat(String tabStr, String prefix) 91 | { 92 | StringBuilder stb = new StringBuilder(); 93 | String[] splits = tabStr.split("\n"); 94 | for (String split : splits) 95 | { 96 | if (split.startsWith(prefix)) 97 | { 98 | stb.append(split); 99 | stb.append(","); 100 | } 101 | 102 | if (prefix == null) 103 | { 104 | stb.append(split); 105 | stb.append(","); 106 | } 107 | } 108 | return stb.toString().substring(0, stb.toString().length() - 1); 109 | } 110 | 111 | } -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/annotation/NotEmpty.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | *空字段校验注解 10 | */ 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target({ElementType.FIELD,ElementType.TYPE}) 13 | 14 | public @interface NotEmpty 15 | { 16 | // 必填: 就是不为null、"" 17 | boolean required() default true; 18 | String extra() default ""; 19 | } 20 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/config/AppConfig.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.config; 2 | 3 | import cn.hutool.core.date.DatePattern; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.fasterxml.jackson.databind.module.SimpleModule; 6 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; 7 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; 8 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; 9 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; 10 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; 11 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; 12 | import com.jzm.backme.constant.UserConstant; 13 | import com.jzm.backme.interceptor.TokenInterceptor; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 16 | import org.springframework.context.annotation.Bean; 17 | import org.springframework.context.annotation.Configuration; 18 | import org.springframework.context.annotation.Primary; 19 | import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; 20 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 21 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 22 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 23 | 24 | import java.text.SimpleDateFormat; 25 | import java.time.LocalDate; 26 | import java.time.LocalDateTime; 27 | import java.time.LocalTime; 28 | import java.time.format.DateTimeFormatter; 29 | import java.util.TimeZone; 30 | 31 | /** 32 | * @author: jzm 33 | * @date: 2024-04-11 19:23 34 | **/ 35 | 36 | @Configuration 37 | public class AppConfig implements WebMvcConfigurer 38 | { 39 | 40 | @Autowired 41 | private TokenInterceptor tokenInterceptor; 42 | 43 | @Override 44 | public void addInterceptors(InterceptorRegistry registry) 45 | { 46 | registry.addInterceptor(tokenInterceptor); 47 | } 48 | 49 | @Override 50 | public void addCorsMappings(CorsRegistry registry) { 51 | // 设置允许跨域的路径 52 | registry.addMapping("/**") 53 | // 设置允许跨域请求的域名 54 | .allowedOriginPatterns("*") 55 | // 是否允许cookie 56 | .allowCredentials(true) 57 | // 设置允许的请求方式 58 | .allowedMethods("*") 59 | // 设置允许的header属性 60 | .allowedHeaders("*") 61 | // 跨域允许时间 62 | .maxAge(3600); 63 | } 64 | 65 | 66 | /** 67 | * 设置时间格式化 68 | */ 69 | @Bean 70 | @Primary 71 | @ConditionalOnMissingBean(ObjectMapper.class) 72 | public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { 73 | ObjectMapper objectMapper = builder.createXmlMapper(false).build(); 74 | // 全局配置序列化返回 JSON 处理 75 | SimpleModule simpleModule = new SimpleModule(); 76 | //封装类型 Long ==> String 77 | simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN))); 78 | simpleModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN))); 79 | 80 | simpleModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN))); 81 | simpleModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN))); 82 | 83 | simpleModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN))); 84 | simpleModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN))); 85 | 86 | objectMapper.registerModule(simpleModule); 87 | objectMapper.setDateFormat(new SimpleDateFormat(DatePattern.NORM_DATETIME_PATTERN)); 88 | objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8")); 89 | return objectMapper; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/config/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.config; 2 | 3 | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; 4 | import com.jzm.backme.context.UserContext; 5 | import com.jzm.backme.domain.User; 6 | import com.jzm.backme.util.StringUtil; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.apache.ibatis.reflection.MetaObject; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.transaction.annotation.EnableTransactionManagement; 11 | 12 | import java.time.LocalDateTime; 13 | 14 | @Slf4j 15 | @Component 16 | @EnableTransactionManagement 17 | public class MybatisPlusConfig implements MetaObjectHandler 18 | { 19 | @Override 20 | public void insertFill(MetaObject metaObject) { 21 | this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class); 22 | User user = UserContext.get(); 23 | if(StringUtil.isNotEmpty(user)){ 24 | this.strictInsertFill(metaObject, "createBy", user::getUserId, Long.class); 25 | } 26 | } 27 | 28 | @Override 29 | public void updateFill(MetaObject metaObject) { 30 | this.strictUpdateFill(metaObject,"updateTime", LocalDateTime::now, LocalDateTime.class); 31 | User user = UserContext.get(); 32 | if(StringUtil.isNotEmpty(user)){ 33 | this.strictInsertFill(metaObject, "updateBy", user::getUserId, Long.class); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/config/Swagger2Config.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import springfox.documentation.builders.ApiInfoBuilder; 6 | import springfox.documentation.service.ApiInfo; 7 | import springfox.documentation.service.Contact; 8 | import springfox.documentation.spi.DocumentationType; 9 | import springfox.documentation.spring.web.plugins.Docket; 10 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 11 | 12 | @Configuration 13 | @EnableSwagger2 // 3.0版本加不加无所谓 14 | public class Swagger2Config 15 | { 16 | 17 | private boolean enabled = true; 18 | 19 | @Bean 20 | public Docket coreApiConfig(){ 21 | return new Docket(DocumentationType.SWAGGER_2) 22 | .apiInfo(adminApiInfo()) 23 | .groupName("group1") 24 | .enable(enabled) 25 | .select() 26 | .build(); 27 | } 28 | 29 | private ApiInfo adminApiInfo(){ 30 | return new ApiInfoBuilder() 31 | .title("后台管理系统--api文档") 32 | .description("后台管理系统接口描述") 33 | .version("1.0") 34 | .contact(new Contact("郡主喵","http://baidu.com","728831102@qq.com")) 35 | .build(); 36 | } 37 | } -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/config/fisco/ContractConfig.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.config.fisco; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | /** 7 | * 与指定合约交互的配置 8 | */ 9 | @Data 10 | @ConfigurationProperties(prefix = "fisco.contract") 11 | public class ContractConfig 12 | { 13 | private String address; 14 | private String name; 15 | private String owner; 16 | private String bin; 17 | private String abi; 18 | } 19 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/config/fisco/FiscoConfig.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.config.fisco; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.boot.context.properties.NestedConfigurationProperty; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * fisco网络连接配置 11 | */ 12 | @Data 13 | @Configuration 14 | @ConfigurationProperties(prefix = "fisco") 15 | @Component 16 | 17 | public class FiscoConfig 18 | { 19 | private String peers; 20 | 21 | private int groupId = 1; 22 | 23 | private String certPath = "conf"; 24 | 25 | private String hexPrivateKey; 26 | 27 | // 嵌套属性映射,作为一个嵌套属性注入 28 | @NestedConfigurationProperty 29 | private ContractConfig contract; // 选填属性 30 | 31 | private String frontUrl; // 选填属性 32 | } 33 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/config/fisco/SdkBeanConfig.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.config.fisco; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.fisco.bcos.sdk.BcosSDK; 5 | import org.fisco.bcos.sdk.client.Client; 6 | import org.fisco.bcos.sdk.config.ConfigOption; 7 | import org.fisco.bcos.sdk.config.exceptions.ConfigException; 8 | import org.fisco.bcos.sdk.config.model.ConfigProperty; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | 13 | import java.util.Arrays; 14 | import java.util.HashMap; 15 | import java.util.List; 16 | import java.util.Map; 17 | import java.util.stream.Collectors; 18 | 19 | /** 20 | * fisco客户端配置类 21 | */ 22 | @Configuration 23 | @Slf4j 24 | public class SdkBeanConfig 25 | { 26 | 27 | @Autowired 28 | private FiscoConfig config; 29 | 30 | 31 | @Bean 32 | public Client client() throws Exception 33 | { 34 | String certPaths = this.config.getCertPath(); 35 | String[] possibilities = certPaths.split(",|;"); 36 | for (String certPath : possibilities) 37 | { 38 | try 39 | { 40 | 41 | ConfigProperty property = new ConfigProperty(); 42 | configNetwork(property); 43 | configCryptoMaterial(property, certPath); 44 | ConfigOption configOption = new ConfigOption(property); 45 | Client client = new BcosSDK(configOption).getClient(config.getGroupId()); 46 | configCryptoKeyPair(client); 47 | return client; 48 | } catch (Exception ex) 49 | { 50 | log.error("区块链网络连接异常", ex); 51 | } 52 | } 53 | throw new ConfigException("Failed to connect to peers:" + config.getPeers()); 54 | } 55 | 56 | 57 | public void configNetwork(ConfigProperty configProperty) 58 | { 59 | String peerStr = config.getPeers(); 60 | List peers = Arrays.stream(peerStr.split(",")).collect(Collectors.toList()); 61 | Map networkConfig = new HashMap<>(); 62 | networkConfig.put("peers", peers); 63 | 64 | configProperty.setNetwork(networkConfig); 65 | } 66 | 67 | public void configCryptoMaterial(ConfigProperty configProperty, String certPath) 68 | { 69 | Map cryptoMaterials = new HashMap<>(); 70 | cryptoMaterials.put("certPath", certPath); 71 | configProperty.setCryptoMaterial(cryptoMaterials); 72 | } 73 | 74 | public void configCryptoKeyPair(Client client) 75 | { 76 | if (config.getHexPrivateKey() == null || config.getHexPrivateKey().isEmpty()) 77 | { 78 | client.getCryptoSuite().setCryptoKeyPair(client.getCryptoSuite().createKeyPair()); 79 | return; 80 | } 81 | String privateKey; 82 | if (!config.getHexPrivateKey().contains(",")) 83 | { 84 | privateKey = config.getHexPrivateKey(); 85 | } else 86 | { 87 | String[] list = config.getHexPrivateKey().split(","); 88 | privateKey = list[0]; 89 | } 90 | if (privateKey.startsWith("0x") || privateKey.startsWith("0X")) 91 | { 92 | privateKey = privateKey.substring(2); 93 | config.setHexPrivateKey(privateKey); 94 | } 95 | client.getCryptoSuite().setCryptoKeyPair(client.getCryptoSuite().createKeyPair(privateKey)); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/config/fisco/contract/ContractErrCode.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.config.fisco.contract; 2 | 3 | 4 | import com.jzm.backme.util.StringUtil; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /** 10 | * @author: jzm 11 | * @date: 2024-04-16 19:34 12 | **/ 13 | 14 | public class ContractErrCode 15 | { 16 | public static final Map errCode = new HashMap(); 17 | 18 | { 19 | errCode.put("40001", "账户地址不能为空地址"); 20 | errCode.put("40002", "参数租客地址与合同租客地址不相等"); 21 | errCode.put("40003", "参数租客地址与合同租客地址不相等"); 22 | errCode.put("40004", "房东终止合同失败:租客实际缴租金 + 保证金 < 应缴纳租金"); 23 | errCode.put("40005", "租客终止合同失败:租客实际缴租金 < 应缴纳租金 + 2个月租金"); 24 | errCode.put("40006", "参数房东地址与合同房东地址不相等"); 25 | errCode.put("40007", "账户地址不能是空地址"); 26 | errCode.put("40008", "账户月不足以支付money"); 27 | errCode.put("40010", ""); 28 | errCode.put("40011", "签署合同不存在"); 29 | errCode.put("40012", "签署合同已经过了签署时间"); 30 | errCode.put("40013", "这个Person account 不存在"); 31 | errCode.put("40014", "调用者必须是房东角色"); 32 | errCode.put("40015", "调用者必须是租客角色"); 33 | errCode.put("40016", "调用者必须是管理员"); 34 | } 35 | 36 | // 根据错误码匹配 37 | public static ContractException get(String code) 38 | { 39 | String val = errCode.get(code); 40 | if (StringUtil.isEmpty(val)) 41 | { // 匹配不到,直接返回 42 | return new ContractException(code); 43 | } 44 | return new ContractException(val); 45 | } 46 | 47 | public static ContractException get(ContractResponse contractResponse) 48 | { 49 | String code = contractResponse.getMes(); 50 | return get(code); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/config/fisco/contract/ContractException.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.config.fisco.contract; 2 | 3 | 4 | import com.jzm.backme.exception.base.BaseException; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-04-16 19:30 9 | **/ 10 | 11 | public class ContractException extends BaseException 12 | { 13 | public ContractException(String message, int code) 14 | { 15 | super(message, code); 16 | } 17 | 18 | public ContractException(String message) 19 | { 20 | super(message, 400); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/config/fisco/contract/ContractResponse.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.config.fisco.contract; 2 | 3 | import cn.hutool.json.JSONArray; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class ContractResponse 8 | { 9 | private JSONArray vals; 10 | 11 | private String mes; // 响应消息 12 | } 13 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/config/fisco/service/ContractService.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.config.fisco.service; 2 | 3 | import cn.hutool.json.JSONArray; 4 | import cn.hutool.json.JSONUtil; 5 | import com.jzm.backme.config.fisco.contract.ContractResponse; 6 | import org.fisco.bcos.sdk.abi.ABICodecException; 7 | import org.fisco.bcos.sdk.client.Client; 8 | import org.fisco.bcos.sdk.crypto.CryptoSuite; 9 | import org.fisco.bcos.sdk.model.CryptoType; 10 | import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor; 11 | import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory; 12 | import org.fisco.bcos.sdk.transaction.model.dto.CallResponse; 13 | import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse; 14 | import org.fisco.bcos.sdk.transaction.model.exception.TransactionBaseException; 15 | 16 | import java.util.Arrays; 17 | import java.util.List; 18 | 19 | /** 20 | * ContractService 顶层类(基于fisco-sdk的合约交互) 21 | * // 目前能确定的是发送交易的调用者地址,就是client里面私钥指定的。 22 | * 23 | * @author: jzm 24 | * @date: 2024-03-22 11:08 25 | **/ 26 | 27 | public class ContractService 28 | { 29 | protected String contractAddress; 30 | protected String owner; 31 | protected String ABI; 32 | protected String BIN; 33 | 34 | protected String SM_BIN; 35 | 36 | private Client client; 37 | 38 | 39 | protected AssembleTransactionProcessor txProcessor; 40 | 41 | 42 | protected ContractService() 43 | { 44 | 45 | } 46 | 47 | protected void initConfig(String ABI, String BIN, String contractAddress) 48 | { 49 | this.ABI = ABI; 50 | this.BIN = BIN; 51 | this.contractAddress = contractAddress; 52 | } 53 | 54 | protected ContractService client(Client client) 55 | { 56 | this.client = client; 57 | return this; 58 | } 59 | 60 | protected void init() throws Exception 61 | { 62 | this.txProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(client, client.getCryptoSuite().getCryptoKeyPair()); 63 | } 64 | 65 | /** 66 | *

1.returnMes == Success,resVals.size() == 0 ;mes:null,vals :null // 成功没返回值

67 | *

2.returnMes == Success,resVals.size() > 0; mes:null,vals: resVals // 成功有返回值

68 | *

3.returnMes != Success,resVals == null; mes: 错误消息,vals: null // 出异常

69 | * 70 | * @param funcName 函数名 71 | * @param funcParams 函数参数 72 | * @return 73 | */ 74 | public ContractResponse sendCallGetValues(String from, String funcName, List funcParams) 75 | { 76 | CallResponse response = _setCallGetValues(from, funcName, funcParams); 77 | ContractResponse res = new ContractResponse(); 78 | if (response.getReturnMessage().equals("Success")) 79 | { 80 | JSONArray resAry = JSONUtil.parseArray(response.getValues()); 81 | if (resAry.size() != 0) 82 | { 83 | res.setVals(resAry); 84 | } 85 | return res; 86 | } 87 | // 调用合约错误 88 | res.setMes(response.getReturnMessage()); 89 | return res; 90 | } 91 | 92 | public ContractResponse sendCallGetValues(String funcName, List funcParams) 93 | { 94 | return sendCallGetValues(owner, funcName, funcParams); 95 | } 96 | 97 | 98 | protected CallResponse _setCallGetValues(String from, String funcName, List funcParams) 99 | { 100 | try 101 | { 102 | return this.txProcessor.sendCall(from, contractAddress, ABI, funcName, funcParams); 103 | } catch (ABICodecException e) // 转化为自定义响应 104 | { 105 | CallResponse callResponse = new CallResponse(); 106 | callResponse.setReturnMessage("ABI异常:" + e.getMessage()); 107 | return callResponse; 108 | } catch (TransactionBaseException e) 109 | { 110 | CallResponse callResponse = new CallResponse(); 111 | callResponse.setReturnMessage("合约异常:" + e.getMessage()); 112 | return callResponse; 113 | } 114 | } 115 | 116 | 117 | public ContractService deploy(List params) 118 | { 119 | try 120 | { 121 | TransactionResponse response = _deploy(params); 122 | this.contractAddress = response.getContractAddress(); 123 | this.owner = response.getTransactionReceipt().getFrom(); 124 | return this; 125 | } catch (ABICodecException e) 126 | { 127 | e.printStackTrace(); 128 | return null; 129 | } 130 | } 131 | 132 | 133 | private TransactionResponse _deploy(List params) throws ABICodecException 134 | { 135 | return this.txProcessor.deployAndGetResponse(ABI, getBin(client.getCryptoSuite()), params); 136 | } 137 | 138 | 139 | private String getBin(CryptoSuite cryptoSuite) 140 | { 141 | return (cryptoSuite.getCryptoTypeConfig() == CryptoType.ECDSA_TYPE ? BIN : SM_BIN); 142 | } 143 | 144 | // set、get 145 | public void setSM_BIN(String SM_BIN) 146 | { 147 | this.SM_BIN = SM_BIN; 148 | } 149 | 150 | protected void setAbiBinCon(String abi, String bin, String contractAddress) 151 | { 152 | this.initConfig(abi, bin, contractAddress); 153 | } 154 | 155 | public String getContractAddress() 156 | { 157 | return contractAddress; 158 | } 159 | 160 | static class Builder 161 | { 162 | 163 | private Client client; 164 | private String ABI; 165 | private String BIN; 166 | private String SM_BIN; 167 | private String contractAddress; 168 | private String ownerAddress; 169 | 170 | private Builder() 171 | { 172 | } 173 | 174 | public static Builder create() 175 | { 176 | return new Builder(); 177 | } 178 | 179 | public Builder client(Client client) 180 | { 181 | this.client = client; 182 | return this; 183 | } 184 | 185 | public Builder BIN(String BIN) 186 | { 187 | this.BIN = BIN; 188 | return this; 189 | } 190 | 191 | public Builder SM_BIN(String SM_BIN) 192 | { 193 | this.SM_BIN = SM_BIN; 194 | return this; 195 | } 196 | 197 | public Builder contractAddress(String conAdd) 198 | { 199 | this.contractAddress = conAdd; 200 | return this; 201 | } 202 | 203 | public Builder ownerAddress(String ownerAdd) 204 | { 205 | this.ownerAddress = ownerAdd; 206 | return this; 207 | } 208 | 209 | public Builder ABI(String ABI) 210 | { 211 | this.ABI = ABI; 212 | return this; 213 | } 214 | 215 | 216 | public ContractService execute() throws Exception 217 | { 218 | ContractService cs = new ContractService(); 219 | cs.setAbiBinCon(this.ABI, this.BIN, this.contractAddress); 220 | cs.client(this.client); 221 | cs.SM_BIN = this.SM_BIN; 222 | cs.owner = this.ownerAddress; 223 | cs.init(); 224 | return cs; 225 | } 226 | 227 | } 228 | 229 | } -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/config/fisco/service/WeFrontService.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.config.fisco.service; 2 | 3 | import cn.hutool.http.Header; 4 | import cn.hutool.http.HttpResponse; 5 | import cn.hutool.http.HttpUtil; 6 | import cn.hutool.json.JSONArray; 7 | import cn.hutool.json.JSONObject; 8 | import cn.hutool.json.JSONUtil; 9 | import com.jzm.backme.config.fisco.ContractConfig; 10 | import com.jzm.backme.config.fisco.FiscoConfig; 11 | import com.jzm.backme.config.fisco.contract.ContractErrCode; 12 | import com.jzm.backme.config.fisco.contract.ContractResponse; 13 | import com.jzm.backme.util.StringUtil; 14 | import lombok.extern.slf4j.Slf4j; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.stereotype.Component; 17 | 18 | import java.util.List; 19 | 20 | /** 21 | * 基于webase-front的合约交互 22 | * 23 | * @author: jzm 24 | * @date: 2024-04-16 15:53 25 | **/ 26 | 27 | @Component 28 | @Slf4j 29 | public class WeFrontService 30 | { 31 | public static final String callErr_pre = "Call contract return error:"; 32 | public static final String network_err = "区块链网络交互异常"; // 除了合约交互异常 33 | public static final String tran_message = "message"; 34 | public static final String tran_mes_suc = "Success"; 35 | 36 | @Autowired 37 | private FiscoConfig fiscoConfig; 38 | 39 | private String commonReq(String userAddress, String funcName, List funcParam) 40 | { 41 | JSONObject data = new JSONObject(); 42 | FiscoConfig f = fiscoConfig; 43 | ContractConfig c = f.getContract(); 44 | JSONArray abiJSON = JSONUtil.parseArray(c.getAbi()); 45 | data.putOpt("groupId", f.getGroupId()); 46 | data.putOpt("user", userAddress); 47 | data.putOpt("contractName", c.getName()); 48 | data.putOpt("funcName", funcName); 49 | data.putOpt("funcParam", funcParam); 50 | data.putOpt("contractAddress", c.getAddress()); 51 | data.putOpt("contractAbi", abiJSON); 52 | 53 | HttpResponse response = HttpUtil.createPost(f.getFrontUrl()).header(Header.CONTENT_TYPE, "application/json; charset=utf-8"). 54 | body(data.toString()).execute(); 55 | return response.body(); 56 | } 57 | 58 | public ContractResponse sendTranGetValues(String to, String funcName, List funcParam) 59 | { 60 | String res = commonReq(to, funcName, funcParam); 61 | JSONObject jsonObj = JSONUtil.parseObj(res); 62 | ContractResponse cr = new ContractResponse(); 63 | 64 | // 错误消息 65 | if (jsonObj.containsKey(tran_message) && jsonObj.getStr(tran_message).equals(tran_mes_suc)) 66 | { 67 | String output = jsonObj.getStr("output"); 68 | if (StringUtil.isNotEmpty(output)) 69 | { 70 | try 71 | { 72 | JSONArray resAry = JSONUtil.parseArray(output); 73 | cr.setVals(resAry); 74 | } catch (Exception e) 75 | { // 1个参数 76 | cr.setVals(new JSONArray().put(output)); 77 | } 78 | } 79 | return cr; 80 | } 81 | // 失败消息 82 | if (jsonObj.containsKey(tran_message)) 83 | { 84 | cr.setMes(jsonObj.getStr(tran_message)); 85 | return cr; 86 | } 87 | // 其余,没有返回交易凭证,但是报错了 88 | cr.setMes(network_err); 89 | log.error(JSONUtil.toJsonStr(jsonObj)); // 打印日志 90 | return cr; 91 | } 92 | 93 | public ContractResponse sendTranGetValues(String funcName, List funcParam) 94 | { 95 | String owner = fiscoConfig.getContract().getOwner(); 96 | return sendTranGetValues(owner, funcName, funcParam); 97 | } 98 | 99 | public ContractResponse sendCallGetValues(String to, String funcName, List funcParam) 100 | { 101 | String res = commonReq(to, funcName, funcParam); 102 | ContractResponse cr = new ContractResponse(); 103 | try 104 | { 105 | JSONArray jsonAry = JSONUtil.parseArray(res); 106 | if (jsonAry.size() == 1 && jsonAry.getStr(0).contains(callErr_pre)) 107 | { // 合约异常 108 | cr.setMes(jsonAry.getStr(0).substring(callErr_pre.length() + 1)); 109 | } 110 | if (jsonAry.size() != 0) 111 | { 112 | cr.setVals(jsonAry); 113 | } 114 | } catch (Exception e) 115 | { // 网络交互异常 116 | cr.setMes(network_err); 117 | log.error(JSONUtil.toJsonStr(e)); 118 | } 119 | return cr; 120 | } 121 | 122 | public ContractResponse sendCallGetValues(String funcName, List funcParam) 123 | { 124 | String owner = fiscoConfig.getContract().getOwner(); 125 | return sendCallGetValues(owner, funcName, funcParam); 126 | } 127 | 128 | 129 | public void commonWrite(String funcName, List funcParams) 130 | { 131 | String owner = fiscoConfig.getContract().getOwner(); 132 | commonWrite(owner, funcName, funcParams); 133 | } 134 | 135 | public void commonWrite(String callAdd, String funcName, List funcParams) 136 | { 137 | ContractResponse response; 138 | if (StringUtil.isNotEmpty(callAdd)) 139 | { 140 | response = sendTranGetValues(callAdd, funcName, funcParams); 141 | } else 142 | { 143 | response = sendTranGetValues(funcName, funcParams); 144 | } 145 | if (StringUtil.isNotEmpty(response.getMes())) 146 | { 147 | throw ContractErrCode.get(response.getMes()); 148 | } 149 | } 150 | 151 | public ContractResponse commonRead(String callAdd, String funcName, List funcParams) 152 | { 153 | ContractResponse response; 154 | if (StringUtil.isNotEmpty(callAdd)) 155 | { 156 | response = sendCallGetValues(callAdd, funcName, funcParams); 157 | } else 158 | { 159 | response = sendCallGetValues(funcName, funcParams); 160 | } 161 | if (StringUtil.isNotEmpty(response.getMes())) 162 | { 163 | throw ContractErrCode.get(response.getMes()); 164 | } 165 | return response; 166 | } 167 | 168 | public ContractResponse commonRead(String funcName, List funcParams) 169 | { 170 | String owner = fiscoConfig.getContract().getOwner(); 171 | return commonRead(owner, funcName, funcParams); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/config/redis/FastJson2JsonRedisSerializer.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.config.redis; 2 | 3 | import com.alibaba.fastjson2.JSON; 4 | import com.alibaba.fastjson2.JSONReader; 5 | import com.alibaba.fastjson2.JSONWriter; 6 | import com.alibaba.fastjson2.filter.Filter; 7 | import com.jzm.backme.constant.Constant; 8 | import org.springframework.data.redis.serializer.RedisSerializer; 9 | import org.springframework.data.redis.serializer.SerializationException; 10 | 11 | import java.nio.charset.Charset; 12 | 13 | /** 14 | * Redis使用FastJson序列化 15 | * 16 | * @author jzm 17 | */ 18 | public class FastJson2JsonRedisSerializer implements RedisSerializer 19 | { 20 | public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); 21 | 22 | static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(Constant.JSON_WHITELIST_STR); 23 | 24 | 25 | private Class clazz; 26 | 27 | public FastJson2JsonRedisSerializer(Class clazz) 28 | { 29 | super(); 30 | this.clazz = clazz; 31 | } 32 | 33 | @Override 34 | public byte[] serialize(T t) throws SerializationException 35 | { 36 | if (t == null) 37 | { 38 | return new byte[0]; 39 | } 40 | return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET); 41 | } 42 | 43 | @Override 44 | public T deserialize(byte[] bytes) throws SerializationException 45 | { 46 | if (bytes == null || bytes.length <= 0) 47 | { 48 | return null; 49 | } 50 | String str = new String(bytes, DEFAULT_CHARSET); 51 | 52 | return JSON.parseObject(str, clazz, AUTO_TYPE_FILTER); 53 | } 54 | } -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/config/redis/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.config.redis; 2 | 3 | import org.springframework.cache.annotation.CachingConfigurerSupport; 4 | import org.springframework.cache.annotation.EnableCaching; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.data.redis.connection.RedisConnectionFactory; 8 | import org.springframework.data.redis.core.RedisTemplate; 9 | import org.springframework.data.redis.core.script.DefaultRedisScript; 10 | import org.springframework.data.redis.serializer.StringRedisSerializer; 11 | 12 | /** 13 | * redis配置 14 | * 15 | * @author jzm 16 | */ 17 | @Configuration 18 | @EnableCaching 19 | public class RedisConfig extends CachingConfigurerSupport 20 | { 21 | @Bean 22 | @SuppressWarnings(value = {"unchecked", "rawtypes"}) 23 | // 设置key、value的序列化方式 24 | public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) 25 | { 26 | RedisTemplate template = new RedisTemplate<>(); 27 | template.setConnectionFactory(connectionFactory); 28 | 29 | FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); 30 | 31 | // 使用StringRedisSerializer来序列化和反序列化redis的key值 32 | template.setKeySerializer(new StringRedisSerializer()); 33 | template.setValueSerializer(serializer); 34 | 35 | // Hash的key也采用StringRedisSerializer的序列化方式 36 | template.setHashKeySerializer(new StringRedisSerializer()); 37 | template.setHashValueSerializer(serializer); 38 | 39 | template.afterPropertiesSet(); 40 | return template; 41 | } 42 | 43 | @Bean 44 | public DefaultRedisScript limitScript() 45 | { 46 | DefaultRedisScript redisScript = new DefaultRedisScript<>(); 47 | redisScript.setScriptText(limitScriptText()); 48 | redisScript.setResultType(Long.class); 49 | return redisScript; 50 | } 51 | 52 | /** 53 | * 限流脚本 54 | */ 55 | private String limitScriptText() 56 | { 57 | return "local key = KEYS[1]\n" + 58 | "local count = tonumber(ARGV[1])\n" + 59 | "local time = tonumber(ARGV[2])\n" + 60 | "local current = redis.call('get', key);\n" + 61 | "if current and tonumber(current) > count then\n" + 62 | " return tonumber(current);\n" + 63 | "end\n" + 64 | "current = redis.call('incr', key)\n" + 65 | "if tonumber(current) == 1 then\n" + 66 | " redis.call('expire', key, time)\n" + 67 | "end\n" + 68 | "return tonumber(current);"; 69 | } 70 | } -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/constant/CacheConstant.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.constant; 2 | 3 | /** 4 | * 缓存的key 常量 5 | * 6 | * @author ruoyi 7 | */ 8 | public class CacheConstant 9 | { 10 | 11 | /** 12 | * 登录用户 redis key 13 | */ 14 | public static final String LOGIN_USER_KEY = "login_users:"; 15 | 16 | /** 17 | * 验证码 redis key 18 | */ 19 | public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; 20 | 21 | 22 | /** 23 | * 防重提交 redis key 24 | */ 25 | public static final String REPEAT_SUBMIT_KEY = "repeat_submit:"; 26 | 27 | /** 28 | * 限流 redis key 29 | */ 30 | public static final String RATE_LIMIT_KEY = "rate_limit:"; 31 | 32 | /** 33 | * 登录账户密码错误次数 redis key 34 | */ 35 | // 剩余次数 36 | public static final String PWD_ERR_REM_CNT_KEY = "pwd_err_rem_cnt:"; 37 | public static final String PWD_ERR_MAX_CNT_KEY = "pwd_err_max_cnt:"; 38 | } 39 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/constant/Constant.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.constant; 2 | 3 | public class Constant 4 | { 5 | 6 | 7 | /** 8 | * 响应成功、失败标识 9 | */ 10 | public static final int OK_CODE = 200; 11 | public static final int ERROR_CODE = 400; 12 | public static final int WARN_CODE = 300; 13 | public static final String OK_MES = "ok"; 14 | public static final String FAIL_MES = "fail"; 15 | 16 | public static String UTF_8 = "utf-8"; 17 | 18 | 19 | /** 20 | * 密码错误允许最大次数 21 | */ 22 | public static final Integer PWD_ERR_MAX_CNT = 5; 23 | 24 | /** 25 | * token自定义字段 26 | */ 27 | public static String USER_ID = "userId"; 28 | public static String PASSWORD = "password"; 29 | 30 | /** 31 | * 产品相关 32 | */ 33 | public static final int CATEGORY_NAME_MIN_LEN = 1; 34 | public static final int CATEGORY_NAME_MAX_LEN = 5; 35 | 36 | 37 | /** 38 | * 令牌前缀 39 | */ 40 | public static final String TOKEN_PREFIX = "Bearer"; 41 | 42 | 43 | /** 44 | * 前缀 45 | */ 46 | public static final String HTTPS_PREFIX = "https://"; 47 | 48 | public static final String HTTP_PREFIX = "http://"; 49 | 50 | public static int In_Code_Pre_Len = 6; // 就是随机的6位数字。 51 | 52 | 53 | /** 54 | * 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全) 55 | */ 56 | public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.jzm" }; 57 | 58 | /** 59 | * 排除拦截列表 60 | */ 61 | public static final String[] ExclusionList = new String[]{ 62 | "/test","/login","/register","/get/captcha", 63 | "/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs" 64 | }; 65 | 66 | /** 67 | * 公共响应状态(类似于 启用 0 禁用 1的判别) 68 | */ 69 | public static final String Zero = "0"; 70 | public static final String One = "1"; 71 | 72 | 73 | public static final String Contract_0 = "0"; // 预发布 74 | public static final String Contract_1 = "1"; // 签署-未生效 75 | public static final String Contract_2 = "2"; // 生效 76 | public static final String Contract_3 = "3"; // 停止 77 | 78 | 79 | 80 | 81 | } -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/constant/HeaderConstant.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.constant; 2 | 3 | /** 4 | * 请求头常量 5 | * 6 | * @author: jzm 7 | * @date: 2024-02-28 14:40 8 | **/ 9 | 10 | public class HeaderConstant 11 | { 12 | 13 | 14 | /** 15 | * 请求头 16 | */ 17 | public static final String CAPTCHA_KEY = "captcha-key"; 18 | public static final String CAPTCHA_VAL = "captcha-val"; 19 | public static final String AUTHORIZATION = "Authorization"; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/constant/HttpStatus.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.constant; 2 | 3 | 4 | import com.jzm.backme.model.AjaxResult; 5 | 6 | /** 7 | * http错误状态的常量 8 | * 9 | * @author: jzm 10 | * @date: 2024-02-27 08:44 11 | **/ 12 | 13 | public class HttpStatus extends AjaxResult 14 | { 15 | public static final HttpStatus PASSWORD_NOT_MATCH = new HttpStatus(401,"密码长度不匹配!"); 16 | public static final HttpStatus PASSWORD_RETRY_LIMIT_EXCEED(String blockedTime){ 17 | return new HttpStatus(403,"密码输入错误次数达到上限,剩余解禁时间:" + blockedTime); 18 | } 19 | public static final HttpStatus PASSWORD_REMAIN_INPUT_COUNT(int count) { 20 | return new HttpStatus(402,"密码输入错误,当前剩余输入当前次数:" + count); 21 | } 22 | 23 | // 密码重复提交最大次数 24 | public static final HttpStatus USERNAME_NOT_MATCH= new HttpStatus(404,"用户名长度不匹配!"); 25 | public static final HttpStatus USER_NOT_EXISTS= new HttpStatus(405,"用户不存在!"); 26 | public static final HttpStatus USER_DELETE= new HttpStatus(406,"用户已经注销!"); 27 | public static final HttpStatus CAPTCHA_CHECK_FAILED= new HttpStatus(407,"验证码错误!"); 28 | public static final HttpStatus CAPTCHA_EXPIRED= new HttpStatus(407,"验证码已经过期!"); 29 | public static final HttpStatus USER_BLOCKED= new HttpStatus(407,"用户已经被锁定!"); 30 | public static final HttpStatus USER_NOT_LOGIN= new HttpStatus(408, "用户没登录!"); 31 | public static final HttpStatus USER_LOGIN_EXPIRED= new HttpStatus(409, "用户登录过期,需要重新登录!"); 32 | public static final HttpStatus USER_TOKEN_ILLICIT= new HttpStatus(410,"用户令牌格式不对!" ); 33 | public static final HttpStatus PASSWORD_OR_PHONE_NOT_EMPTY= new HttpStatus(411, "用户密码和电话号是不能为空!"); 34 | public static final HttpStatus PHONE_NOT_MATCH= new HttpStatus(412, "电话输入格式不对!"); 35 | public static final HttpStatus USER_EXISTS= new HttpStatus(413, "用户已经存在!"); 36 | public static final HttpStatus PHONE_EXISTS= new HttpStatus(414,"该电话号已经绑定其他账户!" ); 37 | public static final HttpStatus EMAIL_NOT_MATCH= new HttpStatus(415, "邮箱格式不匹配!"); 38 | public static final HttpStatus EMAIL_EXISTS= new HttpStatus(416, "该邮箱已经绑定其他账户!"); 39 | public static final HttpStatus PASSWORD_OR_USERNAME_NOT_EMPTY= new HttpStatus(417, "用户名/密码不能为空"); 40 | public static final HttpStatus PASSWORD_EXISTS = new HttpStatus(418,"该密码已经绑定其他账户"); 41 | public static final HttpStatus REQ_HED_PAM_NOT_ENOUGH = new HttpStatus(419,"请求头部参数不全!"); 42 | public static final HttpStatus OFF_LIMIT_EXCEEDED = new HttpStatus(420,"用户离线超时,请重新登录!"); 43 | 44 | private HttpStatus(int code, String mes){ 45 | super(null,code,mes); 46 | } 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/constant/UserConstant.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.constant; 2 | 3 | public class UserConstant 4 | { 5 | 6 | /** 用户状态 */ 7 | /** 8 | * 启用 9 | */ 10 | public static final String NORMAL = "0"; 11 | 12 | /** 13 | * 禁用 14 | */ 15 | public static final String EXCEPTION = "1"; 16 | 17 | /** 18 | * 用户名长度限制 19 | */ 20 | public static final int USERNAME_MIN_LENGTH = 2; 21 | public static final int USERNAME_MAX_LENGTH = 20; 22 | 23 | /** 24 | * 密码长度限制 25 | */ 26 | public static final int PASSWORD_MIN_LENGTH = 5; 27 | public static final int PASSWORD_MAX_LENGTH = 20; 28 | 29 | /** 30 | * 手机号码格式限制 31 | */ 32 | public static final String MOBILE_PHONE_NUMBER_PATTERN = "^0{0,1}(13[0-9]|15[0-9]|14[0-9]|18[0-9])[0-9]{8}$"; 33 | 34 | /** 35 | * 邮箱格式限制 36 | */ 37 | public static final String EMAIL_PATTERN = "^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?"; 38 | 39 | /** 40 | * 排除拦截列表 41 | */ 42 | public static final String[] ExclusionList = new String[]{ 43 | "/test", "/login", "/register", "/get/captcha", 44 | "/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/v2/**", "/*/api-docs" 45 | }; 46 | 47 | public static final Integer LiveTime = 5; // 密码校验机制存活时间 48 | public static final Integer PwdBlockedTime = 10; // 密码输入错误锁定时间 49 | } 50 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/context/UserContext.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.context; 2 | 3 | import com.jzm.backme.domain.User; 4 | 5 | /** 6 | * @author: jzm 7 | * @date: 2024-04-14 15:41 8 | **/ 9 | 10 | public class UserContext 11 | { 12 | 13 | private static ThreadLocal local = new ThreadLocal<>(); 14 | 15 | public static User get(){ 16 | return local.get(); 17 | } 18 | 19 | public static void set(User user){ 20 | local.set(user); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/controller/CaptchaController.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.controller; 2 | 3 | import com.jzm.backme.model.AjaxResult; 4 | import com.jzm.backme.service.CaptchaService; 5 | import io.swagger.annotations.ApiOperation; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | /** 12 | * 验证码控制器 13 | * 14 | * @author: jzm 15 | * @date: 2024-03-01 19:52 16 | **/ 17 | @RestController 18 | public class CaptchaController 19 | { 20 | @Autowired 21 | private CaptchaService captchaService; 22 | 23 | @RequestMapping(path = "/get/captcha", method = RequestMethod.GET) 24 | @ApiOperation(value = "获取验证码") 25 | public AjaxResult getCaptcha() 26 | { 27 | return captchaService.getCaptcha(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/controller/ContractController.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.controller; 2 | 3 | import cn.hutool.core.util.IdUtil; 4 | import com.jzm.backme.constant.Constant; 5 | import com.jzm.backme.constant.UserConstant; 6 | import com.jzm.backme.controller.base.BaseController; 7 | import com.jzm.backme.domain.Contract; 8 | import com.jzm.backme.domain.House; 9 | import com.jzm.backme.domain.User; 10 | import com.jzm.backme.model.AjaxResult; 11 | import com.jzm.backme.model.to.contract.ContractQueryTo; 12 | import com.jzm.backme.model.vo.ContractVo; 13 | import com.jzm.backme.service.*; 14 | import com.jzm.backme.util.DateUtil; 15 | import com.jzm.backme.util.NotEmptyUtil; 16 | import com.jzm.backme.util.StringUtil; 17 | import com.jzm.backme.util.user.UserUtil; 18 | import io.swagger.annotations.ApiOperation; 19 | import org.springframework.web.bind.annotation.RequestBody; 20 | import org.springframework.web.bind.annotation.RequestMapping; 21 | import org.springframework.web.bind.annotation.RequestMethod; 22 | import org.springframework.web.bind.annotation.RestController; 23 | 24 | import javax.annotation.Resource; 25 | import java.time.LocalDateTime; 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | /** 30 | *

31 | * 合同表 -- 存储合同信息 前端控制器 32 | *

33 | * 34 | * @author qhx2004 35 | * @since 2024-04-14 36 | */ 37 | // 预发布 38 | // 签署未生效 39 | // 签署已经生效 40 | // 签署-停止 41 | @RestController 42 | @RequestMapping("/contract") 43 | public class ContractController extends BaseController 44 | { 45 | 46 | 47 | @Resource 48 | private ContractService contractService; 49 | 50 | @Resource 51 | private MainContractService mainContractService; 52 | 53 | @Resource 54 | private LoginService loginService; 55 | 56 | @Resource 57 | private UserService userService; 58 | 59 | @Resource 60 | private HouseService houseService; 61 | 62 | @RequestMapping(value = "/create", method = RequestMethod.POST) 63 | public AjaxResult create(@RequestBody Contract contract) 64 | { 65 | loginService.checkLandlord(); 66 | contract.setLandlordId(loginService.getUserId()); 67 | 68 | String errPre = "添加合同失败:"; 69 | String errMes = NotEmptyUtil.checkEmptyFiled(contract); 70 | if (StringUtil.isNotEmpty(errMes)) 71 | { 72 | return error(errPre + errMes); 73 | } 74 | House house = houseService.getById(contract.getHouseId()); 75 | if (StringUtil.isEmpty(house)) 76 | { 77 | return error(errPre + "输入的房屋编号不存在"); 78 | } 79 | String uuid = IdUtil.fastSimpleUUID(); 80 | contract.setContractNum(uuid); 81 | boolean end = false; 82 | while (!end) 83 | { // 唯一序列号 84 | end = contractService.save(contract); 85 | } 86 | return success(); 87 | } 88 | 89 | @RequestMapping(value = "/getAll", method = RequestMethod.POST) 90 | public AjaxResult getAll(@RequestBody ContractQueryTo contractQueryTo) 91 | { 92 | int page = contractQueryTo.getPage(); 93 | int pageSize = contractQueryTo.getPageSize(); 94 | List contractVos = startOrderPage(page, pageSize, ContractVo.class, () -> 95 | { 96 | if (loginService.isLandlord()) 97 | { // 房东只能看到自己的合同 98 | contractQueryTo.setLandlordId(loginService.getUserId()); 99 | } 100 | contractService.getAll(contractQueryTo); 101 | }); 102 | return getAll(contractVos, contractQueryTo.getType()); 103 | } 104 | 105 | private AjaxResult getAll(List contractVos, String type) 106 | { 107 | for (ContractVo contractVo : contractVos) 108 | { 109 | Long contractId = contractVo.getContractId(); 110 | mainContractService.getContract(contractId, contractVo); 111 | } 112 | if (StringUtil.isEmpty(type)) 113 | { 114 | return toAjax(contractVos); 115 | } 116 | ArrayList resList = new ArrayList<>(); 117 | // 格局要求响应类型,获得交易参数 118 | for (ContractVo contractVo : contractVos) 119 | { 120 | String sign = contractVo.getSign(); 121 | String begin = contractVo.getBegin(); 122 | String stop = contractVo.getStop(); 123 | // 预发布 124 | if (StringUtil.equals(Constant.Contract_0, type) && StringUtil.equals(sign, Constant.Zero)) 125 | { 126 | resList.add(contractVo); 127 | } 128 | // 签署-未生效 129 | if (StringUtil.equals(Constant.Contract_1, type) && StringUtil.equals(sign, Constant.One) && 130 | StringUtil.equals(begin, Constant.Zero)) 131 | { 132 | resList.add(contractVo); 133 | } 134 | // 签署-生效 135 | if (StringUtil.equals(Constant.Contract_2, type) && StringUtil.equals(begin, Constant.One) 136 | && StringUtil.equals(stop, Constant.Zero)) 137 | { 138 | resList.add(contractVo); 139 | } 140 | // 签署-终止 141 | if (StringUtil.equals(Constant.Contract_3, type) && 142 | StringUtil.equals(stop, Constant.One)) 143 | { 144 | resList.add(contractVo); 145 | } 146 | } 147 | return success(resList, resList.size()); 148 | } 149 | 150 | 151 | @RequestMapping(value = "/sign", method = RequestMethod.POST) 152 | @ApiOperation("签署合同") 153 | public AjaxResult signContract(@RequestBody ContractVo contractVo) 154 | { 155 | loginService.checkTenant(); 156 | String errPre = "签署合同失败:"; 157 | String errMes = NotEmptyUtil.checkEmptyFiled(contractVo, "houseId"); 158 | if (StringUtil.isNotEmpty(errMes)) 159 | { 160 | return error(errPre + errMes); 161 | } 162 | if (!UserUtil.verifyAccount(contractVo.getTenant())) 163 | { 164 | return error(errPre + "租客地址不是合法区块链网络地址"); 165 | } 166 | if (!StringUtil.equals(contractVo.getRent(), contractVo.getEarnest())) 167 | { 168 | return error(errPre + "规定保证金应等于租金"); 169 | } 170 | LocalDateTime beginEndTime = contractVo.getBeginEndTime(); 171 | LocalDateTime endTime = DateUtil.addTime(LocalDateTime.now(), 30); 172 | if (DateUtil.compare(beginEndTime, endTime) < 0) 173 | { 174 | return error("合同结束日期,至少大于当时间1个月"); 175 | } 176 | // 设置房东地址 177 | User landlord = userService.getById(contractVo.getLandlordId()); 178 | contractVo.setLandlord(landlord.getUser()); 179 | contractVo.setSignTime(LocalDateTime.now()); 180 | contractVo.setSign(UserConstant.EXCEPTION); 181 | mainContractService.signContract(contractVo); 182 | boolean end = contractService.updateById(contractVo); 183 | return toAjax(end); 184 | } 185 | 186 | 187 | @RequestMapping(value = "/tenantPrestore", method = RequestMethod.POST) 188 | @ApiOperation("租客预存赔偿金") 189 | public AjaxResult tenantPrestore(@RequestBody Contract contract) 190 | { 191 | loginService.checkTenant(); 192 | String address = loginService.getAccountAddress(); 193 | mainContractService.tenantPrestore(address, contract.getContractId()); 194 | return success(); 195 | } 196 | 197 | 198 | @RequestMapping(value = "/landlordPrestore", method = RequestMethod.POST) 199 | @ApiOperation("房东预存赔偿金") 200 | public AjaxResult landlordPrestore(@RequestBody Contract contract) 201 | { 202 | loginService.checkLandlord(); 203 | String address = loginService.getAccountAddress(); 204 | mainContractService.landlordPrestore(address, contract.getContractId()); 205 | return success(); 206 | } 207 | 208 | @RequestMapping(value = "/backPrestoreMoney", method = RequestMethod.POST) 209 | @ApiOperation("退回预存的钱") 210 | public AjaxResult backPrestoreMoney(@RequestBody Contract contract) 211 | { 212 | String address = loginService.getAccountAddress(); 213 | mainContractService.backPrestoreMoney(address, contract.getContractId()); 214 | return success(); 215 | } 216 | 217 | 218 | @RequestMapping(value = "/stop", method = RequestMethod.POST) 219 | @ApiOperation("终止合同") 220 | public AjaxResult stopContract(@RequestBody Contract contract) 221 | { 222 | String errPre = "终止合同失败:"; 223 | if (!loginService.isTenant() && !loginService.isTenant()) 224 | { 225 | return error(errPre + "操作者只能是租客/房东"); 226 | } 227 | String address = loginService.getAccountAddress(); 228 | if (loginService.isTenant()) 229 | { 230 | mainContractService.stopContractTenant(address, contract.getContractId()); 231 | } else 232 | { 233 | mainContractService.stopContractLandlord(address, contract.getContractId()); 234 | } 235 | // 报错下面走不了 236 | Contract newCon = new Contract(); 237 | newCon.setContractId(contract.getContractId()); 238 | newCon.setStopTime(LocalDateTime.now()); 239 | contractService.updateById(newCon); 240 | return success(); 241 | } 242 | 243 | 244 | } 245 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/controller/HouseController.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.controller; 2 | 3 | import com.jzm.backme.controller.base.BaseController; 4 | import com.jzm.backme.model.to.house.HouseAddTo; 5 | import com.jzm.backme.model.to.house.HouseDeleteTo; 6 | import com.jzm.backme.model.to.house.HousePassTo; 7 | import com.jzm.backme.model.to.house.HouseQueryTo; 8 | import com.jzm.backme.domain.House; 9 | import com.jzm.backme.model.AjaxResult; 10 | import com.jzm.backme.model.vo.HouseVo; 11 | import com.jzm.backme.service.HouseService; 12 | import com.jzm.backme.service.LoginService; 13 | import com.jzm.backme.service.MainContractService; 14 | import com.jzm.backme.util.NotEmptyUtil; 15 | import com.jzm.backme.util.StringUtil; 16 | import com.jzm.backme.util.user.UserUtil; 17 | import io.swagger.annotations.ApiOperation; 18 | import org.springframework.web.bind.annotation.RequestBody; 19 | import org.springframework.web.bind.annotation.RequestMapping; 20 | import org.springframework.web.bind.annotation.RequestMethod; 21 | import org.springframework.web.bind.annotation.RestController; 22 | 23 | import javax.annotation.Resource; 24 | import java.util.List; 25 | 26 | /** 27 | *

28 | * 房屋表 -- 存储房屋信息 前端控制器 29 | *

30 | * 31 | * @author qhx2004 32 | * @since 2024-04-14 33 | */ 34 | @RestController 35 | @RequestMapping("/house") 36 | public class HouseController extends BaseController 37 | { 38 | @Resource 39 | private HouseService houseService; 40 | 41 | @Resource 42 | private MainContractService mainContractService; 43 | 44 | @Resource 45 | private LoginService loginService; 46 | 47 | @RequestMapping(value = "/create",method = RequestMethod.POST) 48 | public AjaxResult create(@RequestBody HouseAddTo hdT){ 49 | loginService.checkLandlord(); 50 | hdT.setLandlordId(loginService.getUserId()); 51 | String errPre = "添加房屋失败:"; 52 | String errMes = NotEmptyUtil.checkEmptyFiled(hdT); 53 | if(StringUtil.isNotEmpty(errMes)){ 54 | return error(errPre + errMes); 55 | } 56 | if(!UserUtil.verifyPhone(hdT.getLinkPhone())){ 57 | return error(errPre + "联系人电话格式不对"); 58 | } 59 | if(!UserUtil.verifyUsername(hdT.getLinkMan())){ 60 | return error(errPre + "联系人名称格式不对"); 61 | } 62 | boolean end = houseService.save(hdT); 63 | if(end){ // 上链 64 | mainContractService.addHouse(loginService.getAccountAddress(),hdT.getHouseId(),hdT.getPassword()); 65 | } 66 | return toAjax(end); 67 | } 68 | 69 | 70 | @RequestMapping(value = "/getAll",method = RequestMethod.POST) 71 | public AjaxResult getAll(@RequestBody HouseQueryTo houseQueryTo){ 72 | int page = houseQueryTo.getPage(); 73 | int pageSize = houseQueryTo.getPageSize(); 74 | List houseVos = startOrderPage(page, pageSize, HouseVo.class,() -> 75 | { 76 | houseService.getAll(houseQueryTo); 77 | }); 78 | return getAll(houseVos); 79 | } 80 | 81 | private AjaxResult getAll(List houseVos) 82 | { 83 | for (HouseVo houseVo : houseVos) 84 | { 85 | Long houseId = houseVo.getHouseId(); 86 | String password = mainContractService.getHouseAdmin(houseId); 87 | houseVo.setPassword(password); 88 | } 89 | return success(houseVos,houseVos.size()); 90 | } 91 | 92 | @RequestMapping(value = "/updatePass",method = RequestMethod.POST) 93 | @ApiOperation("修改房屋密码") 94 | public AjaxResult updatePass(@RequestBody HousePassTo housePassTo){ 95 | String errPre = "修改房屋密码失败:"; 96 | Long houseId = housePassTo.getHouseId(); 97 | String password = mainContractService.getHouseAdmin(houseId); 98 | if(StringUtil.equals(password,housePassTo.getOldPass())) 99 | { 100 | return error(errPre+"输入的旧密码与原先密码不一致!"); 101 | } 102 | mainContractService.changeHousePass(houseId,password); 103 | return success(); 104 | } 105 | 106 | @RequestMapping(value = "/delete",method = RequestMethod.POST) 107 | public AjaxResult delete(@RequestBody HouseDeleteTo houseDeleteTo){ 108 | List houseIds = houseDeleteTo.getHouseIds(); 109 | boolean end = houseService.removeBatchByIds(houseIds); 110 | return toAjax(end); 111 | } 112 | 113 | @RequestMapping(value = "/updateStatus",method = RequestMethod.POST) 114 | @ApiOperation("修改房屋状态") 115 | public AjaxResult updateStatus(@RequestBody House house){ 116 | boolean end = houseService.updateStatus(house); 117 | return toAjax(end); 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/controller/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.controller; 2 | 3 | import cn.hutool.core.bean.BeanUtil; 4 | import cn.hutool.crypto.digest.MD5; 5 | import com.jzm.backme.constant.CacheConstant; 6 | import com.jzm.backme.constant.HttpStatus; 7 | import com.jzm.backme.controller.base.BaseController; 8 | import com.jzm.backme.domain.Role; 9 | import com.jzm.backme.domain.User; 10 | import com.jzm.backme.model.AjaxResult; 11 | import com.jzm.backme.model.to.LoginTo; 12 | import com.jzm.backme.model.to.user.PassTo; 13 | import com.jzm.backme.model.vo.UserVo; 14 | import com.jzm.backme.service.LoginService; 15 | import com.jzm.backme.service.MainContractService; 16 | import com.jzm.backme.service.UserService; 17 | import com.jzm.backme.util.NotEmptyUtil; 18 | import com.jzm.backme.util.StringUtil; 19 | import com.jzm.backme.util.TokenUtil; 20 | import com.jzm.backme.util.redis.RedisCache; 21 | import com.jzm.backme.util.user.UserUtil; 22 | import io.swagger.annotations.ApiOperation; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.web.bind.annotation.RequestBody; 25 | import org.springframework.web.bind.annotation.RequestMapping; 26 | import org.springframework.web.bind.annotation.RequestMethod; 27 | import org.springframework.web.bind.annotation.RestController; 28 | 29 | import java.util.HashMap; 30 | 31 | 32 | /** 33 | * @author: jzm 34 | * @date: 2024-04-14 15:50 35 | **/ 36 | 37 | @RestController 38 | public class LoginController extends BaseController 39 | { 40 | @Autowired 41 | private UserService userService; 42 | 43 | @Autowired 44 | private RedisCache redisCache; 45 | 46 | @Autowired 47 | private LoginService loginService; 48 | 49 | @Autowired 50 | private MainContractService mainContractService; 51 | 52 | 53 | @RequestMapping(path = "/login", method = RequestMethod.POST) 54 | public AjaxResult login(@RequestBody LoginTo loginTo) 55 | { 56 | // 校验验证码 57 | HttpStatus errStatus = loginService.verifyCaptcha(); 58 | if (StringUtil.isNotEmpty(errStatus)) 59 | { 60 | return errStatus; 61 | } 62 | String phone = loginTo.getPhone(); 63 | String password = loginTo.getPassword(); 64 | String errMes = NotEmptyUtil.checkEmptyFiled(loginTo); 65 | if (StringUtil.isNotEmpty(errMes)) 66 | { 67 | return AjaxResult.error(errMes); 68 | } 69 | if (!UserUtil.verifyPhone(phone)) 70 | { 71 | return HttpStatus.PHONE_NOT_MATCH; 72 | } 73 | if (!UserUtil.verifyPassword(password)) 74 | { 75 | return HttpStatus.PASSWORD_NOT_MATCH; 76 | } 77 | User user = userService.getOne(phone, password); 78 | if (StringUtil.isEmpty(user)) 79 | { 80 | return HttpStatus.USER_NOT_EXISTS; 81 | } 82 | if (UserUtil.isDisable(user.getStatus())) 83 | { 84 | return HttpStatus.USER_BLOCKED; 85 | } 86 | 87 | // 生成token、缓存redis 88 | Long userId = user.getUserId(); 89 | Role role = userService.getRole(userId); 90 | UserVo userVo = new UserVo(); 91 | BeanUtil.copyProperties(role, userVo); 92 | BeanUtil.copyProperties(user, userVo); 93 | int balance = mainContractService.getBalance(user.getUser()); 94 | userVo.setBalance(balance); 95 | // 缓存用户信息 96 | redisCache.setCacheObject(CacheConstant.LOGIN_USER_KEY + userId, userVo); 97 | String token = TokenUtil.createToken(userId); 98 | HashMap res = new HashMap<>(); 99 | res.put("token", token); 100 | return HttpStatus.success(res); 101 | } 102 | 103 | 104 | @RequestMapping(path = "/logout", method = RequestMethod.POST) 105 | public AjaxResult logout() 106 | { 107 | Long userId = loginService.getUserId(); 108 | if (StringUtil.isEmpty(userId)) 109 | { 110 | return AjaxResult.success("账户退出成功"); 111 | } 112 | redisCache.deleteObject(CacheConstant.LOGIN_USER_KEY + userId); 113 | return AjaxResult.success("账户退出成功"); 114 | } 115 | 116 | @RequestMapping(path = "/getUserInfo", method = RequestMethod.GET) 117 | public AjaxResult getUserInfo() 118 | { 119 | Long userId = loginService.getUserId(); 120 | User user = redisCache.getCacheObject(CacheConstant.LOGIN_USER_KEY + userId); 121 | return AjaxResult.success(user); 122 | } 123 | 124 | 125 | @RequestMapping(path = "/updateUser", method = RequestMethod.POST) 126 | public AjaxResult updateUser(@RequestBody User user) 127 | { 128 | String phone = user.getPhone(); 129 | String username = user.getUsername(); 130 | 131 | if (!StringUtil.isAllNotEmpty(username, phone)) 132 | { 133 | return error("用户名、电话为必填项!"); 134 | } else if (!UserUtil.verifyPhone(phone)) 135 | { 136 | return error("电话格式不正确!"); 137 | } else if (!userService.checkPhoneUpUnique(phone)) 138 | { 139 | return error("电话已经被其他账户绑定!"); 140 | } 141 | boolean end = userService.updateById(user); 142 | return toAjax(end); 143 | } 144 | 145 | 146 | @RequestMapping(path = "/updatePass", method = RequestMethod.POST) 147 | @ApiOperation("用户修改密码") 148 | public AjaxResult updatePassword(@RequestBody PassTo passTo) 149 | { 150 | String oldPassword = passTo.getOldPassword(); 151 | String newPassword = passTo.getNewPassword(); 152 | String errPre = "用户修改密码错误:"; 153 | if (StringUtil.isEmpty(oldPassword) || StringUtil.isEmpty(newPassword)) 154 | { 155 | return error(errPre + "用户密码不能为空"); 156 | } 157 | if (!UserUtil.verifyPassword(oldPassword)) 158 | { 159 | return error(errPre + "旧密码格式不对!"); 160 | } 161 | if (!UserUtil.verifyPassword(newPassword)) 162 | { 163 | return error(errPre + "新密码格式不对!"); 164 | } 165 | if (StringUtil.equals(newPassword, oldPassword)) 166 | { 167 | return success(); 168 | } 169 | if (!userService.isPasswordExists(oldPassword)) 170 | { 171 | return error(errPre + "旧密码不存在!"); 172 | } 173 | if (!userService.checkPassUnique(newPassword)) 174 | { 175 | return error(errPre + "新密码已经被其他用户注册!"); 176 | } 177 | boolean end = userService.updatePass(passTo); 178 | return toAjax(end); 179 | } 180 | 181 | 182 | } 183 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/controller/PaymentController.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.controller; 2 | 3 | import com.jzm.backme.controller.base.BaseController; 4 | import com.jzm.backme.domain.Contract; 5 | import com.jzm.backme.model.AjaxResult; 6 | import com.jzm.backme.model.to.payment.PaymentAddTo; 7 | import com.jzm.backme.model.to.payment.PaymentQueryTo; 8 | import com.jzm.backme.model.vo.PaymentVo; 9 | import com.jzm.backme.service.ContractService; 10 | import com.jzm.backme.service.LoginService; 11 | import com.jzm.backme.service.MainContractService; 12 | import com.jzm.backme.service.PaymentService; 13 | import com.jzm.backme.util.StringUtil; 14 | import org.springframework.web.bind.annotation.RequestBody; 15 | import org.springframework.web.bind.annotation.RequestMapping; 16 | import org.springframework.web.bind.annotation.RequestMethod; 17 | import org.springframework.web.bind.annotation.RestController; 18 | 19 | import javax.annotation.Resource; 20 | import java.util.List; 21 | 22 | /** 23 | *

24 | * 缴纳记录表 -- 记录租金缴纳信息 前端控制器 25 | *

26 | * 27 | * @author qhx2004 28 | * @since 2024-04-14 29 | */ 30 | @RestController 31 | @RequestMapping("/payment") 32 | public class PaymentController extends BaseController 33 | { 34 | 35 | @Resource 36 | private ContractService contractService; 37 | 38 | @Resource 39 | private PaymentService paymentService; 40 | 41 | @Resource 42 | private MainContractService mainContractService; 43 | 44 | @Resource 45 | private LoginService loginService; 46 | 47 | 48 | @RequestMapping(value = "/create",method = RequestMethod.POST) 49 | public AjaxResult create(@RequestBody PaymentAddTo pt){ 50 | loginService.checkTenant(); 51 | String errPre = "添加缴纳记录错误:"; 52 | String address = loginService.getAccountAddress(); 53 | Contract contract = contractService.getById(pt.getContractId()); 54 | if(StringUtil.isEmpty(contract)){ 55 | return error(errPre + "合同编号不存在"); 56 | } 57 | if(StringUtil.isNotEmpty(contract.getStopTime())){ 58 | return error(errPre + "合同已经终止"); 59 | } 60 | pt.setPayer(address); 61 | pt.setPayerId(loginService.getUserId()); 62 | pt.setContractNum(contract.getContractNum()); 63 | if(pt.getMoney() <= 10){ 64 | return error(errPre +"缴费金额不能小于10元"); 65 | } 66 | boolean end = paymentService.save(pt); 67 | if(end){ 68 | mainContractService.payRent(address,pt); 69 | } 70 | return toAjax(end); 71 | } 72 | 73 | 74 | @RequestMapping(value = "/getAll",method = RequestMethod.POST) 75 | public AjaxResult getAll(@RequestBody PaymentQueryTo qt){ 76 | int page = qt.getPage(); 77 | int pageSize = qt.getPageSize(); 78 | List paymentVos = startOrderPage(page, pageSize, PaymentVo.class, () -> { 79 | paymentService.getAll(qt); 80 | }); 81 | return getAll(paymentVos); 82 | } 83 | 84 | private AjaxResult getAll(List paymentVos) 85 | { 86 | for (PaymentVo paymentVo : paymentVos) 87 | { 88 | Long paymentId = paymentVo.getPaymentId(); 89 | mainContractService.getPayRent(paymentId,paymentVo); 90 | } 91 | return success(paymentVos,paymentVos.size()); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.controller; 2 | 3 | import cn.hutool.core.bean.BeanUtil; 4 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 5 | import com.jzm.backme.controller.base.BaseController; 6 | import com.jzm.backme.domain.Role; 7 | import com.jzm.backme.model.to.user.*; 8 | import com.jzm.backme.domain.User; 9 | import com.jzm.backme.domain.UserRole; 10 | import com.jzm.backme.exception.CustomException; 11 | import com.jzm.backme.exception.PermissionException; 12 | import com.jzm.backme.model.AjaxResult; 13 | import com.jzm.backme.model.vo.UserVo; 14 | import com.jzm.backme.service.*; 15 | import com.jzm.backme.util.NotEmptyUtil; 16 | import com.jzm.backme.util.StringUtil; 17 | import com.jzm.backme.util.user.UserUtil; 18 | import org.springframework.web.bind.annotation.RequestBody; 19 | import org.springframework.web.bind.annotation.RequestMapping; 20 | import org.springframework.web.bind.annotation.RequestMethod; 21 | import org.springframework.web.bind.annotation.RestController; 22 | 23 | import javax.annotation.Resource; 24 | import java.util.List; 25 | 26 | /** 27 | *

28 | * 用户表 -- 存储用户信息 前端控制器 29 | *

30 | * 31 | * @author qhx2004 32 | * @since 2024-04-14 33 | */ 34 | @RestController 35 | @RequestMapping("/user") 36 | public class UserController extends BaseController { 37 | 38 | @Resource 39 | private UserService userService; 40 | 41 | @Resource 42 | private LoginService loginService; 43 | 44 | @Resource 45 | private UserRoleService userRoleService; 46 | 47 | @Resource 48 | private MainContractService mainContractService; 49 | 50 | 51 | @RequestMapping(value = "/getAll",method = RequestMethod.POST) 52 | public AjaxResult getAll(@RequestBody UserQueryTo queryTo){ 53 | loginService.checkAdmin(); 54 | int page = queryTo.getPage(); 55 | int pageSize = queryTo.getPageSize(); 56 | List userVos = startOrderPage(page, pageSize, UserVo.class, () -> 57 | { 58 | userService.getAll(queryTo); 59 | }); 60 | return getAll(userVos); 61 | } 62 | 63 | // 重新粘贴userVos 64 | public AjaxResult getAll(List userVos){ 65 | for (UserVo userVo : userVos) 66 | { 67 | String user = userVo.getUser(); 68 | // 账户余额 69 | int balance = mainContractService.getBalance(user); 70 | // 角色 71 | Role role = userService.getRole(userVo.getUserId()); 72 | BeanUtil.copyProperties(role,userVo); 73 | userVo.setBalance(balance); 74 | } 75 | return success(userVos,userVos.size()); 76 | } 77 | 78 | @RequestMapping(value = "/create",method = RequestMethod.POST) 79 | public AjaxResult create(@RequestBody UserAddTo user){ 80 | loginService.checkAdmin(); 81 | String errPre = "添加用户失败:"; 82 | String errMes = NotEmptyUtil.checkEmptyFiled(user); 83 | String username = user.getUsername(); 84 | String phone = user.getPhone(); 85 | String password = user.getPassword(); 86 | if(StringUtil.isNotEmpty(errMes)){ 87 | return error(errPre+errMes); 88 | } 89 | if(!UserUtil.verifyPassword(password)){ 90 | return error(errPre+"密码格式不对"); 91 | } 92 | if(!UserUtil.verifyPhone(phone)){ 93 | return error(errPre+"电话格式不对"); 94 | } 95 | if(StringUtil.isNotEmpty(username) && !UserUtil.verifyUsername(username)){ 96 | return error(errPre +"用户名格式不对"); 97 | } 98 | if(!UserUtil.verifyAccount(user.getUser())){ 99 | return error(errPre +"账户地址不是合法的区块链账户地址"); 100 | } 101 | if(!userService.checkPhoneUnique(phone)){ 102 | return error(errPre + "电话已经被其他账户绑定"); 103 | } 104 | if(!userService.checkPassUnique(password)){ 105 | return error(errPre +"密码已经被其他用户注册"); 106 | } 107 | 108 | if(!userService.checkUserUnique(user.getUser())){ 109 | return error(errPre + "区块链账户地址已经被其他账户绑定"); 110 | } 111 | if(StringUtil.isEmpty(username)){ 112 | int l = phone.length(); 113 | user.setUsername("用户:"+phone.substring(l-4,l)); 114 | } 115 | user.setPassword( UserUtil.cryptPass(password)); 116 | boolean end = userService.save(user); 117 | // 创建角色 118 | if(!end){ 119 | throw new CustomException(errPre +"数据库异常"); 120 | } 121 | mainContractService.addPerson(user.getUser(),user.getRoleId()); 122 | 123 | UserRole userRole = new UserRole(); 124 | userRole.setUserId(user.getUserId()); 125 | userRole.setRoleId(user.getRoleId()); 126 | userRoleService.save(userRole); 127 | return success(); 128 | } 129 | 130 | @RequestMapping(value = "/payMoney",method = RequestMethod.POST) 131 | public AjaxResult payMoney(@RequestBody UserPayMoneyTo ut){ 132 | loginService.checkAdmin(); 133 | String errPre = "重置失败:"; 134 | String userAdd = ut.getUser(); 135 | int amount = ut.getAmount(); 136 | if(amount < 1){ 137 | return error(errPre+"充值金额至少大于等于1"); 138 | } 139 | mainContractService.addBalance(userAdd,amount); 140 | return AjaxResult.success(); 141 | } 142 | 143 | @RequestMapping(value = "/update",method = RequestMethod.POST) 144 | public AjaxResult update(@RequestBody User user){ // 不修改区块链账户,username、password、phone 145 | loginService.checkAdmin(); 146 | // 修改用户失败 147 | String errPre = "修改用户失败:"; 148 | if(!userService.checkPhoneUpUnique(user.getPhone())){ 149 | return error(errPre + "电话已经被其他用户绑定!"); 150 | } 151 | 152 | if(!UserUtil.verifyUsername(user.getUsername())){ 153 | return error(errPre +"用户名格式不对"); 154 | } 155 | LambdaQueryWrapper updateWrapper = new LambdaQueryWrapper<>(); 156 | updateWrapper.eq(User::getUserId,user.getUserId()); 157 | boolean end = userService.update(user, updateWrapper); 158 | return toAjax(end); 159 | } 160 | 161 | @RequestMapping(value = "/updateStatus",method = RequestMethod.POST) 162 | public AjaxResult updateStatus(@RequestBody User user){ 163 | boolean end = userService.updateStatus(user); 164 | return toAjax(end); 165 | } 166 | 167 | @RequestMapping(value = "/updatePass",method = RequestMethod.POST) 168 | public AjaxResult updatePass(@RequestBody UserPassTo upt){ 169 | String errPre = "修改密码失败:"; 170 | String password = upt.getPassword(); 171 | String newPass = upt.getNewPassword(); 172 | if(!StringUtil.isAllNotEmpty(password,newPass)){ 173 | return error(errPre +"密码不能为空"); 174 | } 175 | if(StringUtil.equals(password,newPass)){ 176 | return success(); 177 | } 178 | password = UserUtil.cryptPass(upt.getPassword()); 179 | newPass = UserUtil.cryptPass(upt.getNewPassword()); 180 | if(userService.checkMd5PassUnique(password)){ 181 | return error(errPre +"旧密码不存在"); 182 | } 183 | if(userService.checkMd5PassUnique(newPass)) { 184 | return error(errPre +"新密码已经被其他账户绑定"); 185 | } 186 | upt.setNewPassword(newPass); 187 | boolean end = userService.updatePass(upt); 188 | return toAjax(end); 189 | } 190 | 191 | 192 | 193 | @RequestMapping(value = "/delete",method = RequestMethod.POST) 194 | public AjaxResult delete(@RequestBody UserDeleteTo userDeleteTo){ 195 | loginService.checkAdmin(); 196 | List userIds = userDeleteTo.getUserIds(); 197 | for (Long userId : userIds) 198 | { 199 | if(StringUtil.equals(userId,loginService.getUserId())){ // 操作者权限不足,不能删除自己 200 | throw new PermissionException("操作者不能删除自己"); 201 | } 202 | } 203 | boolean end = userService.removeBatchByIds(userIds); 204 | return toAjax(end); 205 | } 206 | 207 | 208 | public static void main(String[] args) 209 | { 210 | System.out.println(UserUtil.cryptPass("123457")); 211 | } 212 | 213 | 214 | 215 | } 216 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/controller/base/BaseBaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.controller.base; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableLogic; 6 | import io.swagger.annotations.ApiModelProperty; 7 | import lombok.Data; 8 | 9 | import java.io.Serializable; 10 | import java.time.LocalDateTime; 11 | 12 | /** 13 | * @author: jzm 14 | * @date: 2024-04-20 11:43 15 | **/ 16 | 17 | @Data 18 | public abstract class BaseBaseEntity implements Serializable 19 | { 20 | @ApiModelProperty("删除标志(0代表存在 1代表删除)") 21 | @TableLogic 22 | private String delFlag; 23 | 24 | @ApiModelProperty("创建者") 25 | @TableField(fill = FieldFill.INSERT) 26 | private Long createBy; 27 | 28 | @ApiModelProperty("创建时间") 29 | @TableField(fill = FieldFill.INSERT) 30 | private LocalDateTime createTime; 31 | 32 | @ApiModelProperty("更新者") 33 | @TableField(fill = FieldFill.INSERT_UPDATE) 34 | private Long updateBy; 35 | 36 | @ApiModelProperty("更新时间") 37 | @TableField(fill = FieldFill.INSERT_UPDATE) 38 | private LocalDateTime updateTime; 39 | } 40 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/controller/base/BaseController.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.controller.base; 2 | 3 | import cn.hutool.core.bean.BeanUtil; 4 | import com.github.pagehelper.ISelect; 5 | import com.github.pagehelper.PageInfo; 6 | import com.jzm.backme.model.AjaxResult; 7 | import com.jzm.backme.model.PageResult; 8 | import com.jzm.backme.util.PageUtil; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @author: jzm 14 | * @date: 2024-04-14 17:41 15 | **/ 16 | 17 | public class BaseController 18 | { 19 | 20 | private final String defSortField = "createTime"; 21 | 22 | /** 23 | * 设置请求分页数据 24 | */ 25 | protected PageInfo startPage(int pageNum, int pageSize, ISelect select) 26 | { 27 | return PageUtil.startPage(pageNum, pageSize, select); 28 | } 29 | 30 | /** 31 | * 设置请求分页数据库 + 默认排序字段createTime + 升序排序 32 | */ 33 | protected PageInfo startOrderPage(int pageNum, int pageSize, ISelect select) 34 | { 35 | return startOrderByDesc(pageNum,pageSize,defSortField,select); 36 | } 37 | 38 | protected List startOrderPage(int pageNum, int pageSize,Class cls, ISelect select) 39 | { 40 | return startOrderPage(pageNum,pageSize,cls,defSortField,select); 41 | } 42 | 43 | /** 44 | * 分页返回原始查询 45 | */ 46 | protected List startOrderPage(int pageNum, int pageSize,Class cls,String filed, ISelect select) 47 | { 48 | PageInfo pageInfo = startOrderByDesc(pageNum, pageSize, filed, select); 49 | List list = pageInfo.getList(); 50 | List resList = BeanUtil.copyToList(list, cls); 51 | return resList; 52 | } 53 | 54 | 55 | /** 56 | * 设置请求降序排序 57 | */ 58 | protected PageInfo startOrderByDesc(int pageNumb, int pageSize, String filed, ISelect select) 59 | { 60 | return PageUtil.orderByDesc(pageNumb, pageSize, filed, select); 61 | } 62 | 63 | 64 | /** 65 | * 设置请求升序排序 66 | */ 67 | protected PageInfo startOrderByAsc(int pageNumb, int pageSize, String filed, ISelect select) 68 | { 69 | return PageUtil.orderByAsc(pageNumb, pageSize, filed, select); 70 | } 71 | 72 | 73 | /** 74 | * 清理线程变量 75 | */ 76 | protected void cleanPage() 77 | { 78 | PageUtil.clearPage(); 79 | } 80 | 81 | 82 | protected PageResult success(Object data,long total){ 83 | return PageResult.success(data,total); 84 | } 85 | 86 | 87 | /** 88 | * 返回成功响应结果 89 | * 90 | * @return 成功响应 91 | */ 92 | protected AjaxResult success() 93 | { 94 | return AjaxResult.success(); 95 | 96 | } 97 | 98 | /** 99 | * 返回成功响应结果 100 | * 101 | * @param mes 成功消息 102 | * @return 成功响应 103 | */ 104 | protected AjaxResult success(String mes) 105 | { 106 | return AjaxResult.success(mes); 107 | } 108 | 109 | /** 110 | * 返回成功响应 111 | * 112 | * @param data 成功内容 113 | * @return 成功响应 114 | */ 115 | protected AjaxResult success(Object data) 116 | { 117 | return AjaxResult.success(data); 118 | } 119 | 120 | /** 121 | * 返回警告响应 122 | * 123 | * @param mes 警告信息 124 | * @return 警告响应 125 | */ 126 | protected AjaxResult warn(String mes) 127 | { 128 | return AjaxResult.warn(mes); 129 | } 130 | 131 | /** 132 | * 返回警告响应 133 | * 134 | * @param data 警告内容 135 | * @param mes 警告信息 136 | * @return 警告响应 137 | */ 138 | protected AjaxResult warn(Object data, String mes) 139 | { 140 | return AjaxResult.warn(data, mes); 141 | } 142 | 143 | 144 | /** 145 | * 返回失败响应结果 146 | * 147 | * @return 失败响应 148 | */ 149 | protected AjaxResult error() 150 | { 151 | return AjaxResult.error(); 152 | } 153 | 154 | /** 155 | * 返回失败响应结果 156 | * 157 | * @param mes 158 | * @return 失败响应 159 | */ 160 | protected AjaxResult error(String mes) 161 | { 162 | return AjaxResult.error(mes); 163 | } 164 | 165 | /** 166 | * 最后返回响应结果 167 | * 168 | * @param data 响应数据 169 | * @return 响应结果 170 | */ 171 | protected AjaxResult toAjax(Object data) 172 | { 173 | return success(data); 174 | } 175 | 176 | protected PageResult toAjax(PageInfo pageInfo){ 177 | return PageResult.success(pageInfo.getList(),pageInfo.getTotal()); 178 | } 179 | 180 | /** 181 | * 最后返回响应结果 182 | * 183 | * @param results 增、删、改...等修改行为的响应结果 184 | * @return 响应结果 185 | */ 186 | protected AjaxResult toAjax(boolean results) 187 | { 188 | return results ? success() : error(); 189 | } 190 | 191 | 192 | } 193 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/domain/Contract.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.domain; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import java.io.Serializable; 7 | import java.time.LocalDateTime; 8 | 9 | import com.jzm.backme.annotation.NotEmpty; 10 | import com.jzm.backme.controller.base.BaseBaseEntity; 11 | import com.jzm.backme.domain.base.BaseEntity; 12 | import com.jzm.backme.util.user.UserUtil; 13 | import io.swagger.annotations.ApiModel; 14 | import io.swagger.annotations.ApiModelProperty; 15 | import lombok.Getter; 16 | import lombok.Setter; 17 | 18 | /** 19 | *

20 | * 合同表 -- 存储合同信息 21 | *

22 | * 23 | * @author qhx2004 24 | * @since 2024-04-15 25 | */ 26 | @Getter 27 | @Setter 28 | @TableName("contract") 29 | @ApiModel(value = "Contract对象", description = "合同表 -- 存储合同信息") 30 | public class Contract extends BaseBaseEntity implements Serializable { 31 | 32 | private static final long serialVersionUID = 1L; 33 | 34 | @ApiModelProperty("合同id") 35 | @TableId(value = "contract_id", type = IdType.AUTO) 36 | private Long contractId; 37 | 38 | @NotEmpty(extra = "房屋编号") 39 | private Long houseId; 40 | 41 | private Long landlordId; 42 | 43 | @ApiModelProperty("0 未签署 1签署") 44 | private String sign; 45 | 46 | @ApiModelProperty("合同编号") 47 | private String contractNum; 48 | 49 | @ApiModelProperty("签署日期") 50 | private LocalDateTime signTime; 51 | 52 | @ApiModelProperty("停止日期") 53 | private LocalDateTime stopTime; 54 | 55 | 56 | public static void main(String[] args) 57 | { 58 | System.out.println(UserUtil.cryptPass("123458")); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/domain/House.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.domain; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import java.io.Serializable; 7 | import java.time.LocalDateTime; 8 | 9 | import com.jzm.backme.annotation.NotEmpty; 10 | import com.jzm.backme.domain.base.BaseEntity; 11 | import io.swagger.annotations.ApiModel; 12 | import io.swagger.annotations.ApiModelProperty; 13 | import lombok.Getter; 14 | import lombok.Setter; 15 | 16 | /** 17 | *

18 | * 房屋表 -- 存储房屋信息 19 | *

20 | * 21 | * @author qhx2004 22 | * @since 2024-04-15 23 | */ 24 | @Getter 25 | @Setter 26 | @TableName("house") 27 | @ApiModel(value = "House对象", description = "房屋表 -- 存储房屋信息") 28 | public class House extends BaseEntity implements Serializable { 29 | 30 | private static final long serialVersionUID = 1L; 31 | 32 | @TableId(value = "house_id", type = IdType.AUTO) 33 | private Long houseId; 34 | 35 | @ApiModelProperty("房屋地址") 36 | @NotEmpty(extra = "房屋地址") 37 | private String address; 38 | 39 | @ApiModelProperty("房东id") 40 | private Long landlordId; 41 | 42 | @ApiModelProperty("联系人") 43 | @NotEmpty(extra = "联系人") 44 | private String linkMan; 45 | 46 | @ApiModelProperty("联系电话") 47 | @NotEmpty(extra = "联系电话") 48 | private String linkPhone; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/domain/Payment.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.domain; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import java.io.Serializable; 7 | import java.time.LocalDateTime; 8 | 9 | import com.jzm.backme.controller.base.BaseBaseEntity; 10 | import com.jzm.backme.domain.base.BaseEntity; 11 | import io.swagger.annotations.ApiModel; 12 | import io.swagger.annotations.ApiModelProperty; 13 | import lombok.Getter; 14 | import lombok.Setter; 15 | 16 | /** 17 | *

18 | * 缴纳记录表 -- 记录租金缴纳信息 19 | *

20 | * 21 | * @author qhx2004 22 | * @since 2024-04-15 23 | */ 24 | @Getter 25 | @Setter 26 | @TableName("payment") 27 | @ApiModel(value = "Payment对象", description = "缴纳记录表 -- 记录租金缴纳信息") 28 | public class Payment extends BaseBaseEntity implements Serializable { 29 | 30 | private static final long serialVersionUID = 1L; 31 | 32 | @ApiModelProperty("缴纳记录id") 33 | @TableId(value = "payment_id", type = IdType.AUTO) 34 | private Long paymentId; 35 | 36 | @ApiModelProperty("缴纳人账户地址") 37 | private String payer; 38 | 39 | @ApiModelProperty("缴纳人用户id") 40 | private Long payerId; 41 | 42 | @ApiModelProperty("合同序列码") 43 | private String contractNum; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/domain/Role.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.domain; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import java.io.Serializable; 5 | import io.swagger.annotations.ApiModel; 6 | import io.swagger.annotations.ApiModelProperty; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Data; 9 | import lombok.Getter; 10 | import lombok.Setter; 11 | 12 | /** 13 | *

14 | * 角色表 15 | *

16 | * 17 | * @author qhx2004 18 | * @since 2024-04-14 19 | */ 20 | @Getter 21 | @Setter 22 | @TableName("role") 23 | @ApiModel(value = "Role对象", description = " 角色表") 24 | @AllArgsConstructor 25 | public class Role implements Serializable { 26 | 27 | private static final long serialVersionUID = 1L; 28 | 29 | private Long roleId; 30 | 31 | private String roleName; 32 | } 33 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/domain/User.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.domain; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import java.io.Serializable; 7 | import java.time.LocalDateTime; 8 | 9 | import com.jzm.backme.annotation.NotEmpty; 10 | import com.jzm.backme.domain.base.BaseEntity; 11 | import io.swagger.annotations.ApiModel; 12 | import io.swagger.annotations.ApiModelProperty; 13 | import lombok.Getter; 14 | import lombok.Setter; 15 | 16 | /** 17 | *

18 | * 用户表 -- 存储用户信息 19 | *

20 | * 21 | * @author qhx2004 22 | * @since 2024-04-15 23 | */ 24 | @Getter 25 | @Setter 26 | @TableName("user") 27 | @ApiModel(value = "User对象", description = "用户表 -- 存储用户信息") 28 | public class User extends BaseEntity implements Serializable { 29 | 30 | private static final long serialVersionUID = 1L; 31 | 32 | @TableId(value = "user_id", type = IdType.AUTO) 33 | private Long userId; 34 | 35 | private String username; 36 | 37 | @ApiModelProperty("用户区块链账户地址") 38 | @NotEmpty(extra = "区块链账户地址") 39 | private String user; 40 | 41 | @NotEmpty(extra = "用户电话") 42 | private String phone; 43 | 44 | @ApiModelProperty("用户密码") 45 | @NotEmpty(extra = "密码") 46 | private String password; 47 | 48 | private String sex; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/domain/UserRole.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.domain; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableName; 4 | import java.io.Serializable; 5 | import io.swagger.annotations.ApiModel; 6 | import io.swagger.annotations.ApiModelProperty; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | 10 | /** 11 | *

12 | * 用户 - 角色表 13 | *

14 | * 15 | * @author qhx2004 16 | * @since 2024-04-15 17 | */ 18 | @Getter 19 | @Setter 20 | @TableName("user_role") 21 | @ApiModel(value = "UserRole对象", description = "用户 - 角色表") 22 | public class UserRole implements Serializable { 23 | 24 | private static final long serialVersionUID = 1L; 25 | 26 | private Long userId; 27 | 28 | private Long roleId; 29 | } 30 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/domain/base/BaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.domain.base; 2 | 3 | import com.jzm.backme.controller.base.BaseBaseEntity; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | @Data 8 | public abstract class BaseEntity extends BaseBaseEntity 9 | { 10 | 11 | @ApiModelProperty("状态") 12 | private String status; 13 | 14 | } 15 | 16 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/exception/CustomException.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.exception; 2 | 3 | import com.jzm.backme.exception.base.BaseException; 4 | 5 | /** 6 | * @author: jzm 7 | * @date: 2024-04-14 20:47 8 | **/ 9 | 10 | public class CustomException extends BaseException 11 | { 12 | 13 | public CustomException(String message) 14 | { 15 | super(message,400); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/exception/PermissionException.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.exception; 2 | 3 | 4 | import com.jzm.backme.exception.base.BaseException; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-03-07 20:34 9 | **/ 10 | 11 | public class PermissionException extends BaseException 12 | { 13 | public PermissionException(String message, int code) 14 | { 15 | super(message, code); 16 | } 17 | 18 | public PermissionException(String message) 19 | { 20 | super(message); 21 | } 22 | 23 | public PermissionException(){ 24 | this("操作者权限不足"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/exception/base/BaseException.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.exception.base; 2 | 3 | 4 | import lombok.Data; 5 | 6 | /** 7 | * 基础异常 8 | * 9 | * @author jzm 10 | */ 11 | @Data 12 | public class BaseException extends RuntimeException 13 | { 14 | private static final long serialVersionUID = 1L; 15 | 16 | private String mes; 17 | private int code; 18 | 19 | public BaseException(String message, int code){ 20 | super(message); 21 | this.mes = message; 22 | this.code = code; 23 | } 24 | 25 | public BaseException(String message){ 26 | super(message); 27 | this.mes = message; 28 | this.code = 400; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/handler/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.handler; 2 | 3 | import com.jzm.backme.exception.base.BaseException; 4 | import com.jzm.backme.model.AjaxResult; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.web.bind.annotation.ControllerAdvice; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | import org.springframework.web.bind.annotation.ResponseBody; 9 | 10 | /** 11 | * @author: jzm 12 | * @date: 2024-04-18 21:27 13 | **/ 14 | 15 | @ControllerAdvice 16 | @ResponseBody 17 | @Slf4j 18 | public class GlobalExceptionHandler 19 | { 20 | @ExceptionHandler(BaseException.class) 21 | public AjaxResult handlerBaseException(BaseException ex) 22 | { 23 | ex.printStackTrace(); 24 | return AjaxResult.error(ex.getCode(), ex.getMessage()); 25 | } 26 | 27 | @ExceptionHandler(Exception.class) 28 | public AjaxResult handlerException(Exception ex) 29 | { 30 | ex.printStackTrace(); 31 | return AjaxResult.error(400, ex.getMessage()); 32 | } 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/interceptor/TokenInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.interceptor; 2 | 3 | import cn.hutool.Hutool; 4 | import cn.hutool.json.JSONUtil; 5 | import com.jzm.backme.constant.*; 6 | import com.jzm.backme.context.UserContext; 7 | import com.jzm.backme.domain.User; 8 | import com.jzm.backme.model.AjaxResult; 9 | import com.jzm.backme.model.vo.UserVo; 10 | import com.jzm.backme.util.ServletUtil; 11 | import com.jzm.backme.util.StringUtil; 12 | import com.jzm.backme.util.TokenUtil; 13 | import com.jzm.backme.util.redis.RedisCache; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.stereotype.Component; 16 | import org.springframework.web.servlet.HandlerInterceptor; 17 | 18 | import javax.servlet.http.HttpServletRequest; 19 | import javax.servlet.http.HttpServletResponse; 20 | import java.security.MessageDigest; 21 | 22 | /** 23 | * @author: jzm 24 | * @date: 2024-04-14 16:58 25 | **/ 26 | 27 | @Component 28 | public class TokenInterceptor implements HandlerInterceptor 29 | { 30 | 31 | @Autowired 32 | private RedisCache redisCache; 33 | 34 | @Override 35 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception 36 | { 37 | // 设置跨域 38 | response.setHeader("Access-Control-Allow-Origin", "*"); // 修改携带cookie,PS 39 | response.setHeader("Access-Control-Allow-Methods", "*"); 40 | response.setHeader("Access-Control-Allow-Headers", "*"); 41 | // 预检请求缓存时间(秒),即在这个时间内相同的预检请求不再发送,直接使用缓存结果。 42 | response.setHeader("Access-Control-Max-Age", "3600"); 43 | 44 | if (request.getMethod().equalsIgnoreCase("options")) 45 | { // 设置预请求直接通过 46 | return true; 47 | } 48 | String path = request.getRequestURI(); 49 | // 排除不过滤列表 50 | if (isExclusionList(path, UserConstant.ExclusionList)) 51 | { 52 | return true; 53 | } 54 | // token拿取和校验 55 | String authorization = request.getHeader(HeaderConstant.AUTHORIZATION); 56 | if (StringUtil.isEmpty(authorization)) 57 | { 58 | ServletUtil.renderString(response, JSONUtil.toJsonStr(HttpStatus.USER_NOT_LOGIN)); 59 | return false; 60 | } 61 | if (!authorization.startsWith(Constant.TOKEN_PREFIX)) 62 | { 63 | ServletUtil.renderString(response, JSONUtil.toJsonStr(HttpStatus.USER_TOKEN_ILLICIT)); 64 | return false; 65 | } 66 | String token = authorization.substring(Constant.TOKEN_PREFIX.length()); 67 | String userId = TokenUtil.parseTokenGetUserId(token); 68 | String loginKey = CacheConstant.LOGIN_USER_KEY + userId; 69 | User user = redisCache.getCacheObject(loginKey); 70 | if (StringUtil.isEmpty(user)) 71 | { 72 | ServletUtil.renderString(response, JSONUtil.toJsonStr(HttpStatus.USER_LOGIN_EXPIRED)); 73 | return false; 74 | } 75 | UserContext.set(user); 76 | return true; 77 | } 78 | 79 | // 排除不拦截列表(其实mvc配置就行,但是我这里面懒写了)。 80 | private boolean isExclusionList(String path, String... exclusionList) 81 | { 82 | for (String ep : exclusionList) 83 | { 84 | if (ep.equals(path)) 85 | { 86 | return true; 87 | } 88 | // 这是 /path/qhx => /path/** 89 | if (ep.contains("/**")) 90 | { 91 | int len = ep.length(); 92 | ep = ep.substring(0, len - "/**".length()); 93 | if (path.contains(ep)) 94 | { 95 | return true; 96 | } 97 | } 98 | } 99 | return false; 100 | } 101 | 102 | 103 | } 104 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/mapper/ContractMapper.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.mapper; 2 | 3 | import com.jzm.backme.domain.Contract; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 合同表 -- 存储合同信息 Mapper 接口 10 | *

11 | * 12 | * @author qhx2004 13 | * @since 2024-04-14 14 | */ 15 | @Mapper 16 | public interface ContractMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/mapper/HouseMapper.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.mapper; 2 | 3 | import com.jzm.backme.domain.House; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 房屋表 -- 存储房屋信息 Mapper 接口 10 | *

11 | * 12 | * @author qhx2004 13 | * @since 2024-04-14 14 | */ 15 | @Mapper 16 | public interface HouseMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/mapper/PaymentMapper.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.mapper; 2 | 3 | import com.jzm.backme.domain.Payment; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 缴纳记录表 -- 记录租金缴纳信息 Mapper 接口 10 | *

11 | * 12 | * @author qhx2004 13 | * @since 2024-04-14 14 | */ 15 | @Mapper 16 | public interface PaymentMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/mapper/RoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.mapper; 2 | 3 | import com.jzm.backme.domain.Role; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 角色表 Mapper 接口 10 | *

11 | * 12 | * @author qhx2004 13 | * @since 2024-04-14 14 | */ 15 | @Mapper 16 | public interface RoleMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.mapper; 2 | 3 | import com.jzm.backme.domain.Role; 4 | import com.jzm.backme.domain.User; 5 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 6 | import org.apache.ibatis.annotations.Mapper; 7 | 8 | /** 9 | *

10 | * 用户表 -- 存储用户信息 Mapper 接口 11 | *

12 | * 13 | * @author qhx2004 14 | * @since 2024-04-14 15 | */ 16 | @Mapper 17 | public interface UserMapper extends BaseMapper { 18 | 19 | Role selectRole(Long userId); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/mapper/UserRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.mapper; 2 | 3 | import com.jzm.backme.domain.UserRole; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 用户 - 角色表 Mapper 接口 10 | *

11 | * 12 | * @author qhx2004 13 | * @since 2024-04-14 14 | */ 15 | @Mapper 16 | public interface UserRoleMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/AjaxResult.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model; 2 | 3 | 4 | import com.fasterxml.jackson.annotation.JsonInclude; 5 | import com.jzm.backme.constant.Constant; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | 9 | import java.io.Serializable; 10 | 11 | /** 12 | * 公共响应类 13 | * 14 | * @author: jzm 15 | * @date: 2024-01-08 20:29 16 | **/ 17 | 18 | @Setter 19 | @Getter 20 | @JsonInclude(value = JsonInclude.Include.NON_EMPTY) // 排除值为空字段的序列化 21 | public class AjaxResult implements Serializable 22 | { 23 | private static final long serialVersionUID = 1L; 24 | 25 | private Object data; 26 | private int code; 27 | private String mes; 28 | 29 | 30 | protected AjaxResult(Object data, int code, String mes) 31 | { 32 | this.data = data; 33 | this.code = code; 34 | this.mes = mes; 35 | } 36 | 37 | /** 38 | * 返回默认成功响应 39 | * 40 | * @return 成功响应 41 | */ 42 | public static AjaxResult success() 43 | { 44 | return AjaxResult.success(Constant.OK_MES); 45 | } 46 | 47 | 48 | /** 49 | * 返回成功响应 50 | * 51 | * @param mes 成功信息 52 | * @return 成功响应 53 | */ 54 | public static AjaxResult success(String mes) 55 | { 56 | return AjaxResult.common(null,200, mes); 57 | } 58 | 59 | /** 60 | * 返回成功响应 61 | * 62 | * @param data 成功内容 63 | * @return 成功响应 64 | */ 65 | public static AjaxResult success(Object data) 66 | { 67 | return AjaxResult.common(data,Constant.OK_CODE, Constant.OK_MES); 68 | } 69 | 70 | 71 | /** 72 | * 返回警告响应 73 | * 74 | * @param data 警告内容 75 | * @param mes 警告信息 76 | * @return 警告响应 77 | */ 78 | public static AjaxResult warn(Object data, String mes) 79 | { 80 | return AjaxResult.common(data,Constant.WARN_CODE, mes); 81 | } 82 | 83 | 84 | /** 85 | * 返回警告响应 86 | * 87 | * @param mes 警告信息 88 | * @return 警告响应 89 | */ 90 | public static AjaxResult warn(String mes) 91 | { 92 | return AjaxResult.warn(null, mes); 93 | } 94 | 95 | /** 96 | * 返回失败响应 97 | * 98 | * @return 失败响应 99 | */ 100 | public static AjaxResult error() 101 | { 102 | return AjaxResult.error(Constant.FAIL_MES); 103 | } 104 | 105 | /** 106 | * 返回失败响应 107 | * 108 | * @param mes 失败信息 109 | * @return 失败响应 110 | */ 111 | public static AjaxResult error(String mes) 112 | { 113 | return AjaxResult.common(null,Constant.ERROR_CODE, mes); 114 | } 115 | 116 | /** 117 | * 返回失败响应 118 | * 119 | * @param code 失败编码 120 | * @param mes 失败信息 121 | * @return 失败响应 122 | */ 123 | public static AjaxResult error(int code, String mes) 124 | { 125 | return AjaxResult.common(null, code, mes); 126 | } 127 | 128 | 129 | /** 130 | * 返回响应 131 | * 132 | * @param data 响应内容 133 | * @param code 响应编码 134 | * @param mes 响应消息 135 | * @return 响应 136 | */ 137 | private static AjaxResult common(Object data, int code, String mes) 138 | { 139 | return new AjaxResult(data, code, mes); 140 | } 141 | 142 | 143 | } 144 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/PageResult.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model; 2 | 3 | import com.jzm.backme.constant.Constant; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | /** 8 | * @author: jzm 9 | * @date: 2024-03-08 18:04 10 | **/ 11 | 12 | @Setter 13 | @Getter 14 | public class PageResult extends AjaxResult 15 | { 16 | private long total; 17 | 18 | protected PageResult(Object data, int code, String mes,long total) 19 | { 20 | super(data, code, mes); 21 | this.total = total; 22 | } 23 | 24 | private static PageResult common(Object data, int code, String mes,long total){ 25 | return new PageResult(data,code,mes,total); 26 | } 27 | public static PageResult success(Object data,long total){ 28 | return common(data, Constant.OK_CODE,Constant.OK_MES,total); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/LoginTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to; 2 | 3 | import com.jzm.backme.annotation.NotEmpty; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-04-14 16:17 9 | **/ 10 | 11 | @Data 12 | public class LoginTo 13 | { 14 | @NotEmpty(extra = "密码") 15 | private String password; 16 | 17 | @NotEmpty(extra = "电话") 18 | private String phone; 19 | } 20 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/base/BasePageQueryTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.base; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author: jzm 7 | * @date: 2024-04-14 20:07 8 | **/ 9 | 10 | @Data 11 | public class BasePageQueryTo 12 | { 13 | private int page; 14 | private int pageSize; 15 | } 16 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/contract/ContractQueryTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.contract; 2 | 3 | import com.jzm.backme.model.to.base.BasePageQueryTo; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-04-16 22:12 9 | **/ 10 | 11 | @Data 12 | public class ContractQueryTo extends BasePageQueryTo 13 | { 14 | private Long landlordId; 15 | private String type; 16 | // 预发布 17 | // 签署未生效 18 | // 签署已经生效 19 | // 签署-过期 20 | // 签署-停止 21 | } 22 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/house/HouseAddTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.house; 2 | 3 | import com.jzm.backme.annotation.NotEmpty; 4 | import com.jzm.backme.domain.House; 5 | import lombok.Data; 6 | 7 | /** 8 | * @author: jzm 9 | * @date: 2024-04-16 20:44 10 | **/ 11 | 12 | @Data 13 | public class HouseAddTo extends House 14 | { 15 | @NotEmpty(extra = "房屋密码") 16 | private String password; 17 | } 18 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/house/HouseDeleteTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.house; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author: jzm 9 | * @date: 2024-04-14 20:02 10 | **/ 11 | 12 | @Data 13 | public class HouseDeleteTo 14 | { 15 | private List houseIds; 16 | } 17 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/house/HousePassTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.house; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author: jzm 7 | * @date: 2024-04-16 21:06 8 | **/ 9 | 10 | @Data 11 | public class HousePassTo 12 | { 13 | private Long houseId; 14 | private String oldPass; 15 | private String newPass; 16 | } 17 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/house/HouseQueryTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.house; 2 | 3 | import com.jzm.backme.model.to.base.BasePageQueryTo; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-04-16 20:51 9 | **/ 10 | 11 | @Data 12 | public class HouseQueryTo extends BasePageQueryTo 13 | { 14 | private String linkPhone; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/payment/PaymentAddTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.payment; 2 | 3 | import com.jzm.backme.domain.Payment; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-04-17 14:38 9 | **/ 10 | 11 | @Data 12 | public class PaymentAddTo extends Payment 13 | { 14 | private int money; 15 | private Long contractId; 16 | } 17 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/payment/PaymentQueryTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.payment; 2 | 3 | import com.jzm.backme.model.to.base.BasePageQueryTo; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-04-17 14:57 9 | **/ 10 | 11 | @Data 12 | public class PaymentQueryTo extends BasePageQueryTo 13 | { 14 | private String payer; // 缴纳账户地址 15 | private String contractNum; // 合同序列号 16 | } 17 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/user/PassTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.user; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author: jzm 7 | * @date: 2024-04-20 21:26 8 | **/ 9 | 10 | @Data 11 | public class PassTo 12 | { 13 | private String oldPassword; 14 | private String newPassword; 15 | } 16 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/user/UserAddTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.user; 2 | 3 | import com.jzm.backme.domain.User; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-04-14 20:29 9 | **/ 10 | 11 | @Data 12 | public class UserAddTo extends User 13 | { 14 | private Long roleId; 15 | } 16 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/user/UserDeleteTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.user; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author: jzm 9 | * @date: 2024-04-14 19:24 10 | **/ 11 | 12 | @Data 13 | public class UserDeleteTo 14 | { 15 | private List userIds; 16 | } 17 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/user/UserPassTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.user; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-04-18 10:46 9 | **/ 10 | 11 | @Data 12 | @AllArgsConstructor 13 | public class UserPassTo 14 | { 15 | private String password; 16 | private String newPassword; 17 | } 18 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/user/UserPayMoneyTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.user; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author: jzm 7 | * @date: 2024-04-16 19:49 8 | **/ 9 | 10 | @Data 11 | public class UserPayMoneyTo 12 | { 13 | private String user; 14 | private int amount; 15 | } 16 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/user/UserQueryTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.user; 2 | 3 | import com.jzm.backme.model.to.base.BasePageQueryTo; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-04-14 20:05 9 | **/ 10 | 11 | @Data 12 | public class UserQueryTo extends BasePageQueryTo 13 | { 14 | private String phone; 15 | } 16 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/to/user/UserResTo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.to.user; 2 | 3 | import com.jzm.backme.domain.User; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-04-16 19:58 9 | **/ 10 | 11 | @Data 12 | public class UserResTo extends User 13 | { 14 | private int balance; 15 | } 16 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/vo/ContractVo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.vo; 2 | 3 | import com.jzm.backme.annotation.NotEmpty; 4 | import com.jzm.backme.domain.Contract; 5 | import lombok.Data; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | /** 10 | * @author: jzm 11 | * @date: 2024-04-16 22:19 12 | **/ 13 | 14 | @Data 15 | public class ContractVo extends Contract 16 | { 17 | // 签署结束时间 18 | private LocalDateTime signEndTime; 19 | // 生效 20 | private String begin; 21 | private LocalDateTime beginStartTime; 22 | private LocalDateTime beginEndTime; 23 | private String stop; 24 | 25 | @NotEmpty(extra = "规定每月租金") 26 | private Integer rent; 27 | 28 | @NotEmpty(extra = "规定每月保证金") 29 | private Integer earnest; 30 | 31 | // 签署是否缴纳 32 | String isTenEarnest; // 租客是否缴纳保证金 33 | String isTenRent; // 租客是否缴纳租金 34 | String isLanEarnest; // 房东是否缴纳保证金 35 | 36 | String tenant; // 租客地址 37 | 38 | String landlord; // 房东地址 39 | } 40 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/vo/HouseVo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.vo; 2 | 3 | import com.jzm.backme.domain.House; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-04-16 21:25 9 | **/ 10 | 11 | @Data 12 | public class HouseVo extends House 13 | { 14 | private String password; 15 | } 16 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/vo/PaymentVo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.vo; 2 | 3 | import com.jzm.backme.domain.Payment; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-04-17 15:01 9 | **/ 10 | 11 | @Data 12 | public class PaymentVo extends Payment 13 | { 14 | private int money; // 缴纳金额 15 | } 16 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/model/vo/UserVo.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.model.vo; 2 | 3 | import com.jzm.backme.domain.User; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author: jzm 8 | * @date: 2024-04-14 19:07 9 | **/ 10 | 11 | @Data 12 | public class UserVo extends User 13 | { 14 | private Long roleId; 15 | private String roleName; 16 | private int balance; 17 | } 18 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/CaptchaService.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service; 2 | 3 | import cn.hutool.captcha.CaptchaUtil; 4 | import cn.hutool.captcha.LineCaptcha; 5 | import cn.hutool.core.util.IdUtil; 6 | import com.jzm.backme.constant.CacheConstant; 7 | import com.jzm.backme.model.AjaxResult; 8 | import com.jzm.backme.util.redis.RedisCache; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Component; 11 | 12 | import java.util.HashMap; 13 | import java.util.concurrent.TimeUnit; 14 | 15 | /** 16 | * 验证码业务类 17 | * 18 | * @author: jzm 19 | * @date: 2024-02-28 12:12 20 | **/ 21 | 22 | @Component 23 | public class CaptchaService 24 | { 25 | 26 | @Autowired 27 | RedisCache redisCache; 28 | 29 | public AjaxResult getCaptcha(){ 30 | LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(128, 50); 31 | String uuid = IdUtil.randomUUID(); 32 | // 验证码缓存到redis 33 | String codeKey = CacheConstant.CAPTCHA_CODE_KEY + uuid; 34 | redisCache.setCacheObject(codeKey,lineCaptcha.getCode(),60, TimeUnit.SECONDS); 35 | HashMap result = new HashMap<>(); 36 | result.put("codeUrl",lineCaptcha.getImageBase64Data()); 37 | result.put("codeKey",uuid); 38 | return AjaxResult.success(result); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/ContractService.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service; 2 | 3 | import com.baomidou.mybatisplus.core.toolkit.support.SFunction; 4 | import com.jzm.backme.domain.Contract; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.jzm.backme.model.to.contract.ContractQueryTo; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | *

12 | * 合同表 -- 存储合同信息 服务类 13 | *

14 | * 15 | * @author qhx2004 16 | * @since 2024-04-14 17 | */ 18 | public interface ContractService extends IService { 19 | 20 | List getAll(ContractQueryTo contractQueryTo); 21 | 22 | Contract getOne(SFunction column,Object val); 23 | 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/HouseService.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service; 2 | 3 | import com.jzm.backme.model.to.house.HouseQueryTo; 4 | import com.jzm.backme.model.to.user.UserQueryTo; 5 | import com.jzm.backme.domain.House; 6 | import com.baomidou.mybatisplus.extension.service.IService; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | *

12 | * 房屋表 -- 存储房屋信息 服务类 13 | *

14 | * 15 | * @author qhx2004 16 | * @since 2024-04-14 17 | */ 18 | public interface HouseService extends IService { 19 | 20 | List getAll(HouseQueryTo houseQueryTo); 21 | 22 | boolean updateStatus(House house); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/LoginService.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service; 2 | 3 | import com.jzm.backme.constant.CacheConstant; 4 | import com.jzm.backme.constant.HeaderConstant; 5 | import com.jzm.backme.constant.HttpStatus; 6 | import com.jzm.backme.context.UserContext; 7 | import com.jzm.backme.domain.User; 8 | import com.jzm.backme.exception.PermissionException; 9 | import com.jzm.backme.model.vo.UserVo; 10 | import com.jzm.backme.util.ServletUtil; 11 | import com.jzm.backme.util.StringUtil; 12 | import com.jzm.backme.util.redis.RedisCache; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Service; 15 | 16 | /** 17 | * @author: jzm 18 | * @date: 2024-04-14 16:39 19 | **/ 20 | 21 | @Service 22 | public class LoginService 23 | { 24 | 25 | @Autowired 26 | private RedisCache redisCache; 27 | 28 | /** 29 | * 获取userId 30 | * @return 31 | */ 32 | public final Long getUserId(){ 33 | User user = getUser(); 34 | if(StringUtil.isEmpty(user)){ 35 | return null; 36 | } 37 | return user.getUserId(); 38 | } 39 | 40 | public final String getAccountAddress(){ 41 | return getUser().getUser(); 42 | } 43 | 44 | public final User getUser(){ 45 | return UserContext.get(); 46 | } 47 | 48 | public final boolean isRole(Long roleId){ 49 | User user = getUser(); 50 | if(user instanceof UserVo){ 51 | UserVo userVo = (UserVo) user; 52 | if(userVo.getRoleId() == roleId){ 53 | return true; 54 | } 55 | } 56 | return false; 57 | } 58 | 59 | public final boolean isAdmin(){ 60 | return isRole(1L); 61 | } 62 | 63 | public final boolean isLandlord(){ 64 | return isRole(2L); 65 | } 66 | 67 | public final boolean isTenant(){ 68 | return isRole(3L); 69 | } 70 | 71 | 72 | public final boolean isNotAdmin(){ 73 | return !isAdmin(); 74 | } 75 | 76 | public final void checkAdmin(){ 77 | if(!isAdmin()){ 78 | throw new PermissionException(); 79 | } 80 | } 81 | 82 | public final void checkLandlord(){ 83 | if(!isLandlord()){ 84 | throw new PermissionException("操作者必须是房东"); 85 | } 86 | } 87 | 88 | public final void checkTenant(){ 89 | if(!isTenant()){ 90 | throw new PermissionException("操作者必须是租客"); 91 | } 92 | } 93 | 94 | 95 | /** 96 | * 校验验证码 97 | */ 98 | public final HttpStatus verifyCaptcha(){ 99 | String codeVal = ServletUtil.getHeader(HeaderConstant.CAPTCHA_VAL); 100 | String codeKey = ServletUtil.getHeader(HeaderConstant.CAPTCHA_KEY); 101 | 102 | if(codeVal != null){ 103 | codeKey = CacheConstant.CAPTCHA_CODE_KEY + codeKey; 104 | String val = redisCache.getCacheObject(codeKey); 105 | if(val == null) { // 验证码过期 106 | return HttpStatus.CAPTCHA_EXPIRED; 107 | } 108 | if(!StringUtil.equals(val,codeVal)){ // 验证码不一致 109 | return HttpStatus.CAPTCHA_CHECK_FAILED; 110 | } 111 | return null; 112 | } 113 | return HttpStatus.CAPTCHA_CHECK_FAILED; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/MainContractService.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service; 2 | 3 | import cn.hutool.json.JSONArray; 4 | import com.jzm.backme.config.fisco.contract.ContractResponse; 5 | import com.jzm.backme.config.fisco.service.WeFrontService; 6 | import com.jzm.backme.model.to.payment.PaymentAddTo; 7 | import com.jzm.backme.model.vo.ContractVo; 8 | import com.jzm.backme.model.vo.PaymentVo; 9 | import com.jzm.backme.util.Convert; 10 | import com.jzm.backme.util.DateUtil; 11 | import io.swagger.models.auth.In; 12 | import org.fisco.bcos.sdk.abi.datatypes.Int; 13 | import org.fisco.bcos.sdk.client.Client; 14 | import org.fisco.bcos.sdk.client.protocol.response.BcosBlock; 15 | import org.fisco.bcos.sdk.client.protocol.response.BlockNumber; 16 | import org.springframework.beans.factory.annotation.Autowired; 17 | import org.springframework.stereotype.Component; 18 | 19 | import javax.annotation.Resource; 20 | import java.math.BigInteger; 21 | import java.util.ArrayList; 22 | import java.util.Arrays; 23 | import java.util.List; 24 | 25 | /** 26 | * 主合约交互类 27 | * 28 | * @author: jzm 29 | * @date: 2024-04-15 22:14 30 | **/ 31 | 32 | @Component 33 | public class MainContractService 34 | { 35 | 36 | @Resource 37 | private WeFrontService weFrontService; 38 | 39 | public void addPerson(String account, Long role) 40 | { 41 | weFrontService.commonWrite("addPerson", Arrays.asList(account, role)); 42 | } 43 | 44 | public void addBalance(String account, int amount) 45 | { 46 | weFrontService.commonWrite("addBalance", Arrays.asList(account, amount)); 47 | } 48 | 49 | public int getBalance(String account) 50 | { 51 | ContractResponse response = weFrontService.commonRead("getPerson", Arrays.asList(account)); 52 | String hex = response.getVals().getStr(0); 53 | return Convert.hexToInt(hex); 54 | } 55 | 56 | public void addHouse(String address, Long houseId, String password) 57 | { 58 | weFrontService.commonWrite(address, "addHouse", Arrays.asList(houseId, password)); 59 | } 60 | 61 | public void changeHousePass(Long houseId, String password) 62 | { 63 | weFrontService.commonWrite("changeHousePass", Arrays.asList(houseId, password)); 64 | } 65 | 66 | public String getHouseAdmin(Long houseId) 67 | { 68 | ContractResponse response = weFrontService.commonRead("getHouseAdmin", Arrays.asList(houseId)); 69 | return response.getVals().getStr(1); 70 | } 71 | 72 | // 租客获取 73 | public String getHouse(Long houseId, Long contractId) 74 | { 75 | ContractResponse response = weFrontService.commonRead("getHouse", Arrays.asList(houseId, contractId)); 76 | return response.getVals().getStr(1); 77 | } 78 | 79 | public void getContract(Long contractId, ContractVo contractVo) 80 | { 81 | ContractResponse response = weFrontService.commonRead("getContract", Arrays.asList(contractId)); 82 | JSONArray vals = response.getVals(); 83 | contractVo.setLandlord(vals.getStr(1)); 84 | contractVo.setTenant(vals.getStr(2)); 85 | contractVo.setEarnest(Convert.hexToInt(vals.getStr(3))); 86 | contractVo.setRent(Convert.hexToInt(vals.getStr(4))); 87 | contractVo.setBeginStartTime(DateUtil.parseLDT(vals.getStr(5))); 88 | contractVo.setBeginEndTime(DateUtil.parseLDT(vals.getStr(6))); 89 | contractVo.setIsTenEarnest(Convert.boolConv(vals.getBool(7))); 90 | contractVo.setIsTenRent(Convert.boolConv(vals.getBool(8))); 91 | contractVo.setIsLanEarnest(Convert.boolConv(vals.getBool(9))); 92 | contractVo.setBegin(Convert.boolConv(vals.getBool(10))); 93 | contractVo.setStop(Convert.boolConv(vals.getBool(11))); 94 | contractVo.setSignEndTime(DateUtil.parseLDT(vals.getStr(12))); 95 | } 96 | 97 | public void signContract(ContractVo contractVo) 98 | { 99 | Long contractId = contractVo.getContractId(); 100 | String landlord = contractVo.getLandlord(); 101 | String tenant = contractVo.getTenant(); 102 | Integer earnest = contractVo.getEarnest(); 103 | Long beginEndTime = DateUtil.datetimeToTimestamp(contractVo.getBeginEndTime()) / DateUtil.S; 104 | 105 | weFrontService.commonWrite("signContract", Arrays.asList( 106 | contractId, landlord, tenant, earnest, beginEndTime 107 | )); 108 | } 109 | 110 | public void tenantPrestore(String address, Long contractId) 111 | { 112 | weFrontService.commonWrite(address, "tenantPrestore", Arrays.asList(address, contractId)); 113 | } 114 | 115 | public void landlordPrestore(String address, Long contractId) 116 | { 117 | weFrontService.commonWrite(address, "landlordPrestore", Arrays.asList(address, contractId)); 118 | } 119 | 120 | public void backPrestoreMoney(String address, Long contractId) 121 | { 122 | weFrontService.commonWrite(address, "backPrestoreMoney", Arrays.asList(contractId, address)); 123 | } 124 | 125 | public void stopContractTenant(String address, Long contractId) 126 | { 127 | weFrontService.commonWrite(address, "stopContractTenant", Arrays.asList( 128 | contractId, address 129 | )); 130 | } 131 | 132 | public void payRent(String address, PaymentAddTo pt) 133 | { 134 | weFrontService.commonWrite(address, "payRent", Arrays.asList( 135 | pt.getPayerId(), 136 | pt.getContractId(), 137 | pt.getMoney() 138 | )); 139 | } 140 | 141 | public void getPayRent(Long paymentId, PaymentVo paymentVo) 142 | { 143 | ContractResponse response = weFrontService.commonRead("getPayRent", Arrays.asList(paymentId)); 144 | JSONArray vals = response.getVals(); 145 | paymentVo.setMoney(Convert.hexToInt(vals.getStr(2))); 146 | } 147 | 148 | public void stopContractLandlord(String address, Long contractId) 149 | { 150 | weFrontService.commonWrite(address, "stopContractLandlord", Arrays.asList( 151 | contractId, address 152 | )); 153 | } 154 | 155 | 156 | } 157 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/PaymentService.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service; 2 | 3 | import com.jzm.backme.domain.Payment; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | import com.jzm.backme.model.to.payment.PaymentQueryTo; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | *

11 | * 缴纳记录表 -- 记录租金缴纳信息 服务类 12 | *

13 | * 14 | * @author qhx2004 15 | * @since 2024-04-14 16 | */ 17 | public interface PaymentService extends IService { 18 | 19 | List getAll(PaymentQueryTo qt); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/RoleService.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service; 2 | 3 | import com.jzm.backme.domain.Role; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | /** 7 | *

8 | * 角色表 服务类 9 | *

10 | * 11 | * @author qhx2004 12 | * @since 2024-04-14 13 | */ 14 | public interface RoleService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/UserRoleService.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service; 2 | 3 | import com.jzm.backme.domain.Role; 4 | import com.jzm.backme.domain.UserRole; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | /** 8 | *

9 | * 用户 - 角色表 服务类 10 | *

11 | * 12 | * @author qhx2004 13 | * @since 2024-04-14 14 | */ 15 | public interface UserRoleService extends IService { 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service; 2 | 3 | import com.jzm.backme.domain.Role; 4 | import com.jzm.backme.domain.User; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.jzm.backme.model.to.user.PassTo; 7 | import com.jzm.backme.model.to.user.UserPassTo; 8 | import com.jzm.backme.model.to.user.UserQueryTo; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | *

14 | * 用户表 -- 存储用户信息 服务类 15 | *

16 | * 17 | * @author qhx2004 18 | * @since 2024-04-14 19 | */ 20 | public interface UserService extends IService { 21 | 22 | User getOne(String phone, String password); 23 | 24 | List getAll(UserQueryTo queryTo); 25 | 26 | boolean checkPhoneUnique(String phone); 27 | boolean checkPhoneUpUnique(String phone); 28 | 29 | boolean checkPassUnique(String password); 30 | boolean isPasswordExists(String oldPassword); 31 | 32 | boolean checkMd5PassUnique(String password); 33 | 34 | boolean checkUserUnique(String user); 35 | 36 | Role getRole(Long userId); 37 | 38 | boolean updateStatus(User user); 39 | boolean updatePass(UserPassTo upt); 40 | 41 | boolean updatePass(PassTo passTo); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/impl/ContractServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 4 | import com.baomidou.mybatisplus.core.toolkit.support.SFunction; 5 | import com.jzm.backme.constant.Constant; 6 | import com.jzm.backme.domain.Contract; 7 | import com.jzm.backme.mapper.ContractMapper; 8 | import com.jzm.backme.model.to.contract.ContractQueryTo; 9 | import com.jzm.backme.service.ContractService; 10 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 11 | import com.jzm.backme.util.StringUtil; 12 | import org.springframework.stereotype.Service; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | *

18 | * 合同表 -- 存储合同信息 服务实现类 19 | *

20 | * 21 | * @author qhx2004 22 | * @since 2024-04-14 23 | */ 24 | @Service 25 | public class ContractServiceImpl extends ServiceImpl implements ContractService { 26 | 27 | @Override 28 | public List getAll(ContractQueryTo contractQueryTo) 29 | { 30 | Long landlordId = contractQueryTo.getLandlordId(); 31 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() 32 | .eq(StringUtil.isNotEmpty(landlordId), Contract::getLandlordId, landlordId); 33 | 34 | return this.list(queryWrapper); 35 | } 36 | 37 | @Override 38 | public Contract getOne(SFunction column, Object val) 39 | { 40 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() 41 | .eq(column, val); 42 | return this.getOne(queryWrapper); 43 | } 44 | 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/impl/HouseServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 4 | import com.jzm.backme.model.to.house.HouseQueryTo; 5 | import com.jzm.backme.model.to.user.UserQueryTo; 6 | import com.jzm.backme.domain.House; 7 | import com.jzm.backme.mapper.HouseMapper; 8 | import com.jzm.backme.service.HouseService; 9 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 10 | import com.jzm.backme.util.StringUtil; 11 | import org.springframework.stereotype.Service; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | *

17 | * 房屋表 -- 存储房屋信息 服务实现类 18 | *

19 | * 20 | * @author qhx2004 21 | * @since 2024-04-14 22 | */ 23 | @Service 24 | public class HouseServiceImpl extends ServiceImpl implements HouseService { 25 | 26 | @Override 27 | public List getAll(HouseQueryTo houseQueryTo) 28 | { 29 | String linkPhone = houseQueryTo.getLinkPhone(); 30 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() 31 | .eq(StringUtil.isNotEmpty(linkPhone),House::getLinkPhone,linkPhone); 32 | 33 | return this.list(queryWrapper); 34 | } 35 | 36 | @Override 37 | public boolean updateStatus(House house) 38 | { 39 | Long houseId = house.getHouseId(); 40 | House newHouse = new House(); 41 | 42 | newHouse.setHouseId(houseId); 43 | newHouse.setStatus(house.getStatus()); 44 | LambdaQueryWrapper updateWrapper = new LambdaQueryWrapper() 45 | .eq(House::getHouseId, houseId); 46 | 47 | return this.update(newHouse,updateWrapper); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/impl/PaymentServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 4 | import com.jzm.backme.domain.Payment; 5 | import com.jzm.backme.mapper.PaymentMapper; 6 | import com.jzm.backme.model.to.payment.PaymentQueryTo; 7 | import com.jzm.backme.service.PaymentService; 8 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 9 | import com.jzm.backme.util.StringUtil; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | *

16 | * 缴纳记录表 -- 记录租金缴纳信息 服务实现类 17 | *

18 | * 19 | * @author qhx2004 20 | * @since 2024-04-14 21 | */ 22 | @Service 23 | public class PaymentServiceImpl extends ServiceImpl implements PaymentService { 24 | 25 | @Override 26 | public List getAll(PaymentQueryTo qt) 27 | { 28 | String payer = qt.getPayer(); 29 | String contractNum = qt.getContractNum(); 30 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() 31 | .eq(StringUtil.isNotEmpty(payer), Payment::getPayer, payer) 32 | .eq(StringUtil.isNotEmpty(contractNum),Payment::getContractNum,contractNum); 33 | 34 | 35 | return this.list(queryWrapper); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/impl/RoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service.impl; 2 | 3 | import com.jzm.backme.domain.Role; 4 | import com.jzm.backme.mapper.RoleMapper; 5 | import com.jzm.backme.service.RoleService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 角色表 服务实现类 12 | *

13 | * 14 | * @author qhx2004 15 | * @since 2024-04-14 16 | */ 17 | @Service 18 | public class RoleServiceImpl extends ServiceImpl implements RoleService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/impl/UserRoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service.impl; 2 | 3 | import com.jzm.backme.domain.UserRole; 4 | import com.jzm.backme.mapper.UserRoleMapper; 5 | import com.jzm.backme.service.UserRoleService; 6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 用户 - 角色表 服务实现类 12 | *

13 | * 14 | * @author qhx2004 15 | * @since 2024-04-14 16 | */ 17 | @Service 18 | public class UserRoleServiceImpl extends ServiceImpl implements UserRoleService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 4 | import com.baomidou.mybatisplus.core.toolkit.support.SFunction; 5 | import com.jzm.backme.domain.Role; 6 | import com.jzm.backme.domain.User; 7 | import com.jzm.backme.mapper.UserMapper; 8 | import com.jzm.backme.model.to.user.PassTo; 9 | import com.jzm.backme.model.to.user.UserPassTo; 10 | import com.jzm.backme.model.to.user.UserQueryTo; 11 | import com.jzm.backme.service.UserService; 12 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 13 | import com.jzm.backme.util.StringUtil; 14 | import com.jzm.backme.util.user.UserUtil; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.stereotype.Service; 17 | 18 | import java.util.List; 19 | 20 | /** 21 | *

22 | * 用户表 -- 存储用户信息 服务实现类 23 | *

24 | * 25 | * @author qhx2004 26 | * @since 2024-04-14 27 | */ 28 | @Service 29 | public class UserServiceImpl extends ServiceImpl implements UserService { 30 | 31 | @Autowired 32 | private UserMapper userMapper; 33 | 34 | @Override 35 | public User getOne(String phone, String password) 36 | { 37 | password = UserUtil.cryptPass(password); 38 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() 39 | .eq(User::getPhone, phone).eq(User::getPassword, password); 40 | 41 | return this.getOne(queryWrapper); 42 | } 43 | 44 | @Override 45 | public List getAll(UserQueryTo queryTo) 46 | { 47 | String phone = queryTo.getPhone(); 48 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() 49 | .eq(StringUtil.isNotEmpty(phone), User::getPhone, phone); 50 | return this.list(queryWrapper); 51 | } 52 | 53 | @Override 54 | public boolean checkPhoneUnique(String phone) 55 | { 56 | return checkFieldUnique(User::getPhone,phone); 57 | } 58 | 59 | @Override 60 | public boolean checkPhoneUpUnique(String phone) 61 | { 62 | User one = getOne(User::getPhone, phone); 63 | if( StringUtil.isEmpty(one) || one.getPhone().equals(phone)){ 64 | return true; 65 | } 66 | return false; 67 | } 68 | 69 | @Override 70 | public boolean checkPassUnique(String password) 71 | { 72 | password = UserUtil.cryptPass(password); 73 | return checkMd5PassUnique(password); 74 | } 75 | 76 | @Override 77 | public boolean isPasswordExists(String oldPassword) 78 | { 79 | return !checkPassUnique(oldPassword); 80 | } 81 | 82 | @Override 83 | public boolean checkMd5PassUnique(String password) 84 | { 85 | return checkFieldUnique(User::getPassword,password); 86 | } 87 | 88 | @Override 89 | public boolean checkUserUnique(String user) 90 | { 91 | return checkFieldUnique(User::getUser,user); 92 | } 93 | 94 | private boolean checkFieldUnique(SFunction column,Object val){ 95 | User one = getOne(column,val); 96 | if(StringUtil.isEmpty(one)){ 97 | return true; 98 | } 99 | return false; 100 | } 101 | 102 | private User getOne(SFunction column,Object val){ 103 | LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() 104 | .eq(column, val); 105 | return this.getOne(queryWrapper); 106 | } 107 | 108 | @Override 109 | public Role getRole(Long userId) 110 | { 111 | return userMapper.selectRole(userId); 112 | } 113 | 114 | @Override 115 | public boolean updateStatus(User user) 116 | { 117 | Long userId = user.getUserId(); 118 | LambdaQueryWrapper updateWrapper = new LambdaQueryWrapper() 119 | .eq(User::getUserId, userId); 120 | User newUser = new User(); 121 | newUser.setUserId(userId); 122 | newUser.setStatus(user.getStatus()); 123 | return this.update(newUser,updateWrapper); 124 | } 125 | 126 | @Override 127 | public boolean updatePass(UserPassTo upt) 128 | { 129 | String password = upt.getPassword(); 130 | String newPassword = upt.getNewPassword(); 131 | LambdaQueryWrapper updateWrapper = new LambdaQueryWrapper() 132 | .eq(User::getPassword, password); 133 | User newUser = new User(); 134 | newUser.setPassword(newPassword); 135 | return this.update(newUser,updateWrapper); 136 | } 137 | 138 | @Override 139 | public boolean updatePass(PassTo passTo) 140 | { 141 | String oldPassword = passTo.getOldPassword(); 142 | oldPassword = UserUtil.cryptPass(oldPassword); 143 | 144 | String newPassword = passTo.getNewPassword(); 145 | newPassword = UserUtil.cryptPass(newPassword); 146 | 147 | UserPassTo userPassTo = new UserPassTo(oldPassword, newPassword); 148 | return updatePass(userPassTo); 149 | } 150 | 151 | 152 | } 153 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/util/Convert.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.util; 2 | 3 | /** 4 | * @author: jzm 5 | * @date: 2024-04-17 08:44 6 | **/ 7 | 8 | public class Convert 9 | { 10 | /** 11 | * 16进制字符串(0x开头的)-数字 12 | * @return 13 | */ 14 | public static Integer hexToInt(String val){ 15 | if(val.startsWith("0x")){ 16 | val = val.substring("0x".length()); 17 | }else{ 18 | return Integer.parseInt(val); 19 | } 20 | return Integer.parseInt(val, 16); 21 | } 22 | 23 | public static Long hexToLong(String val) 24 | { 25 | return Long.parseLong(hexToInt(val).toString()); 26 | } 27 | 28 | 29 | public static String boolConv(Boolean bool){ 30 | if(!bool){ 31 | return "0"; 32 | }else{ 33 | return "1"; 34 | } 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/util/DateUtil.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.util; 2 | 3 | import java.time.LocalDateTime; 4 | import java.time.ZoneId; 5 | import java.time.ZoneOffset; 6 | import java.time.ZonedDateTime; 7 | import java.util.Date; 8 | 9 | /** 10 | * @author: jzm 11 | * @date: 2024-04-17 09:11 12 | **/ 13 | 14 | public class DateUtil extends cn.hutool.core.date.DateUtil 15 | { 16 | 17 | 18 | public static final long S = 1000L; 19 | public static final long M = S * 60; 20 | public static final long H = M * 60; 21 | public static final long D = H * 24; 22 | 23 | public static LocalDateTime parseLDTs(String s_timestamp){ 24 | // 是否为16进制数字 25 | if(s_timestamp.startsWith("0x")){ 26 | s_timestamp = s_timestamp.substring("0x".length()); 27 | } 28 | return parseLDTms(String.valueOf(Long.parseLong(s_timestamp) * 1000)); 29 | } 30 | 31 | public static LocalDateTime parseLDT(String s_timestamp){ 32 | return parseLDTs(s_timestamp); 33 | } 34 | 35 | public static LocalDateTime parseLDTms(String ms_timestamp){ 36 | if(ms_timestamp.startsWith("0x")){ 37 | ms_timestamp = ms_timestamp.substring("0x".length()); 38 | } 39 | Date date = new Date(Long.parseLong(ms_timestamp)); 40 | String dateTime = formatDateTime(date); 41 | return DateUtil.parseLocalDateTime(dateTime); 42 | } 43 | 44 | public static int compare(LocalDateTime d1,LocalDateTime d2){ 45 | Date date1 = localToDate(d1); 46 | Date date2 = localToDate(d2); 47 | return DateUtil.compare(date1,date2); 48 | } 49 | 50 | 51 | public static LocalDateTime addTime(LocalDateTime source,int day){ 52 | Long end = datetimeToTimestamp(source); 53 | end = end + day * D; 54 | return parseLDTms(String.valueOf(end)); 55 | } 56 | 57 | public static Date localToDate(LocalDateTime localDateTime){ 58 | ZonedDateTime l1 = localDateTime.atZone(ZoneId.systemDefault()); 59 | return Date.from(l1.toInstant()); 60 | } 61 | 62 | 63 | public static Long datetimeToTimestamp(LocalDateTime beginEndTime) 64 | { 65 | return beginEndTime.toInstant(ZoneOffset.of("+8")).toEpochMilli(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/util/NotEmptyUtil.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.util; 2 | 3 | import com.jzm.backme.annotation.NotEmpty; 4 | import lombok.extern.slf4j.Slf4j; 5 | 6 | import java.lang.reflect.Field; 7 | 8 | /** 9 | *

自定义字段检验工具类

10 | * 11 | * 配合 @NotEmpty + 反射:实现被该注解注释字段,校验空值。如果该注解没元数据 12 | * 则: 字段名 + 不能为空 13 | * 14 | * 15 | * @author: jzm 16 | * @date: 2024-03-08 10:56 17 | **/ 18 | 19 | @Slf4j 20 | public class NotEmptyUtil 21 | { 22 | 23 | 24 | public static String checkEmptyFiled(Object obj,String ...fileNames) 25 | { 26 | return checkEmptyFiled(obj,obj.getClass(),fileNames); 27 | } 28 | 29 | /** 30 | * 检验字段是否空 31 | * 32 | * @param obj 检验对象 33 | * @param fileNames 忽略字段列表 34 | * @return 第一个空字段 35 | */ 36 | public static String checkEmptyFiled(Object obj,Class cls,String ...fileNames) 37 | { 38 | NotEmpty notEmptyCls = cls.getAnnotation(NotEmpty.class); // 类获取的空 39 | Field[] fields = cls.getDeclaredFields(); 40 | for (Field field : fields) 41 | { 42 | field.setAccessible(true); 43 | try 44 | { 45 | // 忽略字段 46 | String fileName = field.getName(); 47 | if(StringUtil.equalsAny(fileName,fileNames)) 48 | { 49 | continue; 50 | } 51 | // 获取字段值 52 | Object value = field.get(obj); 53 | // 其他类型(不校验非引用类型) 54 | if(StringUtil.isEmpty(value)) 55 | { 56 | String end = checkFileIsAn(field); // 检查字段是否注解 57 | if(end != null) 58 | { 59 | return end; 60 | } 61 | if(notEmptyCls != null && notEmptyCls.required()){ // 检查是否类标记注解 62 | return fileName + "不能为空"; 63 | } 64 | } 65 | // 字符串类型: "" 值 66 | if(value instanceof String){ 67 | if(StringUtil.isEmpty(value.toString())) 68 | { 69 | String end = checkFileIsAn(field); // 检查字段是否注解 70 | if(end != null) 71 | { 72 | return end; 73 | } 74 | if(notEmptyCls != null && notEmptyCls.required()){ // 检查是否类标记注解 75 | return fileName + "不能为空"; 76 | } 77 | } 78 | } 79 | // 是对象类型校验对象 80 | //if(value != null && value.getClass().isInstance(value)){ 81 | // Class fieldType = value.getClass(); 82 | // String res = checkEmptyFiled(value, fieldType, fileNames); 83 | // if(StringUtil.isNotEmpty(res)){ 84 | // return res; 85 | // } 86 | //} 87 | 88 | } catch (IllegalAccessException e) 89 | { 90 | log.error("读取字段异常:"+e.getMessage()); 91 | return null; 92 | } catch (Exception e) 93 | { 94 | log.error(e.getMessage()); 95 | } 96 | } 97 | if( cls.getSuperclass() == Object.class) // 到这结束递归 98 | { 99 | return null; 100 | } 101 | return checkEmptyFiled(obj,cls.getSuperclass(),fileNames); 102 | } 103 | 104 | 105 | private static String checkFileIsAn(Field field) 106 | { 107 | NotEmpty verifyField = field.getAnnotation(NotEmpty.class); 108 | if (verifyField != null && verifyField.required()){ 109 | if(StringUtil.isEmpty(verifyField.extra())) 110 | { 111 | return field.getName() + "不能为空!"; 112 | } 113 | return verifyField.extra() + "不能为空!" ; 114 | } 115 | return null; 116 | } 117 | 118 | 119 | 120 | 121 | } 122 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/util/PageUtil.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.util; 2 | 3 | import com.github.pagehelper.ISelect; 4 | import com.github.pagehelper.Page; 5 | import com.github.pagehelper.PageHelper; 6 | import com.github.pagehelper.PageInfo; 7 | 8 | 9 | /** 10 | * 分页工具类 11 | */ 12 | public class PageUtil 13 | { 14 | private static Page _startPage(int pageNum, int pageSize, ISelect select, String orderBy) 15 | { 16 | clearPage(); 17 | Page page = PageHelper.startPage(pageNum, pageSize).doSelectPage(select); 18 | if (orderBy == null) 19 | { 20 | return page; 21 | } 22 | page.setOrderBy(orderBy); 23 | return page; 24 | } 25 | 26 | /** 27 | * 分页 28 | * 29 | * page 起始页 30 | * pageSize 页大小 31 | * 32 | * @param select : () -> userMapper.list() 33 | */ 34 | public static PageInfo startPage(int pageNum, int pageSize, ISelect select) 35 | { 36 | return new PageInfo<>(_startPage(pageNum, pageSize, select, null)); 37 | } 38 | 39 | /** 40 | * 降序 + 分页 41 | */ 42 | public static PageInfo orderByDesc(int pageNum, int pageSize, String filed, ISelect select) 43 | { 44 | return new PageInfo<>(_startPage(pageNum, pageSize, select, filed + " desc")); 45 | } 46 | 47 | 48 | /** 49 | * 升序 + 分页 50 | */ 51 | public static PageInfo orderByAsc(int pageNum, int pageSize, String filed, ISelect select) 52 | { 53 | return new PageInfo<>(_startPage(pageNum, pageSize, select, filed + " asc")); 54 | } 55 | 56 | /** 57 | * 清理分页的线程变量(清除分页数据) 58 | */ 59 | public static void clearPage() 60 | { 61 | PageHelper.clearPage(); 62 | } 63 | 64 | 65 | } 66 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/util/ServletUtil.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.util; 2 | 3 | import cn.hutool.core.convert.Convert; 4 | import com.jzm.backme.constant.Constant; 5 | import org.springframework.web.context.request.RequestAttributes; 6 | import org.springframework.web.context.request.RequestContextHolder; 7 | import org.springframework.web.context.request.ServletRequestAttributes; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | import javax.servlet.http.HttpServletResponse; 11 | import javax.servlet.http.HttpSession; 12 | import java.io.IOException; 13 | import java.io.UnsupportedEncodingException; 14 | import java.net.URLDecoder; 15 | import java.net.URLEncoder; 16 | import java.util.Enumeration; 17 | import java.util.List; 18 | 19 | /** 20 | * 客户端工具类 21 | * 22 | * @author ruoyi 23 | */ 24 | public class ServletUtil 25 | { 26 | /** 27 | * 定义移动端请求的所有可能类型 28 | */ 29 | private final static String[] agent = { "Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser" }; 30 | 31 | /** 32 | * 获取String参数 33 | */ 34 | public static String getParameter(String name) 35 | { 36 | return getRequest().getParameter(name); 37 | } 38 | 39 | /** 40 | * 获取String参数 41 | */ 42 | public static String getParameter(String name, String defaultValue) 43 | { 44 | return Convert.toStr(getRequest().getParameter(name), defaultValue); 45 | } 46 | 47 | /** 48 | * 获取Integer参数 49 | */ 50 | public static Integer getParameterToInt(String name) 51 | { 52 | return Convert.toInt(getRequest().getParameter(name)); 53 | } 54 | 55 | /** 56 | * 获取Integer参数 57 | */ 58 | public static Integer getParameterToInt(String name, Integer defaultValue) 59 | { 60 | return Convert.toInt(getRequest().getParameter(name), defaultValue); 61 | } 62 | 63 | /** 64 | * 获取Boolean参数 65 | */ 66 | public static Boolean getParameterToBool(String name) 67 | { 68 | return Convert.toBool(getRequest().getParameter(name)); 69 | } 70 | 71 | /** 72 | * 获取Boolean参数 73 | */ 74 | public static Boolean getParameterToBool(String name, Boolean defaultValue) 75 | { 76 | return Convert.toBool(getRequest().getParameter(name), defaultValue); 77 | } 78 | 79 | /** 80 | * 获取request 81 | */ 82 | public static HttpServletRequest getRequest() 83 | { 84 | return getRequestAttributes().getRequest(); 85 | } 86 | 87 | /** 88 | * 获取Header 89 | */ 90 | 91 | public static String getHeader(String name){ 92 | return getRequest().getHeader(name); 93 | } 94 | 95 | public static Enumeration getHeaders(String name){ 96 | return getRequest().getHeaders(name); 97 | } 98 | 99 | 100 | 101 | /** 102 | * 获取response 103 | */ 104 | public static HttpServletResponse getResponse() 105 | { 106 | return getRequestAttributes().getResponse(); 107 | } 108 | 109 | /** 110 | * 获取session 111 | */ 112 | public static HttpSession getSession() 113 | { 114 | return getRequest().getSession(); 115 | } 116 | 117 | public static ServletRequestAttributes getRequestAttributes() 118 | { 119 | RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); 120 | return (ServletRequestAttributes) attributes; 121 | } 122 | 123 | /** 124 | * 将字符串渲染到客户端 125 | * 126 | * @param response 渲染对象 127 | * @param string 待渲染的字符串 128 | * @return null 129 | */ 130 | public static String renderString(HttpServletResponse response, String string) 131 | { 132 | try 133 | { 134 | response.setContentType("application/json"); 135 | response.setCharacterEncoding("utf-8"); 136 | response.getWriter().print(string); 137 | } 138 | catch (IOException e) 139 | { 140 | e.printStackTrace(); 141 | } 142 | return null; 143 | } 144 | 145 | /** 146 | * 是否是Ajax异步请求 147 | * 148 | * @param request 149 | */ 150 | public static boolean isAjaxRequest(HttpServletRequest request) 151 | { 152 | String accept = request.getHeader("accept"); 153 | if (accept != null && accept.contains("application/json")) 154 | { 155 | return true; 156 | } 157 | 158 | String xRequestedWith = request.getHeader("X-Requested-With"); 159 | if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) 160 | { 161 | return true; 162 | } 163 | 164 | String uri = request.getRequestURI(); 165 | if (StringUtil.inStringIgnoreCase(uri, ".json", ".xml")) 166 | { 167 | return true; 168 | } 169 | 170 | String ajax = request.getParameter("__ajax"); 171 | return StringUtil.inStringIgnoreCase(ajax, "json", "xml"); 172 | } 173 | 174 | /** 175 | * 判断User-Agent 是不是来自于手机 176 | */ 177 | public static boolean checkAgentIsMobile(String ua) 178 | { 179 | boolean flag = false; 180 | if (!ua.contains("Windows NT") || (ua.contains("Windows NT") && ua.contains("compatible; MSIE 9.0;"))) 181 | { 182 | // 排除 苹果桌面系统 183 | if (!ua.contains("Windows NT") && !ua.contains("Macintosh")) 184 | { 185 | for (String item : agent) 186 | { 187 | if (ua.contains(item)) 188 | { 189 | flag = true; 190 | break; 191 | } 192 | } 193 | } 194 | } 195 | return flag; 196 | } 197 | 198 | /** 199 | * 内容编码 200 | * 201 | * @param str 内容 202 | * @return 编码后的内容 203 | */ 204 | public static String urlEncode(String str) 205 | { 206 | try 207 | { 208 | return URLEncoder.encode(str, Constant.UTF_8); 209 | } 210 | catch (UnsupportedEncodingException e) 211 | { 212 | return StringUtil.EMPTY; 213 | } 214 | } 215 | 216 | /** 217 | * 内容解码(utf-8解码) 218 | * 219 | * @param str 内容 220 | * @return 解码后的内容 221 | */ 222 | public static String urlDecode(String str) 223 | { 224 | try 225 | { 226 | return URLDecoder.decode(str, Constant.UTF_8); 227 | } 228 | catch (UnsupportedEncodingException e) 229 | { 230 | return StringUtil.EMPTY; 231 | } 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/util/StringUtil.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.util; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | 5 | import java.util.Objects; 6 | 7 | /** 8 | * String 工具类 9 | * 10 | * @author: jzm 11 | * @date: 2024-01-08 19:44 12 | **/ 13 | 14 | public class StringUtil extends StrUtil 15 | { 16 | 17 | public static boolean equals(Object a,Object b){ 18 | return Objects.equals(a, b) || StringUtil.equals(a.toString(),b.toString()); 19 | } 20 | 21 | /** 22 | * 是空字符串? 23 | * 24 | * @param str 25 | * @return true:为空 false:非空 26 | */ 27 | public static boolean isEmpty(CharSequence str) 28 | { 29 | if (StrUtil.isEmpty(str)) 30 | { 31 | return true; 32 | } 33 | if (str instanceof String) 34 | { 35 | if (((String) str).trim().equals("")) 36 | { 37 | return true; 38 | } 39 | } 40 | return false; 41 | } 42 | 43 | /** 44 | * 是空? 45 | * 46 | * @param obj 对象 47 | * @return true:为空 false:非空 48 | */ 49 | public static boolean isEmpty(Object obj) 50 | { 51 | return obj == null; 52 | } 53 | 54 | /** 55 | * 不是空? 56 | * 57 | * @param str 58 | * @return true:非空 false:为空 59 | */ 60 | public static boolean isNotEmpty(CharSequence str) 61 | { 62 | return !isEmpty(str); 63 | } 64 | 65 | public static boolean isNotEmpty(Object obj) 66 | { 67 | return !isEmpty(obj); 68 | } 69 | 70 | /** 71 | * 判断字符串列表是否包含被包含字符串 72 | * 73 | * @param str 被包含字符串 74 | * @param strs 字符串列表 75 | * @return 包含返回true 76 | */ 77 | public static boolean inStringIgnoreCase(String str, String... strs) 78 | { 79 | if (str != null && strs != null) 80 | { 81 | for (String s : strs) 82 | { 83 | if (s.equalsIgnoreCase(str)) 84 | { 85 | return true; 86 | } 87 | } 88 | return false; 89 | } 90 | return false; 91 | } 92 | 93 | public static boolean isNull(Object obj) 94 | { 95 | return obj == null; 96 | } 97 | 98 | public static boolean isNotNull(Object obj) 99 | { 100 | return !isNull(obj); 101 | } 102 | 103 | 104 | 105 | 106 | } 107 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/util/TokenUtil.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.util; 2 | 3 | import cn.hutool.crypto.digest.MD5; 4 | import cn.hutool.jwt.JWTUtil; 5 | import com.jzm.backme.constant.Constant; 6 | import java.io.UnsupportedEncodingException; 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | /** 11 | * token工具类 12 | * 13 | * @author: jzm 14 | * @date: 2024-02-26 21:31 15 | **/ 16 | 17 | public class TokenUtil extends JWTUtil 18 | { 19 | private static String CREATE_TIME = "create_time"; 20 | 21 | private static String EXPIRE_TIME = "expire_time"; 22 | 23 | 24 | private static final String SECRET = "abcdefghijklmnopqrstuvwxyz"; 25 | 26 | protected static final long MILLIS_SECOND = 1000; // 单位 1s 27 | 28 | protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; // 单位 1 min 29 | 30 | protected static final Long MILLIS_HOUR = 60 * MILLIS_MINUTE; // 单位 1 hour 31 | protected static final Long MILLIS_DAY = 24 * MILLIS_HOUR; // 单位 1 day 32 | 33 | 34 | 35 | // 默认一天后过期 36 | public static String createToken(Long userId) { 37 | return createToken(userId,MILLIS_DAY); 38 | } 39 | 40 | public static String createTokenByPassWord(String password,long expireTime) { 41 | return createToken(Constant.PASSWORD,password,expireTime); 42 | } 43 | 44 | public static String createToken(Long userId, long expireTime) 45 | { 46 | return createToken(Constant.USER_ID,userId,expireTime); 47 | } 48 | 49 | // 创建令牌 50 | public static String createToken(String key,Object val, long expireTime){ 51 | Map claims = new HashMap<>(); 52 | claims.put(key,val); 53 | claims.put(CREATE_TIME, System.currentTimeMillis()); 54 | claims.put(EXPIRE_TIME, expireTime * MILLIS_MINUTE + System.currentTimeMillis()); 55 | return createToken(claims,SECRET); 56 | } 57 | 58 | 59 | private static String createToken(Map claims,String key) 60 | { 61 | try 62 | { 63 | return TokenUtil.createToken(claims,key.getBytes(Constant.UTF_8)); 64 | } catch (UnsupportedEncodingException e) 65 | { 66 | return null; 67 | } 68 | } 69 | 70 | public static String parseTokenGetUserId(String token) { 71 | return parseTokenGetClaims(token, Constant.USER_ID).toString(); 72 | } 73 | 74 | public static Object parseTokenGetClaims(String token,String name) { 75 | return parseToken(token).getPayload(name); 76 | } 77 | 78 | /** 校验token是否过期 79 | * 80 | * @param token 81 | * @return 82 | */ 83 | public static boolean verify(String token){ 84 | long currentTime = System.currentTimeMillis(); 85 | return Long.parseLong(parseTokenGetClaims(token,EXPIRE_TIME).toString()) > currentTime; 86 | } 87 | 88 | /** 89 | * 校验token从创建时间 - 到现在超过time分钟否 90 | * 91 | * @param token 92 | * @param time 单位 min 93 | * @return 94 | */ 95 | // 按照我们的设计,用户每次携带token,校验, 96 | // 都会去更新这个token创建时间,那么直到我们有很长一次才被校验时,说明我们用户已经长期未登录了。 97 | public static boolean verify(String token,Long time) 98 | { 99 | Long creteTime = Long.valueOf(parseTokenGetClaims(token, CREATE_TIME).toString()); 100 | Long currentTime = System.currentTimeMillis(); 101 | return time > (currentTime - creteTime )/MILLIS_MINUTE; 102 | } 103 | 104 | public static String verifyRefresh(String token) 105 | { 106 | if(verify(token,20L)) // 离线没超过20min 107 | { 108 | Long userId = Long.valueOf(parseTokenGetUserId(token)); 109 | return createToken(userId); 110 | } 111 | return null; 112 | } 113 | 114 | 115 | public static void main(String[] args) 116 | { 117 | System.out.println(MD5.create().digestHex("12345")); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/util/redis/RedisCache.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.util.redis; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.data.redis.core.BoundSetOperations; 5 | import org.springframework.data.redis.core.HashOperations; 6 | import org.springframework.data.redis.core.RedisTemplate; 7 | import org.springframework.data.redis.core.ValueOperations; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.util.*; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | /** 15 | * spring redis 工具类 16 | * 17 | * @author jzm 18 | **/ 19 | @SuppressWarnings(value = {"unchecked", "rawtypes"}) 20 | @Component 21 | @Service 22 | public class RedisCache 23 | { 24 | @Autowired 25 | public RedisTemplate redisTemplate; 26 | /** 27 | * 缓存基本的对象,Integer、String、实体类等 28 | * 29 | * @param key 缓存的键值 30 | * @param value 缓存的值 31 | */ 32 | public void setCacheObject(final String key, final T value) 33 | { 34 | redisTemplate.opsForValue().set(key, value); 35 | } 36 | 37 | /** 38 | * 缓存基本的对象,Integer、String、实体类等 39 | * 40 | * @param key 缓存的键值 41 | * @param value 缓存的值 42 | * @param timeout 时间 43 | * @param timeUnit 时间颗粒度 44 | */ 45 | public void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) 46 | { 47 | redisTemplate.opsForValue().set(key, value, timeout, timeUnit); 48 | } 49 | 50 | /** 51 | * 设置有效时间 52 | * 53 | * @param key Redis键 54 | * @param timeout 超时时间 55 | * @return true=设置成功;false=设置失败 56 | */ 57 | public boolean expire(final String key, final long timeout) 58 | { 59 | return expire(key, timeout, TimeUnit.SECONDS); 60 | } 61 | 62 | /** 63 | * 设置有效时间 64 | * 65 | * @param key Redis键 66 | * @param timeout 超时时间 67 | * @param unit 时间单位 68 | * @return true=设置成功;false=设置失败 69 | */ 70 | public boolean expire(final String key, final long timeout, final TimeUnit unit) 71 | { 72 | return redisTemplate.expire(key, timeout, unit); 73 | } 74 | 75 | /** 76 | * 获取有效时间 77 | * 78 | * @param key Redis键 79 | * @return 有效时间 80 | */ 81 | public long getExpire(final String key) 82 | { 83 | return redisTemplate.getExpire(key); 84 | } 85 | 86 | /** 87 | * 判断 key是否存在 88 | * 89 | * @param key 键 90 | * @return true 存在 false不存在 91 | */ 92 | public Boolean hasKey(String key) 93 | { 94 | return redisTemplate.hasKey(key); 95 | } 96 | 97 | /** 98 | * 获得缓存的基本对象。 99 | * 100 | * @param key 缓存键值 101 | * @return 缓存键值对应的数据 102 | */ 103 | public T getCacheObject(final String key) 104 | { 105 | ValueOperations operation = redisTemplate.opsForValue(); 106 | return operation.get(key); 107 | } 108 | 109 | /** 110 | * 删除单个对象 111 | * 112 | * @param key 113 | */ 114 | public boolean deleteObject(final String key) 115 | { 116 | return redisTemplate.delete(key); 117 | } 118 | 119 | /** 120 | * 删除集合对象 121 | * 122 | * @param collection 多个对象 123 | * @return 124 | */ 125 | public boolean deleteObject(final Collection collection) 126 | { 127 | return redisTemplate.delete(collection) > 0; 128 | } 129 | 130 | /** 131 | * 缓存List数据 132 | * 133 | * @param key 缓存的键值 134 | * @param dataList 待缓存的List数据 135 | * @return 缓存的对象 136 | */ 137 | public long setCacheList(final String key, final List dataList) 138 | { 139 | Long count = redisTemplate.opsForList().rightPushAll(key, dataList); 140 | return count == null ? 0 : count; 141 | } 142 | 143 | /** 144 | * 获得缓存的list对象 145 | * 146 | * @param key 缓存的键值 147 | * @return 缓存键值对应的数据 148 | */ 149 | public List getCacheList(final String key) 150 | { 151 | return redisTemplate.opsForList().range(key, 0, -1); 152 | } 153 | 154 | /** 155 | * 缓存Set 156 | * 157 | * @param key 缓存键值 158 | * @param dataSet 缓存的数据 159 | * @return 缓存数据的对象 160 | */ 161 | public BoundSetOperations setCacheSet(final String key, final Set dataSet) 162 | { 163 | BoundSetOperations setOperation = redisTemplate.boundSetOps(key); 164 | for (T t : dataSet) 165 | { 166 | setOperation.add(t); 167 | } 168 | return setOperation; 169 | } 170 | 171 | /** 172 | * 获得缓存的set 173 | * 174 | * @param key 175 | * @return 176 | */ 177 | public Set getCacheSet(final String key) 178 | { 179 | return redisTemplate.opsForSet().members(key); 180 | } 181 | 182 | /** 183 | * 缓存Map 184 | * 185 | * @param key 186 | * @param dataMap 187 | */ 188 | public void setCacheMap(final String key, final Map dataMap) 189 | { 190 | if (dataMap != null) 191 | { 192 | redisTemplate.opsForHash().putAll(key, dataMap); 193 | } 194 | } 195 | 196 | /** 197 | * 获得缓存的Map 198 | * 199 | * @param key 200 | * @return 201 | */ 202 | public Map getCacheMap(final String key) 203 | { 204 | return redisTemplate.opsForHash().entries(key); 205 | } 206 | 207 | /** 208 | * 往Hash中存入数据 209 | * 210 | * @param key Redis键 211 | * @param hKey Hash键 212 | * @param value 值 213 | */ 214 | public void setCacheMapValue(final String key, final String hKey, final T value) 215 | { 216 | redisTemplate.opsForHash().put(key, hKey, value); 217 | } 218 | 219 | /** 220 | * 获取Hash中的数据 221 | * 222 | * @param key Redis键 223 | * @param hKey Hash键 224 | * @return Hash中的对象 225 | */ 226 | public T getCacheMapValue(final String key, final String hKey) 227 | { 228 | HashOperations opsForHash = redisTemplate.opsForHash(); 229 | return opsForHash.get(key, hKey); 230 | } 231 | 232 | /** 233 | * 获取多个Hash中的数据 234 | * 235 | * @param key Redis键 236 | * @param hKeys Hash键集合 237 | * @return Hash对象集合 238 | */ 239 | public List getMultiCacheMapValue(final String key, final Collection hKeys) 240 | { 241 | return redisTemplate.opsForHash().multiGet(key, hKeys); 242 | } 243 | 244 | /** 245 | * 删除Hash中的某条数据 246 | * 247 | * @param key Redis键 248 | * @param hKey Hash键 249 | * @return 是否成功 250 | */ 251 | public boolean deleteCacheMapValue(final String key, final String hKey) 252 | { 253 | return redisTemplate.opsForHash().delete(key, hKey) > 0; 254 | } 255 | 256 | /** 257 | * 获得缓存的基本对象列表 258 | * 259 | * @param pattern 字符串前缀 260 | * @return 对象列表 261 | */ 262 | public Collection keys(final String pattern) 263 | { 264 | return redisTemplate.keys(pattern); 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /back-me/src/main/java/com/jzm/backme/util/user/UserUtil.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.util.user; 2 | 3 | 4 | import cn.hutool.crypto.digest.MD5; 5 | import com.jzm.backme.constant.UserConstant; 6 | import com.jzm.backme.util.StringUtil; 7 | 8 | import java.time.LocalDateTime; 9 | import java.util.List; 10 | 11 | /** 12 | * 用户工具类(对用户相关参数的校验) 13 | * 14 | * @author: jzm 15 | * @date: 2024-02-28 10:49 16 | **/ 17 | 18 | public class UserUtil 19 | { 20 | 21 | public static String cryptPass(String password){ 22 | return MD5.create().digestHex(password); 23 | } 24 | 25 | public static boolean verifyPassword(String password) { 26 | if (StringUtil.isEmpty(password) || password.length() < UserConstant.PASSWORD_MIN_LENGTH || password.length() > UserConstant.PASSWORD_MAX_LENGTH) { 27 | return false; 28 | } 29 | return true; 30 | } 31 | 32 | public static boolean verifyUsername(String username) { 33 | if (StringUtil.isEmpty(username) || username.length() UserConstant.USERNAME_MAX_LENGTH) { 34 | return false; 35 | } 36 | return true; 37 | } 38 | 39 | public static boolean verifyPhone(String phone) { 40 | return phone.matches(UserConstant.MOBILE_PHONE_NUMBER_PATTERN); 41 | } 42 | 43 | public static boolean isDelete(String flag){ 44 | return UserConstant.EXCEPTION.equals(flag); 45 | } 46 | 47 | public static boolean isDisable(String flag){ 48 | return UserConstant.EXCEPTION.equals(flag); 49 | } 50 | 51 | 52 | public static boolean verifyAccount(String tenant) 53 | { 54 | if(tenant.startsWith("0x") && tenant.length() == 42){ 55 | return true; 56 | } 57 | return false; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /back-me/src/main/resources/application-hikari.yml: -------------------------------------------------------------------------------- 1 | # 数据源配置 2 | spring: 3 | datasource: 4 | type: com.zaxxer.hikari.HikariDataSource 5 | url: jdbc:mysql://localhost:3306/nine?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 6 | username: root 7 | password: 123456 8 | driverClassName: com.mysql.cj.jdbc.Driver 9 | hikari: 10 | maximum-pool-size: 20 11 | auto-commit: true 12 | connection-timeout: 300000 13 | max-lifetime: 1800000 14 | minimum-idle: 5 -------------------------------------------------------------------------------- /back-me/src/main/resources/application-redis.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | # redis 配置 3 | redis: 4 | # 地址 5 | host: 192.168.233.131 6 | # 端口,默认为6379 7 | port: 6379 8 | # 数据库索引 9 | database: 0 10 | # 密码 11 | password: 12 | # 连接超时时间 13 | timeout: 10s 14 | lettuce: 15 | pool: 16 | # 连接池中的最小空闲连接 17 | min-idle: 0 18 | # 连接池中的最大空闲连接 19 | max-idle: 8 20 | # 连接池的最大数据库连接数 21 | max-active: 8 22 | # #连接池最大阻塞等待时间(使用负值表示没有限制) 23 | max-wait: -1ms 24 | -------------------------------------------------------------------------------- /back-me/src/main/resources/conf/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBvTCCAWSgAwIBAgIUe5Dq+UN79J8FcPLUCsvb0RctSS0wCgYIKoZIzj0EAwIw 3 | NTEOMAwGA1UEAwwFY2hhaW4xEzARBgNVBAoMCmZpc2NvLWJjb3MxDjAMBgNVBAsM 4 | BWNoYWluMCAXDTIzMTIwNDA2NDMxNloYDzIxMjMxMTEwMDY0MzE2WjA1MQ4wDAYD 5 | VQQDDAVjaGFpbjETMBEGA1UECgwKZmlzY28tYmNvczEOMAwGA1UECwwFY2hhaW4w 6 | VjAQBgcqhkjOPQIBBgUrgQQACgNCAAQteBjP4iIy7d5xNwW1GCAAi5bKVoydrSjj 7 | zCKjXXoCVZ5AtDJkbPVcZAVjsDHsB5vCdwpO7U+dcqQPGbEeImnEo1MwUTAdBgNV 8 | HQ4EFgQUgdJZ+PurR4/WRE8AZMQS8NpBIEMwHwYDVR0jBBgwFoAUgdJZ+PurR4/W 9 | RE8AZMQS8NpBIEMwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNHADBEAiA9 10 | VuTIuxFI0Z3cu1sHo6k+uRoG8DTg7HtvhRfo2Wg1egIgfMtC4I7InDjCCZg389HH 11 | 5kVvaOwBDaedDrr3tBhDikA= 12 | -----END CERTIFICATE----- 13 | -------------------------------------------------------------------------------- /back-me/src/main/resources/conf/sdk.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBgzCCASmgAwIBAgIUWSelVr59R4Bw2nanXt1aayhqLCswCgYIKoZIzj0EAwIw 3 | NzEPMA0GA1UEAwwGYWdlbmN5MRMwEQYDVQQKDApmaXNjby1iY29zMQ8wDQYDVQQL 4 | DAZhZ2VuY3kwIBcNMjMxMjA0MDY0MzE2WhgPMjEyMzExMTAwNjQzMTZaMDExDDAK 5 | BgNVBAMMA3NkazETMBEGA1UECgwKZmlzY28tYmNvczEMMAoGA1UECwwDc2RrMFYw 6 | EAYHKoZIzj0CAQYFK4EEAAoDQgAE4tnW7Lyyju1twQPrJYtG+SZZ8ML06XCVQlmO 7 | wxeXJP8jFUTxBhH5nz64jz3fT/RSJpMOb5wTm0tso6BX3wPP6KMaMBgwCQYDVR0T 8 | BAIwADALBgNVHQ8EBAMCBeAwCgYIKoZIzj0EAwIDSAAwRQIgc3DZpg/mCnauO+V9 9 | MTuigUmoip7yrsgdzQ/xlpeZOp0CIQDwLmXdTXWWOLaWKFSpldKhEJ5qK5PFAHCB 10 | YO/EizFJZg== 11 | -----END CERTIFICATE----- 12 | -----BEGIN CERTIFICATE----- 13 | MIIBezCCASGgAwIBAgIUCGNvVIwZalLbnIAZ/hgImi8RKK0wCgYIKoZIzj0EAwIw 14 | NTEOMAwGA1UEAwwFY2hhaW4xEzARBgNVBAoMCmZpc2NvLWJjb3MxDjAMBgNVBAsM 15 | BWNoYWluMB4XDTIzMTIwNDA2NDMxNloXDTMzMTIwMTA2NDMxNlowNzEPMA0GA1UE 16 | AwwGYWdlbmN5MRMwEQYDVQQKDApmaXNjby1iY29zMQ8wDQYDVQQLDAZhZ2VuY3kw 17 | VjAQBgcqhkjOPQIBBgUrgQQACgNCAATYNEiWjAmH7MFQNBjVX3pVbAGNnAZ2pn39 18 | wfToxN08Ri6qNVsLrSdkPr1U7Z9wkrRP7MjwoHgS+I14owiNZHgDoxAwDjAMBgNV 19 | HRMEBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIHY0kdzXI4o52rSv7Dl6Z6FBudfO 20 | zpKfo/xVvBPM40oeAiEAuj2EfpVfWb+lm5o2VTykI/5oPaM/tJxRX35h9L3rnW8= 21 | -----END CERTIFICATE----- 22 | -----BEGIN CERTIFICATE----- 23 | MIIBvTCCAWSgAwIBAgIUe5Dq+UN79J8FcPLUCsvb0RctSS0wCgYIKoZIzj0EAwIw 24 | NTEOMAwGA1UEAwwFY2hhaW4xEzARBgNVBAoMCmZpc2NvLWJjb3MxDjAMBgNVBAsM 25 | BWNoYWluMCAXDTIzMTIwNDA2NDMxNloYDzIxMjMxMTEwMDY0MzE2WjA1MQ4wDAYD 26 | VQQDDAVjaGFpbjETMBEGA1UECgwKZmlzY28tYmNvczEOMAwGA1UECwwFY2hhaW4w 27 | VjAQBgcqhkjOPQIBBgUrgQQACgNCAAQteBjP4iIy7d5xNwW1GCAAi5bKVoydrSjj 28 | zCKjXXoCVZ5AtDJkbPVcZAVjsDHsB5vCdwpO7U+dcqQPGbEeImnEo1MwUTAdBgNV 29 | HQ4EFgQUgdJZ+PurR4/WRE8AZMQS8NpBIEMwHwYDVR0jBBgwFoAUgdJZ+PurR4/W 30 | RE8AZMQS8NpBIEMwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNHADBEAiA9 31 | VuTIuxFI0Z3cu1sHo6k+uRoG8DTg7HtvhRfo2Wg1egIgfMtC4I7InDjCCZg389HH 32 | 5kVvaOwBDaedDrr3tBhDikA= 33 | -----END CERTIFICATE----- 34 | -------------------------------------------------------------------------------- /back-me/src/main/resources/conf/sdk.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgOieuhKo81RmTgxlh52HO 3 | aASLbrrLPd2GtbaNkmLOYWuhRANCAATi2dbsvLKO7W3BA+sli0b5JlnwwvTpcJVC 4 | WY7DF5ck/yMVRPEGEfmfPriPPd9P9FImkw5vnBObS2yjoFffA8/o 5 | -----END PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /back-me/src/main/resources/mapper/ContractMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /back-me/src/main/resources/mapper/HouseMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /back-me/src/main/resources/mapper/PaymentMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /back-me/src/main/resources/mapper/RoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /back-me/src/main/resources/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /back-me/src/main/resources/mapper/UserRoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /back-me/src/test/java/com/jzm/backme/BackMeApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 4 | import com.jzm.backme.config.fisco.FiscoConfig; 5 | import com.jzm.backme.domain.User; 6 | import com.jzm.backme.service.MainContractService; 7 | import com.jzm.backme.service.UserService; 8 | import com.jzm.backme.util.redis.RedisCache; 9 | import org.fisco.bcos.sdk.client.Client; 10 | import org.fisco.bcos.sdk.crypto.signature.SignatureResult; 11 | import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor; 12 | import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionWithRemoteSignProcessor; 13 | import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory; 14 | import org.fisco.bcos.sdk.transaction.signer.RemoteSignCallbackInterface; 15 | import org.fisco.bcos.sdk.transaction.signer.RemoteSignProviderInterface; 16 | import org.junit.jupiter.api.Test; 17 | import org.springframework.boot.test.context.SpringBootTest; 18 | 19 | import javax.annotation.Resource; 20 | import java.util.ArrayList; 21 | 22 | @SpringBootTest 23 | class BackMeApplicationTests 24 | { 25 | 26 | 27 | @Resource 28 | private FiscoConfig fiscoConfig; 29 | 30 | @Resource 31 | private MainContractService mainContractService; 32 | 33 | 34 | AssembleTransactionWithRemoteSignProcessor txProcessor; 35 | 36 | @Test 37 | void fiscoConnetcTest() 38 | { 39 | ArrayList params = new ArrayList<>(); 40 | String calAdd = "0xa5c4f1b07f513a586b19be93fd44966bcbd5d2c5"; 41 | params.add(calAdd); 42 | params.add(2); 43 | String add1 = "0x3269c74547b619586160e462ee1d47366e2a7c64"; 44 | System.out.println(12); 45 | 46 | } 47 | 48 | @Resource 49 | private Client client; 50 | 51 | 52 | @Test 53 | void sendTransactionTest() throws Exception 54 | { 55 | AssembleTransactionProcessor assembleTransactionProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(client, client.getCryptoSuite().getCryptoKeyPair()); 56 | String address = client.getCryptoSuite().getCryptoKeyPair().getAddress(); 57 | System.out.println(12); 58 | 59 | } 60 | 61 | @Resource 62 | private UserService userService; 63 | 64 | @Resource 65 | private RedisCache redisCache; 66 | 67 | 68 | @Test 69 | void Test() throws Exception 70 | { 71 | User user = new User(); 72 | user.setUserId(1L); 73 | user.setPassword("e10adc3949ba59abbe56e057f20f883e"); 74 | 75 | LambdaQueryWrapper wrapper = new LambdaQueryWrapper() 76 | .eq(User::getUserId, user.getUserId()); 77 | boolean update = userService.update(user, wrapper); 78 | } 79 | 80 | 81 | @Test 82 | void redisTest() throws Exception 83 | { 84 | redisCache.setCacheObject("qhx",12); 85 | } 86 | 87 | 88 | 89 | 90 | 91 | 92 | } 93 | -------------------------------------------------------------------------------- /back-me/src/test/java/com/jzm/backme/service/TestServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service; 2 | 3 | import org.fisco.bcos.sdk.abi.ABICodec; 4 | import org.fisco.bcos.sdk.abi.ABICodecException; 5 | import org.fisco.bcos.sdk.client.Client; 6 | import org.fisco.bcos.sdk.crypto.signature.SignatureResult; 7 | import org.fisco.bcos.sdk.model.TransactionReceipt; 8 | import org.fisco.bcos.sdk.transaction.builder.TransactionBuilderService; 9 | import org.fisco.bcos.sdk.transaction.codec.encode.TransactionEncoderService; 10 | import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionWithRemoteSignProcessor; 11 | import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory; 12 | import org.fisco.bcos.sdk.transaction.model.dto.CallResponse; 13 | import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse; 14 | import org.fisco.bcos.sdk.transaction.model.exception.TransactionBaseException; 15 | import org.fisco.bcos.sdk.transaction.model.po.RawTransaction; 16 | import org.fisco.bcos.sdk.transaction.pusher.TransactionPusherService; 17 | import org.fisco.bcos.sdk.transaction.signer.RemoteSignCallbackInterface; 18 | import org.fisco.bcos.sdk.transaction.signer.RemoteSignProviderInterface; 19 | import org.fisco.bcos.sdk.utils.Hex; 20 | import org.junit.jupiter.api.Test; 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.boot.test.context.SpringBootTest; 23 | 24 | import java.math.BigInteger; 25 | import java.util.ArrayList; 26 | import java.util.concurrent.CompletableFuture; 27 | 28 | /** 29 | * @author: jzm 30 | * @date: 2024-04-26 08:30 31 | **/ 32 | 33 | @SpringBootTest 34 | public class TestServiceTest 35 | { 36 | 37 | @Autowired 38 | private Client client; 39 | 40 | 41 | /** 42 | * 外部签名调用合约(除了组成调用的处理器差不多,其余感觉用法上没啥差别) 43 | */ 44 | @Test 45 | public void test() throws ABICodecException, TransactionBaseException 46 | { 47 | CustomExternalSignAndCallBack externalSign = new CustomExternalSignAndCallBack(); 48 | 49 | AssembleTransactionWithRemoteSignProcessor asWt = 50 | TransactionProcessorFactory.createAssembleTransactionWithRemoteSignProcessor( 51 | client, client.getCryptoSuite().getCryptoKeyPair(), "Test", externalSign); 52 | 53 | TransactionBuilderService builder = new TransactionBuilderService(client); 54 | TransactionEncoderService encoder = new TransactionEncoderService(client.getCryptoSuite()); 55 | TransactionPusherService pusher = new TransactionPusherService(client); 56 | ABICodec abiCodec = new ABICodec(client.getCryptoSuite()); 57 | // 生成行交易 58 | RawTransaction rawTransaction = builder.createTransaction(null, 59 | abiCodec.encodeConstructor("abi", "bin", new ArrayList<>()), new BigInteger(String.valueOf(1)), BigInteger.valueOf(1L)); 60 | 61 | // 对rawTransaction进行编码 62 | asWt.deployAsync(rawTransaction,externalSign); 63 | // 对交易进行签名 64 | byte[] encode = encoder.encode(rawTransaction, null); 65 | byte[] hashEncode = client.getCryptoSuite().hash(encode); 66 | // 签名服务对交易进行签名 67 | // 拼接未签名交易与签名, 68 | // 发送带有交易的签名 69 | TransactionReceipt transactionReceipt = pusher.push(Hex.toHexString(hashEncode)); 70 | 71 | 72 | // 部署、交易、查询 73 | TransactionResponse response = asWt.deployByContractLoader("Test", new ArrayList<>()); 74 | // 交易查询 75 | TransactionResponse transactionResponse = asWt.sendTransactionAndGetResponse("to", "abi", "funcName", new ArrayList<>()); 76 | // 调用合约查询 77 | CallResponse callResponse = asWt.sendCallByContractLoader("Test", "address", "get", new ArrayList<>()); 78 | // 定义回调类 79 | BigInteger call = new BigInteger(String.valueOf("12")); 80 | 81 | 82 | 83 | } 84 | 85 | 86 | } 87 | 88 | 89 | class CustomExternalSignAndCallBack implements RemoteSignProviderInterface, RemoteSignCallbackInterface 90 | { 91 | AssembleTransactionWithRemoteSignProcessor assembleTransactionWithRemoteSignProcessor; 92 | RawTransaction rawTransaction; 93 | 94 | public CustomExternalSignAndCallBack(){ 95 | 96 | } 97 | 98 | public CustomExternalSignAndCallBack( 99 | AssembleTransactionWithRemoteSignProcessor asWt, 100 | RawTransaction rawTransaction 101 | ) { 102 | this.assembleTransactionWithRemoteSignProcessor = asWt; 103 | this.rawTransaction = rawTransaction; 104 | } 105 | 106 | 107 | 108 | // TODO 处理外部签名 109 | @Override 110 | public int handleSignedTransaction(SignatureResult signature) 111 | { 112 | System.out.println(System.currentTimeMillis() + " SignatureResult: " + new String(signature.getSignatureBytes())); 113 | 114 | // 在发送叫之前,对数据进行签名 115 | CompletableFuture signAndPush = // 完成 116 | assembleTransactionWithRemoteSignProcessor.signAndPush(rawTransaction, signature.getSignatureBytes()); 117 | return 0; 118 | } 119 | 120 | 121 | // TODO 调用外部签名 122 | @Override 123 | public SignatureResult requestForSign(byte[] dataToSign, int cryptoType) 124 | { 125 | return null; 126 | } 127 | 128 | @Override 129 | public void requestForSignAsync(byte[] dataToSign, int cryptoType, RemoteSignCallbackInterface callback) 130 | { 131 | 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /back-me/src/test/java/com/jzm/backme/service/WebaseFrontServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.jzm.backme.service; 2 | 3 | import com.jzm.backme.config.fisco.contract.ContractResponse; 4 | import com.jzm.backme.config.fisco.service.WeFrontService; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | 9 | import java.util.Arrays; 10 | 11 | /** 12 | * @author: jzm 13 | * @date: 2024-04-16 16:38 14 | **/ 15 | 16 | @SpringBootTest 17 | public class WebaseFrontServiceTest 18 | { 19 | 20 | @Autowired 21 | private WeFrontService weFrontService; 22 | 23 | @Test 24 | public void testWeFront() 25 | { 26 | ContractResponse setAge = weFrontService.sendTranGetValues("setAge", Arrays.asList(20111)); 27 | System.out.println(12); 28 | ContractResponse getAge = weFrontService.sendCallGetValues("getAge", Arrays.asList(2)); 29 | System.out.println(12); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /contracts-me/Roles.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.5 <0.8.0; 2 | 3 | contract Roles { 4 | address owner; 5 | 6 | mapping(string => mapping(address=>bool)) roles; 7 | 8 | constructor(address _oener) public { 9 | owner = _oener; 10 | } 11 | 12 | 13 | modifier onlyOwner(){ 14 | require(msg.sender == owner,"40016"); 15 | _; 16 | } 17 | 18 | function addRole(string memory _role,address _account) internal onlyOwner { 19 | roles[_role][_account] = true; 20 | } 21 | 22 | function removeRole(string memory _role,address _account) internal onlyOwner { 23 | roles[_role][_account] = true; 24 | } 25 | 26 | function hasRole(string memory _role,address _account) public view returns(bool){ 27 | return roles[_role][_account]; 28 | } 29 | 30 | 31 | 32 | 33 | } -------------------------------------------------------------------------------- /contracts-me/data.js: -------------------------------------------------------------------------------- 1 | 2 | let ContractErrCode = { 3 | 40001: '账户地址不能为空地址!', 4 | 40002: '合同上租客已经欠租,请尽快通知租客交租!', 5 | 40003: '参数租客地址与合同租客地址不相等!', 6 | 40004: '房东终止合同失败:租客实际缴租金 + 保证金 < 应缴纳租金!', 7 | 40005: '租客终止合同失败:租客实际缴租金 < 应缴纳租金 + 2个月租金!', 8 | 40006: '参数房东地址与合同房东地址不相等', 9 | 40007: '账户地址不能是空地址!', 10 | 40008: "账户月不足以支付money!", 11 | // 40009: "预存money必须 ==合同租金 +合同保证金!", 12 | 40010: "", 13 | 40011: "签署合同不存在", 14 | 40012: "签署合同已经过了签署时间!", 15 | 40013: "这个Person account 不存在!", 16 | 40014: "调用者必须是房东角色!", 17 | 40015: "调用者必须是租客角色!", 18 | 40016: "调用者必须是管理员!", 19 | } -------------------------------------------------------------------------------- /contracts-me/nine.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : root 5 | Source Server Version : 80032 6 | Source Host : localhost:3306 7 | Source Database : nine 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 80032 11 | File Encoding : 65001 12 | 13 | Date: 2024-04-20 15:56:25 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | 18 | -- ---------------------------- 19 | -- Table structure for contract 20 | -- ---------------------------- 21 | DROP TABLE IF EXISTS `contract`; 22 | CREATE TABLE `contract` ( 23 | `contract_id` bigint NOT NULL AUTO_INCREMENT COMMENT '合同id', 24 | `landlord_id` bigint DEFAULT NULL COMMENT '房东id', 25 | `house_id` bigint DEFAULT NULL, 26 | `sign` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '0 未签署 1签署', 27 | `del_flag` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0', 28 | `contract_num` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '合同编号', 29 | `stop_time` datetime DEFAULT NULL, 30 | `sign_time` datetime DEFAULT NULL COMMENT '签署日期', 31 | `create_time` datetime DEFAULT NULL COMMENT '合同发布时间', 32 | `update_time` datetime DEFAULT NULL, 33 | `create_by` bigint DEFAULT NULL, 34 | `update_by` bigint DEFAULT NULL, 35 | PRIMARY KEY (`contract_id`), 36 | UNIQUE KEY `contract_num` (`contract_num`) USING BTREE 37 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='合同表 -- 存储合同信息'; 38 | 39 | -- ---------------------------- 40 | -- Records of contract 41 | -- ---------------------------- 42 | 43 | -- ---------------------------- 44 | -- Table structure for house 45 | -- ---------------------------- 46 | DROP TABLE IF EXISTS `house`; 47 | CREATE TABLE `house` ( 48 | `house_id` bigint NOT NULL AUTO_INCREMENT, 49 | `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '房屋地址', 50 | `del_flag` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0', 51 | `status` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '0 未出售,1已出售', 52 | `create_time` datetime DEFAULT NULL, 53 | `update_time` datetime DEFAULT NULL, 54 | `landlord_id` bigint DEFAULT NULL COMMENT '房东id', 55 | `link_man` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '联系人', 56 | `link_phone` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '联系电话', 57 | `create_by` bigint DEFAULT NULL, 58 | `update_by` bigint DEFAULT NULL, 59 | PRIMARY KEY (`house_id`) 60 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='房屋表 -- 存储房屋信息'; 61 | 62 | -- ---------------------------- 63 | -- Records of house 64 | -- ---------------------------- 65 | 66 | -- ---------------------------- 67 | -- Table structure for payment 68 | -- ---------------------------- 69 | DROP TABLE IF EXISTS `payment`; 70 | CREATE TABLE `payment` ( 71 | `payment_id` bigint NOT NULL AUTO_INCREMENT COMMENT '缴纳记录id', 72 | `payer` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '缴纳人账户地址', 73 | `payer_id` bigint DEFAULT NULL COMMENT '缴纳人用户id', 74 | `contract_num` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '合同序列号', 75 | `create_time` datetime DEFAULT NULL, 76 | `del_flag` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '0 未删除 1 已删除', 77 | `update_by` bigint DEFAULT NULL, 78 | `create_by` bigint DEFAULT NULL, 79 | `update_time` datetime DEFAULT NULL, 80 | PRIMARY KEY (`payment_id`) 81 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='缴纳记录表 -- 记录租金缴纳信息'; 82 | 83 | -- ---------------------------- 84 | -- Records of payment 85 | -- ---------------------------- 86 | 87 | -- ---------------------------- 88 | -- Table structure for role 89 | -- ---------------------------- 90 | DROP TABLE IF EXISTS `role`; 91 | CREATE TABLE `role` ( 92 | `role_id` bigint DEFAULT NULL, 93 | `role_name` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL 94 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT=' 角色表'; 95 | 96 | -- ---------------------------- 97 | -- Records of role 98 | -- ---------------------------- 99 | INSERT INTO `role` VALUES ('1', '管理员'); 100 | INSERT INTO `role` VALUES ('2', '房东'); 101 | INSERT INTO `role` VALUES ('3', '租客'); 102 | 103 | -- ---------------------------- 104 | -- Table structure for user 105 | -- ---------------------------- 106 | DROP TABLE IF EXISTS `user`; 107 | CREATE TABLE `user` ( 108 | `user_id` bigint NOT NULL AUTO_INCREMENT, 109 | `username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 110 | `user` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户区块链账户地址', 111 | `phone` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 112 | `password` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户密码', 113 | `update_time` datetime DEFAULT NULL, 114 | `create_time` datetime DEFAULT NULL, 115 | `del_flag` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0', 116 | `create_by` bigint DEFAULT NULL, 117 | `update_by` bigint DEFAULT NULL, 118 | `status` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '0 启用 1 禁用', 119 | `sex` enum('0','1','2') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '2', 120 | PRIMARY KEY (`user_id`) 121 | ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户表 -- 存储用户信息'; 122 | 123 | -- ---------------------------- 124 | -- Records of user 125 | -- ---------------------------- 126 | INSERT INTO `user` VALUES ('1', 'admin', '0xa5c4f1b07f513a586b19be93fd44966bcbd5d2c5', '15069680202', 'e10adc3949ba59abbe56e057f20f883e', '2024-04-18 15:16:58', '2024-04-17 19:35:35', '0', '1', '1', '0', '2'); 127 | INSERT INTO `user` VALUES ('3', '测试房东', '0xdde5b34d81a606d74341b0d788e5e0e5db5f6918', '15069680203', 'f1887d3f9e6ee7a32fe5e76f4ab80d63', null, '2024-04-20 15:52:33', '0', '1', null, '0', '2'); 128 | INSERT INTO `user` VALUES ('4', '测试租客', '0x29eec69129e7a4ee98fa43d2fb4799b029589a5d', '15069680204', '93897cc117a734be93733779051c9926', null, '2024-04-20 15:53:33', '0', '1', null, '0', '2'); 129 | 130 | -- ---------------------------- 131 | -- Table structure for user_role 132 | -- ---------------------------- 133 | DROP TABLE IF EXISTS `user_role`; 134 | CREATE TABLE `user_role` ( 135 | `user_id` bigint DEFAULT NULL, 136 | `role_id` bigint DEFAULT NULL 137 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户 - 角色表'; 138 | 139 | -- ---------------------------- 140 | -- Records of user_role 141 | -- ---------------------------- 142 | INSERT INTO `user_role` VALUES ('1', '1'); 143 | INSERT INTO `user_role` VALUES ('3', '2'); 144 | INSERT INTO `user_role` VALUES ('4', '3'); 145 | -------------------------------------------------------------------------------- /nine.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : root 5 | Source Server Version : 80032 6 | Source Host : localhost:3306 7 | Source Database : nine 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 80032 11 | File Encoding : 65001 12 | 13 | Date: 2024-04-20 15:56:25 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | 18 | -- ---------------------------- 19 | -- Table structure for contract 20 | -- ---------------------------- 21 | DROP TABLE IF EXISTS `contract`; 22 | CREATE TABLE `contract` ( 23 | `contract_id` bigint NOT NULL AUTO_INCREMENT COMMENT '合同id', 24 | `landlord_id` bigint DEFAULT NULL COMMENT '房东id', 25 | `house_id` bigint DEFAULT NULL, 26 | `sign` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '0 未签署 1签署', 27 | `del_flag` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0', 28 | `contract_num` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '合同编号', 29 | `stop_time` datetime DEFAULT NULL, 30 | `sign_time` datetime DEFAULT NULL COMMENT '签署日期', 31 | `create_time` datetime DEFAULT NULL COMMENT '合同发布时间', 32 | `update_time` datetime DEFAULT NULL, 33 | `create_by` bigint DEFAULT NULL, 34 | `update_by` bigint DEFAULT NULL, 35 | PRIMARY KEY (`contract_id`), 36 | UNIQUE KEY `contract_num` (`contract_num`) USING BTREE 37 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='合同表 -- 存储合同信息'; 38 | 39 | -- ---------------------------- 40 | -- Records of contract 41 | -- ---------------------------- 42 | 43 | -- ---------------------------- 44 | -- Table structure for house 45 | -- ---------------------------- 46 | DROP TABLE IF EXISTS `house`; 47 | CREATE TABLE `house` ( 48 | `house_id` bigint NOT NULL AUTO_INCREMENT, 49 | `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '房屋地址', 50 | `del_flag` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0', 51 | `status` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '0 未出售,1已出售', 52 | `create_time` datetime DEFAULT NULL, 53 | `update_time` datetime DEFAULT NULL, 54 | `landlord_id` bigint DEFAULT NULL COMMENT '房东id', 55 | `link_man` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '联系人', 56 | `link_phone` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '联系电话', 57 | `create_by` bigint DEFAULT NULL, 58 | `update_by` bigint DEFAULT NULL, 59 | PRIMARY KEY (`house_id`) 60 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='房屋表 -- 存储房屋信息'; 61 | 62 | -- ---------------------------- 63 | -- Records of house 64 | -- ---------------------------- 65 | 66 | -- ---------------------------- 67 | -- Table structure for payment 68 | -- ---------------------------- 69 | DROP TABLE IF EXISTS `payment`; 70 | CREATE TABLE `payment` ( 71 | `payment_id` bigint NOT NULL AUTO_INCREMENT COMMENT '缴纳记录id', 72 | `payer` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '缴纳人账户地址', 73 | `payer_id` bigint DEFAULT NULL COMMENT '缴纳人用户id', 74 | `contract_num` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '合同序列号', 75 | `create_time` datetime DEFAULT NULL, 76 | `del_flag` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '0 未删除 1 已删除', 77 | `update_by` bigint DEFAULT NULL, 78 | `create_by` bigint DEFAULT NULL, 79 | `update_time` datetime DEFAULT NULL, 80 | PRIMARY KEY (`payment_id`) 81 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='缴纳记录表 -- 记录租金缴纳信息'; 82 | 83 | -- ---------------------------- 84 | -- Records of payment 85 | -- ---------------------------- 86 | 87 | -- ---------------------------- 88 | -- Table structure for role 89 | -- ---------------------------- 90 | DROP TABLE IF EXISTS `role`; 91 | CREATE TABLE `role` ( 92 | `role_id` bigint DEFAULT NULL, 93 | `role_name` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL 94 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT=' 角色表'; 95 | 96 | -- ---------------------------- 97 | -- Records of role 98 | -- ---------------------------- 99 | INSERT INTO `role` VALUES ('1', '管理员'); 100 | INSERT INTO `role` VALUES ('2', '房东'); 101 | INSERT INTO `role` VALUES ('3', '租客'); 102 | 103 | -- ---------------------------- 104 | -- Table structure for user 105 | -- ---------------------------- 106 | DROP TABLE IF EXISTS `user`; 107 | CREATE TABLE `user` ( 108 | `user_id` bigint NOT NULL AUTO_INCREMENT, 109 | `username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 110 | `user` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户区块链账户地址', 111 | `phone` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 112 | `password` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户密码', 113 | `update_time` datetime DEFAULT NULL, 114 | `create_time` datetime DEFAULT NULL, 115 | `del_flag` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0', 116 | `create_by` bigint DEFAULT NULL, 117 | `update_by` bigint DEFAULT NULL, 118 | `status` enum('0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '0 启用 1 禁用', 119 | `sex` enum('0','1','2') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '2', 120 | PRIMARY KEY (`user_id`) 121 | ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户表 -- 存储用户信息'; 122 | 123 | -- ---------------------------- 124 | -- Records of user 125 | -- ---------------------------- 126 | INSERT INTO `user` VALUES ('1', 'admin', '0xa5c4f1b07f513a586b19be93fd44966bcbd5d2c5', '15069680202', 'e10adc3949ba59abbe56e057f20f883e', '2024-04-18 15:16:58', '2024-04-17 19:35:35', '0', '1', '1', '0', '2'); 127 | INSERT INTO `user` VALUES ('3', '测试房东', '0xdde5b34d81a606d74341b0d788e5e0e5db5f6918', '15069680203', 'f1887d3f9e6ee7a32fe5e76f4ab80d63', null, '2024-04-20 15:52:33', '0', '1', null, '0', '2'); 128 | INSERT INTO `user` VALUES ('4', '测试租客', '0x29eec69129e7a4ee98fa43d2fb4799b029589a5d', '15069680204', '93897cc117a734be93733779051c9926', null, '2024-04-20 15:53:33', '0', '1', null, '0', '2'); 129 | 130 | -- ---------------------------- 131 | -- Table structure for user_role 132 | -- ---------------------------- 133 | DROP TABLE IF EXISTS `user_role`; 134 | CREATE TABLE `user_role` ( 135 | `user_id` bigint DEFAULT NULL, 136 | `role_id` bigint DEFAULT NULL 137 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户 - 角色表'; 138 | 139 | -- ---------------------------- 140 | -- Records of user_role 141 | -- ---------------------------- 142 | INSERT INTO `user_role` VALUES ('1', '1'); 143 | INSERT INTO `user_role` VALUES ('3', '2'); 144 | INSERT INTO `user_role` VALUES ('4', '3'); 145 | --------------------------------------------------------------------------------