commit 12981b9dbd0a97f4d75a7a1c56bf2233d394ac8c Author: shi Date: Tue Feb 11 15:27:15 2025 +0800 项目初始化 diff --git a/ff-admin/pom.xml b/ff-admin/pom.xml new file mode 100644 index 0000000..94f85f1 --- /dev/null +++ b/ff-admin/pom.xml @@ -0,0 +1,128 @@ + + + 4.0.0 + + ff + com.ff + 0.0.1 + + + com.ff + ff-admin + 0.0.1 + ff-admin + ff-admin + + + + + + + org.springframework.boot + spring-boot-devtools + true + + + + org.springframework + spring-context + + + + + io.springfox + springfox-boot-starter + + + + + io.swagger + swagger-models + 1.6.2 + + + + + mysql + mysql-connector-java + + + + + org.quartz-scheduler + quartz + + + com.mchange + c3p0 + + + + + + + com.ff + ff-base + + + + + com.ff + ff-gen + + + org.projectlombok + lombok + provided + + + io.netty + netty-all + 4.1.111.Final + + + + io.socket + socket.io-client + 1.0.0 + + + com.dtflys.forest + forest-spring-boot-starter + 1.6.3 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.5.15 + + true + + + + + repackage + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.1.0 + + false + ${project.artifactId} + + + + ${project.artifactId} + + + diff --git a/ff-admin/src/main/java/com/ff/FFApplication.java b/ff-admin/src/main/java/com/ff/FFApplication.java new file mode 100644 index 0000000..3a511ff --- /dev/null +++ b/ff-admin/src/main/java/com/ff/FFApplication.java @@ -0,0 +1,44 @@ +package com.ff; + +import com.ff.base.config.IdGeneratorUtil; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.SpringBootVersion; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; + +/** + * 启动程序 + * + * @author ff + */ +@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) +@MapperScan({"com.ff.base.system.mapper","com.ff.quartz.mapper","com.ff.gen.mapper"}) +@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = DaoAuthenticationProvider.class)}) +@EnableAsync +public class FFApplication implements CommandLineRunner +{ + @Autowired + private IdGeneratorUtil idGeneratorUtil; + + + public static void main(String[] args) + { + // System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(FFApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ FF启动成功 ლ(´ڡ`ლ)゙"+ SpringBootVersion.getVersion()); + + + } + + @Override + public void run(String... args) throws Exception { + idGeneratorUtil.init(); + } +} diff --git a/ff-admin/src/main/java/com/ff/FFServletInitializer.java b/ff-admin/src/main/java/com/ff/FFServletInitializer.java new file mode 100644 index 0000000..7e82010 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/FFServletInitializer.java @@ -0,0 +1,18 @@ +package com.ff; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * web容器中进行部署 + * + * @author ff + */ +public class FFServletInitializer extends SpringBootServletInitializer +{ + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) + { + return application.sources(FFApplication.class); + } +} diff --git a/ff-admin/src/main/java/com/ff/annotation/CheckHeader.java b/ff-admin/src/main/java/com/ff/annotation/CheckHeader.java new file mode 100644 index 0000000..99d28f6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/annotation/CheckHeader.java @@ -0,0 +1,20 @@ +package com.ff.annotation; + +import lombok.Data; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 检查标题 + * + * @author shi + * @date 2025/02/10 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface CheckHeader { + // 该注解没有参数,直接标识类需要进行头部验证 +} \ No newline at end of file diff --git a/ff-admin/src/main/java/com/ff/annotation/HeaderCheckAspect.java b/ff-admin/src/main/java/com/ff/annotation/HeaderCheckAspect.java new file mode 100644 index 0000000..4d605b3 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/annotation/HeaderCheckAspect.java @@ -0,0 +1,69 @@ +package com.ff.annotation; + +import com.ff.base.constant.Constants; +import com.ff.config.KeyConfig; +import com.ff.base.utils.sign.Md5Utils; +import com.ff.common.domain.TenantSecretKey; +import com.ff.common.service.ITenantSecretKeyService; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; +import org.springframework.util.Assert; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + +/** + * 标题检查方面 + * + * @author shi + * @date 2025/02/10 + */ +@Aspect +@Component +public class HeaderCheckAspect { + + @Resource + private ITenantSecretKeyService tenantSecretKeyService; + + @Resource + private KeyConfig keyUtils; + + + // 定义切点: 所有带 @CheckHeader 注解的类中的所有方法 + @Pointcut("@within(CheckHeader)") + public void checkHeaderPointcut() { + } + + + // 在方法执行前进行处理 + @Before("checkHeaderPointcut()") + public void beforeMethod() throws Exception { + // 获取当前请求的 HTTP 请求对象 + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + + // 32 位小写 md5(random+key+tenantSecret) + String sign = request.getHeader(Constants.SIGN); + Assert.notNull(sign, "签名不能为空"); + // 随机数 + String random = request.getHeader(Constants.RANDOM); + Assert.notNull(random, "随机数不能为空"); + Assert.isTrue( random.length() == 32, "随机数长度错误"); + + //key值 + String key = request.getHeader(Constants.KEY); + Assert.notNull(key, "key不能为空"); + + + TenantSecretKey tenantSecretKey = tenantSecretKeyService.selectTenantSecretKeyByTenantKey(key); + Assert.notNull(tenantSecretKey, "key不存在"); + + String keyG = Md5Utils.md5New(random + key + tenantSecretKey.getTenantSecret()); + Assert.isTrue(keyG.equals(sign), "签名错误"); + //保存 + keyUtils.set(tenantSecretKey); + } +} \ No newline at end of file diff --git a/ff-admin/src/main/java/com/ff/api/controller/ApiGameController.java b/ff-admin/src/main/java/com/ff/api/controller/ApiGameController.java new file mode 100644 index 0000000..b1fd8a4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/api/controller/ApiGameController.java @@ -0,0 +1,119 @@ +package com.ff.api.controller; + + +import com.ff.annotation.CheckHeader; +import com.ff.api.request.GameLoginRequest; +import com.ff.api.request.MemberCreateApiRequest; +import com.ff.base.constant.Constants; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.common.domain.TenantSecretKey; +import com.ff.config.KeyConfig; +import com.ff.game.api.IGamesService; +import com.ff.game.api.request.CreateMemberRequestDTO; +import com.ff.game.api.request.GamesLogin; +import com.ff.game.api.request.MemberInfoRequestDTO; +import com.ff.game.domain.Game; +import com.ff.game.domain.GamePlatform; +import com.ff.game.domain.GameSecretKey; +import com.ff.game.service.IGamePlatformService; +import com.ff.game.service.IGameSecretKeyService; +import com.ff.game.service.IGameService; +import com.ff.member.domain.Member; +import com.ff.member.service.IMemberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.Assert; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.Map; + +/** + * api控制器 + * + * @author shi + * @date 2025/02/10 + */ +@RestController +@CheckHeader +@RequestMapping("/api/game") +public class ApiGameController extends BaseController { + + + @Autowired + private Map gamesService; + + + @Resource + private IGameService gameService; + + + @Resource + private KeyConfig keyConfig; + + @Resource + private IGameSecretKeyService gameSecretKeyService; + + @Resource + private IMemberService memberService; + + @Resource + private IGamePlatformService gamePlatformService; + + + /** + * 登录 + * + * @param memberCreateApiRequest 成员创建api请求 + * @return {@link AjaxResult } + */ + @PostMapping("/login") + public AjaxResult login(@Validated @RequestBody GameLoginRequest memberCreateApiRequest) { + + Game game = gameService.selectGameById(memberCreateApiRequest.getGameId()); + Assert.notNull(game, "游戏不存在"); + + GamePlatform gamePlatform = gamePlatformService.selectGamePlatformById(game.getPlatformId()); + Assert.notNull(gamePlatform, "游戏平台不存在"); + + + IGamesService iGamesService = gamesService.get(gamePlatform.getPlatformCode() + Constants.SERVICE); + Assert.notNull(iGamesService, "平台不存在"); + + + TenantSecretKey tenantSecretKey = keyConfig.get(); + GameSecretKey gameSecretKey = gameSecretKeyService.findSecretKeyByPlatformAndSystemCode(gamePlatform.getPlatformCode(), memberCreateApiRequest.getCurrencyCode()); + Assert.notNull(gameSecretKey, "货币游戏平台不存在"); + + GameSecretKey gameSecretKeyLang = gameSecretKeyService.findByPlatformAndSystemLangCode(gamePlatform.getPlatformCode(), memberCreateApiRequest.getLangCode()); + Assert.notNull(gameSecretKeyLang, "当前语言不存在"); + + Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(memberCreateApiRequest.getAccount(), memberCreateApiRequest.getCurrencyCode() + tenantSecretKey.getTenantSn())); + + GamesLogin gamesLogin = GamesLogin.builder() + .agentId(gameSecretKey.getCode()) + .agentKey(gameSecretKey.getKey()) + .account(member.getGameAccount()) + .gameId(game.getGameCode()) + .homeUrl(memberCreateApiRequest.getHomeUrl()) + .platform(memberCreateApiRequest.getPlatform()) + .disableFullScreen(memberCreateApiRequest.getDisableFullScreen()) + .lang(gameSecretKeyLang.getLang()) + .build(); + + String login = iGamesService.loginWithoutRedirect(gamesLogin); + + return AjaxResult.success(login); + } + + + + + +} diff --git a/ff-admin/src/main/java/com/ff/api/controller/ApiMemberController.java b/ff-admin/src/main/java/com/ff/api/controller/ApiMemberController.java new file mode 100644 index 0000000..c7f239d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/api/controller/ApiMemberController.java @@ -0,0 +1,125 @@ +package com.ff.api.controller; + + +import com.ff.annotation.CheckHeader; +import com.ff.api.request.MemberCreateApiRequest; +import com.ff.base.constant.Constants; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.utils.StringUtils; +import com.ff.common.domain.TenantSecretKey; +import com.ff.config.KeyConfig; +import com.ff.game.api.IGamesService; +import com.ff.game.api.request.CreateMemberRequestDTO; +import com.ff.game.api.request.MemberInfoRequestDTO; +import com.ff.game.domain.GameSecretKey; +import com.ff.game.service.IGameSecretKeyService; +import com.ff.game.service.IGameService; +import com.ff.member.domain.Member; +import com.ff.member.service.IMemberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.Assert; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.Map; + +/** + * api控制器 + * + * @author shi + * @date 2025/02/10 + */ +@RestController +@CheckHeader +@RequestMapping("/api/member") +public class ApiMemberController extends BaseController { + + + @Autowired + private Map gamesService; + + + @Resource + private IGameService gameService; + + + @Resource + private KeyConfig keyConfig; + + @Resource + private IGameSecretKeyService gameSecretKeyService; + + @Resource + private IMemberService memberService; + + + /** + * 创建成员 + * + * @param memberCreateApiRequest 创建成员api请求 + * @return {@link AjaxResult } + */ + @PostMapping("/create") + public AjaxResult createMember(@Validated @RequestBody MemberCreateApiRequest memberCreateApiRequest) { + + IGamesService iGamesService = gamesService.get(memberCreateApiRequest.getPlatformCode() + Constants.SERVICE); + Assert.notNull(iGamesService, "平台不存在"); + + + TenantSecretKey tenantSecretKey = keyConfig.get(); + GameSecretKey gameSecretKey = gameSecretKeyService.findSecretKeyByPlatformAndSystemCode(memberCreateApiRequest.getPlatformCode(), memberCreateApiRequest.getCurrencyCode()); + Assert.notNull(gameSecretKey, "货币游戏平台不存在"); + + String gameAccount = StringUtils.addSuffix(memberCreateApiRequest.getAccount(), memberCreateApiRequest.getCurrencyCode() + tenantSecretKey.getTenantSn()); + //向第三方注册账号 + CreateMemberRequestDTO gamesBaseRequestDTO = CreateMemberRequestDTO.builder() + .account(gameAccount) + .agentId(gameSecretKey.getCode()) + .agentKey(gameSecretKey.getKey()) + .build(); + Boolean result = iGamesService.createMember(gamesBaseRequestDTO); + Assert.isTrue(result, "建立游戏账号失败"); + //注册本地账号 + Member member = Member.builder() + .tenantKey(tenantSecretKey.getTenantSn()) + .memberAccount(memberCreateApiRequest.getAccount()) + .gameAccount(gameAccount) + .platformCode(memberCreateApiRequest.getPlatformCode()) + .currencyCode(memberCreateApiRequest.getCurrencyCode()) + .build(); + return toAjax(memberService.insertMember(member)); + } + + + /** + * 获取会员信息 + * + * @param memberCreateApiRequest 成员创建api请求 + * @return {@link AjaxResult } + */ + @PostMapping("/info") + public AjaxResult getMemberInfo(@Validated @RequestBody MemberCreateApiRequest memberCreateApiRequest) { + IGamesService iGamesService = gamesService.get(memberCreateApiRequest.getPlatformCode() + Constants.SERVICE); + Assert.notNull(iGamesService, "平台不存在"); + + + TenantSecretKey tenantSecretKey = keyConfig.get(); + GameSecretKey gameSecretKey = gameSecretKeyService.findSecretKeyByPlatformAndSystemCode(memberCreateApiRequest.getPlatformCode(), memberCreateApiRequest.getCurrencyCode()); + Assert.notNull(gameSecretKey, "货币游戏平台不存在"); + + Member member = memberService.selectMemberByGameAccount(StringUtils.addSuffix(memberCreateApiRequest.getAccount(), memberCreateApiRequest.getCurrencyCode() + tenantSecretKey.getTenantSn())); + Assert.notNull(member, "会员不存在"); + //向第三方查询账号 + MemberInfoRequestDTO gamesBaseRequestDTO = MemberInfoRequestDTO.builder() + .accounts(member.getGameAccount()) + .agentId(gameSecretKey.getCode()) + .agentKey(gameSecretKey.getKey()) + .build(); + return AjaxResult.success(iGamesService.getMemberInfo(gamesBaseRequestDTO)); + } + + + +} diff --git a/ff-admin/src/main/java/com/ff/api/request/GameLoginRequest.java b/ff-admin/src/main/java/com/ff/api/request/GameLoginRequest.java new file mode 100644 index 0000000..c39eab4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/api/request/GameLoginRequest.java @@ -0,0 +1,58 @@ +package com.ff.api.request; + +import com.dtflys.forest.annotation.NotNull; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * 游戏登录请求 + * + * @author shi + * @date 2025/02/11 + */ +@Data +public class GameLoginRequest implements Serializable { + private final static long serialVersionUID = 7699430372422335056L; + + + + /** + * 货币代码 + */ + @NotBlank(message = "currencyCode不能为空") + private String currencyCode; + + /** + * 语种id + */ + @NotBlank(message = "langCode不能为空") + private String langCode; + + /** + * 账户 + */ + @NotBlank(message = "account不能为空") + private String account; + + /** + * 游戏id + */ + @NotBlank(message = "gameId不能为空") + private Long gameId; + + + /** + * 游戏回主页功能导向位置 + */ + private String homeUrl; + /** + * 带入 web 或是 app + */ + private String platform; + /** + * 带入 1 即关闭全屏幕模式 + */ + private Integer disableFullScreen; +} diff --git a/ff-admin/src/main/java/com/ff/api/request/MemberCreateApiRequest.java b/ff-admin/src/main/java/com/ff/api/request/MemberCreateApiRequest.java new file mode 100644 index 0000000..768e55d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/api/request/MemberCreateApiRequest.java @@ -0,0 +1,32 @@ +package com.ff.api.request; + + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * 创建成员请求 + * + * @author shi + * @date 2025/02/10 + */ +@Data +public class MemberCreateApiRequest implements Serializable{ + + private static final long serialVersionUID = 8071608271351542925L; + + @NotBlank(message = "account不能为空") + private String account; + + /** 平台编码 */ + @NotBlank(message = "platformCode不能为空") + private String platformCode; + + /** 币种编码 */ + @NotBlank(message = "currencyCode不能为空") + private String currencyCode; + +} diff --git a/ff-admin/src/main/java/com/ff/api/request/MemberInfoApiRequest.java b/ff-admin/src/main/java/com/ff/api/request/MemberInfoApiRequest.java new file mode 100644 index 0000000..2200a88 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/api/request/MemberInfoApiRequest.java @@ -0,0 +1,32 @@ +package com.ff.api.request; + + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * 创建成员请求 + * + * @author shi + * @date 2025/02/10 + */ +@Data +public class MemberInfoApiRequest implements Serializable{ + + private static final long serialVersionUID = 8071608271351542925L; + + @NotBlank(message = "account不能为空") + private String account; + + /** 平台编码 */ + @NotBlank(message = "platformCode不能为空") + private String platformCode; + + /** 币种编码 */ + @NotBlank(message = "currencyCode不能为空") + private String currencyCode; + +} diff --git a/ff-admin/src/main/java/com/ff/common/controller/CaptchaController.java b/ff-admin/src/main/java/com/ff/common/controller/CaptchaController.java new file mode 100644 index 0000000..e56be31 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/controller/CaptchaController.java @@ -0,0 +1,95 @@ +package com.ff.common.controller; + +import com.ff.base.config.FFConfig; +import com.ff.base.constant.CacheConstants; +import com.ff.base.constant.Constants; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.system.service.ISysConfigService; +import com.ff.base.utils.sign.Base64; +import com.ff.base.utils.uuid.IdUtils; +import com.google.code.kaptcha.Producer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.FastByteArrayOutputStream; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletResponse; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + * 验证码操作处理 + * + * @author ff + */ +@RestController +public class CaptchaController +{ + @Resource(name = "captchaProducer") + private Producer captchaProducer; + + @Resource(name = "captchaProducerMath") + private Producer captchaProducerMath; + + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysConfigService configService; + /** + * 生成验证码 + */ + @GetMapping("/captchaImage") + public AjaxResult getCode(HttpServletResponse response) throws IOException + { + AjaxResult ajax = AjaxResult.success(); + boolean captchaEnabled = configService.selectCaptchaEnabled(); + ajax.put("captchaEnabled", captchaEnabled); + if (!captchaEnabled) + { + return ajax; + } + + // 保存验证码信息 + String uuid = IdUtils.simpleUUID(); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + + String capStr = null, code = null; + BufferedImage image = null; + + // 生成验证码 + String captchaType = FFConfig.getCaptchaType(); + if ("math".equals(captchaType)) + { + String capText = captchaProducerMath.createText(); + capStr = capText.substring(0, capText.lastIndexOf("@")); + code = capText.substring(capText.lastIndexOf("@") + 1); + image = captchaProducerMath.createImage(capStr); + } + else if ("char".equals(captchaType)) + { + capStr = code = captchaProducer.createText(); + image = captchaProducer.createImage(capStr); + } + + redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + // 转换流信息写出 + FastByteArrayOutputStream os = new FastByteArrayOutputStream(); + try + { + ImageIO.write(image, "jpg", os); + } + catch (IOException e) + { + return AjaxResult.error(e.getMessage()); + } + + ajax.put("uuid", uuid); + ajax.put("img", Base64.encode(os.toByteArray())); + return ajax; + } +} diff --git a/ff-admin/src/main/java/com/ff/common/controller/CurrencyController.java b/ff-admin/src/main/java/com/ff/common/controller/CurrencyController.java new file mode 100644 index 0000000..871960e --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/controller/CurrencyController.java @@ -0,0 +1,104 @@ +package com.ff.common.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.common.domain.Currency; +import com.ff.common.service.ICurrencyService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 币种Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/common/currency") +public class CurrencyController extends BaseController +{ + @Autowired + private ICurrencyService currencyService; + + /** + * 查询币种列表 + */ + @PreAuthorize("@ss.hasPermi('common:currency:list')") + @GetMapping("/list") + public TableDataInfo list(Currency currency) + { + startPage(); + List list = currencyService.selectCurrencyList(currency); + return getDataTable(list); + } + + /** + * 导出币种列表 + */ + @PreAuthorize("@ss.hasPermi('common:currency:export')") + @Log(title = "币种", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, Currency currency) + { + List list = currencyService.selectCurrencyList(currency); + ExcelUtil util = new ExcelUtil(Currency.class); + util.exportExcel(response, list, "币种数据"); + } + + /** + * 获取币种详细信息 + */ + @PreAuthorize("@ss.hasPermi('common:currency:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(currencyService.selectCurrencyById(id)); + } + + /** + * 新增币种 + */ + @PreAuthorize("@ss.hasPermi('common:currency:add')") + @Log(title = "币种", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody Currency currency) + { + return toAjax(currencyService.insertCurrency(currency)); + } + + /** + * 修改币种 + */ + @PreAuthorize("@ss.hasPermi('common:currency:edit')") + @Log(title = "币种", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody Currency currency) + { + return toAjax(currencyService.updateCurrency(currency)); + } + + /** + * 删除币种 + */ + @PreAuthorize("@ss.hasPermi('common:currency:remove')") + @Log(title = "币种", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(currencyService.deleteCurrencyByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/common/controller/LangController.java b/ff-admin/src/main/java/com/ff/common/controller/LangController.java new file mode 100644 index 0000000..a0a8fab --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/controller/LangController.java @@ -0,0 +1,104 @@ +package com.ff.common.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.common.domain.Lang; +import com.ff.common.service.ILangService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 系统语种管理 Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/common/lang") +public class LangController extends BaseController +{ + @Autowired + private ILangService langService; + + /** + * 查询系统语种管理 列表 + */ + @PreAuthorize("@ss.hasPermi('common:lang:list')") + @GetMapping("/list") + public TableDataInfo list(Lang lang) + { + startPage(); + List list = langService.selectLangList(lang); + return getDataTable(list); + } + + /** + * 导出系统语种管理 列表 + */ + @PreAuthorize("@ss.hasPermi('common:lang:export')") + @Log(title = "系统语种管理 ", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, Lang lang) + { + List list = langService.selectLangList(lang); + ExcelUtil util = new ExcelUtil(Lang.class); + util.exportExcel(response, list, "系统语种管理 数据"); + } + + /** + * 获取系统语种管理 详细信息 + */ + @PreAuthorize("@ss.hasPermi('common:lang:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(langService.selectLangById(id)); + } + + /** + * 新增系统语种管理 + */ + @PreAuthorize("@ss.hasPermi('common:lang:add')") + @Log(title = "系统语种管理 ", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody Lang lang) + { + return toAjax(langService.insertLang(lang)); + } + + /** + * 修改系统语种管理 + */ + @PreAuthorize("@ss.hasPermi('common:lang:edit')") + @Log(title = "系统语种管理 ", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody Lang lang) + { + return toAjax(langService.updateLang(lang)); + } + + /** + * 删除系统语种管理 + */ + @PreAuthorize("@ss.hasPermi('common:lang:remove')") + @Log(title = "系统语种管理 ", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(langService.deleteLangByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/common/controller/TenantSecretKeyController.java b/ff-admin/src/main/java/com/ff/common/controller/TenantSecretKeyController.java new file mode 100644 index 0000000..5d60d8a --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/controller/TenantSecretKeyController.java @@ -0,0 +1,104 @@ +package com.ff.common.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.common.domain.TenantSecretKey; +import com.ff.common.service.ITenantSecretKeyService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 用户租户密钥Controller + * + * @author shi + * @date 2025-02-11 + */ +@RestController +@RequestMapping("/common/key") +public class TenantSecretKeyController extends BaseController +{ + @Autowired + private ITenantSecretKeyService tenantSecretKeyService; + + /** + * 查询用户租户密钥列表 + */ + @PreAuthorize("@ss.hasPermi('common:key:list')") + @GetMapping("/list") + public TableDataInfo list(TenantSecretKey tenantSecretKey) + { + startPage(); + List list = tenantSecretKeyService.selectTenantSecretKeyList(tenantSecretKey); + return getDataTable(list); + } + + /** + * 导出用户租户密钥列表 + */ + @PreAuthorize("@ss.hasPermi('common:key:export')") + @Log(title = "用户租户密钥", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, TenantSecretKey tenantSecretKey) + { + List list = tenantSecretKeyService.selectTenantSecretKeyList(tenantSecretKey); + ExcelUtil util = new ExcelUtil(TenantSecretKey.class); + util.exportExcel(response, list, "用户租户密钥数据"); + } + + /** + * 获取用户租户密钥详细信息 + */ + @PreAuthorize("@ss.hasPermi('common:key:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(tenantSecretKeyService.selectTenantSecretKeyById(id)); + } + + /** + * 新增用户租户密钥 + */ + @PreAuthorize("@ss.hasPermi('common:key:add')") + @Log(title = "用户租户密钥", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody TenantSecretKey tenantSecretKey) + { + return toAjax(tenantSecretKeyService.insertTenantSecretKey(tenantSecretKey)); + } + + /** + * 修改用户租户密钥 + */ + @PreAuthorize("@ss.hasPermi('common:key:edit')") + @Log(title = "用户租户密钥", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody TenantSecretKey tenantSecretKey) + { + return toAjax(tenantSecretKeyService.updateTenantSecretKey(tenantSecretKey)); + } + + /** + * 删除用户租户密钥 + */ + @PreAuthorize("@ss.hasPermi('common:key:remove')") + @Log(title = "用户租户密钥", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(tenantSecretKeyService.deleteTenantSecretKeyByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/common/domain/Currency.java b/ff-admin/src/main/java/com/ff/common/domain/Currency.java new file mode 100644 index 0000000..a573675 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/domain/Currency.java @@ -0,0 +1,54 @@ +package com.ff.common.domain; + +import java.math.BigDecimal; +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.Data; +/** + * 币种对象 ff_currency + * + * @author shi + * @date 2025-02-10 + */ +@Data +public class Currency extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 币种状态(0正常 1停用) */ + @Excel(name = "币种状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 币种国家 */ + @Excel(name = "币种国家") + private String country; + + /** 币种编码 */ + @Excel(name = "币种编码") + private String currencyCode; + + /** 币种符号 */ + @Excel(name = "币种符号") + private String currencySign; + + /** 汇率 */ + @Excel(name = "汇率") + private BigDecimal gameRate; + + /** 币种展示内容 */ + @Excel(name = "币种展示内容") + private String currencyDisplay; + + /** 币种名称 */ + @Excel(name = "币种名称") + private String currencyName; + + /** 币种全称 */ + @Excel(name = "币种全称") + private String fullName; + + +} diff --git a/ff-admin/src/main/java/com/ff/common/domain/Lang.java b/ff-admin/src/main/java/com/ff/common/domain/Lang.java new file mode 100644 index 0000000..a4799a3 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/domain/Lang.java @@ -0,0 +1,37 @@ +package com.ff.common.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.Data; +/** + * 系统语种管理 对象 ff_lang + * + * @author shi + * @date 2025-02-10 + */ +@Data +public class Lang extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 语言名称 */ + @Excel(name = "语言名称") + private String name; + + /** 国家代码 */ + @Excel(name = "国家代码") + private String country; + + /** 语种 */ + @Excel(name = "语种") + private String langCode; + + /** 语种开关 0 关闭 1 开启 */ + @Excel(name = "语种开关 0 关闭 1 开启") + private Boolean langStatus; + + +} diff --git a/ff-admin/src/main/java/com/ff/common/domain/TenantSecretKey.java b/ff-admin/src/main/java/com/ff/common/domain/TenantSecretKey.java new file mode 100644 index 0000000..15e313d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/domain/TenantSecretKey.java @@ -0,0 +1,37 @@ +package com.ff.common.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.Data; +/** + * 用户租户密钥对象 ff_tenant_secret_key + * + * @author shi + * @date 2025-02-11 + */ +@Data +public class TenantSecretKey extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 租户key */ + @Excel(name = "租户key") + private String tenantKey; + + /** 商户后缀 */ + @Excel(name = "商户后缀") + private String tenantSn; + + /** 租户密钥 */ + @Excel(name = "租户密钥") + private String tenantSecret; + + /** 租户状态(0正常 1停用) */ + @Excel(name = "租户状态", readConverterExp = "0=正常,1=停用") + private String tenantStatus; + + +} diff --git a/ff-admin/src/main/java/com/ff/common/mapper/CurrencyMapper.java b/ff-admin/src/main/java/com/ff/common/mapper/CurrencyMapper.java new file mode 100644 index 0000000..5aaf2f4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/mapper/CurrencyMapper.java @@ -0,0 +1,61 @@ +package com.ff.common.mapper; + +import java.util.List; +import com.ff.common.domain.Currency; + +/** + * 币种Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface CurrencyMapper +{ + /** + * 查询币种 + * + * @param id 币种主键 + * @return 币种 + */ + Currency selectCurrencyById(Long id); + + /** + * 查询币种列表 + * + * @param currency 币种 + * @return 币种集合 + */ + List selectCurrencyList(Currency currency); + + /** + * 新增币种 + * + * @param currency 币种 + * @return 结果 + */ + int insertCurrency(Currency currency); + + /** + * 修改币种 + * + * @param currency 币种 + * @return 结果 + */ + int updateCurrency(Currency currency); + + /** + * 删除币种 + * + * @param id 币种主键 + * @return 结果 + */ + int deleteCurrencyById(Long id); + + /** + * 批量删除币种 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteCurrencyByIds(Long[] ids); +} diff --git a/ff-admin/src/main/java/com/ff/common/mapper/LangMapper.java b/ff-admin/src/main/java/com/ff/common/mapper/LangMapper.java new file mode 100644 index 0000000..0e7eb31 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/mapper/LangMapper.java @@ -0,0 +1,61 @@ +package com.ff.common.mapper; + +import java.util.List; +import com.ff.common.domain.Lang; + +/** + * 系统语种管理 Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface LangMapper +{ + /** + * 查询系统语种管理 + * + * @param id 系统语种管理 主键 + * @return 系统语种管理 + */ + Lang selectLangById(Long id); + + /** + * 查询系统语种管理 列表 + * + * @param lang 系统语种管理 + * @return 系统语种管理 集合 + */ + List selectLangList(Lang lang); + + /** + * 新增系统语种管理 + * + * @param lang 系统语种管理 + * @return 结果 + */ + int insertLang(Lang lang); + + /** + * 修改系统语种管理 + * + * @param lang 系统语种管理 + * @return 结果 + */ + int updateLang(Lang lang); + + /** + * 删除系统语种管理 + * + * @param id 系统语种管理 主键 + * @return 结果 + */ + int deleteLangById(Long id); + + /** + * 批量删除系统语种管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteLangByIds(Long[] ids); +} diff --git a/ff-admin/src/main/java/com/ff/common/mapper/TenantSecretKeyMapper.java b/ff-admin/src/main/java/com/ff/common/mapper/TenantSecretKeyMapper.java new file mode 100644 index 0000000..9a445f9 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/mapper/TenantSecretKeyMapper.java @@ -0,0 +1,69 @@ +package com.ff.common.mapper; + +import java.util.List; +import com.ff.common.domain.TenantSecretKey; + +/** + * 用户租户密钥Mapper接口 + * + * @author shi + * @date 2025-02-11 + */ +public interface TenantSecretKeyMapper +{ + /** + * 查询用户租户密钥 + * + * @param id 用户租户密钥主键 + * @return 用户租户密钥 + */ + TenantSecretKey selectTenantSecretKeyById(Long id); + + /** + * 按租户密钥选择租户密钥 + * + * @param tenantKey 租户密钥 + * @return {@link TenantSecretKey } + */ + TenantSecretKey selectTenantSecretKeyByTenantKey(String tenantKey); + + /** + * 查询用户租户密钥列表 + * + * @param tenantSecretKey 用户租户密钥 + * @return 用户租户密钥集合 + */ + List selectTenantSecretKeyList(TenantSecretKey tenantSecretKey); + + /** + * 新增用户租户密钥 + * + * @param tenantSecretKey 用户租户密钥 + * @return 结果 + */ + int insertTenantSecretKey(TenantSecretKey tenantSecretKey); + + /** + * 修改用户租户密钥 + * + * @param tenantSecretKey 用户租户密钥 + * @return 结果 + */ + int updateTenantSecretKey(TenantSecretKey tenantSecretKey); + + /** + * 删除用户租户密钥 + * + * @param id 用户租户密钥主键 + * @return 结果 + */ + int deleteTenantSecretKeyById(Long id); + + /** + * 批量删除用户租户密钥 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteTenantSecretKeyByIds(Long[] ids); +} diff --git a/ff-admin/src/main/java/com/ff/common/service/ICurrencyService.java b/ff-admin/src/main/java/com/ff/common/service/ICurrencyService.java new file mode 100644 index 0000000..b8c94f4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/service/ICurrencyService.java @@ -0,0 +1,61 @@ +package com.ff.common.service; + +import java.util.List; +import com.ff.common.domain.Currency; + +/** + * 币种Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface ICurrencyService +{ + /** + * 查询币种 + * + * @param id 币种主键 + * @return 币种 + */ + Currency selectCurrencyById(Long id); + + /** + * 查询币种列表 + * + * @param currency 币种 + * @return 币种集合 + */ + List selectCurrencyList(Currency currency); + + /** + * 新增币种 + * + * @param currency 币种 + * @return 结果 + */ + int insertCurrency(Currency currency); + + /** + * 修改币种 + * + * @param currency 币种 + * @return 结果 + */ + int updateCurrency(Currency currency); + + /** + * 批量删除币种 + * + * @param ids 需要删除的币种主键集合 + * @return 结果 + */ + int deleteCurrencyByIds(Long[] ids); + + /** + * 删除币种信息 + * + * @param id 币种主键 + * @return 结果 + */ + int deleteCurrencyById(Long id); +} diff --git a/ff-admin/src/main/java/com/ff/common/service/ILangService.java b/ff-admin/src/main/java/com/ff/common/service/ILangService.java new file mode 100644 index 0000000..d28a5d2 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/service/ILangService.java @@ -0,0 +1,61 @@ +package com.ff.common.service; + +import java.util.List; +import com.ff.common.domain.Lang; + +/** + * 系统语种管理 Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface ILangService +{ + /** + * 查询系统语种管理 + * + * @param id 系统语种管理 主键 + * @return 系统语种管理 + */ + Lang selectLangById(Long id); + + /** + * 查询系统语种管理 列表 + * + * @param lang 系统语种管理 + * @return 系统语种管理 集合 + */ + List selectLangList(Lang lang); + + /** + * 新增系统语种管理 + * + * @param lang 系统语种管理 + * @return 结果 + */ + int insertLang(Lang lang); + + /** + * 修改系统语种管理 + * + * @param lang 系统语种管理 + * @return 结果 + */ + int updateLang(Lang lang); + + /** + * 批量删除系统语种管理 + * + * @param ids 需要删除的系统语种管理 主键集合 + * @return 结果 + */ + int deleteLangByIds(Long[] ids); + + /** + * 删除系统语种管理 信息 + * + * @param id 系统语种管理 主键 + * @return 结果 + */ + int deleteLangById(Long id); +} diff --git a/ff-admin/src/main/java/com/ff/common/service/ITenantSecretKeyService.java b/ff-admin/src/main/java/com/ff/common/service/ITenantSecretKeyService.java new file mode 100644 index 0000000..b2fefc9 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/service/ITenantSecretKeyService.java @@ -0,0 +1,69 @@ +package com.ff.common.service; + +import java.util.List; +import com.ff.common.domain.TenantSecretKey; + +/** + * 用户租户密钥Service接口 + * + * @author shi + * @date 2025-02-11 + */ +public interface ITenantSecretKeyService +{ + /** + * 查询用户租户密钥 + * + * @param id 用户租户密钥主键 + * @return 用户租户密钥 + */ + TenantSecretKey selectTenantSecretKeyById(Long id); + + /** + * 按租户密钥选择租户密钥 + * + * @param tenantKey 租户密钥 + * @return {@link TenantSecretKey } + */ + TenantSecretKey selectTenantSecretKeyByTenantKey(String tenantKey); + + /** + * 查询用户租户密钥列表 + * + * @param tenantSecretKey 用户租户密钥 + * @return 用户租户密钥集合 + */ + List selectTenantSecretKeyList(TenantSecretKey tenantSecretKey); + + /** + * 新增用户租户密钥 + * + * @param tenantSecretKey 用户租户密钥 + * @return 结果 + */ + int insertTenantSecretKey(TenantSecretKey tenantSecretKey); + + /** + * 修改用户租户密钥 + * + * @param tenantSecretKey 用户租户密钥 + * @return 结果 + */ + int updateTenantSecretKey(TenantSecretKey tenantSecretKey); + + /** + * 批量删除用户租户密钥 + * + * @param ids 需要删除的用户租户密钥主键集合 + * @return 结果 + */ + int deleteTenantSecretKeyByIds(Long[] ids); + + /** + * 删除用户租户密钥信息 + * + * @param id 用户租户密钥主键 + * @return 结果 + */ + int deleteTenantSecretKeyById(Long id); +} diff --git a/ff-admin/src/main/java/com/ff/common/service/impl/CurrencyServiceImpl.java b/ff-admin/src/main/java/com/ff/common/service/impl/CurrencyServiceImpl.java new file mode 100644 index 0000000..45acbf0 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/service/impl/CurrencyServiceImpl.java @@ -0,0 +1,96 @@ +package com.ff.common.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.common.mapper.CurrencyMapper; +import com.ff.common.domain.Currency; +import com.ff.common.service.ICurrencyService; + +/** + * 币种Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class CurrencyServiceImpl implements ICurrencyService +{ + @Autowired + private CurrencyMapper currencyMapper; + + /** + * 查询币种 + * + * @param id 币种主键 + * @return 币种 + */ + @Override + public Currency selectCurrencyById(Long id) + { + return currencyMapper.selectCurrencyById(id); + } + + /** + * 查询币种列表 + * + * @param currency 币种 + * @return 币种 + */ + @Override + public List selectCurrencyList(Currency currency) + { + return currencyMapper.selectCurrencyList(currency); + } + + /** + * 新增币种 + * + * @param currency 币种 + * @return 结果 + */ + @Override + public int insertCurrency(Currency currency) + { + currency.setCreateTime(DateUtils.getNowDate()); + return currencyMapper.insertCurrency(currency); + } + + /** + * 修改币种 + * + * @param currency 币种 + * @return 结果 + */ + @Override + public int updateCurrency(Currency currency) + { + currency.setUpdateTime(DateUtils.getNowDate()); + return currencyMapper.updateCurrency(currency); + } + + /** + * 批量删除币种 + * + * @param ids 需要删除的币种主键 + * @return 结果 + */ + @Override + public int deleteCurrencyByIds(Long[] ids) + { + return currencyMapper.deleteCurrencyByIds(ids); + } + + /** + * 删除币种信息 + * + * @param id 币种主键 + * @return 结果 + */ + @Override + public int deleteCurrencyById(Long id) + { + return currencyMapper.deleteCurrencyById(id); + } +} diff --git a/ff-admin/src/main/java/com/ff/common/service/impl/LangServiceImpl.java b/ff-admin/src/main/java/com/ff/common/service/impl/LangServiceImpl.java new file mode 100644 index 0000000..28b62b6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/service/impl/LangServiceImpl.java @@ -0,0 +1,96 @@ +package com.ff.common.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.common.mapper.LangMapper; +import com.ff.common.domain.Lang; +import com.ff.common.service.ILangService; + +/** + * 系统语种管理 Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class LangServiceImpl implements ILangService +{ + @Autowired + private LangMapper langMapper; + + /** + * 查询系统语种管理 + * + * @param id 系统语种管理 主键 + * @return 系统语种管理 + */ + @Override + public Lang selectLangById(Long id) + { + return langMapper.selectLangById(id); + } + + /** + * 查询系统语种管理 列表 + * + * @param lang 系统语种管理 + * @return 系统语种管理 + */ + @Override + public List selectLangList(Lang lang) + { + return langMapper.selectLangList(lang); + } + + /** + * 新增系统语种管理 + * + * @param lang 系统语种管理 + * @return 结果 + */ + @Override + public int insertLang(Lang lang) + { + lang.setCreateTime(DateUtils.getNowDate()); + return langMapper.insertLang(lang); + } + + /** + * 修改系统语种管理 + * + * @param lang 系统语种管理 + * @return 结果 + */ + @Override + public int updateLang(Lang lang) + { + lang.setUpdateTime(DateUtils.getNowDate()); + return langMapper.updateLang(lang); + } + + /** + * 批量删除系统语种管理 + * + * @param ids 需要删除的系统语种管理 主键 + * @return 结果 + */ + @Override + public int deleteLangByIds(Long[] ids) + { + return langMapper.deleteLangByIds(ids); + } + + /** + * 删除系统语种管理 信息 + * + * @param id 系统语种管理 主键 + * @return 结果 + */ + @Override + public int deleteLangById(Long id) + { + return langMapper.deleteLangById(id); + } +} diff --git a/ff-admin/src/main/java/com/ff/common/service/impl/TenantSecretKeyServiceImpl.java b/ff-admin/src/main/java/com/ff/common/service/impl/TenantSecretKeyServiceImpl.java new file mode 100644 index 0000000..e3d0fe6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/common/service/impl/TenantSecretKeyServiceImpl.java @@ -0,0 +1,107 @@ +package com.ff.common.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.common.mapper.TenantSecretKeyMapper; +import com.ff.common.domain.TenantSecretKey; +import com.ff.common.service.ITenantSecretKeyService; + +/** + * 用户租户密钥Service业务层处理 + * + * @author shi + * @date 2025-02-11 + */ +@Service +public class TenantSecretKeyServiceImpl implements ITenantSecretKeyService +{ + @Autowired + private TenantSecretKeyMapper tenantSecretKeyMapper; + + /** + * 查询用户租户密钥 + * + * @param id 用户租户密钥主键 + * @return 用户租户密钥 + */ + @Override + public TenantSecretKey selectTenantSecretKeyById(Long id) + { + return tenantSecretKeyMapper.selectTenantSecretKeyById(id); + } + + /** + * 按租户密钥选择租户密钥 + * + * @param tenantKey 租户密钥 + * @return {@link TenantSecretKey } + */ + @Override + public TenantSecretKey selectTenantSecretKeyByTenantKey(String tenantKey) { + return tenantSecretKeyMapper.selectTenantSecretKeyByTenantKey(tenantKey); + } + + /** + * 查询用户租户密钥列表 + * + * @param tenantSecretKey 用户租户密钥 + * @return 用户租户密钥 + */ + @Override + public List selectTenantSecretKeyList(TenantSecretKey tenantSecretKey) + { + return tenantSecretKeyMapper.selectTenantSecretKeyList(tenantSecretKey); + } + + /** + * 新增用户租户密钥 + * + * @param tenantSecretKey 用户租户密钥 + * @return 结果 + */ + @Override + public int insertTenantSecretKey(TenantSecretKey tenantSecretKey) + { + tenantSecretKey.setCreateTime(DateUtils.getNowDate()); + return tenantSecretKeyMapper.insertTenantSecretKey(tenantSecretKey); + } + + /** + * 修改用户租户密钥 + * + * @param tenantSecretKey 用户租户密钥 + * @return 结果 + */ + @Override + public int updateTenantSecretKey(TenantSecretKey tenantSecretKey) + { + tenantSecretKey.setUpdateTime(DateUtils.getNowDate()); + return tenantSecretKeyMapper.updateTenantSecretKey(tenantSecretKey); + } + + /** + * 批量删除用户租户密钥 + * + * @param ids 需要删除的用户租户密钥主键 + * @return 结果 + */ + @Override + public int deleteTenantSecretKeyByIds(Long[] ids) + { + return tenantSecretKeyMapper.deleteTenantSecretKeyByIds(ids); + } + + /** + * 删除用户租户密钥信息 + * + * @param id 用户租户密钥主键 + * @return 结果 + */ + @Override + public int deleteTenantSecretKeyById(Long id) + { + return tenantSecretKeyMapper.deleteTenantSecretKeyById(id); + } +} diff --git a/ff-admin/src/main/java/com/ff/config/ContentRefreshedEventListener.java b/ff-admin/src/main/java/com/ff/config/ContentRefreshedEventListener.java new file mode 100644 index 0000000..0b0d82b --- /dev/null +++ b/ff-admin/src/main/java/com/ff/config/ContentRefreshedEventListener.java @@ -0,0 +1,54 @@ +package com.ff.config; + +import com.ff.base.datasource.DynamicDataSource; +import com.ff.base.system.domain.SysDatasource; +import com.ff.base.system.mapper.SysDatasourceMapper; +import com.ff.base.system.service.ISysConfigService; +import com.ff.base.system.service.ISysDictTypeService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 启动项目时加载多数据源 + * + * @author liukang + */ +@Slf4j +@Component +public class ContentRefreshedEventListener implements ApplicationListener { + + @Resource + private DynamicDataSource dynamicDataSource; + + @Resource + private SysDatasourceMapper dataSourceMapper; + + @Resource + private ISysConfigService sysConfigService; + + @Resource + private ISysDictTypeService sysDictTypeService; + /** + * 项目加载时运行 + * + * @param event + */ + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + // 创建所有数据源 + SysDatasource sysDatasource = new SysDatasource(); + sysDatasource.setStatus("1"); + List dataourceList = dataSourceMapper.selectSysDatasourceList(sysDatasource); + if (!CollectionUtils.isEmpty(dataourceList)) { + dynamicDataSource.createDataSource(dataourceList); + } + sysConfigService.loadingConfigCache(); + sysDictTypeService.loadingDictCache(); + } +} diff --git a/ff-admin/src/main/java/com/ff/config/KeyConfig.java b/ff-admin/src/main/java/com/ff/config/KeyConfig.java new file mode 100644 index 0000000..287b8eb --- /dev/null +++ b/ff-admin/src/main/java/com/ff/config/KeyConfig.java @@ -0,0 +1,44 @@ +package com.ff.config; + +import com.ff.common.domain.TenantSecretKey; +import org.springframework.stereotype.Component; + +/** + * 关键 工具 + * + * @author shi + * @date 2025/02/11 + */ +@Component +public class KeyConfig { + + // 定义一个 ThreadLocal 变量,持有当前线程的全局变量 + private ThreadLocal threadLocalVariable = new ThreadLocal<>(); + + /** + * 设置 + * + * @param value 价值 + */ + public void set(TenantSecretKey value) { + threadLocalVariable.set(value); + } + + + /** + * 得到 + * + * @return {@link String } + */ + public TenantSecretKey get() { + return threadLocalVariable.get(); + } + + + /** + * 清楚 + */ + public void clear() { + threadLocalVariable.remove(); + } +} diff --git a/ff-admin/src/main/java/com/ff/config/SwaggerConfig.java b/ff-admin/src/main/java/com/ff/config/SwaggerConfig.java new file mode 100644 index 0000000..9a689b9 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/config/SwaggerConfig.java @@ -0,0 +1,121 @@ +package com.ff.config; + +import com.ff.base.config.FFConfig; +import io.swagger.annotations.ApiOperation; +import io.swagger.models.auth.In; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.*; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; + +import java.util.ArrayList; +import java.util.List; + +/** + * Swagger2的接口配置 + * + * @author ff + */ +@Configuration +public class SwaggerConfig +{ + /** 系统基础配置 */ + @Autowired + private FFConfig ffConfig; + + /** 是否开启swagger */ + @Value("${swagger.enabled}") + private boolean enabled; + + /** 设置请求的统一前缀 */ + @Value("${swagger.pathMapping}") + private String pathMapping; + + /** + * 创建API + */ + @Bean + public Docket createRestApi() + { + return new Docket(DocumentationType.OAS_30) + // 是否启用Swagger + .enable(enabled) + // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息) + .apiInfo(apiInfo()) + // 设置哪些接口暴露给Swagger展示 + .select() + // 扫描所有有注解的api,用这种方式更灵活 + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + // 扫描指定包中的swagger注解 + // .apis(RequestHandlerSelectors.basePackage("com.ff.project.tool.swagger")) + // 扫描所有 .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build() + /* 设置安全模式,swagger可以设置访问token */ + .securitySchemes(securitySchemes()) + .securityContexts(securityContexts()) + .pathMapping(pathMapping); + } + + /** + * 安全模式,这里指定token通过Authorization头请求头传递 + */ + private List securitySchemes() + { + List apiKeyList = new ArrayList(); + apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue())); + return apiKeyList; + } + + /** + * 安全上下文 + */ + private List securityContexts() + { + List securityContexts = new ArrayList<>(); + securityContexts.add( + SecurityContext.builder() + .securityReferences(defaultAuth()) + .operationSelector(o -> o.requestMappingPattern().matches("/.*")) + .build()); + return securityContexts; + } + + /** + * 默认的安全上引用 + */ + private List defaultAuth() + { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + List securityReferences = new ArrayList<>(); + securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); + return securityReferences; + } + + /** + * 添加摘要信息 + */ + private ApiInfo apiInfo() + { + // 用ApiInfoBuilder进行定制 + return new ApiInfoBuilder() + // 设置标题 + .title("标题:FF管理系统_接口文档") + // 描述 + .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...") + // 作者信息 + .contact(new Contact(ffConfig.getName(), null, null)) + // 版本 + .version("版本号:" + ffConfig.getVersion()) + .build(); + } +} diff --git a/ff-admin/src/main/java/com/ff/file/controller/FileController.java b/ff-admin/src/main/java/com/ff/file/controller/FileController.java new file mode 100644 index 0000000..ba36f07 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/file/controller/FileController.java @@ -0,0 +1,45 @@ +package com.ff.file.controller; + +import com.ff.base.annotation.Anonymous; +import com.ff.base.constant.Constants; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.exception.base.BaseException; +import com.ff.base.utils.MessageUtils; +import com.ff.file.service.ISysFileService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import java.util.Map; + +/** + * 文件管理 + * + * @author ff + */ +@RestController +@RequestMapping("/file") +public class FileController { + + @Autowired + private Map fileServiceMap; + + /** + * 通用上传请求(单个) + */ + @PostMapping("/upload/{service}") + @Anonymous + public AjaxResult uploadFile(MultipartFile file, @PathVariable String service) { + + ISysFileService sysFileService = fileServiceMap.get(service + Constants.SERVICE); + if (sysFileService == null) { + throw new BaseException(MessageUtils.message("upload.file.server.not.exist")); + } + return sysFileService.uploadFile(file); + + } + +} diff --git a/ff-admin/src/main/java/com/ff/file/service/ISysFileService.java b/ff-admin/src/main/java/com/ff/file/service/ISysFileService.java new file mode 100644 index 0000000..485a87a --- /dev/null +++ b/ff-admin/src/main/java/com/ff/file/service/ISysFileService.java @@ -0,0 +1,21 @@ +package com.ff.file.service; + +import com.ff.base.core.domain.AjaxResult; +import org.springframework.web.multipart.MultipartFile; + +/** + * 文件上传接口 + * + * @author ruoyi + */ +public interface ISysFileService +{ + /** + * 文件上传接口 + * + * @param file 上传的文件 + * @return 访问地址 + * @throws Exception + */ + public AjaxResult uploadFile(MultipartFile file) ; +} diff --git a/ff-admin/src/main/java/com/ff/file/service/impl/LocalSysFileServiceImpl.java b/ff-admin/src/main/java/com/ff/file/service/impl/LocalSysFileServiceImpl.java new file mode 100644 index 0000000..7001aa5 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/file/service/impl/LocalSysFileServiceImpl.java @@ -0,0 +1,48 @@ +package com.ff.file.service.impl; + +import com.ff.base.config.FFConfig; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.exception.base.BaseException; +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.file.FileUploadUtils; +import com.ff.base.utils.file.FileUtils; +import com.ff.file.service.ISysFileService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +/** + * 本地文件存储 + * + * @author ruoyi + */ +@Service("localSysFileService") +@Slf4j +public class LocalSysFileServiceImpl implements ISysFileService { + /** + * 本地文件上传接口 + * + * @param file 上传的文件 + * @return 访问地址 + * @throws Exception + */ + @Override + public AjaxResult uploadFile(MultipartFile file) { + try { + // 上传文件路径 + String filePath = FFConfig.getUploadPath(); + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + AjaxResult ajax = AjaxResult.success(); + ajax.put("url", fileName); + ajax.put("fileName", FileUtils.getName(fileName)); + ajax.put("originalFilename", file.getOriginalFilename()); + return ajax; + } catch (IOException e) { + log.error("本地文件上传异常,{}", e); + throw new BaseException(MessageUtils.message("upload.file.exception"), e.getMessage()); + } + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/IGamesService.java b/ff-admin/src/main/java/com/ff/game/api/IGamesService.java new file mode 100644 index 0000000..6722464 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/IGamesService.java @@ -0,0 +1,139 @@ +package com.ff.game.api; + + + +import com.ff.game.api.request.*; +import com.ff.game.domain.GameBettingDetails; +import com.ff.game.domain.GameFreeRecord; + +import java.util.List; + +/** + * 游戏数据解析服务 + * + * @author shi + * @date 2024/10/21 + */ +public interface IGamesService { + + + /** + * 获取密钥 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + String getKey(GamesBaseRequestDTO gamesBaseRequestDTO); + + /** + * 创建成员 + * + * @param createMemberRequestDTO 创建成员请求dto + * @return {@link Boolean } + */ + Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO); + + + /** + * 获取会员信息 + * + * @param memberInfoRequestDTO 会员信息请求dto + * @return {@link MemberInfoResponseDTO } + */ + MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO); + + /** + * 无重定向登录 + * + * @param gamesLogin 游戏登录 + * @return {@link String } + */ + String loginWithoutRedirect(GamesLogin gamesLogin); + + + + /** + * 获取游戏列表 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO); + + + /** + * 按代理id进行交换转账 + * + * @param exchangeTransferMoneyRequestDTO 外汇转账moeny dto + * @return {@link Long } + */ + Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO); + + /** + * 按时间获取投注记录 + * + * @param betRecordByTimeDTO 按时间dto投注记录 + * @return {@link List }<{@link GameBettingDetails }> + */ + List getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO); + + + /** + * 赠送免费局数 + * + * @param createFreeSpinRequest 创建自由旋转请求 + * @return {@link Boolean } + */ + Boolean createFreeSpin(CreateFreeSpinRequestDTO createFreeSpinRequest); + + /** + * 获取游戏详细信息 + * + * @param getGameDetailRequestDTO 获取游戏详细信息请求dto + * @return {@link GetGameDetailResponseDTO } + */ + GetGameDetailResponseDTO getGameDetail(GetGameDetailRequestDTO getGameDetailRequestDTO); + + + /** + * 强制会员从游戏注销 + * + * @param kickMemberRequestDTO 踢会员请求dto + * @return {@link Boolean } + */ + Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO); + + /** + * 踢成员全部 + * + * @param kickMemberAllDTO 踢成员全部dto + * @return {@link Boolean } + */ + Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO); + /** + * 免费游戏玩家使用的纪录 + * + * @param getFreeSpinDashflowRequestDTO 获取自由旋转dashflow请求dto + * @return {@link List }<{@link GameFreeRecord }> + */ + List getFreeSpinDashflow(GetFreeSpinDashflowRequestDTO getFreeSpinDashflowRequestDTO); + + /** + * 取消赠送免费局数 + * + * @param cancelFreeSpinRequestDTO 取消免费旋转请求 + * @return {@link Boolean } + */ + Boolean cancelFreeSpin(CancelFreeSpinRequestDTO cancelFreeSpinRequestDTO); + + + + /** + * 数据构建 + * + * @param gamesDataBuildDTO 数据 + * @return {@link GameBettingDetails } + */ + GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO); + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/address/MyJILIAddressSource.java b/ff-admin/src/main/java/com/ff/game/api/jili/address/MyJILIAddressSource.java new file mode 100644 index 0000000..d27b734 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/address/MyJILIAddressSource.java @@ -0,0 +1,33 @@ +package com.ff.game.api.jili.address; + +import com.dtflys.forest.callback.AddressSource; +import com.dtflys.forest.http.ForestAddress; +import com.dtflys.forest.http.ForestRequest; +import com.ff.base.constant.Constants; +import com.ff.base.system.service.ISysConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Random; + + +/** + * 我jili address来源 + * + * @author shi + * @date 2025/02/10 + */ +@Component +public class MyJILIAddressSource implements AddressSource { + + @Resource + private ISysConfigService configService; + + + @Override + public ForestAddress getAddress(ForestRequest request) { + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + return new ForestAddress("https",apiBaseUrl, 443,"api1"); + } +} \ No newline at end of file diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/client/JILIClient.java b/ff-admin/src/main/java/com/ff/game/api/jili/client/JILIClient.java new file mode 100644 index 0000000..6d93e57 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/client/JILIClient.java @@ -0,0 +1,56 @@ +package com.ff.game.api.jili.client; + +import com.dtflys.forest.annotation.Address; +import com.dtflys.forest.annotation.Get; +import com.dtflys.forest.annotation.Request; +import com.dtflys.forest.annotation.Var; +import com.ff.game.api.jili.address.MyJILIAddressSource; +import com.ff.game.api.jili.dto.JILICreateMemberResponseDTO; +import com.ff.game.api.jili.dto.JILIGamesDTO; +import com.ff.game.api.jili.dto.JILILoginWithoutRedirectResponseDTO; +import com.ff.game.api.jili.dto.JILIMemberInfoDTO; + +/** + * jili 请求 + * + * @author shi + * @date 2025/02/10 + */ +@Address(source = MyJILIAddressSource.class) +public interface JILIClient { + /** + * 创建成员 + * + * @param parameters 参数 + * @return {@link String } + */ + @Get("/CreateMember?${parameters}") + JILICreateMemberResponseDTO createMember(@Var("parameters") String parameters); + + /** + * 获取会员信息 + * + * @param parameters 参数 + * @return {@link JILIMemberInfoDTO } + */ + @Get("/GetMemberInfo?${parameters}") + JILIMemberInfoDTO getMemberInfo(@Var("parameters") String parameters); + + /** + * 无重定向登录 + * + * @param parameters 参数 + * @return {@link JILILoginWithoutRedirectResponseDTO } + */ + @Get("/LoginWithoutRedirect?${parameters}") + JILILoginWithoutRedirectResponseDTO loginWithoutRedirect(@Var("parameters") String parameters); + + /** + * 获取游戏列表 + * + * @param parameters 参数 + * @return {@link JILIGamesDTO } + */ + @Get("/GetGameList?${parameters}") + JILIGamesDTO getGameList(@Var("parameters") String parameters); +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordDataResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordDataResponseDTO.java new file mode 100644 index 0000000..2ea7665 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordDataResponseDTO.java @@ -0,0 +1,89 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + + +/** + * JiLi游戏纪录查询返回数据类型 + * + * @author shi + * @date 2024/10/21 + */ +@NoArgsConstructor +@Data +public class JILIBetRecordDataResponseDTO { + /** + * 账户 + */ + @JsonProperty("Account") + private String account; + /** + * 投注id + */ + @JsonProperty("WagersId") + private long wagersId; + /** + * 游戏id + */ + @JsonProperty("GameId") + private int gameId; + /** + * 下注时间 + */ + @JsonProperty("WagersTime") + private Long wagersTime; + /** + * 投注金额 + */ + @JsonProperty("BetAmount") + private BigDecimal betAmount; + /** + * 回报时间 + */ + @JsonProperty("PayoffTime") + private Long payoffTime; + /** + * 支付金额 + */ + @JsonProperty("PayoffAmount") + private BigDecimal payoffAmount; + /** + * 注单状态 1: 赢 2: 输 3: 平局 + */ + @JsonProperty("Status") + private int status; + /** + * 结算时间 + */ + @JsonProperty("SettlementTime") + private Long settlementTime; + /** + * 游戏类别id + */ + @JsonProperty("GameCategoryId") + private int gameCategoryId; + /** + * 类型 + */ + @JsonProperty("Type") + private int type; + /** + * 代理id + */ + @JsonProperty("AgentId") + private String agentId; + /** + * 有效投注金额 + */ + @JsonProperty("Turnover") + private BigDecimal turnover; + /** + * 圆形指数 + */ + @JsonProperty("RoundIndex") + private long roundIndex; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordResponseDTO.java new file mode 100644 index 0000000..11c4567 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIBetRecordResponseDTO.java @@ -0,0 +1,62 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * JiLi游戏纪录查询返回值 + * + * @author shi + * @date 2024/10/21 + */ +@NoArgsConstructor +@Data +public class JILIBetRecordResponseDTO { + + + @JsonProperty("ErrorCode") + private int errorCode; + @JsonProperty("Message") + private String message; + @JsonProperty("Data") + private DataBean data; + + @NoArgsConstructor + @Data + public static class DataBean { + @JsonProperty("Result") + private List result; + @JsonProperty("Pagination") + private PaginationBean pagination; + + @NoArgsConstructor + @Data + public static class PaginationBean { + /** + * 当前页面 + */ + @JsonProperty("CurrentPage") + private int currentPage; + /** + * 总页数 + */ + @JsonProperty("TotalPages") + private int totalPages; + /** + * 页数限制 + */ + @JsonProperty("PageLimit") + private int pageLimit; + /** + * 总数 + */ + @JsonProperty("TotalNumber") + private int totalNumber; + } + + + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICancelFreeSpinResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICancelFreeSpinResponseDTO.java new file mode 100644 index 0000000..8723ddb --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICancelFreeSpinResponseDTO.java @@ -0,0 +1,23 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * jilicancel自由自旋响应 + * + * @author shi + * @date 2024/11/11 + */ +@NoArgsConstructor +@Data +public class JILICancelFreeSpinResponseDTO { + + @JsonProperty("ErrorCode") + private int errorCode; + @JsonProperty("Message") + private String message; + @JsonProperty("CancelTime") + private int cancelTime; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateFreeSpinResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateFreeSpinResponseDTO.java new file mode 100644 index 0000000..80f25f8 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateFreeSpinResponseDTO.java @@ -0,0 +1,31 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * jilicreate自由旋转响应dto + * + * @author shi + * @date 2024/11/11 + */ +@NoArgsConstructor +@Data +public class JILICreateFreeSpinResponseDTO { + /** + * 错误代码 + */ + @JsonProperty("ErrorCode") + private Integer errorCode; + /** + * 消息 + */ + @JsonProperty("Message") + private String message; + /** + * 创造时间 + */ + @JsonProperty("CreateTime") + private Integer createTime; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateMemberResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateMemberResponseDTO.java new file mode 100644 index 0000000..db07ebf --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILICreateMemberResponseDTO.java @@ -0,0 +1,28 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ff.game.api.request.GamesBaseRequestDTO; +import lombok.Data; + + +/** + * 创建成员响应dto + * + * @author shi + * @date 2024/10/22 + */ +@Data +public class JILICreateMemberResponseDTO extends GamesBaseRequestDTO { + + /** + * 错误代码 + */ + @JsonProperty("ErrorCode") + private int errorCode; + /** + * 消息 + */ + @JsonProperty("Message") + private String message; + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIExchangeMoneyResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIExchangeMoneyResponseDTO.java new file mode 100644 index 0000000..2098f01 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIExchangeMoneyResponseDTO.java @@ -0,0 +1,72 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * jiliexchange货币回应 + * + * @author shi + * @date 2024/10/22 + */ +@Data +public class JILIExchangeMoneyResponseDTO { + + + /** + * 错误代码 + */ + @JsonProperty("ErrorCode") + private int errorCode; + /** + * 消息 + */ + @JsonProperty("Message") + private String message; + + + + @JsonProperty("Data") + private BeanData data; + + @Data + public class BeanData{ + /** + * 交易序号,额度转移纪录唯一值, 长度上限 50 + */ + @JsonProperty("TransactionId") + private String transactionId; + /** + * 转账前金额(游戏币) + */ + @JsonProperty("CoinBefore") + private BigDecimal coinBefore; + /** + * 转账后金额(游戏币) + */ + @JsonProperty("CoinAfter") + private BigDecimal coinAfter; + /** + * 转账前金额(指定货币) + */ + @JsonProperty("CurrencyBefore") + private BigDecimal currencyBefore; + /** + * 转账后金额(指定货币) + */ + @JsonProperty("CurrencyAfter") + private BigDecimal currencyAfter; + /** + * 状态: + * 1: 成功 + * 2: 失败 + */ + @JsonProperty("Status") + private Integer status; + } + + + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDTO.java new file mode 100644 index 0000000..e4707d1 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDTO.java @@ -0,0 +1,38 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 游戏 + * + * @author shi + * @date 2024/10/22 + */ + +@NoArgsConstructor +@Data +public class JILIGamesDTO { + + + /** + * 错误代码 + */ + @JsonProperty("ErrorCode") + private int errorCode; + /** + * 消息 + */ + @JsonProperty("Message") + private String message; + /** + * 数据 + */ + @JsonProperty("Data") + private List data; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDataDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDataDTO.java new file mode 100644 index 0000000..c2ba812 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGamesDataDTO.java @@ -0,0 +1,66 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * jiligames数据dto + * + * @author shi + * @date 2024/10/22 + */ +@NoArgsConstructor +@Data +public class JILIGamesDataDTO { + /** + * 游戏id + */ + @JsonProperty("GameId") + private int gameId; + + /** + *自己系统游戏id + */ + private Long systemGameId; + + /** + * 名称 + */ + private NameBean name; + /** + * 游戏类别id + */ + @JsonProperty("GameCategoryId") + private int gameCategoryId; + /** + * jp + */ + @JsonProperty("JP") + private boolean jP; + /** + * freespin + */ + @JsonProperty("Freespin") + private boolean freespin; + + @NoArgsConstructor + @Data + public static class NameBean { + /** + * en-us + */ + @JsonProperty("en-US") + private String enUS; + /** + * zh cn + */ + @JsonProperty("zh-CN") + private String zhCN; + /** + * zh-tw + */ + @JsonProperty("zh-TW") + private String zhTW; + } +} \ No newline at end of file diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetFreeSpinDashflowResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetFreeSpinDashflowResponseDTO.java new file mode 100644 index 0000000..469cec7 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetFreeSpinDashflowResponseDTO.java @@ -0,0 +1,74 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * jiliget自由旋转气流响应dto + * + * @author shi + * @date 2024/11/11 + */ +@NoArgsConstructor +@Data +public class JILIGetFreeSpinDashflowResponseDTO { + /** 错误码 */ + @JsonProperty("ErrorCode") + private int errorCode; + + /** 错误信息 */ + @JsonProperty("Message") + private String message; + + /** 数据列表 */ + @JsonProperty("Data") + private List data; + + /** + * 内部类 DataBean + */ + @NoArgsConstructor + @Data + public static class DataBean { + + /** 用户账号 */ + @JsonProperty("Account") + private String account; + + /** 参考ID */ + @JsonProperty("ReferenceID") + private String referenceID; + + /** 发送时间 */ + @JsonProperty("SendTime") + private Long sendTime; + + /** 过期时间 */ + @JsonProperty("ExpiredTime") + private Long expiredTime; + + /** 更新时间 */ + @JsonProperty("UpdateTime") + private Long updateTime; + + /** 发送金额 */ + @JsonProperty("SendAmount") + private int sendAmount; + + /** 已使用金额 */ + @JsonProperty("UsedAmount") + private int usedAmount; + + /** 未使用金额 */ + @JsonProperty("UnusedAmount") + private int unusedAmount; + + /** 可领取的游戏 */ + @JsonProperty("ClaimGame") + private int claimGame; + } + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetGameDetailResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetGameDetailResponseDTO.java new file mode 100644 index 0000000..2dd7594 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIGetGameDetailResponseDTO.java @@ -0,0 +1,31 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 获取游戏详细信息请求dto + * + * @author shi + * @date 2024/11/12 + */ +@NoArgsConstructor +@Data +public class JILIGetGameDetailResponseDTO { + + + @JsonProperty("ErrorCode") + private int errorCode; + @JsonProperty("Message") + private String message; + @JsonProperty("Data") + private DataBean data; + + @NoArgsConstructor + @Data + public static class DataBean { + @JsonProperty("Url") + private String url; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberAllDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberAllDTO.java new file mode 100644 index 0000000..fc7a3b6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberAllDTO.java @@ -0,0 +1,21 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * jilikick会员全部dto + * + * @author shi + * @date 2024/11/12 + */ +@NoArgsConstructor +@Data +public class JILIKickMemberAllDTO { + + @JsonProperty("ErrorCode") + private int errorCode; + @JsonProperty("Message") + private String message; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberDTO.java new file mode 100644 index 0000000..9f40b74 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIKickMemberDTO.java @@ -0,0 +1,15 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Data +public class JILIKickMemberDTO { + + @JsonProperty("ErrorCode") + private int errorCode; + @JsonProperty("Message") + private String message; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILILoginWithoutRedirectResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILILoginWithoutRedirectResponseDTO.java new file mode 100644 index 0000000..1d85aa9 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILILoginWithoutRedirectResponseDTO.java @@ -0,0 +1,23 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 登录时不重定向响应dto + * + * @author shi + * @date 2024/10/22 + */ +@NoArgsConstructor +@Data +public class JILILoginWithoutRedirectResponseDTO { + + @JsonProperty("ErrorCode") + private int errorCode; + @JsonProperty("Message") + private String message; + @JsonProperty("Data") + private String data; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIMemberInfoDTO.java b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIMemberInfoDTO.java new file mode 100644 index 0000000..72465d2 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/dto/JILIMemberInfoDTO.java @@ -0,0 +1,62 @@ +package com.ff.game.api.jili.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 会员信息dto + * + * @author shi + * @date 2024/10/30 + */ +@NoArgsConstructor +@Data +public class JILIMemberInfoDTO { + + + /** + * 错误代码 + */ + @JsonProperty("ErrorCode") + private int errorCode; + /** + * 消息 + */ + @JsonProperty("Message") + private String message; + /** + * 数据 + */ + @JsonProperty("Data") + private List data; + + /** + * 数据bean + * + * @author shi + * @date 2024/10/30 + */ + @NoArgsConstructor + @Data + public static class DataBean { + /** + * 账户 + */ + @JsonProperty("Account") + private String account; + /** + * 平衡 + */ + @JsonProperty("Balance") + private BigDecimal balance; + /** + * 地位 + */ + @JsonProperty("Status") + private Integer status; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/jili/service/impl/GamesJILIServiceImpl.java b/ff-admin/src/main/java/com/ff/game/api/jili/service/impl/GamesJILIServiceImpl.java new file mode 100644 index 0000000..dd06303 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/jili/service/impl/GamesJILIServiceImpl.java @@ -0,0 +1,763 @@ +package com.ff.game.api.jili.service.impl; + +import cn.hutool.core.util.NumberUtil; +import com.alibaba.fastjson2.JSON; +import com.ff.base.constant.CacheConstants; +import com.ff.base.constant.Constants; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.enums.FreeStatus; +import com.ff.base.enums.GamePlatforms; +import com.ff.base.enums.GameStatus; +import com.ff.base.enums.JILIGameType; +import com.ff.base.exception.base.BaseException; +import com.ff.base.system.service.ISysConfigService; +import com.ff.base.utils.DateUtils; +import com.ff.base.utils.JsonUtil; +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.http.HttpClientSslUtils; +import com.ff.base.utils.http.HttpUtils; +import com.ff.base.utils.sign.Md5Utils; +import com.ff.base.utils.uuid.IdUtils; +import com.ff.game.api.IGamesService; +import com.ff.game.api.jili.client.JILIClient; +import com.ff.game.api.jili.dto.*; +import com.ff.game.api.request.*; +import com.ff.game.domain.*; +import com.ff.game.service.*; +import com.ff.member.domain.Member; +import com.ff.member.service.IMemberService; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.entity.ContentType; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + + +/** + * 游戏数据解析服务 + * + * @author shi + * @date 2024/10/21 + */ +@Service("JILIService") +@Slf4j +public class GamesJILIServiceImpl implements IGamesService { + + + @Resource + private ISysConfigService configService; + + @Resource + private RedisCache redisCache; + + @Resource + private IGameExchangeMoneyService gameExchangeMoneyService; + + + @Resource + private IGamePlatformService gamePlatformService; + + + @Resource + private IGameService gameService; + + + @Resource + private IMemberService memberService; + + @Resource + private IGameFreeRecordService gameFreeRecordService; + + @Resource + private IGameSecretKeyService gameSecretKeyService; + + @Resource + private JILIClient jiliClient; + + /** + * 获得就是成功 + * + * @param errorCode 错误代码 + * @return {@link Boolean } + */ + private Boolean getIsSuccess(Integer errorCode) { + return 0 == errorCode; + } + + + /** + * 获取密钥 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + @Override + public String getKey(GamesBaseRequestDTO gamesBaseRequestDTO) { + Random random = new Random(); + //取出对应的key跟密钥跟请求参数 + String agentKey = gamesBaseRequestDTO.getAgentKey(); + String agentId = gamesBaseRequestDTO.getAgentId(); + String query = gamesBaseRequestDTO.getQuery(); + + String now = DateUtils.getFormattedDate(); + String keyG = Md5Utils.md5New(now + agentId + agentKey); + + String md5string = Md5Utils.md5New(query + keyG); + Integer randomText1 = 100000 + random.nextInt(900000); + Integer randomText2 = 100000 + random.nextInt(900000); + String key = randomText1 + md5string + randomText2; + return key; + } + + /** + * 创建成员 + * + * @param createMemberRequestDTO 创建成员请求dto + * @return {@link Boolean } + */ + @Override + public Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO) { + String query = "Account=" + createMemberRequestDTO.getAccount() + "&AgentId=" + createMemberRequestDTO.getAgentId(); + log.info("GamesJILIServiceImpl [createMember] 请求参数 {}", query); + createMemberRequestDTO.setQuery(query); + String key = this.getKey(createMemberRequestDTO); + JILICreateMemberResponseDTO createMemberResponseDTO = jiliClient.createMember(query + "&Key=" + key); + Boolean isSuccess = this.getIsSuccess(createMemberResponseDTO.getErrorCode()); + if (!isSuccess) { + throw new BaseException(createMemberResponseDTO.getMessage()); + } + //判断是否获取成功 + return isSuccess; + } + + + /** + * 获取会员信息 + * + * @param memberInfoRequestDTO 会员信息请求dto + * @return {@link MemberInfoResponseDTO } + */ + @Override + public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO) { + String query = "Accounts=" + memberInfoRequestDTO.getAccounts() + "&AgentId=" + memberInfoRequestDTO.getAgentId(); + log.info("GamesJILIServiceImpl [getMemberInfo] 请求参数 {}", query); + memberInfoRequestDTO.setQuery(query); + String key = this.getKey(memberInfoRequestDTO); + JILIMemberInfoDTO jiliMemberInfoDTO = jiliClient.getMemberInfo(query + "&Key=" + key); + //判断是否获取成功 + if (this.getIsSuccess(jiliMemberInfoDTO.getErrorCode())) { + List memberInfoResponseDTOS = new ArrayList<>(); + jiliMemberInfoDTO.getData().forEach(e -> { + memberInfoResponseDTOS.add(MemberInfoResponseDTO.builder() + .status(e.getStatus()) + .balance(e.getBalance()) + .account(e.getAccount()) + .build()); + }); + return memberInfoResponseDTOS.get(0); + } else { + throw new BaseException(jiliMemberInfoDTO.getMessage()); + } + } + + /** + * 无重定向登录 + * + * @param gamesLogin 游戏登录 + * @return {@link String } + */ + @Override + public String loginWithoutRedirect(GamesLogin gamesLogin) { + String query = "Account=" + gamesLogin.getAccount() + "&GameId=" + gamesLogin.getGameId() + "&Lang=" + gamesLogin.getLang() + "&AgentId=" + gamesLogin.getAgentId(); + log.info("GamesJILIServiceImpl [loginWithoutRedirect] 请求参数 {}", query); + gamesLogin.setQuery(query); + String key = this.getKey(gamesLogin); + +// if (!StringUtils.isEmpty(gamesLogin.getHomeUrl())) { +// query += "&HomeUrl=" + gamesLogin.getHomeUrl(); +// } + if (!StringUtils.isEmpty(gamesLogin.getPlatform())) { + query += "&platform=" + gamesLogin.getPlatform(); + } + if (!ObjectUtils.isEmpty(gamesLogin.getDisableFullScreen())) { + query += "&disableFullScreen=" + gamesLogin.getDisableFullScreen(); + } + + JILILoginWithoutRedirectResponseDTO loginWithoutRedirectResponseDTO = jiliClient.loginWithoutRedirect(query + "&AgentId=" + gamesLogin.getAgentId() + "&Key=" + key); + //判断是否获取成功 + if (this.getIsSuccess(loginWithoutRedirectResponseDTO.getErrorCode())) { + return loginWithoutRedirectResponseDTO.getData(); + } else { + throw new BaseException(loginWithoutRedirectResponseDTO.getMessage()); + } + + } + + + /** + * 获取游戏列表 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + @Transactional + @Override + public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) { + + List gamesDatas = redisCache.getCacheList(CacheConstants.JILI_GAMES); + if (!CollectionUtils.isEmpty(gamesDatas)) { + return CacheConstants.JILI_GAMES; + } + + + gamesBaseRequestDTO.setQuery("AgentId=" + gamesBaseRequestDTO.getAgentId()); + String key = this.getKey(gamesBaseRequestDTO); + JILIGamesDTO jiliGames = jiliClient.getGameList("AgentId=" + gamesBaseRequestDTO.getAgentId() + "&Key=" + key); + //判断是否获取成功 + if (this.getIsSuccess(jiliGames.getErrorCode())) { + + for (JILIGamesDataDTO gamesDataDTO : jiliGames.getData()) { + if (JILIGameType.GAME_HALL.getCode().equals(gamesDataDTO.getGameCategoryId())) { + continue; + } + + GamePlatform gamePlatform = GamePlatform.builder() + .platformType(JILIGameType.findSystemByCode(gamesDataDTO.getGameCategoryId())) + .platformCode(GamePlatforms.JILI.getCode()) + .build(); + List gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform); + //没有此平台就新增一个平台 + if (CollectionUtils.isEmpty(gamePlatforms)) { + gamePlatform.setPlatformName(GamePlatforms.JILI.getInfo() + JILIGameType.findInfoByCode(gamesDataDTO.getGameCategoryId())); + gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1); + gamePlatform.setCreateBy(Constants.SYSTEM); + gamePlatformService.insertGamePlatform(gamePlatform); + } else { + gamePlatform = gamePlatforms.get(0); + } + Game game = Game.builder() + .platformId(gamePlatform.getId()) + .gameCode(gamesDataDTO.getGameId()) + .build(); + List games = gameService.selectGameList(game); + //不存在这个游戏 + if (CollectionUtils.isEmpty(games)) { + game.setFreespin(gamesDataDTO.isFreespin()); + game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1); + game.setGameName(gamesDataDTO.getName().getZhCN()); + game.setCreateBy(Constants.SYSTEM); + gameService.insertGame(game); + } else { + game = games.get(0); + } + gamesDataDTO.setSystemGameId(game.getId()); + + + } + + redisCache.deleteObject(CacheConstants.JILI_GAMES); + redisCache.setCacheList(CacheConstants.JILI_GAMES, jiliGames.getData()); + redisCache.expire(CacheConstants.JILI_GAMES, 5L, TimeUnit.HOURS); + } else { + log.error("GameBettingDataJILIServiceImpl [getGameList] 获取游戏列表失败,错误代码{},错误信息{}", jiliGames.getErrorCode(), jiliGames.getMessage()); + throw new BaseException(MessageUtils.message("game.list.retrieve.failed")); + + } + + return CacheConstants.JILI_GAMES; + } + + /** + * 按代理id进行交换转账 + * + * @param exchangeTransferMoneyRequestDTO 外汇转账moeny dto + * @return {@link Long } + */ + @Override + @Transactional + public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { + String systemByCode = gameSecretKeyService.findSystemByCode(exchangeTransferMoneyRequestDTO.getAgentId(), GamePlatforms.JILI.getInfo()); + Member member = memberService.selectMemberByMemberAccount(exchangeTransferMoneyRequestDTO.getAccount()); + String transactionId = exchangeTransferMoneyRequestDTO.getTransactionId(); + //如果没有自定义单号 + if (!StringUtils.hasText(exchangeTransferMoneyRequestDTO.getTransactionId())) { + transactionId = GamePlatforms.JILI.getCode() + IdUtils.simpleUUID(); + } + + //获取下一个自增id + GameExchangeMoney exchangeMoney = GameExchangeMoney + .builder() + .quota(exchangeTransferMoneyRequestDTO.getQuota()) + .platformId(exchangeTransferMoneyRequestDTO.getPlatformId()) + .balance(exchangeTransferMoneyRequestDTO.getAmount()) + .exchangeType(exchangeTransferMoneyRequestDTO.getTransferType()) + .currencyCode(systemByCode) + .memberId(member.getId()) + .platformCode(GamePlatforms.JILI.getCode()) + .build(); + exchangeMoney.setCreateBy(Constants.SYSTEM); + //接口限制限制50字符 + exchangeMoney.setTransactionId(transactionId); + String query = "Account=" + exchangeTransferMoneyRequestDTO.getAccount() + + "&TransactionId=" + exchangeMoney.getTransactionId() + + "&Amount=" + exchangeTransferMoneyRequestDTO.getAmount() + + "&TransferType=" + exchangeTransferMoneyRequestDTO.getTransferType() + + "&AgentId=" + exchangeTransferMoneyRequestDTO.getAgentId(); + log.info("GamesJILIServiceImpl [exchangeTransferByAgentId] 请求参数 {}", query); + exchangeTransferMoneyRequestDTO.setQuery(query); + + String key = this.getKey(exchangeTransferMoneyRequestDTO); + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + try { + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/ExchangeTransferByAgentId?" + query + "&Key=" + key, "AgentId=" + exchangeTransferMoneyRequestDTO.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED); + + JILIExchangeMoneyResponseDTO exchangeMoneyResponse = JsonUtil.stringToObj(result, JILIExchangeMoneyResponseDTO.class); + //判断是否转移成功 + if (this.getIsSuccess(exchangeMoneyResponse.getErrorCode())) { + JILIExchangeMoneyResponseDTO.BeanData exchangeMoneyResponseData = exchangeMoneyResponse.getData(); + //更新数据 + exchangeMoney.setBalance(NumberUtil.sub(exchangeMoneyResponseData.getCurrencyAfter(), exchangeMoneyResponseData.getCurrencyBefore()).abs()); + exchangeMoney.setCoinBefore(exchangeMoneyResponseData.getCoinBefore()); + exchangeMoney.setCoinAfter(exchangeMoneyResponseData.getCoinAfter()); + exchangeMoney.setCurrencyBefore(exchangeMoneyResponseData.getCurrencyBefore()); + exchangeMoney.setCurrencyAfter(exchangeMoneyResponseData.getCurrencyAfter()); + exchangeMoney.setStatus(exchangeMoneyResponseData.getStatus()); + gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney); + } else { + log.error("GameBettingDataJILIServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", exchangeMoneyResponse.getErrorCode(), exchangeMoneyResponse.getMessage()); + throw new BaseException(MessageUtils.message("game.account.balance.transfer.failed")); + + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.account.balance.transfer.failed")); + + } + + return exchangeMoney.getId(); + } + + + /** + * 按时间获取投注记录 + * + * @param betRecordByTimeDTO 按时间dto投注记录 + * @return {@link List }<{@link GameBettingDetails }> + */ + @Override + public List getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) { + String startTime = DateUtils.formatDateToGMT4(new Date(betRecordByTimeDTO.getStartTime())); + String endTime = DateUtils.formatDateToGMT4(new Date(betRecordByTimeDTO.getEndTime())); + List gameBettingDetails = new ArrayList<>(); + //请求参数 + String query = "StartTime=" + startTime + "&EndTime=" + endTime + "&Page=" + betRecordByTimeDTO.getPage() + "&PageLimit=" + betRecordByTimeDTO.getPageLimit() + "&AgentId=" + betRecordByTimeDTO.getAgentId(); + log.info("GamesJILIServiceImpl [getBetRecordByTime] 请求参数 {}", query); + betRecordByTimeDTO.setQuery(query); + //获取key + String key = this.getKey(betRecordByTimeDTO); + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + String result = null; + try { + result = HttpClientSslUtils.doPost(apiBaseUrl + "/GetBetRecordByTime?" + query + "&Key=" + key, "AgentId=" + betRecordByTimeDTO.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED); + + JILIBetRecordResponseDTO betRecordJILIResponse = JSON.parseObject(result, JILIBetRecordResponseDTO.class); + + //判断是否获取成功 + if (this.getIsSuccess(betRecordJILIResponse.getErrorCode())) { + //数据组装 + JILIBetRecordResponseDTO.DataBean dataBean = betRecordJILIResponse.getData(); + for (JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO : dataBean.getResult()) { + GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(jiliBetRecordDataResponseDTO).gamesKey(key).build()); + if (!ObjectUtils.isEmpty(bettingDetails)) { + gameBettingDetails.add(bettingDetails); + } + + } + + //获取下一页数据 + while (dataBean.getPagination().getCurrentPage() != dataBean.getPagination().getTotalPages() && dataBean.getPagination().getTotalPages() > 0) { + betRecordByTimeDTO.setPage(dataBean.getPagination().getCurrentPage() + 1); + //请求参数 + query = "StartTime=" + startTime + "&EndTime=" + endTime + "&Page=" + betRecordByTimeDTO.getPage() + "&PageLimit=" + betRecordByTimeDTO.getPageLimit() + "&AgentId=" + betRecordByTimeDTO.getAgentId(); + log.info("GamesJILIServiceImpl [getBetRecordByTime] 请求参数 {}", query); + betRecordByTimeDTO.setQuery(query); + key = this.getKey(betRecordByTimeDTO); + result = HttpUtils.sendPost(apiBaseUrl + "/GetBetRecordByTime?" + query + "&Key=" + key, ""); + betRecordJILIResponse = JsonUtil.stringToObj(result, JILIBetRecordResponseDTO.class); + dataBean = betRecordJILIResponse.getData(); + for (JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO : dataBean.getResult()) { + GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(jiliBetRecordDataResponseDTO).gamesKey(key).build()); + if (!ObjectUtils.isEmpty(bettingDetails)) { + gameBettingDetails.add(bettingDetails); + } + } + } + + + return gameBettingDetails; + } else { + log.error("GameBettingDataJILIServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", betRecordJILIResponse.getErrorCode(), betRecordJILIResponse.getMessage()); + throw new BaseException(MessageUtils.message("game.bet.record.retrieve.failed")); + + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [getBetRecordByTime] 获取投注记录失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.bet.record.retrieve.failed")); + + } + + } + + /** + * 赠送免费局数 + * + * @param createFreeSpinRequest 创建自由旋转请求 + * @return {@link Boolean } + */ + @Override + public Boolean createFreeSpin(CreateFreeSpinRequestDTO createFreeSpinRequest) { + + String freeSpinValidity = DateUtils.formatDateToGMT4(new Date(createFreeSpinRequest.getFreeSpinValidity())); + + + List gameIds = createFreeSpinRequest.getGameIds(); + GameUniqueDTO gameUniqueDTO = new GameUniqueDTO(); + gameUniqueDTO.setGameIds(gameIds); + List gameList = gameService.selectGameUniqueList(gameUniqueDTO); + String gameCodes = gameList.stream() + .map(Game::getGameCode) + .map(String::valueOf) + .collect(Collectors.joining(",")); + String referenceId = GamePlatforms.JILI.getCode() + IdUtils.simpleUUID(); + //请求参数 + String query = "Account=" + createFreeSpinRequest.getAccount() + + "&Currency=" + createFreeSpinRequest.getCurrency() + + "&ReferenceId=" + referenceId + + "&FreeSpinValidity=" + freeSpinValidity + + "&NumberOfRounds=" + createFreeSpinRequest.getNumberOfRounds() + + "&GameIds=" + gameCodes; + //判断是否有免费游戏局数可使用的开始时间 + if (!ObjectUtils.isEmpty(createFreeSpinRequest.getStartTime())) { + String startTime = DateUtils.formatDateToGMT4(new Date(createFreeSpinRequest.getStartTime())); + query += "&StartTime=" + startTime; + } + query += "&AgentId=" + createFreeSpinRequest.getAgentId(); + ; + log.info("GamesJILIServiceImpl [createFreeSpin] 请求参数 {}", query); + createFreeSpinRequest.setQuery(query); + //获取key + String key = this.getKey(createFreeSpinRequest); + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + String result = null; + try { + result = HttpClientSslUtils.doPost(apiBaseUrl + "/CreateFreeSpin?" + query + "&Key=" + key, "AgentId=" + createFreeSpinRequest.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED); + + JILICreateFreeSpinResponseDTO createFreeSpinResponseDTO = JSON.parseObject(result, JILICreateFreeSpinResponseDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(createFreeSpinResponseDTO.getErrorCode())) { + Member member = memberService.selectMemberByMemberAccount(createFreeSpinRequest.getAccount()); + if (ObjectUtils.isEmpty(member)) { + member = new Member(); + } + for (Game game : gameList) { + GameFreeRecord gameFreeRecord = GameFreeRecord.builder() + .currencyCode(gameSecretKeyService.findSystemByCode(createFreeSpinRequest.getAgentId(), GamePlatforms.JILI.getInfo())) + .referenceId(referenceId) + .memberId(member.getId()) + .memberAccount(createFreeSpinRequest.getAccount()) + .gameId(game.getId()) + .sendTime(createFreeSpinRequest.getStartTime()) + .expiredTime(createFreeSpinRequest.getFreeSpinValidity()) + .freeUpdateTime(DateUtils.getNowDate()) + .sendGame(game.getGameName()) + .sendAmount(createFreeSpinRequest.getNumberOfRounds()) + .unusedAmount(createFreeSpinRequest.getNumberOfRounds()) + .build(); + gameFreeRecord.setCreateBy(Constants.SYSTEM); + gameFreeRecordService.insertGameFreeRecord(gameFreeRecord); + } + + return Boolean.TRUE; + } else { + log.error("GameBettingDataJILIServiceImpl [createFreeSpin] 赠送免费局数,错误代码{},错误信息{}", createFreeSpinResponseDTO.getErrorCode(), createFreeSpinResponseDTO.getMessage()); + throw new BaseException(createFreeSpinResponseDTO.getMessage()); + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [createFreeSpin] 赠送免费局数,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.free.round.gift.failed")); + + } + + } + + /** + * 获取游戏详细信息 + * + * @param getGameDetailRequestDTO 获取游戏详细信息请求dto + * @return {@link GetGameDetailResponseDTO } + */ + @Override + public GetGameDetailResponseDTO getGameDetail(GetGameDetailRequestDTO getGameDetailRequestDTO) { + String query = "WagersId=" + getGameDetailRequestDTO.getWagersId(); + + getGameDetailRequestDTO.setQuery(query + "&AgentId=" + getGameDetailRequestDTO.getAgentId()); + String key = this.getKey(getGameDetailRequestDTO); + if (StringUtils.hasText(getGameDetailRequestDTO.getLang())) { + query += "&Lang=" + getGameDetailRequestDTO.getLang(); + } + getGameDetailRequestDTO.setQuery(query); + log.info("GamesJILIServiceImpl [getGameDetail] 请求参数 {}", query); + + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + try { + + String result = HttpClientSslUtils.doGet(apiBaseUrl + "/GetGameDetailUrl?" + query + "&AgentId=" + getGameDetailRequestDTO.getAgentId() + "&Key=" + key); + JILIGetGameDetailResponseDTO jiliGetGameDetailResponseDTO = JsonUtil.stringToObj(result, JILIGetGameDetailResponseDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(jiliGetGameDetailResponseDTO.getErrorCode())) { + GetGameDetailResponseDTO getGameDetailResponseDTO = new GetGameDetailResponseDTO(); + getGameDetailResponseDTO.setUrl(jiliGetGameDetailResponseDTO.getData().getUrl()); + return getGameDetailResponseDTO; + } else { + log.error("GameBettingDataJILIServiceImpl [getGameDetail] 获取游戏游玩详情失败,错误代码{},错误信息{}", jiliGetGameDetailResponseDTO.getErrorCode(), jiliGetGameDetailResponseDTO.getMessage()); + throw new BaseException(MessageUtils.message("game.play.details.retrieve.failed")); + + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [getGameDetail] 获取游戏游玩详情失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.play.details.retrieve.failed")); + + } + } + + /** + * 强制会员从游戏注销 + * + * @param kickMemberRequestDTO 踢会员请求dto + * @return {@link Boolean } + */ + @Override + public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) { + String query = "Account=" + kickMemberRequestDTO.getAccount(); + + kickMemberRequestDTO.setQuery(query + "&AgentId=" + kickMemberRequestDTO.getAgentId()); + String key = this.getKey(kickMemberRequestDTO); + log.info("GamesJILIServiceImpl [kickMember] 请求参数 {}", query); + + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + try { + + String result = HttpClientSslUtils.doGet(apiBaseUrl + "/KickMember?" + query + "&AgentId=" + kickMemberRequestDTO.getAgentId() + "&Key=" + key); + JILIKickMemberDTO jiliKickMemberDTO = JsonUtil.stringToObj(result, JILIKickMemberDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(jiliKickMemberDTO.getErrorCode())) { + return Boolean.TRUE; + } else { + log.error("GameBettingDataJILIServiceImpl [kickMember] 强制会员从游戏注销失败,错误代码{},错误信息{}", jiliKickMemberDTO.getErrorCode(), jiliKickMemberDTO.getMessage()); + throw new BaseException(MessageUtils.message("game.member.force.logout.failed")); + + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [kickMember] 强制会员从游戏注销失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.member.force.logout.failed")); + + } + } + + /** + * 踢成员全部 + * + * @param kickMemberAllDTO 踢成员全部dto + * @return {@link Boolean } + */ + @Override + public Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO) { + String query = "AgentId=" + kickMemberAllDTO.getAgentId(); + if (!ObjectUtils.isEmpty(kickMemberAllDTO.getGameId())) { + query = "GameId=" + kickMemberAllDTO.getGameId() + "&" + query; + } + + + kickMemberAllDTO.setQuery(query); + String key = this.getKey(kickMemberAllDTO); + log.info("GamesJILIServiceImpl [kickMemberAll] 请求参数 {}", query); + + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + try { + + String result = HttpClientSslUtils.doGet(apiBaseUrl + "/KickMemberAll?" + query + "&Key=" + key); + JILIKickMemberAllDTO jiliKickMemberAllDTO = JsonUtil.stringToObj(result, JILIKickMemberAllDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(jiliKickMemberAllDTO.getErrorCode())) { + return Boolean.TRUE; + } else { + log.error("GameBettingDataJILIServiceImpl [kickMemberAll] 强制全部会员从游戏注销失败,错误代码{},错误信息{}", jiliKickMemberAllDTO.getErrorCode(), jiliKickMemberAllDTO.getMessage()); + throw new BaseException(MessageUtils.message("game.members.force.logout.failed")); + + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [kickMemberAll] 强制全部会员从游戏注销失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.members.force.logout.failed")); + + } + } + + /** + * 免费游戏玩家使用的纪录 + * + * @param getFreeSpinDashflowRequestDTO 获取自由旋转dashflow请求dto + * @return {@link List }<{@link GameFreeRecord }> + */ + @Override + public List getFreeSpinDashflow(GetFreeSpinDashflowRequestDTO getFreeSpinDashflowRequestDTO) { + List gameFreeRecordsResult = new ArrayList<>(); + //请求参数 + String query = "UpdateTime=" + DateUtils.formatDateToGMT4(new Date(getFreeSpinDashflowRequestDTO.getStartTime())) + + "&AgentId=" + getFreeSpinDashflowRequestDTO.getAgentId(); + + log.info("GamesJILIServiceImpl [getFreeSpinDashflow] 请求参数 {}", query); + getFreeSpinDashflowRequestDTO.setQuery(query); + //获取key + String key = this.getKey(getFreeSpinDashflowRequestDTO); + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + String result = null; + try { + result = HttpClientSslUtils.doPost(apiBaseUrl + "/GetFreeSpinDashflow?" + query + "&Key=" + key, "AgentId=" + getFreeSpinDashflowRequestDTO.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED); + + JILIGetFreeSpinDashflowResponseDTO getFreeSpinDashflowResponseDTO = JSON.parseObject(result, JILIGetFreeSpinDashflowResponseDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(getFreeSpinDashflowResponseDTO.getErrorCode())) { + for (JILIGetFreeSpinDashflowResponseDTO.DataBean data : getFreeSpinDashflowResponseDTO.getData()) { + List gameFreeRecords = gameFreeRecordService.selectGameFreeRecordList(GameFreeRecord.builder() + .referenceId(data.getReferenceID()) + .build()); + for (GameFreeRecord gameFreeRecord : gameFreeRecords) { + gameFreeRecord.setSendTime(data.getSendTime()); + gameFreeRecord.setExpiredTime(data.getExpiredTime()); + gameFreeRecord.setFreeUpdateTime(data.getUpdateTime()); + gameFreeRecord.setSendAmount(data.getSendAmount()); + gameFreeRecord.setUsedAmount(data.getUsedAmount()); + gameFreeRecord.setUnusedAmount(data.getUnusedAmount()); + gameFreeRecordService.updateGameFreeRecord(gameFreeRecord); + gameFreeRecordsResult.add(gameFreeRecord); + } + } + + return gameFreeRecordsResult; + } else { + log.error("GameBettingDataJILIServiceImpl [getFreeSpinDashflow] 查询免费游戏玩家使用的纪录,错误代码{},错误信息{}", getFreeSpinDashflowResponseDTO.getErrorCode(), getFreeSpinDashflowResponseDTO.getMessage()); + throw new BaseException(getFreeSpinDashflowResponseDTO.getMessage()); + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [getFreeSpinDashflow] 查询免费游戏玩家使用的纪录,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.free.play.record.query.failed")); + + } + } + + /** + * 取消赠送免费局数 + * + * @param cancelFreeSpinRequestDTO 取消免费旋转请求 + * @return {@link Boolean } + */ + @Override + public Boolean cancelFreeSpin(CancelFreeSpinRequestDTO cancelFreeSpinRequestDTO) { + //请求参数 + String query = "ReferenceId=" + cancelFreeSpinRequestDTO.getReferenceId() + + "&AgentId=" + cancelFreeSpinRequestDTO.getAgentId(); + ; + log.info("GamesJILIServiceImpl [cancelFreeSpin] 请求参数 {}", query); + cancelFreeSpinRequestDTO.setQuery(query); + //获取key + String key = this.getKey(cancelFreeSpinRequestDTO); + String apiBaseUrl = configService.selectConfigByKey(Constants.JILI_API_BASE_URL); + String result = null; + try { + result = HttpClientSslUtils.doPost(apiBaseUrl + "/CancelFreeSpin?" + query + "&Key=" + key, "AgentId=" + cancelFreeSpinRequestDTO.getAgentId(), ContentType.APPLICATION_FORM_URLENCODED); + + JILICancelFreeSpinResponseDTO cancelFreeSpinResponseDTO = JSON.parseObject(result, JILICancelFreeSpinResponseDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(cancelFreeSpinResponseDTO.getErrorCode())) { + List gameFreeRecords = gameFreeRecordService.selectGameFreeRecordList(GameFreeRecord.builder() + .referenceId(cancelFreeSpinRequestDTO.getReferenceId()) + .build()); + for (GameFreeRecord gameFreeRecord : gameFreeRecords) { + gameFreeRecord.setFreeStatus(FreeStatus.CANCEL.getCode()); + gameFreeRecordService.updateGameFreeRecord(gameFreeRecord); + } + return Boolean.TRUE; + } else { + log.error("GameBettingDataJILIServiceImpl [cancelFreeSpin] 取消赠送免费局数,错误代码{},错误信息{}", cancelFreeSpinResponseDTO.getErrorCode(), cancelFreeSpinResponseDTO.getMessage()); + throw new BaseException(cancelFreeSpinResponseDTO.getMessage()); + } + } catch (Exception e) { + log.error("GameBettingDataJILIServiceImpl [cancelFreeSpin] 取消赠送免费局数,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.free.round.cancel.failed")); + + } + } + + + /** + * 数据构建 + * + * @param gamesDataBuildDTO 数据 + * @return {@link GameBettingDetails } + */ + @Override + public GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO) { + + //转化类 + JILIBetRecordDataResponseDTO jiliBetRecordDataResponseDTO = (JILIBetRecordDataResponseDTO) gamesDataBuildDTO.getData(); + String systemByCode = gameSecretKeyService.findSystemByCode(jiliBetRecordDataResponseDTO.getAgentId(), GamePlatforms.JILI.getInfo()); + Member member = memberService.selectMemberByMemberAccount(jiliBetRecordDataResponseDTO.getAccount()); + if (ObjectUtils.isEmpty(member)) { + return null; + } + List gamesDatas = redisCache.getCacheList(CacheConstants.JILI_GAMES); + Map dataDTOMap = gamesDatas.stream().collect(Collectors.toMap(JILIGamesDataDTO::getGameId, e -> e)); + JILIGamesDataDTO gamesDataDTO = dataDTOMap.get(jiliBetRecordDataResponseDTO.getGameId()); + BigDecimal payoffAmount = BigDecimal.ZERO; + if (GameStatus.WIN.getCode().equals(jiliBetRecordDataResponseDTO.getStatus())) { + payoffAmount = NumberUtil.sub(jiliBetRecordDataResponseDTO.getPayoffAmount(), jiliBetRecordDataResponseDTO.getTurnover()); + } else if (GameStatus.FAIL.getCode().equals(jiliBetRecordDataResponseDTO.getStatus())) { + payoffAmount = NumberUtil.sub(jiliBetRecordDataResponseDTO.getPayoffAmount(), jiliBetRecordDataResponseDTO.getTurnover()).negate(); + } + + //数据构造 + GameBettingDetails gameBettingDetails = GameBettingDetails.builder() + //保存我们的币种id + .currencyCode(systemByCode) + .memberId(member.getId()) + .gameCode(jiliBetRecordDataResponseDTO.getGameId()) + .gameType(JILIGameType.findSystemByCode(jiliBetRecordDataResponseDTO.getGameCategoryId())) + .platformCode(GamePlatforms.JILI.getCode()) + .gameId(gamesDataDTO.getSystemGameId()) + .gameName(gamesDataDTO.getName().getZhCN()) + .gameStatus(jiliBetRecordDataResponseDTO.getStatus()) + .gameStatusType(jiliBetRecordDataResponseDTO.getType()) + .gameCurrencyCode(jiliBetRecordDataResponseDTO.getAgentId()) + .account(String.valueOf(jiliBetRecordDataResponseDTO.getAccount())) + .wagersId(jiliBetRecordDataResponseDTO.getWagersId()) + .wagersTime(jiliBetRecordDataResponseDTO.getWagersTime()) + .betAmount(jiliBetRecordDataResponseDTO.getBetAmount().abs()) + .payoffTime(jiliBetRecordDataResponseDTO.getPayoffTime()) + .payoffAmount(payoffAmount) + .settlementTime(jiliBetRecordDataResponseDTO.getSettlementTime()) + .turnover(jiliBetRecordDataResponseDTO.getTurnover()) + .orderNo(String.valueOf(jiliBetRecordDataResponseDTO.getRoundIndex())) + .build(); + gameBettingDetails.setCreateBy(Constants.SYSTEM); + gameBettingDetails.setCreateTime(DateUtils.getNowDate()); + return gameBettingDetails; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/BetRecordByTimeDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/BetRecordByTimeDTO.java new file mode 100644 index 0000000..c2cc3f6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/BetRecordByTimeDTO.java @@ -0,0 +1,40 @@ +package com.ff.game.api.request; + +import lombok.Data; + +/** + * 按时间dto投注记录 + * + * @author shi + * @date 2024/10/22 + */ +@Data +public class BetRecordByTimeDTO extends GamesBaseRequestDTO { + /** + * 开始时间 + */ + private Long startTime; + /** + * 结束时间 + */ + private Long endTime; + /** + * 页数 + */ + private Integer page; + /** + * 每页资料笔数 + */ + private Integer pageLimit; + /** + * 游戏id + */ + private Integer gameId; + /** + * 指定平台 + */ + private String gamePlatform; + + + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/CancelFreeSpinRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/CancelFreeSpinRequestDTO.java new file mode 100644 index 0000000..f7297ae --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/CancelFreeSpinRequestDTO.java @@ -0,0 +1,17 @@ +package com.ff.game.api.request; + +import lombok.Data; + +/** + * 取消免费旋转请求 + * + * @author shi + * @date 2024/11/11 + */ +@Data +public class CancelFreeSpinRequestDTO extends GamesBaseRequestDTO { + /** + * 取消免费赠送游戏id + */ + private String referenceId; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/CreateFreeSpinRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/CreateFreeSpinRequestDTO.java new file mode 100644 index 0000000..795e7de --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/CreateFreeSpinRequestDTO.java @@ -0,0 +1,62 @@ +package com.ff.game.api.request; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 创建自由旋转请求dto + * + * @author shi + * @date 2024/11/11 + */ +@Data +public class CreateFreeSpinRequestDTO extends GamesBaseRequestDTO { + + /** + * 玩家账号 (JILI 新玩家则会自动创立账号) + */ + private String account; + + /** + * 玩家使用货币。转账钱包这项请填空字符串。 + */ + private String currency; + + /** + * 免费局数序号, 长度上限 50 + */ + private String referenceId; + + /** + * 有效期限 + * + * + */ + private Long freeSpinValidity; + + /** + * 局数 + */ + private Integer numberOfRounds; + + /** + * 可使用游戏 ID, 超过一笔时以逗号分隔; 系统内游戏id + * 长度 上限 200 + */ + private List gameIds; + + /** + * 指定投注额; + * 未指定时, 一律使用游戏中的最小投注额 + */ + private BigDecimal betValue; + + /** + * 免费游戏局数可使用的开始时间 + * 未带此参数时, 赠送后玩家可以立即使用 + */ + private Long startTime; + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/CreateMemberRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/CreateMemberRequestDTO.java new file mode 100644 index 0000000..46ec0ab --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/CreateMemberRequestDTO.java @@ -0,0 +1,26 @@ +package com.ff.game.api.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * 创建成员请求dto + * + * @author shi + * @date 2024/10/22 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@SuperBuilder +public class CreateMemberRequestDTO extends GamesBaseRequestDTO { + /** + * 账户 + */ + private String account; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/ExchangeTransferMoneyRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/ExchangeTransferMoneyRequestDTO.java new file mode 100644 index 0000000..a1a29ab --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/ExchangeTransferMoneyRequestDTO.java @@ -0,0 +1,52 @@ +package com.ff.game.api.request; + +import com.ff.base.annotation.Excel; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 外汇转账 + * + * @author shi + * @date 2024/10/22 + */ +@Data +public class ExchangeTransferMoneyRequestDTO extends GamesBaseRequestDTO { + + + /** + * 账户 + */ + private String account; + + + /** 游戏平台id */ + @Excel(name = "游戏平台id") + private Long platformId; + /** + * 金额 + */ + private BigDecimal amount; + + + /** + * 租户额度 + */ + private BigDecimal quota; + + + /** + * 转账类型 + * 1: 从 游戏商 转移额度到 平台商 (不看 amount 值,全 + * 部转出) + * 2: 从 平台商 转移额度到 游戏商 + * 3: 从 游戏商 转移额度到 平台商 + */ + private Integer transferType; + + /** + * 交易id + */ + private String transactionId; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GameUniqueDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/GameUniqueDTO.java new file mode 100644 index 0000000..dc1de1d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GameUniqueDTO.java @@ -0,0 +1,19 @@ +package com.ff.game.api.request; + + +import com.ff.game.domain.Game; +import lombok.Data; + +import java.util.List; + +/** + * 游戏独有dto + * + * @author shi + * @date 2024/11/11 + */ +@Data +public class GameUniqueDTO extends Game { + + private List gameIds; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GamesBaseRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/GamesBaseRequestDTO.java new file mode 100644 index 0000000..e5025ff --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GamesBaseRequestDTO.java @@ -0,0 +1,37 @@ +package com.ff.game.api.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.io.Serializable; + +/** + * 游戏请求dto + * + * @author shi + * @date 2024/10/22 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@SuperBuilder +public class GamesBaseRequestDTO implements Serializable { + private static final long serialVersionUID = 5139311242800113436L; + /** + * 代理id + */ + private String agentId; + + /** + * 代理密钥 + */ + private String agentKey; + + /** + * 查询 + */ + private String query; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GamesDataBuildDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/GamesDataBuildDTO.java new file mode 100644 index 0000000..17efcd6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GamesDataBuildDTO.java @@ -0,0 +1,31 @@ +package com.ff.game.api.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 游戏数据构建dto + * + * @author shi + * @date 2024/10/22 + */ +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Data +public class GamesDataBuildDTO +{ + + /** + * 数据 + */ + private Object data; + + /** + * 游戏列表key + */ + private String gamesKey; + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GamesLogin.java b/ff-admin/src/main/java/com/ff/game/api/request/GamesLogin.java new file mode 100644 index 0000000..061450d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GamesLogin.java @@ -0,0 +1,44 @@ +package com.ff.game.api.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * 游戏登录 + * + * @author shi + * @date 2024/10/22 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@SuperBuilder +public class GamesLogin extends GamesBaseRequestDTO{ + /** + * 账户 + */ + private String account; + /** + * 游戏唯一识别值(同等 GameList 各游戏的 GameId) + */ + private Integer gameId; + /** + * UI 语系, 请参考 附录 – 语系参数 + */ + private String lang; + /** + * 不列入 md5 加密,游戏回主页功能导向位置 + */ + private String homeUrl; + /** + * 不列入 md5 加密,带入 web 或是 app + */ + private String platform; + /** + * 不列入 md5 加密, 带入 1 即关闭全屏幕模式 + */ + private Integer disableFullScreen; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GetFreeSpinDashflowRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/GetFreeSpinDashflowRequestDTO.java new file mode 100644 index 0000000..d0418ac --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GetFreeSpinDashflowRequestDTO.java @@ -0,0 +1,19 @@ +package com.ff.game.api.request; + +import lombok.Data; + +/** + * 获取自由旋转dashflow请求dto + * + * @author shi + * @date 2024/11/11 + */ +@Data +public class GetFreeSpinDashflowRequestDTO extends GamesBaseRequestDTO { + + /** + * 开始时间 + */ + private Long startTime; + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailRequestDTO.java new file mode 100644 index 0000000..7c082c3 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailRequestDTO.java @@ -0,0 +1,22 @@ +package com.ff.game.api.request; + +import lombok.Data; + +/** + * 获取游戏详细信息请求dto + * + * @author shi + * @date 2024/11/12 + */ +@Data +public class GetGameDetailRequestDTO extends GamesBaseRequestDTO { + + /** + * 投注id + */ + private Long wagersId; + /** + * 郎 + */ + private String lang; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailResponseDTO.java new file mode 100644 index 0000000..373d4ed --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/GetGameDetailResponseDTO.java @@ -0,0 +1,21 @@ +package com.ff.game.api.request; + +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 获取游戏详细信息请求dto + * + * @author shi + * @date 2024/11/12 + */ +@NoArgsConstructor +@Data +public class GetGameDetailResponseDTO { + + + /** + * url + */ + private String url; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/KickMemberAllDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/KickMemberAllDTO.java new file mode 100644 index 0000000..1d4fd8c --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/KickMemberAllDTO.java @@ -0,0 +1,15 @@ +package com.ff.game.api.request; + +import lombok.Data; + +/** + * 踢成员全部dto + * + * @author shi + * @date 2024/11/12 + */ +@Data +public class KickMemberAllDTO extends GamesBaseRequestDTO { + private Long gameId; + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/KickMemberRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/KickMemberRequestDTO.java new file mode 100644 index 0000000..dbf144b --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/KickMemberRequestDTO.java @@ -0,0 +1,18 @@ +package com.ff.game.api.request; + +import lombok.Data; + +/** + * 踢会员请求dto + * + * @author shi + * @date 2024/11/12 + */ +@Data +public class KickMemberRequestDTO extends GamesBaseRequestDTO { + + /** + * 账户 + */ + private String account; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/MemberInfoRequestDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/MemberInfoRequestDTO.java new file mode 100644 index 0000000..40a3182 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/MemberInfoRequestDTO.java @@ -0,0 +1,25 @@ +package com.ff.game.api.request; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * 创建成员请求dto + * + * @author shi + * @date 2024/10/22 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@SuperBuilder +public class MemberInfoRequestDTO extends GamesBaseRequestDTO { + /** + * 账户 + */ + private String accounts; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/api/request/MemberInfoResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/request/MemberInfoResponseDTO.java new file mode 100644 index 0000000..4d5ec47 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/request/MemberInfoResponseDTO.java @@ -0,0 +1,39 @@ +package com.ff.game.api.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + + +/** + * 成员信息响应dto + * + * @author shi + * @date 2024/10/30 + */ +@NoArgsConstructor +@Data +@AllArgsConstructor +@Builder +public class MemberInfoResponseDTO { + + + /** + * 账户 + */ + private String account; + /** + * 余额 + */ + private BigDecimal balance; + /** + * 状态: + * 1: 在线 + * 2: 脱机 + * 3: 账号不存在 + */ + private Integer status; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKBetRecordResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKBetRecordResponseDTO.java new file mode 100644 index 0000000..f605858 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKBetRecordResponseDTO.java @@ -0,0 +1,54 @@ +package com.ff.game.api.xk.dto; + +import io.jsonwebtoken.lang.Collections; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +@NoArgsConstructor +@Data +public class XKBetRecordResponseDTO { + + private Integer code; + private String msg; + private DataBean data; + + @NoArgsConstructor + @Data + public static class DataBean { + private Integer currentPage; + private Integer totalPages; + private Integer pageLimit; + private Integer totalNumber; + private List result; + + public List getResult() { + if (Collections.isEmpty(result)) { + return new ArrayList<>(); + } + return result; + } + + @NoArgsConstructor + @Data + public static class ResultBean { + private String account; + private Long wagersId; + private Integer gameId; + private Long wagersTime; + private BigDecimal betAmount; + private Long payoffTime; + private BigDecimal payoffAmount; + private Integer status; + private Long settlementTime; + private Integer gameCategoryId; + private Integer type; + private String agentId; + private BigDecimal turnover; + private Long roundIndex; + } + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKCreateMemberResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKCreateMemberResponseDTO.java new file mode 100644 index 0000000..f573bd2 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKCreateMemberResponseDTO.java @@ -0,0 +1,32 @@ +package com.ff.game.api.xk.dto; + + +import com.ff.game.api.request.GamesBaseRequestDTO; +import lombok.Data; +import lombok.NoArgsConstructor; + + +/** + * 创建成员响应dto + * + * @author shi + * @date 2024/10/22 + */ +@NoArgsConstructor +@Data +public class XKCreateMemberResponseDTO extends GamesBaseRequestDTO { + + + /** + * 代码 + */ + private int code; + /** + * 数据 + */ + private String data; + /** + * msg + */ + private String msg; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKExchangeMoneyResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKExchangeMoneyResponseDTO.java new file mode 100644 index 0000000..47601d3 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKExchangeMoneyResponseDTO.java @@ -0,0 +1,46 @@ +package com.ff.game.api.xk.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +@NoArgsConstructor +@Data +public class XKExchangeMoneyResponseDTO { + + private int code; + private String msg; + private DataBean data; + + @NoArgsConstructor + @Data + public static class DataBean { + /** + * 交易序号,额度转移纪录唯一值, 长度上限 50 + */ + private String transactionId; + /** + * 转账前金额(游戏币) + */ + private BigDecimal coinBefore; + /** + * 转账后金额(游戏币) + */ + private BigDecimal coinAfter; + /** + * 转账前金额(指定货币) + */ + private BigDecimal currencyBefore; + /** + * 转账后金额(指定货币) + */ + private BigDecimal currencyAfter; + /** + * 状态: + * 1: 成功 + * 2: 失败 + */ + private Integer status; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKGamesDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKGamesDTO.java new file mode 100644 index 0000000..3cf5c87 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKGamesDTO.java @@ -0,0 +1,56 @@ +package com.ff.game.api.xk.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * xkgames数据 + * + * @author shi + * @date 2024/11/13 + */ +@NoArgsConstructor +@Data +public class XKGamesDTO { + + private int code; + /** + * msg + */ + private String msg; + /** + * 数据 + */ + private List data; + + @NoArgsConstructor + @Data + public static class DataBean { + /** + * 游戏id + */ + private int gameId; + /** + * 名称 + */ + private String name; + /** + * 游戏类别id + */ + private int gameCategoryId; + /** + *自己系统游戏id + */ + private Long systemGameId; + /** + * jp + */ + private boolean jp; + /** + * 是否免费 + */ + private boolean freeSpin; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberAllDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberAllDTO.java new file mode 100644 index 0000000..227532b --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberAllDTO.java @@ -0,0 +1,27 @@ +package com.ff.game.api.xk.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * xkkick会员全部dto + * + * @author shi + * @date 2024/11/13 + */ +@Data +@NoArgsConstructor +public class XKKickMemberAllDTO { + /** + * 代码 + */ + private int code; + /** + * 数据 + */ + private String data; + /** + * msg + */ + private String msg; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberDTO.java new file mode 100644 index 0000000..24b7f2f --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKKickMemberDTO.java @@ -0,0 +1,13 @@ +package com.ff.game.api.xk.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Data +public class XKKickMemberDTO { + + private int code; + private String msg; + private Object data; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKLoginWithoutRedirectResponseDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKLoginWithoutRedirectResponseDTO.java new file mode 100644 index 0000000..c2254b5 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKLoginWithoutRedirectResponseDTO.java @@ -0,0 +1,29 @@ +package com.ff.game.api.xk.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 登录时不重定向响应dto + * + * @author shi + * @date 2024/10/22 + */ +@NoArgsConstructor +@Data +public class XKLoginWithoutRedirectResponseDTO { + + + /** + * 代码 + */ + private int code; + /** + * 数据 + */ + private String data; + /** + * msg + */ + private String msg; +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKMemberInfoDTO.java b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKMemberInfoDTO.java new file mode 100644 index 0000000..0199d0f --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/dto/XKMemberInfoDTO.java @@ -0,0 +1,49 @@ +package com.ff.game.api.xk.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 会员信息dto + * + * @author shi + * @date 2024/10/30 + */ +@NoArgsConstructor +@Data +public class XKMemberInfoDTO { + + + /** + * 代码 + */ + private Integer code; + /** + * msg + */ + private String msg; + /** + * 数据 + */ + private List data; + + @NoArgsConstructor + @Data + public static class DataBean { + /** + * 账户 + */ + private String account; + /** + * 平衡 + */ + private BigDecimal balance; + /** + * 地位 + */ + private Integer status; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/api/xk/service/impl/GamesXKServiceImpl.java b/ff-admin/src/main/java/com/ff/game/api/xk/service/impl/GamesXKServiceImpl.java new file mode 100644 index 0000000..d0b3a6a --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/api/xk/service/impl/GamesXKServiceImpl.java @@ -0,0 +1,618 @@ +package com.ff.game.api.xk.service.impl; + +import cn.hutool.core.util.NumberUtil; +import com.alibaba.fastjson2.JSON; +import com.ff.base.constant.CacheConstants; +import com.ff.base.constant.Constants; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.enums.GamePlatforms; +import com.ff.base.enums.GameStatus; +import com.ff.base.enums.XKGameType; +import com.ff.base.exception.base.BaseException; +import com.ff.base.system.service.ISysConfigService; +import com.ff.base.utils.DateUtils; +import com.ff.base.utils.JsonUtil; +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.http.HttpClientSslUtils; +import com.ff.base.utils.sign.Md5Utils; +import com.ff.base.utils.uuid.IdUtils; +import com.ff.game.api.IGamesService; +import com.ff.game.api.request.*; +import com.ff.game.api.xk.dto.*; +import com.ff.game.domain.*; +import com.ff.game.service.*; +import com.ff.member.domain.Member; +import com.ff.member.service.IMemberService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + + +/** + * XK 游戏 impl + * + * @author shi + * @date 2024/11/12 + */ +@Service("XKService") +@Slf4j +public class GamesXKServiceImpl implements IGamesService { + + + @Resource + private ISysConfigService configService; + + @Resource + private RedisCache redisCache; + + @Resource + private IGameExchangeMoneyService gameExchangeMoneyService; + + + @Resource + private IGamePlatformService gamePlatformService; + + + @Resource + private IGameService gameService; + + + + + @Resource + private IMemberService memberService; + + @Resource + private IGameFreeRecordService gameFreeRecordService; + @Resource + private IGameSecretKeyService gameSecretKeyService; + /** + * 获得就是成功 + * + * @param errorCode 错误代码 + * @return {@link Boolean } + */ + private Boolean getIsSuccess(Integer errorCode) { + return 0 == errorCode; + } + + + /** + * 获取密钥 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + @Override + public String getKey(GamesBaseRequestDTO gamesBaseRequestDTO) { + Random random = new Random(); + //取出对应的key跟密钥跟请求参数 + String agentKey = gamesBaseRequestDTO.getAgentKey(); + String agentId = gamesBaseRequestDTO.getAgentId(); + String query = gamesBaseRequestDTO.getQuery(); + + String now = DateUtils.getFormattedDate(); + String keyG = Md5Utils.md5New(now + agentId + agentKey); + + String md5string = Md5Utils.md5New(query + keyG); + Integer randomText1 = 100000 + random.nextInt(900000); + Integer randomText2 = 100000 + random.nextInt(900000); + String key = randomText1 + md5string + randomText2; + return key; + } + + /** + * 创建成员 + * + * @param createMemberRequestDTO 创建成员请求dto + * @return {@link Boolean } + */ + @Override + public Boolean createMember(CreateMemberRequestDTO createMemberRequestDTO) { + log.info("GamesXKServiceImpl [createMember] 请求参数 {}", createMemberRequestDTO); + + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + Map params = new LinkedHashMap<>(); + params.put("account", createMemberRequestDTO.getAccount()); + params.put("agentId", createMemberRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + createMemberRequestDTO.setQuery(query); + String key = this.getKey(createMemberRequestDTO); + params.put("key", key); + try { + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/createMember", JsonUtil.objToPrettyString(params)); + XKCreateMemberResponseDTO xkCreateMemberResponseDTO = JsonUtil.stringToObj(result, XKCreateMemberResponseDTO.class); + //判断是否获取成功 + return !this.getIsSuccess(xkCreateMemberResponseDTO.getCode()); + + } catch (Exception e) { + log.error("GamesXKServiceImpl [createMember] 建立游戏账号,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.account.create.failed")); + } + } + + + /** + * 获取会员信息 + * + * @param memberInfoRequestDTO 会员信息请求dto + * @return {@link MemberInfoResponseDTO } + */ + @Override + public MemberInfoResponseDTO getMemberInfo(MemberInfoRequestDTO memberInfoRequestDTO) { + log.info("GamesXKServiceImpl [getMemberInfo] 请求参数 {}", memberInfoRequestDTO); + Map params = new LinkedHashMap<>(); + params.put("accounts", memberInfoRequestDTO.getAccounts()); + params.put("agentId", memberInfoRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + memberInfoRequestDTO.setQuery(query); + String key = this.getKey(memberInfoRequestDTO); + params.put("key", key); + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + try { + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/getMemberInfo", JsonUtil.objToPrettyString(params)); + XKMemberInfoDTO xkMemberInfoDTO = JsonUtil.stringToObj(result, XKMemberInfoDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(xkMemberInfoDTO.getCode())) { + List memberInfoResponseDTOS = new ArrayList<>(); + xkMemberInfoDTO.getData().forEach(e -> { + memberInfoResponseDTOS.add(MemberInfoResponseDTO.builder() + .status(e.getStatus()) + .balance(e.getBalance()) + .account(e.getAccount()) + .build()); + }); + return memberInfoResponseDTOS.get(0); + } else { + log.error("GamesXKServiceImpl [getMemberInfo] 查询游戏账号信息失败,错误代码{},错误信息{}", xkMemberInfoDTO.getCode(), xkMemberInfoDTO.getMsg()); + throw new BaseException(MessageUtils.message("game.account.query.failed")); + } + + } catch (Exception e) { + log.error("GamesXKServiceImpl [getMemberInfo] 查询游戏账号信息失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.account.query.failed")); + } + + } + + /** + * 无重定向登录 + * + * @param gamesLogin 游戏登录 + * @return {@link String } + */ + @Override + public String loginWithoutRedirect(GamesLogin gamesLogin) { + log.info("GamesXKServiceImpl [loginWithoutRedirect] 请求参数 {}", gamesLogin); + + Map params = new LinkedHashMap<>(); + params.put("account", gamesLogin.getAccount()); + params.put("gameId", gamesLogin.getGameId()); + params.put("lang", gamesLogin.getLang()); + params.put("agentId", gamesLogin.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + gamesLogin.setQuery(query); + String key = this.getKey(gamesLogin); + params.put("key", key); + params.put("disableFullScreen", gamesLogin.getDisableFullScreen()); + params.put("homeUrl", gamesLogin.getHomeUrl()); + params.put("platform", gamesLogin.getPlatform()); + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + try { + + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/loginWithoutRedirect", JsonUtil.objToPrettyString(params)); + XKLoginWithoutRedirectResponseDTO xkLoginWithoutRedirectResponseDTO = JsonUtil.stringToObj(result, XKLoginWithoutRedirectResponseDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(xkLoginWithoutRedirectResponseDTO.getCode())) { + return xkLoginWithoutRedirectResponseDTO.getData(); + } else { + log.error("GamesXKServiceImpl [loginWithoutRedirect] 游戏登录失败,错误代码{},错误信息{}", xkLoginWithoutRedirectResponseDTO.getCode(), xkLoginWithoutRedirectResponseDTO.getMsg()); + throw new BaseException(MessageUtils.message("game.login.failed")); + } + } catch (Exception e) { + log.error("GamesXKServiceImpl [loginWithoutRedirect] 游戏登录失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.login.failed")); + } + } + + + /** + * 获取游戏列表 + * + * @param gamesBaseRequestDTO 游戏请求dto + * @return {@link String } + */ + @Transactional + @Override + public String getGameList(GamesBaseRequestDTO gamesBaseRequestDTO) { + List gamesDatas = redisCache.getCacheList(CacheConstants.XK_GAMES); + if (!CollectionUtils.isEmpty(gamesDatas)) { + return CacheConstants.XK_GAMES; + } + + Map params = new LinkedHashMap<>(); + params.put("agentId", gamesBaseRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + gamesBaseRequestDTO.setQuery(query); + String key = this.getKey(gamesBaseRequestDTO); + params.put("key", key); + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + try { + + + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/getGameList", JsonUtil.objToPrettyString(params)); + XKGamesDTO xkGamesDTO = JsonUtil.stringToObj(result, XKGamesDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(xkGamesDTO.getCode())) { + + Map gamePlatformMap = new HashMap<>(); + + for (XKGamesDTO.DataBean gamesDataDTO : xkGamesDTO.getData()) { + if (XKGameType.GAME_HALL.getCode().equals(gamesDataDTO.getGameCategoryId())) { + continue; + } + + GamePlatform gamePlatform = GamePlatform.builder() + .platformType(XKGameType.findSystemByCode(gamesDataDTO.getGameCategoryId())) + .platformCode(GamePlatforms.XK.getCode()) + .build(); + List gamePlatforms = gamePlatformService.selectGamePlatformList(gamePlatform); + //没有此平台就新增一个平台 + if (CollectionUtils.isEmpty(gamePlatforms)) { + gamePlatform.setPlatformName(GamePlatforms.XK.getInfo() + XKGameType.findInfoByCode(gamesDataDTO.getGameCategoryId())); + gamePlatform.setSortNo(gamePlatformService.selectMaxSortNo() + 1); + gamePlatform.setCreateBy(Constants.SYSTEM); + gamePlatformService.insertGamePlatform(gamePlatform); + } else { + gamePlatform = gamePlatforms.get(0); + } + Game game = Game.builder() + .platformId(gamePlatform.getId()) + .gameCode(gamesDataDTO.getGameId()) + .build(); + List games = gameService.selectGameList(game); + //不存在这个游戏 + if (CollectionUtils.isEmpty(games)) { + game.setFreespin(gamesDataDTO.isFreeSpin()); + game.setSortNo(gameService.selectMaxSortNoByPlatformId(gamePlatform.getId()) + 1); + game.setGameName(gamesDataDTO.getName()); + game.setCreateBy(Constants.SYSTEM); + gameService.insertGame(game); + } else { + game = games.get(0); + } + gamesDataDTO.setSystemGameId(game.getId()); + + + } + + + + redisCache.deleteObject(CacheConstants.XK_GAMES); + redisCache.setCacheList(CacheConstants.XK_GAMES, xkGamesDTO.getData()); + redisCache.expire(CacheConstants.XK_GAMES, 5L, TimeUnit.HOURS); + } else { + log.error("GamesXKServiceImpl [getGameList] 获取游戏列表失败,错误代码{},错误信息{}", xkGamesDTO.getCode(), xkGamesDTO.getMsg()); + throw new BaseException(MessageUtils.message("game.list.retrieve.failed")); + } + } catch (Exception e) { + log.error("GamesXKServiceImpl [getGameList] 获取游戏列表失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.list.retrieve.failed")); + } + return CacheConstants.JILI_GAMES; + } + + /** + * 按代理id进行交换转账 + * + * @param exchangeTransferMoneyRequestDTO 外汇转账moeny dto + * @return {@link Long } + */ + @Override + @Transactional + public Long exchangeTransferByAgentId(ExchangeTransferMoneyRequestDTO exchangeTransferMoneyRequestDTO) { + log.info("GamesXKServiceImpl [exchangeTransferByAgentId] 请求参数 {}", exchangeTransferMoneyRequestDTO); + String systemByCode = gameSecretKeyService.findSystemByCode(exchangeTransferMoneyRequestDTO.getAgentId(),GamePlatforms.XK.getInfo()); + Member member = memberService.selectMemberByMemberAccount(exchangeTransferMoneyRequestDTO.getAccount()); + //获取下一个自增id + GameExchangeMoney exchangeMoney = GameExchangeMoney + .builder() + .quota(exchangeTransferMoneyRequestDTO.getQuota()) + .platformId(exchangeTransferMoneyRequestDTO.getPlatformId()) + .balance(exchangeTransferMoneyRequestDTO.getAmount()) + .exchangeType(exchangeTransferMoneyRequestDTO.getTransferType()) + .currencyCode(systemByCode) + .memberId(member.getId()) + .platformCode(GamePlatforms.XK.getCode()) + .build(); + exchangeMoney.setCreateBy(Constants.SYSTEM); + //接口限制限制50字符 + exchangeMoney.setTransactionId(GamePlatforms.XK.getCode() + IdUtils.simpleUUID()); + Map params = new LinkedHashMap<>(); + params.put("account", exchangeTransferMoneyRequestDTO.getAccount()); + params.put("transactionId", exchangeMoney.getTransactionId()); + params.put("amount", exchangeTransferMoneyRequestDTO.getAmount().stripTrailingZeros().toString()); + params.put("transferType", exchangeTransferMoneyRequestDTO.getTransferType()); + params.put("agentId", exchangeTransferMoneyRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + exchangeTransferMoneyRequestDTO.setQuery(query); + String key = this.getKey(exchangeTransferMoneyRequestDTO); + params.put("key", key); + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + try { + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/exchangeTransferByAgentId", JsonUtil.objToPrettyString(params)); + + XKExchangeMoneyResponseDTO exchangeMoneyResponse = JsonUtil.stringToObj(result, XKExchangeMoneyResponseDTO.class); + //判断是否转移成功 + if (this.getIsSuccess(exchangeMoneyResponse.getCode())) { + XKExchangeMoneyResponseDTO.DataBean exchangeMoneyResponseData = exchangeMoneyResponse.getData(); + //更新数据 + exchangeMoney.setBalance(NumberUtil.sub(exchangeMoneyResponseData.getCurrencyAfter(), exchangeMoneyResponseData.getCurrencyBefore()).abs()); + exchangeMoney.setCoinBefore(exchangeMoneyResponseData.getCoinBefore()); + exchangeMoney.setCoinAfter(exchangeMoneyResponseData.getCoinAfter()); + exchangeMoney.setCurrencyBefore(exchangeMoneyResponseData.getCurrencyBefore()); + exchangeMoney.setCurrencyAfter(exchangeMoneyResponseData.getCurrencyAfter()); + exchangeMoney.setStatus(exchangeMoneyResponseData.getStatus()); + gameExchangeMoneyService.insertGameExchangeMoney(exchangeMoney); + } else { + log.error("GamesXKServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误代码{},错误信息{}", exchangeMoneyResponse.getCode(), exchangeMoneyResponse.getMsg()); + throw new BaseException(MessageUtils.message("game.account.balance.transfer.failed")); + } + } catch (Exception e) { + log.error("GamesXKServiceImpl [exchangeTransferByAgentId] 金额转移失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.account.balance.transfer.failed")); + } + + return exchangeMoney.getId(); + } + + + /** + * 按时间获取投注记录 + * + * @param betRecordByTimeDTO 按时间dto投注记录 + * @return {@link List }<{@link GameBettingDetails }> + */ + @Override + public List getBetRecordByTime(BetRecordByTimeDTO betRecordByTimeDTO) { + List gameBettingDetails = new ArrayList<>(); + //请求参数 + log.info("GamesXKServiceImpl [getBetRecordByTime] 请求参数 {}", betRecordByTimeDTO); + Map params = new LinkedHashMap<>(); + params.put("startTime", betRecordByTimeDTO.getStartTime()); + params.put("endTime", betRecordByTimeDTO.getEndTime()); + params.put("page", betRecordByTimeDTO.getPage()); + params.put("pageLimit", betRecordByTimeDTO.getPageLimit()); + params.put("agentId", betRecordByTimeDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + betRecordByTimeDTO.setQuery(query); + String key = this.getKey(betRecordByTimeDTO); + params.put("key", key); + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + String result = null; + try { + result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/getGameRecordByTime", JsonUtil.objToPrettyString(params)); + + XKBetRecordResponseDTO betRecordJILIResponse = JSON.parseObject(result, XKBetRecordResponseDTO.class); + + //判断是否获取成功 + if (this.getIsSuccess(betRecordJILIResponse.getCode())) { + //数据组装 + XKBetRecordResponseDTO.DataBean dataBean = betRecordJILIResponse.getData(); + for (XKBetRecordResponseDTO.DataBean.ResultBean bean : dataBean.getResult()) { + GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(bean).gamesKey(key).build()); + gameBettingDetails.add(bettingDetails); + } + + //获取下一页数据 + while (!Objects.equals(dataBean.getCurrentPage(), dataBean.getTotalPages())&&dataBean.getTotalPages()>0) { + betRecordByTimeDTO.setPage(dataBean.getCurrentPage() + 1); + //请求参数 + params = new LinkedHashMap<>(); + params.put("startTime", betRecordByTimeDTO.getStartTime()); + params.put("endTime", betRecordByTimeDTO.getEndTime()); + params.put("page", betRecordByTimeDTO.getPage()); + params.put("pageLimit", betRecordByTimeDTO.getPageLimit()); + params.put("agentId", betRecordByTimeDTO.getAgentId()); + query = JsonUtil.mapToQueryString(params); + betRecordByTimeDTO.setQuery(query); + key = this.getKey(betRecordByTimeDTO); + params.put("key", key); + result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/getGameRecordByTime", JsonUtil.objToPrettyString(params)); + betRecordJILIResponse = JsonUtil.stringToObj(result, XKBetRecordResponseDTO.class); + dataBean = betRecordJILIResponse.getData(); + for (XKBetRecordResponseDTO.DataBean.ResultBean bean : dataBean.getResult()) { + GameBettingDetails bettingDetails = this.dataBuild(GamesDataBuildDTO.builder().data(bean).gamesKey(key).build()); + gameBettingDetails.add(bettingDetails); + } + } + + + return gameBettingDetails; + } else { + log.error("GamesXKServiceImpl [getBetRecordByTime] 获取投注记录失败,错误代码{},错误信息{}", betRecordJILIResponse.getCode(), betRecordJILIResponse.getMsg()); + throw new BaseException(MessageUtils.message("game.bet.record.retrieve.failed")); + } + } catch (Exception e) { + log.error("GamesXKServiceImpl [getBetRecordByTime] 获取投注记录失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.bet.record.retrieve.failed")); + } + + } + + /** + * 赠送免费局数 + * + * @param createFreeSpinRequest 创建自由旋转请求 + * @return {@link Boolean } + */ + @Override + public Boolean createFreeSpin(CreateFreeSpinRequestDTO createFreeSpinRequest) { + return Boolean.FALSE; + } + + /** + * 获取游戏详细信息 + * + * @param getGameDetailRequestDTO 获取游戏详细信息请求dto + * @return {@link GetGameDetailResponseDTO } + */ + @Override + public GetGameDetailResponseDTO getGameDetail(GetGameDetailRequestDTO getGameDetailRequestDTO) { + return new GetGameDetailResponseDTO(); + } + + /** + * 强制会员从游戏注销 + * + * @param kickMemberRequestDTO 踢会员请求dto + * @return {@link Boolean } + */ + @Override + public Boolean kickMember(KickMemberRequestDTO kickMemberRequestDTO) { + log.info("GamesXKServiceImpl [kickMember] 请求参数 {}", kickMemberRequestDTO); + Map params = new LinkedHashMap<>(); + params.put("account", kickMemberRequestDTO.getAccount()); + params.put("agentId", kickMemberRequestDTO.getAgentId()); + String query = JsonUtil.mapToQueryString(params); + kickMemberRequestDTO.setQuery(query); + String key = this.getKey(kickMemberRequestDTO); + params.put("key", key); + + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + try { + + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/kickMember", JsonUtil.objToPrettyString(params)); + XKKickMemberDTO xkKickMemberDTO = JsonUtil.stringToObj(result, XKKickMemberDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(xkKickMemberDTO.getCode())) { + return Boolean.TRUE; + } else { + log.error("GamesXKServiceImpl [kickMember] 强制会员从游戏注销失败,错误代码{},错误信息{}", xkKickMemberDTO.getCode(), xkKickMemberDTO.getMsg()); + throw new BaseException(MessageUtils.message("game.member.force.logout.failed")); + } + } catch (Exception e) { + log.error("GamesXKServiceImpl [kickMember] 强制会员从游戏注销失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.member.force.logout.failed")); + } + } + + /** + * 踢成员全部 + * + * @param kickMemberAllDTO 踢成员全部dto + * @return {@link Boolean } + */ + @Override + public Boolean kickMemberAll(KickMemberAllDTO kickMemberAllDTO) { + log.info("GamesXKServiceImpl [kickMemberAll] 请求参数 {}", kickMemberAllDTO); + Map params = new LinkedHashMap<>(); + params.put("agentId", kickMemberAllDTO.getAgentId()); + if (!ObjectUtils.isEmpty(kickMemberAllDTO.getGameId())) { + params.put("gameId", kickMemberAllDTO.getGameId()); + } + String query = JsonUtil.mapToQueryString(params); + kickMemberAllDTO.setQuery(query); + String key = this.getKey(kickMemberAllDTO); + params.put("key", key); + kickMemberAllDTO.setQuery(query); + String apiBaseUrl = configService.selectConfigByKey(Constants.XK_API_BASE_URL); + try { + + String result = HttpClientSslUtils.doPost(apiBaseUrl + "/api/kickMemberAll", JsonUtil.objToPrettyString(params)); + XKKickMemberAllDTO xkKickMemberAllDTO = JsonUtil.stringToObj(result, XKKickMemberAllDTO.class); + //判断是否获取成功 + if (this.getIsSuccess(xkKickMemberAllDTO.getCode())) { + return Boolean.TRUE; + } else { + log.error("GamesXKServiceImpl [kickMemberAll] 强制全部会员从游戏注销失败,错误代码{},错误信息{}", xkKickMemberAllDTO.getCode(), xkKickMemberAllDTO.getMsg()); + throw new BaseException(MessageUtils.message("game.members.force.logout.failed")); + } + } catch (Exception e) { + log.error("GamesXKServiceImpl [kickMemberAll] 强制全部会员从游戏注销失败,错误信息{}", e); + throw new BaseException(MessageUtils.message("game.members.force.logout.failed")); + } + } + + /** + * 免费游戏玩家使用的纪录 + * + * @param getFreeSpinDashflowRequestDTO 获取自由旋转dashflow请求dto + * @return {@link List }<{@link GameFreeRecord }> + */ + @Override + public List getFreeSpinDashflow(GetFreeSpinDashflowRequestDTO getFreeSpinDashflowRequestDTO) { + return new ArrayList<>(); + } + + /** + * 取消赠送免费局数 + * + * @param cancelFreeSpinRequestDTO 取消免费旋转请求 + * @return {@link Boolean } + */ + @Override + public Boolean cancelFreeSpin(CancelFreeSpinRequestDTO cancelFreeSpinRequestDTO) { + return Boolean.TRUE; + } + + + /** + * 数据构建 + * + * @param gamesDataBuildDTO 数据 + * @return {@link GameBettingDetails } + */ + @Override + public GameBettingDetails dataBuild(GamesDataBuildDTO gamesDataBuildDTO) { + //转化类 + XKBetRecordResponseDTO.DataBean.ResultBean resultBean = (XKBetRecordResponseDTO.DataBean.ResultBean) gamesDataBuildDTO.getData(); + String systemByCode = gameSecretKeyService.findSystemByCode(resultBean.getAgentId(),GamePlatforms.XK.getInfo()); + Member member = memberService.selectMemberByMemberAccount(resultBean.getAccount()); + List gamesDatas = redisCache.getCacheList(CacheConstants.XK_GAMES); + Map dataDTOMap = gamesDatas.stream().collect(Collectors.toMap(XKGamesDTO.DataBean::getGameId, e -> e)); + XKGamesDTO.DataBean gamesDataDTO = dataDTOMap.get(resultBean.getGameId()); + BigDecimal payoffAmount=BigDecimal.ZERO; + + if (GameStatus.WIN.getCode().equals(resultBean.getStatus())) { + payoffAmount = NumberUtil.sub(resultBean.getPayoffAmount(), resultBean.getTurnover()); + } else if (GameStatus.FAIL.getCode().equals(resultBean.getStatus())){ + payoffAmount = NumberUtil.sub(resultBean.getPayoffAmount(), resultBean.getTurnover()).negate(); + } + //数据构造 + GameBettingDetails gameBettingDetails = GameBettingDetails.builder() + //保存我们的币种id + .currencyCode(systemByCode) + .memberId(member.getId()) + .gameCode(resultBean.getGameId()) + .gameType(XKGameType.findSystemByCode(resultBean.getGameCategoryId())) + .platformCode(GamePlatforms.XK.getCode()) + .gameId(gamesDataDTO.getSystemGameId()) + .gameName(gamesDataDTO.getName()) + .gameStatus(resultBean.getStatus()) + .gameStatusType(resultBean.getType()) + .gameCurrencyCode(resultBean.getAgentId()) + .account(String.valueOf(resultBean.getAccount())) + .wagersId(resultBean.getWagersId()) + .wagersTime(resultBean.getWagersTime()) + .betAmount(resultBean.getBetAmount().abs()) + .payoffTime(resultBean.getPayoffTime()) + .payoffAmount(payoffAmount) + .settlementTime(resultBean.getSettlementTime()) + .turnover(resultBean.getTurnover()) + .orderNo(String.valueOf(resultBean.getRoundIndex())) + .build(); + gameBettingDetails.setCreateBy(Constants.SYSTEM); + gameBettingDetails.setCreateTime(DateUtils.getNowDate()); + return gameBettingDetails; + } +} diff --git a/ff-admin/src/main/java/com/ff/game/controller/GameBettingDetailsController.java b/ff-admin/src/main/java/com/ff/game/controller/GameBettingDetailsController.java new file mode 100644 index 0000000..9b46dc9 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/controller/GameBettingDetailsController.java @@ -0,0 +1,104 @@ +package com.ff.game.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.game.domain.GameBettingDetails; +import com.ff.game.service.IGameBettingDetailsService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 会员投注细目Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/game/details") +public class GameBettingDetailsController extends BaseController +{ + @Autowired + private IGameBettingDetailsService gameBettingDetailsService; + + /** + * 查询会员投注细目列表 + */ + @PreAuthorize("@ss.hasPermi('game:details:list')") + @GetMapping("/list") + public TableDataInfo list(GameBettingDetails gameBettingDetails) + { + startPage(); + List list = gameBettingDetailsService.selectGameBettingDetailsList(gameBettingDetails); + return getDataTable(list); + } + + /** + * 导出会员投注细目列表 + */ + @PreAuthorize("@ss.hasPermi('game:details:export')") + @Log(title = "会员投注细目", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, GameBettingDetails gameBettingDetails) + { + List list = gameBettingDetailsService.selectGameBettingDetailsList(gameBettingDetails); + ExcelUtil util = new ExcelUtil(GameBettingDetails.class); + util.exportExcel(response, list, "会员投注细目数据"); + } + + /** + * 获取会员投注细目详细信息 + */ + @PreAuthorize("@ss.hasPermi('game:details:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(gameBettingDetailsService.selectGameBettingDetailsById(id)); + } + + /** + * 新增会员投注细目 + */ + @PreAuthorize("@ss.hasPermi('game:details:add')") + @Log(title = "会员投注细目", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody GameBettingDetails gameBettingDetails) + { + return toAjax(gameBettingDetailsService.insertGameBettingDetails(gameBettingDetails)); + } + + /** + * 修改会员投注细目 + */ + @PreAuthorize("@ss.hasPermi('game:details:edit')") + @Log(title = "会员投注细目", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody GameBettingDetails gameBettingDetails) + { + return toAjax(gameBettingDetailsService.updateGameBettingDetails(gameBettingDetails)); + } + + /** + * 删除会员投注细目 + */ + @PreAuthorize("@ss.hasPermi('game:details:remove')") + @Log(title = "会员投注细目", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(gameBettingDetailsService.deleteGameBettingDetailsByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/controller/GameController.java b/ff-admin/src/main/java/com/ff/game/controller/GameController.java new file mode 100644 index 0000000..5dde5a0 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/controller/GameController.java @@ -0,0 +1,104 @@ +package com.ff.game.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.game.domain.Game; +import com.ff.game.service.IGameService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 平台子游戏管理Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/game/game") +public class GameController extends BaseController +{ + @Autowired + private IGameService gameService; + + /** + * 查询平台子游戏管理列表 + */ + @PreAuthorize("@ss.hasPermi('game:game:list')") + @GetMapping("/list") + public TableDataInfo list(Game game) + { + startPage(); + List list = gameService.selectGameList(game); + return getDataTable(list); + } + + /** + * 导出平台子游戏管理列表 + */ + @PreAuthorize("@ss.hasPermi('game:game:export')") + @Log(title = "平台子游戏管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, Game game) + { + List list = gameService.selectGameList(game); + ExcelUtil util = new ExcelUtil(Game.class); + util.exportExcel(response, list, "平台子游戏管理数据"); + } + + /** + * 获取平台子游戏管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('game:game:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(gameService.selectGameById(id)); + } + + /** + * 新增平台子游戏管理 + */ + @PreAuthorize("@ss.hasPermi('game:game:add')") + @Log(title = "平台子游戏管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody Game game) + { + return toAjax(gameService.insertGame(game)); + } + + /** + * 修改平台子游戏管理 + */ + @PreAuthorize("@ss.hasPermi('game:game:edit')") + @Log(title = "平台子游戏管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody Game game) + { + return toAjax(gameService.updateGame(game)); + } + + /** + * 删除平台子游戏管理 + */ + @PreAuthorize("@ss.hasPermi('game:game:remove')") + @Log(title = "平台子游戏管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(gameService.deleteGameByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/controller/GameExchangeMoneyController.java b/ff-admin/src/main/java/com/ff/game/controller/GameExchangeMoneyController.java new file mode 100644 index 0000000..61c681b --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/controller/GameExchangeMoneyController.java @@ -0,0 +1,104 @@ +package com.ff.game.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.game.domain.GameExchangeMoney; +import com.ff.game.service.IGameExchangeMoneyService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 会员金额转移记录Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/game/money") +public class GameExchangeMoneyController extends BaseController +{ + @Autowired + private IGameExchangeMoneyService gameExchangeMoneyService; + + /** + * 查询会员金额转移记录列表 + */ + @PreAuthorize("@ss.hasPermi('game:money:list')") + @GetMapping("/list") + public TableDataInfo list(GameExchangeMoney gameExchangeMoney) + { + startPage(); + List list = gameExchangeMoneyService.selectGameExchangeMoneyList(gameExchangeMoney); + return getDataTable(list); + } + + /** + * 导出会员金额转移记录列表 + */ + @PreAuthorize("@ss.hasPermi('game:money:export')") + @Log(title = "会员金额转移记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, GameExchangeMoney gameExchangeMoney) + { + List list = gameExchangeMoneyService.selectGameExchangeMoneyList(gameExchangeMoney); + ExcelUtil util = new ExcelUtil(GameExchangeMoney.class); + util.exportExcel(response, list, "会员金额转移记录数据"); + } + + /** + * 获取会员金额转移记录详细信息 + */ + @PreAuthorize("@ss.hasPermi('game:money:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(gameExchangeMoneyService.selectGameExchangeMoneyById(id)); + } + + /** + * 新增会员金额转移记录 + */ + @PreAuthorize("@ss.hasPermi('game:money:add')") + @Log(title = "会员金额转移记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody GameExchangeMoney gameExchangeMoney) + { + return toAjax(gameExchangeMoneyService.insertGameExchangeMoney(gameExchangeMoney)); + } + + /** + * 修改会员金额转移记录 + */ + @PreAuthorize("@ss.hasPermi('game:money:edit')") + @Log(title = "会员金额转移记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody GameExchangeMoney gameExchangeMoney) + { + return toAjax(gameExchangeMoneyService.updateGameExchangeMoney(gameExchangeMoney)); + } + + /** + * 删除会员金额转移记录 + */ + @PreAuthorize("@ss.hasPermi('game:money:remove')") + @Log(title = "会员金额转移记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(gameExchangeMoneyService.deleteGameExchangeMoneyByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/controller/GameFreeRecordController.java b/ff-admin/src/main/java/com/ff/game/controller/GameFreeRecordController.java new file mode 100644 index 0000000..8c9f9fb --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/controller/GameFreeRecordController.java @@ -0,0 +1,104 @@ +package com.ff.game.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.game.domain.GameFreeRecord; +import com.ff.game.service.IGameFreeRecordService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 免费赠送游戏记录Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/game/record") +public class GameFreeRecordController extends BaseController +{ + @Autowired + private IGameFreeRecordService gameFreeRecordService; + + /** + * 查询免费赠送游戏记录列表 + */ + @PreAuthorize("@ss.hasPermi('game:record:list')") + @GetMapping("/list") + public TableDataInfo list(GameFreeRecord gameFreeRecord) + { + startPage(); + List list = gameFreeRecordService.selectGameFreeRecordList(gameFreeRecord); + return getDataTable(list); + } + + /** + * 导出免费赠送游戏记录列表 + */ + @PreAuthorize("@ss.hasPermi('game:record:export')") + @Log(title = "免费赠送游戏记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, GameFreeRecord gameFreeRecord) + { + List list = gameFreeRecordService.selectGameFreeRecordList(gameFreeRecord); + ExcelUtil util = new ExcelUtil(GameFreeRecord.class); + util.exportExcel(response, list, "免费赠送游戏记录数据"); + } + + /** + * 获取免费赠送游戏记录详细信息 + */ + @PreAuthorize("@ss.hasPermi('game:record:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(gameFreeRecordService.selectGameFreeRecordById(id)); + } + + /** + * 新增免费赠送游戏记录 + */ + @PreAuthorize("@ss.hasPermi('game:record:add')") + @Log(title = "免费赠送游戏记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody GameFreeRecord gameFreeRecord) + { + return toAjax(gameFreeRecordService.insertGameFreeRecord(gameFreeRecord)); + } + + /** + * 修改免费赠送游戏记录 + */ + @PreAuthorize("@ss.hasPermi('game:record:edit')") + @Log(title = "免费赠送游戏记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody GameFreeRecord gameFreeRecord) + { + return toAjax(gameFreeRecordService.updateGameFreeRecord(gameFreeRecord)); + } + + /** + * 删除免费赠送游戏记录 + */ + @PreAuthorize("@ss.hasPermi('game:record:remove')") + @Log(title = "免费赠送游戏记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(gameFreeRecordService.deleteGameFreeRecordByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/controller/GamePlatformController.java b/ff-admin/src/main/java/com/ff/game/controller/GamePlatformController.java new file mode 100644 index 0000000..265e783 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/controller/GamePlatformController.java @@ -0,0 +1,104 @@ +package com.ff.game.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.game.domain.GamePlatform; +import com.ff.game.service.IGamePlatformService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 平台管理Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/game/platform") +public class GamePlatformController extends BaseController +{ + @Autowired + private IGamePlatformService gamePlatformService; + + /** + * 查询平台管理列表 + */ + @PreAuthorize("@ss.hasPermi('game:platform:list')") + @GetMapping("/list") + public TableDataInfo list(GamePlatform gamePlatform) + { + startPage(); + List list = gamePlatformService.selectGamePlatformList(gamePlatform); + return getDataTable(list); + } + + /** + * 导出平台管理列表 + */ + @PreAuthorize("@ss.hasPermi('game:platform:export')") + @Log(title = "平台管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, GamePlatform gamePlatform) + { + List list = gamePlatformService.selectGamePlatformList(gamePlatform); + ExcelUtil util = new ExcelUtil(GamePlatform.class); + util.exportExcel(response, list, "平台管理数据"); + } + + /** + * 获取平台管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('game:platform:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(gamePlatformService.selectGamePlatformById(id)); + } + + /** + * 新增平台管理 + */ + @PreAuthorize("@ss.hasPermi('game:platform:add')") + @Log(title = "平台管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody GamePlatform gamePlatform) + { + return toAjax(gamePlatformService.insertGamePlatform(gamePlatform)); + } + + /** + * 修改平台管理 + */ + @PreAuthorize("@ss.hasPermi('game:platform:edit')") + @Log(title = "平台管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody GamePlatform gamePlatform) + { + return toAjax(gamePlatformService.updateGamePlatform(gamePlatform)); + } + + /** + * 删除平台管理 + */ + @PreAuthorize("@ss.hasPermi('game:platform:remove')") + @Log(title = "平台管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(gamePlatformService.deleteGamePlatformByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/controller/GameSecretKeyController.java b/ff-admin/src/main/java/com/ff/game/controller/GameSecretKeyController.java new file mode 100644 index 0000000..627fc8d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/controller/GameSecretKeyController.java @@ -0,0 +1,104 @@ +package com.ff.game.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.game.domain.GameSecretKey; +import com.ff.game.service.IGameSecretKeyService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 游戏平台密钥管理Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/game/key") +public class GameSecretKeyController extends BaseController +{ + @Autowired + private IGameSecretKeyService gameSecretKeyService; + + /** + * 查询游戏平台密钥管理列表 + */ + @PreAuthorize("@ss.hasPermi('game:key:list')") + @GetMapping("/list") + public TableDataInfo list(GameSecretKey gameSecretKey) + { + startPage(); + List list = gameSecretKeyService.selectGameSecretKeyList(gameSecretKey); + return getDataTable(list); + } + + /** + * 导出游戏平台密钥管理列表 + */ + @PreAuthorize("@ss.hasPermi('game:key:export')") + @Log(title = "游戏平台密钥管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, GameSecretKey gameSecretKey) + { + List list = gameSecretKeyService.selectGameSecretKeyList(gameSecretKey); + ExcelUtil util = new ExcelUtil(GameSecretKey.class); + util.exportExcel(response, list, "游戏平台密钥管理数据"); + } + + /** + * 获取游戏平台密钥管理详细信息 + */ + @PreAuthorize("@ss.hasPermi('game:key:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(gameSecretKeyService.selectGameSecretKeyById(id)); + } + + /** + * 新增游戏平台密钥管理 + */ + @PreAuthorize("@ss.hasPermi('game:key:add')") + @Log(title = "游戏平台密钥管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody GameSecretKey gameSecretKey) + { + return toAjax(gameSecretKeyService.insertGameSecretKey(gameSecretKey)); + } + + /** + * 修改游戏平台密钥管理 + */ + @PreAuthorize("@ss.hasPermi('game:key:edit')") + @Log(title = "游戏平台密钥管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody GameSecretKey gameSecretKey) + { + return toAjax(gameSecretKeyService.updateGameSecretKey(gameSecretKey)); + } + + /** + * 删除游戏平台密钥管理 + */ + @PreAuthorize("@ss.hasPermi('game:key:remove')") + @Log(title = "游戏平台密钥管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(gameSecretKeyService.deleteGameSecretKeyByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/domain/Game.java b/ff-admin/src/main/java/com/ff/game/domain/Game.java new file mode 100644 index 0000000..1095607 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/domain/Game.java @@ -0,0 +1,64 @@ +package com.ff.game.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 平台子游戏管理对象 ff_game + * + * @author shi + * @date 2025-02-10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Game extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 排序 */ + @Excel(name = "排序") + private Integer sortNo; + + /** 游戏平台id */ + @Excel(name = "游戏平台id") + private Long platformId; + + /** 游戏第三方id */ + @Excel(name = "游戏第三方id") + private Integer gameCode; + + /** 第三方来源分类 */ + @Excel(name = "第三方来源分类") + private Integer gameSourceType; + + /** 游戏名称 */ + @Excel(name = "游戏名称") + private String gameName; + + /** 是否支持免费游戏 1 支持 0 不支持 */ + @Excel(name = "是否支持免费游戏 1 支持 0 不支持") + private Boolean freespin; + + /** 是否支持试玩 0关闭 1开启 */ + @Excel(name = "是否支持试玩 0关闭 1开启") + private Boolean demoStatus; + + /** 维护开关 维护状态 0关闭 1开启 */ + @Excel(name = "维护开关 维护状态 0关闭 1开启") + private Boolean stopStatus; + + /** 游戏开关 平台开关状态 0关闭 1开启 */ + @Excel(name = "游戏开关 平台开关状态 0关闭 1开启") + private Boolean gameStatus; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/domain/GameBettingDetails.java b/ff-admin/src/main/java/com/ff/game/domain/GameBettingDetails.java new file mode 100644 index 0000000..5c708ab --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/domain/GameBettingDetails.java @@ -0,0 +1,109 @@ +package com.ff.game.domain; + +import java.math.BigDecimal; +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 会员投注细目对象 ff_game_betting_details + * + * @author shi + * @date 2025-02-10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class GameBettingDetails extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 币种编码 */ + @Excel(name = "币种编码") + private String currencyCode; + + /** 会员id */ + @Excel(name = "会员id") + private Long memberId; + + /** 游戏id */ + @Excel(name = "游戏id ") + private Integer gameCode; + + /** 游戏id */ + @Excel(name = "游戏id") + private Long gameId; + + /** 游戏类型 ff_game_type 字典 */ + @Excel(name = "游戏类型 ff_game_type 字典") + private Long gameType; + + /** 游戏平台 */ + @Excel(name = "游戏平台 ") + private String platformCode; + + /** 游戏名称 */ + @Excel(name = "游戏名称") + private String gameName; + + /** 注单状态 1: 赢 2: 输 3: 平局 */ + @Excel(name = "注单状态 1: 赢 2: 输 3: 平局") + private Integer gameStatus; + + /** 注单类型 */ + @Excel(name = "注单类型") + private Integer gameStatusType; + + /** 游戏币种类型 */ + @Excel(name = "游戏币种类型") + private String gameCurrencyCode; + + /** 游戏账号 */ + @Excel(name = "游戏账号") + private String account; + + /** 游戏注单唯一值 */ + @Excel(name = "游戏注单唯一值") + private Long wagersId; + + /** 投注时间 (Unix 时间戳) */ + @Excel(name = "投注时间 (Unix 时间戳)") + private Long wagersTime; + + /** 投注金额 */ + @Excel(name = "投注金额") + private BigDecimal betAmount; + + /** 派彩时间 (Unix 时间戳) */ + @Excel(name = "派彩时间 (Unix 时间戳)") + private Long payoffTime; + + /** 派彩金额 */ + @Excel(name = "派彩金额") + private BigDecimal payoffAmount; + + /** 对帐时间 (Unix 时间戳) */ + @Excel(name = "对帐时间 (Unix 时间戳)") + private Long settlementTime; + + /** 有效投注金额 ※注 1 */ + @Excel(name = "有效投注金额 ※注 1") + private BigDecimal turnover; + + /** 订单id */ + @Excel(name = "订单id") + private String orderNo; + + /** 结算状态 1 未结算 2已结算 3 已撤单 */ + @Excel(name = "结算状态 1 未结算 2已结算 3 已撤单") + private Integer settlementStatus; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/domain/GameExchangeMoney.java b/ff-admin/src/main/java/com/ff/game/domain/GameExchangeMoney.java new file mode 100644 index 0000000..6251d64 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/domain/GameExchangeMoney.java @@ -0,0 +1,81 @@ +package com.ff.game.domain; + +import java.math.BigDecimal; +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 会员金额转移记录对象 ff_game_exchange_money + * + * @author shi + * @date 2025-02-10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class GameExchangeMoney extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 币种编码 */ + @Excel(name = "币种编码") + private String currencyCode; + + /** 交易id */ + @Excel(name = "交易id") + private String transactionId; + + /** 会员id */ + @Excel(name = "会员id") + private Long memberId; + + /** 游戏平台 */ + @Excel(name = "游戏平台 ") + private String platformCode; + + /** 平台id */ + @Excel(name = "平台id") + private Long platformId; + + /** 操作金额 */ + @Excel(name = "操作金额") + private BigDecimal balance; + + /** 租户操作额度 */ + @Excel(name = "租户操作额度") + private BigDecimal quota; + + /** 转账前金额(游戏币) */ + @Excel(name = " 转账前金额(游戏币)") + private BigDecimal coinBefore; + + /** 转账后金额(游戏币) */ + @Excel(name = "转账后金额(游戏币)") + private BigDecimal coinAfter; + + /** 转账前金额(指定货币) */ + @Excel(name = "转账前金额(指定货币)") + private BigDecimal currencyBefore; + + /** 转账后金额(指定货币) */ + @Excel(name = "转账后金额(指定货币)") + private BigDecimal currencyAfter; + + /** 转出类型 1游戏商转入到用户全部转出 2 用户转移到游戏商 3 游戏商转移额度到平台商 */ + @Excel(name = "转出类型 1游戏商转入到用户全部转出 2 用户转移到游戏商 3 游戏商转移额度到平台商") + private Integer exchangeType; + + /** 状态 1 成功 2失败 */ + @Excel(name = "状态 1 成功 2失败") + private Integer status; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/domain/GameFreeRecord.java b/ff-admin/src/main/java/com/ff/game/domain/GameFreeRecord.java new file mode 100644 index 0000000..0636a82 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/domain/GameFreeRecord.java @@ -0,0 +1,83 @@ +package com.ff.game.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 免费赠送游戏记录对象 ff_game_free_record + * + * @author shi + * @date 2025-02-10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class GameFreeRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 币种编码 */ + @Excel(name = "币种编码") + private String currencyCode; + + /** 免费局数序号(唯一标识符) */ + @Excel(name = "免费局数序号", readConverterExp = "唯=一标识符") + private String referenceId; + + /** 会员id */ + @Excel(name = "会员id") + private Long memberId; + + /** 用户账号 */ + @Excel(name = "用户账号") + private String memberAccount; + + /** 游戏id */ + @Excel(name = "游戏id ") + private Long gameId; + + /** 免费游戏局数可使用的开始时间 */ + @Excel(name = "免费游戏局数可使用的开始时间") + private Long sendTime; + + /** 免费局数过期时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "免费局数过期时间", width = 30, dateFormat = "yyyy-MM-dd") + private Long expiredTime; + + /** 免费局数记录更新时间 */ + @Excel(name = "免费局数记录更新时间") + private Long freeUpdateTime; + + /** 免费局数赠送的游戏名称 */ + @Excel(name = "免费局数赠送的游戏名称") + private String sendGame; + + /** 免费局数赠送的数量 */ + @Excel(name = "免费局数赠送的数量") + private Integer sendAmount; + + /** 已使用的免费局数数量 */ + @Excel(name = "已使用的免费局数数量") + private Integer usedAmount; + + /** 未使用的免费局数数量 */ + @Excel(name = "未使用的免费局数数量") + private Integer unusedAmount; + + /** 免费状态 1正常 0 取消 */ + @Excel(name = "免费状态 1正常 0 取消 ") + private Integer freeStatus; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/domain/GamePlatform.java b/ff-admin/src/main/java/com/ff/game/domain/GamePlatform.java new file mode 100644 index 0000000..a24b3c1 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/domain/GamePlatform.java @@ -0,0 +1,54 @@ +package com.ff.game.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 平台管理对象 ff_game_platform + * + * @author shi + * @date 2025-02-10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class GamePlatform extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 排序 */ + @Excel(name = "排序") + private Integer sortNo; + + /** 平台编码 */ + @Excel(name = "平台编码") + private String platformCode; + + /** 平台类型 ff_game_type 字典 */ + @Excel(name = "平台类型 ff_game_platform_type 字典") + private Long platformType; + + /** 平台名称 */ + @Excel(name = "平台名称") + private String platformName; + + /** 维护开关 维护状态 1 开启 2关闭 */ + @Excel(name = "维护开关 维护状态 1 开启 2关闭") + private Integer stopStatus; + + /** 平台开关 平台开关状态 1 开启 2关闭 */ + @Excel(name = "平台开关 平台开关状态 1 开启 2关闭") + private Integer platformStatus; + + + + +} diff --git a/ff-admin/src/main/java/com/ff/game/domain/GameSecretKey.java b/ff-admin/src/main/java/com/ff/game/domain/GameSecretKey.java new file mode 100644 index 0000000..9ea4ae6 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/domain/GameSecretKey.java @@ -0,0 +1,49 @@ +package com.ff.game.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.Data; +/** + * 游戏平台密钥管理对象 ff_game_secret_key + * + * @author shi + * @date 2025-02-10 + */ +@Data +public class GameSecretKey extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 平台 */ + @Excel(name = "平台") + private String platform; + + /** 代码 */ + @Excel(name = "代码") + private String code; + + /** 密钥 */ + @Excel(name = "密钥") + private String key; + + /** 系统代码 */ + @Excel(name = "系统代码") + private String systemCode; + + /** 语言 */ + @Excel(name = "语言") + private String lang; + + /** 系统语种id */ + @Excel(name = "系统语种id") + private String systemLangCode; + + /** 信息 */ + @Excel(name = "信息") + private String info; + + +} diff --git a/ff-admin/src/main/java/com/ff/game/mapper/GameBettingDetailsMapper.java b/ff-admin/src/main/java/com/ff/game/mapper/GameBettingDetailsMapper.java new file mode 100644 index 0000000..aa9bb9c --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/mapper/GameBettingDetailsMapper.java @@ -0,0 +1,61 @@ +package com.ff.game.mapper; + +import java.util.List; +import com.ff.game.domain.GameBettingDetails; + +/** + * 会员投注细目Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface GameBettingDetailsMapper +{ + /** + * 查询会员投注细目 + * + * @param id 会员投注细目主键 + * @return 会员投注细目 + */ + GameBettingDetails selectGameBettingDetailsById(Long id); + + /** + * 查询会员投注细目列表 + * + * @param gameBettingDetails 会员投注细目 + * @return 会员投注细目集合 + */ + List selectGameBettingDetailsList(GameBettingDetails gameBettingDetails); + + /** + * 新增会员投注细目 + * + * @param gameBettingDetails 会员投注细目 + * @return 结果 + */ + int insertGameBettingDetails(GameBettingDetails gameBettingDetails); + + /** + * 修改会员投注细目 + * + * @param gameBettingDetails 会员投注细目 + * @return 结果 + */ + int updateGameBettingDetails(GameBettingDetails gameBettingDetails); + + /** + * 删除会员投注细目 + * + * @param id 会员投注细目主键 + * @return 结果 + */ + int deleteGameBettingDetailsById(Long id); + + /** + * 批量删除会员投注细目 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteGameBettingDetailsByIds(Long[] ids); +} diff --git a/ff-admin/src/main/java/com/ff/game/mapper/GameExchangeMoneyMapper.java b/ff-admin/src/main/java/com/ff/game/mapper/GameExchangeMoneyMapper.java new file mode 100644 index 0000000..089132c --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/mapper/GameExchangeMoneyMapper.java @@ -0,0 +1,61 @@ +package com.ff.game.mapper; + +import java.util.List; +import com.ff.game.domain.GameExchangeMoney; + +/** + * 会员金额转移记录Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface GameExchangeMoneyMapper +{ + /** + * 查询会员金额转移记录 + * + * @param id 会员金额转移记录主键 + * @return 会员金额转移记录 + */ + GameExchangeMoney selectGameExchangeMoneyById(Long id); + + /** + * 查询会员金额转移记录列表 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 会员金额转移记录集合 + */ + List selectGameExchangeMoneyList(GameExchangeMoney gameExchangeMoney); + + /** + * 新增会员金额转移记录 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 结果 + */ + int insertGameExchangeMoney(GameExchangeMoney gameExchangeMoney); + + /** + * 修改会员金额转移记录 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 结果 + */ + int updateGameExchangeMoney(GameExchangeMoney gameExchangeMoney); + + /** + * 删除会员金额转移记录 + * + * @param id 会员金额转移记录主键 + * @return 结果 + */ + int deleteGameExchangeMoneyById(Long id); + + /** + * 批量删除会员金额转移记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteGameExchangeMoneyByIds(Long[] ids); +} diff --git a/ff-admin/src/main/java/com/ff/game/mapper/GameFreeRecordMapper.java b/ff-admin/src/main/java/com/ff/game/mapper/GameFreeRecordMapper.java new file mode 100644 index 0000000..63a5d78 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/mapper/GameFreeRecordMapper.java @@ -0,0 +1,61 @@ +package com.ff.game.mapper; + +import java.util.List; +import com.ff.game.domain.GameFreeRecord; + +/** + * 免费赠送游戏记录Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface GameFreeRecordMapper +{ + /** + * 查询免费赠送游戏记录 + * + * @param id 免费赠送游戏记录主键 + * @return 免费赠送游戏记录 + */ + GameFreeRecord selectGameFreeRecordById(Long id); + + /** + * 查询免费赠送游戏记录列表 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 免费赠送游戏记录集合 + */ + List selectGameFreeRecordList(GameFreeRecord gameFreeRecord); + + /** + * 新增免费赠送游戏记录 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 结果 + */ + int insertGameFreeRecord(GameFreeRecord gameFreeRecord); + + /** + * 修改免费赠送游戏记录 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 结果 + */ + int updateGameFreeRecord(GameFreeRecord gameFreeRecord); + + /** + * 删除免费赠送游戏记录 + * + * @param id 免费赠送游戏记录主键 + * @return 结果 + */ + int deleteGameFreeRecordById(Long id); + + /** + * 批量删除免费赠送游戏记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteGameFreeRecordByIds(Long[] ids); +} diff --git a/ff-admin/src/main/java/com/ff/game/mapper/GameMapper.java b/ff-admin/src/main/java/com/ff/game/mapper/GameMapper.java new file mode 100644 index 0000000..c843375 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/mapper/GameMapper.java @@ -0,0 +1,82 @@ +package com.ff.game.mapper; + +import java.util.List; + +import com.ff.game.api.request.GameUniqueDTO; +import com.ff.game.domain.Game; + +/** + * 平台子游戏管理Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface GameMapper +{ + /** + * 查询平台子游戏管理 + * + * @param id 平台子游戏管理主键 + * @return 平台子游戏管理 + */ + Game selectGameById(Long id); + + /** + * 查询平台子游戏管理列表 + * + * @param game 平台子游戏管理 + * @return 平台子游戏管理集合 + */ + List selectGameList(Game game); + + /** + * 新增平台子游戏管理 + * + * @param game 平台子游戏管理 + * @return 结果 + */ + int insertGame(Game game); + + /** + * 修改平台子游戏管理 + * + * @param game 平台子游戏管理 + * @return 结果 + */ + int updateGame(Game game); + + /** + * 删除平台子游戏管理 + * + * @param id 平台子游戏管理主键 + * @return 结果 + */ + int deleteGameById(Long id); + + /** + * 批量删除平台子游戏管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteGameByIds(Long[] ids); + + + /** + * 按平台id选择最大排序号 + * + * @param platformId 平台id + * @return {@link Integer } + */ + Integer selectMaxSortNoByPlatformId(Long platformId); + + + /** + * 选择游戏唯一列表 + * + * @param gameUniqueDTO 游戏独有dto + * @return {@link List }<{@link Game }> + */ + List selectGameUniqueList(GameUniqueDTO gameUniqueDTO); + +} diff --git a/ff-admin/src/main/java/com/ff/game/mapper/GamePlatformMapper.java b/ff-admin/src/main/java/com/ff/game/mapper/GamePlatformMapper.java new file mode 100644 index 0000000..e938093 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/mapper/GamePlatformMapper.java @@ -0,0 +1,70 @@ +package com.ff.game.mapper; + +import java.util.List; +import com.ff.game.domain.GamePlatform; + +/** + * 平台管理Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface GamePlatformMapper +{ + /** + * 查询平台管理 + * + * @param id 平台管理主键 + * @return 平台管理 + */ + GamePlatform selectGamePlatformById(Long id); + + /** + * 查询平台管理列表 + * + * @param gamePlatform 平台管理 + * @return 平台管理集合 + */ + List selectGamePlatformList(GamePlatform gamePlatform); + + /** + * 新增平台管理 + * + * @param gamePlatform 平台管理 + * @return 结果 + */ + int insertGamePlatform(GamePlatform gamePlatform); + + /** + * 修改平台管理 + * + * @param gamePlatform 平台管理 + * @return 结果 + */ + int updateGamePlatform(GamePlatform gamePlatform); + + /** + * 删除平台管理 + * + * @param id 平台管理主键 + * @return 结果 + */ + int deleteGamePlatformById(Long id); + + /** + * 批量删除平台管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteGamePlatformByIds(Long[] ids); + + + /** + * 选择最大排序号 + * + * @return {@link Integer } + */ + Integer selectMaxSortNo(); + +} diff --git a/ff-admin/src/main/java/com/ff/game/mapper/GameSecretKeyMapper.java b/ff-admin/src/main/java/com/ff/game/mapper/GameSecretKeyMapper.java new file mode 100644 index 0000000..1f88f31 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/mapper/GameSecretKeyMapper.java @@ -0,0 +1,90 @@ +package com.ff.game.mapper; + +import java.util.List; + +import com.ff.common.domain.TenantSecretKey; +import com.ff.game.domain.GameSecretKey; +import org.apache.ibatis.annotations.Param; + +/** + * 游戏平台密钥管理Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface GameSecretKeyMapper +{ + /** + * 查询游戏平台密钥管理 + * + * @param id 游戏平台密钥管理主键 + * @return 游戏平台密钥管理 + */ + GameSecretKey selectGameSecretKeyById(Long id); + + /** + * 查询游戏平台密钥管理列表 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 游戏平台密钥管理集合 + */ + List selectGameSecretKeyList(GameSecretKey gameSecretKey); + + /** + * 新增游戏平台密钥管理 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 结果 + */ + int insertGameSecretKey(GameSecretKey gameSecretKey); + + /** + * 修改游戏平台密钥管理 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 结果 + */ + int updateGameSecretKey(GameSecretKey gameSecretKey); + + /** + * 删除游戏平台密钥管理 + * + * @param id 游戏平台密钥管理主键 + * @return 结果 + */ + int deleteGameSecretKeyById(Long id); + + /** + * 批量删除游戏平台密钥管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteGameSecretKeyByIds(Long[] ids); + + /** + * 按代码查找系统 + * + * @param code 代码 + * @return {@link String } + */ + String findSystemByCode(@Param("code") String code, @Param("platform")String platform); + + /** + * 通过平台和系统代码查找密钥 + * + * @param platform 平台 + * @param systemCode 系统代码 + * @return {@link TenantSecretKey } + */ + GameSecretKey findSecretKeyByPlatformAndSystemCode(@Param("platform") String platform, @Param("systemCode") String systemCode); + + /** + * 按平台和系统查找lang代码 + * + * @param platform 平台 + * @param systemLangCode 系统语言代码 + * @return {@link GameSecretKey } + */ + GameSecretKey findByPlatformAndSystemLangCode(@Param("platform") String platform, @Param("systemLangCode") String systemLangCode); +} diff --git a/ff-admin/src/main/java/com/ff/game/service/IGameBettingDetailsService.java b/ff-admin/src/main/java/com/ff/game/service/IGameBettingDetailsService.java new file mode 100644 index 0000000..affec19 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/IGameBettingDetailsService.java @@ -0,0 +1,61 @@ +package com.ff.game.service; + +import java.util.List; +import com.ff.game.domain.GameBettingDetails; + +/** + * 会员投注细目Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IGameBettingDetailsService +{ + /** + * 查询会员投注细目 + * + * @param id 会员投注细目主键 + * @return 会员投注细目 + */ + GameBettingDetails selectGameBettingDetailsById(Long id); + + /** + * 查询会员投注细目列表 + * + * @param gameBettingDetails 会员投注细目 + * @return 会员投注细目集合 + */ + List selectGameBettingDetailsList(GameBettingDetails gameBettingDetails); + + /** + * 新增会员投注细目 + * + * @param gameBettingDetails 会员投注细目 + * @return 结果 + */ + int insertGameBettingDetails(GameBettingDetails gameBettingDetails); + + /** + * 修改会员投注细目 + * + * @param gameBettingDetails 会员投注细目 + * @return 结果 + */ + int updateGameBettingDetails(GameBettingDetails gameBettingDetails); + + /** + * 批量删除会员投注细目 + * + * @param ids 需要删除的会员投注细目主键集合 + * @return 结果 + */ + int deleteGameBettingDetailsByIds(Long[] ids); + + /** + * 删除会员投注细目信息 + * + * @param id 会员投注细目主键 + * @return 结果 + */ + int deleteGameBettingDetailsById(Long id); +} diff --git a/ff-admin/src/main/java/com/ff/game/service/IGameExchangeMoneyService.java b/ff-admin/src/main/java/com/ff/game/service/IGameExchangeMoneyService.java new file mode 100644 index 0000000..b40b050 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/IGameExchangeMoneyService.java @@ -0,0 +1,61 @@ +package com.ff.game.service; + +import java.util.List; +import com.ff.game.domain.GameExchangeMoney; + +/** + * 会员金额转移记录Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IGameExchangeMoneyService +{ + /** + * 查询会员金额转移记录 + * + * @param id 会员金额转移记录主键 + * @return 会员金额转移记录 + */ + GameExchangeMoney selectGameExchangeMoneyById(Long id); + + /** + * 查询会员金额转移记录列表 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 会员金额转移记录集合 + */ + List selectGameExchangeMoneyList(GameExchangeMoney gameExchangeMoney); + + /** + * 新增会员金额转移记录 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 结果 + */ + int insertGameExchangeMoney(GameExchangeMoney gameExchangeMoney); + + /** + * 修改会员金额转移记录 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 结果 + */ + int updateGameExchangeMoney(GameExchangeMoney gameExchangeMoney); + + /** + * 批量删除会员金额转移记录 + * + * @param ids 需要删除的会员金额转移记录主键集合 + * @return 结果 + */ + int deleteGameExchangeMoneyByIds(Long[] ids); + + /** + * 删除会员金额转移记录信息 + * + * @param id 会员金额转移记录主键 + * @return 结果 + */ + int deleteGameExchangeMoneyById(Long id); +} diff --git a/ff-admin/src/main/java/com/ff/game/service/IGameFreeRecordService.java b/ff-admin/src/main/java/com/ff/game/service/IGameFreeRecordService.java new file mode 100644 index 0000000..3c5f3b3 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/IGameFreeRecordService.java @@ -0,0 +1,61 @@ +package com.ff.game.service; + +import java.util.List; +import com.ff.game.domain.GameFreeRecord; + +/** + * 免费赠送游戏记录Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IGameFreeRecordService +{ + /** + * 查询免费赠送游戏记录 + * + * @param id 免费赠送游戏记录主键 + * @return 免费赠送游戏记录 + */ + GameFreeRecord selectGameFreeRecordById(Long id); + + /** + * 查询免费赠送游戏记录列表 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 免费赠送游戏记录集合 + */ + List selectGameFreeRecordList(GameFreeRecord gameFreeRecord); + + /** + * 新增免费赠送游戏记录 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 结果 + */ + int insertGameFreeRecord(GameFreeRecord gameFreeRecord); + + /** + * 修改免费赠送游戏记录 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 结果 + */ + int updateGameFreeRecord(GameFreeRecord gameFreeRecord); + + /** + * 批量删除免费赠送游戏记录 + * + * @param ids 需要删除的免费赠送游戏记录主键集合 + * @return 结果 + */ + int deleteGameFreeRecordByIds(Long[] ids); + + /** + * 删除免费赠送游戏记录信息 + * + * @param id 免费赠送游戏记录主键 + * @return 结果 + */ + int deleteGameFreeRecordById(Long id); +} diff --git a/ff-admin/src/main/java/com/ff/game/service/IGamePlatformService.java b/ff-admin/src/main/java/com/ff/game/service/IGamePlatformService.java new file mode 100644 index 0000000..a616d2a --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/IGamePlatformService.java @@ -0,0 +1,71 @@ +package com.ff.game.service; + +import java.util.List; +import com.ff.game.domain.GamePlatform; + +/** + * 平台管理Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IGamePlatformService +{ + /** + * 查询平台管理 + * + * @param id 平台管理主键 + * @return 平台管理 + */ + GamePlatform selectGamePlatformById(Long id); + + /** + * 查询平台管理列表 + * + * @param gamePlatform 平台管理 + * @return 平台管理集合 + */ + List selectGamePlatformList(GamePlatform gamePlatform); + + /** + * 新增平台管理 + * + * @param gamePlatform 平台管理 + * @return 结果 + */ + int insertGamePlatform(GamePlatform gamePlatform); + + /** + * 修改平台管理 + * + * @param gamePlatform 平台管理 + * @return 结果 + */ + int updateGamePlatform(GamePlatform gamePlatform); + + /** + * 批量删除平台管理 + * + * @param ids 需要删除的平台管理主键集合 + * @return 结果 + */ + int deleteGamePlatformByIds(Long[] ids); + + /** + * 删除平台管理信息 + * + * @param id 平台管理主键 + * @return 结果 + */ + int deleteGamePlatformById(Long id); + + + /** + * 选择最大排序号 + * + * @return {@link Integer } + */ + Integer selectMaxSortNo(); + + +} diff --git a/ff-admin/src/main/java/com/ff/game/service/IGameSecretKeyService.java b/ff-admin/src/main/java/com/ff/game/service/IGameSecretKeyService.java new file mode 100644 index 0000000..2260294 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/IGameSecretKeyService.java @@ -0,0 +1,94 @@ +package com.ff.game.service; + +import java.util.List; + +import com.ff.common.domain.TenantSecretKey; +import com.ff.game.domain.GameSecretKey; + +/** + * 游戏平台密钥管理Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IGameSecretKeyService +{ + /** + * 查询游戏平台密钥管理 + * + * @param id 游戏平台密钥管理主键 + * @return 游戏平台密钥管理 + */ + GameSecretKey selectGameSecretKeyById(Long id); + + /** + * 查询游戏平台密钥管理列表 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 游戏平台密钥管理集合 + */ + List selectGameSecretKeyList(GameSecretKey gameSecretKey); + + /** + * 新增游戏平台密钥管理 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 结果 + */ + int insertGameSecretKey(GameSecretKey gameSecretKey); + + /** + * 修改游戏平台密钥管理 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 结果 + */ + int updateGameSecretKey(GameSecretKey gameSecretKey); + + /** + * 批量删除游戏平台密钥管理 + * + * @param ids 需要删除的游戏平台密钥管理主键集合 + * @return 结果 + */ + int deleteGameSecretKeyByIds(Long[] ids); + + /** + * 删除游戏平台密钥管理信息 + * + * @param id 游戏平台密钥管理主键 + * @return 结果 + */ + int deleteGameSecretKeyById(Long id); + + + + /** + * 按代码查找系统 + * + * @param code 代码 + * @param platform 平台 + * @return {@link String } + */ + String findSystemByCode( String code,String platform); + + /** + * 通过平台和系统代码查找密钥 + * + * @param platform 平台 + * @param systemCode 系统代码 + * @return {@link GameSecretKey } + */ + GameSecretKey findSecretKeyByPlatformAndSystemCode(String platform, String systemCode); + + + /** + * 按平台和系统查找lang代码 + * + * @param platform 平台 + * @param systemLangCode 系统语言代码 + * @return {@link GameSecretKey } + */ + GameSecretKey findByPlatformAndSystemLangCode( String platform,String systemLangCode); + +} diff --git a/ff-admin/src/main/java/com/ff/game/service/IGameService.java b/ff-admin/src/main/java/com/ff/game/service/IGameService.java new file mode 100644 index 0000000..6ab7108 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/IGameService.java @@ -0,0 +1,81 @@ +package com.ff.game.service; + +import java.util.List; + +import com.ff.game.api.request.GameUniqueDTO; +import com.ff.game.domain.Game; + +/** + * 平台子游戏管理Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IGameService +{ + /** + * 查询平台子游戏管理 + * + * @param id 平台子游戏管理主键 + * @return 平台子游戏管理 + */ + Game selectGameById(Long id); + + /** + * 查询平台子游戏管理列表 + * + * @param game 平台子游戏管理 + * @return 平台子游戏管理集合 + */ + List selectGameList(Game game); + + /** + * 新增平台子游戏管理 + * + * @param game 平台子游戏管理 + * @return 结果 + */ + int insertGame(Game game); + + /** + * 修改平台子游戏管理 + * + * @param game 平台子游戏管理 + * @return 结果 + */ + int updateGame(Game game); + + /** + * 批量删除平台子游戏管理 + * + * @param ids 需要删除的平台子游戏管理主键集合 + * @return 结果 + */ + int deleteGameByIds(Long[] ids); + + /** + * 删除平台子游戏管理信息 + * + * @param id 平台子游戏管理主键 + * @return 结果 + */ + int deleteGameById(Long id); + + /** + * 按平台id选择最大排序号 + * + * @param platformId 平台id + * @return {@link Integer } + */ + Integer selectMaxSortNoByPlatformId(Long platformId); + + /** + * 选择游戏唯一列表 + * + * @param gameUniqueDTO 游戏独有dto + * @return {@link List }<{@link Game }> + */ + List selectGameUniqueList(GameUniqueDTO gameUniqueDTO); + + +} diff --git a/ff-admin/src/main/java/com/ff/game/service/impl/GameBettingDetailsServiceImpl.java b/ff-admin/src/main/java/com/ff/game/service/impl/GameBettingDetailsServiceImpl.java new file mode 100644 index 0000000..23c1286 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/impl/GameBettingDetailsServiceImpl.java @@ -0,0 +1,96 @@ +package com.ff.game.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.game.mapper.GameBettingDetailsMapper; +import com.ff.game.domain.GameBettingDetails; +import com.ff.game.service.IGameBettingDetailsService; + +/** + * 会员投注细目Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class GameBettingDetailsServiceImpl implements IGameBettingDetailsService +{ + @Autowired + private GameBettingDetailsMapper gameBettingDetailsMapper; + + /** + * 查询会员投注细目 + * + * @param id 会员投注细目主键 + * @return 会员投注细目 + */ + @Override + public GameBettingDetails selectGameBettingDetailsById(Long id) + { + return gameBettingDetailsMapper.selectGameBettingDetailsById(id); + } + + /** + * 查询会员投注细目列表 + * + * @param gameBettingDetails 会员投注细目 + * @return 会员投注细目 + */ + @Override + public List selectGameBettingDetailsList(GameBettingDetails gameBettingDetails) + { + return gameBettingDetailsMapper.selectGameBettingDetailsList(gameBettingDetails); + } + + /** + * 新增会员投注细目 + * + * @param gameBettingDetails 会员投注细目 + * @return 结果 + */ + @Override + public int insertGameBettingDetails(GameBettingDetails gameBettingDetails) + { + gameBettingDetails.setCreateTime(DateUtils.getNowDate()); + return gameBettingDetailsMapper.insertGameBettingDetails(gameBettingDetails); + } + + /** + * 修改会员投注细目 + * + * @param gameBettingDetails 会员投注细目 + * @return 结果 + */ + @Override + public int updateGameBettingDetails(GameBettingDetails gameBettingDetails) + { + gameBettingDetails.setUpdateTime(DateUtils.getNowDate()); + return gameBettingDetailsMapper.updateGameBettingDetails(gameBettingDetails); + } + + /** + * 批量删除会员投注细目 + * + * @param ids 需要删除的会员投注细目主键 + * @return 结果 + */ + @Override + public int deleteGameBettingDetailsByIds(Long[] ids) + { + return gameBettingDetailsMapper.deleteGameBettingDetailsByIds(ids); + } + + /** + * 删除会员投注细目信息 + * + * @param id 会员投注细目主键 + * @return 结果 + */ + @Override + public int deleteGameBettingDetailsById(Long id) + { + return gameBettingDetailsMapper.deleteGameBettingDetailsById(id); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/service/impl/GameExchangeMoneyServiceImpl.java b/ff-admin/src/main/java/com/ff/game/service/impl/GameExchangeMoneyServiceImpl.java new file mode 100644 index 0000000..dc6559f --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/impl/GameExchangeMoneyServiceImpl.java @@ -0,0 +1,96 @@ +package com.ff.game.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.game.mapper.GameExchangeMoneyMapper; +import com.ff.game.domain.GameExchangeMoney; +import com.ff.game.service.IGameExchangeMoneyService; + +/** + * 会员金额转移记录Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class GameExchangeMoneyServiceImpl implements IGameExchangeMoneyService +{ + @Autowired + private GameExchangeMoneyMapper gameExchangeMoneyMapper; + + /** + * 查询会员金额转移记录 + * + * @param id 会员金额转移记录主键 + * @return 会员金额转移记录 + */ + @Override + public GameExchangeMoney selectGameExchangeMoneyById(Long id) + { + return gameExchangeMoneyMapper.selectGameExchangeMoneyById(id); + } + + /** + * 查询会员金额转移记录列表 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 会员金额转移记录 + */ + @Override + public List selectGameExchangeMoneyList(GameExchangeMoney gameExchangeMoney) + { + return gameExchangeMoneyMapper.selectGameExchangeMoneyList(gameExchangeMoney); + } + + /** + * 新增会员金额转移记录 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 结果 + */ + @Override + public int insertGameExchangeMoney(GameExchangeMoney gameExchangeMoney) + { + gameExchangeMoney.setCreateTime(DateUtils.getNowDate()); + return gameExchangeMoneyMapper.insertGameExchangeMoney(gameExchangeMoney); + } + + /** + * 修改会员金额转移记录 + * + * @param gameExchangeMoney 会员金额转移记录 + * @return 结果 + */ + @Override + public int updateGameExchangeMoney(GameExchangeMoney gameExchangeMoney) + { + gameExchangeMoney.setUpdateTime(DateUtils.getNowDate()); + return gameExchangeMoneyMapper.updateGameExchangeMoney(gameExchangeMoney); + } + + /** + * 批量删除会员金额转移记录 + * + * @param ids 需要删除的会员金额转移记录主键 + * @return 结果 + */ + @Override + public int deleteGameExchangeMoneyByIds(Long[] ids) + { + return gameExchangeMoneyMapper.deleteGameExchangeMoneyByIds(ids); + } + + /** + * 删除会员金额转移记录信息 + * + * @param id 会员金额转移记录主键 + * @return 结果 + */ + @Override + public int deleteGameExchangeMoneyById(Long id) + { + return gameExchangeMoneyMapper.deleteGameExchangeMoneyById(id); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/service/impl/GameFreeRecordServiceImpl.java b/ff-admin/src/main/java/com/ff/game/service/impl/GameFreeRecordServiceImpl.java new file mode 100644 index 0000000..039bc1e --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/impl/GameFreeRecordServiceImpl.java @@ -0,0 +1,96 @@ +package com.ff.game.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.game.mapper.GameFreeRecordMapper; +import com.ff.game.domain.GameFreeRecord; +import com.ff.game.service.IGameFreeRecordService; + +/** + * 免费赠送游戏记录Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class GameFreeRecordServiceImpl implements IGameFreeRecordService +{ + @Autowired + private GameFreeRecordMapper gameFreeRecordMapper; + + /** + * 查询免费赠送游戏记录 + * + * @param id 免费赠送游戏记录主键 + * @return 免费赠送游戏记录 + */ + @Override + public GameFreeRecord selectGameFreeRecordById(Long id) + { + return gameFreeRecordMapper.selectGameFreeRecordById(id); + } + + /** + * 查询免费赠送游戏记录列表 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 免费赠送游戏记录 + */ + @Override + public List selectGameFreeRecordList(GameFreeRecord gameFreeRecord) + { + return gameFreeRecordMapper.selectGameFreeRecordList(gameFreeRecord); + } + + /** + * 新增免费赠送游戏记录 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 结果 + */ + @Override + public int insertGameFreeRecord(GameFreeRecord gameFreeRecord) + { + gameFreeRecord.setCreateTime(DateUtils.getNowDate()); + return gameFreeRecordMapper.insertGameFreeRecord(gameFreeRecord); + } + + /** + * 修改免费赠送游戏记录 + * + * @param gameFreeRecord 免费赠送游戏记录 + * @return 结果 + */ + @Override + public int updateGameFreeRecord(GameFreeRecord gameFreeRecord) + { + gameFreeRecord.setUpdateTime(DateUtils.getNowDate()); + return gameFreeRecordMapper.updateGameFreeRecord(gameFreeRecord); + } + + /** + * 批量删除免费赠送游戏记录 + * + * @param ids 需要删除的免费赠送游戏记录主键 + * @return 结果 + */ + @Override + public int deleteGameFreeRecordByIds(Long[] ids) + { + return gameFreeRecordMapper.deleteGameFreeRecordByIds(ids); + } + + /** + * 删除免费赠送游戏记录信息 + * + * @param id 免费赠送游戏记录主键 + * @return 结果 + */ + @Override + public int deleteGameFreeRecordById(Long id) + { + return gameFreeRecordMapper.deleteGameFreeRecordById(id); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/service/impl/GamePlatformServiceImpl.java b/ff-admin/src/main/java/com/ff/game/service/impl/GamePlatformServiceImpl.java new file mode 100644 index 0000000..00471e3 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/impl/GamePlatformServiceImpl.java @@ -0,0 +1,108 @@ +package com.ff.game.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.game.mapper.GamePlatformMapper; +import com.ff.game.domain.GamePlatform; +import com.ff.game.service.IGamePlatformService; + +/** + * 平台管理Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class GamePlatformServiceImpl implements IGamePlatformService +{ + @Autowired + private GamePlatformMapper gamePlatformMapper; + + /** + * 查询平台管理 + * + * @param id 平台管理主键 + * @return 平台管理 + */ + @Override + public GamePlatform selectGamePlatformById(Long id) + { + return gamePlatformMapper.selectGamePlatformById(id); + } + + /** + * 查询平台管理列表 + * + * @param gamePlatform 平台管理 + * @return 平台管理 + */ + @Override + public List selectGamePlatformList(GamePlatform gamePlatform) + { + return gamePlatformMapper.selectGamePlatformList(gamePlatform); + } + + /** + * 新增平台管理 + * + * @param gamePlatform 平台管理 + * @return 结果 + */ + @Override + public int insertGamePlatform(GamePlatform gamePlatform) + { + gamePlatform.setCreateTime(DateUtils.getNowDate()); + return gamePlatformMapper.insertGamePlatform(gamePlatform); + } + + /** + * 修改平台管理 + * + * @param gamePlatform 平台管理 + * @return 结果 + */ + @Override + public int updateGamePlatform(GamePlatform gamePlatform) + { + gamePlatform.setUpdateTime(DateUtils.getNowDate()); + return gamePlatformMapper.updateGamePlatform(gamePlatform); + } + + /** + * 批量删除平台管理 + * + * @param ids 需要删除的平台管理主键 + * @return 结果 + */ + @Override + public int deleteGamePlatformByIds(Long[] ids) + { + return gamePlatformMapper.deleteGamePlatformByIds(ids); + } + + /** + * 删除平台管理信息 + * + * @param id 平台管理主键 + * @return 结果 + */ + @Override + public int deleteGamePlatformById(Long id) + { + return gamePlatformMapper.deleteGamePlatformById(id); + } + + + + /** + * 选择最大排序号 + * + * @return {@link Integer } + */ + @Override + public Integer selectMaxSortNo() { + return gamePlatformMapper.selectMaxSortNo(); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/service/impl/GameSecretKeyServiceImpl.java b/ff-admin/src/main/java/com/ff/game/service/impl/GameSecretKeyServiceImpl.java new file mode 100644 index 0000000..da84490 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/impl/GameSecretKeyServiceImpl.java @@ -0,0 +1,134 @@ +package com.ff.game.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import com.ff.common.domain.TenantSecretKey; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.game.mapper.GameSecretKeyMapper; +import com.ff.game.domain.GameSecretKey; +import com.ff.game.service.IGameSecretKeyService; + +/** + * 游戏平台密钥管理Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class GameSecretKeyServiceImpl implements IGameSecretKeyService +{ + @Autowired + private GameSecretKeyMapper gameSecretKeyMapper; + + /** + * 查询游戏平台密钥管理 + * + * @param id 游戏平台密钥管理主键 + * @return 游戏平台密钥管理 + */ + @Override + public GameSecretKey selectGameSecretKeyById(Long id) + { + return gameSecretKeyMapper.selectGameSecretKeyById(id); + } + + /** + * 查询游戏平台密钥管理列表 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 游戏平台密钥管理 + */ + @Override + public List selectGameSecretKeyList(GameSecretKey gameSecretKey) + { + return gameSecretKeyMapper.selectGameSecretKeyList(gameSecretKey); + } + + /** + * 新增游戏平台密钥管理 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 结果 + */ + @Override + public int insertGameSecretKey(GameSecretKey gameSecretKey) + { + gameSecretKey.setCreateTime(DateUtils.getNowDate()); + return gameSecretKeyMapper.insertGameSecretKey(gameSecretKey); + } + + /** + * 修改游戏平台密钥管理 + * + * @param gameSecretKey 游戏平台密钥管理 + * @return 结果 + */ + @Override + public int updateGameSecretKey(GameSecretKey gameSecretKey) + { + gameSecretKey.setUpdateTime(DateUtils.getNowDate()); + return gameSecretKeyMapper.updateGameSecretKey(gameSecretKey); + } + + /** + * 批量删除游戏平台密钥管理 + * + * @param ids 需要删除的游戏平台密钥管理主键 + * @return 结果 + */ + @Override + public int deleteGameSecretKeyByIds(Long[] ids) + { + return gameSecretKeyMapper.deleteGameSecretKeyByIds(ids); + } + + /** + * 删除游戏平台密钥管理信息 + * + * @param id 游戏平台密钥管理主键 + * @return 结果 + */ + @Override + public int deleteGameSecretKeyById(Long id) + { + return gameSecretKeyMapper.deleteGameSecretKeyById(id); + } + + + /** + * 按代码查找系统 + * + * @param code 代码 + * @param platform 平台 + * @return {@link String } + */ + @Override + public String findSystemByCode(String code,String platform) { + return gameSecretKeyMapper.findSystemByCode(code,platform); + } + + /** + * 通过平台和系统代码查找密钥 + * + * @param platform 平台 + * @param systemCode 系统代码 + * @return {@link GameSecretKey } + */ + @Override + public GameSecretKey findSecretKeyByPlatformAndSystemCode(String platform, String systemCode) { + return gameSecretKeyMapper.findSecretKeyByPlatformAndSystemCode(platform,systemCode); + } + + /** + * 按平台和系统查找lang代码 + * + * @param platform 平台 + * @param systemLangCode 系统语言代码 + * @return {@link GameSecretKey } + */ + @Override + public GameSecretKey findByPlatformAndSystemLangCode(String platform, String systemLangCode) { + return gameSecretKeyMapper.findByPlatformAndSystemLangCode(platform,systemLangCode); + } +} diff --git a/ff-admin/src/main/java/com/ff/game/service/impl/GameServiceImpl.java b/ff-admin/src/main/java/com/ff/game/service/impl/GameServiceImpl.java new file mode 100644 index 0000000..62c1a0b --- /dev/null +++ b/ff-admin/src/main/java/com/ff/game/service/impl/GameServiceImpl.java @@ -0,0 +1,132 @@ +package com.ff.game.service.impl; + +import java.util.List; + +import com.ff.base.constant.ConfigConstants; +import com.ff.base.utils.DateUtils; +import com.ff.game.api.request.GameUniqueDTO; +import com.ff.member.service.IMemberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.game.mapper.GameMapper; +import com.ff.game.domain.Game; +import com.ff.game.service.IGameService; + +import javax.annotation.Resource; + +/** + * 平台子游戏管理Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class GameServiceImpl implements IGameService +{ + @Autowired + private GameMapper gameMapper; + + @Resource + private IMemberService memberService; + + /** + * 查询平台子游戏管理 + * + * @param id 平台子游戏管理主键 + * @return 平台子游戏管理 + */ + @Override + public Game selectGameById(Long id) + { + return gameMapper.selectGameById(id); + } + + /** + * 查询平台子游戏管理列表 + * + * @param game 平台子游戏管理 + * @return 平台子游戏管理 + */ + @Override + public List selectGameList(Game game) + { + return gameMapper.selectGameList(game); + } + + /** + * 新增平台子游戏管理 + * + * @param game 平台子游戏管理 + * @return 结果 + */ + @Override + public int insertGame(Game game) + { + game.setCreateTime(DateUtils.getNowDate()); + return gameMapper.insertGame(game); + } + + /** + * 修改平台子游戏管理 + * + * @param game 平台子游戏管理 + * @return 结果 + */ + @Override + public int updateGame(Game game) + { + game.setUpdateTime(DateUtils.getNowDate()); + return gameMapper.updateGame(game); + } + + /** + * 批量删除平台子游戏管理 + * + * @param ids 需要删除的平台子游戏管理主键 + * @return 结果 + */ + @Override + public int deleteGameByIds(Long[] ids) + { + return gameMapper.deleteGameByIds(ids); + } + + /** + * 删除平台子游戏管理信息 + * + * @param id 平台子游戏管理主键 + * @return 结果 + */ + @Override + public int deleteGameById(Long id) + { + return gameMapper.deleteGameById(id); + } + + + /** + * 按平台id选择最大排序号 + * + * @param platformId 平台id + * @return {@link Integer } + */ + @Override + public Integer selectMaxSortNoByPlatformId(Long platformId) { + return gameMapper.selectMaxSortNoByPlatformId(platformId); + } + + + + /** + * 选择游戏唯一列表 + * + * @param gameUniqueDTO 游戏独有dto + * @return {@link List }<{@link Game }> + */ + @Override + public List selectGameUniqueList(GameUniqueDTO gameUniqueDTO) { + return gameMapper.selectGameUniqueList(gameUniqueDTO); + } + + +} diff --git a/ff-admin/src/main/java/com/ff/member/controller/MemberController.java b/ff-admin/src/main/java/com/ff/member/controller/MemberController.java new file mode 100644 index 0000000..03ff24a --- /dev/null +++ b/ff-admin/src/main/java/com/ff/member/controller/MemberController.java @@ -0,0 +1,104 @@ +package com.ff.member.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.member.domain.Member; +import com.ff.member.service.IMemberService; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 会员Controller + * + * @author shi + * @date 2025-02-10 + */ +@RestController +@RequestMapping("/member/member") +public class MemberController extends BaseController +{ + @Autowired + private IMemberService memberService; + + /** + * 查询会员列表 + */ + @PreAuthorize("@ss.hasPermi('member:member:list')") + @GetMapping("/list") + public TableDataInfo list(Member member) + { + startPage(); + List list = memberService.selectMemberList(member); + return getDataTable(list); + } + + /** + * 导出会员列表 + */ + @PreAuthorize("@ss.hasPermi('member:member:export')") + @Log(title = "会员", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, Member member) + { + List list = memberService.selectMemberList(member); + ExcelUtil util = new ExcelUtil(Member.class); + util.exportExcel(response, list, "会员数据"); + } + + /** + * 获取会员详细信息 + */ + @PreAuthorize("@ss.hasPermi('member:member:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(memberService.selectMemberById(id)); + } + + /** + * 新增会员 + */ + @PreAuthorize("@ss.hasPermi('member:member:add')") + @Log(title = "会员", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody Member member) + { + return toAjax(memberService.insertMember(member)); + } + + /** + * 修改会员 + */ + @PreAuthorize("@ss.hasPermi('member:member:edit')") + @Log(title = "会员", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody Member member) + { + return toAjax(memberService.updateMember(member)); + } + + /** + * 删除会员 + */ + @PreAuthorize("@ss.hasPermi('member:member:remove')") + @Log(title = "会员", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(memberService.deleteMemberByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/member/domain/Member.java b/ff-admin/src/main/java/com/ff/member/domain/Member.java new file mode 100644 index 0000000..3f271a2 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/member/domain/Member.java @@ -0,0 +1,48 @@ +package com.ff.member.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 会员对象 ff_member + * + * @author shi + * @date 2025-02-11 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Member extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 租户key */ + @Excel(name = "租户key") + private String tenantKey; + + /** 会员账号 */ + @Excel(name = "会员账号") + private String memberAccount; + + /** 游戏账号 */ + @Excel(name = "游戏账号") + private String gameAccount; + + /** 平台编码 */ + @Excel(name = "平台编码") + private String platformCode; + + /** 币种编码 */ + @Excel(name = "币种编码") + private String currencyCode; + + +} diff --git a/ff-admin/src/main/java/com/ff/member/mapper/MemberMapper.java b/ff-admin/src/main/java/com/ff/member/mapper/MemberMapper.java new file mode 100644 index 0000000..59989ab --- /dev/null +++ b/ff-admin/src/main/java/com/ff/member/mapper/MemberMapper.java @@ -0,0 +1,79 @@ +package com.ff.member.mapper; + +import java.util.List; +import com.ff.member.domain.Member; + +/** + * 会员Mapper接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface MemberMapper +{ + /** + * 查询会员 + * + * @param id 会员主键 + * @return 会员 + */ + Member selectMemberById(Long id); + + /** + * 查询会员列表 + * + * @param member 会员 + * @return 会员集合 + */ + List selectMemberList(Member member); + + /** + * 新增会员 + * + * @param member 会员 + * @return 结果 + */ + int insertMember(Member member); + + /** + * 修改会员 + * + * @param member 会员 + * @return 结果 + */ + int updateMember(Member member); + + /** + * 删除会员 + * + * @param id 会员主键 + * @return 结果 + */ + int deleteMemberById(Long id); + + /** + * 批量删除会员 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteMemberByIds(Long[] ids); + + + /** + * 按成员帐户选择成员 + * + * @param memberAccount 会员帐户 + * @return {@link Member } + */ + Member selectMemberByMemberAccount(String memberAccount); + + + /** + * 按游戏帐户选择成员 + * + * @param gameAccount 游戏账号 + * @return {@link Member } + */ + Member selectMemberByGameAccount(String gameAccount); +} diff --git a/ff-admin/src/main/java/com/ff/member/service/IMemberService.java b/ff-admin/src/main/java/com/ff/member/service/IMemberService.java new file mode 100644 index 0000000..5a9e2ff --- /dev/null +++ b/ff-admin/src/main/java/com/ff/member/service/IMemberService.java @@ -0,0 +1,77 @@ +package com.ff.member.service; + +import java.util.List; +import com.ff.member.domain.Member; + +/** + * 会员Service接口 + * + * @author shi + * @date 2025-02-10 + */ +public interface IMemberService +{ + /** + * 查询会员 + * + * @param id 会员主键 + * @return 会员 + */ + Member selectMemberById(Long id); + + /** + * 查询会员列表 + * + * @param member 会员 + * @return 会员集合 + */ + List selectMemberList(Member member); + + /** + * 新增会员 + * + * @param member 会员 + * @return 结果 + */ + int insertMember(Member member); + + /** + * 修改会员 + * + * @param member 会员 + * @return 结果 + */ + int updateMember(Member member); + + /** + * 批量删除会员 + * + * @param ids 需要删除的会员主键集合 + * @return 结果 + */ + int deleteMemberByIds(Long[] ids); + + /** + * 删除会员信息 + * + * @param id 会员主键 + * @return 结果 + */ + int deleteMemberById(Long id); + + /** + * 按成员帐户选择成员 + * + * @param memberAccount 会员帐户 + * @return {@link Member } + */ + Member selectMemberByMemberAccount(String memberAccount); + + /** + * 按游戏帐户选择成员 + * + * @param gameAccount 游戏账号 + * @return {@link Member } + */ + Member selectMemberByGameAccount(String gameAccount); +} diff --git a/ff-admin/src/main/java/com/ff/member/service/impl/MemberServiceImpl.java b/ff-admin/src/main/java/com/ff/member/service/impl/MemberServiceImpl.java new file mode 100644 index 0000000..c8985ad --- /dev/null +++ b/ff-admin/src/main/java/com/ff/member/service/impl/MemberServiceImpl.java @@ -0,0 +1,119 @@ +package com.ff.member.service.impl; + +import java.util.List; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ff.member.mapper.MemberMapper; +import com.ff.member.domain.Member; +import com.ff.member.service.IMemberService; + +/** + * 会员Service业务层处理 + * + * @author shi + * @date 2025-02-10 + */ +@Service +public class MemberServiceImpl implements IMemberService +{ + @Autowired + private MemberMapper memberMapper; + + /** + * 查询会员 + * + * @param id 会员主键 + * @return 会员 + */ + @Override + public Member selectMemberById(Long id) + { + return memberMapper.selectMemberById(id); + } + + /** + * 查询会员列表 + * + * @param member 会员 + * @return 会员 + */ + @Override + public List selectMemberList(Member member) + { + return memberMapper.selectMemberList(member); + } + + /** + * 新增会员 + * + * @param member 会员 + * @return 结果 + */ + @Override + public int insertMember(Member member) + { + member.setCreateTime(DateUtils.getNowDate()); + return memberMapper.insertMember(member); + } + + /** + * 修改会员 + * + * @param member 会员 + * @return 结果 + */ + @Override + public int updateMember(Member member) + { + member.setUpdateTime(DateUtils.getNowDate()); + return memberMapper.updateMember(member); + } + + /** + * 批量删除会员 + * + * @param ids 需要删除的会员主键 + * @return 结果 + */ + @Override + public int deleteMemberByIds(Long[] ids) + { + return memberMapper.deleteMemberByIds(ids); + } + + /** + * 删除会员信息 + * + * @param id 会员主键 + * @return 结果 + */ + @Override + public int deleteMemberById(Long id) + { + return memberMapper.deleteMemberById(id); + } + + + /** + * 按成员帐户选择成员 + * + * @param memberAccount 会员帐户 + * @return {@link Member } + */ + @Override + public Member selectMemberByMemberAccount(String memberAccount) { + return memberMapper.selectMemberByMemberAccount(memberAccount); + } + + /** + * 按游戏帐户选择成员 + * + * @param gameAccount 游戏账号 + * @return {@link Member } + */ + @Override + public Member selectMemberByGameAccount(String gameAccount) { + return memberMapper.selectMemberByGameAccount(gameAccount); + } +} diff --git a/ff-admin/src/main/java/com/ff/monitor/SysLogininforController.java b/ff-admin/src/main/java/com/ff/monitor/SysLogininforController.java new file mode 100644 index 0000000..00954c7 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/monitor/SysLogininforController.java @@ -0,0 +1,78 @@ +package com.ff.monitor; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.web.service.SysPasswordService; +import com.ff.base.system.domain.SysLogininfor; +import com.ff.base.system.service.ISysLogininforService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 系统访问记录 + * + * @author ff + */ +@RestController +@RequestMapping("/monitor/logininfor") +public class SysLogininforController extends BaseController +{ + @Autowired + private ISysLogininforService logininforService; + + @Autowired + private SysPasswordService passwordService; + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')") + @GetMapping("/list") + public TableDataInfo list(SysLogininfor logininfor) + { + startPage(); + List list = logininforService.selectLogininforList(logininfor); + return getDataTable(list); + } + + @Log(title = "登录日志", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysLogininfor logininfor) + { + List list = logininforService.selectLogininforList(logininfor); + ExcelUtil util = new ExcelUtil(SysLogininfor.class); + util.exportExcel(response, list, "登录日志"); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @Log(title = "登录日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{infoIds}") + public AjaxResult remove(@PathVariable Long[] infoIds) + { + return toAjax(logininforService.deleteLogininforByIds(infoIds)); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @Log(title = "登录日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + logininforService.cleanLogininfor(); + return success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')") + @Log(title = "账户解锁", businessType = BusinessType.OTHER) + @GetMapping("/unlock/{userName}") + public AjaxResult unlock(@PathVariable("userName") String userName) + { + passwordService.clearLoginRecordCache(userName); + return success(); + } +} diff --git a/ff-admin/src/main/java/com/ff/monitor/SysOperlogController.java b/ff-admin/src/main/java/com/ff/monitor/SysOperlogController.java new file mode 100644 index 0000000..dd08069 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/monitor/SysOperlogController.java @@ -0,0 +1,65 @@ +package com.ff.monitor; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.system.domain.SysOperLog; +import com.ff.base.system.service.ISysOperLogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 操作日志记录 + * + * @author ff + */ +@RestController +@RequestMapping("/monitor/operlog") +public class SysOperlogController extends BaseController +{ + @Autowired + private ISysOperLogService operLogService; + + @PreAuthorize("@ss.hasPermi('monitor:operlog:list')") + @GetMapping("/list") + public TableDataInfo list(SysOperLog operLog) + { + startPage(); + List list = operLogService.selectOperLogList(operLog); + return getDataTable(list); + } + + @Log(title = "操作日志", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:operlog:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysOperLog operLog) + { + List list = operLogService.selectOperLogList(operLog); + ExcelUtil util = new ExcelUtil(SysOperLog.class); + util.exportExcel(response, list, "操作日志"); + } + + @Log(title = "操作日志", businessType = BusinessType.DELETE) + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @DeleteMapping("/{operIds}") + public AjaxResult remove(@PathVariable Long[] operIds) + { + return toAjax(operLogService.deleteOperLogByIds(operIds)); + } + + @Log(title = "操作日志", businessType = BusinessType.CLEAN) + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @DeleteMapping("/clean") + public AjaxResult clean() + { + operLogService.cleanOperLog(); + return success(); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/config/ScheduleConfig.java b/ff-admin/src/main/java/com/ff/quartz/config/ScheduleConfig.java new file mode 100644 index 0000000..c56e1bc --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/config/ScheduleConfig.java @@ -0,0 +1,57 @@ +package com.ff.quartz.config;//package com.ff.quartz.config; +// +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.scheduling.quartz.SchedulerFactoryBean; +//import javax.sql.DataSource; +//import java.util.Properties; +// +///** +// * 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效) +// * +// * @author ff +// */ +//@Configuration +//public class ScheduleConfig +//{ +// @Bean +// public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) +// { +// SchedulerFactoryBean factory = new SchedulerFactoryBean(); +// factory.setDataSource(dataSource); +// +// // quartz参数 +// Properties prop = new Properties(); +// prop.put("org.quartz.scheduler.instanceName", "ffScheduler"); +// prop.put("org.quartz.scheduler.instanceId", "AUTO"); +// // 线程池配置 +// prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); +// prop.put("org.quartz.threadPool.threadCount", "20"); +// prop.put("org.quartz.threadPool.threadPriority", "5"); +// // JobStore配置 +// prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); +// // 集群配置 +// prop.put("org.quartz.jobStore.isClustered", "true"); +// prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); +// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "10"); +// prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); +// +// // sqlserver 启用 +// // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); +// prop.put("org.quartz.jobStore.misfireThreshold", "12000"); +// prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); +// factory.setQuartzProperties(prop); +// +// factory.setSchedulerName("ffScheduler"); +// // 延时启动 +// factory.setStartupDelay(1); +// factory.setApplicationContextSchedulerContextKey("applicationContextKey"); +// // 可选,QuartzScheduler +// // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 +// factory.setOverwriteExistingJobs(true); +// // 设置自动启动,默认为true +// factory.setAutoStartup(true); +// +// return factory; +// } +//} diff --git a/ff-admin/src/main/java/com/ff/quartz/controller/SysJobController.java b/ff-admin/src/main/java/com/ff/quartz/controller/SysJobController.java new file mode 100644 index 0000000..fe850b4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/controller/SysJobController.java @@ -0,0 +1,179 @@ +package com.ff.quartz.controller; + +import com.ff.base.annotation.Log; +import com.ff.base.constant.Constants; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.exception.job.TaskException; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.quartz.domain.SysJob; +import com.ff.quartz.service.ISysJobService; +import com.ff.quartz.util.CronUtils; +import com.ff.quartz.util.ScheduleUtils; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 调度任务信息操作处理 + * + * @author ff + */ +@RestController +@RequestMapping("/monitor/job") +public class SysJobController extends BaseController +{ + @Autowired + private ISysJobService jobService; + + /** + * 查询定时任务列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:list')") + @GetMapping("/list") + public TableDataInfo list(SysJob sysJob) + { + startPage(); + List list = jobService.selectJobList(sysJob); + return getDataTable(list); + } + + /** + * 导出定时任务列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:export')") + @Log(title = "定时任务", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJob sysJob) + { + List list = jobService.selectJobList(sysJob); + ExcelUtil util = new ExcelUtil(SysJob.class); + util.exportExcel(response, list, "定时任务"); + } + + /** + * 获取定时任务详细信息 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:query')") + @GetMapping(value = "/{jobId}") + public AjaxResult getInfo(@PathVariable("jobId") Long jobId) + { + return success(jobService.selectJobById(jobId)); + } + + /** + * 新增定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:add')") + @Log(title = "定时任务", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("新增任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setCreateBy(getUsername()); + return toAjax(jobService.insertJob(job)); + } + + /** + * 修改定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:edit')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("修改任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setUpdateBy(getUsername()); + return toAjax(jobService.updateJob(job)); + } + + /** + * 定时任务状态修改 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException + { + SysJob newJob = jobService.selectJobById(job.getJobId()); + newJob.setStatus(job.getStatus()); + return toAjax(jobService.changeStatus(newJob)); + } + + /** + * 定时任务立即执行一次 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/run") + public AjaxResult run(@RequestBody SysJob job) throws SchedulerException + { + boolean result = jobService.run(job); + return result ? success() : error("任务不存在或已过期!"); + } + + /** + * 删除定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "定时任务", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobIds}") + public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException + { + jobService.deleteJobByIds(jobIds); + return success(); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/controller/SysJobLogController.java b/ff-admin/src/main/java/com/ff/quartz/controller/SysJobLogController.java new file mode 100644 index 0000000..2ea8a1e --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/controller/SysJobLogController.java @@ -0,0 +1,88 @@ +package com.ff.quartz.controller; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.quartz.domain.SysJobLog; +import com.ff.quartz.service.ISysJobLogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 调度日志操作处理 + * + * @author ff + */ +@RestController +@RequestMapping("/monitor/jobLog") +public class SysJobLogController extends BaseController +{ + @Autowired + private ISysJobLogService jobLogService; + + /** + * 查询定时任务调度日志列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:list')") + @GetMapping("/list") + public TableDataInfo list(SysJobLog sysJobLog) + { + startPage(); + List list = jobLogService.selectJobLogList(sysJobLog); + return getDataTable(list); + } + + /** + * 导出定时任务调度日志列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:export')") + @Log(title = "任务调度日志", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJobLog sysJobLog) + { + List list = jobLogService.selectJobLogList(sysJobLog); + ExcelUtil util = new ExcelUtil(SysJobLog.class); + util.exportExcel(response, list, "调度日志"); + } + + /** + * 根据调度编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:query')") + @GetMapping(value = "/{jobLogId}") + public AjaxResult getInfo(@PathVariable Long jobLogId) + { + return success(jobLogService.selectJobLogById(jobLogId)); + } + + + /** + * 删除定时任务调度日志 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "定时任务调度日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobLogIds}") + public AjaxResult remove(@PathVariable Long[] jobLogIds) + { + return toAjax(jobLogService.deleteJobLogByIds(jobLogIds)); + } + + /** + * 清空定时任务调度日志 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "调度日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + jobLogService.cleanJobLog(); + return success(); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/domain/SysJob.java b/ff-admin/src/main/java/com/ff/quartz/domain/SysJob.java new file mode 100644 index 0000000..7e8451b --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/domain/SysJob.java @@ -0,0 +1,172 @@ +package com.ff.quartz.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ff.base.annotation.Excel; +import com.ff.base.annotation.Excel.ColumnType; +import com.ff.base.constant.ScheduleConstants; +import com.ff.base.core.domain.BaseEntity; +import com.ff.base.utils.StringUtils; +import com.ff.quartz.util.CronUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.util.Date; + +/** + * 定时任务调度表 sys_job + * + * @author ff + */ +public class SysJob extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 任务ID */ + @Excel(name = "任务序号", cellType = ColumnType.NUMERIC) + private Long jobId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** cron执行表达式 */ + @Excel(name = "执行表达式 ") + private String cronExpression; + + /** cron计划策略 */ + @Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行") + private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT; + + /** 是否并发执行(0允许 1禁止) */ + @Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止") + private String concurrent; + + /** 任务状态(0正常 1暂停) */ + @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停") + private String status; + + public Long getJobId() + { + return jobId; + } + + public void setJobId(Long jobId) + { + this.jobId = jobId; + } + + @NotBlank(message = "任务名称不能为空") + @Size(min = 0, max = 64, message = "任务名称不能超过64个字符") + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + @NotBlank(message = "调用目标字符串不能为空") + @Size(min = 0, max = 500, message = "调用目标字符串长度不能超过500个字符") + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + @NotBlank(message = "Cron执行表达式不能为空") + @Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符") + public String getCronExpression() + { + return cronExpression; + } + + public void setCronExpression(String cronExpression) + { + this.cronExpression = cronExpression; + } + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + public Date getNextValidTime() + { + if (StringUtils.isNotEmpty(cronExpression)) + { + return CronUtils.getNextExecution(cronExpression); + } + return null; + } + + public String getMisfirePolicy() + { + return misfirePolicy; + } + + public void setMisfirePolicy(String misfirePolicy) + { + this.misfirePolicy = misfirePolicy; + } + + public String getConcurrent() + { + return concurrent; + } + + public void setConcurrent(String concurrent) + { + this.concurrent = concurrent; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("jobId", getJobId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("cronExpression", getCronExpression()) + .append("nextValidTime", getNextValidTime()) + .append("misfirePolicy", getMisfirePolicy()) + .append("concurrent", getConcurrent()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/domain/SysJobLog.java b/ff-admin/src/main/java/com/ff/quartz/domain/SysJobLog.java new file mode 100644 index 0000000..cd08116 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/domain/SysJobLog.java @@ -0,0 +1,156 @@ +package com.ff.quartz.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 定时任务调度日志表 sys_job_log + * + * @author ff + */ +public class SysJobLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Excel(name = "日志序号") + private Long jobLogId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** 日志信息 */ + @Excel(name = "日志信息") + private String jobMessage; + + /** 执行状态(0正常 1失败) */ + @Excel(name = "执行状态", readConverterExp = "0=正常,1=失败") + private String status; + + /** 异常信息 */ + @Excel(name = "异常信息") + private String exceptionInfo; + + /** 开始时间 */ + private Date startTime; + + /** 停止时间 */ + private Date stopTime; + + public Long getJobLogId() + { + return jobLogId; + } + + public void setJobLogId(Long jobLogId) + { + this.jobLogId = jobLogId; + } + + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + public String getJobMessage() + { + return jobMessage; + } + + public void setJobMessage(String jobMessage) + { + this.jobMessage = jobMessage; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getExceptionInfo() + { + return exceptionInfo; + } + + public void setExceptionInfo(String exceptionInfo) + { + this.exceptionInfo = exceptionInfo; + } + + public Date getStartTime() + { + return startTime; + } + + public void setStartTime(Date startTime) + { + this.startTime = startTime; + } + + public Date getStopTime() + { + return stopTime; + } + + public void setStopTime(Date stopTime) + { + this.stopTime = stopTime; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("jobLogId", getJobLogId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("jobMessage", getJobMessage()) + .append("status", getStatus()) + .append("exceptionInfo", getExceptionInfo()) + .append("startTime", getStartTime()) + .append("stopTime", getStopTime()) + .toString(); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/mapper/SysJobLogMapper.java b/ff-admin/src/main/java/com/ff/quartz/mapper/SysJobLogMapper.java new file mode 100644 index 0000000..86c9fb4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/mapper/SysJobLogMapper.java @@ -0,0 +1,65 @@ +package com.ff.quartz.mapper; + +import com.ff.quartz.domain.SysJobLog; + +import java.util.List; + +/** + * 调度任务日志信息 数据层 + * + * @author ff + */ +public interface SysJobLogMapper +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 查询所有调度任务日志 + * + * @return 调度任务日志列表 + */ + public List selectJobLogAll(); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + * @return 结果 + */ + public int insertJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); +} diff --git a/ff-admin/src/main/java/com/ff/quartz/mapper/SysJobMapper.java b/ff-admin/src/main/java/com/ff/quartz/mapper/SysJobMapper.java new file mode 100644 index 0000000..3aac4d2 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/mapper/SysJobMapper.java @@ -0,0 +1,68 @@ +package com.ff.quartz.mapper; + +import com.ff.quartz.domain.SysJob; + +import java.util.List; + +/** + * 调度任务信息 数据层 + * + * @author ff + */ +public interface SysJobMapper +{ + /** + * 查询调度任务日志集合 + * + * @param job 调度信息 + * @return 操作日志集合 + */ + public List selectJobList(SysJob job); + + /** + * 查询所有调度任务 + * + * @return 调度任务列表 + */ + public List selectJobAll(); + + /** + * 通过调度ID查询调度任务信息 + * + * @param jobId 调度ID + * @return 角色对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 通过调度ID删除调度任务信息 + * + * @param jobId 调度ID + * @return 结果 + */ + public int deleteJobById(Long jobId); + + /** + * 批量删除调度任务信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteJobByIds(Long[] ids); + + /** + * 修改调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int updateJob(SysJob job); + + /** + * 新增调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int insertJob(SysJob job); +} diff --git a/ff-admin/src/main/java/com/ff/quartz/service/ISysJobLogService.java b/ff-admin/src/main/java/com/ff/quartz/service/ISysJobLogService.java new file mode 100644 index 0000000..fc43da0 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/service/ISysJobLogService.java @@ -0,0 +1,57 @@ +package com.ff.quartz.service; + +import com.ff.quartz.domain.SysJobLog; + +import java.util.List; + +/** + * 定时任务调度日志信息信息 服务层 + * + * @author ff + */ +public interface ISysJobLogService +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + public void addJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的日志ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); +} diff --git a/ff-admin/src/main/java/com/ff/quartz/service/ISysJobService.java b/ff-admin/src/main/java/com/ff/quartz/service/ISysJobService.java new file mode 100644 index 0000000..374d375 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/service/ISysJobService.java @@ -0,0 +1,103 @@ +package com.ff.quartz.service; + +import com.ff.base.exception.job.TaskException; +import com.ff.quartz.domain.SysJob; +import org.quartz.SchedulerException; + +import java.util.List; + +/** + * 定时任务调度信息信息 服务层 + * + * @author ff + */ +public interface ISysJobService +{ + /** + * 获取quartz调度器的计划任务 + * + * @param job 调度信息 + * @return 调度任务集合 + */ + public List selectJobList(SysJob job); + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 暂停任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int pauseJob(SysJob job) throws SchedulerException; + + /** + * 恢复任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int resumeJob(SysJob job) throws SchedulerException; + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + * @return 结果 + */ + public int deleteJob(SysJob job) throws SchedulerException; + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + public void deleteJobByIds(Long[] jobIds) throws SchedulerException; + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + * @return 结果 + */ + public int changeStatus(SysJob job) throws SchedulerException; + + /** + * 立即运行任务 + * + * @param job 调度信息 + * @return 结果 + */ + public boolean run(SysJob job) throws SchedulerException; + + /** + * 新增任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int insertJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 更新任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int updateJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + public boolean checkCronExpressionIsValid(String cronExpression); +} diff --git a/ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobLogServiceImpl.java b/ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobLogServiceImpl.java new file mode 100644 index 0000000..0b951ec --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobLogServiceImpl.java @@ -0,0 +1,88 @@ +package com.ff.quartz.service.impl; + +import com.ff.quartz.domain.SysJobLog; +import com.ff.quartz.mapper.SysJobLogMapper; +import com.ff.quartz.service.ISysJobLogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 定时任务调度日志信息 服务层 + * + * @author ff + */ +@Service +public class SysJobLogServiceImpl implements ISysJobLogService +{ + @Autowired + private SysJobLogMapper jobLogMapper; + + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + @Override + public List selectJobLogList(SysJobLog jobLog) + { + return jobLogMapper.selectJobLogList(jobLog); + } + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + @Override + public SysJobLog selectJobLogById(Long jobLogId) + { + return jobLogMapper.selectJobLogById(jobLogId); + } + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + @Override + public void addJobLog(SysJobLog jobLog) + { + jobLogMapper.insertJobLog(jobLog); + } + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteJobLogByIds(Long[] logIds) + { + return jobLogMapper.deleteJobLogByIds(logIds); + } + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + */ + @Override + public int deleteJobLogById(Long jobId) + { + return jobLogMapper.deleteJobLogById(jobId); + } + + /** + * 清空任务日志 + */ + @Override + public void cleanJobLog() + { + jobLogMapper.cleanJobLog(); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobServiceImpl.java b/ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobServiceImpl.java new file mode 100644 index 0000000..5e14476 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/service/impl/SysJobServiceImpl.java @@ -0,0 +1,262 @@ +package com.ff.quartz.service.impl; + +import com.ff.base.constant.ScheduleConstants; +import com.ff.base.exception.job.TaskException; +import com.ff.quartz.domain.SysJob; +import com.ff.quartz.mapper.SysJobMapper; +import com.ff.quartz.service.ISysJobService; +import com.ff.quartz.util.CronUtils; +import com.ff.quartz.util.ScheduleUtils; +import org.quartz.JobDataMap; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.PostConstruct; +import java.util.List; + +/** + * 定时任务调度信息 服务层 + * + * @author ff + */ +@Service +public class SysJobServiceImpl implements ISysJobService +{ + @Autowired + private Scheduler scheduler; + + @Autowired + private SysJobMapper jobMapper; + + /** + * 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据) + */ + @PostConstruct + public void init() throws SchedulerException, TaskException + { + scheduler.clear(); + List jobList = jobMapper.selectJobAll(); + for (SysJob job : jobList) + { + ScheduleUtils.createScheduleJob(scheduler, job); + } + } + + /** + * 获取quartz调度器的计划任务列表 + * + * @param job 调度信息 + * @return + */ + @Override + public List selectJobList(SysJob job) + { + return jobMapper.selectJobList(job); + } + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + @Override + public SysJob selectJobById(Long jobId) + { + return jobMapper.selectJobById(jobId); + } + + /** + * 暂停任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int pauseJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 恢复任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int resumeJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.NORMAL.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + int rows = jobMapper.deleteJobById(jobId); + if (rows > 0) + { + scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteJobByIds(Long[] jobIds) throws SchedulerException + { + for (Long jobId : jobIds) + { + SysJob job = jobMapper.selectJobById(jobId); + deleteJob(job); + } + } + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int changeStatus(SysJob job) throws SchedulerException + { + int rows = 0; + String status = job.getStatus(); + if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) + { + rows = resumeJob(job); + } + else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) + { + rows = pauseJob(job); + } + return rows; + } + + /** + * 立即运行任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean run(SysJob job) throws SchedulerException + { + boolean result = false; + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + SysJob properties = selectJobById(job.getJobId()); + // 参数 + JobDataMap dataMap = new JobDataMap(); + dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties); + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + result = true; + scheduler.triggerJob(jobKey, dataMap); + } + return result; + } + + /** + * 新增任务 + * + * @param job 调度信息 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int insertJob(SysJob job) throws SchedulerException, TaskException + { + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.insertJob(job); + if (rows > 0) + { + ScheduleUtils.createScheduleJob(scheduler, job); + } + return rows; + } + + /** + * 更新任务的时间表达式 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateJob(SysJob job) throws SchedulerException, TaskException + { + SysJob properties = selectJobById(job.getJobId()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + updateSchedulerJob(job, properties.getJobGroup()); + } + return rows; + } + + /** + * 更新任务 + * + * @param job 任务对象 + * @param jobGroup 任务组名 + */ + public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException + { + Long jobId = job.getJobId(); + // 判断是否存在 + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(jobKey); + } + ScheduleUtils.createScheduleJob(scheduler, job); + } + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + @Override + public boolean checkCronExpressionIsValid(String cronExpression) + { + return CronUtils.isValid(cronExpression); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/task/RyTask.java b/ff-admin/src/main/java/com/ff/quartz/task/RyTask.java new file mode 100644 index 0000000..2253a81 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/task/RyTask.java @@ -0,0 +1,34 @@ +package com.ff.quartz.task; + +import com.ff.base.datasource.DynamicDataSourceContextHolder; +import com.ff.base.utils.StringUtils; +import org.springframework.stereotype.Component; + +import javax.sql.DataSource; +import java.util.Map; + +/** + * 定时任务调度测试 + * + * @author ff + */ +@Component("ryTask") +public class RyTask { + public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) { + System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); + } + + public void ryParams(String params) { + System.out.println("执行有参方法:" + params); + } + + public void ryNoParams() { + Map resolvedDataSources = DynamicDataSourceContextHolder.getAllDataSource(); + for (Map.Entry entry : resolvedDataSources.entrySet()) { + Object key = entry.getKey(); + // 设置数据源类型 + DynamicDataSourceContextHolder.setDataSourceType(key.toString()); + System.out.println("执行无参方法"); + } + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/util/AbstractQuartzJob.java b/ff-admin/src/main/java/com/ff/quartz/util/AbstractQuartzJob.java new file mode 100644 index 0000000..e53fcf7 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/util/AbstractQuartzJob.java @@ -0,0 +1,100 @@ +package com.ff.quartz.util; + +import com.ff.base.constant.Constants; +import com.ff.base.constant.ScheduleConstants; +import com.ff.base.datasource.DynamicDataSourceContextHolder; +import com.ff.base.utils.ExceptionUtil; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.bean.BeanUtils; +import com.ff.base.utils.spring.SpringUtils; +import com.ff.quartz.domain.SysJob; +import com.ff.quartz.domain.SysJobLog; +import com.ff.quartz.service.ISysJobLogService; +import org.quartz.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +import javax.sql.DataSource; +import java.util.Date; +import java.util.Map; + +/** + * 抽象quartz调用 + * + * @author ff + */ +public abstract class AbstractQuartzJob implements Job { + private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class); + + /** + * 线程本地变量 + */ + private static ThreadLocal threadLocal = new ThreadLocal<>(); + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + SysJob sysJob = new SysJob(); + BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); + try { + before(context, sysJob); + if (sysJob != null) { + doExecute(context, sysJob); + } + after(context, sysJob, null); + } catch (Exception e) { + log.error("任务执行异常 - :", e); + after(context, sysJob, e); + } + + } + + /** + * 执行前 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void before(JobExecutionContext context, SysJob sysJob) { + threadLocal.set(new Date()); + } + + /** + * 执行后 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void after(JobExecutionContext context, SysJob sysJob, Exception e) { + Date startTime = threadLocal.get(); + threadLocal.remove(); + + final SysJobLog sysJobLog = new SysJobLog(); + sysJobLog.setJobName(sysJob.getJobName()); + sysJobLog.setJobGroup(sysJob.getJobGroup()); + sysJobLog.setInvokeTarget(sysJob.getInvokeTarget()); + sysJobLog.setStartTime(startTime); + sysJobLog.setStopTime(new Date()); + long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime(); + sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒"); + if (e != null) { + sysJobLog.setStatus(Constants.FAIL); + String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000); + sysJobLog.setExceptionInfo(errorMsg); + } else { + sysJobLog.setStatus(Constants.SUCCESS); + } + + // 写入数据库当中 + SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog); + } + + /** + * 执行方法,由子类重载 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + * @throws Exception 执行过程中的异常 + */ + protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception; +} diff --git a/ff-admin/src/main/java/com/ff/quartz/util/CronUtils.java b/ff-admin/src/main/java/com/ff/quartz/util/CronUtils.java new file mode 100644 index 0000000..d550083 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/util/CronUtils.java @@ -0,0 +1,64 @@ +package com.ff.quartz.util; + +import org.quartz.CronExpression; + +import java.text.ParseException; +import java.util.Date; + +/** + * cron表达式工具类 + * + * @author ff + * + */ +public class CronUtils +{ + /** + * 返回一个布尔值代表一个给定的Cron表达式的有效性 + * + * @param cronExpression Cron表达式 + * @return boolean 表达式是否有效 + */ + public static boolean isValid(String cronExpression) + { + return CronExpression.isValidExpression(cronExpression); + } + + /** + * 返回一个字符串值,表示该消息无效Cron表达式给出有效性 + * + * @param cronExpression Cron表达式 + * @return String 无效时返回表达式错误描述,如果有效返回null + */ + public static String getInvalidMessage(String cronExpression) + { + try + { + new CronExpression(cronExpression); + return null; + } + catch (ParseException pe) + { + return pe.getMessage(); + } + } + + /** + * 返回下一个执行时间根据给定的Cron表达式 + * + * @param cronExpression Cron表达式 + * @return Long 下次Cron表达式执行时间 + */ + public static Date getNextExecution(String cronExpression) + { + try + { + CronExpression cron = new CronExpression(cronExpression); + return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis())); + } + catch (ParseException e) + { + throw new IllegalArgumentException(e.getMessage()); + } + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/util/JobInvokeUtil.java b/ff-admin/src/main/java/com/ff/quartz/util/JobInvokeUtil.java new file mode 100644 index 0000000..7403739 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/util/JobInvokeUtil.java @@ -0,0 +1,183 @@ +package com.ff.quartz.util; + +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.spring.SpringUtils; +import com.ff.quartz.domain.SysJob; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.List; + +/** + * 任务执行工具 + * + * @author ff + */ +public class JobInvokeUtil +{ + /** + * 执行方法 + * + * @param sysJob 系统任务 + */ + public static void invokeMethod(SysJob sysJob) throws Exception + { + String invokeTarget = sysJob.getInvokeTarget(); + String beanName = getBeanName(invokeTarget); + String methodName = getMethodName(invokeTarget); + List methodParams = getMethodParams(invokeTarget); + + if (!isValidClassName(beanName)) + { + Object bean = SpringUtils.getBean(beanName); + invokeMethod(bean, methodName, methodParams); + } + else + { + Object bean = Class.forName(beanName).getDeclaredConstructor().newInstance(); + invokeMethod(bean, methodName, methodParams); + } + } + + /** + * 调用任务方法 + * + * @param bean 目标对象 + * @param methodName 方法名称 + * @param methodParams 方法参数 + */ + private static void invokeMethod(Object bean, String methodName, List methodParams) + throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException + { + if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) + { + Method method = bean.getClass().getMethod(methodName, getMethodParamsType(methodParams)); + method.invoke(bean, getMethodParamsValue(methodParams)); + } + else + { + Method method = bean.getClass().getMethod(methodName); + method.invoke(bean); + } + } + + /** + * 校验是否为为class包名 + * + * @param invokeTarget 名称 + * @return true是 false否 + */ + public static boolean isValidClassName(String invokeTarget) + { + return StringUtils.countMatches(invokeTarget, ".") > 1; + } + + /** + * 获取bean名称 + * + * @param invokeTarget 目标字符串 + * @return bean名称 + */ + public static String getBeanName(String invokeTarget) + { + String beanName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringBeforeLast(beanName, "."); + } + + /** + * 获取bean方法 + * + * @param invokeTarget 目标字符串 + * @return method方法 + */ + public static String getMethodName(String invokeTarget) + { + String methodName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringAfterLast(methodName, "."); + } + + /** + * 获取method方法参数相关列表 + * + * @param invokeTarget 目标字符串 + * @return method方法相关参数列表 + */ + public static List getMethodParams(String invokeTarget) + { + String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")"); + if (StringUtils.isEmpty(methodStr)) + { + return null; + } + String[] methodParams = methodStr.split(",(?=([^\"']*[\"'][^\"']*[\"'])*[^\"']*$)"); + List classs = new LinkedList<>(); + for (int i = 0; i < methodParams.length; i++) + { + String str = StringUtils.trimToEmpty(methodParams[i]); + // String字符串类型,以'或"开头 + if (StringUtils.startsWithAny(str, "'", "\"")) + { + classs.add(new Object[] { StringUtils.substring(str, 1, str.length() - 1), String.class }); + } + // boolean布尔类型,等于true或者false + else if ("true".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str)) + { + classs.add(new Object[] { Boolean.valueOf(str), Boolean.class }); + } + // long长整形,以L结尾 + else if (StringUtils.endsWith(str, "L")) + { + classs.add(new Object[] { Long.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Long.class }); + } + // double浮点类型,以D结尾 + else if (StringUtils.endsWith(str, "D")) + { + classs.add(new Object[] { Double.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Double.class }); + } + // 其他类型归类为整形 + else + { + classs.add(new Object[] { Integer.valueOf(str), Integer.class }); + } + } + return classs; + } + + /** + * 获取参数类型 + * + * @param methodParams 参数相关列表 + * @return 参数类型列表 + */ + public static Class[] getMethodParamsType(List methodParams) + { + Class[] classs = new Class[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Class) os[1]; + index++; + } + return classs; + } + + /** + * 获取参数值 + * + * @param methodParams 参数相关列表 + * @return 参数值列表 + */ + public static Object[] getMethodParamsValue(List methodParams) + { + Object[] classs = new Object[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Object) os[0]; + index++; + } + return classs; + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/util/QuartzDisallowConcurrentExecution.java b/ff-admin/src/main/java/com/ff/quartz/util/QuartzDisallowConcurrentExecution.java new file mode 100644 index 0000000..5ec7ff5 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/util/QuartzDisallowConcurrentExecution.java @@ -0,0 +1,23 @@ +package com.ff.quartz.util; + +import com.ff.quartz.domain.SysJob; +import com.ff.quartz.util.AbstractQuartzJob; +import com.ff.quartz.util.JobInvokeUtil; +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; + +/** + * 定时任务处理(禁止并发执行) + * + * @author ff + * + */ +@DisallowConcurrentExecution +public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/util/QuartzJobExecution.java b/ff-admin/src/main/java/com/ff/quartz/util/QuartzJobExecution.java new file mode 100644 index 0000000..18f99f8 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/util/QuartzJobExecution.java @@ -0,0 +1,21 @@ +package com.ff.quartz.util; + +import com.ff.quartz.domain.SysJob; +import com.ff.quartz.util.AbstractQuartzJob; +import com.ff.quartz.util.JobInvokeUtil; +import org.quartz.JobExecutionContext; + +/** + * 定时任务处理(允许并发执行) + * + * @author ff + * + */ +public class QuartzJobExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/ff-admin/src/main/java/com/ff/quartz/util/ScheduleUtils.java b/ff-admin/src/main/java/com/ff/quartz/util/ScheduleUtils.java new file mode 100644 index 0000000..6a966b8 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/quartz/util/ScheduleUtils.java @@ -0,0 +1,132 @@ +package com.ff.quartz.util; + +import com.ff.base.constant.Constants; +import com.ff.base.constant.ScheduleConstants; +import com.ff.base.exception.job.TaskException; +import com.ff.base.exception.job.TaskException.Code; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.spring.SpringUtils; +import com.ff.quartz.domain.SysJob; +import org.quartz.*; + +/** + * 定时任务工具类 + * + * @author ff + * + */ +public class ScheduleUtils +{ + /** + * 得到quartz任务类 + * + * @param sysJob 执行计划 + * @return 具体执行任务类 + */ + private static Class getQuartzJobClass(SysJob sysJob) + { + boolean isConcurrent = "0".equals(sysJob.getConcurrent()); + return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class; + } + + /** + * 构建任务触发对象 + */ + public static TriggerKey getTriggerKey(Long jobId, String jobGroup) + { + return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 构建任务键对象 + */ + public static JobKey getJobKey(Long jobId, String jobGroup) + { + return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 创建定时任务 + */ + public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException + { + Class jobClass = getQuartzJobClass(job); + // 构建job信息 + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build(); + + // 表达式调度构建器 + CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); + cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); + + // 按新的cronExpression表达式构建一个新的trigger + CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup)) + .withSchedule(cronScheduleBuilder).build(); + + // 放入参数,运行时的方法可以获取 + jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); + + // 判断是否存在 + if (scheduler.checkExists(getJobKey(jobId, jobGroup))) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(getJobKey(jobId, jobGroup)); + } + + // 判断任务是否过期 + if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression()))) + { + // 执行调度任务 + scheduler.scheduleJob(jobDetail, trigger); + } + + // 暂停任务 + if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + } + + /** + * 设置定时任务策略 + */ + public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) + throws TaskException + { + switch (job.getMisfirePolicy()) + { + case ScheduleConstants.MISFIRE_DEFAULT: + return cb; + case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: + return cb.withMisfireHandlingInstructionIgnoreMisfires(); + case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: + return cb.withMisfireHandlingInstructionFireAndProceed(); + case ScheduleConstants.MISFIRE_DO_NOTHING: + return cb.withMisfireHandlingInstructionDoNothing(); + default: + throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() + + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); + } + } + + /** + * 检查包名是否为白名单配置 + * + * @param invokeTarget 目标字符串 + * @return 结果 + */ + public static boolean whiteList(String invokeTarget) + { + String packageName = StringUtils.substringBefore(invokeTarget, "("); + int count = StringUtils.countMatches(packageName, "."); + if (count > 1) + { + return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR); + } + Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]); + String beanPackageName = obj.getClass().getPackage().getName(); + return StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_WHITELIST_STR) + && !StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_ERROR_STR); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysConfigController.java b/ff-admin/src/main/java/com/ff/system/SysConfigController.java new file mode 100644 index 0000000..94311f2 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysConfigController.java @@ -0,0 +1,129 @@ +package com.ff.system; + +import com.ff.base.annotation.Anonymous; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.system.domain.SysConfig; +import com.ff.base.system.service.ISysConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 参数配置 信息操作处理 + * + * @author ff + */ +@RestController +@RequestMapping("/system/config") +public class SysConfigController extends BaseController +{ + @Autowired + private ISysConfigService configService; + + /** + * 获取参数配置列表 + */ + @PreAuthorize("@ss.hasPermi('system:config:list')") + @GetMapping("/list") + public TableDataInfo list(SysConfig config) + { + startPage(); + List list = configService.selectConfigList(config); + return getDataTable(list); + } + + @Log(title = "参数管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:config:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysConfig config) + { + List list = configService.selectConfigList(config); + ExcelUtil util = new ExcelUtil(SysConfig.class); + util.exportExcel(response, list, "参数数据"); + } + + /** + * 根据参数编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:config:query')") + @GetMapping(value = "/{configId}") + public AjaxResult getInfo(@PathVariable Long configId) + { + return success(configService.selectConfigById(configId)); + } + + /** + * 根据参数键名查询参数值 + */ + @Anonymous + @GetMapping(value = "/configKey/{configKey}") + public AjaxResult getConfigKey(@PathVariable String configKey) + { + return success(configService.selectConfigByKey(configKey)); + } + + /** + * 新增参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:add')") + @Log(title = "参数管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysConfig config) + { + if (!configService.checkConfigKeyUnique(config)) + { + return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setCreateBy(getUsername()); + return toAjax(configService.insertConfig(config)); + } + + /** + * 修改参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:edit')") + @Log(title = "参数管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysConfig config) + { + if (!configService.checkConfigKeyUnique(config)) + { + return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setUpdateBy(getUsername()); + return toAjax(configService.updateConfig(config)); + } + + /** + * 删除参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:remove')") + @Log(title = "参数管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{configIds}") + public AjaxResult remove(@PathVariable Long[] configIds) + { + configService.deleteConfigByIds(configIds); + return success(); + } + + /** + * 刷新参数缓存 + */ + @PreAuthorize("@ss.hasPermi('system:config:remove')") + @Log(title = "参数管理", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + configService.resetConfigCache(); + return success(); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysDatasourceController.java b/ff-admin/src/main/java/com/ff/system/SysDatasourceController.java new file mode 100644 index 0000000..0372b26 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysDatasourceController.java @@ -0,0 +1,105 @@ +package com.ff.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.ff.base.system.domain.SysDatasource; +import com.ff.base.system.service.ISysDatasourceService; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.core.page.TableDataInfo; + +/** + * 租户数据源Controller + * + * @author liukang + * @date 2024-11-20 + */ +@RestController +@RequestMapping("/system/datasource") +public class SysDatasourceController extends BaseController +{ + @Autowired + private ISysDatasourceService sysDatasourceService; + + /** + * 查询租户数据源列表 + */ + @PreAuthorize("@ss.hasPermi('system:datasource:list')") + @GetMapping("/list") + public TableDataInfo list(SysDatasource sysDatasource) + { + startPage(); + List list = sysDatasourceService.selectSysDatasourceList(sysDatasource); + return getDataTable(list); + } + + /** + * 导出租户数据源列表 + */ + @PreAuthorize("@ss.hasPermi('system:datasource:export')") + @Log(title = "租户数据源", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysDatasource sysDatasource) + { + List list = sysDatasourceService.selectSysDatasourceList(sysDatasource); + ExcelUtil util = new ExcelUtil(SysDatasource.class); + util.exportExcel(response, list, "租户数据源数据"); + } + + /** + * 获取租户数据源详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:datasource:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysDatasourceService.selectSysDatasourceById(id)); + } + + /** + * 新增租户数据源 + */ + @PreAuthorize("@ss.hasPermi('system:datasource:add')") + @Log(title = "租户数据源", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysDatasource sysDatasource) + { + return toAjax(sysDatasourceService.insertSysDatasource(sysDatasource)); + } + + /** + * 修改租户数据源 + */ + @PreAuthorize("@ss.hasPermi('system:datasource:edit')") + @Log(title = "租户数据源", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysDatasource sysDatasource) + { + return toAjax(sysDatasourceService.updateSysDatasource(sysDatasource)); + } + + /** + * 删除租户数据源 + */ + @PreAuthorize("@ss.hasPermi('system:datasource:remove')") + @Log(title = "租户数据源", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(sysDatasourceService.deleteSysDatasourceByIds(ids)); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysDeptController.java b/ff-admin/src/main/java/com/ff/system/SysDeptController.java new file mode 100644 index 0000000..9438ab4 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysDeptController.java @@ -0,0 +1,126 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.constant.UserConstants; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysDept; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.StringUtils; +import com.ff.base.system.service.ISysDeptService; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 部门信息 + * + * @author ff + */ +@RestController +@RequestMapping("/system/dept") +public class SysDeptController extends BaseController +{ + @Autowired + private ISysDeptService deptService; + + /** + * 获取部门列表 + */ + @PreAuthorize("@ss.hasPermi('system:dept:list')") + @GetMapping("/list") + public AjaxResult list(SysDept dept) + { + List depts = deptService.selectDeptList(dept); + return success(depts); + } + + /** + * 查询部门列表(排除节点) + */ + @PreAuthorize("@ss.hasPermi('system:dept:list')") + @GetMapping("/list/exclude/{deptId}") + public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) + { + List depts = deptService.selectDeptList(new SysDept()); + depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")); + return success(depts); + } + + /** + * 根据部门编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:dept:query')") + @GetMapping(value = "/{deptId}") + public AjaxResult getInfo(@PathVariable Long deptId) + { + deptService.checkDeptDataScope(deptId); + return success(deptService.selectDeptById(deptId)); + } + + /** + * 新增部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:add')") + @Log(title = "部门管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDept dept) + { + if (!deptService.checkDeptNameUnique(dept)) + { + return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + dept.setCreateBy(getUsername()); + return toAjax(deptService.insertDept(dept)); + } + + /** + * 修改部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:edit')") + @Log(title = "部门管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDept dept) + { + Long deptId = dept.getDeptId(); + deptService.checkDeptDataScope(deptId); + if (!deptService.checkDeptNameUnique(dept)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + else if (dept.getParentId().equals(deptId)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); + } + else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0) + { + return error("该部门包含未停用的子部门!"); + } + dept.setUpdateBy(getUsername()); + return toAjax(deptService.updateDept(dept)); + } + + /** + * 删除部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:remove')") + @Log(title = "部门管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{deptId}") + public AjaxResult remove(@PathVariable Long deptId) + { + if (deptService.hasChildByDeptId(deptId)) + { + return warn("存在下级部门,不允许删除"); + } + if (deptService.checkDeptExistUser(deptId)) + { + return warn("部门存在用户,不允许删除"); + } + deptService.checkDeptDataScope(deptId); + return toAjax(deptService.deleteDeptById(deptId)); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysDictDataController.java b/ff-admin/src/main/java/com/ff/system/SysDictDataController.java new file mode 100644 index 0000000..8c07d02 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysDictDataController.java @@ -0,0 +1,126 @@ +package com.ff.system; + +import com.fasterxml.jackson.annotation.JsonView; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysDictData; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.system.service.ISysDictDataService; +import com.ff.base.system.service.ISysDictTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; + +/** + * 数据字典信息 + * + * @author ff + */ +@RestController +@RequestMapping("/system/dict/data") +public class SysDictDataController extends BaseController +{ + @Autowired + private ISysDictDataService dictDataService; + + @Autowired + private ISysDictTypeService dictTypeService; + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/allList") + @JsonView(SysDictData.DictDataSimpleView.class) + public AjaxResult allList(SysDictData dictData) + { + dictData.setStatus("0"); + List list = dictDataService.selectDictDataList(dictData); + return AjaxResult.success(list); + } + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/list") + public TableDataInfo list(SysDictData dictData) + { + startPage(); + List list = dictDataService.selectDictDataList(dictData); + return getDataTable(list); + } + + @Log(title = "字典数据", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictData dictData) + { + List list = dictDataService.selectDictDataList(dictData); + ExcelUtil util = new ExcelUtil(SysDictData.class); + util.exportExcel(response, list, "字典数据"); + } + + /** + * 查询字典数据详细 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictCode}") + public AjaxResult getInfo(@PathVariable Long dictCode) + { + return success(dictDataService.selectDictDataById(dictCode)); + } + + /** + * 根据字典类型查询字典数据信息 + */ + @GetMapping(value = "/type/{dictType}") + public AjaxResult dictType(@PathVariable String dictType) + { + List data = dictTypeService.selectDictDataByType(dictType); + if (StringUtils.isNull(data)) + { + data = new ArrayList(); + } + return success(data); + } + + /** + * 新增字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "字典数据", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictData dict) + { + dict.setCreateBy(getUsername()); + return toAjax(dictDataService.insertDictData(dict)); + } + + /** + * 修改保存字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @Log(title = "字典数据", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictData dict) + { + dict.setUpdateBy(getUsername()); + return toAjax(dictDataService.updateDictData(dict)); + } + + /** + * 删除字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictCodes}") + public AjaxResult remove(@PathVariable Long[] dictCodes) + { + dictDataService.deleteDictDataByIds(dictCodes); + return success(); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysDictTypeController.java b/ff-admin/src/main/java/com/ff/system/SysDictTypeController.java new file mode 100644 index 0000000..7406791 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysDictTypeController.java @@ -0,0 +1,125 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysDictType; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.system.service.ISysDictTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 数据字典信息 + * + * @author ff + */ +@RestController +@RequestMapping("/system/dict/type") +public class SysDictTypeController extends BaseController +{ + @Autowired + private ISysDictTypeService dictTypeService; + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/list") + public TableDataInfo list(SysDictType dictType) + { + startPage(); + List list = dictTypeService.selectDictTypeList(dictType); + return getDataTable(list); + } + + @Log(title = "字典类型", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictType dictType) + { + List list = dictTypeService.selectDictTypeList(dictType); + ExcelUtil util = new ExcelUtil(SysDictType.class); + util.exportExcel(response, list, "字典类型"); + } + + /** + * 查询字典类型详细 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictId}") + public AjaxResult getInfo(@PathVariable Long dictId) + { + return success(dictTypeService.selectDictTypeById(dictId)); + } + + /** + * 新增字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "字典类型", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictType dict) + { + if (!dictTypeService.checkDictTypeUnique(dict)) + { + return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setCreateBy(getUsername()); + return toAjax(dictTypeService.insertDictType(dict)); + } + + /** + * 修改字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @Log(title = "字典类型", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictType dict) + { + if (!dictTypeService.checkDictTypeUnique(dict)) + { + return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setUpdateBy(getUsername()); + return toAjax(dictTypeService.updateDictType(dict)); + } + + /** + * 删除字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictIds}") + public AjaxResult remove(@PathVariable Long[] dictIds) + { + dictTypeService.deleteDictTypeByIds(dictIds); + return success(); + } + + /** + * 刷新字典缓存 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + dictTypeService.resetDictCache(); + return success(); + } + + /** + * 获取字典选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List dictTypes = dictTypeService.selectDictTypeAll(); + return success(dictTypes); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysIndexController.java b/ff-admin/src/main/java/com/ff/system/SysIndexController.java new file mode 100644 index 0000000..2b2afb5 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysIndexController.java @@ -0,0 +1,29 @@ +package com.ff.system; + +import com.ff.base.config.FFConfig; +import com.ff.base.utils.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 首页 + * + * @author ff + */ +@RestController +public class SysIndexController +{ + /** 系统基础配置 */ + @Autowired + private FFConfig FfConfig; + + /** + * 访问首页,提示语 + */ + @RequestMapping("/") + public String index() + { + return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", FfConfig.getName(), FfConfig.getVersion()); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysLoginController.java b/ff-admin/src/main/java/com/ff/system/SysLoginController.java new file mode 100644 index 0000000..5de7522 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysLoginController.java @@ -0,0 +1,99 @@ +package com.ff.system; + +import com.ff.base.constant.Constants; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.domain.model.LoginBody; +import com.ff.base.system.domain.SysMenu; +import com.ff.base.system.domain.SysUser; +import com.ff.base.system.service.ISysDatasourceService; +import com.ff.base.system.service.ISysMenuService; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.web.service.SysLoginService; +import com.ff.base.web.service.SysPermissionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.Set; + +/** + * 登录验证 + * + * @author ff + */ +@RestController +public class SysLoginController +{ + @Autowired + private SysLoginService loginService; + + @Autowired + private ISysMenuService menuService; + + @Autowired + private SysPermissionService permissionService; + + @Resource + private ISysDatasourceService datasourceService; + + /** + * 登录方法 + * + * @param loginBody 登录信息 + * @return 结果 + */ + @PostMapping("/login") + public AjaxResult login(@RequestBody LoginBody loginBody) + { + AjaxResult ajax = AjaxResult.success(); + // 生成令牌 + String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), + loginBody.getUuid()); + ajax.put(Constants.TOKEN, token); + return ajax; + } + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("getInfo") + public AjaxResult getInfo(HttpServletRequest request) + { + SysUser user = SecurityUtils.getLoginUser().getUser(); + // 角色集合 + Set roles = permissionService.getRolePermission(user); + // 权限集合 + Set permissions = permissionService.getMenuPermission(user); + + // 切换数据源 + String tenantId = request.getHeader(Constants.TENANT_ID); + + AjaxResult ajax = AjaxResult.success(); + ajax.put("user", user); + ajax.put("roles", roles); + ajax.put("permissions", permissions); + ajax.put("timeZone", datasourceService.selectSysDatasourceByTenantId(tenantId)); + ajax.put("timeZoneName", datasourceService.selectTimeZoneNameByTenantId(tenantId)); + return ajax; + } + + /** + * 获取路由信息 + * + * @return 路由信息 + */ + @GetMapping("getRouters") + public AjaxResult getRouters() + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuTreeByUserId(userId); + return AjaxResult.success(menuService.buildMenus(menus)); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysMenuController.java b/ff-admin/src/main/java/com/ff/system/SysMenuController.java new file mode 100644 index 0000000..bdac1fd --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysMenuController.java @@ -0,0 +1,136 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.constant.UserConstants; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysMenu; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.StringUtils; +import com.ff.base.system.service.ISysMenuService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 菜单信息 + * + * @author ff + */ +@RestController +@RequestMapping("/system/menu") +public class SysMenuController extends BaseController +{ + @Autowired + private ISysMenuService menuService; + + /** + * 获取菜单列表 + */ + @PreAuthorize("@ss.hasPermi('system:menu:list')") + @GetMapping("/list") + public AjaxResult list(SysMenu menu) + { + List menus = menuService.selectMenuList(menu, getUserId()); + return success(menus); + } + + /** + * 根据菜单编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:menu:query')") + @GetMapping(value = "/{menuId}") + public AjaxResult getInfo(@PathVariable Long menuId) + { + return success(menuService.selectMenuById(menuId)); + } + + /** + * 获取菜单下拉树列表 + */ + @GetMapping("/treeselect") + public AjaxResult treeselect(SysMenu menu) + { + List menus = menuService.selectMenuList(menu, getUserId()); + return success(menuService.buildMenuTreeSelect(menus)); + } + + /** + * 加载对应角色菜单列表树 + */ + @GetMapping(value = "/roleMenuTreeselect/{roleId}") + public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) + { + List menus = menuService.selectMenuList(getUserId()); + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); + ajax.put("menus", menuService.buildMenuTreeSelect(menus)); + return ajax; + } + + /** + * 新增菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:add')") + @Log(title = "菜单管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysMenu menu) + { + if (!menuService.checkMenuNameUnique(menu)) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + menu.setCreateBy(getUsername()); + return toAjax(menuService.insertMenu(menu)); + } + + /** + * 修改菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:edit')") + @Log(title = "菜单管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysMenu menu) + { + if (!menuService.checkMenuNameUnique(menu)) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + else if (menu.getMenuId().equals(menu.getParentId())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); + } + menu.setUpdateBy(getUsername()); + return toAjax(menuService.updateMenu(menu)); + } + + /** + * 删除菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:remove')") + @Log(title = "菜单管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{menuId}") + public AjaxResult remove(@PathVariable("menuId") Long menuId) + { + if (menuService.hasChildByMenuId(menuId)) + { + return warn("存在子菜单,不允许删除"); + } + if (menuService.checkMenuExistRole(menuId)) + { + return warn("菜单已分配,不允许删除"); + } + return toAjax(menuService.deleteMenuById(menuId)); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysPostController.java b/ff-admin/src/main/java/com/ff/system/SysPostController.java new file mode 100644 index 0000000..b00990e --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysPostController.java @@ -0,0 +1,123 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.system.domain.SysPost; +import com.ff.base.system.service.ISysPostService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 岗位信息操作处理 + * + * @author ff + */ +@RestController +@RequestMapping("/system/post") +public class SysPostController extends BaseController +{ + @Autowired + private ISysPostService postService; + + /** + * 获取岗位列表 + */ + @PreAuthorize("@ss.hasPermi('system:post:list')") + @GetMapping("/list") + public TableDataInfo list(SysPost post) + { + startPage(); + List list = postService.selectPostList(post); + return getDataTable(list); + } + + @Log(title = "岗位管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:post:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysPost post) + { + List list = postService.selectPostList(post); + ExcelUtil util = new ExcelUtil(SysPost.class); + util.exportExcel(response, list, "岗位数据"); + } + + /** + * 根据岗位编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:post:query')") + @GetMapping(value = "/{postId}") + public AjaxResult getInfo(@PathVariable Long postId) + { + return success(postService.selectPostById(postId)); + } + + /** + * 新增岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:add')") + @Log(title = "岗位管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysPost post) + { + if (!postService.checkPostNameUnique(post)) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (!postService.checkPostCodeUnique(post)) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setCreateBy(getUsername()); + return toAjax(postService.insertPost(post)); + } + + /** + * 修改岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:edit')") + @Log(title = "岗位管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysPost post) + { + if (!postService.checkPostNameUnique(post)) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (!postService.checkPostCodeUnique(post)) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setUpdateBy(getUsername()); + return toAjax(postService.updatePost(post)); + } + + /** + * 删除岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:remove')") + @Log(title = "岗位管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{postIds}") + public AjaxResult remove(@PathVariable Long[] postIds) + { + return toAjax(postService.deletePostByIds(postIds)); + } + + /** + * 获取岗位选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List posts = postService.selectPostAll(); + return success(posts); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysProfileController.java b/ff-admin/src/main/java/com/ff/system/SysProfileController.java new file mode 100644 index 0000000..60fbc5d --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysProfileController.java @@ -0,0 +1,131 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.config.FFConfig; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysUser; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.file.FileUploadUtils; +import com.ff.base.utils.file.MimeTypeUtils; +import com.ff.base.web.service.TokenService; +import com.ff.base.system.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +/** + * 个人信息 业务处理 + * + * @author ff + */ +@RestController +@RequestMapping("/system/user/profile") +public class SysProfileController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private TokenService tokenService; + + /** + * 个人信息 + */ + @GetMapping + public AjaxResult profile() + { + LoginUser loginUser = getLoginUser(); + SysUser user = loginUser.getUser(); + AjaxResult ajax = AjaxResult.success(user); + ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername())); + ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername())); + return ajax; + } + + /** + * 修改用户 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult updateProfile(@RequestBody SysUser user) + { + LoginUser loginUser = getLoginUser(); + SysUser currentUser = loginUser.getUser(); + currentUser.setNickName(user.getNickName()); + currentUser.setEmail(user.getEmail()); + currentUser.setPhonenumber(user.getPhonenumber()); + currentUser.setSex(user.getSex()); + if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser)) + { + return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在"); + } + if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser)) + { + return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在"); + } + if (userService.updateUserProfile(currentUser) > 0) + { + // 更新缓存用户信息 + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改个人信息异常,请联系管理员"); + } + + /** + * 重置密码 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping("/updatePwd") + public AjaxResult updatePwd(String oldPassword, String newPassword) + { + LoginUser loginUser = getLoginUser(); + String userName = loginUser.getUsername(); + String password = loginUser.getPassword(); + if (!SecurityUtils.matchesPassword(oldPassword, password)) + { + return error("修改密码失败,旧密码错误"); + } + if (SecurityUtils.matchesPassword(newPassword, password)) + { + return error("新密码不能与旧密码相同"); + } + newPassword = SecurityUtils.encryptPassword(newPassword); + if (userService.resetUserPwd(userName, newPassword) > 0) + { + // 更新缓存用户密码 + loginUser.getUser().setPassword(newPassword); + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改密码异常,请联系管理员"); + } + + /** + * 头像上传 + */ + @Log(title = "用户头像", businessType = BusinessType.UPDATE) + @PostMapping("/avatar") + public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception + { + if (!file.isEmpty()) + { + LoginUser loginUser = getLoginUser(); + String avatar = FileUploadUtils.upload(FFConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION); + if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("imgUrl", avatar); + // 更新缓存用户头像 + loginUser.getUser().setAvatar(avatar); + tokenService.setLoginUser(loginUser); + return ajax; + } + } + return error("上传图片异常,请联系管理员"); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysRegisterController.java b/ff-admin/src/main/java/com/ff/system/SysRegisterController.java new file mode 100644 index 0000000..8067487 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysRegisterController.java @@ -0,0 +1,38 @@ +package com.ff.system; + +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.domain.model.RegisterBody; +import com.ff.base.utils.StringUtils; +import com.ff.base.web.service.SysRegisterService; +import com.ff.base.system.service.ISysConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * 注册验证 + * + * @author ff + */ +@RestController +public class SysRegisterController extends BaseController +{ + @Autowired + private SysRegisterService registerService; + + @Autowired + private ISysConfigService configService; + + @PostMapping("/register") + public AjaxResult register(@RequestBody RegisterBody user) + { + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) + { + return error("当前系统没有开启注册功能!"); + } + String msg = registerService.register(user); + return StringUtils.isEmpty(msg) ? success() : error(msg); + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysRoleController.java b/ff-admin/src/main/java/com/ff/system/SysRoleController.java new file mode 100644 index 0000000..31bb249 --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysRoleController.java @@ -0,0 +1,256 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysDept; +import com.ff.base.system.domain.SysRole; +import com.ff.base.system.domain.SysUser; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.web.service.SysPermissionService; +import com.ff.base.web.service.TokenService; +import com.ff.base.system.domain.SysUserRole; +import com.ff.base.system.service.ISysDeptService; +import com.ff.base.system.service.ISysRoleService; +import com.ff.base.system.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 角色信息 + * + * @author ff + */ +@RestController +@RequestMapping("/system/role") +public class SysRoleController extends BaseController +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private TokenService tokenService; + + @Autowired + private SysPermissionService permissionService; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysDeptService deptService; + + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/list") + public TableDataInfo list(SysRole role) + { + startPage(); + List list = roleService.selectRoleList(role); + return getDataTable(list); + } + + @Log(title = "角色管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:role:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysRole role) + { + List list = roleService.selectRoleList(role); + ExcelUtil util = new ExcelUtil(SysRole.class); + util.exportExcel(response, list, "角色数据"); + } + + /** + * 根据角色编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping(value = "/{roleId}") + public AjaxResult getInfo(@PathVariable Long roleId) + { + roleService.checkRoleDataScope(roleId); + return success(roleService.selectRoleById(roleId)); + } + + /** + * 新增角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:add')") + @Log(title = "角色管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysRole role) + { + if (!roleService.checkRoleNameUnique(role)) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (!roleService.checkRoleKeyUnique(role)) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setCreateBy(getUsername()); + return toAjax(roleService.insertRole(role)); + + } + + /** + * 修改保存角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + if (!roleService.checkRoleNameUnique(role)) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (!roleService.checkRoleKeyUnique(role)) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setUpdateBy(getUsername()); + + if (roleService.updateRole(role) > 0) + { + // 更新缓存用户权限 + LoginUser loginUser = getLoginUser(); + if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) + { + loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser())); + loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName())); + tokenService.setLoginUser(loginUser); + } + return success(); + } + return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员"); + } + + /** + * 修改保存数据权限 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/dataScope") + public AjaxResult dataScope(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + return toAjax(roleService.authDataScope(role)); + } + + /** + * 状态修改 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + role.setUpdateBy(getUsername()); + return toAjax(roleService.updateRoleStatus(role)); + } + + /** + * 删除角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:remove')") + @Log(title = "角色管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{roleIds}") + public AjaxResult remove(@PathVariable Long[] roleIds) + { + return toAjax(roleService.deleteRoleByIds(roleIds)); + } + + /** + * 获取角色选择框列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + return success(roleService.selectRoleAll()); + } + + /** + * 查询已分配用户角色列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/authUser/allocatedList") + public TableDataInfo allocatedList(SysUser user) + { + startPage(); + List list = userService.selectAllocatedList(user); + return getDataTable(list); + } + + /** + * 查询未分配用户角色列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/authUser/unallocatedList") + public TableDataInfo unallocatedList(SysUser user) + { + startPage(); + List list = userService.selectUnallocatedList(user); + return getDataTable(list); + } + + /** + * 取消授权用户 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancel") + public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole) + { + return toAjax(roleService.deleteAuthUser(userRole)); + } + + /** + * 批量取消授权用户 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancelAll") + public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds) + { + return toAjax(roleService.deleteAuthUsers(roleId, userIds)); + } + + /** + * 批量选择用户授权 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/selectAll") + public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds) + { + roleService.checkRoleDataScope(roleId); + return toAjax(roleService.insertAuthUsers(roleId, userIds)); + } + + /** + * 获取对应角色部门树列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping(value = "/deptTree/{roleId}") + public AjaxResult deptTree(@PathVariable("roleId") Long roleId) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); + ajax.put("depts", deptService.selectDeptTreeList(new SysDept())); + return ajax; + } +} diff --git a/ff-admin/src/main/java/com/ff/system/SysUserController.java b/ff-admin/src/main/java/com/ff/system/SysUserController.java new file mode 100644 index 0000000..2ab59fc --- /dev/null +++ b/ff-admin/src/main/java/com/ff/system/SysUserController.java @@ -0,0 +1,250 @@ +package com.ff.system; + +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.system.domain.SysDept; +import com.ff.base.system.domain.SysRole; +import com.ff.base.system.domain.SysUser; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.poi.ExcelUtil; +import com.ff.base.system.service.ISysDeptService; +import com.ff.base.system.service.ISysPostService; +import com.ff.base.system.service.ISysRoleService; +import com.ff.base.system.service.ISysUserService; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 用户信息 + * + * @author ff + */ +@RestController +@RequestMapping("/system/user") +public class SysUserController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysDeptService deptService; + + @Autowired + private ISysPostService postService; + + /** + * 获取用户列表 + */ + @PreAuthorize("@ss.hasPermi('system:user:list')") + @GetMapping("/list") + public TableDataInfo list(SysUser user) + { + startPage(); + List list = userService.selectUserList(user); + return getDataTable(list); + } + + @Log(title = "用户管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:user:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysUser user) + { + List list = userService.selectUserList(user); + ExcelUtil util = new ExcelUtil(SysUser.class); + util.exportExcel(response, list, "用户数据"); + } + + @Log(title = "用户管理", businessType = BusinessType.IMPORT) + @PreAuthorize("@ss.hasPermi('system:user:import')") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(SysUser.class); + List userList = util.importExcel(file.getInputStream()); + String operName = getUsername(); + String message = userService.importUser(userList, updateSupport, operName); + return success(message); + } + + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) + { + ExcelUtil util = new ExcelUtil(SysUser.class); + util.importTemplateExcel(response, "用户数据"); + } + + /** + * 根据用户编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:user:query')") + @GetMapping(value = { "/", "/{userId}" }) + public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) + { + userService.checkUserDataScope(userId); + AjaxResult ajax = AjaxResult.success(); + List roles = roleService.selectRoleAll(); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + ajax.put("posts", postService.selectPostAll()); + if (StringUtils.isNotNull(userId)) + { + SysUser sysUser = userService.selectUserById(userId); + ajax.put(AjaxResult.DATA_TAG, sysUser); + ajax.put("postIds", postService.selectPostListByUserId(userId)); + ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList())); + } + return ajax; + } + + /** + * 新增用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:add')") + @Log(title = "用户管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysUser user) + { + deptService.checkDeptDataScope(user.getDeptId()); + roleService.checkRoleDataScope(user.getRoleIds()); + if (!userService.checkUserNameUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setCreateBy(getUsername()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + return toAjax(userService.insertUser(user)); + } + + /** + * 修改用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + deptService.checkDeptDataScope(user.getDeptId()); + roleService.checkRoleDataScope(user.getRoleIds()); + if (!userService.checkUserNameUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setUpdateBy(getUsername()); + return toAjax(userService.updateUser(user)); + } + + /** + * 删除用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:remove')") + @Log(title = "用户管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{userIds}") + public AjaxResult remove(@PathVariable Long[] userIds) + { + if (ArrayUtils.contains(userIds, getUserId())) + { + return error("当前用户不能删除"); + } + return toAjax(userService.deleteUserByIds(userIds)); + } + + /** + * 重置密码 + */ + @PreAuthorize("@ss.hasPermi('system:user:resetPwd')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/resetPwd") + public AjaxResult resetPwd(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + user.setUpdateBy(getUsername()); + return toAjax(userService.resetPwd(user)); + } + + /** + * 状态修改 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setUpdateBy(getUsername()); + return toAjax(userService.updateUserStatus(user)); + } + + /** + * 根据用户编号获取授权角色 + */ + @PreAuthorize("@ss.hasPermi('system:user:query')") + @GetMapping("/authRole/{userId}") + public AjaxResult authRole(@PathVariable("userId") Long userId) + { + AjaxResult ajax = AjaxResult.success(); + SysUser user = userService.selectUserById(userId); + List roles = roleService.selectRolesByUserId(userId); + ajax.put("user", user); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + return ajax; + } + + /** + * 用户授权角色 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.GRANT) + @PutMapping("/authRole") + public AjaxResult insertAuthRole(Long userId, Long[] roleIds) + { + userService.checkUserDataScope(userId); + roleService.checkRoleDataScope(roleIds); + userService.insertUserAuth(userId, roleIds); + return success(); + } + + /** + * 获取部门树列表 + */ + @PreAuthorize("@ss.hasPermi('system:user:list')") + @GetMapping("/deptTree") + public AjaxResult deptTree(SysDept dept) + { + return success(deptService.selectDeptTreeList(dept)); + } +} diff --git a/ff-admin/src/main/resources/META-INF/spring-devtools.properties b/ff-admin/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..37e7b58 --- /dev/null +++ b/ff-admin/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.json=/com.alibaba.fastjson2.*.jar \ No newline at end of file diff --git a/ff-admin/src/main/resources/application-druid.yml b/ff-admin/src/main/resources/application-druid.yml new file mode 100644 index 0000000..d86c02e --- /dev/null +++ b/ff-admin/src/main/resources/application-druid.yml @@ -0,0 +1,95 @@ +# 数据源配置 +spring: + # redis 配置 + redis: + # 地址 + host: 127.0.0.1 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 1 + # 密码 + password: + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://192.168.1.11:3306/ff-game?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true + username: root + password: 123456 + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ff + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + +forest: + backend: okhttp3 # 后端HTTP框架(默认为 okhttp3) + max-connections: 1000 # 连接池最大连接数(默认为 500) + max-route-connections: 500 # 每个路由的最大连接数(默认为 500) + max-request-queue-size: 100 # [自v1.5.22版本起可用] 最大请求等待队列大小 + max-async-thread-size: 300 # [自v1.5.21版本起可用] 最大异步线程数 + max-async-queue-size: 16 # [自v1.5.22版本起可用] 最大异步线程池队列大小 + timeout: 3000 # [已不推荐使用] 请求超时时间,单位为毫秒(默认为 3000) + connect-timeout: 3000 # 连接超时时间,单位为毫秒(默认为 timeout) + read-timeout: 3000 # 数据读取超时时间,单位为毫秒(默认为 timeout) + max-retry-count: 0 # 请求失败后重试次数(默认为 0 次不重试) + ssl-protocol: TLS # 单向验证的HTTPS的默认TLS协议(默认为 TLS) + log-enabled: true # 打开或关闭日志(默认为 true) + log-request: true # 打开/关闭Forest请求日志(默认为 true) + log-response-status: true # 打开/关闭Forest响应状态日志(默认为 true) + log-response-content: true # 打开/关闭Forest响应内容日志(默认为 false) + async-mode: platform # [自v1.5.27版本起可用] 异步模式(默认为 platform) diff --git a/ff-admin/src/main/resources/application-prod.yml b/ff-admin/src/main/resources/application-prod.yml new file mode 100644 index 0000000..18e7937 --- /dev/null +++ b/ff-admin/src/main/resources/application-prod.yml @@ -0,0 +1,97 @@ +# 项目相关配置 +ff: + # 文件路径 示例( Windows配置D:/ff/uploadPath,Linux配置 /home/ff/uploadPath) + profile: D:/opt/sever/dist/ff-admin/uploadPath +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 28080 + servlet: + # 应用的访问路径 + context-path: /ff-api + +# 日志配置 +logging: + level: + com.ff: debug + org.springframework: warn + file: + path: D:/opt/sever/dist/ff-admin/logs + +# 数据源配置 +spring: + # redis 配置 + redis: + # 地址 + host: 127.0.0.1 + # 端口,默认为6379 + port: 26379 + # 数据库索引 + database: 0 + # 密码 + password: reAa123456 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://192.168.1.11:23306/ff-admin?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true + username: root + password: myAa123456 + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ff + login-password: ff_prod + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true diff --git a/ff-admin/src/main/resources/application.yml b/ff-admin/src/main/resources/application.yml new file mode 100644 index 0000000..73d1cb4 --- /dev/null +++ b/ff-admin/src/main/resources/application.yml @@ -0,0 +1,138 @@ +# 项目相关配置 +ff: + # 名称 + name: FF + # 版本 + version: 0.0.1 + # 版权年份 + copyrightYear: 2024 + # 文件路径 示例( Windows配置D:/ff/uploadPath,Linux配置 /home/ff/uploadPath) + profile: D:/ff/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数字计算 char 字符验证 + captchaType: math + +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 9080 + servlet: + # 应用的访问路径 + context-path: / + tomcat: + # tomcat的URI编码 + uri-encoding: UTF-8 + # 连接数满后的排队数,默认为100 + accept-count: 1000 + threads: + # tomcat最大线程数,默认为200 + max: 800 + # Tomcat启动初始化的线程数,默认值10 + min-spare: 100 + +# 日志配置 +logging: + level: + com.ff: debug + org.springframework: warn + +# 用户配置 +user: + password: + # 密码最大错误次数 + maxRetryCount: 5 + # 密码锁定时间(默认10分钟) + lockTime: 10 + +# 跑批处理配置 +batchProcessing: + # 批量数量 + commissionBatchSize: 20 + agentLevelBatchSize: 50 + bettingDataBatchSize: 1000 + +# Spring配置 +spring: + mvc: + pathmatch: + matching-strategy: ant_path_matcher + # 资源信息 + messages: + # 国际化资源文件路径 + basename: i18n/messages + profiles: + active: druid + # 文件上传 + servlet: + multipart: + # 单个文件大小 + max-file-size: 20MB + # 设置总上传的文件大小 + max-request-size: 20MB + # 服务模块 + devtools: + restart: + # 热部署开关 + enabled: false + +# token配置 +token: + # 令牌自定义标识 + header: Authorization + # 令牌密钥 + secret: abcdefghijklmnopqrstuvwxyz + # 令牌有效期(默认10080分钟 七天) + expireTime: 10080 + +# MyBatis配置 +mybatis: + # 搜索指定包别名 + typeAliasesPackage: com.ff.**.domain + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + mapperLocations: classpath*:mapper/**/*Mapper.xml + # 加载全局的配置文件 + configLocation: classpath:mybatis/mybatis-config.xml + +# PageHelper分页插件 +pagehelper: + helperDialect: mysql + supportMethodsArguments: true + params: count=countSql + +# Swagger配置 +swagger: + # 是否开启swagger + enabled: true + # 请求前缀 + pathMapping: / + +# 防止XSS攻击 +xss: + # 过滤开关 + enabled: true + # 排除链接(多个用逗号分隔) + excludes: /system/notice + # 匹配链接 + urlPatterns: /system/*,/monitor/*,/tool/* + +#雪花算法id生成器配置 +snowflake: + worker: + id: 1 + datacenter: + id: 1 + +#aes密钥 +encrypt: + body: + aes-key: gktsdFKqo7lJi3Kc #AES加密秘钥 + +netty: + app: + port: 9820 + + web: + port: 9821 + + diff --git a/ff-admin/src/main/resources/i18n/messages.properties b/ff-admin/src/main/resources/i18n/messages.properties new file mode 100644 index 0000000..094f953 --- /dev/null +++ b/ff-admin/src/main/resources/i18n/messages.properties @@ -0,0 +1,44 @@ +#错误消息 +opration.success=操作成功 +opration.fail=操作失败 +not.null=* 必须填写 +user.jcaptcha.error=验证码错误 +user.jcaptcha.expire=验证码已失效 +user.not.exists=用户不存在/密码错误 +user.password.not.match=用户不存在/密码错误 +user.password.retry.limit.count=密码输入错误{0}次 +user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟 +user.password.delete=对不起,您的账号已被删除 +user.blocked=用户已封禁,请联系管理员 +role.blocked=角色已封禁,请联系管理员 +login.blocked=很遗憾,访问IP已被列入系统黑名单 +user.logout.success=退出成功 + +length.not.valid=长度必须在{min}到{max}个字符之间 + +user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 +user.password.not.valid=* 5-50个字符 + +user.email.not.valid=邮箱格式错误 +user.mobile.phone.number.not.valid=手机号格式错误 +user.login.success=登录成功 +user.register.success=注册成功 +user.notfound=请重新登录 +user.forcelogout=管理员强制退出,请重新登录 +user.unknown.error=未知错误,请重新登录 + +##文件上传消息 +upload.exceed.maxSize=上传的文件大小超出限制的文件大小!
允许的文件最大大小是:{0}MB! +upload.filename.exceed.length=上传的文件名最长{0}个字符 +upload.file.exception=本地文件上传异常 +upload.file.server.not.exist=文件服务不存在 + +##权限 +no.permission=您没有数据的权限,请联系管理员添加权限 [{0}] +no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}] +no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}] +no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}] +no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}] +no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}] + + diff --git a/ff-admin/src/main/resources/logback.xml b/ff-admin/src/main/resources/logback.xml new file mode 100644 index 0000000..b94939f --- /dev/null +++ b/ff-admin/src/main/resources/logback.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/sys-info.log + + + + ${log.path}/sys-info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/sys-error.log + + + + ${log.path}/sys-error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + ${log.path}/sys-user.log + + + ${log.path}/sys-user.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ff-admin/src/main/resources/mapper/common/CurrencyMapper.xml b/ff-admin/src/main/resources/mapper/common/CurrencyMapper.xml new file mode 100644 index 0000000..b5687d3 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/common/CurrencyMapper.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, status, country, currency_code, currency_sign, game_rate, currency_display, currency_name, full_name, create_by, create_time, update_by, update_time, remark from ff_currency + + + + + + + + insert into ff_currency + + status, + country, + currency_code, + currency_sign, + game_rate, + currency_display, + currency_name, + full_name, + create_by, + create_time, + update_by, + update_time, + remark, + + + #{status}, + #{country}, + #{currencyCode}, + #{currencySign}, + #{gameRate}, + #{currencyDisplay}, + #{currencyName}, + #{fullName}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{remark}, + + + + + update ff_currency + + status = #{status}, + country = #{country}, + currency_code = #{currencyCode}, + currency_sign = #{currencySign}, + game_rate = #{gameRate}, + currency_display = #{currencyDisplay}, + currency_name = #{currencyName}, + full_name = #{fullName}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + remark = #{remark}, + + where id = #{id} + + + + delete from ff_currency where id = #{id} + + + + delete from ff_currency where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/common/LangMapper.xml b/ff-admin/src/main/resources/mapper/common/LangMapper.xml new file mode 100644 index 0000000..62f8ad5 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/common/LangMapper.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + select id, name, country, lang_code, lang_status, create_by, create_time, update_by, update_time from ff_lang + + + + + + + + insert into ff_lang + + name, + country, + lang_code, + lang_status, + create_by, + create_time, + update_by, + update_time, + + + #{name}, + #{country}, + #{langCode}, + #{langStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_lang + + name = #{name}, + country = #{country}, + lang_code = #{langCode}, + lang_status = #{langStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_lang where id = #{id} + + + + delete from ff_lang where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/common/TenantSecretKeyMapper.xml b/ff-admin/src/main/resources/mapper/common/TenantSecretKeyMapper.xml new file mode 100644 index 0000000..839ebc0 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/common/TenantSecretKeyMapper.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + select id, tenant_key, tenant_sn, tenant_secret, tenant_status, create_by, create_time, update_by, update_time from ff_tenant_secret_key + + + + + + + + + + insert into ff_tenant_secret_key + + tenant_key, + tenant_sn, + tenant_secret, + tenant_status, + create_by, + create_time, + update_by, + update_time, + + + #{tenantKey}, + #{tenantSn}, + #{tenantSecret}, + #{tenantStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_tenant_secret_key + + tenant_key = #{tenantKey}, + tenant_sn = #{tenantSn}, + tenant_secret = #{tenantSecret}, + tenant_status = #{tenantStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_tenant_secret_key where id = #{id} + + + + delete from ff_tenant_secret_key where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/game/GameBettingDetailsMapper.xml b/ff-admin/src/main/resources/mapper/game/GameBettingDetailsMapper.xml new file mode 100644 index 0000000..282e764 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/game/GameBettingDetailsMapper.xml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, currency_code, member_id, game_code, game_id, game_type, platform_code, game_name, game_status, game_status_type, game_currency_code, account, wagers_id, wagers_time, bet_amount, payoff_time, payoff_amount, settlement_time, turnover, order_no, settlement_status, create_by, create_time, update_by, update_time from ff_game_betting_details + + + + + + + + insert into ff_game_betting_details + + currency_code, + member_id, + game_code, + game_id, + game_type, + platform_code, + game_name, + game_status, + game_status_type, + game_currency_code, + account, + wagers_id, + wagers_time, + bet_amount, + payoff_time, + payoff_amount, + settlement_time, + turnover, + order_no, + settlement_status, + create_by, + create_time, + update_by, + update_time, + + + #{currencyCode}, + #{memberId}, + #{gameCode}, + #{gameId}, + #{gameType}, + #{platformCode}, + #{gameName}, + #{gameStatus}, + #{gameStatusType}, + #{gameCurrencyCode}, + #{account}, + #{wagersId}, + #{wagersTime}, + #{betAmount}, + #{payoffTime}, + #{payoffAmount}, + #{settlementTime}, + #{turnover}, + #{orderNo}, + #{settlementStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_betting_details + + currency_code = #{currencyCode}, + member_id = #{memberId}, + game_code = #{gameCode}, + game_id = #{gameId}, + game_type = #{gameType}, + platform_code = #{platformCode}, + game_name = #{gameName}, + game_status = #{gameStatus}, + game_status_type = #{gameStatusType}, + game_currency_code = #{gameCurrencyCode}, + account = #{account}, + wagers_id = #{wagersId}, + wagers_time = #{wagersTime}, + bet_amount = #{betAmount}, + payoff_time = #{payoffTime}, + payoff_amount = #{payoffAmount}, + settlement_time = #{settlementTime}, + turnover = #{turnover}, + order_no = #{orderNo}, + settlement_status = #{settlementStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_betting_details where id = #{id} + + + + delete from ff_game_betting_details where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/game/GameExchangeMoneyMapper.xml b/ff-admin/src/main/resources/mapper/game/GameExchangeMoneyMapper.xml new file mode 100644 index 0000000..b9f1c25 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/game/GameExchangeMoneyMapper.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, currency_code, transaction_id, member_id, platform_code, platform_id, balance, quota, coin_before, coin_after, currency_before, currency_after, exchange_type, status, create_by, create_time, update_by, update_time from ff_game_exchange_money + + + + + + + + insert into ff_game_exchange_money + + currency_code, + transaction_id, + member_id, + platform_code, + platform_id, + balance, + quota, + coin_before, + coin_after, + currency_before, + currency_after, + exchange_type, + status, + create_by, + create_time, + update_by, + update_time, + + + #{currencyCode}, + #{transactionId}, + #{memberId}, + #{platformCode}, + #{platformId}, + #{balance}, + #{quota}, + #{coinBefore}, + #{coinAfter}, + #{currencyBefore}, + #{currencyAfter}, + #{exchangeType}, + #{status}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_exchange_money + + currency_code = #{currencyCode}, + transaction_id = #{transactionId}, + member_id = #{memberId}, + platform_code = #{platformCode}, + platform_id = #{platformId}, + balance = #{balance}, + quota = #{quota}, + coin_before = #{coinBefore}, + coin_after = #{coinAfter}, + currency_before = #{currencyBefore}, + currency_after = #{currencyAfter}, + exchange_type = #{exchangeType}, + status = #{status}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_exchange_money where id = #{id} + + + + delete from ff_game_exchange_money where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/game/GameFreeRecordMapper.xml b/ff-admin/src/main/resources/mapper/game/GameFreeRecordMapper.xml new file mode 100644 index 0000000..fb12de8 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/game/GameFreeRecordMapper.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, currency_code, reference_id, member_id, member_account, game_id, send_time, expired_time, free_update_time, send_game, send_amount, used_amount, unused_amount, free_status, create_by, create_time, update_by, update_time from ff_game_free_record + + + + + + + + insert into ff_game_free_record + + currency_code, + reference_id, + member_id, + member_account, + game_id, + send_time, + expired_time, + free_update_time, + send_game, + send_amount, + used_amount, + unused_amount, + free_status, + create_by, + create_time, + update_by, + update_time, + + + #{currencyCode}, + #{referenceId}, + #{memberId}, + #{memberAccount}, + #{gameId}, + #{sendTime}, + #{expiredTime}, + #{freeUpdateTime}, + #{sendGame}, + #{sendAmount}, + #{usedAmount}, + #{unusedAmount}, + #{freeStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_free_record + + currency_code = #{currencyCode}, + reference_id = #{referenceId}, + member_id = #{memberId}, + member_account = #{memberAccount}, + game_id = #{gameId}, + send_time = #{sendTime}, + expired_time = #{expiredTime}, + free_update_time = #{freeUpdateTime}, + send_game = #{sendGame}, + send_amount = #{sendAmount}, + used_amount = #{usedAmount}, + unused_amount = #{unusedAmount}, + free_status = #{freeStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_free_record where id = #{id} + + + + delete from ff_game_free_record where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/game/GameMapper.xml b/ff-admin/src/main/resources/mapper/game/GameMapper.xml new file mode 100644 index 0000000..5c91e38 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/game/GameMapper.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, sort_no, platform_id, game_code, game_source_type, game_name, freespin, demo_status, stop_status, game_status, create_by, create_time, update_by, update_time from ff_game + + + + + + + + insert into ff_game + + sort_no, + platform_id, + game_code, + game_source_type, + game_name, + freespin, + demo_status, + stop_status, + game_status, + create_by, + create_time, + update_by, + update_time, + + + #{sortNo}, + #{platformId}, + #{gameCode}, + #{gameSourceType}, + #{gameName}, + #{freespin}, + #{demoStatus}, + #{stopStatus}, + #{gameStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game + + sort_no = #{sortNo}, + platform_id = #{platformId}, + game_code = #{gameCode}, + game_source_type = #{gameSourceType}, + game_name = #{gameName}, + freespin = #{freespin}, + demo_status = #{demoStatus}, + stop_status = #{stopStatus}, + game_status = #{gameStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game where id = #{id} + + + + delete from ff_game where id in + + #{id} + + + + + + + + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/game/GamePlatformMapper.xml b/ff-admin/src/main/resources/mapper/game/GamePlatformMapper.xml new file mode 100644 index 0000000..3a733cd --- /dev/null +++ b/ff-admin/src/main/resources/mapper/game/GamePlatformMapper.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + select id, sort_no, platform_code, platform_type, platform_name, stop_status, platform_status, create_by, create_time, update_by, update_time from ff_game_platform + + + + + + + + insert into ff_game_platform + + sort_no, + platform_code, + platform_type, + platform_name, + stop_status, + platform_status, + create_by, + create_time, + update_by, + update_time, + + + #{sortNo}, + #{platformCode}, + #{platformType}, + #{platformName}, + #{stopStatus}, + #{platformStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_platform + + sort_no = #{sortNo}, + platform_code = #{platformCode}, + platform_type = #{platformType}, + platform_name = #{platformName}, + stop_status = #{stopStatus}, + platform_status = #{platformStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_platform where id = #{id} + + + + delete from ff_game_platform where id in + + #{id} + + + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/game/GameSecretKeyMapper.xml b/ff-admin/src/main/resources/mapper/game/GameSecretKeyMapper.xml new file mode 100644 index 0000000..e5968a2 --- /dev/null +++ b/ff-admin/src/main/resources/mapper/game/GameSecretKeyMapper.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + select id, platform, code, `key`, system_code, lang, system_lang_code, info, create_by, create_time, update_by, update_time from ff_game_secret_key + + + + + + + + insert into ff_game_secret_key + + platform, + code, + `key`, + system_code, + lang, + system_lang_code, + info, + create_by, + create_time, + update_by, + update_time, + + + #{platform}, + #{code}, + #{key}, + #{systemCode}, + #{lang}, + #{systemLangCode}, + #{info}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_secret_key + + platform = #{platform}, + code = #{code}, + `key` = #{key}, + system_code = #{systemCode}, + lang = #{lang}, + system_lang_code = #{systemLangCode}, + info = #{info}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_secret_key where id = #{id} + + + + delete from ff_game_secret_key where id in + + #{id} + + + + + + + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/member/MemberMapper.xml b/ff-admin/src/main/resources/mapper/member/MemberMapper.xml new file mode 100644 index 0000000..a5441ee --- /dev/null +++ b/ff-admin/src/main/resources/mapper/member/MemberMapper.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + select id, tenant_key, member_account, game_account, platform_code, currency_code, create_by, create_time, update_by, update_time from ff_member + + + + + + + + insert into ff_member + + tenant_key, + member_account, + game_account, + platform_code, + currency_code, + create_by, + create_time, + update_by, + update_time, + + + #{tenantKey}, + #{memberAccount}, + #{gameAccount}, + #{platformCode}, + #{currencyCode}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_member + + tenant_key = #{tenantKey}, + member_account = #{memberAccount}, + game_account = #{gameAccount}, + platform_code = #{platformCode}, + currency_code = #{currencyCode}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_member where id = #{id} + + + + delete from ff_member where id in + + #{id} + + + + + + + \ No newline at end of file diff --git a/ff-admin/src/main/resources/mapper/quartz/SysJobLogMapper.xml b/ff-admin/src/main/resources/mapper/quartz/SysJobLogMapper.xml new file mode 100644 index 0000000..2a05f6c --- /dev/null +++ b/ff-admin/src/main/resources/mapper/quartz/SysJobLogMapper.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + select job_log_id, job_name, job_group, invoke_target, job_message, status, exception_info, create_time + from sys_job_log + + + + + + + + + + delete from sys_job_log where job_log_id = #{jobLogId} + + + + delete from sys_job_log where job_log_id in + + #{jobLogId} + + + + + truncate table sys_job_log + + + + insert into sys_job_log( + job_log_id, + job_name, + job_group, + invoke_target, + job_message, + status, + exception_info, + create_time + )values( + #{jobLogId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{jobMessage}, + #{status}, + #{exceptionInfo}, + UNIX_TIMESTAMP() * 1000 + ) + + + diff --git a/ff-admin/src/main/resources/mapper/quartz/SysJobMapper.xml b/ff-admin/src/main/resources/mapper/quartz/SysJobMapper.xml new file mode 100644 index 0000000..948b5aa --- /dev/null +++ b/ff-admin/src/main/resources/mapper/quartz/SysJobMapper.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark + from sys_job + + + + + + + + + + delete from sys_job where job_id = #{jobId} + + + + delete from sys_job where job_id in + + #{jobId} + + + + + update sys_job + + job_name = #{jobName}, + job_group = #{jobGroup}, + invoke_target = #{invokeTarget}, + cron_expression = #{cronExpression}, + misfire_policy = #{misfirePolicy}, + concurrent = #{concurrent}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where job_id = #{jobId} + + + + insert into sys_job( + job_id, + job_name, + job_group, + invoke_target, + cron_expression, + misfire_policy, + concurrent, + status, + remark, + create_by, + create_time + )values( + #{jobId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{cronExpression}, + #{misfirePolicy}, + #{concurrent}, + #{status}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + diff --git a/ff-admin/src/main/resources/mybatis/mybatis-config.xml b/ff-admin/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 0000000..ac47c03 --- /dev/null +++ b/ff-admin/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/ff-admin/target/classes/META-INF/spring-devtools.properties b/ff-admin/target/classes/META-INF/spring-devtools.properties new file mode 100644 index 0000000..37e7b58 --- /dev/null +++ b/ff-admin/target/classes/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.json=/com.alibaba.fastjson2.*.jar \ No newline at end of file diff --git a/ff-admin/target/classes/application-druid.yml b/ff-admin/target/classes/application-druid.yml new file mode 100644 index 0000000..d86c02e --- /dev/null +++ b/ff-admin/target/classes/application-druid.yml @@ -0,0 +1,95 @@ +# 数据源配置 +spring: + # redis 配置 + redis: + # 地址 + host: 127.0.0.1 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 1 + # 密码 + password: + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://192.168.1.11:3306/ff-game?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true + username: root + password: 123456 + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ff + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + +forest: + backend: okhttp3 # 后端HTTP框架(默认为 okhttp3) + max-connections: 1000 # 连接池最大连接数(默认为 500) + max-route-connections: 500 # 每个路由的最大连接数(默认为 500) + max-request-queue-size: 100 # [自v1.5.22版本起可用] 最大请求等待队列大小 + max-async-thread-size: 300 # [自v1.5.21版本起可用] 最大异步线程数 + max-async-queue-size: 16 # [自v1.5.22版本起可用] 最大异步线程池队列大小 + timeout: 3000 # [已不推荐使用] 请求超时时间,单位为毫秒(默认为 3000) + connect-timeout: 3000 # 连接超时时间,单位为毫秒(默认为 timeout) + read-timeout: 3000 # 数据读取超时时间,单位为毫秒(默认为 timeout) + max-retry-count: 0 # 请求失败后重试次数(默认为 0 次不重试) + ssl-protocol: TLS # 单向验证的HTTPS的默认TLS协议(默认为 TLS) + log-enabled: true # 打开或关闭日志(默认为 true) + log-request: true # 打开/关闭Forest请求日志(默认为 true) + log-response-status: true # 打开/关闭Forest响应状态日志(默认为 true) + log-response-content: true # 打开/关闭Forest响应内容日志(默认为 false) + async-mode: platform # [自v1.5.27版本起可用] 异步模式(默认为 platform) diff --git a/ff-admin/target/classes/application-prod.yml b/ff-admin/target/classes/application-prod.yml new file mode 100644 index 0000000..18e7937 --- /dev/null +++ b/ff-admin/target/classes/application-prod.yml @@ -0,0 +1,97 @@ +# 项目相关配置 +ff: + # 文件路径 示例( Windows配置D:/ff/uploadPath,Linux配置 /home/ff/uploadPath) + profile: D:/opt/sever/dist/ff-admin/uploadPath +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 28080 + servlet: + # 应用的访问路径 + context-path: /ff-api + +# 日志配置 +logging: + level: + com.ff: debug + org.springframework: warn + file: + path: D:/opt/sever/dist/ff-admin/logs + +# 数据源配置 +spring: + # redis 配置 + redis: + # 地址 + host: 127.0.0.1 + # 端口,默认为6379 + port: 26379 + # 数据库索引 + database: 0 + # 密码 + password: reAa123456 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://192.168.1.11:23306/ff-admin?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true + username: root + password: myAa123456 + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ff + login-password: ff_prod + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true diff --git a/ff-admin/target/classes/application.yml b/ff-admin/target/classes/application.yml new file mode 100644 index 0000000..73d1cb4 --- /dev/null +++ b/ff-admin/target/classes/application.yml @@ -0,0 +1,138 @@ +# 项目相关配置 +ff: + # 名称 + name: FF + # 版本 + version: 0.0.1 + # 版权年份 + copyrightYear: 2024 + # 文件路径 示例( Windows配置D:/ff/uploadPath,Linux配置 /home/ff/uploadPath) + profile: D:/ff/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数字计算 char 字符验证 + captchaType: math + +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 9080 + servlet: + # 应用的访问路径 + context-path: / + tomcat: + # tomcat的URI编码 + uri-encoding: UTF-8 + # 连接数满后的排队数,默认为100 + accept-count: 1000 + threads: + # tomcat最大线程数,默认为200 + max: 800 + # Tomcat启动初始化的线程数,默认值10 + min-spare: 100 + +# 日志配置 +logging: + level: + com.ff: debug + org.springframework: warn + +# 用户配置 +user: + password: + # 密码最大错误次数 + maxRetryCount: 5 + # 密码锁定时间(默认10分钟) + lockTime: 10 + +# 跑批处理配置 +batchProcessing: + # 批量数量 + commissionBatchSize: 20 + agentLevelBatchSize: 50 + bettingDataBatchSize: 1000 + +# Spring配置 +spring: + mvc: + pathmatch: + matching-strategy: ant_path_matcher + # 资源信息 + messages: + # 国际化资源文件路径 + basename: i18n/messages + profiles: + active: druid + # 文件上传 + servlet: + multipart: + # 单个文件大小 + max-file-size: 20MB + # 设置总上传的文件大小 + max-request-size: 20MB + # 服务模块 + devtools: + restart: + # 热部署开关 + enabled: false + +# token配置 +token: + # 令牌自定义标识 + header: Authorization + # 令牌密钥 + secret: abcdefghijklmnopqrstuvwxyz + # 令牌有效期(默认10080分钟 七天) + expireTime: 10080 + +# MyBatis配置 +mybatis: + # 搜索指定包别名 + typeAliasesPackage: com.ff.**.domain + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + mapperLocations: classpath*:mapper/**/*Mapper.xml + # 加载全局的配置文件 + configLocation: classpath:mybatis/mybatis-config.xml + +# PageHelper分页插件 +pagehelper: + helperDialect: mysql + supportMethodsArguments: true + params: count=countSql + +# Swagger配置 +swagger: + # 是否开启swagger + enabled: true + # 请求前缀 + pathMapping: / + +# 防止XSS攻击 +xss: + # 过滤开关 + enabled: true + # 排除链接(多个用逗号分隔) + excludes: /system/notice + # 匹配链接 + urlPatterns: /system/*,/monitor/*,/tool/* + +#雪花算法id生成器配置 +snowflake: + worker: + id: 1 + datacenter: + id: 1 + +#aes密钥 +encrypt: + body: + aes-key: gktsdFKqo7lJi3Kc #AES加密秘钥 + +netty: + app: + port: 9820 + + web: + port: 9821 + + diff --git a/ff-admin/target/classes/com/ff/FFApplication.class b/ff-admin/target/classes/com/ff/FFApplication.class new file mode 100644 index 0000000..894457e Binary files /dev/null and b/ff-admin/target/classes/com/ff/FFApplication.class differ diff --git a/ff-admin/target/classes/com/ff/FFServletInitializer.class b/ff-admin/target/classes/com/ff/FFServletInitializer.class new file mode 100644 index 0000000..be1b92d Binary files /dev/null and b/ff-admin/target/classes/com/ff/FFServletInitializer.class differ diff --git a/ff-admin/target/classes/com/ff/config/ContentRefreshedEventListener.class b/ff-admin/target/classes/com/ff/config/ContentRefreshedEventListener.class new file mode 100644 index 0000000..259b5f8 Binary files /dev/null and b/ff-admin/target/classes/com/ff/config/ContentRefreshedEventListener.class differ diff --git a/ff-admin/target/classes/com/ff/config/SwaggerConfig.class b/ff-admin/target/classes/com/ff/config/SwaggerConfig.class new file mode 100644 index 0000000..8de7bc1 Binary files /dev/null and b/ff-admin/target/classes/com/ff/config/SwaggerConfig.class differ diff --git a/ff-admin/target/classes/com/ff/file/controller/FileController.class b/ff-admin/target/classes/com/ff/file/controller/FileController.class new file mode 100644 index 0000000..e72eea7 Binary files /dev/null and b/ff-admin/target/classes/com/ff/file/controller/FileController.class differ diff --git a/ff-admin/target/classes/com/ff/file/service/ISysFileService.class b/ff-admin/target/classes/com/ff/file/service/ISysFileService.class new file mode 100644 index 0000000..1ad43a0 Binary files /dev/null and b/ff-admin/target/classes/com/ff/file/service/ISysFileService.class differ diff --git a/ff-admin/target/classes/com/ff/file/service/impl/LocalSysFileServiceImpl.class b/ff-admin/target/classes/com/ff/file/service/impl/LocalSysFileServiceImpl.class new file mode 100644 index 0000000..3d43add Binary files /dev/null and b/ff-admin/target/classes/com/ff/file/service/impl/LocalSysFileServiceImpl.class differ diff --git a/ff-admin/target/classes/com/ff/member/controller/MemberController.class b/ff-admin/target/classes/com/ff/member/controller/MemberController.class new file mode 100644 index 0000000..7e74eea Binary files /dev/null and b/ff-admin/target/classes/com/ff/member/controller/MemberController.class differ diff --git a/ff-admin/target/classes/com/ff/member/domain/Member.class b/ff-admin/target/classes/com/ff/member/domain/Member.class new file mode 100644 index 0000000..02775b8 Binary files /dev/null and b/ff-admin/target/classes/com/ff/member/domain/Member.class differ diff --git a/ff-admin/target/classes/com/ff/member/mapper/MemberMapper.class b/ff-admin/target/classes/com/ff/member/mapper/MemberMapper.class new file mode 100644 index 0000000..cbd820d Binary files /dev/null and b/ff-admin/target/classes/com/ff/member/mapper/MemberMapper.class differ diff --git a/ff-admin/target/classes/com/ff/member/service/IMemberService.class b/ff-admin/target/classes/com/ff/member/service/IMemberService.class new file mode 100644 index 0000000..e59ae93 Binary files /dev/null and b/ff-admin/target/classes/com/ff/member/service/IMemberService.class differ diff --git a/ff-admin/target/classes/com/ff/member/service/impl/MemberServiceImpl.class b/ff-admin/target/classes/com/ff/member/service/impl/MemberServiceImpl.class new file mode 100644 index 0000000..fe3f952 Binary files /dev/null and b/ff-admin/target/classes/com/ff/member/service/impl/MemberServiceImpl.class differ diff --git a/ff-admin/target/classes/com/ff/monitor/SysLogininforController.class b/ff-admin/target/classes/com/ff/monitor/SysLogininforController.class new file mode 100644 index 0000000..684452c Binary files /dev/null and b/ff-admin/target/classes/com/ff/monitor/SysLogininforController.class differ diff --git a/ff-admin/target/classes/com/ff/monitor/SysOperlogController.class b/ff-admin/target/classes/com/ff/monitor/SysOperlogController.class new file mode 100644 index 0000000..110037d Binary files /dev/null and b/ff-admin/target/classes/com/ff/monitor/SysOperlogController.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/controller/SysJobController.class b/ff-admin/target/classes/com/ff/quartz/controller/SysJobController.class new file mode 100644 index 0000000..a2d331d Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/controller/SysJobController.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/controller/SysJobLogController.class b/ff-admin/target/classes/com/ff/quartz/controller/SysJobLogController.class new file mode 100644 index 0000000..34531df Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/controller/SysJobLogController.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/domain/SysJob.class b/ff-admin/target/classes/com/ff/quartz/domain/SysJob.class new file mode 100644 index 0000000..4f4f699 Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/domain/SysJob.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/domain/SysJobLog.class b/ff-admin/target/classes/com/ff/quartz/domain/SysJobLog.class new file mode 100644 index 0000000..14c8189 Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/domain/SysJobLog.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/mapper/SysJobLogMapper.class b/ff-admin/target/classes/com/ff/quartz/mapper/SysJobLogMapper.class new file mode 100644 index 0000000..84d0d8a Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/mapper/SysJobLogMapper.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/mapper/SysJobMapper.class b/ff-admin/target/classes/com/ff/quartz/mapper/SysJobMapper.class new file mode 100644 index 0000000..42518b0 Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/mapper/SysJobMapper.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/service/ISysJobLogService.class b/ff-admin/target/classes/com/ff/quartz/service/ISysJobLogService.class new file mode 100644 index 0000000..41db0d0 Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/service/ISysJobLogService.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/service/ISysJobService.class b/ff-admin/target/classes/com/ff/quartz/service/ISysJobService.class new file mode 100644 index 0000000..e15e204 Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/service/ISysJobService.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/service/impl/SysJobLogServiceImpl.class b/ff-admin/target/classes/com/ff/quartz/service/impl/SysJobLogServiceImpl.class new file mode 100644 index 0000000..b5ab374 Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/service/impl/SysJobLogServiceImpl.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/service/impl/SysJobServiceImpl.class b/ff-admin/target/classes/com/ff/quartz/service/impl/SysJobServiceImpl.class new file mode 100644 index 0000000..84e130c Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/service/impl/SysJobServiceImpl.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/task/RyTask.class b/ff-admin/target/classes/com/ff/quartz/task/RyTask.class new file mode 100644 index 0000000..c1c251b Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/task/RyTask.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/util/AbstractQuartzJob.class b/ff-admin/target/classes/com/ff/quartz/util/AbstractQuartzJob.class new file mode 100644 index 0000000..5150ef9 Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/util/AbstractQuartzJob.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/util/CronUtils.class b/ff-admin/target/classes/com/ff/quartz/util/CronUtils.class new file mode 100644 index 0000000..12e0bb3 Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/util/CronUtils.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/util/JobInvokeUtil.class b/ff-admin/target/classes/com/ff/quartz/util/JobInvokeUtil.class new file mode 100644 index 0000000..962c14c Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/util/JobInvokeUtil.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/util/QuartzDisallowConcurrentExecution.class b/ff-admin/target/classes/com/ff/quartz/util/QuartzDisallowConcurrentExecution.class new file mode 100644 index 0000000..6e19caf Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/util/QuartzDisallowConcurrentExecution.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/util/QuartzJobExecution.class b/ff-admin/target/classes/com/ff/quartz/util/QuartzJobExecution.class new file mode 100644 index 0000000..ad305a8 Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/util/QuartzJobExecution.class differ diff --git a/ff-admin/target/classes/com/ff/quartz/util/ScheduleUtils.class b/ff-admin/target/classes/com/ff/quartz/util/ScheduleUtils.class new file mode 100644 index 0000000..09825d7 Binary files /dev/null and b/ff-admin/target/classes/com/ff/quartz/util/ScheduleUtils.class differ diff --git a/ff-admin/target/classes/com/ff/system/SysConfigController.class b/ff-admin/target/classes/com/ff/system/SysConfigController.class new file mode 100644 index 0000000..6ac39c2 Binary files /dev/null and b/ff-admin/target/classes/com/ff/system/SysConfigController.class differ diff --git a/ff-admin/target/classes/com/ff/system/SysDatasourceController.class b/ff-admin/target/classes/com/ff/system/SysDatasourceController.class new file mode 100644 index 0000000..4775d77 Binary files /dev/null and b/ff-admin/target/classes/com/ff/system/SysDatasourceController.class differ diff --git a/ff-admin/target/classes/com/ff/system/SysDeptController.class b/ff-admin/target/classes/com/ff/system/SysDeptController.class new file mode 100644 index 0000000..dff2ad6 Binary files /dev/null and b/ff-admin/target/classes/com/ff/system/SysDeptController.class differ diff --git a/ff-admin/target/classes/com/ff/system/SysDictDataController.class b/ff-admin/target/classes/com/ff/system/SysDictDataController.class new file mode 100644 index 0000000..bfbf295 Binary files /dev/null and b/ff-admin/target/classes/com/ff/system/SysDictDataController.class differ diff --git a/ff-admin/target/classes/com/ff/system/SysDictTypeController.class b/ff-admin/target/classes/com/ff/system/SysDictTypeController.class new file mode 100644 index 0000000..8032098 Binary files /dev/null and b/ff-admin/target/classes/com/ff/system/SysDictTypeController.class differ diff --git a/ff-admin/target/classes/com/ff/system/SysIndexController.class b/ff-admin/target/classes/com/ff/system/SysIndexController.class new file mode 100644 index 0000000..e7f903e Binary files /dev/null and b/ff-admin/target/classes/com/ff/system/SysIndexController.class differ diff --git a/ff-admin/target/classes/com/ff/system/SysLoginController.class b/ff-admin/target/classes/com/ff/system/SysLoginController.class new file mode 100644 index 0000000..2f436d6 Binary files /dev/null and b/ff-admin/target/classes/com/ff/system/SysLoginController.class differ diff --git a/ff-admin/target/classes/com/ff/system/SysMenuController.class b/ff-admin/target/classes/com/ff/system/SysMenuController.class new file mode 100644 index 0000000..b87527a Binary files /dev/null and b/ff-admin/target/classes/com/ff/system/SysMenuController.class differ diff --git a/ff-admin/target/classes/com/ff/system/SysPostController.class b/ff-admin/target/classes/com/ff/system/SysPostController.class new file mode 100644 index 0000000..2f0c7c9 Binary files /dev/null and b/ff-admin/target/classes/com/ff/system/SysPostController.class differ diff --git a/ff-admin/target/classes/com/ff/system/SysProfileController.class b/ff-admin/target/classes/com/ff/system/SysProfileController.class new file mode 100644 index 0000000..a251a62 Binary files /dev/null and b/ff-admin/target/classes/com/ff/system/SysProfileController.class differ diff --git a/ff-admin/target/classes/com/ff/system/SysRegisterController.class b/ff-admin/target/classes/com/ff/system/SysRegisterController.class new file mode 100644 index 0000000..8e62a3e Binary files /dev/null and b/ff-admin/target/classes/com/ff/system/SysRegisterController.class differ diff --git a/ff-admin/target/classes/com/ff/system/SysRoleController.class b/ff-admin/target/classes/com/ff/system/SysRoleController.class new file mode 100644 index 0000000..bd69b2f Binary files /dev/null and b/ff-admin/target/classes/com/ff/system/SysRoleController.class differ diff --git a/ff-admin/target/classes/com/ff/system/SysUserController.class b/ff-admin/target/classes/com/ff/system/SysUserController.class new file mode 100644 index 0000000..bfde2c0 Binary files /dev/null and b/ff-admin/target/classes/com/ff/system/SysUserController.class differ diff --git a/ff-admin/target/classes/i18n/messages.properties b/ff-admin/target/classes/i18n/messages.properties new file mode 100644 index 0000000..094f953 --- /dev/null +++ b/ff-admin/target/classes/i18n/messages.properties @@ -0,0 +1,44 @@ +#错误消息 +opration.success=操作成功 +opration.fail=操作失败 +not.null=* 必须填写 +user.jcaptcha.error=验证码错误 +user.jcaptcha.expire=验证码已失效 +user.not.exists=用户不存在/密码错误 +user.password.not.match=用户不存在/密码错误 +user.password.retry.limit.count=密码输入错误{0}次 +user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟 +user.password.delete=对不起,您的账号已被删除 +user.blocked=用户已封禁,请联系管理员 +role.blocked=角色已封禁,请联系管理员 +login.blocked=很遗憾,访问IP已被列入系统黑名单 +user.logout.success=退出成功 + +length.not.valid=长度必须在{min}到{max}个字符之间 + +user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 +user.password.not.valid=* 5-50个字符 + +user.email.not.valid=邮箱格式错误 +user.mobile.phone.number.not.valid=手机号格式错误 +user.login.success=登录成功 +user.register.success=注册成功 +user.notfound=请重新登录 +user.forcelogout=管理员强制退出,请重新登录 +user.unknown.error=未知错误,请重新登录 + +##文件上传消息 +upload.exceed.maxSize=上传的文件大小超出限制的文件大小!
允许的文件最大大小是:{0}MB! +upload.filename.exceed.length=上传的文件名最长{0}个字符 +upload.file.exception=本地文件上传异常 +upload.file.server.not.exist=文件服务不存在 + +##权限 +no.permission=您没有数据的权限,请联系管理员添加权限 [{0}] +no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}] +no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}] +no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}] +no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}] +no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}] + + diff --git a/ff-admin/target/classes/logback.xml b/ff-admin/target/classes/logback.xml new file mode 100644 index 0000000..b94939f --- /dev/null +++ b/ff-admin/target/classes/logback.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/sys-info.log + + + + ${log.path}/sys-info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/sys-error.log + + + + ${log.path}/sys-error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + ${log.path}/sys-user.log + + + ${log.path}/sys-user.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ff-admin/target/classes/mapper/game/GameBettingDetailsMapper.xml b/ff-admin/target/classes/mapper/game/GameBettingDetailsMapper.xml new file mode 100644 index 0000000..282e764 --- /dev/null +++ b/ff-admin/target/classes/mapper/game/GameBettingDetailsMapper.xml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, currency_code, member_id, game_code, game_id, game_type, platform_code, game_name, game_status, game_status_type, game_currency_code, account, wagers_id, wagers_time, bet_amount, payoff_time, payoff_amount, settlement_time, turnover, order_no, settlement_status, create_by, create_time, update_by, update_time from ff_game_betting_details + + + + + + + + insert into ff_game_betting_details + + currency_code, + member_id, + game_code, + game_id, + game_type, + platform_code, + game_name, + game_status, + game_status_type, + game_currency_code, + account, + wagers_id, + wagers_time, + bet_amount, + payoff_time, + payoff_amount, + settlement_time, + turnover, + order_no, + settlement_status, + create_by, + create_time, + update_by, + update_time, + + + #{currencyCode}, + #{memberId}, + #{gameCode}, + #{gameId}, + #{gameType}, + #{platformCode}, + #{gameName}, + #{gameStatus}, + #{gameStatusType}, + #{gameCurrencyCode}, + #{account}, + #{wagersId}, + #{wagersTime}, + #{betAmount}, + #{payoffTime}, + #{payoffAmount}, + #{settlementTime}, + #{turnover}, + #{orderNo}, + #{settlementStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_betting_details + + currency_code = #{currencyCode}, + member_id = #{memberId}, + game_code = #{gameCode}, + game_id = #{gameId}, + game_type = #{gameType}, + platform_code = #{platformCode}, + game_name = #{gameName}, + game_status = #{gameStatus}, + game_status_type = #{gameStatusType}, + game_currency_code = #{gameCurrencyCode}, + account = #{account}, + wagers_id = #{wagersId}, + wagers_time = #{wagersTime}, + bet_amount = #{betAmount}, + payoff_time = #{payoffTime}, + payoff_amount = #{payoffAmount}, + settlement_time = #{settlementTime}, + turnover = #{turnover}, + order_no = #{orderNo}, + settlement_status = #{settlementStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_betting_details where id = #{id} + + + + delete from ff_game_betting_details where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/target/classes/mapper/game/GameExchangeMoneyMapper.xml b/ff-admin/target/classes/mapper/game/GameExchangeMoneyMapper.xml new file mode 100644 index 0000000..b9f1c25 --- /dev/null +++ b/ff-admin/target/classes/mapper/game/GameExchangeMoneyMapper.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, currency_code, transaction_id, member_id, platform_code, platform_id, balance, quota, coin_before, coin_after, currency_before, currency_after, exchange_type, status, create_by, create_time, update_by, update_time from ff_game_exchange_money + + + + + + + + insert into ff_game_exchange_money + + currency_code, + transaction_id, + member_id, + platform_code, + platform_id, + balance, + quota, + coin_before, + coin_after, + currency_before, + currency_after, + exchange_type, + status, + create_by, + create_time, + update_by, + update_time, + + + #{currencyCode}, + #{transactionId}, + #{memberId}, + #{platformCode}, + #{platformId}, + #{balance}, + #{quota}, + #{coinBefore}, + #{coinAfter}, + #{currencyBefore}, + #{currencyAfter}, + #{exchangeType}, + #{status}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_exchange_money + + currency_code = #{currencyCode}, + transaction_id = #{transactionId}, + member_id = #{memberId}, + platform_code = #{platformCode}, + platform_id = #{platformId}, + balance = #{balance}, + quota = #{quota}, + coin_before = #{coinBefore}, + coin_after = #{coinAfter}, + currency_before = #{currencyBefore}, + currency_after = #{currencyAfter}, + exchange_type = #{exchangeType}, + status = #{status}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_exchange_money where id = #{id} + + + + delete from ff_game_exchange_money where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/target/classes/mapper/game/GameFreeRecordMapper.xml b/ff-admin/target/classes/mapper/game/GameFreeRecordMapper.xml new file mode 100644 index 0000000..fb12de8 --- /dev/null +++ b/ff-admin/target/classes/mapper/game/GameFreeRecordMapper.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, currency_code, reference_id, member_id, member_account, game_id, send_time, expired_time, free_update_time, send_game, send_amount, used_amount, unused_amount, free_status, create_by, create_time, update_by, update_time from ff_game_free_record + + + + + + + + insert into ff_game_free_record + + currency_code, + reference_id, + member_id, + member_account, + game_id, + send_time, + expired_time, + free_update_time, + send_game, + send_amount, + used_amount, + unused_amount, + free_status, + create_by, + create_time, + update_by, + update_time, + + + #{currencyCode}, + #{referenceId}, + #{memberId}, + #{memberAccount}, + #{gameId}, + #{sendTime}, + #{expiredTime}, + #{freeUpdateTime}, + #{sendGame}, + #{sendAmount}, + #{usedAmount}, + #{unusedAmount}, + #{freeStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_free_record + + currency_code = #{currencyCode}, + reference_id = #{referenceId}, + member_id = #{memberId}, + member_account = #{memberAccount}, + game_id = #{gameId}, + send_time = #{sendTime}, + expired_time = #{expiredTime}, + free_update_time = #{freeUpdateTime}, + send_game = #{sendGame}, + send_amount = #{sendAmount}, + used_amount = #{usedAmount}, + unused_amount = #{unusedAmount}, + free_status = #{freeStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_free_record where id = #{id} + + + + delete from ff_game_free_record where id in + + #{id} + + + \ No newline at end of file diff --git a/ff-admin/target/classes/mapper/game/GameMapper.xml b/ff-admin/target/classes/mapper/game/GameMapper.xml new file mode 100644 index 0000000..5c91e38 --- /dev/null +++ b/ff-admin/target/classes/mapper/game/GameMapper.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, sort_no, platform_id, game_code, game_source_type, game_name, freespin, demo_status, stop_status, game_status, create_by, create_time, update_by, update_time from ff_game + + + + + + + + insert into ff_game + + sort_no, + platform_id, + game_code, + game_source_type, + game_name, + freespin, + demo_status, + stop_status, + game_status, + create_by, + create_time, + update_by, + update_time, + + + #{sortNo}, + #{platformId}, + #{gameCode}, + #{gameSourceType}, + #{gameName}, + #{freespin}, + #{demoStatus}, + #{stopStatus}, + #{gameStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game + + sort_no = #{sortNo}, + platform_id = #{platformId}, + game_code = #{gameCode}, + game_source_type = #{gameSourceType}, + game_name = #{gameName}, + freespin = #{freespin}, + demo_status = #{demoStatus}, + stop_status = #{stopStatus}, + game_status = #{gameStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game where id = #{id} + + + + delete from ff_game where id in + + #{id} + + + + + + + + + + \ No newline at end of file diff --git a/ff-admin/target/classes/mapper/game/GamePlatformMapper.xml b/ff-admin/target/classes/mapper/game/GamePlatformMapper.xml new file mode 100644 index 0000000..3a733cd --- /dev/null +++ b/ff-admin/target/classes/mapper/game/GamePlatformMapper.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + select id, sort_no, platform_code, platform_type, platform_name, stop_status, platform_status, create_by, create_time, update_by, update_time from ff_game_platform + + + + + + + + insert into ff_game_platform + + sort_no, + platform_code, + platform_type, + platform_name, + stop_status, + platform_status, + create_by, + create_time, + update_by, + update_time, + + + #{sortNo}, + #{platformCode}, + #{platformType}, + #{platformName}, + #{stopStatus}, + #{platformStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_platform + + sort_no = #{sortNo}, + platform_code = #{platformCode}, + platform_type = #{platformType}, + platform_name = #{platformName}, + stop_status = #{stopStatus}, + platform_status = #{platformStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_platform where id = #{id} + + + + delete from ff_game_platform where id in + + #{id} + + + + + \ No newline at end of file diff --git a/ff-admin/target/classes/mapper/game/GameSecretKeyMapper.xml b/ff-admin/target/classes/mapper/game/GameSecretKeyMapper.xml new file mode 100644 index 0000000..e5968a2 --- /dev/null +++ b/ff-admin/target/classes/mapper/game/GameSecretKeyMapper.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + select id, platform, code, `key`, system_code, lang, system_lang_code, info, create_by, create_time, update_by, update_time from ff_game_secret_key + + + + + + + + insert into ff_game_secret_key + + platform, + code, + `key`, + system_code, + lang, + system_lang_code, + info, + create_by, + create_time, + update_by, + update_time, + + + #{platform}, + #{code}, + #{key}, + #{systemCode}, + #{lang}, + #{systemLangCode}, + #{info}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_game_secret_key + + platform = #{platform}, + code = #{code}, + `key` = #{key}, + system_code = #{systemCode}, + lang = #{lang}, + system_lang_code = #{systemLangCode}, + info = #{info}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_game_secret_key where id = #{id} + + + + delete from ff_game_secret_key where id in + + #{id} + + + + + + + + + \ No newline at end of file diff --git a/ff-admin/target/classes/mapper/member/MemberMapper.xml b/ff-admin/target/classes/mapper/member/MemberMapper.xml new file mode 100644 index 0000000..a5441ee --- /dev/null +++ b/ff-admin/target/classes/mapper/member/MemberMapper.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + select id, tenant_key, member_account, game_account, platform_code, currency_code, create_by, create_time, update_by, update_time from ff_member + + + + + + + + insert into ff_member + + tenant_key, + member_account, + game_account, + platform_code, + currency_code, + create_by, + create_time, + update_by, + update_time, + + + #{tenantKey}, + #{memberAccount}, + #{gameAccount}, + #{platformCode}, + #{currencyCode}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update ff_member + + tenant_key = #{tenantKey}, + member_account = #{memberAccount}, + game_account = #{gameAccount}, + platform_code = #{platformCode}, + currency_code = #{currencyCode}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from ff_member where id = #{id} + + + + delete from ff_member where id in + + #{id} + + + + + + + \ No newline at end of file diff --git a/ff-admin/target/classes/mapper/quartz/SysJobLogMapper.xml b/ff-admin/target/classes/mapper/quartz/SysJobLogMapper.xml new file mode 100644 index 0000000..2a05f6c --- /dev/null +++ b/ff-admin/target/classes/mapper/quartz/SysJobLogMapper.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + select job_log_id, job_name, job_group, invoke_target, job_message, status, exception_info, create_time + from sys_job_log + + + + + + + + + + delete from sys_job_log where job_log_id = #{jobLogId} + + + + delete from sys_job_log where job_log_id in + + #{jobLogId} + + + + + truncate table sys_job_log + + + + insert into sys_job_log( + job_log_id, + job_name, + job_group, + invoke_target, + job_message, + status, + exception_info, + create_time + )values( + #{jobLogId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{jobMessage}, + #{status}, + #{exceptionInfo}, + UNIX_TIMESTAMP() * 1000 + ) + + + diff --git a/ff-admin/target/classes/mapper/quartz/SysJobMapper.xml b/ff-admin/target/classes/mapper/quartz/SysJobMapper.xml new file mode 100644 index 0000000..948b5aa --- /dev/null +++ b/ff-admin/target/classes/mapper/quartz/SysJobMapper.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark + from sys_job + + + + + + + + + + delete from sys_job where job_id = #{jobId} + + + + delete from sys_job where job_id in + + #{jobId} + + + + + update sys_job + + job_name = #{jobName}, + job_group = #{jobGroup}, + invoke_target = #{invokeTarget}, + cron_expression = #{cronExpression}, + misfire_policy = #{misfirePolicy}, + concurrent = #{concurrent}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where job_id = #{jobId} + + + + insert into sys_job( + job_id, + job_name, + job_group, + invoke_target, + cron_expression, + misfire_policy, + concurrent, + status, + remark, + create_by, + create_time + )values( + #{jobId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{cronExpression}, + #{misfirePolicy}, + #{concurrent}, + #{status}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + diff --git a/ff-admin/target/classes/mybatis/mybatis-config.xml b/ff-admin/target/classes/mybatis/mybatis-config.xml new file mode 100644 index 0000000..ac47c03 --- /dev/null +++ b/ff-admin/target/classes/mybatis/mybatis-config.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/ff-base/pom.xml b/ff-base/pom.xml new file mode 100644 index 0000000..2033248 --- /dev/null +++ b/ff-base/pom.xml @@ -0,0 +1,198 @@ + + + 4.0.0 + + ff + com.ff + 0.0.1 + + + com.ff + ff-base + 0.0.1 + ff-base + ff-base + + + + + org.projectlombok + lombok + provided + + + + + + org.springframework.boot + spring-boot-dependencies + 2.5.15 + pom + import + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-aop + + + + + com.alibaba + druid-spring-boot-starter + + + + + pro.fessional + kaptcha + + + + + com.github.oshi + oshi-core + + + + + org.springframework + spring-context-support + + + + + org.springframework + spring-web + + + + + org.springframework.boot + spring-boot-starter-security + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-validation + + + + + org.apache.commons + commons-lang3 + + + + + com.fasterxml.jackson.core + jackson-databind + + + + + com.alibaba.fastjson2 + fastjson2 + + + + + commons-io + commons-io + + + + + org.apache.poi + poi-ooxml + + + + + org.apache.httpcomponents + httpclient + + + + com.squareup.okhttp3 + okhttp + + + + org.yaml + snakeyaml + + + + + io.jsonwebtoken + jjwt + + + + + javax.xml.bind + jaxb-api + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + org.apache.commons + commons-pool2 + + + + + eu.bitwalker + UserAgentUtils + + + + + javax.servlet + javax.servlet-api + + + + + com.google.zxing + core + + + com.google.zxing + javase + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/ff-base/src/main/java/com/ff/base/annotation/Anonymous.java b/ff-base/src/main/java/com/ff/base/annotation/Anonymous.java new file mode 100644 index 0000000..723551d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/annotation/Anonymous.java @@ -0,0 +1,15 @@ +package com.ff.base.annotation; + +import java.lang.annotation.*; + +/** + * 匿名访问不鉴权注解 + * + * @author ff + */ +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Anonymous +{ +} diff --git a/ff-base/src/main/java/com/ff/base/annotation/DataScope.java b/ff-base/src/main/java/com/ff/base/annotation/DataScope.java new file mode 100644 index 0000000..c2bb562 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/annotation/DataScope.java @@ -0,0 +1,29 @@ +package com.ff.base.annotation; + +import java.lang.annotation.*; + +/** + * 数据权限过滤注解 + * + * @author ff + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DataScope +{ + /** + * 部门表的别名 + */ + public String deptAlias() default ""; + + /** + * 用户表的别名 + */ + public String userAlias() default ""; + + /** + * 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来 + */ + public String permission() default ""; +} diff --git a/ff-base/src/main/java/com/ff/base/annotation/DataSource.java b/ff-base/src/main/java/com/ff/base/annotation/DataSource.java new file mode 100644 index 0000000..de37399 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/annotation/DataSource.java @@ -0,0 +1,24 @@ +package com.ff.base.annotation; + +import com.ff.base.enums.DataSourceType; + +import java.lang.annotation.*; + +/** + * 自定义多数据源切换注解 + * + * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准 + * + * @author ff + */ +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +public @interface DataSource +{ + /** + * 切换数据源名称 + */ + public DataSourceType value() default DataSourceType.MASTER; +} diff --git a/ff-base/src/main/java/com/ff/base/annotation/Excel.java b/ff-base/src/main/java/com/ff/base/annotation/Excel.java new file mode 100644 index 0000000..5ffa0f0 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/annotation/Excel.java @@ -0,0 +1,193 @@ +package com.ff.base.annotation; + +import com.ff.base.utils.poi.ExcelHandlerAdapter; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.math.BigDecimal; + +/** + * 自定义导出Excel数据注解 + * + * @author ff + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Excel +{ + /** + * 导出时在excel中排序 + */ + public int sort() default Integer.MAX_VALUE; + + /** + * 导出到Excel中的名字. + */ + public String name() default ""; + + /** + * 日期格式, 如: yyyy-MM-dd + */ + public String dateFormat() default ""; + + /** + * 如果是字典类型,请设置字典的type值 (如: sys_user_sex) + */ + public String dictType() default ""; + + /** + * 读取内容转表达式 (如: 0=男,1=女,2=未知) + */ + public String readConverterExp() default ""; + + /** + * 分隔符,读取字符串组内容 + */ + public String separator() default ","; + + /** + * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化) + */ + public int scale() default -1; + + /** + * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN + */ + public int roundingMode() default BigDecimal.ROUND_HALF_EVEN; + + /** + * 导出时在excel中每个列的高度 + */ + public double height() default 14; + + /** + * 导出时在excel中每个列的宽度 + */ + public double width() default 16; + + /** + * 文字后缀,如% 90 变成90% + */ + public String suffix() default ""; + + /** + * 当值为空时,字段的默认值 + */ + public String defaultValue() default ""; + + /** + * 提示信息 + */ + public String prompt() default ""; + + /** + * 设置只能选择不能输入的列内容. + */ + public String[] combo() default {}; + + /** + * 是否从字典读数据到combo,默认不读取,如读取需要设置dictType注解. + */ + public boolean comboReadDict() default false; + + /** + * 是否需要纵向合并单元格,应对需求:含有list集合单元格) + */ + public boolean needMerge() default false; + + /** + * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. + */ + public boolean isExport() default true; + + /** + * 另一个类中的属性名称,支持多级获取,以小数点隔开 + */ + public String targetAttr() default ""; + + /** + * 是否自动统计数据,在最后追加一行统计数据总和 + */ + public boolean isStatistics() default false; + + /** + * 导出类型(0数字 1字符串 2图片) + */ + public ColumnType cellType() default ColumnType.STRING; + + /** + * 导出列头背景颜色 + */ + public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT; + + /** + * 导出列头字体颜色 + */ + public IndexedColors headerColor() default IndexedColors.WHITE; + + /** + * 导出单元格背景颜色 + */ + public IndexedColors backgroundColor() default IndexedColors.WHITE; + + /** + * 导出单元格字体颜色 + */ + public IndexedColors color() default IndexedColors.BLACK; + + /** + * 导出字段对齐方式 + */ + public HorizontalAlignment align() default HorizontalAlignment.CENTER; + + /** + * 自定义数据处理器 + */ + public Class handler() default ExcelHandlerAdapter.class; + + /** + * 自定义数据处理器参数 + */ + public String[] args() default {}; + + /** + * 字段类型(0:导出导入;1:仅导出;2:仅导入) + */ + Type type() default Type.ALL; + + public enum Type + { + ALL(0), EXPORT(1), IMPORT(2); + private final int value; + + Type(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } + + public enum ColumnType + { + NUMERIC(0), STRING(1), IMAGE(2), TEXT(3); + private final int value; + + ColumnType(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } +} diff --git a/ff-base/src/main/java/com/ff/base/annotation/Excels.java b/ff-base/src/main/java/com/ff/base/annotation/Excels.java new file mode 100644 index 0000000..8a1e940 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/annotation/Excels.java @@ -0,0 +1,20 @@ +package com.ff.base.annotation; + +import com.ff.base.annotation.Excel; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Excel注解集 + * + * @author ff + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Excels +{ + public Excel[] value(); +} diff --git a/ff-base/src/main/java/com/ff/base/annotation/Log.java b/ff-base/src/main/java/com/ff/base/annotation/Log.java new file mode 100644 index 0000000..8616ae2 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/annotation/Log.java @@ -0,0 +1,48 @@ +package com.ff.base.annotation; + +import com.ff.base.enums.BusinessType; +import com.ff.base.enums.OperatorType; + +import java.lang.annotation.*; + +/** + * 自定义操作日志记录注解 + * + * @author ff + * + */ +@Target({ ElementType.PARAMETER, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Log +{ + /** + * 模块 + */ + public String title() default ""; + + /** + * 功能 + */ + public BusinessType businessType() default BusinessType.OTHER; + + /** + * 操作人类别 + */ + public OperatorType operatorType() default OperatorType.MANAGE; + + /** + * 是否保存请求的参数 + */ + public boolean isSaveRequestData() default true; + + /** + * 是否保存响应的参数 + */ + public boolean isSaveResponseData() default true; + + /** + * 排除指定的请求参数 + */ + public String[] excludeParamNames() default {}; +} diff --git a/ff-base/src/main/java/com/ff/base/annotation/RateLimiter.java b/ff-base/src/main/java/com/ff/base/annotation/RateLimiter.java new file mode 100644 index 0000000..e778d46 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/annotation/RateLimiter.java @@ -0,0 +1,37 @@ +package com.ff.base.annotation; + +import com.ff.base.constant.CacheConstants; +import com.ff.base.enums.LimitType; + +import java.lang.annotation.*; + +/** + * 限流注解 + * + * @author ff + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RateLimiter +{ + /** + * 限流key + */ + public String key() default CacheConstants.RATE_LIMIT_KEY; + + /** + * 限流时间,单位秒 + */ + public int time() default 60; + + /** + * 限流次数 + */ + public int count() default 100; + + /** + * 限流类型 + */ + public LimitType limitType() default LimitType.DEFAULT; +} diff --git a/ff-base/src/main/java/com/ff/base/annotation/RepeatSubmit.java b/ff-base/src/main/java/com/ff/base/annotation/RepeatSubmit.java new file mode 100644 index 0000000..cd6d242 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/annotation/RepeatSubmit.java @@ -0,0 +1,26 @@ +package com.ff.base.annotation; + +import java.lang.annotation.*; + +/** + * 自定义注解防止表单重复提交 + * + * @author ff + * + */ +@Inherited +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RepeatSubmit +{ + /** + * 间隔时间(ms),小于此时间视为重复提交 + */ + public int interval() default 5000; + + /** + * 提示消息 + */ + public String message() default "不允许重复提交,请稍候再试"; +} diff --git a/ff-base/src/main/java/com/ff/base/annotation/Sensitive.java b/ff-base/src/main/java/com/ff/base/annotation/Sensitive.java new file mode 100644 index 0000000..2689b44 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/annotation/Sensitive.java @@ -0,0 +1,25 @@ +package com.ff.base.annotation; + +import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.ff.base.config.serializer.SensitiveJsonSerializer; +import com.ff.base.enums.DesensitizedType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 数据脱敏注解 + * + * @author ff + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@JacksonAnnotationsInside +@JsonSerialize(using = SensitiveJsonSerializer.class) +public @interface Sensitive +{ + DesensitizedType desensitizedType(); +} diff --git a/ff-base/src/main/java/com/ff/base/aspectj/DataScopeAspect.java b/ff-base/src/main/java/com/ff/base/aspectj/DataScopeAspect.java new file mode 100644 index 0000000..db84520 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/aspectj/DataScopeAspect.java @@ -0,0 +1,185 @@ +package com.ff.base.aspectj; + +import com.ff.base.annotation.DataScope; +import com.ff.base.core.domain.BaseEntity; +import com.ff.base.system.domain.SysRole; +import com.ff.base.system.domain.SysUser; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.core.text.Convert; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.security.context.PermissionContextHolder; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +/** + * 数据过滤处理 + * + * @author ff + */ +@Aspect +@Component +public class DataScopeAspect +{ + /** + * 全部数据权限 + */ + public static final String DATA_SCOPE_ALL = "1"; + + /** + * 自定数据权限 + */ + public static final String DATA_SCOPE_CUSTOM = "2"; + + /** + * 部门数据权限 + */ + public static final String DATA_SCOPE_DEPT = "3"; + + /** + * 部门及以下数据权限 + */ + public static final String DATA_SCOPE_DEPT_AND_CHILD = "4"; + + /** + * 仅本人数据权限 + */ + public static final String DATA_SCOPE_SELF = "5"; + + /** + * 数据权限过滤关键字 + */ + public static final String DATA_SCOPE = "dataScope"; + + @Before("@annotation(controllerDataScope)") + public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable + { + clearDataScope(point); + handleDataScope(point, controllerDataScope); + } + + protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) + { + // 获取当前的用户 + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNotNull(loginUser)) + { + SysUser currentUser = loginUser.getUser(); + // 如果是超级管理员,则不过滤数据 + if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) + { + String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext()); + dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), + controllerDataScope.userAlias(), permission); + } + } + } + + /** + * 数据范围过滤 + * + * @param joinPoint 切点 + * @param user 用户 + * @param deptAlias 部门别名 + * @param userAlias 用户别名 + * @param permission 权限字符 + */ + public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission) + { + StringBuilder sqlString = new StringBuilder(); + List conditions = new ArrayList(); + List scopeCustomIds = new ArrayList(); + user.getRoles().forEach(role -> { + if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) + { + scopeCustomIds.add(Convert.toStr(role.getRoleId())); + } + }); + + for (SysRole role : user.getRoles()) + { + String dataScope = role.getDataScope(); + if (conditions.contains(dataScope)) + { + continue; + } + if (!StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) + { + continue; + } + if (DATA_SCOPE_ALL.equals(dataScope)) + { + sqlString = new StringBuilder(); + conditions.add(dataScope); + break; + } + else if (DATA_SCOPE_CUSTOM.equals(dataScope)) + { + if (scopeCustomIds.size() > 1) + { + // 多个自定数据权限使用in查询,避免多次拼接。 + sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id in ({}) ) ", deptAlias, String.join(",", scopeCustomIds))); + } + else + { + sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, role.getRoleId())); + } + } + else if (DATA_SCOPE_DEPT.equals(dataScope)) + { + sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId())); + } + else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) + { + sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", deptAlias, user.getDeptId(), user.getDeptId())); + } + else if (DATA_SCOPE_SELF.equals(dataScope)) + { + if (StringUtils.isNotBlank(userAlias)) + { + sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId())); + } + else + { + // 数据权限为仅本人且没有userAlias别名不查询任何数据 + sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias)); + } + } + conditions.add(dataScope); + } + + // 角色都不包含传递过来的权限字符,这个时候sqlString也会为空,所以要限制一下,不查询任何数据 + if (StringUtils.isEmpty(conditions)) + { + sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias)); + } + + if (StringUtils.isNotBlank(sqlString.toString())) + { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params) && params instanceof BaseEntity) + { + BaseEntity baseEntity = (BaseEntity) params; + baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")"); + } + } + } + + /** + * 拼接权限sql前先清空params.dataScope参数防止注入 + */ + private void clearDataScope(final JoinPoint joinPoint) + { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params) && params instanceof BaseEntity) + { + BaseEntity baseEntity = (BaseEntity) params; + baseEntity.getParams().put(DATA_SCOPE, ""); + } + } +} diff --git a/ff-base/src/main/java/com/ff/base/aspectj/DataSourceAspect.java b/ff-base/src/main/java/com/ff/base/aspectj/DataSourceAspect.java new file mode 100644 index 0000000..ead00f0 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/aspectj/DataSourceAspect.java @@ -0,0 +1,73 @@ +package com.ff.base.aspectj; + +import com.ff.base.annotation.DataSource; +import com.ff.base.utils.StringUtils; +import com.ff.base.datasource.DynamicDataSourceContextHolder; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.Objects; + +/** + * 多数据源处理 + * + * @author ff + */ +@Aspect +@Order(1) +@Component +public class DataSourceAspect +{ + protected Logger logger = LoggerFactory.getLogger(getClass()); + + @Pointcut("@annotation(com.ff.base.annotation.DataSource)" + + "|| @within(com.ff.base.annotation.DataSource)") + public void dsPointCut() + { + + } + + @Around("dsPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable + { + DataSource dataSource = getDataSource(point); + + if (StringUtils.isNotNull(dataSource)) + { + DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name()); + } + + try + { + return point.proceed(); + } + finally + { + // 销毁数据源 在执行方法之后 + DynamicDataSourceContextHolder.clearDataSourceType(); + } + } + + /** + * 获取需要切换的数据源 + */ + public DataSource getDataSource(ProceedingJoinPoint point) + { + MethodSignature signature = (MethodSignature) point.getSignature(); + DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class); + if (Objects.nonNull(dataSource)) + { + return dataSource; + } + + return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class); + } +} diff --git a/ff-base/src/main/java/com/ff/base/aspectj/LogAspect.java b/ff-base/src/main/java/com/ff/base/aspectj/LogAspect.java new file mode 100644 index 0000000..cf3d912 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/aspectj/LogAspect.java @@ -0,0 +1,256 @@ +package com.ff.base.aspectj; + +import com.alibaba.fastjson2.JSON; +import com.ff.base.annotation.Log; +import com.ff.base.system.domain.SysUser; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.enums.BusinessStatus; +import com.ff.base.enums.HttpMethod; +import com.ff.base.filter.PropertyPreExcludeFilter; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.ServletUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.ip.IpUtils; +import com.ff.base.manager.AsyncManager; +import com.ff.base.manager.factory.AsyncFactory; +import com.ff.base.system.domain.SysOperLog; +import org.apache.commons.lang3.ArrayUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.NamedThreadLocal; +import org.springframework.stereotype.Component; +import org.springframework.validation.BindingResult; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Collection; +import java.util.Map; + +/** + * 操作日志记录处理 + * + * @author ff + */ +@Aspect +@Component +public class LogAspect +{ + private static final Logger log = LoggerFactory.getLogger(LogAspect.class); + + /** 排除敏感属性字段 */ + public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" }; + + /** 计算操作消耗时间 */ + private static final ThreadLocal TIME_THREADLOCAL = new NamedThreadLocal("Cost Time"); + + /** + * 处理请求前执行 + */ + @Before(value = "@annotation(controllerLog)") + public void boBefore(JoinPoint joinPoint, Log controllerLog) + { + TIME_THREADLOCAL.set(System.currentTimeMillis()); + } + + /** + * 处理完请求后执行 + * + * @param joinPoint 切点 + */ + @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult") + public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) + { + handleLog(joinPoint, controllerLog, null, jsonResult); + } + + /** + * 拦截异常操作 + * + * @param joinPoint 切点 + * @param e 异常 + */ + @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) + { + handleLog(joinPoint, controllerLog, e, null); + } + + protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) + { + try + { + // 获取当前的用户 + LoginUser loginUser = SecurityUtils.getLoginUser(); + + // *========数据库日志=========*// + SysOperLog operLog = new SysOperLog(); + operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); + // 请求的地址 + String ip = IpUtils.getIpAddr(); + operLog.setOperIp(ip); + operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255)); + if (loginUser != null) + { + operLog.setOperName(loginUser.getUsername()); + SysUser currentUser = loginUser.getUser(); + if (StringUtils.isNotNull(currentUser) && StringUtils.isNotNull(currentUser.getDept())) + { + operLog.setDeptName(currentUser.getDept().getDeptName()); + } + } + + if (e != null) + { + operLog.setStatus(BusinessStatus.FAIL.ordinal()); + operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); + } + // 设置方法名称 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = joinPoint.getSignature().getName(); + operLog.setMethod(className + "." + methodName + "()"); + // 设置请求方式 + operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); + // 处理设置注解上的参数 + getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); + // 设置消耗时间 + operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get()); + // 保存数据库 + AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); + } + catch (Exception exp) + { + // 记录本地异常日志 + log.error("异常信息:{}", exp.getMessage()); + exp.printStackTrace(); + } + finally + { + TIME_THREADLOCAL.remove(); + } + } + + /** + * 获取注解中对方法的描述信息 用于Controller层注解 + * + * @param log 日志 + * @param operLog 操作日志 + * @throws Exception + */ + public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception + { + // 设置action动作 + operLog.setBusinessType(log.businessType().ordinal()); + // 设置标题 + operLog.setTitle(log.title()); + // 设置操作人类别 + operLog.setOperatorType(log.operatorType().ordinal()); + // 是否需要保存request,参数和值 + if (log.isSaveRequestData()) + { + // 获取参数的信息,传入到数据库中。 + setRequestValue(joinPoint, operLog, log.excludeParamNames()); + } + // 是否需要保存response,参数和值 + if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) + { + operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000)); + } + } + + /** + * 获取请求的参数,放到log中 + * + * @param operLog 操作日志 + * @throws Exception 异常 + */ + private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception + { + Map paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest()); + String requestMethod = operLog.getRequestMethod(); + if (StringUtils.isEmpty(paramsMap) + && (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))) + { + String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames); + operLog.setOperParam(StringUtils.substring(params, 0, 2000)); + } + else + { + operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000)); + } + } + + /** + * 参数拼装 + */ + private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames) + { + String params = ""; + if (paramsArray != null && paramsArray.length > 0) + { + for (Object o : paramsArray) + { + if (StringUtils.isNotNull(o) && !isFilterObject(o)) + { + try + { + String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames)); + params += jsonObj.toString() + " "; + } + catch (Exception e) + { + } + } + } + } + return params.trim(); + } + + /** + * 忽略敏感属性 + */ + public PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames) + { + return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames)); + } + + /** + * 判断是否需要过滤的对象。 + * + * @param o 对象信息。 + * @return 如果是需要过滤的对象,则返回true;否则返回false。 + */ + @SuppressWarnings("rawtypes") + public boolean isFilterObject(final Object o) + { + Class clazz = o.getClass(); + if (clazz.isArray()) + { + return clazz.getComponentType().isAssignableFrom(MultipartFile.class); + } + else if (Collection.class.isAssignableFrom(clazz)) + { + Collection collection = (Collection) o; + for (Object value : collection) + { + return value instanceof MultipartFile; + } + } + else if (Map.class.isAssignableFrom(clazz)) + { + Map map = (Map) o; + for (Object value : map.entrySet()) + { + Map.Entry entry = (Map.Entry) value; + return entry.getValue() instanceof MultipartFile; + } + } + return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse + || o instanceof BindingResult; + } +} diff --git a/ff-base/src/main/java/com/ff/base/aspectj/RateLimiterAspect.java b/ff-base/src/main/java/com/ff/base/aspectj/RateLimiterAspect.java new file mode 100644 index 0000000..25fb735 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/aspectj/RateLimiterAspect.java @@ -0,0 +1,91 @@ +package com.ff.base.aspectj; + +import com.ff.base.annotation.RateLimiter; +import com.ff.base.enums.LimitType; +import com.ff.base.exception.ServiceException; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.TenantUtils; +import com.ff.base.utils.ip.IpUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.script.RedisScript; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.List; + +/** + * 限流处理 + * + * @author ff + */ +@Aspect +@Component +public class RateLimiterAspect +{ + private static final Logger log = LoggerFactory.getLogger(RateLimiterAspect.class); + + private RedisTemplate redisTemplate; + + private RedisScript limitScript; + + @Autowired + public void setRedisTemplate1(RedisTemplate redisTemplate) + { + this.redisTemplate = redisTemplate; + } + + @Autowired + public void setLimitScript(RedisScript limitScript) + { + this.limitScript = limitScript; + } + + @Before("@annotation(rateLimiter)") + public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable + { + int time = rateLimiter.time(); + int count = rateLimiter.count(); + + String combineKey = TenantUtils.getTenantIdRedis(getCombineKey(rateLimiter, point)) ; + List keys = Collections.singletonList(combineKey); + try + { + Long number = redisTemplate.execute(limitScript, keys, count, time); + if (StringUtils.isNull(number) || number.intValue() > count) + { + throw new ServiceException("访问过于频繁,请稍候再试"); + } + log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), combineKey); + } + catch (ServiceException e) + { + throw e; + } + catch (Exception e) + { + throw new RuntimeException("服务器限流异常,请稍候再试"); + } + } + + public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) + { + StringBuffer stringBuffer = new StringBuffer(rateLimiter.key()); + if (rateLimiter.limitType() == LimitType.IP) + { + stringBuffer.append(IpUtils.getIpAddr()).append("-"); + } + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = signature.getMethod(); + Class targetClass = method.getDeclaringClass(); + stringBuffer.append(targetClass.getName()).append("-").append(method.getName()); + return stringBuffer.toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/ApplicationConfig.java b/ff-base/src/main/java/com/ff/base/config/ApplicationConfig.java new file mode 100644 index 0000000..2ccf934 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/ApplicationConfig.java @@ -0,0 +1,31 @@ +package com.ff.base.config; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +import java.util.TimeZone; + +/** + * 程序注解配置 + * + * @author ff + */ +@Configuration +// 表示通过aop框架暴露该代理对象,AopContext能够访问 +@EnableAspectJAutoProxy(exposeProxy = true) +// 指定要扫描的Mapper类的包的路径 +@MapperScan("com.ff.**.mapper") +public class ApplicationConfig +{ + /** + * 时区配置 + */ + @Bean + public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() + { + return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault()); + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/AsyncConfig.java b/ff-base/src/main/java/com/ff/base/config/AsyncConfig.java new file mode 100644 index 0000000..7379d18 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/AsyncConfig.java @@ -0,0 +1,17 @@ +package com.ff.base.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; + +/** + * 异步配置 + * + * @author shi + * @date 2024/12/14 + */ +@EnableAsync +@Configuration +public class AsyncConfig { + + +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/config/CaptchaConfig.java b/ff-base/src/main/java/com/ff/base/config/CaptchaConfig.java new file mode 100644 index 0000000..a1eca61 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/CaptchaConfig.java @@ -0,0 +1,85 @@ +package com.ff.base.config; + +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.google.code.kaptcha.util.Config; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Properties; + +import static com.google.code.kaptcha.Constants.*; + +/** + * 验证码配置 + * + * @author ff + */ +@Configuration +public class CaptchaConfig +{ + @Bean(name = "captchaProducer") + public DefaultKaptcha getKaptchaBean() + { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } + + @Bean(name = "captchaProducerMath") + public DefaultKaptcha getKaptchaBeanMath() + { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 边框颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); + // 验证码文本生成器 + properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ff.base.config.KaptchaTextCreator"); + // 验证码文本字符间距 默认为2 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6"); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 验证码噪点颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_NOISE_COLOR, "white"); + // 干扰实现类 + properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/DruidConfig.java b/ff-base/src/main/java/com/ff/base/config/DruidConfig.java new file mode 100644 index 0000000..f29bf27 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/DruidConfig.java @@ -0,0 +1,112 @@ +package com.ff.base.config; + +import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; +import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties; +import com.alibaba.druid.util.Utils; +import com.ff.base.datasource.DynamicDataSource; +import com.ff.base.enums.DataSourceType; +import com.ff.base.utils.spring.SpringUtils; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +import javax.servlet.*; +import javax.sql.DataSource; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * druid 配置多数据源 + * + * @author ff + */ +@Configuration +public class DruidConfig +{ + @Bean + @ConfigurationProperties("spring.datasource.druid.master") + public DataSource masterDataSource() + { + return DruidDataSourceBuilder.create().build(); + } + + + @Bean(name = "dynamicDataSource") + @Primary + public DynamicDataSource dataSource() + { + Map targetDataSources = new HashMap<>(); + DataSource defaultDataSource = masterDataSource(); + targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource()); + return new DynamicDataSource(defaultDataSource, targetDataSources); + } + + /** + * 设置数据源 + * + * @param targetDataSources 备选数据源集合 + * @param sourceName 数据源名称 + * @param beanName bean名称 + */ + public void setDataSource(Map targetDataSources, String sourceName, String beanName) + { + try + { + DataSource dataSource = SpringUtils.getBean(beanName); + targetDataSources.put(sourceName, dataSource); + } + catch (Exception e) + { + } + } + + /** + * 去除监控页面底部的广告 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true") + public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) + { + // 获取web监控页面的参数 + DruidStatProperties.StatViewServlet config = properties.getStatViewServlet(); + // 提取common.js的配置路径 + String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*"; + String commonJsPattern = pattern.replaceAll("\\*", "js/common.js"); + final String filePath = "support/http/resources/js/common.js"; + // 创建filter进行过滤 + Filter filter = new Filter() + { + @Override + public void init(javax.servlet.FilterConfig filterConfig) throws ServletException + { + } + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + chain.doFilter(request, response); + // 重置缓冲区,响应头不会被重置 + response.resetBuffer(); + // 获取common.js + String text = Utils.readFromResource(filePath); + // 正则替换banner, 除去底部的广告信息 + text = text.replaceAll("
", ""); + text = text.replaceAll("powered.*?shrek.wang", ""); + response.getWriter().write(text); + } + @Override + public void destroy() + { + } + }; + FilterRegistrationBean registrationBean = new FilterRegistrationBean(); + registrationBean.setFilter(filter); + registrationBean.addUrlPatterns(commonJsPattern); + return registrationBean; + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/FFConfig.java b/ff-base/src/main/java/com/ff/base/config/FFConfig.java new file mode 100644 index 0000000..dbafb0a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/FFConfig.java @@ -0,0 +1,122 @@ +package com.ff.base.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 读取项目相关配置 + * + * @author ff + */ +@Component +@ConfigurationProperties(prefix = "ff") +public class FFConfig +{ + /** 项目名称 */ + private String name; + + /** 版本 */ + private String version; + + /** 版权年份 */ + private String copyrightYear; + + /** 上传路径 */ + private static String profile; + + /** 获取地址开关 */ + private static boolean addressEnabled; + + /** 验证码类型 */ + private static String captchaType; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getVersion() + { + return version; + } + + public void setVersion(String version) + { + this.version = version; + } + + public String getCopyrightYear() + { + return copyrightYear; + } + + public void setCopyrightYear(String copyrightYear) + { + this.copyrightYear = copyrightYear; + } + + public static String getProfile() + { + return profile; + } + + public void setProfile(String profile) + { + FFConfig.profile = profile; + } + + public static boolean isAddressEnabled() + { + return addressEnabled; + } + + public void setAddressEnabled(boolean addressEnabled) + { + FFConfig.addressEnabled = addressEnabled; + } + + public static String getCaptchaType() { + return captchaType; + } + + public void setCaptchaType(String captchaType) { + FFConfig.captchaType = captchaType; + } + + /** + * 获取导入上传路径 + */ + public static String getImportPath() + { + return getProfile() + "/import"; + } + + /** + * 获取头像上传路径 + */ + public static String getAvatarPath() + { + return getProfile() + "/avatar"; + } + + /** + * 获取下载路径 + */ + public static String getDownloadPath() + { + return getProfile() + "/download/"; + } + + /** + * 获取上传路径 + */ + public static String getUploadPath() + { + return getProfile() + "/upload"; + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/FastJson2JsonRedisSerializer.java b/ff-base/src/main/java/com/ff/base/config/FastJson2JsonRedisSerializer.java new file mode 100644 index 0000000..f1cd58b --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/FastJson2JsonRedisSerializer.java @@ -0,0 +1,53 @@ +package com.ff.base.config; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.JSONWriter; +import com.alibaba.fastjson2.filter.Filter; +import com.ff.base.constant.Constants; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.SerializationException; + +import java.nio.charset.Charset; + +/** + * Redis使用FastJson序列化 + * + * @author ff + */ +public class FastJson2JsonRedisSerializer implements RedisSerializer +{ + public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + + static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(Constants.JSON_WHITELIST_STR); + + private Class clazz; + + public FastJson2JsonRedisSerializer(Class clazz) + { + super(); + this.clazz = clazz; + } + + @Override + public byte[] serialize(T t) throws SerializationException + { + if (t == null) + { + return new byte[0]; + } + return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET); + } + + @Override + public T deserialize(byte[] bytes) throws SerializationException + { + if (bytes == null || bytes.length <= 0) + { + return null; + } + String str = new String(bytes, DEFAULT_CHARSET); + + return JSON.parseObject(str, clazz, AUTO_TYPE_FILTER); + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/FilterConfig.java b/ff-base/src/main/java/com/ff/base/config/FilterConfig.java new file mode 100644 index 0000000..04b3ca4 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/FilterConfig.java @@ -0,0 +1,59 @@ +package com.ff.base.config; + +import com.ff.base.filter.RepeatableFilter; +import com.ff.base.filter.XssFilter; +import com.ff.base.utils.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.servlet.DispatcherType; +import java.util.HashMap; +import java.util.Map; + +/** + * Filter配置 + * + * @author ff + */ +@Configuration +public class FilterConfig +{ + @Value("${xss.excludes}") + private String excludes; + + @Value("${xss.urlPatterns}") + private String urlPatterns; + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + @ConditionalOnProperty(value = "xss.enabled", havingValue = "true") + public FilterRegistrationBean xssFilterRegistration() + { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setDispatcherTypes(DispatcherType.REQUEST); + registration.setFilter(new XssFilter()); + registration.addUrlPatterns(StringUtils.split(urlPatterns, ",")); + registration.setName("xssFilter"); + registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); + Map initParameters = new HashMap(); + initParameters.put("excludes", excludes); + registration.setInitParameters(initParameters); + return registration; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + public FilterRegistrationBean someFilterRegistration() + { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setFilter(new RepeatableFilter()); + registration.addUrlPatterns("/*"); + registration.setName("repeatableFilter"); + registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE); + return registration; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/config/I18nConfig.java b/ff-base/src/main/java/com/ff/base/config/I18nConfig.java new file mode 100644 index 0000000..05b77d0 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/I18nConfig.java @@ -0,0 +1,60 @@ +package com.ff.base.config; + +import com.ff.base.constant.Constants; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; +import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; + +/** + * 资源文件配置加载 + * + * @author ff + */ +@Configuration +@Slf4j +public class I18nConfig implements WebMvcConfigurer { + + private final List LOCALELIST = Arrays.asList( + new Locale("bn", "IN"), new Locale("da", "DK"), new Locale("de", "DE"), new Locale("en", "US"), + new Locale("es", "AR"), new Locale("fr", "FR"), new Locale("gr", "GR"), new Locale("hi", "IN"), + new Locale("id", "ID"), new Locale("it", "IT"), new Locale("ja", "JP"), new Locale("ko", "KR"), + new Locale("ms", "MY"), new Locale("my", "MM"), new Locale("nl", "NL"), new Locale("pt", "BR"), + new Locale("ro", "RO"), new Locale("ru", "RU"), new Locale("th", "TH"), new Locale("vi", "VN"), + new Locale("zh", "CN") + ); + + @Bean + public LocaleResolver localeResolver() { + AcceptHeaderLocaleResolver slr = new AcceptHeaderLocaleResolver(); + // 默认语言 + slr.setDefaultLocale(Constants.DEFAULT_LOCALE); + // 支持的所有语言 + slr.setSupportedLocales(LOCALELIST); + return slr; + } + + + @Bean + public LocaleChangeInterceptor localeChangeInterceptor() { + LocaleChangeInterceptor lci = new LocaleChangeInterceptor(); + // 参数名 + lci.setParamName("lang"); + return lci; + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(localeChangeInterceptor()); + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/IdGeneratorUtil.java b/ff-base/src/main/java/com/ff/base/config/IdGeneratorUtil.java new file mode 100644 index 0000000..7e4257d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/IdGeneratorUtil.java @@ -0,0 +1,34 @@ +package com.ff.base.config; + +import com.ff.base.utils.SnowflakeIdGenerator; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +/** + * 雪花算法id + * + * @author liukang + * @date 2024-11-04 + */ +@Configuration +public class IdGeneratorUtil { + + private static SnowflakeIdGenerator snowflakeIdGenerator; + + @Value("${snowflake.worker.id}") + private long workerId; + + @Value("${snowflake.datacenter.id}") + private long dataCenterId; + + public void init() { + snowflakeIdGenerator = new SnowflakeIdGenerator(workerId, dataCenterId); + } + + public static long generateId() { + if (snowflakeIdGenerator == null) { + throw new IllegalStateException("SnowflakeIdGenerator is not initialized"); + } + return snowflakeIdGenerator.nextId(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/JacksonConfig.java b/ff-base/src/main/java/com/ff/base/config/JacksonConfig.java new file mode 100644 index 0000000..ab94743 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/JacksonConfig.java @@ -0,0 +1,24 @@ +package com.ff.base.config; + +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +/** + * 序列化配置 + * + * @author ff + */ +@Configuration +public class JacksonConfig { + + + /** * Jackson全局转化long类型为String,解决jackson序列化时long类型缺失精度问题 * @return Jackson2ObjectMapperBuilderCustomizer 注入的对象 */ + @Bean + public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { + + return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder + .serializerByType(Long.class, ToStringSerializer.instance) + .serializerByType(Long.TYPE, ToStringSerializer.instance); + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/KaptchaTextCreator.java b/ff-base/src/main/java/com/ff/base/config/KaptchaTextCreator.java new file mode 100644 index 0000000..94f56b8 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/KaptchaTextCreator.java @@ -0,0 +1,69 @@ +package com.ff.base.config; + +import com.google.code.kaptcha.text.impl.DefaultTextCreator; + +import java.util.Random; + +/** + * 验证码文本生成器 + * + * @author ff + */ +public class KaptchaTextCreator extends DefaultTextCreator +{ + private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(","); + + @Override + public String getText() + { + Integer result = 0; + Random random = new Random(); + int x = random.nextInt(10); + int y = random.nextInt(10); + StringBuilder suChinese = new StringBuilder(); + int randomoperands = random.nextInt(3); + if (randomoperands == 0) + { + result = x * y; + suChinese.append(CNUMBERS[x]); + suChinese.append("*"); + suChinese.append(CNUMBERS[y]); + } + else if (randomoperands == 1) + { + if ((x != 0) && y % x == 0) + { + result = y / x; + suChinese.append(CNUMBERS[y]); + suChinese.append("/"); + suChinese.append(CNUMBERS[x]); + } + else + { + result = x + y; + suChinese.append(CNUMBERS[x]); + suChinese.append("+"); + suChinese.append(CNUMBERS[y]); + } + } + else + { + if (x >= y) + { + result = x - y; + suChinese.append(CNUMBERS[x]); + suChinese.append("-"); + suChinese.append(CNUMBERS[y]); + } + else + { + result = y - x; + suChinese.append(CNUMBERS[y]); + suChinese.append("-"); + suChinese.append(CNUMBERS[x]); + } + } + suChinese.append("=?@" + result); + return suChinese.toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/MyBatisConfig.java b/ff-base/src/main/java/com/ff/base/config/MyBatisConfig.java new file mode 100644 index 0000000..4ba23eb --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/MyBatisConfig.java @@ -0,0 +1,133 @@ +package com.ff.base.config; + +import com.ff.base.utils.StringUtils; +import org.apache.ibatis.io.VFS; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.boot.autoconfigure.SpringBootVFS; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.core.type.classreading.CachingMetadataReaderFactory; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.classreading.MetadataReaderFactory; +import org.springframework.util.ClassUtils; + +import javax.sql.DataSource; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +/** + * Mybatis支持*匹配扫描包 + * + * @author ff + */ +@Configuration +public class MyBatisConfig +{ + @Autowired + private Environment env; + + static final String DEFAULT_RESOURCE_PATTERN = "**/*.class"; + + public static String setTypeAliasesPackage(String typeAliasesPackage) + { + ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver(); + MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver); + List allResult = new ArrayList(); + try + { + for (String aliasesPackage : typeAliasesPackage.split(",")) + { + List result = new ArrayList(); + aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN; + Resource[] resources = resolver.getResources(aliasesPackage); + if (resources != null && resources.length > 0) + { + MetadataReader metadataReader = null; + for (Resource resource : resources) + { + if (resource.isReadable()) + { + metadataReader = metadataReaderFactory.getMetadataReader(resource); + try + { + result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName()); + } + catch (ClassNotFoundException e) + { + e.printStackTrace(); + } + } + } + } + if (result.size() > 0) + { + HashSet hashResult = new HashSet(result); + allResult.addAll(hashResult); + } + } + if (allResult.size() > 0) + { + typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0])); + } + else + { + throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包"); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + return typeAliasesPackage; + } + + public Resource[] resolveMapperLocations(String[] mapperLocations) + { + ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); + List resources = new ArrayList(); + if (mapperLocations != null) + { + for (String mapperLocation : mapperLocations) + { + try + { + Resource[] mappers = resourceResolver.getResources(mapperLocation); + resources.addAll(Arrays.asList(mappers)); + } + catch (IOException e) + { + // ignore + } + } + } + return resources.toArray(new Resource[resources.size()]); + } + + @Bean + public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception + { + String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage"); + String mapperLocations = env.getProperty("mybatis.mapperLocations"); + String configLocation = env.getProperty("mybatis.configLocation"); + typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage); + VFS.addImplClass(SpringBootVFS.class); + + final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); + sessionFactory.setDataSource(dataSource); + sessionFactory.setTypeAliasesPackage(typeAliasesPackage); + sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ","))); + sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation)); + return sessionFactory.getObject(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/RedisConfig.java b/ff-base/src/main/java/com/ff/base/config/RedisConfig.java new file mode 100644 index 0000000..eaaaeba --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/RedisConfig.java @@ -0,0 +1,69 @@ +package com.ff.base.config; + +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.script.DefaultRedisScript; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * redis配置 + * + * @author ff + */ +@Configuration +@EnableCaching +public class RedisConfig extends CachingConfigurerSupport +{ + @Bean + @SuppressWarnings(value = { "unchecked", "rawtypes" }) + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) + { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(connectionFactory); + + FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); + + // 使用StringRedisSerializer来序列化和反序列化redis的key值 + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(serializer); + + // Hash的key也采用StringRedisSerializer的序列化方式 + template.setHashKeySerializer(new StringRedisSerializer()); + template.setHashValueSerializer(serializer); + + template.afterPropertiesSet(); + return template; + } + + @Bean + public DefaultRedisScript limitScript() + { + DefaultRedisScript redisScript = new DefaultRedisScript<>(); + redisScript.setScriptText(limitScriptText()); + redisScript.setResultType(Long.class); + return redisScript; + } + + /** + * 限流脚本 + */ + private String limitScriptText() + { + return "local key = KEYS[1]\n" + + "local count = tonumber(ARGV[1])\n" + + "local time = tonumber(ARGV[2])\n" + + "local current = redis.call('get', key);\n" + + "if current and tonumber(current) > count then\n" + + " return tonumber(current);\n" + + "end\n" + + "current = redis.call('incr', key)\n" + + "if tonumber(current) == 1 then\n" + + " redis.call('expire', key, time)\n" + + "end\n" + + "return tonumber(current);"; + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/ResourcesConfig.java b/ff-base/src/main/java/com/ff/base/config/ResourcesConfig.java new file mode 100644 index 0000000..b15d80d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/ResourcesConfig.java @@ -0,0 +1,84 @@ +package com.ff.base.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.ff.base.constant.Constants; +import com.ff.base.interceptor.DataSourceSwitchInterceptor; +import com.ff.base.interceptor.RepeatSubmitInterceptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.CacheControl; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * 通用配置 + * + * @author ff + */ +@Configuration +public class ResourcesConfig implements WebMvcConfigurer +{ + @Autowired + private RepeatSubmitInterceptor repeatSubmitInterceptor; + + @Autowired + private DataSourceSwitchInterceptor dataSourceSwitchInterceptor; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) + { + /** 本地文件上传路径 */ + registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**") + .addResourceLocations("file:" + FFConfig.getProfile() + "/"); + + /** swagger配置 */ + registry.addResourceHandler("/swagger-ui/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/") + .setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());; + } + + /** + * 自定义拦截规则 + */ + @Override + public void addInterceptors(InterceptorRegistry registry) + { + registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**"); + registry.addInterceptor(dataSourceSwitchInterceptor).addPathPatterns("/**"); + } + + /** + * 跨域配置 + */ + @Bean + public CorsFilter corsFilter() + { + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + // 设置访问源地址 + config.addAllowedOriginPattern("*"); + // 设置访问源请求头 + config.addAllowedHeader("*"); + // 设置访问源请求方法 + config.addAllowedMethod("*"); + // 有效期 1800秒 + config.setMaxAge(1800L); + // 添加映射路径,拦截一切请求 + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", config); + // 返回新的CorsFilter + return new CorsFilter(source); + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/SecurityConfig.java b/ff-base/src/main/java/com/ff/base/config/SecurityConfig.java new file mode 100644 index 0000000..b061637 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/SecurityConfig.java @@ -0,0 +1,165 @@ +package com.ff.base.config; + +import com.ff.base.config.properties.PermitAllUrlProperties; +import com.ff.base.security.encode.CustomMd5PasswordEncoder; +import com.ff.base.security.filter.JwtAuthenticationTokenFilter; +import com.ff.base.security.handle.AuthenticationEntryPointImpl; +import com.ff.base.security.handle.LogoutSuccessHandlerImpl; +import com.ff.base.security.provider.MyDaoAuthenticationProvider; +import com.ff.base.web.service.MemberDetailsServiceImpl; +import com.ff.base.web.service.UserDetailsServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.logout.LogoutFilter; +import org.springframework.web.filter.CorsFilter; + +import java.util.ArrayList; +import java.util.List; + +/** + * spring security配置 + * + * @author ff + */ +@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true) +@Configuration +public class SecurityConfig { + /** + * 后台自定义用户认证逻辑 + */ + @Autowired + private UserDetailsServiceImpl userDetailsService; + + /** + * 会员自定义用户认证逻辑 + */ + @Autowired + private MemberDetailsServiceImpl memberDetailsService; + + /** + * 认证失败处理类 + */ + @Autowired + private AuthenticationEntryPointImpl unauthorizedHandler; + + /** + * 退出处理类 + */ + @Autowired + private LogoutSuccessHandlerImpl logoutSuccessHandler; + + /** + * token认证过滤器 + */ + @Autowired + private JwtAuthenticationTokenFilter authenticationTokenFilter; + + /** + * 跨域过滤器 + */ + @Autowired + private CorsFilter corsFilter; + + /** + * 允许匿名访问的地址 + */ + @Autowired + private PermitAllUrlProperties permitAllUrl; + + /** + * 身份验证实现 + */ + @Bean + public AuthenticationManager authenticationManager() { + + // 后台、会员两种验证方式实现类 + List userDetailsServices = new ArrayList<>(); + userDetailsServices.add(userDetailsService); + userDetailsServices.add(memberDetailsService); + + List providers = new ArrayList<>(); + MyDaoAuthenticationProvider adminDaoAuthenticationProvider = new MyDaoAuthenticationProvider(); + adminDaoAuthenticationProvider.setUserDetailsService(userDetailsService); // or userDetailsService + adminDaoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder()); + adminDaoAuthenticationProvider.setUserDetailsServices(userDetailsServices); + + MyDaoAuthenticationProvider memberDaoAuthenticationProvider = new MyDaoAuthenticationProvider(); + memberDaoAuthenticationProvider.setUserDetailsService(memberDetailsService); // or userDetailsService + memberDaoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder()); + memberDaoAuthenticationProvider.setUserDetailsServices(userDetailsServices); + providers.add(adminDaoAuthenticationProvider); + providers.add(memberDaoAuthenticationProvider); + + return new ProviderManager(providers); + + } + + + /** + * anyRequest | 匹配所有请求路径 + * access | SpringEl表达式结果为true时可以访问 + * anonymous | 匿名可以访问 + * denyAll | 用户不能访问 + * fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录) + * hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问 + * hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问 + * hasAuthority | 如果有参数,参数表示权限,则其权限可以访问 + * hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问 + * hasRole | 如果有参数,参数表示角色,则其角色可以访问 + * permitAll | 用户可以任意访问 + * rememberMe | 允许通过remember-me登录的用户访问 + * authenticated | 用户登录后可访问 + */ + @Bean + protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { + return httpSecurity + // CSRF禁用,因为不使用session + .csrf(csrf -> csrf.disable()) + // 禁用HTTP响应标头 + .headers((headersCustomizer) -> { + headersCustomizer.cacheControl(cache -> cache.disable()).frameOptions(options -> options.sameOrigin()); + }) + // 认证失败处理类 + .exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler)) + // 基于token,所以不需要session + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + // 注解标记允许匿名访问的url + .authorizeHttpRequests((requests) -> { + permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll()); + // 对于登录login 注册register 验证码captchaImage 允许匿名访问 + requests.antMatchers("/api/**","/login", "/register","/ws", "/captchaImage").permitAll() + // 静态资源,可匿名访问 + .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() + .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() + // 除上面外的所有请求全部需要鉴权认证 + .anyRequest().authenticated(); + }) + // 添加Logout filter + .logout(logout -> logout.logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler)) + // 添加JWT filter + .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class) + // 添加CORS filter + .addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class) + .addFilterBefore(corsFilter, LogoutFilter.class) + .build(); + } + + /** + * 强散列哈希加密实现 + */ + @Bean + public CustomMd5PasswordEncoder bCryptPasswordEncoder() { + return new CustomMd5PasswordEncoder(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/ServerConfig.java b/ff-base/src/main/java/com/ff/base/config/ServerConfig.java new file mode 100644 index 0000000..ca967e5 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/ServerConfig.java @@ -0,0 +1,33 @@ +package com.ff.base.config; + +import com.ff.base.utils.ServletUtils; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; + +/** + * 服务相关配置 + * + * @author ff + */ +@Component +public class ServerConfig +{ + /** + * 获取完整的请求路径,包括:域名,端口,上下文访问路径 + * + * @return 服务地址 + */ + public String getUrl() + { + HttpServletRequest request = ServletUtils.getRequest(); + return getDomain(request); + } + + public static String getDomain(HttpServletRequest request) + { + StringBuffer url = request.getRequestURL(); + String contextPath = request.getServletContext().getContextPath(); + return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/ThreadPoolConfig.java b/ff-base/src/main/java/com/ff/base/config/ThreadPoolConfig.java new file mode 100644 index 0000000..8693106 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/ThreadPoolConfig.java @@ -0,0 +1,64 @@ +package com.ff.base.config; + +import com.ff.base.utils.Threads; +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 线程池配置 + * + * @author ff + **/ +@Configuration +public class ThreadPoolConfig +{ + // 核心线程池大小 + private int corePoolSize = 50; + + // 最大可创建的线程数 + private int maxPoolSize = 200; + + // 队列最大长度 + private int queueCapacity = 1000; + + // 线程池维护线程所允许的空闲时间 + private int keepAliveSeconds = 300; + + @Bean(name = "threadPoolTaskExecutor") + public ThreadPoolTaskExecutor threadPoolTaskExecutor() + { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setMaxPoolSize(maxPoolSize); + executor.setCorePoolSize(corePoolSize); + executor.setQueueCapacity(queueCapacity); + executor.setKeepAliveSeconds(keepAliveSeconds); + // 线程池对拒绝任务(无线程可用)的处理策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + return executor; + } + + /** + * 执行周期性或定时任务 + */ + @Bean(name = "scheduledExecutorService") + protected ScheduledExecutorService scheduledExecutorService() + { + return new ScheduledThreadPoolExecutor(corePoolSize, + new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(), + new ThreadPoolExecutor.CallerRunsPolicy()) + { + @Override + protected void afterExecute(Runnable r, Throwable t) + { + super.afterExecute(r, t); + Threads.printException(r, t); + } + }; + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/properties/DruidProperties.java b/ff-base/src/main/java/com/ff/base/config/properties/DruidProperties.java new file mode 100644 index 0000000..869842a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/properties/DruidProperties.java @@ -0,0 +1,89 @@ +package com.ff.base.config.properties; + +import com.alibaba.druid.pool.DruidDataSource; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +/** + * druid 配置属性 + * + * @author ff + */ +@Configuration +public class DruidProperties +{ + @Value("${spring.datasource.druid.initialSize}") + private int initialSize; + + @Value("${spring.datasource.druid.minIdle}") + private int minIdle; + + @Value("${spring.datasource.druid.maxActive}") + private int maxActive; + + @Value("${spring.datasource.druid.maxWait}") + private int maxWait; + + @Value("${spring.datasource.druid.connectTimeout}") + private int connectTimeout; + + @Value("${spring.datasource.druid.socketTimeout}") + private int socketTimeout; + + @Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}") + private int timeBetweenEvictionRunsMillis; + + @Value("${spring.datasource.druid.minEvictableIdleTimeMillis}") + private int minEvictableIdleTimeMillis; + + @Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}") + private int maxEvictableIdleTimeMillis; + + @Value("${spring.datasource.druid.validationQuery}") + private String validationQuery; + + @Value("${spring.datasource.druid.testWhileIdle}") + private boolean testWhileIdle; + + @Value("${spring.datasource.druid.testOnBorrow}") + private boolean testOnBorrow; + + @Value("${spring.datasource.druid.testOnReturn}") + private boolean testOnReturn; + + public DruidDataSource dataSource(DruidDataSource datasource) + { + /** 配置初始化大小、最小、最大 */ + datasource.setInitialSize(initialSize); + datasource.setMaxActive(maxActive); + datasource.setMinIdle(minIdle); + + /** 配置获取连接等待超时的时间 */ + datasource.setMaxWait(maxWait); + + /** 配置驱动连接超时时间,检测数据库建立连接的超时时间,单位是毫秒 */ + datasource.setConnectTimeout(connectTimeout); + + /** 配置网络超时时间,等待数据库操作完成的网络超时时间,单位是毫秒 */ + datasource.setSocketTimeout(socketTimeout); + + /** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */ + datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + + /** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */ + datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis); + + /** + * 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。 + */ + datasource.setValidationQuery(validationQuery); + /** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */ + datasource.setTestWhileIdle(testWhileIdle); + /** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ + datasource.setTestOnBorrow(testOnBorrow); + /** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ + datasource.setTestOnReturn(testOnReturn); + return datasource; + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/properties/PermitAllUrlProperties.java b/ff-base/src/main/java/com/ff/base/config/properties/PermitAllUrlProperties.java new file mode 100644 index 0000000..2ed6c99 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/properties/PermitAllUrlProperties.java @@ -0,0 +1,70 @@ +package com.ff.base.config.properties; + +import com.ff.base.annotation.Anonymous; +import org.apache.commons.lang3.RegExUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import java.util.*; +import java.util.regex.Pattern; + +/** + * 设置Anonymous注解允许匿名访问的url + * + * @author ff + */ +@Configuration +public class PermitAllUrlProperties implements InitializingBean, ApplicationContextAware +{ + private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}"); + + private ApplicationContext applicationContext; + + private List urls = new ArrayList<>(); + + public String ASTERISK = "*"; + + @Override + public void afterPropertiesSet() + { + RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); + Map map = mapping.getHandlerMethods(); + + map.keySet().forEach(info -> { + HandlerMethod handlerMethod = map.get(info); + + // 获取方法上边的注解 替代path variable 为 * + Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class); + Optional.ofNullable(method).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns()) + .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)))); + + // 获取类上边的注解, 替代path variable 为 * + Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class); + Optional.ofNullable(controller).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns()) + .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)))); + }); + } + + @Override + public void setApplicationContext(ApplicationContext context) throws BeansException + { + this.applicationContext = context; + } + + public List getUrls() + { + return urls; + } + + public void setUrls(List urls) + { + this.urls = urls; + } +} diff --git a/ff-base/src/main/java/com/ff/base/config/serializer/SensitiveJsonSerializer.java b/ff-base/src/main/java/com/ff/base/config/serializer/SensitiveJsonSerializer.java new file mode 100644 index 0000000..cbe7f48 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/config/serializer/SensitiveJsonSerializer.java @@ -0,0 +1,68 @@ +package com.ff.base.config.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.BeanProperty; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.ContextualSerializer; +import com.ff.base.annotation.Sensitive; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.enums.DesensitizedType; +import com.ff.base.utils.SecurityUtils; + +import java.io.IOException; +import java.util.Objects; + +/** + * 数据脱敏序列化过滤 + * + * @author ff + */ +public class SensitiveJsonSerializer extends JsonSerializer implements ContextualSerializer +{ + private DesensitizedType desensitizedType; + + @Override + public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException + { + if (desensitization()) + { + gen.writeString(desensitizedType.desensitizer().apply(value)); + } + else + { + gen.writeString(value); + } + } + + @Override + public JsonSerializer createContextual(SerializerProvider prov, BeanProperty property) + throws JsonMappingException + { + Sensitive annotation = property.getAnnotation(Sensitive.class); + if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) + { + this.desensitizedType = annotation.desensitizedType(); + return this; + } + return prov.findValueSerializer(property.getType(), property); + } + + /** + * 是否需要脱敏处理 + */ + private boolean desensitization() + { + try + { + LoginUser securityUser = SecurityUtils.getLoginUser(); + // 管理员不脱敏 + return !securityUser.getUser().isAdmin(); + } + catch (Exception e) + { + return true; + } + } +} diff --git a/ff-base/src/main/java/com/ff/base/constant/BusinessConstants.java b/ff-base/src/main/java/com/ff/base/constant/BusinessConstants.java new file mode 100644 index 0000000..e137c83 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/constant/BusinessConstants.java @@ -0,0 +1,70 @@ +package com.ff.base.constant; + +/** + * 业务常量信息 + * + * @author ff + */ +public class BusinessConstants { + + //有效投注 + public static final Integer VALID_BETTING = 1; + + //净盈利 + public static final Integer PROFIT = 2; + + // 是 + public static final Integer IS_TRUE = 1; + + // 不是 + public static final Integer IS_FALSE = 0; + + // 开启 + public static final Integer IS_ENABLED = 1; + + // 关闭 + public static final Integer IS_DISABLED = 0; + + // 已处理 + public static final int PROCESSED = 1; + + //未处理 + public static final int UNPROCESSED = 0; + + //不强制 + public static final int NOT_FORCE = 2; + + //已作废 + public static final int DISCARD = 3; + + //已删除 + public static final int DELETED = 2; + + /** + * 通用成功标识 + */ + public static final Integer SUCCESS = 1; + + /** + * 通用失败标识 + */ + public static final Integer FAIL = 0; + + /** + * 被全选 + */ + public static final String ALL_SELECTED = "0"; + + /** + * 有效 + */ + public static final String VALID = "1"; + + /** + * 无效 + */ + public static final String INVALID = "0"; + +} + + diff --git a/ff-base/src/main/java/com/ff/base/constant/CacheConstants.java b/ff-base/src/main/java/com/ff/base/constant/CacheConstants.java new file mode 100644 index 0000000..cc7b46b --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/constant/CacheConstants.java @@ -0,0 +1,71 @@ +package com.ff.base.constant; + +/** + * 缓存的key 常量 + * + * @author ff + */ +public class CacheConstants +{ + /** + * 登录用户 redis key + */ + public static final String LOGIN_TOKEN_KEY = "login_tokens:"; + + /** + * 验证码 redis key + */ + public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; + + /** + * 参数管理 cache key + */ + public static final String SYS_CONFIG_KEY = "sys_config:"; + + /** + * 字典管理 cache key + */ + public static final String SYS_DICT_KEY = "sys_dict:"; + + /** + * 防重提交 redis key + */ + public static final String REPEAT_SUBMIT_KEY = "repeat_submit:"; + + /** + * 限流 redis key + */ + public static final String RATE_LIMIT_KEY = "rate_limit:"; + + /** + * 登录账户密码错误次数 redis key + */ + public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; + + /** + * jili 游戏 + */ + public static final String JILI_GAMES= "jili_games:"; + + /** + * xk 游戏 + */ + public static final String XK_GAMES= "xk_games:"; + + + /** + * 通知窗口 + */ + public static final String NOTICE_WINDOW= "notice:window:"; + + /** + * 代理关系 + */ + public static final String AGENT_RELATION_KEY = "agentRelation:"; + + + /** + * 个性化配置预览 + */ + public static final String LAYOUT_PREVIEW = "layout:preview:"; +} diff --git a/ff-base/src/main/java/com/ff/base/constant/ConfigConstants.java b/ff-base/src/main/java/com/ff/base/constant/ConfigConstants.java new file mode 100644 index 0000000..2ad2c14 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/constant/ConfigConstants.java @@ -0,0 +1,94 @@ +package com.ff.base.constant; + +/** + * 通用常量信息 + * + * @author ff + */ +public class ConfigConstants +{ + + /** + * 游戏充值 + */ + public static final String GAME_RECHARGE = "game.recharge"; + + + /** + * 游戏下载应用 + */ + public static final String GAME_DOWNLOAD_APP = "game.download.app"; + + /** + * 游戏充值下载应用 + */ + public static final String GAME_RECHARGE_DOWNLOAD_APP = "game.download.app"; + /** + * 游戏安卓下载应用 + */ + public static final String GAME_ANDROID_DOWNLOAD_APP = "game.android.download.app"; + /** + * 热门一 + */ + public static final String HOT_ONE = "hot.one"; + /** + * 热门二 + */ + public static final String HOT_TWO = "hot.two"; + /** + * 通知全部删除状态 + */ + public static final String NOTICE_ALL_DELETE_STATUS = "notice.all.delete.status"; + /** + * 通知全部已读状态 + */ + public static final String NOTICE_ALL_READ_STATUS = "notice.all.read.status"; + /** + * 通知显示发布时间 + */ + public static final String NOTICE_SHOW_CREATE_TIME = "notice.show.create.time"; + + + /** + * 第三方游戏账号唯一key + */ + public static final String GAME_ACCOUNT = "game.account"; + + /** + * 关于我们开关 + */ + public static final String ABOUT_SWITCH = "about.switch"; + + + /** + * 跳过消息中心 + */ + public static final String SKIP_MESSAGE_CENTER = "skip.message.center"; + + + /** + * 是否开启在线客服开关 + */ + public static final String OPEN_SERVICE = "open.service"; + + + /** + * 文件访问地址前缀 + */ + public static final String VIEW_FILE_URL = "view.file.url"; + + /** + * H5防拦截开关 1 开启 2关闭 + */ + public static final String H5_INTERCEPT_OPEN = "h5.intercept.open"; + + /** + * 域名nginx配置文件 + */ + public static final String DOMAIN_NGINX_CONFIG = "domain.nginx.config"; + + /** + * 域nginx配置参数 + */ + public static final String DOMAIN_NGINX_CONFIG_PARAM = "domain.nginx.config.param"; +} diff --git a/ff-base/src/main/java/com/ff/base/constant/Constants.java b/ff-base/src/main/java/com/ff/base/constant/Constants.java new file mode 100644 index 0000000..28003f2 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/constant/Constants.java @@ -0,0 +1,238 @@ +package com.ff.base.constant; + +import io.jsonwebtoken.Claims; + +import java.util.Locale; + +/** + * 通用常量信息 + * + * @author ff + */ +public class Constants { + /** + * UTF-8 字符集 + */ + public static final String UTF8 = "UTF-8"; + + /** + * GBK 字符集 + */ + public static final String GBK = "GBK"; + + /** + * 系统语言 + */ + public static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE; + + /** + * www主域 + */ + public static final String WWW = "www."; + + /** + * http请求 + */ + public static final String HTTP = "http://"; + + /** + * https请求 + */ + public static final String HTTPS = "https://"; + + /** + * 通用成功标识 + */ + public static final String SUCCESS = "0"; + + /** + * 通用失败标识 + */ + public static final String FAIL = "1"; + + /** + * 登录成功 + */ + public static final String LOGIN_SUCCESS = "Success"; + + /** + * 注销 + */ + public static final String LOGOUT = "Logout"; + + /** + * 注册 + */ + public static final String REGISTER = "Register"; + + /** + * 登录失败 + */ + public static final String LOGIN_FAIL = "Error"; + + /** + * 所有权限标识 + */ + public static final String ALL_PERMISSION = "*:*:*"; + + /** + * 管理员角色权限标识 + */ + public static final String SUPER_ADMIN = "admin"; + + /** + * 角色权限分隔符 + */ + public static final String ROLE_DELIMETER = ","; + + /** + * 权限标识分隔符 + */ + public static final String PERMISSION_DELIMETER = ","; + + /** + * 验证码有效期(分钟) + */ + public static final Integer CAPTCHA_EXPIRATION = 2; + + /** + * 令牌 + */ + public static final String TOKEN = "token"; + + /** + * 令牌前缀 + */ + public static final String TOKEN_PREFIX = "Bearer "; + + /** + * 令牌前缀 + */ + public static final String LOGIN_USER_KEY = "login_user_key"; + + /** + * 用户ID + */ + public static final String JWT_USERID = "userid"; + + /** + * 用户名称 + */ + public static final String JWT_USERNAME = Claims.SUBJECT; + + /** + * 用户头像 + */ + public static final String JWT_AVATAR = "avatar"; + + /** + * 创建时间 + */ + public static final String JWT_CREATED = "created"; + + /** + * 用户权限 + */ + public static final String JWT_AUTHORITIES = "authorities"; + + /** + * 资源映射路径 前缀 + */ + public static final String RESOURCE_PREFIX = "/profile"; + + /** + * RMI 远程方法调用 + */ + public static final String LOOKUP_RMI = "rmi:"; + + /** + * LDAP 远程方法调用 + */ + public static final String LOOKUP_LDAP = "ldap:"; + + /** + * LDAPS 远程方法调用 + */ + public static final String LOOKUP_LDAPS = "ldaps:"; + + /** + * 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全) + */ + public static final String[] JSON_WHITELIST_STR = {"org.springframework", "com.ff"}; + + /** + * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) + */ + public static final String[] JOB_WHITELIST_STR = {"com.ff.quartz.task"}; + + /** + * 定时任务违规的字符 + */ + public static final String[] JOB_ERROR_STR = {"java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", + "org.springframework", "org.apache", "com.ff.base.utils.file", "com.ff.base.config", "com.ff.generator"}; + + + /** + * md5密码加密前缀 + */ + public static final String PASS_PREFIX = "FF_"; + + /** + * jili 接口请求前缀 + */ + public static final String JILI_API_BASE_URL = "jili.api.base.url"; + + /** + * 吉利测试地址 + */ + public static final String JILI_GAME_DOME = "jili.game.dome"; + + /** + * xk 接口请求前缀 + */ + public static final String XK_API_BASE_URL = "xk.api.base.url"; + /** + * 服务 + */ + public static final String SERVICE = "Service"; + + /** + * 系统 + */ + public static final String SYSTEM = "system"; + + + + + /** + * 主 数据源 + */ + public static final String DATA_SOURCE = "master"; + + + + /** + * 租户id + */ + public static final String TENANT_ID = "tenantId"; + + + /** + * 签名 + */ + public static final String SIGN = "sign"; + + + /** + * 随机 + */ + public static final String RANDOM = "random"; + + + /** + * 钥匙 + */ + public static final String KEY = "key"; + + +} diff --git a/ff-base/src/main/java/com/ff/base/constant/GenConstants.java b/ff-base/src/main/java/com/ff/base/constant/GenConstants.java new file mode 100644 index 0000000..2040a2c --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/constant/GenConstants.java @@ -0,0 +1,120 @@ +package com.ff.base.constant; + +/** + * 代码生成通用常量 + * + * @author ff + */ +public class GenConstants +{ + /** 单表(增删改查) */ + public static final String TPL_CRUD = "crud"; + + /** 树表(增删改查) */ + public static final String TPL_TREE = "tree"; + + /** 主子表(增删改查) */ + public static final String TPL_SUB = "sub"; + + /** 树编码字段 */ + public static final String TREE_CODE = "treeCode"; + + /** 树父编码字段 */ + public static final String TREE_PARENT_CODE = "treeParentCode"; + + /** 树名称字段 */ + public static final String TREE_NAME = "treeName"; + + /** 上级菜单ID字段 */ + public static final String PARENT_MENU_ID = "parentMenuId"; + + /** 上级菜单名称字段 */ + public static final String PARENT_MENU_NAME = "parentMenuName"; + + /** 数据库字符串类型 */ + public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" }; + + /** 数据库文本类型 */ + public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" }; + + /** 数据库时间类型 */ + public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" }; + + /** 数据库数字类型 */ + public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer", + "bit", "bigint", "float", "double", "decimal" }; + + /** 页面不需要编辑字段 */ + public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" }; + + /** 页面不需要显示的列表字段 */ + public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by", + "update_time" }; + + /** 页面不需要查询字段 */ + public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by", + "update_time", "remark" }; + + /** Entity基类字段 */ + public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" }; + + /** Tree基类字段 */ + public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" }; + + /** 文本框 */ + public static final String HTML_INPUT = "input"; + + /** 文本域 */ + public static final String HTML_TEXTAREA = "textarea"; + + /** 下拉框 */ + public static final String HTML_SELECT = "select"; + + /** 单选框 */ + public static final String HTML_RADIO = "radio"; + + /** 复选框 */ + public static final String HTML_CHECKBOX = "checkbox"; + + /** 日期控件 */ + public static final String HTML_DATETIME = "datetime"; + + /** 图片上传控件 */ + public static final String HTML_IMAGE_UPLOAD = "imageUpload"; + + /** 文件上传控件 */ + public static final String HTML_FILE_UPLOAD = "fileUpload"; + + /** 富文本控件 */ + public static final String HTML_EDITOR = "editor"; + + /** 字符串类型 */ + public static final String TYPE_STRING = "String"; + + /** 整型 */ + public static final String TYPE_INTEGER = "Integer"; + /** + * bool + */ + public static final String BOOL = "Boolean"; + /** 长整型 */ + public static final String TYPE_LONG = "Long"; + + /** 浮点型 */ + public static final String TYPE_DOUBLE = "Double"; + + /** 高精度计算类型 */ + public static final String TYPE_BIGDECIMAL = "BigDecimal"; + + /** 时间类型 */ + public static final String TYPE_DATE = "Date"; + + /** 模糊查询 */ + public static final String QUERY_LIKE = "LIKE"; + + /** 相等查询 */ + public static final String QUERY_EQ = "EQ"; + + /** 需要 */ + public static final String REQUIRE = "1"; +} diff --git a/ff-base/src/main/java/com/ff/base/constant/HttpStatus.java b/ff-base/src/main/java/com/ff/base/constant/HttpStatus.java new file mode 100644 index 0000000..837f4bf --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/constant/HttpStatus.java @@ -0,0 +1,99 @@ +package com.ff.base.constant; + +/** + * 返回状态码 + * + * @author ff + */ +public class HttpStatus +{ + /** + * 操作成功 + */ + public static final int SUCCESS = 200; + + /** + * 操作成功 + */ + public static final String SUCCESSSTRING = "200"; + + /** + * 对象创建成功 + */ + public static final int CREATED = 201; + + /** + * 请求已经被接受 + */ + public static final int ACCEPTED = 202; + + /** + * 操作已经执行成功,但是没有返回数据 + */ + public static final int NO_CONTENT = 204; + + /** + * 资源已被移除 + */ + public static final int MOVED_PERM = 301; + + /** + * 重定向 + */ + public static final int SEE_OTHER = 303; + + /** + * 资源没有被修改 + */ + public static final int NOT_MODIFIED = 304; + + /** + * 参数列表错误(缺少,格式不匹配) + */ + public static final int BAD_REQUEST = 400; + + /** + * 未授权 + */ + public static final int UNAUTHORIZED = 401; + + /** + * 访问受限,授权过期 + */ + public static final int FORBIDDEN = 403; + + /** + * 资源,服务未找到 + */ + public static final int NOT_FOUND = 404; + + /** + * 不允许的http方法 + */ + public static final int BAD_METHOD = 405; + + /** + * 资源冲突,或者资源被锁 + */ + public static final int CONFLICT = 409; + + /** + * 不支持的数据,媒体类型 + */ + public static final int UNSUPPORTED_TYPE = 415; + + /** + * 系统内部错误 + */ + public static final int ERROR = 500; + + /** + * 接口未实现 + */ + public static final int NOT_IMPLEMENTED = 501; + + /** + * 系统警告消息 + */ + public static final int WARN = 601; +} diff --git a/ff-base/src/main/java/com/ff/base/constant/ScheduleConstants.java b/ff-base/src/main/java/com/ff/base/constant/ScheduleConstants.java new file mode 100644 index 0000000..09e9496 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/constant/ScheduleConstants.java @@ -0,0 +1,50 @@ +package com.ff.base.constant; + +/** + * 任务调度通用常量 + * + * @author ff + */ +public class ScheduleConstants +{ + public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME"; + + /** 执行目标key */ + public static final String TASK_PROPERTIES = "TASK_PROPERTIES"; + + /** 默认 */ + public static final String MISFIRE_DEFAULT = "0"; + + /** 立即触发执行 */ + public static final String MISFIRE_IGNORE_MISFIRES = "1"; + + /** 触发一次执行 */ + public static final String MISFIRE_FIRE_AND_PROCEED = "2"; + + /** 不触发立即执行 */ + public static final String MISFIRE_DO_NOTHING = "3"; + + public enum Status + { + /** + * 正常 + */ + NORMAL("0"), + /** + * 暂停 + */ + PAUSE("1"); + + private String value; + + private Status(String value) + { + this.value = value; + } + + public String getValue() + { + return value; + } + } +} diff --git a/ff-base/src/main/java/com/ff/base/constant/UserConstants.java b/ff-base/src/main/java/com/ff/base/constant/UserConstants.java new file mode 100644 index 0000000..027526c --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/constant/UserConstants.java @@ -0,0 +1,78 @@ +package com.ff.base.constant; + +/** + * 用户常量信息 + * + * @author ff + */ +public class UserConstants +{ + /** + * 平台内系统用户的唯一标志 + */ + public static final String SYS_USER = "SYS_USER"; + + /** 正常状态 */ + public static final String NORMAL = "0"; + + /** 异常状态 */ + public static final String EXCEPTION = "1"; + + /** 用户封禁状态 */ + public static final String USER_DISABLE = "1"; + + /** 角色封禁状态 */ + public static final String ROLE_DISABLE = "1"; + + /** 部门正常状态 */ + public static final String DEPT_NORMAL = "0"; + + /** 部门停用状态 */ + public static final String DEPT_DISABLE = "1"; + + /** 字典正常状态 */ + public static final String DICT_NORMAL = "0"; + + /** 是否为系统默认(是) */ + public static final String YES = "Y"; + + /** 是否菜单外链(是) */ + public static final String YES_FRAME = "0"; + + /** 是否菜单外链(否) */ + public static final String NO_FRAME = "1"; + + /** 菜单类型(目录) */ + public static final String TYPE_DIR = "M"; + + /** 菜单类型(菜单) */ + public static final String TYPE_MENU = "C"; + + /** 菜单类型(按钮) */ + public static final String TYPE_BUTTON = "F"; + + /** Layout组件标识 */ + public final static String LAYOUT = "Layout"; + + /** ParentView组件标识 */ + public final static String PARENT_VIEW = "ParentView"; + + /** InnerLink组件标识 */ + public final static String INNER_LINK = "InnerLink"; + + /** 校验是否唯一的返回标识 */ + public final static boolean UNIQUE = true; + public final static boolean NOT_UNIQUE = false; + + /** + * 用户名长度限制 + */ + public static final int USERNAME_MIN_LENGTH = 2; + public static final int USERNAME_MAX_LENGTH = 20; + + /** + * 密码长度限制 + */ + public static final int PASSWORD_MIN_LENGTH = 5; + public static final int PASSWORD_MAX_LENGTH = 20; +} diff --git a/ff-base/src/main/java/com/ff/base/core/controller/BaseController.java b/ff-base/src/main/java/com/ff/base/core/controller/BaseController.java new file mode 100644 index 0000000..b28e6e1 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/controller/BaseController.java @@ -0,0 +1,203 @@ +package com.ff.base.core.controller; + +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.ff.base.constant.HttpStatus; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.core.page.PageDomain; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.core.page.TableSupport; +import com.ff.base.utils.DateUtils; +import com.ff.base.utils.PageUtils; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.sql.SqlUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; + +import java.beans.PropertyEditorSupport; +import java.util.Date; +import java.util.List; + +/** + * web层通用数据处理 + * + * @author ff + */ +public class BaseController +{ + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * 将前台传递过来的日期格式的字符串,自动转化为Date类型 + */ + @InitBinder + public void initBinder(WebDataBinder binder) + { + // Date 类型转换 + binder.registerCustomEditor(Date.class, new PropertyEditorSupport() + { + @Override + public void setAsText(String text) + { + setValue(DateUtils.parseDate(text)); + } + }); + } + + /** + * 设置请求分页数据 + */ + protected void startPage() + { + PageUtils.startPage(); + } + + /** + * 设置请求排序数据 + */ + protected void startOrderBy() + { + PageDomain pageDomain = TableSupport.buildPageRequest(); + if (StringUtils.isNotEmpty(pageDomain.getOrderBy())) + { + String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); + PageHelper.orderBy(orderBy); + } + } + + /** + * 清理分页的线程变量 + */ + protected void clearPage() + { + PageUtils.clearPage(); + } + + /** + * 响应请求分页数据 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected TableDataInfo getDataTable(List list) + { + TableDataInfo rspData = new TableDataInfo(); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setMsg("查询成功"); + rspData.setRows(list); + rspData.setTotal(Long.valueOf(new PageInfo(list).getTotal()).intValue()); + return rspData; + } + + /** + * 返回成功 + */ + public AjaxResult success() + { + return AjaxResult.success(); + } + + /** + * 返回失败消息 + */ + public AjaxResult error() + { + return AjaxResult.error(); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(String message) + { + return AjaxResult.success(message); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(Object data) + { + return AjaxResult.success(data); + } + + /** + * 返回失败消息 + */ + public AjaxResult error(String message) + { + return AjaxResult.error(message); + } + + /** + * 返回警告消息 + */ + public AjaxResult warn(String message) + { + return AjaxResult.warn(message); + } + + /** + * 响应返回结果 + * + * @param rows 影响行数 + * @return 操作结果 + */ + protected AjaxResult toAjax(int rows) + { + return rows > 0 ? AjaxResult.success() : AjaxResult.error(); + } + + /** + * 响应返回结果 + * + * @param result 结果 + * @return 操作结果 + */ + protected AjaxResult toAjax(boolean result) + { + return result ? success() : error(); + } + + /** + * 页面跳转 + */ + public String redirect(String url) + { + return StringUtils.format("redirect:{}", url); + } + + /** + * 获取用户缓存信息 + */ + public LoginUser getLoginUser() + { + return SecurityUtils.getLoginUser(); + } + + /** + * 获取登录用户id + */ + public Long getUserId() + { + return getLoginUser().getUserId(); + } + + /** + * 获取登录部门id + */ + public Long getDeptId() + { + return getLoginUser().getDeptId(); + } + + /** + * 获取登录用户名 + */ + public String getUsername() + { + return getLoginUser().getUsername(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/core/domain/AjaxResult.java b/ff-base/src/main/java/com/ff/base/core/domain/AjaxResult.java new file mode 100644 index 0000000..aa596b7 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/domain/AjaxResult.java @@ -0,0 +1,218 @@ +package com.ff.base.core.domain; + +import com.ff.base.constant.HttpStatus; +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.StringUtils; + +import java.util.HashMap; +import java.util.Objects; + +/** + * 操作消息提醒 + * + * @author ff + */ +public class AjaxResult extends HashMap +{ + private static final long serialVersionUID = 1L; + + /** 状态码 */ + public static final String CODE_TAG = "code"; + + /** 返回内容 */ + public static final String MSG_TAG = "msg"; + + /** 数据对象 */ + public static final String DATA_TAG = "data"; + + /** + * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 + */ + public AjaxResult() + { + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + */ + public AjaxResult(int code, String msg) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + * @param data 数据对象 + */ + public AjaxResult(int code, String msg, Object data) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + if (StringUtils.isNotNull(data)) + { + super.put(DATA_TAG, data); + } + } + + /** + * 返回成功消息 + * + * @return 成功消息 + */ + public static AjaxResult success() + { + return AjaxResult.success(MessageUtils.message("opration.success")); + } + + /** + * 返回成功数据 + * + * @return 成功消息 + */ + public static AjaxResult success(Object data) + { + return AjaxResult.success(MessageUtils.message("opration.success"), data); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @return 成功消息 + */ + public static AjaxResult success(String msg) + { + return AjaxResult.success(msg, null); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 成功消息 + */ + public static AjaxResult success(String msg, Object data) + { + return new AjaxResult(HttpStatus.SUCCESS, msg, data); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @return 警告消息 + */ + public static AjaxResult warn(String msg) + { + return AjaxResult.warn(msg, null); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 警告消息 + */ + public static AjaxResult warn(String msg, Object data) + { + return new AjaxResult(HttpStatus.WARN, msg, data); + } + + /** + * 返回错误消息 + * + * @return 错误消息 + */ + public static AjaxResult error() + { + return AjaxResult.error(MessageUtils.message("opration.fail")); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(String msg) + { + return AjaxResult.error(msg, null); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 错误消息 + */ + public static AjaxResult error(String msg, Object data) + { + return new AjaxResult(HttpStatus.ERROR, msg, data); + } + + /** + * 返回错误消息 + * + * @param code 状态码 + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(int code, String msg) + { + return new AjaxResult(code, msg, null); + } + + /** + * 是否为成功消息 + * + * @return 结果 + */ + public boolean isSuccess() + { + return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG)); + } + + /** + * 是否为警告消息 + * + * @return 结果 + */ + public boolean isWarn() + { + return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG)); + } + + /** + * 是否为错误消息 + * + * @return 结果 + */ + public boolean isError() + { + return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG)); + } + + /** + * 方便链式调用 + * + * @param key 键 + * @param value 值 + * @return 数据对象 + */ + @Override + public AjaxResult put(String key, Object value) + { + super.put(key, value); + return this; + } +} diff --git a/ff-base/src/main/java/com/ff/base/core/domain/BaseEntity.java b/ff-base/src/main/java/com/ff/base/core/domain/BaseEntity.java new file mode 100644 index 0000000..0a2308d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/domain/BaseEntity.java @@ -0,0 +1,63 @@ +package com.ff.base.core.domain; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.Data; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * Entity基类 + * + * @author ff + */ +@Data +public class BaseEntity implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + private Long id; + + /** 搜索值 */ + @JsonIgnore + private String searchValue; + + /** 创建者 */ + private String createBy; + + /** 创建时间 */ + @JsonSerialize(using = ToStringSerializer.class) + private Long createTime; + + /** 更新者 */ + private String updateBy; + + /** 更新时间 */ + @JsonSerialize(using = ToStringSerializer.class) + private Long updateTime; + + /** 备注 */ + private String remark; + + /** 请求参数 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private Map params; + + + + public Map getParams() + { + if (params == null) + { + params = new HashMap<>(); + } + return params; + } +} diff --git a/ff-base/src/main/java/com/ff/base/core/domain/TreeEntity.java b/ff-base/src/main/java/com/ff/base/core/domain/TreeEntity.java new file mode 100644 index 0000000..aa6a9b2 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/domain/TreeEntity.java @@ -0,0 +1,32 @@ +package com.ff.base.core.domain; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tree基类 + * + * @author ff + */ +@Data +public class TreeEntity extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 父菜单名称 */ + private String parentName; + + /** 父菜单ID */ + private Long parentId; + + /** 显示顺序 */ + private Integer orderNum; + + /** 祖级列表 */ + private String ancestors; + + /** 子部门 */ + private List children = new ArrayList<>(); +} diff --git a/ff-base/src/main/java/com/ff/base/core/domain/TreeSelect.java b/ff-base/src/main/java/com/ff/base/core/domain/TreeSelect.java new file mode 100644 index 0000000..7e90daa --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/domain/TreeSelect.java @@ -0,0 +1,52 @@ +package com.ff.base.core.domain; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.ff.base.system.domain.SysDept; +import com.ff.base.system.domain.SysMenu; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Treeselect树结构实体类 + * + * @author ff + */ +@Data +public class TreeSelect implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 节点ID */ + private Long id; + + /** 节点名称 */ + private String label; + + /** 子节点 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + + public TreeSelect() + { + + } + + public TreeSelect(SysDept dept) + { + this.id = dept.getDeptId(); + this.label = dept.getDeptName(); + this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + public TreeSelect(SysMenu menu) + { + this.id = menu.getMenuId(); + this.label = menu.getMenuName(); + this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + +} diff --git a/ff-base/src/main/java/com/ff/base/core/domain/model/LoginBody.java b/ff-base/src/main/java/com/ff/base/core/domain/model/LoginBody.java new file mode 100644 index 0000000..ed52432 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/domain/model/LoginBody.java @@ -0,0 +1,33 @@ +package com.ff.base.core.domain.model; + +import lombok.Data; + +/** + * 用户登录对象 + * + * @author ff + */ +@Data +public class LoginBody +{ + /** + * 用户名 + */ + private String username; + + /** + * 用户密码 + */ + private String password; + + /** + * 验证码 + */ + private String code; + + /** + * 唯一标识 + */ + private String uuid; + +} diff --git a/ff-base/src/main/java/com/ff/base/core/domain/model/LoginForm.java b/ff-base/src/main/java/com/ff/base/core/domain/model/LoginForm.java new file mode 100644 index 0000000..2400007 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/domain/model/LoginForm.java @@ -0,0 +1,48 @@ +package com.ff.base.core.domain.model; + +import lombok.Data; + +/** + * 登录信息 + * + * @author liukang + */ +@Data +public class LoginForm { + + + /** + * 账号名称 + */ + private String accountName; + + /** + * 密码 + */ + private String password; + + /** + * 登录类型 0.后台登录 1.会员登录 + */ + private Integer loginType; + + /** + * 登录域名地址 + */ + private String loginDomain; + + /** + * 登录设备类型 + */ + private String loginDeviceType; + + /** + * 最后登录设备号 + */ + private String loginDeviceNum; + + /** + * 登录浏览器信息 + */ + private String loginBrowser; +} diff --git a/ff-base/src/main/java/com/ff/base/core/domain/model/LoginUser.java b/ff-base/src/main/java/com/ff/base/core/domain/model/LoginUser.java new file mode 100644 index 0000000..e2fbb46 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/domain/model/LoginUser.java @@ -0,0 +1,281 @@ +package com.ff.base.core.domain.model; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.ff.base.system.domain.SysUser; +import lombok.Data; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; +import java.util.Set; + +/** + * 登录用户身份权限 + * + * @author ff + */ +@Data +public class LoginUser implements UserDetails +{ + private static final long serialVersionUID = 1L; + + /** + * 用户ID + */ + private Long userId; + + /** + * 部门ID + */ + private Long deptId; + + /** + * 用户唯一标识 + */ + private String token; + + /** + * 登录时间 + */ + private Long loginTime; + + /** + * 过期时间 + */ + private Long expireTime; + + /** + * 登录IP地址 + */ + private String ipaddr; + + /** + * 登录地点 + */ + private String loginLocation; + + /** + * 浏览器类型 + */ + private String browser; + + /** + * 操作系统 + */ + private String os; + + /** + * 权限列表 + */ + private Set permissions; + + /** + * 用户信息 + */ + private SysUser user; + + /** + * 币种 + */ + private String currencyType; + + public LoginUser() + { + } + + public LoginUser(SysUser user, Set permissions) + { + this.user = user; + this.permissions = permissions; + } + + public LoginUser(Long userId, Long deptId, SysUser user, Set permissions) + { + this.userId = userId; + this.deptId = deptId; + this.user = user; + this.permissions = permissions; + } + + public LoginUser(Long userId,String currencyType, SysUser user) + { + this.userId = userId; + this.user = user; + this.currencyType = currencyType; + } + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public String getToken() + { + return token; + } + + public void setToken(String token) + { + this.token = token; + } + + @JSONField(serialize = false) + @Override + public String getPassword() + { + return user.getPassword(); + } + + @Override + public String getUsername() + { + return user.getUserName(); + } + + /** + * 账户是否未过期,过期无法验证 + */ + @JSONField(serialize = false) + @Override + public boolean isAccountNonExpired() + { + return true; + } + + /** + * 指定用户是否解锁,锁定的用户无法进行身份验证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isAccountNonLocked() + { + return true; + } + + /** + * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isCredentialsNonExpired() + { + return true; + } + + /** + * 是否可用 ,禁用的用户不能身份验证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isEnabled() + { + return true; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public Long getExpireTime() + { + return expireTime; + } + + public void setExpireTime(Long expireTime) + { + this.expireTime = expireTime; + } + + public Set getPermissions() + { + return permissions; + } + + public void setPermissions(Set permissions) + { + this.permissions = permissions; + } + + public SysUser getUser() + { + return user; + } + + public void setUser(SysUser user) + { + this.user = user; + } + + @Override + public Collection getAuthorities() + { + return null; + } +} diff --git a/ff-base/src/main/java/com/ff/base/core/domain/model/RegisterBody.java b/ff-base/src/main/java/com/ff/base/core/domain/model/RegisterBody.java new file mode 100644 index 0000000..7feb851 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/domain/model/RegisterBody.java @@ -0,0 +1,11 @@ +package com.ff.base.core.domain.model; + +/** + * 用户注册对象 + * + * @author ff + */ +public class RegisterBody extends LoginBody +{ + +} diff --git a/ff-base/src/main/java/com/ff/base/core/page/PageDomain.java b/ff-base/src/main/java/com/ff/base/core/page/PageDomain.java new file mode 100644 index 0000000..47ef09d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/page/PageDomain.java @@ -0,0 +1,103 @@ +package com.ff.base.core.page; + +import com.ff.base.utils.StringUtils; +import lombok.Data; + +/** + * 分页数据 + * + * @author ff + */ +@Data +public class PageDomain +{ + /** 当前记录起始索引 */ + private Integer pageNum; + + /** 每页显示记录数 */ + private Integer pageSize; + + /** 排序列 */ + private String orderByColumn; + + /** 排序的方向desc或者asc */ + private String isAsc = "asc"; + + /** 分页参数合理化 */ + private Boolean reasonable = true; + + public String getOrderBy() + { + if (StringUtils.isEmpty(orderByColumn)) + { + return ""; + } + return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc; + } + + public Integer getPageNum() + { + return pageNum; + } + + public void setPageNum(Integer pageNum) + { + this.pageNum = pageNum; + } + + public Integer getPageSize() + { + return pageSize; + } + + public void setPageSize(Integer pageSize) + { + this.pageSize = pageSize; + } + + public String getOrderByColumn() + { + return orderByColumn; + } + + public void setOrderByColumn(String orderByColumn) + { + this.orderByColumn = orderByColumn; + } + + public String getIsAsc() + { + return isAsc; + } + + public void setIsAsc(String isAsc) + { + if (StringUtils.isNotEmpty(isAsc)) + { + // 兼容前端排序类型 + if ("ascending".equals(isAsc)) + { + isAsc = "asc"; + } + else if ("descending".equals(isAsc)) + { + isAsc = "desc"; + } + this.isAsc = isAsc; + } + } + + public Boolean getReasonable() + { + if (StringUtils.isNull(reasonable)) + { + return Boolean.TRUE; + } + return reasonable; + } + + public void setReasonable(Boolean reasonable) + { + this.reasonable = reasonable; + } +} diff --git a/ff-base/src/main/java/com/ff/base/core/page/TableDataInfo.java b/ff-base/src/main/java/com/ff/base/core/page/TableDataInfo.java new file mode 100644 index 0000000..8465c07 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/page/TableDataInfo.java @@ -0,0 +1,85 @@ +package com.ff.base.core.page; + +import java.io.Serializable; +import java.util.List; + +/** + * 表格分页数据对象 + * + * @author ff + */ +public class TableDataInfo implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 总记录数 */ + private int total; + + /** 列表数据 */ + private List rows; + + /** 消息状态码 */ + private int code; + + /** 消息内容 */ + private String msg; + + /** + * 表格数据对象 + */ + public TableDataInfo() + { + } + + /** + * 分页 + * + * @param list 列表数据 + * @param total 总记录数 + */ + public TableDataInfo(List list, int total) + { + this.rows = list; + this.total = total; + } + + public int getTotal() + { + return total; + } + + public void setTotal(int total) + { + this.total = total; + } + + public List getRows() + { + return rows; + } + + public void setRows(List rows) + { + this.rows = rows; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } +} diff --git a/ff-base/src/main/java/com/ff/base/core/page/TableSupport.java b/ff-base/src/main/java/com/ff/base/core/page/TableSupport.java new file mode 100644 index 0000000..57d2d17 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/page/TableSupport.java @@ -0,0 +1,56 @@ +package com.ff.base.core.page; + +import com.ff.base.core.text.Convert; +import com.ff.base.utils.ServletUtils; + +/** + * 表格数据处理 + * + * @author ff + */ +public class TableSupport +{ + /** + * 当前记录起始索引 + */ + public static final String PAGE_NUM = "pageNum"; + + /** + * 每页显示记录数 + */ + public static final String PAGE_SIZE = "pageSize"; + + /** + * 排序列 + */ + public static final String ORDER_BY_COLUMN = "orderByColumn"; + + /** + * 排序的方向 "desc" 或者 "asc". + */ + public static final String IS_ASC = "isAsc"; + + /** + * 分页参数合理化 + */ + public static final String REASONABLE = "reasonable"; + + /** + * 封装分页对象 + */ + public static PageDomain getPageDomain() + { + PageDomain pageDomain = new PageDomain(); + pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1)); + pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10)); + pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN)); + pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC)); + pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE)); + return pageDomain; + } + + public static PageDomain buildPageRequest() + { + return getPageDomain(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/core/redis/RedisCache.java b/ff-base/src/main/java/com/ff/base/core/redis/RedisCache.java new file mode 100644 index 0000000..8c74d20 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/redis/RedisCache.java @@ -0,0 +1,244 @@ +package com.ff.base.core.redis; + +import com.ff.base.utils.TenantUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.BoundSetOperations; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * spring redis 工具类 + * + * @author ff + **/ +@SuppressWarnings(value = {"unchecked", "rawtypes"}) +@Component +public class RedisCache { + @Autowired + public RedisTemplate redisTemplate; + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + */ + public void setCacheObject(final String key, final T value) { + redisTemplate.opsForValue().set(TenantUtils.getTenantIdRedis(key), value); + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + */ + public void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) { + redisTemplate.opsForValue().set(TenantUtils.getTenantIdRedis(key) , value, timeout, timeUnit); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout) { + return expire(TenantUtils.getTenantIdRedis(key), timeout, TimeUnit.SECONDS); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @param unit 时间单位 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout, final TimeUnit unit) { + return redisTemplate.expire(TenantUtils.getTenantIdRedis(key), timeout, unit); + } + + /** + * 获取有效时间 + * + * @param key Redis键 + * @return 有效时间 + */ + public long getExpire(final String key) { + return redisTemplate.getExpire(TenantUtils.getTenantIdRedis(key)); + } + + /** + * 判断 key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public Boolean hasKey(String key) { + return redisTemplate.hasKey(TenantUtils.getTenantIdRedis(key)); + } + + /** + * 获得缓存的基本对象。 + * + * @param key 缓存键值 + * @return 缓存键值对应的数据 + */ + public T getCacheObject(final String key) { + ValueOperations operation = redisTemplate.opsForValue(); + return operation.get(TenantUtils.getTenantIdRedis(key)); + } + + /** + * 删除单个对象 + * + * @param key + */ + public boolean deleteObject(final String key) { + return redisTemplate.delete(TenantUtils.getTenantIdRedis(key)); + } + + /** + * 删除集合对象 + * + * @param collection 多个对象 + * @return + */ + public boolean deleteObject(final Collection collection) { + return redisTemplate.delete(collection) > 0; + } + + /** + * 缓存List数据 + * + * @param key 缓存的键值 + * @param dataList 待缓存的List数据 + * @return 缓存的对象 + */ + public long setCacheList(final String key, final List dataList) { + Long count = redisTemplate.opsForList().rightPushAll(TenantUtils.getTenantIdRedis(key), dataList); + return count == null ? 0 : count; + } + + /** + * 获得缓存的list对象 + * + * @param key 缓存的键值 + * @return 缓存键值对应的数据 + */ + public List getCacheList(final String key) { + return redisTemplate.opsForList().range(TenantUtils.getTenantIdRedis(key), 0, -1); + } + + /** + * 缓存Set + * + * @param key 缓存键值 + * @param dataSet 缓存的数据 + * @return 缓存数据的对象 + */ + public BoundSetOperations setCacheSet(final String key, final Set dataSet) { + BoundSetOperations setOperation = redisTemplate.boundSetOps(TenantUtils.getTenantIdRedis(key)); + Iterator it = dataSet.iterator(); + while (it.hasNext()) { + setOperation.add(it.next()); + } + return setOperation; + } + + /** + * 获得缓存的set + * + * @param key + * @return + */ + public Set getCacheSet(final String key) { + return redisTemplate.opsForSet().members(TenantUtils.getTenantIdRedis(key)); + } + + /** + * 缓存Map + * + * @param key + * @param dataMap + */ + public void setCacheMap(final String key, final Map dataMap) { + if (dataMap != null) { + redisTemplate.opsForHash().putAll(TenantUtils.getTenantIdRedis(key), dataMap); + } + } + + /** + * 获得缓存的Map + * + * @param key + * @return + */ + public Map getCacheMap(final String key) { + return redisTemplate.opsForHash().entries(TenantUtils.getTenantIdRedis(key)); + } + + /** + * 往Hash中存入数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @param value 值 + */ + public void setCacheMapValue(final String key, final String hKey, final T value) { + redisTemplate.opsForHash().put(TenantUtils.getTenantIdRedis(key), hKey, value); + } + + /** + * 获取Hash中的数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return Hash中的对象 + */ + public T getCacheMapValue(final String key, final String hKey) { + HashOperations opsForHash = redisTemplate.opsForHash(); + return opsForHash.get(TenantUtils.getTenantIdRedis(key), hKey); + } + + /** + * 获取多个Hash中的数据 + * + * @param key Redis键 + * @param hKeys Hash键集合 + * @return Hash对象集合 + */ + public List getMultiCacheMapValue(final String key, final Collection hKeys) { + return redisTemplate.opsForHash().multiGet(TenantUtils.getTenantIdRedis(key), hKeys); + } + + /** + * 删除Hash中的某条数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return 是否成功 + */ + public boolean deleteCacheMapValue(final String key, final String hKey) { + return redisTemplate.opsForHash().delete(TenantUtils.getTenantIdRedis(key), hKey) > 0; + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public Collection keys(final String pattern) { + return redisTemplate.keys(TenantUtils.getTenantIdRedis(pattern)); + } +} diff --git a/ff-base/src/main/java/com/ff/base/core/text/CharsetKit.java b/ff-base/src/main/java/com/ff/base/core/text/CharsetKit.java new file mode 100644 index 0000000..0e2542f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/text/CharsetKit.java @@ -0,0 +1,87 @@ +package com.ff.base.core.text; + +import com.ff.base.utils.StringUtils; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +/** + * 字符集工具类 + * + * @author ff + */ +public class CharsetKit +{ + /** ISO-8859-1 */ + public static final String ISO_8859_1 = "ISO-8859-1"; + /** UTF-8 */ + public static final String UTF_8 = "UTF-8"; + /** GBK */ + public static final String GBK = "GBK"; + + /** ISO-8859-1 */ + public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1); + /** UTF-8 */ + public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8); + /** GBK */ + public static final Charset CHARSET_GBK = Charset.forName(GBK); + + /** + * 转换为Charset对象 + * + * @param charset 字符集,为空则返回默认字符集 + * @return Charset + */ + public static Charset charset(String charset) + { + return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, String srcCharset, String destCharset) + { + return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset)); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, Charset srcCharset, Charset destCharset) + { + if (null == srcCharset) + { + srcCharset = StandardCharsets.ISO_8859_1; + } + + if (null == destCharset) + { + destCharset = StandardCharsets.UTF_8; + } + + if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) + { + return source; + } + return new String(source.getBytes(srcCharset), destCharset); + } + + /** + * @return 系统字符集编码 + */ + public static String systemCharset() + { + return Charset.defaultCharset().name(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/core/text/Convert.java b/ff-base/src/main/java/com/ff/base/core/text/Convert.java new file mode 100644 index 0000000..07e54f5 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/text/Convert.java @@ -0,0 +1,1011 @@ +package com.ff.base.core.text; + +import com.ff.base.utils.StringUtils; +import org.apache.commons.lang3.ArrayUtils; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.RoundingMode; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.text.NumberFormat; +import java.util.Set; + +/** + * 类型转换器 + * + * @author ff + */ +public class Convert +{ + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static String toStr(Object value, String defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof String) + { + return (String) value; + } + return value.toString(); + } + + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static String toStr(Object value) + { + return toStr(value, null); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Character toChar(Object value, Character defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof Character) + { + return (Character) value; + } + + final String valueStr = toStr(value, null); + return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Character toChar(Object value) + { + return toChar(value, null); + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Byte toByte(Object value, Byte defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Byte) + { + return (Byte) value; + } + if (value instanceof Number) + { + return ((Number) value).byteValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Byte.parseByte(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Byte toByte(Object value) + { + return toByte(value, null); + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Short toShort(Object value, Short defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Short) + { + return (Short) value; + } + if (value instanceof Number) + { + return ((Number) value).shortValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Short.parseShort(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Short toShort(Object value) + { + return toShort(value, null); + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Number toNumber(Object value, Number defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Number) + { + return (Number) value; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return NumberFormat.getInstance().parse(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Number toNumber(Object value) + { + return toNumber(value, null); + } + + /** + * 转换为int
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Integer toInt(Object value, Integer defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Integer) + { + return (Integer) value; + } + if (value instanceof Number) + { + return ((Number) value).intValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Integer.parseInt(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为int
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Integer toInt(Object value) + { + return toInt(value, null); + } + + /** + * 转换为Integer数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String str) + { + return toIntArray(",", str); + } + + /** + * 转换为Long数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String str) + { + return toLongArray(",", str); + } + + /** + * 转换为Integer数组
+ * + * @param split 分隔符 + * @param split 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Integer[] {}; + } + String[] arr = str.split(split); + final Integer[] ints = new Integer[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Integer v = toInt(arr[i], 0); + ints[i] = v; + } + return ints; + } + + /** + * 转换为Long数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Long[] {}; + } + String[] arr = str.split(split); + final Long[] longs = new Long[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Long v = toLong(arr[i], null); + longs[i] = v; + } + return longs; + } + + /** + * 转换为String数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String str) + { + if (StringUtils.isEmpty(str)) + { + return new String[] {}; + } + return toStrArray(",", str); + } + + /** + * 转换为String数组
+ * + * @param split 分隔符 + * @param split 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String split, String str) + { + return str.split(split); + } + + /** + * 转换为long
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Long toLong(Object value, Long defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Long) + { + return (Long) value; + } + if (value instanceof Number) + { + return ((Number) value).longValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).longValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为long
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Long toLong(Object value) + { + return toLong(value, null); + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Double toDouble(Object value, Double defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Double) + { + return (Double) value; + } + if (value instanceof Number) + { + return ((Number) value).doubleValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).doubleValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Double toDouble(Object value) + { + return toDouble(value, null); + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Float toFloat(Object value, Float defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Float) + { + return (Float) value; + } + if (value instanceof Number) + { + return ((Number) value).floatValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Float.parseFloat(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Float toFloat(Object value) + { + return toFloat(value, null); + } + + /** + * 转换为boolean
+ * String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Boolean toBool(Object value, Boolean defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Boolean) + { + return (Boolean) value; + } + String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + valueStr = valueStr.trim().toLowerCase(); + switch (valueStr) + { + case "true": + case "yes": + case "ok": + case "1": + return true; + case "false": + case "no": + case "0": + return false; + default: + return defaultValue; + } + } + + /** + * 转换为boolean
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Boolean toBool(Object value) + { + return toBool(value, null); + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * + * @param clazz Enum的Class + * @param value 值 + * @param defaultValue 默认值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value, E defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (clazz.isAssignableFrom(value.getClass())) + { + @SuppressWarnings("unchecked") + E myE = (E) value; + return myE; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Enum.valueOf(clazz, valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * + * @param clazz Enum的Class + * @param value 值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value) + { + return toEnum(clazz, value, null); + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value, BigInteger defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigInteger) + { + return (BigInteger) value; + } + if (value instanceof Long) + { + return BigInteger.valueOf((Long) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigInteger(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value) + { + return toBigInteger(value, null); + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigDecimal) + { + return (BigDecimal) value; + } + if (value instanceof Long) + { + return new BigDecimal((Long) value); + } + if (value instanceof Double) + { + return BigDecimal.valueOf((Double) value); + } + if (value instanceof Integer) + { + return new BigDecimal((Integer) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigDecimal(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value) + { + return toBigDecimal(value, null); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @return 字符串 + */ + public static String utf8Str(Object obj) + { + return str(obj, CharsetKit.CHARSET_UTF_8); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charsetName 字符集 + * @return 字符串 + */ + public static String str(Object obj, String charsetName) + { + return str(obj, Charset.forName(charsetName)); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(Object obj, Charset charset) + { + if (null == obj) + { + return null; + } + + if (obj instanceof String) + { + return (String) obj; + } + else if (obj instanceof byte[]) + { + return str((byte[]) obj, charset); + } + else if (obj instanceof Byte[]) + { + byte[] bytes = ArrayUtils.toPrimitive((Byte[]) obj); + return str(bytes, charset); + } + else if (obj instanceof ByteBuffer) + { + return str((ByteBuffer) obj, charset); + } + return obj.toString(); + } + + /** + * 将byte数组转为字符串 + * + * @param bytes byte数组 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(byte[] bytes, String charset) + { + return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset)); + } + + /** + * 解码字节码 + * + * @param data 字符串 + * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 + * @return 解码后的字符串 + */ + public static String str(byte[] data, Charset charset) + { + if (data == null) + { + return null; + } + + if (null == charset) + { + return new String(data); + } + return new String(data, charset); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, String charset) + { + if (data == null) + { + return null; + } + + return str(data, Charset.forName(charset)); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, Charset charset) + { + if (null == charset) + { + charset = Charset.defaultCharset(); + } + return charset.decode(data).toString(); + } + + // ----------------------------------------------------------------------- 全角半角转换 + /** + * 半角转全角 + * + * @param input String. + * @return 全角字符串. + */ + public static String toSBC(String input) + { + return toSBC(input, null); + } + + /** + * 半角转全角 + * + * @param input String + * @param notConvertSet 不替换的字符集合 + * @return 全角字符串. + */ + public static String toSBC(String input, Set notConvertSet) + { + char[] c = input.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == ' ') + { + c[i] = '\u3000'; + } + else if (c[i] < '\177') + { + c[i] = (char) (c[i] + 65248); + + } + } + return new String(c); + } + + /** + * 全角转半角 + * + * @param input String. + * @return 半角字符串 + */ + public static String toDBC(String input) + { + return toDBC(input, null); + } + + /** + * 替换全角为半角 + * + * @param text 文本 + * @param notConvertSet 不替换的字符集合 + * @return 替换后的字符 + */ + public static String toDBC(String text, Set notConvertSet) + { + char[] c = text.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == '\u3000') + { + c[i] = ' '; + } + else if (c[i] > '\uFF00' && c[i] < '\uFF5F') + { + c[i] = (char) (c[i] - 65248); + } + } + String returnString = new String(c); + + return returnString; + } + + /** + * 数字金额大写转换 先写个完整的然后将如零拾替换成零 + * + * @param n 数字 + * @return 中文大写数字 + */ + public static String digitUppercase(double n) + { + String[] fraction = { "角", "分" }; + String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }; + String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } }; + + String head = n < 0 ? "负" : ""; + n = Math.abs(n); + + String s = ""; + for (int i = 0; i < fraction.length; i++) + { + // 优化double计算精度丢失问题 + BigDecimal nNum = new BigDecimal(n); + BigDecimal decimal = new BigDecimal(10); + BigDecimal scale = nNum.multiply(decimal).setScale(2, RoundingMode.HALF_EVEN); + double d = scale.doubleValue(); + s += (digit[(int) (Math.floor(d * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", ""); + } + if (s.length() < 1) + { + s = "整"; + } + int integerPart = (int) Math.floor(n); + + for (int i = 0; i < unit[0].length && integerPart > 0; i++) + { + String p = ""; + for (int j = 0; j < unit[1].length && n > 0; j++) + { + p = digit[integerPart % 10] + unit[1][j] + p; + integerPart = integerPart / 10; + } + s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s; + } + return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整"); + } +} diff --git a/ff-base/src/main/java/com/ff/base/core/text/StrFormatter.java b/ff-base/src/main/java/com/ff/base/core/text/StrFormatter.java new file mode 100644 index 0000000..4e9146b --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/core/text/StrFormatter.java @@ -0,0 +1,92 @@ +package com.ff.base.core.text; + +import com.ff.base.utils.StringUtils; + +/** + * 字符串格式化 + * + * @author ff + */ +public class StrFormatter +{ + public static final String EMPTY_JSON = "{}"; + public static final char C_BACKSLASH = '\\'; + public static final char C_DELIM_START = '{'; + public static final char C_DELIM_END = '}'; + + /** + * 格式化字符串
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @param strPattern 字符串模板 + * @param argArray 参数列表 + * @return 结果 + */ + public static String format(final String strPattern, final Object... argArray) + { + if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) + { + return strPattern; + } + final int strPatternLength = strPattern.length(); + + // 初始化定义好的长度以获得更好的性能 + StringBuilder sbuf = new StringBuilder(strPatternLength + 50); + + int handledPosition = 0; + int delimIndex;// 占位符所在位置 + for (int argIndex = 0; argIndex < argArray.length; argIndex++) + { + delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); + if (delimIndex == -1) + { + if (handledPosition == 0) + { + return strPattern; + } + else + { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 + sbuf.append(strPattern, handledPosition, strPatternLength); + return sbuf.toString(); + } + } + else + { + if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) + { + if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) + { + // 转义符之前还有一个转义符,占位符依旧有效 + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + else + { + // 占位符被转义 + argIndex--; + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(C_DELIM_START); + handledPosition = delimIndex + 1; + } + } + else + { + // 正常占位符 + sbuf.append(strPattern, handledPosition, delimIndex); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + } + } + // 加入最后一个占位符后所有的字符 + sbuf.append(strPattern, handledPosition, strPattern.length()); + + return sbuf.toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/datasource/DynamicDataSource.java b/ff-base/src/main/java/com/ff/base/datasource/DynamicDataSource.java new file mode 100644 index 0000000..c185f80 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/datasource/DynamicDataSource.java @@ -0,0 +1,83 @@ +package com.ff.base.datasource; + +import com.alibaba.druid.pool.DruidDataSource; +import com.ff.base.system.domain.SysDatasource; +import com.ff.base.utils.bean.BeanUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +import javax.sql.DataSource; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * 动态数据源 + * + * @author ff + */ +@Slf4j +public class DynamicDataSource extends AbstractRoutingDataSource { + + private final Map targetDataSourceMap; + + public DynamicDataSource(DataSource defaultTargetDataSource, Map targetDataSources) { + super.setDefaultTargetDataSource(defaultTargetDataSource); + super.setTargetDataSources(targetDataSources); + super.afterPropertiesSet(); + this.targetDataSourceMap = targetDataSources; + } + + @Override + protected Object determineCurrentLookupKey() { + return DynamicDataSourceContextHolder.getDataSourceType(); + } + + + + /** + * 添加数据源信息 + * + * @param dataSources 数据源实体集合 + */ + public void createDataSource(List dataSources) { + try { + if (CollectionUtils.isNotEmpty(dataSources)) { + for (SysDatasource ds : dataSources) { + //校验数据库是否可以连接 + Class.forName(ds.getDriverClassName()); + DriverManager.getConnection(ds.getUrl(), ds.getUsername(), ds.getPassword()); + //定义数据源 + DruidDataSource dataSource = new DruidDataSource(); + BeanUtils.copyProperties(ds, dataSource); + //申请连接时执行validationQuery检测连接是否有效,这里建议配置为TRUE,防止取到的连接不可用 + dataSource.setTestOnBorrow(true); + //建议配置为true,不影响性能,并且保证安全性。 + //申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 + dataSource.setTestWhileIdle(true); + dataSource.init(); + this.targetDataSourceMap.put(ds.getTenantId(), dataSource); + } + super.setTargetDataSources(this.targetDataSourceMap); + // 将TargetDataSources中的连接信息放入resolvedDataSources管理 + super.afterPropertiesSet(); + } + } catch (ClassNotFoundException | SQLException e) { + log.error("---程序报错---:{}", e.getMessage()); + } + } + + /** + * 校验数据源是否存在 + * + * @param key 数据源保存的key + * @return 返回结果,true:存在,false:不存在 + */ + public boolean existsDataSource(String key) { + return Objects.nonNull(this.targetDataSourceMap.get(key)); + } + +} diff --git a/ff-base/src/main/java/com/ff/base/datasource/DynamicDataSourceContextHolder.java b/ff-base/src/main/java/com/ff/base/datasource/DynamicDataSourceContextHolder.java new file mode 100644 index 0000000..5d0e57d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/datasource/DynamicDataSourceContextHolder.java @@ -0,0 +1,60 @@ +package com.ff.base.datasource; + +import com.ff.base.utils.spring.SpringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +import javax.sql.DataSource; +import java.util.Map; + +/** + * 数据源切换处理 + * + * @author ff + */ +public class DynamicDataSourceContextHolder { + public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class); + + /** + * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本, + * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 + */ + private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>(); + + /** + * 设置数据源的变量 + */ + public static void setDataSourceType(String dsType) { + log.info("切换到{}数据源", dsType); + CONTEXT_HOLDER.set(dsType); + MDC.put("dataSource", dsType); + } + + /** + * 获得数据源的变量 + */ + public static String getDataSourceType() { + return CONTEXT_HOLDER.get(); + } + + /** + * 清空数据源变量 + */ + public static void clearDataSourceType() { + MDC.remove("dataSource"); + CONTEXT_HOLDER.remove(); + } + + /** + * 获取所有数据源 + * + * @return + */ + public static Map getAllDataSource() { + AbstractRoutingDataSource abstractRoutingDataSource = SpringUtils.getBean(AbstractRoutingDataSource.class); + return abstractRoutingDataSource.getResolvedDataSources(); + } + +} diff --git a/ff-base/src/main/java/com/ff/base/decorator/ContextCopyingDecorator.java b/ff-base/src/main/java/com/ff/base/decorator/ContextCopyingDecorator.java new file mode 100644 index 0000000..f1fbbd9 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/decorator/ContextCopyingDecorator.java @@ -0,0 +1,47 @@ +package com.ff.base.decorator; + +import org.slf4j.MDC; +import org.springframework.core.task.TaskDecorator; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; + +import java.util.Map; + +/** + * 上下文复制装饰器 + * + * @author shi + * @date 2024/12/14 + */ +public class ContextCopyingDecorator implements TaskDecorator { + @Override + public Runnable decorate(Runnable runnable) { + try { + // 从父线程中获取上下文,然后应用到子线程中 + RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); + Map previous = MDC.getCopyOfContextMap(); + SecurityContext securityContext = SecurityContextHolder.getContext(); + return () -> { + try { + if (previous == null) { + MDC.clear(); + } else { + MDC.setContextMap(previous); + } + RequestContextHolder.setRequestAttributes(requestAttributes); + SecurityContextHolder.setContext(securityContext); + runnable.run(); + } finally { + // 清除请求数据 + MDC.clear(); + RequestContextHolder.resetRequestAttributes(); + SecurityContextHolder.clearContext(); + } + }; + } catch (IllegalStateException e) { + return runnable; + } + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/AccountAuditStatus.java b/ff-base/src/main/java/com/ff/base/enums/AccountAuditStatus.java new file mode 100644 index 0000000..ecda3d5 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/AccountAuditStatus.java @@ -0,0 +1,33 @@ +package com.ff.base.enums; + +/** + * 人工加款审核状态 + * + * @author liukang + */ +public enum AccountAuditStatus +{ + + AccountAuditStatus_0("0", "待审核"), + AccountAuditStatus_1("1", "审核通过"), + AccountAuditStatus_2("2", "审核拒绝"); + + private final String code; + private final String info; + + AccountAuditStatus(String code, String info) + { + this.code = code; + this.info = info; + } + + public String getCode() + { + return code; + } + + public String getInfo() + { + return info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/AccountChangeType.java b/ff-base/src/main/java/com/ff/base/enums/AccountChangeType.java new file mode 100644 index 0000000..dab6ce1 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/AccountChangeType.java @@ -0,0 +1,40 @@ +package com.ff.base.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 资金账户类型枚举 + * + * @author liukang + */ +@Getter +@AllArgsConstructor +public enum AccountChangeType { + + AccountChangeType_0("0","资金切换"), + AccountChangeType_1("1","会员充值"), + AccountChangeType_2("2","会员提现"), + AccountChangeType_3("3","银商结算"), + AccountChangeType_4("4","资金修正"), + AccountChangeType_5("5","活动"), + AccountChangeType_6("6","返水"), + AccountChangeType_7("7","返佣"), + AccountChangeType_8("8","任务"), + AccountChangeType_9("9","VIP奖励"), + AccountChangeType_10("10","充值优惠"), + AccountChangeType_11("11","俱乐部"), + AccountChangeType_12("12","奖励"), + AccountChangeType_13("13","公积金"); + + /** + * 账变大类(字典ff_account_change_type) + */ + private String changeType; + + + /** + * 描述信息 + */ + private String info; +} diff --git a/ff-base/src/main/java/com/ff/base/enums/AccountType.java b/ff-base/src/main/java/com/ff/base/enums/AccountType.java new file mode 100644 index 0000000..e5cc526 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/AccountType.java @@ -0,0 +1,22 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 账号类型 + * + * @author shang + */ +@Getter +public enum AccountType { + MEMBER(0, "会员"), + AGENT(1, "代理"); + + private final Integer code; + private final String info; + + AccountType(Integer code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityBetPlatformType.java b/ff-base/src/main/java/com/ff/base/enums/ActivityBetPlatformType.java new file mode 100644 index 0000000..0725cf7 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityBetPlatformType.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 活动指定平台 + * + * @author liukang + */ +@Getter +public enum ActivityBetPlatformType { + + /** + * 1.全部 2.指定平台 + */ + BETPLATFORMTYPE_1("1", "全部"), + BETPLATFORMTYPE_2("2", "指定平台"); + + private final String code; + private final String info; + + ActivityBetPlatformType(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityBetSendStatus.java b/ff-base/src/main/java/com/ff/base/enums/ActivityBetSendStatus.java new file mode 100644 index 0000000..4e5f2c4 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityBetSendStatus.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 推广活动奖励发放状态 + * + * @author liukang + */ +@Getter +public enum ActivityBetSendStatus { + + SENDSTATUS_1("1", "未发放"), + SENDSTATUS_2("2", "已发放"), + SENDSTATUS_3("3", "人工申请待申请"), + SENDSTATUS_4("4", "人工申请审核中"), + SENDSTATUS_5("5", "人工申请已拒绝"); + + private final String code; + private final String info; + + ActivityBetSendStatus(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityBetSendWay.java b/ff-base/src/main/java/com/ff/base/enums/ActivityBetSendWay.java new file mode 100644 index 0000000..9423f6f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityBetSendWay.java @@ -0,0 +1,29 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 打码活动奖励派发方式 + * + * @author liukang + */ +@Getter +public enum ActivityBetSendWay { + + /** + * 1.玩家自领-过期作废 2.玩家自领-过期自动派发 3.玩家申请-人工派发 + */ + SENDWAY_1("1", "玩家自领-过期作废"), + SENDWAY_2("2", "玩家自领-过期自动派发"), + SENDWAY_3("3", "玩家申请-人工派发"), + SENDWAY_4("3", "直接到账"); + + + private final String code; + private final String info; + + ActivityBetSendWay(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityChargeReceiveLimitType.java b/ff-base/src/main/java/com/ff/base/enums/ActivityChargeReceiveLimitType.java new file mode 100644 index 0000000..3673f99 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityChargeReceiveLimitType.java @@ -0,0 +1,36 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 充值活动更多申领限制 + * + * @author liukang + * @date 2025/01/08 + */ +@Getter +public enum ActivityChargeReceiveLimitType { + ReceiveLimitType_1("1", "完成短信验证才能领取"), + ReceiveLimitType_2("2", "完成邮箱验证才能领取"), + ReceiveLimitType_3("3", "完成银行卡绑定才能领取"), + ReceiveLimitType_4("4", "绑定虚拟货币才能领取"), + ReceiveLimitType_5("5", "绑定三方钱包才能领取"), + ReceiveLimitType_6("6", "绑定收款方式才能领取"), + ReceiveLimitType_7("7", "填写真实姓名才能领取"), + ReceiveLimitType_8("8", "同姓名只能领取1次"), + ReceiveLimitType_9("9", "同类型活动只能申领1次"), + ReceiveLimitType_10("10", "完成首充才能领取"), + ReceiveLimitType_11("11", "同登录IP号只能申领1次"), + ReceiveLimitType_12("12", "同登录设备号只能申领1次"), + ReceiveLimitType_13("13", "充值后且未投注才能领取"); + + private final String code; + private final String info; + + ActivityChargeReceiveLimitType(String code, String info) { + this.code = code; + this.info = info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityChargeRepeatReceive.java b/ff-base/src/main/java/com/ff/base/enums/ActivityChargeRepeatReceive.java new file mode 100644 index 0000000..06e6abe --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityChargeRepeatReceive.java @@ -0,0 +1,29 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 充值活动多笔重复领取 + * + * @author liukang + */ +@Getter +public enum ActivityChargeRepeatReceive { + + /** + *多笔重复领取(1.开启 2.关闭) 只有单笔充值才有此开关 并且开启后不用看领取次数 + * + * 开启:每笔充值满足条件都可获得对应奖励,例如,充5笔200档,该档可领取5次 + * 关闭:每个阶梯奖励仅可领取一次 + */ + REPEATRECEIVE_1("1", "开启"), + REPEATRECEIVE_2("2", "关闭"); + + private final String code; + private final String info; + + ActivityChargeRepeatReceive(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityChargeRewardType.java b/ff-base/src/main/java/com/ff/base/enums/ActivityChargeRewardType.java new file mode 100644 index 0000000..3d5c34d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityChargeRewardType.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 充值活动奖金方式 + * + * @author liukang + */ +@Getter +public enum ActivityChargeRewardType { + + /** + *奖励类型 1.固定金额 2.随机金额 3.比例 + */ + REWARDTYPE_1("1", "固定金额"), + REWARDTYPE_2("2", "随机金额"), + REWARDTYPE_3("3", "比例"); + + private final String code; + private final String info; + + ActivityChargeRewardType(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityChargeRuleType.java b/ff-base/src/main/java/com/ff/base/enums/ActivityChargeRuleType.java new file mode 100644 index 0000000..4db1a78 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityChargeRuleType.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 充值活动条件类型 + * + * @author liukang + */ +@Getter +public enum ActivityChargeRuleType { + + /** + *活动条件 1.账号首充 2.累计充值 3.单笔充值 + */ + RULETYPE_1("1", "账号首充"), + RULETYPE_2("2", "累计充值"), + RULETYPE_3("3", "单笔充值"); + + private final String code; + private final String info; + + ActivityChargeRuleType(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityChargeSendStatus.java b/ff-base/src/main/java/com/ff/base/enums/ActivityChargeSendStatus.java new file mode 100644 index 0000000..16e0ce7 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityChargeSendStatus.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 充值活动奖励发放状态 + * + * @author liukang + */ +@Getter +public enum ActivityChargeSendStatus { + + /** + * 1.未发放 2.已发放 + */ + SENDSTATUS_1("1", "未发放"), + SENDSTATUS_2("2", "已发放"); + + private final String code; + private final String info; + + ActivityChargeSendStatus(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityChargeSendWay.java b/ff-base/src/main/java/com/ff/base/enums/ActivityChargeSendWay.java new file mode 100644 index 0000000..609efd0 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityChargeSendWay.java @@ -0,0 +1,28 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 充值活动奖励派发方式 + * + * @author liukang + */ +@Getter +public enum ActivityChargeSendWay { + + /** + * 1.玩家自领-过期作废 2.玩家自领-过期自动派发 3.玩家申请-人工派发 + */ + SENDWAY_1("1", "玩家自领-过期作废"), + SENDWAY_2("2", "玩家自领-过期自动派发"), + SENDWAY_3("3", "立即派发"); + + + private final String code; + private final String info; + + ActivityChargeSendWay(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionAccordCondition.java b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionAccordCondition.java new file mode 100644 index 0000000..447b053 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionAccordCondition.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 推广活动奖励是否满足条件 + * + * @author liukang + */ +@Getter +public enum ActivityExtensionAccordCondition { + + ACCORDCONDITION_1("1", "满足"), + ACCORDCONDITION_2("2", "不满足"); + + private final String code; + private final String info; + + ActivityExtensionAccordCondition(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionChargeStatus.java b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionChargeStatus.java new file mode 100644 index 0000000..603845d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionChargeStatus.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 推广活动充值状态 + * + * @author liukang + */ +@Getter +public enum ActivityExtensionChargeStatus { + + CHARGESTATUS_1("1", "仅限已充值"), + CHARGESTATUS_2("2", "不限制"); + + private final String code; + private final String info; + + ActivityExtensionChargeStatus(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionChargeType.java b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionChargeType.java new file mode 100644 index 0000000..d28c61d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionChargeType.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 推广活动充值类型 + * + * @author liukang + */ +@Getter +public enum ActivityExtensionChargeType { + + /** + * 1.累计充值 2.累计充值天数 3.累计充值次数 + */ + CHARGETYPE_1("1", "累计充值"), + CHARGETYPE_2("2", "累计充值天数"), + CHARGETYPE_3("3", "累计充值次数"); + + private final String code; + private final String info; + + ActivityExtensionChargeType(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionLoginApp.java b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionLoginApp.java new file mode 100644 index 0000000..d2ec83e --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionLoginApp.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 推广活动充值状态 + * + * @author liukang + */ +@Getter +public enum ActivityExtensionLoginApp { + + LOGINAPP_1("1", "关闭"), + LOGINAPP_2("2", "开启"); + + private final String code; + private final String info; + + ActivityExtensionLoginApp(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionRewardType.java b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionRewardType.java new file mode 100644 index 0000000..1856e26 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionRewardType.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 推广活动奖励类型 + * + * @author liukang + */ +@Getter +public enum ActivityExtensionRewardType { + + /** + *奖励类型 1.固定金额 2.随机金额 3.累计日结(只领取最高一档,按推广的每人进行派奖,次日自动派发到账 例如:今日有效推广8人,满足最高档奖励10/人,则可获得8*10=80的奖励) + */ + REWARDTYPE_1("1", "固定金额"), + REWARDTYPE_2("2", "随机金额"), + REWARDTYPE_3("3", "累计日结"); + + private final String code; + private final String info; + + ActivityExtensionRewardType(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionSendStatus.java b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionSendStatus.java new file mode 100644 index 0000000..549b22a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionSendStatus.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 推广活动奖励发放状态 + * + * @author liukang + */ +@Getter +public enum ActivityExtensionSendStatus { + + SENDSTATUS_1("1", "未发放"), + SENDSTATUS_2("2", "已发放"), + SENDSTATUS_3("3", "日结待发放"), + SENDSTATUS_4("4", "人工申请待申请"), + SENDSTATUS_5("5", "人工申请审核中"), + SENDSTATUS_6("6", "人工申请已拒绝"); + + private final String code; + private final String info; + + ActivityExtensionSendStatus(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionSendWay.java b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionSendWay.java new file mode 100644 index 0000000..d5c863f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityExtensionSendWay.java @@ -0,0 +1,29 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 推广活动奖励派发方式 + * + * @author liukang + */ +@Getter +public enum ActivityExtensionSendWay { + + /** + * 1.玩家自领-过期作废 2.玩家自领-过期自动派发 3.玩家申请-人工派发 + */ + SENDWAY_1("1", "玩家自领-过期作废"), + SENDWAY_2("2", "玩家自领-过期自动派发"), + SENDWAY_3("3", "玩家申请-人工派发"), + SENDWAY_4("3", "直接到账"); + + + private final String code; + private final String info; + + ActivityExtensionSendWay(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityLimitedTimeDay.java b/ff-base/src/main/java/com/ff/base/enums/ActivityLimitedTimeDay.java new file mode 100644 index 0000000..41d6687 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityLimitedTimeDay.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 充值活动是否限时充值 + * + * @author liukang + */ +@Getter +public enum ActivityLimitedTimeDay { + + /** + * 是否限时充值 1.是 2.否 + */ + LIMITEDTIMEDAY_1("1", "是"), + LIMITEDTIMEDAY_2("2", "否"); + + private final String code; + private final String info; + + ActivityLimitedTimeDay(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityLoopType.java b/ff-base/src/main/java/com/ff/base/enums/ActivityLoopType.java new file mode 100644 index 0000000..9205f45 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityLoopType.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 活动循环方式 + * + * @author liukang + */ +@Getter +public enum ActivityLoopType { + + /** + * 循环方式 1.每日循环(00:00重置) 2.每周循环(周一00:00重置) 3.每月循环(每月1日00:00重置) + */ + LOOPTYPE_1("1", "每日循环(00:00重置)"), + LOOPTYPE_2("2", "每周循环(周一00:00重置)"), + LOOPTYPE_3("3", "每月循环(每月1日00:00重置)"); + + private final String code; + private final String info; + + ActivityLoopType(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityMainEntrance.java b/ff-base/src/main/java/com/ff/base/enums/ActivityMainEntrance.java new file mode 100644 index 0000000..21a0fa0 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityMainEntrance.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 活动首页快捷入口 + * + * @author liukang + */ +@Getter +public enum ActivityMainEntrance { + + /** + * 首页快捷入口 1.开启 2.关闭 + */ + MAINENTRANCE_1("1", "开启"), + MAINENTRANCE_2("2", "关闭"); + + private final String code; + private final String info; + + ActivityMainEntrance(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityReceiveCount.java b/ff-base/src/main/java/com/ff/base/enums/ActivityReceiveCount.java new file mode 100644 index 0000000..fb13630 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityReceiveCount.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 活动领取次数 + * + * @author liukang + */ +@Getter +public enum ActivityReceiveCount { + + /** + * 1.可逐条领取 2.领取最高一档(只能领一次) + */ + RECEIVECOUNT_1("1", "可逐条领取"), + RECEIVECOUNT_2("2", "领取最高一档(只能领一次)"); + + private final String code; + private final String info; + + ActivityReceiveCount(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityReceiveLimitType.java b/ff-base/src/main/java/com/ff/base/enums/ActivityReceiveLimitType.java new file mode 100644 index 0000000..d80df53 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityReceiveLimitType.java @@ -0,0 +1,35 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 活动更多申领限制 + * + * @author liukang + * @date 2025/01/03 + */ +@Getter +public enum ActivityReceiveLimitType { + ReceiveLimitType_1("1", "完成短信验证才能领取"), + ReceiveLimitType_2("2", "完成邮箱验证才能领取"), + ReceiveLimitType_3("3", "完成银行卡绑定才能领取"), + ReceiveLimitType_4("4", "绑定虚拟货币才能领取"), + ReceiveLimitType_5("5", "绑定三方钱包才能领取"), + ReceiveLimitType_6("6", "绑定收款方式才能领取"), + ReceiveLimitType_7("7", "填写真实姓名才能领取"), + ReceiveLimitType_8("8", "同姓名只能领取1次"), + ReceiveLimitType_9("9", "同类型活动只能申领1次"), + ReceiveLimitType_10("10", "完成首充才能领取"), + ReceiveLimitType_11("11", "同登录IP号只能申领1次"), + ReceiveLimitType_12("12", "同登录设备号只能申领1次"); + + private final String code; + private final String info; + + ActivityReceiveLimitType(String code, String info) { + this.code = code; + this.info = info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityRewardAuditStatus.java b/ff-base/src/main/java/com/ff/base/enums/ActivityRewardAuditStatus.java new file mode 100644 index 0000000..ae45443 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityRewardAuditStatus.java @@ -0,0 +1,25 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 活动奖励审核状态 + * + * @author liukang + */ +@Getter +public enum ActivityRewardAuditStatus { + + + AUDITSTATUS_1("1", "待审核"), + AUDITSTATUS_2("2", "通过"), + AUDITSTATUS_3("3", "拒绝"); + + private final String code; + private final String info; + + ActivityRewardAuditStatus(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityShowStatus.java b/ff-base/src/main/java/com/ff/base/enums/ActivityShowStatus.java new file mode 100644 index 0000000..236cf70 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityShowStatus.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 充值活动奖励派发方式 + * + * @author liukang + */ +@Getter +public enum ActivityShowStatus { + + /** + * 1.展示 2.隐藏 + */ + SHOW("1", "展示"), + HIDE("2", "隐藏"); + + + private final String code; + private final String info; + + ActivityShowStatus(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityStatus.java b/ff-base/src/main/java/com/ff/base/enums/ActivityStatus.java new file mode 100644 index 0000000..54a061c --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityStatus.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 活动任务状态 + * + * @author shang + */ +@Getter +public enum ActivityStatus { + + DRAFT(0, "草稿"), + UNDER_REVIEW(1, "审核中"), + IN_PROGRESS(2, "进行中"), + MANUALLY_CLOSED(3, "手动关闭"), + EXPIRED_CLOSED(4, "过期关闭"), + DELETE(5, "已删除"); + + private final Integer code; + private final String info; + + ActivityStatus(Integer code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ActivityTemplateType.java b/ff-base/src/main/java/com/ff/base/enums/ActivityTemplateType.java new file mode 100644 index 0000000..57c0e55 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ActivityTemplateType.java @@ -0,0 +1,50 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 活动模板类型 + * + * @author shang + */ +@Getter +public enum ActivityTemplateType { + + ActivityTemplateType_1(1, "充值"), + ActivityTemplateType_2(2, "打码"), + ActivityTemplateType_3(3, "救援金"), + ActivityTemplateType_4(4, "签到"), + ActivityTemplateType_5(5, "幸运转盘"), + ActivityTemplateType_6(6, "幸运注单"), + ActivityTemplateType_7(7, "红包"), + ActivityTemplateType_8(8, "投资"), + ActivityTemplateType_9(9, "推广"), + ActivityTemplateType_10(10, "代理"), + ActivityTemplateType_11(11, "集字"), + ActivityTemplateType_12(12, "竞猜"), + ActivityTemplateType_13(13, "新人彩金"), + ActivityTemplateType_14(14, "抽奖助力"), + ActivityTemplateType_15(15, "砍一刀"), + ActivityTemplateType_16(16, "排行榜"), + ActivityTemplateType_17(17, "自定义"); + + + private final Integer code; + private final String info; + + ActivityTemplateType(Integer code, String info) + { + this.code = code; + this.info = info; + } + public static ActivityTemplateType getActivityTemplateTypByCode(Integer code) + { + for (ActivityTemplateType item : ActivityTemplateType.values()) { + if(item.getCode().equals(code)) { + return item; + } + } + return null; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/AgentModelType.java b/ff-base/src/main/java/com/ff/base/enums/AgentModelType.java new file mode 100644 index 0000000..311716c --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/AgentModelType.java @@ -0,0 +1,36 @@ +package com.ff.base.enums; + +import com.ff.base.exception.base.BaseException; +import com.ff.base.utils.MessageUtils; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 代理模式类型 + * + * @author shang + */ + +@Getter +@AllArgsConstructor +public enum AgentModelType { + ONE_LEVEL_PROFIT(1, "一级净盈利"), + THREE_LEVEL_PROFIT(2, "三级净盈利"), + GLOBAL_AGENT(3, "全民代理"), + UNLIMITED(4, "无限极差"), + ONE_LEVEL_AGENT(5, "一级代理"); + + private final Integer code; + private final String info; + + public static AgentModelType getAgentModelTypeByCode(Integer code) + { + for (AgentModelType item : AgentModelType.values()) { + if(item.getCode().equals(code)) { + return item; + } + } + throw new BaseException(MessageUtils.message("agent.agentmode.enum.not.exists")); + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/AndroidForceDownload.java b/ff-base/src/main/java/com/ff/base/enums/AndroidForceDownload.java new file mode 100644 index 0000000..64ba867 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/AndroidForceDownload.java @@ -0,0 +1,24 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 安卓强制下载 + * + * @author shi + * @date 2024/12/23 + */ +@Getter +public enum AndroidForceDownload { + DISABLED("1", "关闭(全部限制)"), + ENABLED("2", "开启"); + + private final String code; + private final String description; + + AndroidForceDownload(String code, String description) { + this.code = code; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/AnnouncementStatus.java b/ff-base/src/main/java/com/ff/base/enums/AnnouncementStatus.java new file mode 100644 index 0000000..8b4ca70 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/AnnouncementStatus.java @@ -0,0 +1,25 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 公告状态 + * + * @author shi + * @date 2024/11/22 + */ +@Getter +public enum AnnouncementStatus { + PENDING_REVIEW(0, "待审核"), + PENDING_EFFECT(1, "待生效"), + ACTIVE(2, "生效中"), + EXPIRED(3, "已过期"), + CANCELLED(4, "已取消"); + private final Integer code; + private final String description; + + AnnouncementStatus(Integer code, String description) { + this.code = code; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/AppLocation.java b/ff-base/src/main/java/com/ff/base/enums/AppLocation.java new file mode 100644 index 0000000..8c053d6 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/AppLocation.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 应用程序位置 + * + * @author shi + * @date 2024/12/03 + */ +@Getter +public enum AppLocation { + HOME(1, "首页"), + SECONDARY_PAGE(2, "二级页面"); + + private final Integer code; + private final String description; + + AppLocation(Integer code, String description) { + this.code = code; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/AwardType.java b/ff-base/src/main/java/com/ff/base/enums/AwardType.java new file mode 100644 index 0000000..3c500f9 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/AwardType.java @@ -0,0 +1,24 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 奖励类型 + * + * @author shang + */ +@Getter +public enum AwardType { + AwardType_1(1, "固定"), + AwardType_2(2, "随机"); + + private final Integer code; + private final String info; + + AwardType(Integer code, String info) + { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/BannerStatus.java b/ff-base/src/main/java/com/ff/base/enums/BannerStatus.java new file mode 100644 index 0000000..64cc184 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/BannerStatus.java @@ -0,0 +1,25 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * Banner状态 + * + * @author shi + * @date 2024/11/22 + */ +@Getter +public enum BannerStatus { + PENDING_REVIEW(0, "待审核"), + PENDING_EFFECT(1, "待生效"), + ACTIVE(2, "生效中"), + EXPIRED(3, "已过期"), + CANCELLED(4, "已取消"); + private final Integer code; + private final String description; + + BannerStatus(Integer code, String description) { + this.code = code; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/BetTaskSource.java b/ff-base/src/main/java/com/ff/base/enums/BetTaskSource.java new file mode 100644 index 0000000..bbf8dc2 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/BetTaskSource.java @@ -0,0 +1,39 @@ +package com.ff.base.enums; + +/** + * 会员投注任务来源 + * + * @author liukang + */ +public enum BetTaskSource +{ + + BetTaskSource_0("0", "会员充值"), + BetTaskSource_1("1", "充值优惠"), + BetTaskSource_2("2", "返水"), + BetTaskSource_3("3", "系统稽核"), + BetTaskSource_4("4", "资金修正"), + BetTaskSource_5("5", "取消提现"), + BetTaskSource_6("6", "VIP奖励"), + BetTaskSource_7("7", "任务"), + BetTaskSource_8("8", "活动"); + + private final String code; + private final String info; + + BetTaskSource(String code, String info) + { + this.code = code; + this.info = info; + } + + public String getCode() + { + return code; + } + + public String getInfo() + { + return info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/BetTaskStatus.java b/ff-base/src/main/java/com/ff/base/enums/BetTaskStatus.java new file mode 100644 index 0000000..3f92edf --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/BetTaskStatus.java @@ -0,0 +1,38 @@ +package com.ff.base.enums; + +/** + * 会员投注任务状态 + * + * @author liukang + */ +public enum BetTaskStatus +{ + /** + * 账号状态(0正常 1手动冻结 2异常冻结 3禁止领取优惠 4禁止提现 5黑名单 6停用 7禁止进入游戏 8自我禁止-限制游戏 9自我禁止-限制参与优惠 10自我禁止-限制登录) + */ + BetTaskStatus_0("0", "等待投注"), + BetTaskStatus_1("1", "进行中"), + BetTaskStatus_2("2", "完成"), + BetTaskStatus_3("3", "人工解除"), + BetTaskStatus_4("4", "系统解除"), + BetTaskStatus_5("-1", "所有未完成"); + + private final String code; + private final String info; + + BetTaskStatus(String code, String info) + { + this.code = code; + this.info = info; + } + + public String getCode() + { + return code; + } + + public String getInfo() + { + return info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/BoxStatusType.java b/ff-base/src/main/java/com/ff/base/enums/BoxStatusType.java new file mode 100644 index 0000000..6251018 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/BoxStatusType.java @@ -0,0 +1,25 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 宝箱状态类型 + * + * @author shang + */ +@Getter +public enum BoxStatusType { + BoxStatusType_1("1", "不满足条件"), + BoxStatusType_2("2", "可领取"), + BoxStatusType_3("3", "已领取"); + + private final String code; + private final String info; + + BoxStatusType(String code, String info) + { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/BusinessStatus.java b/ff-base/src/main/java/com/ff/base/enums/BusinessStatus.java new file mode 100644 index 0000000..dded7da --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/BusinessStatus.java @@ -0,0 +1,20 @@ +package com.ff.base.enums; + +/** + * 操作状态 + * + * @author ff + * + */ +public enum BusinessStatus +{ + /** + * 成功 + */ + SUCCESS, + + /** + * 失败 + */ + FAIL, +} diff --git a/ff-base/src/main/java/com/ff/base/enums/BusinessType.java b/ff-base/src/main/java/com/ff/base/enums/BusinessType.java new file mode 100644 index 0000000..0edaeb6 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/BusinessType.java @@ -0,0 +1,59 @@ +package com.ff.base.enums; + +/** + * 业务操作类型 + * + * @author ff + */ +public enum BusinessType +{ + /** + * 其它 + */ + OTHER, + + /** + * 新增 + */ + INSERT, + + /** + * 修改 + */ + UPDATE, + + /** + * 删除 + */ + DELETE, + + /** + * 授权 + */ + GRANT, + + /** + * 导出 + */ + EXPORT, + + /** + * 导入 + */ + IMPORT, + + /** + * 强退 + */ + FORCE, + + /** + * 生成代码 + */ + GENCODE, + + /** + * 清空数据 + */ + CLEAN, +} diff --git a/ff-base/src/main/java/com/ff/base/enums/CalcModeType.java b/ff-base/src/main/java/com/ff/base/enums/CalcModeType.java new file mode 100644 index 0000000..13aee38 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/CalcModeType.java @@ -0,0 +1,25 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 计算方式类型 + * + * @author shang + */ +@Getter +public enum CalcModeType { + CalcModeType_0("0", "所有会员(综合盈利会员)"), + CalcModeType_1("1", "仅计算亏损会员"); + + private final String code; + private final String info; + + CalcModeType(String code, String info) + { + this.code = code; + this.info = info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/CalcPerformanceType.java b/ff-base/src/main/java/com/ff/base/enums/CalcPerformanceType.java new file mode 100644 index 0000000..8008e4e --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/CalcPerformanceType.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 佣金计算依据类型 + * + * @author shang + */ +@Getter +public enum CalcPerformanceType { + + CalcPerformanceType_0("0", "有效投注"), + CalcPerformanceType_1("1", "亏损金额"), + CalcPerformanceType_2("2", "净盈利"); + + private final String code; + private final String info; + + CalcPerformanceType(String code, String info) + { + this.code = code; + this.info = info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/CalcRangeType.java b/ff-base/src/main/java/com/ff/base/enums/CalcRangeType.java new file mode 100644 index 0000000..b6a46aa --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/CalcRangeType.java @@ -0,0 +1,24 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 计算方式类型 + * + * @author shang + */ +@Getter +public enum CalcRangeType { + CalcRangeType_0("0", "计算全部(含无效)"), + CalcRangeType_1("1", "只计算有效会员业绩"); + + private final String code; + private final String info; + + CalcRangeType(String code, String info) + { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/CalculateType.java b/ff-base/src/main/java/com/ff/base/enums/CalculateType.java new file mode 100644 index 0000000..6551722 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/CalculateType.java @@ -0,0 +1,28 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 任务目标类型 + */ +@Getter +public enum CalculateType { + CalculateType_1(1, "累计充值"), + CalculateType_2(2, "累计有效投注"), + CalculateType_3(3, "单局有效投注"), + CalculateType_4(4, "单局盈利"), + CalculateType_5(5, "单局亏损"), + CalculateType_6(6, "累计盈利"), + CalculateType_7(7, "累计亏损"), + CalculateType_8(8, "神秘大奖"); + + private final Integer code; + private final String info; + + CalculateType(Integer code, String info) { + this.code = code; + this.info = info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ChangeStatus.java b/ff-base/src/main/java/com/ff/base/enums/ChangeStatus.java new file mode 100644 index 0000000..5fbe7c5 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ChangeStatus.java @@ -0,0 +1,28 @@ +package com.ff.base.enums; + +/** + * 更改状态 + * + * @author shi + * @date 2024/10/31 + */ +public enum ChangeStatus { + SUCCESS(1, "成功"), + FAIL(2, "失败"); + + private final Integer code; + private final String info; + + ChangeStatus(Integer code, String info) { + this.code = code; + this.info = info; + } + + public Integer getCode() { + return code; + } + + public String getInfo() { + return info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ChannelType.java b/ff-base/src/main/java/com/ff/base/enums/ChannelType.java new file mode 100644 index 0000000..29ae9b5 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ChannelType.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 通道类型 + * + * @author shi + * @date 2025/01/11 + */ +@Getter +public enum ChannelType { + CHANNEL_LINK(1, "渠道链接"), + PWA_SHORTCUT_APP(2, "PWA快捷APP"), + WG_GAME_TRIAL_LINK(3, "WG游戏试玩链接"), + INDEPENDENT_CHANNEL_PACKAGE(4, "独立渠道包"), + NATIVE_MAJIA_PACKAGE(5, "原生马甲包"), + DOWNLOAD_SITE_SOURCE(6, "下载站源码"); + + private final Integer value; + private final String description; + + ChannelType(Integer value, String description) { + this.value = value; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/ChargeOrderFlag.java b/ff-base/src/main/java/com/ff/base/enums/ChargeOrderFlag.java new file mode 100644 index 0000000..b4ceeca --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ChargeOrderFlag.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 充值订单标记枚举 + * + * @author liukang + * @date 2024/11/27 + */ +@Getter +@AllArgsConstructor +public enum ChargeOrderFlag { + + ChargeOrderFlag_0( "确认入款"), + ChargeOrderFlag_1("取消入款"), + ChargeOrderFlag_2( "补单审核通过"), + ChargeOrderFlag_3( "补单审核拒绝"), + ChargeOrderFlag_4( "无审核补单"); + + private final String info; + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ChargeOrderPayStatus.java b/ff-base/src/main/java/com/ff/base/enums/ChargeOrderPayStatus.java new file mode 100644 index 0000000..994a0eb --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ChargeOrderPayStatus.java @@ -0,0 +1,43 @@ +package com.ff.base.enums; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Optional; +import java.util.stream.Stream; + +/** + * 充值订单支付状态 + * + * @author liukang + * @date 2024/11/22 + */ +@Getter +@AllArgsConstructor +public enum ChargeOrderPayStatus { + + STATUS_0(0, 0, "待支付"), + STATUS_1(1, 1, "支付超时"), + STATUS_2(2, 2, "补单审核中"), + STATUS_3(3, 3, "支付成功"), + STATUS_4(4, 4, "支付失败"); + + private final Integer status; + private final Integer code; + private final String info; + + /** + * 按code查找状态 + * + * @param code 代码 + * @return {@link String } + */ + public static Integer findStatusByCode(Integer code) { + Optional system = Stream.of(ChargeOrderPayStatus.values()) + .filter(fyPayStatus -> fyPayStatus.getCode().equals(code)) + .map(ChargeOrderPayStatus::getStatus) + .findFirst(); + return system.orElse(null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/CostType.java b/ff-base/src/main/java/com/ff/base/enums/CostType.java new file mode 100644 index 0000000..a00123b --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/CostType.java @@ -0,0 +1,24 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 成本型 + * + * @author shi + * @date 2025/01/11 + */ +@Getter +public enum CostType { + YEAR(1, "年"), + QUARTER(2, "季度"), + MONTH(3, "月"); + + private final Integer value; // 使用包装类 Integer + private final String description; + + CostType(Integer value, String description) { + this.value = value; + this.description = description; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/DataSourceType.java b/ff-base/src/main/java/com/ff/base/enums/DataSourceType.java new file mode 100644 index 0000000..d89deb8 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DataSourceType.java @@ -0,0 +1,19 @@ +package com.ff.base.enums; + +/** + * 数据源 + * + * @author ff + */ +public enum DataSourceType +{ + /** + * 主库 + */ + MASTER, + + /** + * 从库 + */ + SLAVE +} diff --git a/ff-base/src/main/java/com/ff/base/enums/DesensitizedType.java b/ff-base/src/main/java/com/ff/base/enums/DesensitizedType.java new file mode 100644 index 0000000..501c83a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DesensitizedType.java @@ -0,0 +1,60 @@ +package com.ff.base.enums; + +import com.ff.base.utils.DesensitizedUtil; + +import java.util.function.Function; + +/** + * 脱敏类型 + * + * @author ff + */ +public enum DesensitizedType +{ + /** + * 姓名,第2位星号替换 + */ + USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")), + + /** + * 密码,全部字符都用*代替 + */ + PASSWORD(DesensitizedUtil::password), + + /** + * 身份证,中间10位星号替换 + */ + ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\d{4})", "$1** **** ****$2")), + + /** + * 手机号,中间4位星号替换 + */ + PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")), + + /** + * 电子邮箱,仅显示第一个字母和@后面的地址显示,其他星号替换 + */ + EMAIL(s -> s.replaceAll("(^.)[^@]*(@.*$)", "$1****$2")), + + /** + * 银行卡号,保留最后4位,其他星号替换 + */ + BANK_CARD(s -> s.replaceAll("\\d{15}(\\d{3})", "**** **** **** **** $1")), + + /** + * 车牌号码,包含普通车辆、新能源车辆 + */ + CAR_LICENSE(DesensitizedUtil::carLicense); + + private final Function desensitizer; + + DesensitizedType(Function desensitizer) + { + this.desensitizer = desensitizer; + } + + public Function desensitizer() + { + return desensitizer; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/DeviceType.java b/ff-base/src/main/java/com/ff/base/enums/DeviceType.java new file mode 100644 index 0000000..caa2ed6 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DeviceType.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 设备类型枚举 + * + * @author liukang + */ +@Getter +public enum DeviceType { + + DEVICETYPE_1("APP-iOS", "APP-iOS"), + DEVICETYPE_2("H5-iOS", "H5-iOS"), + DEVICETYPE_3("APP-Android", "APP-Android"), + DEVICETYPE_4("H5-Android", "H5-Android"), + DEVICETYPE_5("PC-Windows", "PC-Windows"), + DEVICETYPE_6("PC-Mac", "PC-Mac"); + + private final String code; + private final String info; + + DeviceType(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/DirectFlagType.java b/ff-base/src/main/java/com/ff/base/enums/DirectFlagType.java new file mode 100644 index 0000000..8945b56 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DirectFlagType.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 直属或者其他标识类型 + * + * @author shang + */ + +@Getter +public enum DirectFlagType { + DirectFlagType_0(0, "其他"), + DirectFlagType_1(1, "直属"); + + private final Integer code; + private final String info; + + DirectFlagType(Integer code, String info) + { + this.code = code; + this.info = info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/DiscountReceiveSmallType.java b/ff-base/src/main/java/com/ff/base/enums/DiscountReceiveSmallType.java new file mode 100644 index 0000000..81393f0 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DiscountReceiveSmallType.java @@ -0,0 +1,63 @@ +package com.ff.base.enums; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 优惠领取小类 + * + * @author liukang + * @date 2024/12/21 + */ +@Getter +@AllArgsConstructor +public enum DiscountReceiveSmallType { + + SMALLTYPE_1("1", "VIP晋级奖励"), + SMALLTYPE_2("2", "VIP日俸禄"), + SMALLTYPE_3("3", "VIP周俸禄"), + SMALLTYPE_4("4", "VIP月俸禄"), + + SMALLTYPE_5("5", "新人福利(注册账号)"), + SMALLTYPE_6("6", "新人福利(首次绑定银行卡)"), + SMALLTYPE_7("7", "新人福利(设置生日)"), + SMALLTYPE_8("8", "新人福利(设置取款密码)"), + SMALLTYPE_9("9", "新人福利(设置密保)"), + SMALLTYPE_10("10", "新人福利(利息宝首存)"), + SMALLTYPE_11("11", "新人福利(设置头像)"), + SMALLTYPE_12("12", "新人福利(短信验证)"), + SMALLTYPE_13("13", "新人福利(设置Google验证器)"), + SMALLTYPE_14("14", "新人福利(注册首存)"), + SMALLTYPE_15("15", "新人福利(首次下载安装并登录APP)"), + SMALLTYPE_16("16", "新人福利(邮箱验证)"), + SMALLTYPE_17("17", "新人福利(保存桌面快捷方式)"), + SMALLTYPE_18("18", "新人福利(首次绑定数字货币)"), + SMALLTYPE_19("19", "新人福利(添加提现账户)"), + SMALLTYPE_20("20", "新人福利(首次提现)"), + SMALLTYPE_21("21", "新人福利(设置任意联系方式)"), + + SMALLTYPE_22("22", "每日任务"), + SMALLTYPE_23("23", "每周任务"), + SMALLTYPE_24("24", "神秘任务"), + SMALLTYPE_25("25", "推广活动"), + SMALLTYPE_26("26", "有奖反馈"), + SMALLTYPE_27("27", "活跃度宝箱"), + SMALLTYPE_28("28", "充值活动"), + SMALLTYPE_29("29", "打码活动"), + SMALLTYPE_30("30", "返水活动"); + + private final String smallType; + private final String info; + + public static DiscountReceiveSmallType getDiscountReceiveSmallTypeByType(String smallType) + { + for (DiscountReceiveSmallType item : DiscountReceiveSmallType.values()) { + if(item.getSmallType().equals(smallType)) { + return item; + } + } + return null; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/DiscountReceiveSource.java b/ff-base/src/main/java/com/ff/base/enums/DiscountReceiveSource.java new file mode 100644 index 0000000..7a0c57f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DiscountReceiveSource.java @@ -0,0 +1,28 @@ +package com.ff.base.enums; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Optional; +import java.util.stream.Stream; + +/** + * 优惠领取来源 + * + * @author liukang + * @date 2024/12/21 + */ +@Getter +@AllArgsConstructor +public enum DiscountReceiveSource { + + SOURCE_1("1", "VIP奖励"), + SOURCE_2("2", "返水"), + SOURCE_3("3", "任务奖励"), + SOURCE_4("4", "活动奖励"); + + private final String source; + private final String info; + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/DiscountReceiveStatus.java b/ff-base/src/main/java/com/ff/base/enums/DiscountReceiveStatus.java new file mode 100644 index 0000000..32f7dda --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DiscountReceiveStatus.java @@ -0,0 +1,30 @@ +package com.ff.base.enums; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 优惠领取状态 + * + * @author liukang + * @date 2024/12/21 + */ +@Getter +@AllArgsConstructor +public enum DiscountReceiveStatus { + + STATUS_0("0", "待领取"), + STATUS_1("1", "已领取"), + STATUS_2("2", "系统已派发"), + // 会员降级作废、任务层级去除也需作废等 + STATUS_3("3", "已作废"), + STATUS_4("4", "已过期"), + STATUS_5("-1", "所有已领取"), + STATUS_6("6", "手动已派发"), + STATUS_7("7", "已取消"), + STATUS_8("-2", "所有已放弃"); + private final String status; + private final String info; + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/DnsRecordType.java b/ff-base/src/main/java/com/ff/base/enums/DnsRecordType.java new file mode 100644 index 0000000..811c31a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DnsRecordType.java @@ -0,0 +1,38 @@ +package com.ff.base.enums; + +import lombok.Getter; + +@Getter +public enum DnsRecordType { + A(1, "A"), + AAAA(2, "AAAA"), + CNAME(3, "CNAME"), + TXT(4, "TXT"), + MX(5, "MX"), + SRV(6, "SRV"), + NS(7, "NS"); + + private final Integer value; + private final String name; + + DnsRecordType(Integer value, String name) { + this.value = value; + this.name = name; + } + + + /** + * 按值获取名称 + * + * @param value 价值 + * @return {@link String } + */ + public static String getNameByValue(Integer value) { + for (DnsRecordType type : DnsRecordType.values()) { + if (type.getValue().equals(value)) { + return type.getName(); + } + } + return null; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/DomainCloudfareStatus.java b/ff-base/src/main/java/com/ff/base/enums/DomainCloudfareStatus.java new file mode 100644 index 0000000..0e0e2bc --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DomainCloudfareStatus.java @@ -0,0 +1,25 @@ +package com.ff.base.enums; + +import lombok.Getter; + + +/** + * Cloudfare 状态类型 + * + * @author shi + * @date 2025/01/20 + */ +@Getter +public enum DomainCloudfareStatus { + INITIALIZING("initializing", "初始化中"), + PENDING("pending", "待处理"), + ACTIVE("active", "激活状态"); + + private final String value; + private final String description; + + DomainCloudfareStatus(String value, String description) { + this.value = value; + this.description = description; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/DomainSonType.java b/ff-base/src/main/java/com/ff/base/enums/DomainSonType.java new file mode 100644 index 0000000..9b8bf0c --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DomainSonType.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 域子类型 + * + * @author shi + * @date 2025/01/03 + */ +@Getter +public enum DomainSonType { + WEB_HALL(1, "Web大厅"), + BACKEND_ACCELERATION(2, "后端加速域名"), + APP_HALL(3, "App大厅"), + OSS_DOMAIN(4, "OSS域名"), + DOWNLOAD_SITE(5, "下载站域名"), + PAYMENT_DOMAIN(6, "支付域名"); + + private final Integer value; + private final String description; + + DomainSonType(Integer value, String description) { + this.value = value; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/DomainSonUsageStatus.java b/ff-base/src/main/java/com/ff/base/enums/DomainSonUsageStatus.java new file mode 100644 index 0000000..c3346b5 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DomainSonUsageStatus.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 域子使用状态 + * + * @author shi + * @date 2025/01/21 + */ +@Getter +public enum DomainSonUsageStatus { + PENDING(1, "待启用"), + ENABLE_IN_PROGRESS(2, "启用中"), + SWITCH_IN_PROGRESS(3, "切换中"), + ENABLED(4, "启用成功"), + DISABLE_IN_PROGRESS(5, "停用中"); + + private final Integer value; + private final String description; + + DomainSonUsageStatus(Integer value, String description) { + this.value = value; + this.description = description; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/DomainStatus.java b/ff-base/src/main/java/com/ff/base/enums/DomainStatus.java new file mode 100644 index 0000000..100ecbb --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DomainStatus.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 域状态 + * + * @author shi + * @date 2025/01/02 + */ +@Getter +public enum DomainStatus { + PENDING_VERIFICATION(1, "待验证"), + NORMAL(2, "正常"), + EXPIRED(3, "已过期"), + PENDING_RECOVERY(4, "待找回"); + + + private final int value; + private final String description; + + DomainStatus(int value, String description) { + this.value = value; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/DomainType.java b/ff-base/src/main/java/com/ff/base/enums/DomainType.java new file mode 100644 index 0000000..d39e985 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DomainType.java @@ -0,0 +1,24 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 域类型 + * + * @author shi + * @date 2025/01/04 + */ +@Getter +public enum DomainType { + WILDCARD_DOMAIN(1, "泛解析域名"), + ROOT_DOMAIN(2, "根域名"), + SUB_DOMAIN(3, "子域名"); + + private final int value; + private final String description; + + DomainType(int value, String description) { + this.value = value; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/DownloadType.java b/ff-base/src/main/java/com/ff/base/enums/DownloadType.java new file mode 100644 index 0000000..09d7bb2 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DownloadType.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 下载类型 + * + * @author shi + * @date 2025/01/11 + */ +@Getter +public enum DownloadType { + WEB_HALL(1, "Web大厅"), + DOWNLOAD_SITE(2, "下载站"); + + private final Integer value; + private final String description; + + DownloadType(Integer value, String description) { + this.value = value; + this.description = description; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/DrawType.java b/ff-base/src/main/java/com/ff/base/enums/DrawType.java new file mode 100644 index 0000000..ea7cbf3 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/DrawType.java @@ -0,0 +1,22 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 领取奖励方式 + * + * @author shang + */ +@Getter +public enum DrawType { + DrawType_1("1", "一键领取"), + DrawType_2("2", "单笔领取"); + + private final String code; + private final String info; + + DrawType(String code, String info){ + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/EnableStatus.java b/ff-base/src/main/java/com/ff/base/enums/EnableStatus.java new file mode 100644 index 0000000..cc03c52 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/EnableStatus.java @@ -0,0 +1,24 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 启用状态 + * + * @author shang + */ +@Getter +public enum EnableStatus { + OFF(0, "关闭"), + ON(1, "开启"); + + private final Integer code; + private final String info; + + EnableStatus(Integer code, String info) + { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/EventType.java b/ff-base/src/main/java/com/ff/base/enums/EventType.java new file mode 100644 index 0000000..fe637d0 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/EventType.java @@ -0,0 +1,22 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 事项类型 + */ +@Getter +public enum EventType { + EventType_1(1, "充值"), + EventType_2(2, "投注"); + + private final Integer code; + private final String info; + + EventType(Integer code, String info) + { + this.code = code; + this.info = info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/FeedbackStatus.java b/ff-base/src/main/java/com/ff/base/enums/FeedbackStatus.java new file mode 100644 index 0000000..d43e168 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/FeedbackStatus.java @@ -0,0 +1,24 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 反馈状态 + * + * @author shi + * @date 2024/12/10 + */ +@Getter +public enum FeedbackStatus { + PENDING(1, "待处理"), + ACCEPTED(2, "已采纳"), + IGNORED(3, "已忽略"); + + private final Integer code; + private final String description; + + FeedbackStatus(Integer code, String description) { + this.code = code; + this.description = description; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/FrameStatus.java b/ff-base/src/main/java/com/ff/base/enums/FrameStatus.java new file mode 100644 index 0000000..a09d567 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/FrameStatus.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + +import lombok.Getter; + + +/** + * 弹框状态 + * + * @author shi + * @date 2024/11/25 + */ +@Getter +public enum FrameStatus { + PENDING_REVIEW(0, "待审核"), + PENDING_EFFECT(1, "待生效"), + ACTIVE(2, "生效中"), + EXPIRED(3, "已过期"), + CANCELLED(4, "已取消"); + private final Integer code; + private final String description; + + FrameStatus(Integer code, String description) { + this.code = code; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/FreeStatus.java b/ff-base/src/main/java/com/ff/base/enums/FreeStatus.java new file mode 100644 index 0000000..862721d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/FreeStatus.java @@ -0,0 +1,31 @@ +package com.ff.base.enums; + +/** + * 自由状态 + * + * @author shi + * @date 2024/11/11 + */ +public enum FreeStatus { + NORMAL(1, "正常"), + CANCEL(0, "取消"); + + private final Integer code; + private final String info; + + FreeStatus(Integer code, String info) + { + this.code = code; + this.info = info; + } + + public Integer getCode() + { + return code; + } + + public String getInfo() + { + return info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/FyPayStatus.java b/ff-base/src/main/java/com/ff/base/enums/FyPayStatus.java new file mode 100644 index 0000000..597db16 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/FyPayStatus.java @@ -0,0 +1,44 @@ +package com.ff.base.enums; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Optional; +import java.util.stream.Stream; + +/** + * fypay支付状态 + * + * @author liukang + * @date 2024/10/22 + */ +@Getter +@AllArgsConstructor +public enum FyPayStatus { + + PROCESSING(0, "PROCESSING", "待支付"), + SUCCESS(1, "SUCCESS", "支付成功"), + FAIL(2, "FAIL", "支付失败"), + TIMEOUT(2, "TIMEOUT", "超时关闭"), + EXCEPTION(2, "EXCEPTION", "发起支付异常"), + CLOSE(2, "CLOSE", "手动关闭"); + + private final Integer status; + private final String code; + private final String info; + + /** + * 按code查找状态 + * + * @param code 代码 + * @return {@link String } + */ + public static Integer findStatusByCode(String code) { + Optional system = Stream.of(FyPayStatus.values()) + .filter(fyPayStatus -> fyPayStatus.getCode().equals(code)) + .map(FyPayStatus::getStatus) + .findFirst(); + return system.orElse(null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/GameCollectionStatus.java b/ff-base/src/main/java/com/ff/base/enums/GameCollectionStatus.java new file mode 100644 index 0000000..1914dab --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/GameCollectionStatus.java @@ -0,0 +1,30 @@ +package com.ff.base.enums; + + +/** + * 游戏收藏状态 + * + * @author shi + * @date 2024/11/04 + */ +public enum GameCollectionStatus { + COMPLETE(1, " 收藏中"), + NOT(2, "未收藏"); + + private final Integer code; + private final String info; + + GameCollectionStatus(Integer code, String info) { + this.code = code; + this.info = info; + } + + public Integer getCode() { + return code; + } + + public String getInfo() { + return info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/GameEventEnum.java b/ff-base/src/main/java/com/ff/base/enums/GameEventEnum.java new file mode 100644 index 0000000..2715d83 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/GameEventEnum.java @@ -0,0 +1,22 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 游戏事件 + * + * @author shi + * @date 2024/12/10 + */ +@Getter +public enum GameEventEnum { + FETCH_BETTING_RECORD(1, "投注记录拉取"); + + private final Integer code; + private final String description; + + GameEventEnum(Integer code, String description) { + this.code = code; + this.description = description; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/GameHotStatus.java b/ff-base/src/main/java/com/ff/base/enums/GameHotStatus.java new file mode 100644 index 0000000..99c0ffc --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/GameHotStatus.java @@ -0,0 +1,29 @@ +package com.ff.base.enums; + +/** + * 游戏热门状态 + * + * @author shi + * @date 2024/11/01 + */ +public enum GameHotStatus { + CLOSE("1", " 关闭"), + OPEN("2", "开启"); + + private final String code; + private final String info; + + GameHotStatus(String code, String info) { + this.code = code; + this.info = info; + } + + public String getCode() { + return code; + } + + public String getInfo() { + return info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/GameOpenStatus.java b/ff-base/src/main/java/com/ff/base/enums/GameOpenStatus.java new file mode 100644 index 0000000..b6f0f8a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/GameOpenStatus.java @@ -0,0 +1,29 @@ +package com.ff.base.enums; + +/** + * 游戏状态 + * + * @author shi + * @date 2024/10/23 + */ +public enum GameOpenStatus { + OPEN(1, " 开启"), + CLOSE(2, "关闭"); + + private final Integer code; + private final String info; + + GameOpenStatus(Integer code, String info) { + this.code = code; + this.info = info; + } + + public Integer getCode() { + return code; + } + + public String getInfo() { + return info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/GamePlatforms.java b/ff-base/src/main/java/com/ff/base/enums/GamePlatforms.java new file mode 100644 index 0000000..0699988 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/GamePlatforms.java @@ -0,0 +1,28 @@ +package com.ff.base.enums; + +public enum GamePlatforms { + JILI("JILI", "JILI"), + XK("XK", "XK"), + ; + + private final String code; + private final String info; + + GamePlatforms(String code, String info) + { + this.code = code; + this.info = info; + } + + public String getCode() + { + return code; + } + + public String getInfo() + { + return info; + } + + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/GamePlayStatus.java b/ff-base/src/main/java/com/ff/base/enums/GamePlayStatus.java new file mode 100644 index 0000000..7778c8f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/GamePlayStatus.java @@ -0,0 +1,30 @@ +package com.ff.base.enums; + +/** + * 游戏状态 + * + * @author shi + * @date 2024/10/31 + */ +public enum GamePlayStatus { + ACTIVE(1, "在线"), + OFFLINE(2, "脱机"), + EXIST(3, "账号不存在") + ; + + private final Integer code; + private final String info; + + GamePlayStatus(Integer code, String info) { + this.code = code; + this.info = info; + } + + public Integer getCode() { + return code; + } + + public String getInfo() { + return info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/GamePopularCategory.java b/ff-base/src/main/java/com/ff/base/enums/GamePopularCategory.java new file mode 100644 index 0000000..9f84dd2 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/GamePopularCategory.java @@ -0,0 +1,29 @@ +package com.ff.base.enums; + +/** + * 游戏流行 + * + * @author shi + * @date 2024/10/29 + */ +public enum GamePopularCategory { + PLATFORM(1, "平台"), + GAME(2, "子游戏"); + + private final Integer code; + private final String info; + + GamePopularCategory(Integer code, String info) { + this.code = code; + this.info = info; + } + + public Integer getCode() { + return code; + } + + public String getInfo() { + return info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/GamePopularStatus.java b/ff-base/src/main/java/com/ff/base/enums/GamePopularStatus.java new file mode 100644 index 0000000..d5dd358 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/GamePopularStatus.java @@ -0,0 +1,29 @@ +package com.ff.base.enums; + +/** + * 游戏流行 + * + * @author shi + * @date 2024/10/29 + */ +public enum GamePopularStatus { + POPULAR(1, "热门"), + NOT_POPULAR(2, "非热门"); + + private final Integer code; + private final String info; + + GamePopularStatus(Integer code, String info) { + this.code = code; + this.info = info; + } + + public Integer getCode() { + return code; + } + + public String getInfo() { + return info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/GamePopularType.java b/ff-base/src/main/java/com/ff/base/enums/GamePopularType.java new file mode 100644 index 0000000..1e13b0f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/GamePopularType.java @@ -0,0 +1,29 @@ +package com.ff.base.enums; + +/** + * 游戏流行 + * + * @author shi + * @date 2024/10/29 + */ +public enum GamePopularType { + POPULAR_ONE(1, "热门一"), + POPULAR_TWO(2, "热门二"); + + private final Integer code; + private final String info; + + GamePopularType(Integer code, String info) { + this.code = code; + this.info = info; + } + + public Integer getCode() { + return code; + } + + public String getInfo() { + return info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/GameStatus.java b/ff-base/src/main/java/com/ff/base/enums/GameStatus.java new file mode 100644 index 0000000..299af7f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/GameStatus.java @@ -0,0 +1,30 @@ +package com.ff.base.enums; + +/** + * 游戏状态 + * + * @author shi + * @date 2024/10/23 + */ +public enum GameStatus { + WIN(1, "赢"), + FAIL(2, "输"), + FLAT(3, "平"); + + private final Integer code; + private final String info; + + GameStatus(Integer code, String info) { + this.code = code; + this.info = info; + } + + public Integer getCode() { + return code; + } + + public String getInfo() { + return info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/HttpMethod.java b/ff-base/src/main/java/com/ff/base/enums/HttpMethod.java new file mode 100644 index 0000000..edc94a9 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/HttpMethod.java @@ -0,0 +1,37 @@ +package com.ff.base.enums; + +import org.springframework.lang.Nullable; + +import java.util.HashMap; +import java.util.Map; + +/** + * 请求方式 + * + * @author ff + */ +public enum HttpMethod +{ + GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE; + + private static final Map mappings = new HashMap<>(16); + + static + { + for (HttpMethod httpMethod : values()) + { + mappings.put(httpMethod.name(), httpMethod); + } + } + + @Nullable + public static HttpMethod resolve(@Nullable String method) + { + return (method != null ? mappings.get(method) : null); + } + + public boolean matches(String method) + { + return (this == resolve(method)); + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/InitiatingType.java b/ff-base/src/main/java/com/ff/base/enums/InitiatingType.java new file mode 100644 index 0000000..47b98ef --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/InitiatingType.java @@ -0,0 +1,22 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 发起类型 + */ + +@Getter +public enum InitiatingType { + InitiatingType_1(1, "手动发起"), + InitiatingType_2(2, "定时任务"); + + private final Integer code; + private final String info; + + InitiatingType(Integer code, String info) + { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/JILIGameType.java b/ff-base/src/main/java/com/ff/base/enums/JILIGameType.java new file mode 100644 index 0000000..bf9270d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/JILIGameType.java @@ -0,0 +1,73 @@ +package com.ff.base.enums; + + +import java.util.Optional; +import java.util.stream.Stream; + +/** + * jili游戏类型 + * + * @author shi + * @date 2024/10/22 + */ +public enum JILIGameType { + + ELECTRON(1, 1L,"电子"), + CHESS(2, 2L,"棋牌"), + GAME_HALL(3, 0L,"游戏大厅"), + CATCH_FISH(5, 4L,"捕鱼"), + MACHINE(8, 2L,"棋牌") + + ; + + private final Integer code; + private final Long systemCode; + private final String info; + JILIGameType(Integer code,Long systemCode, String info) + { + this.code = code; + this.systemCode = systemCode; + this.info = info; + } + + public Integer getCode() + { + return code; + } + + public Long getSystemCode() + { + return systemCode; + } + public String getInfo() + { + return info; + } + /** + * 按代码查找系统 + * + * @param code 代码 + * @return {@link String } + */ + public static Long findSystemByCode(Integer code) { + Optional system = Stream.of(JILIGameType.values()) + .filter(gameType -> gameType.getCode().equals(code)) + .map(JILIGameType::getSystemCode) + .findFirst(); + return system.orElse(null); + } + + /** + * 按代码查找信息 + * + * @param code 代码 + * @return {@link String } + */ + public static String findInfoByCode(Integer code) { + Optional system = Stream.of(JILIGameType.values()) + .filter(gameType -> gameType.getCode().equals(code)) + .map(JILIGameType::getInfo) + .findFirst(); + return system.orElse(null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/LangType.java b/ff-base/src/main/java/com/ff/base/enums/LangType.java new file mode 100644 index 0000000..2115d83 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/LangType.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * lang类型 + * + * @author shi + * @date 2024/12/31 + */ +@Getter +public enum LangType { + APP(1, "app"), + BACKEND_SYSTEM(2, "后台管理系统"); + + private final int value; + private final String description; + + LangType(int value, String description) { + this.value = value; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/LayoutLoginType.java b/ff-base/src/main/java/com/ff/base/enums/LayoutLoginType.java new file mode 100644 index 0000000..b32774a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/LayoutLoginType.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 布局登录类型 + * + * @author shi + * @date 2025/01/20 + */ +@Getter +public enum LayoutLoginType { + BEFORE(1, "前"), + AFTER(2, "后"); + + private final Integer value; + private final String description; + + LayoutLoginType(Integer value, String description) { + this.value = value; + this.description = description; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/LimitType.java b/ff-base/src/main/java/com/ff/base/enums/LimitType.java new file mode 100644 index 0000000..857bcf6 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/LimitType.java @@ -0,0 +1,20 @@ +package com.ff.base.enums; + +/** + * 限流类型 + * + * @author ff + */ + +public enum LimitType +{ + /** + * 默认策略全局限流 + */ + DEFAULT, + + /** + * 根据请求者IP进行限流 + */ + IP +} diff --git a/ff-base/src/main/java/com/ff/base/enums/LinkPosition.java b/ff-base/src/main/java/com/ff/base/enums/LinkPosition.java new file mode 100644 index 0000000..4a0d94a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/LinkPosition.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 链接位置 + * + * @author shi + * @date 2025/01/11 + */ +@Getter +public enum LinkPosition { + HALL_PAGE(1, "直达大厅页链接"), + REGISTER_PAGE(2, "直达注册页链接"), + ACTIVITY_PAGE(3, "直达活动页链接"), + TRIAL_PAGE(4, "直达试玩页链接"), + DOWNLOAD_SITE(5, "直达下载站链接"), + GAME_TRIAL(0, "游戏试玩链接"); + + private final int value; + private final String description; + + LinkPosition(int value, String description) { + this.value = value; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/LoadStatus.java b/ff-base/src/main/java/com/ff/base/enums/LoadStatus.java new file mode 100644 index 0000000..6bd386c --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/LoadStatus.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + +import lombok.Getter; + + +/** + * 轮播图状态 + * + * @author shi + * @date 2024/11/25 + */ +@Getter +public enum LoadStatus { + PENDING_REVIEW(0, "待审核"), + PENDING_EFFECT(1, "待生效"), + ACTIVE(2, "生效中"), + EXPIRED(3, "已过期"), + CANCELLED(4, "已取消"); + private final Integer code; + private final String description; + + LoadStatus(Integer code, String description) { + this.code = code; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/LoopType.java b/ff-base/src/main/java/com/ff/base/enums/LoopType.java new file mode 100644 index 0000000..dba0e56 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/LoopType.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 循环方式 + */ +@Getter +public enum LoopType { + LoopType_1("1", "每日循环(0:00重置)"), + LoopType_2("2", "每周循环(周一0:00重置)"), + LoopType_3("3", "每月循环(每月1日00:00重置)"); + + private final String code; + private final String info; + + LoopType(String code, String info) + { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/MarqueeStatus.java b/ff-base/src/main/java/com/ff/base/enums/MarqueeStatus.java new file mode 100644 index 0000000..e12062f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/MarqueeStatus.java @@ -0,0 +1,25 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 字幕状态 + * + * @author shi + * @date 2024/11/21 + */ +@Getter +public enum MarqueeStatus { + PENDING_RELEASE(0, "待发布"), + PENDING_EFFECT(1, "待生效"), + ACTIVE(2, "生效中"), + EXPIRED(3, "已过期"), + CANCELLED(4, "已取消"); + private final Integer code; + private final String description; + + MarqueeStatus(Integer code, String description) { + this.code = code; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/MemberLogOperProject.java b/ff-base/src/main/java/com/ff/base/enums/MemberLogOperProject.java new file mode 100644 index 0000000..d3624b8 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/MemberLogOperProject.java @@ -0,0 +1,47 @@ +package com.ff.base.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 会员日志操作项目枚举 + * + * @author liukang + */ +@Getter +@AllArgsConstructor +public enum MemberLogOperProject { + + LOG_OPER_PROJECT_0("0", "姓名"), + LOG_OPER_PROJECT_1("1", "手机号"), + LOG_OPER_PROJECT_2("2", "账号状态"), + LOG_OPER_PROJECT_3("3", "银行卡"), + LOG_OPER_PROJECT_4("4", "账号密码"), + LOG_OPER_PROJECT_5("5", "忘记密码"), + LOG_OPER_PROJECT_6("6", "提现密码"), + LOG_OPER_PROJECT_7("7", "WhatsApp"), + LOG_OPER_PROJECT_8("8", "Facebook"), + LOG_OPER_PROJECT_9("9", "Telegram"), + LOG_OPER_PROJECT_10("10", "Zalo"), + LOG_OPER_PROJECT_11("11", "邮箱地址"), + LOG_OPER_PROJECT_12("12", "手势密码"), + LOG_OPER_PROJECT_13("13", "谷歌验证"), + LOG_OPER_PROJECT_14("14", "密保问题"), + LOG_OPER_PROJECT_15("15", "会员层级"), + LOG_OPER_PROJECT_16("16", "上级代理"), + LOG_OPER_PROJECT_17("17", "登录"), + LOG_OPER_PROJECT_18("18", "登出"), + LOG_OPER_PROJECT_19("19", "VIP等级"); + + + /** + * 编码 + */ + private String code; + + /** + * 描述 + */ + private String desc; + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/MemberLogOperType.java b/ff-base/src/main/java/com/ff/base/enums/MemberLogOperType.java new file mode 100644 index 0000000..a256292 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/MemberLogOperType.java @@ -0,0 +1,29 @@ +package com.ff.base.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 会员日志操作项目枚举 + * + * @author liukang + */ +@Getter +@AllArgsConstructor +public enum MemberLogOperType { + + LOG_OPER_TYPE_0("0", "无"), + LOG_OPER_TYPE_1("1", "新增"), + LOG_OPER_TYPE_2("2", "修改"); + + /** + * 编码 + */ + private String code; + + /** + * 描述 + */ + private String desc; + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/MemberStatus.java b/ff-base/src/main/java/com/ff/base/enums/MemberStatus.java new file mode 100644 index 0000000..b135e6f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/MemberStatus.java @@ -0,0 +1,53 @@ +package com.ff.base.enums; + +/** + * 会员状态 + * + * @author liukang + */ +public enum MemberStatus +{ + /** + * 账号状态(0正常 1手动冻结 2异常冻结 3禁止领取优惠 4禁止提现 5黑名单 6停用 7禁止进入游戏 8自我禁止-限制游戏 9自我禁止-限制参与优惠 10自我禁止-限制登录) + */ + MemberStatus_0("0", "正常"), + MemberStatus_1("1", "手动冻结"), + MemberStatus_2("2", "异常冻结"), + MemberStatus_3("3", "禁止领取优惠"), + MemberStatus_4("4", "禁止提现"), + MemberStatus_5("5", "黑名单"), + MemberStatus_6("6", "停用"), + MemberStatus_7("7", "禁止进入游戏"), + MemberStatus_8("8", "自我禁止-限制游戏"), + MemberStatus_9("9", "自我禁止-限制参与优惠"), + MemberStatus_10("10", "自我禁止-限制登录"); + + private final String code; + private final String info; + + MemberStatus(String code, String info) + { + this.code = code; + this.info = info; + } + + public static MemberStatus getMemberStatusTypeByCode(String code) + { + for (MemberStatus item : MemberStatus.values()) { + if(item.getCode().equals(code)) { + return item; + } + } + return null; + } + + public String getCode() + { + return code; + } + + public String getInfo() + { + return info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/NoticeStatus.java b/ff-base/src/main/java/com/ff/base/enums/NoticeStatus.java new file mode 100644 index 0000000..cfcaf2a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/NoticeStatus.java @@ -0,0 +1,25 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 通知状态 + * + * @author shi + * @date 2024/11/20 + */ +@Getter +public enum NoticeStatus { + PENDING_REVIEW(0, "待审核"), + PENDING_SEND(1, "待发送"), + SENT(2, "已发送"), + REVOKED(3, "撤回"); + + private final Integer code; + private final String description; + + NoticeStatus(Integer code, String description) { + this.code = code; + this.description = description; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/NoticeType.java b/ff-base/src/main/java/com/ff/base/enums/NoticeType.java new file mode 100644 index 0000000..223caac --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/NoticeType.java @@ -0,0 +1,28 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 通知类型 + * + * @author shi + * @date 2024/11/21 + */ +@Getter +public enum NoticeType { + MESSAGE(1, "消息通知"), + MARQUEE(2, "跑马灯通知"), + NOTICE(3, "公告通知"), + BANNER(4, "banner图"), + LOAD(5, "加载页"), + FRAME(6, "大厅弹框") + ; + + private final Integer code; + private final String description; + + NoticeType(Integer code, String description) { + this.code = code; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/OperationType.java b/ff-base/src/main/java/com/ff/base/enums/OperationType.java new file mode 100644 index 0000000..ef2eec9 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/OperationType.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 操作类型 + * + * @author shi + * @date 2024/11/30 + */ +@Getter +public enum OperationType { + TENANT_BALANCE(1, "用户游玩操作租户余额"); + + private final Integer code; + private final String description; + + OperationType(Integer code, String description) { + this.code = code; + this.description = description; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/OperatorType.java b/ff-base/src/main/java/com/ff/base/enums/OperatorType.java new file mode 100644 index 0000000..0201fab --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/OperatorType.java @@ -0,0 +1,24 @@ +package com.ff.base.enums; + +/** + * 操作人类别 + * + * @author ff + */ +public enum OperatorType +{ + /** + * 其它 + */ + OTHER, + + /** + * 后台用户 + */ + MANAGE, + + /** + * 手机端用户 + */ + MOBILE +} diff --git a/ff-base/src/main/java/com/ff/base/enums/PageType.java b/ff-base/src/main/java/com/ff/base/enums/PageType.java new file mode 100644 index 0000000..3f52d31 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/PageType.java @@ -0,0 +1,37 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +@Getter +public enum PageType { + H5_IOS("H5-iOS", "H5"), + APP_ANDROID("APP-Android", "APP"), + APP_IOS("APP-iOS", "APP"), + PC_WINDOWS("PC-Windows", "APP"), + PC_MAC("PC-Mac", "APP"), + H5_ANDROID("H5-Android", "H5"); + ; + + private final String value; + private final String type; + + PageType(String value, String type) { + this.value = value; + this.type = type; + } + + /** + * 根据 value 查找对应的 type + * @param value 要查找的值 + * @return 对应的 type,如果未找到返回 null + */ + public static String getTypeByValue(String value) { + for (PageType pageType : PageType.values()) { + if (pageType.getValue().equals(value)) { + return pageType.getType(); + } + } + return null; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/PatternSourceType.java b/ff-base/src/main/java/com/ff/base/enums/PatternSourceType.java new file mode 100644 index 0000000..a5175aa --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/PatternSourceType.java @@ -0,0 +1,25 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 来源模式类型 + * + * @author shang + */ +@Getter +public enum PatternSourceType { + + PatternSourceType_1("1", "系统自带"), + PatternSourceType_2("2", "自定义"); + + private final String code; + private final String info; + + PatternSourceType(String code, String info) + { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/PlayType.java b/ff-base/src/main/java/com/ff/base/enums/PlayType.java new file mode 100644 index 0000000..877cdb5 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/PlayType.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 游戏类型 + * + * @author shi + * @date 2024/11/20 + */ +@Getter +public enum PlayType { + BY_LANGUAGE(1, "按语种播放"), + BY_CURRENCY(2, "按币种播放"); + + private final Integer code; + private final String description; + + PlayType(Integer code, String description) { + this.code = code; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/ReadStatus.java b/ff-base/src/main/java/com/ff/base/enums/ReadStatus.java new file mode 100644 index 0000000..11fd073 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ReadStatus.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 读取状态 + * + * @author shi + * @date 2024/11/21 + */ +@Getter +public enum ReadStatus { + READ(1, "已阅"), + DELETED(2, "已删除"); + + private final Integer code; + private final String description; + + ReadStatus(Integer code, String description) { + this.code = code; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/RealtimeRebateReceiveType.java b/ff-base/src/main/java/com/ff/base/enums/RealtimeRebateReceiveType.java new file mode 100644 index 0000000..7852e2e --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/RealtimeRebateReceiveType.java @@ -0,0 +1,21 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 实时返水领取时间类型 + */ +@Getter +public enum RealtimeRebateReceiveType { + RealtimeRebateReceiveType_1("1", "实时领取(影响留存)"), + RealtimeRebateReceiveType_2("2", "次日"); + + private final String code; + private final String info; + + RealtimeRebateReceiveType(String code, String info){ + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/RealtimeRebateSettleType.java b/ff-base/src/main/java/com/ff/base/enums/RealtimeRebateSettleType.java new file mode 100644 index 0000000..12776ac --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/RealtimeRebateSettleType.java @@ -0,0 +1,24 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 实时返水结算派发 + * + * @author shang + */ +@Getter +public enum RealtimeRebateSettleType { + RealtimeRebateSettleType_1("1", "玩家自领-过期自动派发"), + RealtimeRebateSettleType_2("2", "玩家自领-过期作废"), + RealtimeRebateSettleType_3("3", "自动派发"); + + private final String code; + private final String info; + + RealtimeRebateSettleType(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/RebateSettlePeriodType.java b/ff-base/src/main/java/com/ff/base/enums/RebateSettlePeriodType.java new file mode 100644 index 0000000..88a47d6 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/RebateSettlePeriodType.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 返水设置结算周期类型 + * + * @author shang + */ +@Getter +public enum RebateSettlePeriodType { + RebateSettlePeriodType_1("1", "不强制(可无限累计)"), + RebateSettlePeriodType_2("2", "每日某个时间点,强制结算"), + RebateSettlePeriodType_3("3", "每周几某个时间点,强制结算"), + RebateSettlePeriodType_4("4", "每月几号某个时间点,强制结算"); + + private final String code; + private final String info; + + RebateSettlePeriodType(String code, String info) { + this.code = code; + this.info = info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ReceiptType.java b/ff-base/src/main/java/com/ff/base/enums/ReceiptType.java new file mode 100644 index 0000000..e0a7493 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ReceiptType.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 收据类型 + * + * @author shi + * @date 2024/11/20 + */ +@Getter +public enum ReceiptType { + ALL_MEMBERS(1, "全部会员"), + CUSTOM_MEMBERS(2, "自定义会员"), + MEMBER_LEVEL(3, "会员层级"), + MEMBER_VIP(4, "会员VIP"); + + private final Integer code; + private final String description; + + ReceiptType(Integer code, String description) { + this.code = code; + this.description = description; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ReceiveLimitType.java b/ff-base/src/main/java/com/ff/base/enums/ReceiveLimitType.java new file mode 100644 index 0000000..6d3b8ed --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ReceiveLimitType.java @@ -0,0 +1,36 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 领取限制类型 + * + * @author shang + * @date 2024/12/25 + */ +@Getter +public enum ReceiveLimitType { + ReceiveLimitType_10("10", "完成短信验证才能领取"), + ReceiveLimitType_11("11", "完成邮箱验证才能领取"), + ReceiveLimitType_12("12", "完成银行卡绑定才能领取"), + ReceiveLimitType_13("13", "绑定虚拟货币才能领取"), + ReceiveLimitType_14("14", "绑定三方钱包才能领取"), + ReceiveLimitType_15("15", "绑定收款方式才能领取"), + ReceiveLimitType_16("16", "填写真实姓名才能领取"), + ReceiveLimitType_17("17", "同姓名只能领取1次"), + ReceiveLimitType_18("18", "完成首充才能领取"), + ReceiveLimitType_19("19", "仅注册设备号领取"), + ReceiveLimitType_20("20", "同登录IP只能领取1次"), + ReceiveLimitType_1001("1001", "同浏览器指纹只能领取1次"), + ReceiveLimitType_1002("1002", "同登录设备号只能领取1次"); + + private final String code; + private final String info; + + ReceiveLimitType(String code, String info) { + this.code = code; + this.info = info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/ReceiveTimeType.java b/ff-base/src/main/java/com/ff/base/enums/ReceiveTimeType.java new file mode 100644 index 0000000..889226b --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/ReceiveTimeType.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 领取时间类型 + */ +@Getter +public enum ReceiveTimeType { + ReceiveTimeType_0(0, "次日"), + ReceiveTimeType_1(1, "下周"), + ReceiveTimeType_2(2, "当日实时(影响留存)"), + ReceiveTimeType_3(3, "每周"), + ReceiveTimeType_4(4, "下月"), + ReceiveTimeType_5(5, "每月"); + + private final Integer code; + private final String info; + + ReceiveTimeType(Integer code, String info) + { + this.code = code; + this.info = info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/RegisteWay.java b/ff-base/src/main/java/com/ff/base/enums/RegisteWay.java new file mode 100644 index 0000000..1df243e --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/RegisteWay.java @@ -0,0 +1,25 @@ +package com.ff.base.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 注册方式 + * + * @author liukang + */ +@Getter +@AllArgsConstructor +public enum RegisteWay { + + ACCOUNT("1", "账号注册"), + FACEBOOK("2", "FaceBook注册"), + PlATFORM("3", "后台添加"), + AGENT("4", "代理开户"), + EXTENSION("5","推广注册"); + + private String code; + + private String info; + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/RepairStatus.java b/ff-base/src/main/java/com/ff/base/enums/RepairStatus.java new file mode 100644 index 0000000..e0a3cbb --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/RepairStatus.java @@ -0,0 +1,33 @@ +package com.ff.base.enums; + +/** + * 补单审核状态 + * + * @author liukang + */ +public enum RepairStatus +{ + + RepairStatus_0("0", "待审核"), + RepairStatus_1("1", "审核通过"), + RepairStatus_2("2", "审核拒绝"); + + private final String code; + private final String info; + + RepairStatus(String code, String info) + { + this.code = code; + this.info = info; + } + + public String getCode() + { + return code; + } + + public String getInfo() + { + return info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/SetType.java b/ff-base/src/main/java/com/ff/base/enums/SetType.java new file mode 100644 index 0000000..e2b3094 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/SetType.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 返水设定类型 + * + * @author shang + * @date 2024/11/21 + */ + +@Getter +public enum SetType { + SetType_1(1, "按有效投注"), + SetType_2(2, "按VIP等级"); + + private final Integer code; + private final String info; + + SetType(Integer code, String info) + { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/SettleDurationType.java b/ff-base/src/main/java/com/ff/base/enums/SettleDurationType.java new file mode 100644 index 0000000..bfcb957 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/SettleDurationType.java @@ -0,0 +1,36 @@ +package com.ff.base.enums; + + +import com.ff.base.exception.base.BaseException; +import com.ff.base.utils.MessageUtils; +import lombok.Getter; + +/** + * 结算周期类型 + * + * @author shang + */ +@Getter +public enum SettleDurationType { + SettleDurationType_1("1", "日结"), + SettleDurationType_2("2", "周结"), + SettleDurationType_3("3", "月结"); + + private final String code; + private final String info; + + SettleDurationType(String code, String info) { + this.code = code; + this.info = info; + } + + public static SettleDurationType getSettleDurationTypeByCode(String code) + { + for (SettleDurationType item : SettleDurationType.values()) { + if(item.getCode().equals(code)) { + return item; + } + } + throw new BaseException(MessageUtils.message("agent.settleduration.enum.not.exists")); + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/SettleStatus.java b/ff-base/src/main/java/com/ff/base/enums/SettleStatus.java new file mode 100644 index 0000000..7c8867d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/SettleStatus.java @@ -0,0 +1,24 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 结算状态类型 + * + * @author shang + */ +@Getter +public enum SettleStatus { + SettleStatus_0(0, "未提现"), + SettleStatus_1(1, "已提现"); + + private final Integer code; + private final String info; + + SettleStatus(Integer code, String info) + { + this.code = code; + this.info = info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/SonType.java b/ff-base/src/main/java/com/ff/base/enums/SonType.java new file mode 100644 index 0000000..92963f5 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/SonType.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 儿子类型 + * + * @author shi + * @date 2025/01/15 + */ +@Getter +public enum SonType { + APL_PROTECTION(-1L, "apl防封域名"), + DOMAIN_PROTECTION(-2L, "域名防封"); + + private final Long value; + private final String description; + + SonType(Long value, String description) { + this.value = value; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/StopStatus.java b/ff-base/src/main/java/com/ff/base/enums/StopStatus.java new file mode 100644 index 0000000..9f7159f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/StopStatus.java @@ -0,0 +1,25 @@ +package com.ff.base.enums; + +import lombok.Getter; + + +/** + * 停止状态 + * + * @author shi + * @date 2024/11/28 + */ +@Getter +public enum StopStatus { + OPEN(1, "开启"), + CLOSED(2, "关闭"); + + private final Integer code; + private final String description; + + StopStatus(Integer code, String description) { + this.code = code; + this.description = description; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/SupplierCode.java b/ff-base/src/main/java/com/ff/base/enums/SupplierCode.java new file mode 100644 index 0000000..78d214a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/SupplierCode.java @@ -0,0 +1,36 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 供应商代码 + * + * @author shi + * @date 2025/01/18 + */ +@Getter +public enum SupplierCode { + AZURE("Az", "Azure"), + ALI_CLOUD_CN("ALY-CN", "大陆阿里云"), + WANGSU("WS", "wangsu"), + ALI_YUN("AliYun", "阿里云"), + WANGSU_IP("WSIP", "wangsu独立Ip"), + APEIR8("A8", "Apeir8"), + CLOUDFRONT("AWS", "CloundFront"), + SUPEREDGE("SE", "SuperEdge"), + CLOUDFLARE("CF", "cloudFlare"), + YUNDUN("YD", "yundun"), + FUNNULL("FN", "funnull"), + HUAWEI_CLOUD("HWCloud", "华为云"), + TENCENT_CLOUD("TCCloud", "腾讯云"), + GOOGLE("GC", "Google"), + OPEN_SOURCE_RETURN("OSR", "开放回源"); + + private final String value; + private final String description; + + SupplierCode(String value, String description) { + this.value = value; + this.description = description; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/SysUseType.java b/ff-base/src/main/java/com/ff/base/enums/SysUseType.java new file mode 100644 index 0000000..bdec53d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/SysUseType.java @@ -0,0 +1,21 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 系统使用类型 + */ +@Getter +public enum SysUseType { + SysUseType_1(1, "仅系统后台使用"), + SysUseType_2(2, "仅推广使用"); + + private final Integer code; + private final String info; + + SysUseType(Integer code, String info) + { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/TaskBindType.java b/ff-base/src/main/java/com/ff/base/enums/TaskBindType.java new file mode 100644 index 0000000..c3a288f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/TaskBindType.java @@ -0,0 +1,49 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 任务绑定类型 + * + * @author shang + */ +@Getter +public enum TaskBindType { + TaskBindType_0(0, "注册账号"), + TaskBindType_1(1, "首次绑定银行卡"), + TaskBindType_2(2, "设置生日"), + TaskBindType_3(3, "设置取款密码"), + TaskBindType_4(4, "设置密保"), + TaskBindType_5(5, "利息宝首存"), + TaskBindType_6(6, "设置头像"), + TaskBindType_7(7, "短信验证"), + TaskBindType_8(8, "设置Google验证器"), + TaskBindType_9(9, "注册首存"), + TaskBindType_10(10, "首次下载安装并登录APP"), + TaskBindType_11(11, "邮箱验证"), + TaskBindType_12(12, "保存桌面快捷方式"), + TaskBindType_13(13, "首次绑定数字货币"), + TaskBindType_14(14, "添加提现账户"), + TaskBindType_15(15, "首次提现"), + TaskBindType_16(16, "设置任意联系方式"); + + + private final Integer type; + private final String info; + + TaskBindType(Integer type, String info) + { + this.type = type; + this.info = info; + } + + public static TaskBindType getTaskBindTypeByType(Integer type) + { + for (TaskBindType item : TaskBindType.values()) { + if(item.getType().equals(type)) { + return item; + } + } + return null; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/TaskGiveType.java b/ff-base/src/main/java/com/ff/base/enums/TaskGiveType.java new file mode 100644 index 0000000..03c0aa1 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/TaskGiveType.java @@ -0,0 +1,21 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 任务领取方式 + */ +@Getter +public enum TaskGiveType { + TaskGiveType_1(1, "手动领取"), + TaskGiveType_2(2, "自动派发"); + + private final Integer code; + private final String info; + + TaskGiveType(Integer code, String info) + { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/TaskType.java b/ff-base/src/main/java/com/ff/base/enums/TaskType.java new file mode 100644 index 0000000..a7aedc3 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/TaskType.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 活动中心任务类型 + * + * @author shang + */ +@Getter +public enum TaskType { + + TaskType_1(1, "新人福利"), + TaskType_2(2, "每日任务"), + TaskType_3(3, "每周任务"), + TaskType_4(4, "神秘任务"), + TaskType_5(5, "活跃度宝箱"); + + private final Integer code; + private final String info; + + TaskType(Integer code, String info) + { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/TimePeriodType.java b/ff-base/src/main/java/com/ff/base/enums/TimePeriodType.java new file mode 100644 index 0000000..82138d9 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/TimePeriodType.java @@ -0,0 +1,42 @@ +package com.ff.base.enums; + + +import com.ff.base.exception.base.BaseException; +import com.ff.base.utils.MessageUtils; +import lombok.Getter; + +/** + * 时间周期类型 + * + * @author shang + */ +@Getter +public enum TimePeriodType { + TimePeriodType_1(1, "今日"), + TimePeriodType_2(2, "昨日"), + TimePeriodType_3(3, "本周"), + TimePeriodType_4(4, "上周"), + TimePeriodType_5(5, "本月"), + TimePeriodType_6(6, "上月"), + TimePeriodType_7(7, "全部"), + TimePeriodType_8(8, "自定义"); + + private final Integer code; + private final String info; + + TimePeriodType(Integer code, String info) + { + this.code = code; + this.info = info; + } + + public static TimePeriodType getTimePeriodTypeByCode(Integer code) + { + for (TimePeriodType item : TimePeriodType.values()) { + if(item.getCode().equals(code)) { + return item; + } + } + throw new BaseException(MessageUtils.message("agent.timeperiodtype.enum.not.exists")); + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/TimeType.java b/ff-base/src/main/java/com/ff/base/enums/TimeType.java new file mode 100644 index 0000000..677820d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/TimeType.java @@ -0,0 +1,26 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 时间类型 + * + * @author shang + */ +@Getter +public enum TimeType { + TimeType_1(1, "注册时间"), + TimeType_2(2, "最后登录时间"), + TimeType_3(3, "首充时间"), + TimeType_4(4, "创建时间"), + TimeType_5(5, "过期时间"); + + private final Integer code; + private final String info; + + TimeType(Integer code, String info) + { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/Tourist.java b/ff-base/src/main/java/com/ff/base/enums/Tourist.java new file mode 100644 index 0000000..1457f9f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/Tourist.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 旅行者 + * + * @author shi + * @date 2024/11/21 + */ +@Getter +public enum Tourist { + GUEST(1, "登录前游客"), + MEMBER(2, "登录后会员"); + + private final Integer code; + private final String description; + + Tourist(Integer code, String description) { + this.code = code; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/TrackEventType.java b/ff-base/src/main/java/com/ff/base/enums/TrackEventType.java new file mode 100644 index 0000000..3e474be --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/TrackEventType.java @@ -0,0 +1,41 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 跟踪事件类型 + * + * @author shi + * @date 2025/01/14 + */ +@Getter +public enum TrackEventType { + HALL_ACCESS("1", "大厅访问"), + DOWNLOAD_SITE_ACCESS("2", "下载站访问"), + FAST_APP_DOWNLOAD("3", "极速app下载"), + NATIVE_APP_DOWNLOAD("4", "原生app下载"), + PWA_DOWNLOAD("5", "PWA下载"), + IOS_DESCRIPTION_SIGN_DOWNLOAD("6", "ios描述签下载"), + DESKTOP_SHORTCUT_DOWNLOAD("7", "桌面快捷方式下载"), + APP_UPDATE_SUCCESS_COUNT("8", "app更新成功量"), + APP_UPDATE_REQUEST_COUNT("9", "app更新请求量"), + ENTER_GAME("10", "进入游戏"), + CLICK_RECHARGE_BUTTON("11", "点击充值按钮"), + NEW_MEMBER("12", "新增会员(后端记录)"), + NEW_AGENT("13", "新增代理(后端记录)"), + NEW_TOP_AGENT("14", "新增顶级代理(后端记录)"), + FIRST_RECHARGE("15", "首充(后端记录)"), + SAME_DAY_REGISTER_AND_FIRST_RECHARGE("16", "当天注册且首充(后端记录)"), + SECOND_RECHARGE("17", "二充(后端记录)"), + RECHARGE_SUCCESS("18", "充值成功(后端记录)"), + WITHDRAWAL_SUCCESS("19", "提现成功(后端记录)"), + GAME_BETTING_PARTICIPATION("20", "参与游戏投注(后端记录)"); + + private final String value; + private final String description; + + TrackEventType(String value, String description) { + this.value = value; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/TransferType.java b/ff-base/src/main/java/com/ff/base/enums/TransferType.java new file mode 100644 index 0000000..ccbd915 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/TransferType.java @@ -0,0 +1,30 @@ +package com.ff.base.enums; + + +/** + * 传输类型 + * + * @author shi + * @date 2024/10/29 + */ +public enum TransferType { + ALL(1, "从游戏商转移额度到平台商(不看amount值,全部转出"), + GAMES(2, "从平台商转移额度到游戏商"), + SYSTEM(3, "从游戏商转移额度到平台商 无用"); + private final Integer code; + private final String info; + + TransferType(Integer code, String info) { + this.code = code; + this.info = info; + } + + public Integer getCode() { + return code; + } + + public String getInfo() { + return info; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/enums/UsageStatus.java b/ff-base/src/main/java/com/ff/base/enums/UsageStatus.java new file mode 100644 index 0000000..68ce8dc --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/UsageStatus.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 使用状态 + * + * @author shi + * @date 2025/01/11 + */ +@Getter +public enum UsageStatus { + ENABLED_SUCCESS(1, "启用成功"), + DISABLED(2, "停用"); + + private final Integer value; + private final String description; + + UsageStatus(Integer value, String description) { + this.value = value; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/UserStatus.java b/ff-base/src/main/java/com/ff/base/enums/UserStatus.java new file mode 100644 index 0000000..f7fdc19 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/UserStatus.java @@ -0,0 +1,30 @@ +package com.ff.base.enums; + +/** + * 用户状态 + * + * @author ff + */ +public enum UserStatus +{ + OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除"); + + private final String code; + private final String info; + + UserStatus(String code, String info) + { + this.code = code; + this.info = info; + } + + public String getCode() + { + return code; + } + + public String getInfo() + { + return info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/WindowStatus.java b/ff-base/src/main/java/com/ff/base/enums/WindowStatus.java new file mode 100644 index 0000000..a45a5cf --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/WindowStatus.java @@ -0,0 +1,23 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 窗口状态 + * + * @author shi + * @date 2024/11/21 + */ +@Getter +public enum WindowStatus { + OPEN(true, "弹窗开启"), + CLOSED(false, "弹窗关闭"); + + private final Boolean status; + private final String description; + + WindowStatus(Boolean status, String description) { + this.status = status; + this.description = description; + } +} \ No newline at end of file diff --git a/ff-base/src/main/java/com/ff/base/enums/WindowType.java b/ff-base/src/main/java/com/ff/base/enums/WindowType.java new file mode 100644 index 0000000..4fb1fcc --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/WindowType.java @@ -0,0 +1,25 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 窗户类型 + * + * @author shi + * @date 2024/11/21 + */ +@Getter +public enum WindowType { + EVERY_LOGIN(1L, "每次登录"), + DAILY_ONCE(2L, "每日一次"), + EVERY_LOBBY_ENTRY(3L, "每回大厅必弹(少用)"), + ONCE_ONLY(4L, "只弹一次"); + + private final Long code; + private final String description; + + WindowType(Long code, String description) { + this.code = code; + this.description = description; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/WithdrawAccountStatus.java b/ff-base/src/main/java/com/ff/base/enums/WithdrawAccountStatus.java new file mode 100644 index 0000000..51d9bff --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/WithdrawAccountStatus.java @@ -0,0 +1,25 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 会员提现状态类型 + * + * @author shang + * @date 2024/12/25 + */ +@Getter +public enum WithdrawAccountStatus { + ENABLED("0", "启用"), + DISABLED("1", "停用"), + DELETED("2", "删除"); + + private final String code; + private final String info; + + WithdrawAccountStatus(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/WithdrawBehalfStatus.java b/ff-base/src/main/java/com/ff/base/enums/WithdrawBehalfStatus.java new file mode 100644 index 0000000..46d07af --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/WithdrawBehalfStatus.java @@ -0,0 +1,27 @@ +package com.ff.base.enums; + +import lombok.Getter; + +/** + * 提现代付记录状态 + * + * @author liukang + */ +@Getter +public enum WithdrawBehalfStatus { + + /** + * 状态 0.已付款 1.付款失败 2.已强制出款 3.付款中 + */ + BEHALFSTATUS_0("0", "已付款"), + BEHALFSTATUS_1("1", "付款失败"), + BEHALFSTATUS_2("2", "已强制出款"), + BEHALFSTATUS_3("3", "付款中"); + private final String code; + private final String info; + + WithdrawBehalfStatus(String code, String info) { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/WithdrawStatus.java b/ff-base/src/main/java/com/ff/base/enums/WithdrawStatus.java new file mode 100644 index 0000000..1f2c9d6 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/WithdrawStatus.java @@ -0,0 +1,49 @@ +package com.ff.base.enums; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Optional; +import java.util.stream.Stream; + +/** + * 提现状态 + * + * @author liukang + * @date 2024/11/22 + */ +@Getter +@AllArgsConstructor +public enum WithdrawStatus { + + /** + * 1.待出款(未锁定) 2.待出款(已锁定) 3.待三方付款 4.付款失败 5.已拒绝 6.已取消 7.已付款 8.已强制出款 + */ + STATUS_1(1, 1, "待出款(未锁定)"), + STATUS_2(2, 2, "待出款(已锁定)"), + STATUS_3(3, 3, "待三方付款"), + STATUS_4(4, 4, "付款失败"), + STATUS_5(5, 5, "已拒绝"), + STATUS_6(6, 6, "已取消"), + STATUS_7(7, 7, "已付款"), + STATUS_8(8, 8, "已强制出款"); + + private final Integer status; + private final Integer code; + private final String info; + + /** + * 按code查找状态 + * + * @param code 代码 + * @return {@link String } + */ + public static Integer findStatusByCode(Integer code) { + Optional system = Stream.of(WithdrawStatus.values()) + .filter(fyPayStatus -> fyPayStatus.getCode().equals(code)) + .map(WithdrawStatus::getStatus) + .findFirst(); + return system.orElse(null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/WithdrawTipStatus.java b/ff-base/src/main/java/com/ff/base/enums/WithdrawTipStatus.java new file mode 100644 index 0000000..5ecd7a5 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/WithdrawTipStatus.java @@ -0,0 +1,24 @@ +package com.ff.base.enums; + + +import lombok.Getter; + +/** + * 出款上限提示状态 + * + * @author shang + */ +@Getter +public enum WithdrawTipStatus { + WithdrawTipStatus_0(0, "关闭"), + WithdrawTipStatus_1(1, "开启"); + + private final Integer code; + private final String info; + + WithdrawTipStatus(Integer code, String info) + { + this.code = code; + this.info = info; + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/XKGameType.java b/ff-base/src/main/java/com/ff/base/enums/XKGameType.java new file mode 100644 index 0000000..4003f67 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/XKGameType.java @@ -0,0 +1,74 @@ +package com.ff.base.enums; + + +import java.util.Optional; +import java.util.stream.Stream; + + +/** + * xkgame类型 + * + * @author shi + * @date 2024/11/13 + */ +public enum XKGameType { + + ELECTRON(1, 1L,"电子"), + CHESS(2, 2L,"棋牌"), + GAME_HALL(3, 0L,"游戏大厅"), + CATCH_FISH(5, 4L,"捕鱼"), + MACHINE(8, 2L,"棋牌") + + ; + + private final Integer code; + private final Long systemCode; + private final String info; + XKGameType(Integer code, Long systemCode, String info) + { + this.code = code; + this.systemCode = systemCode; + this.info = info; + } + + public Integer getCode() + { + return code; + } + + public Long getSystemCode() + { + return systemCode; + } + public String getInfo() + { + return info; + } + /** + * 按代码查找系统 + * + * @param code 代码 + * @return {@link String } + */ + public static Long findSystemByCode(Integer code) { + Optional system = Stream.of(XKGameType.values()) + .filter(gameType -> gameType.getCode().equals(code)) + .map(XKGameType::getSystemCode) + .findFirst(); + return system.orElse(null); + } + + /** + * 按代码查找信息 + * + * @param code 代码 + * @return {@link String } + */ + public static String findInfoByCode(Integer code) { + Optional system = Stream.of(XKGameType.values()) + .filter(gameType -> gameType.getCode().equals(code)) + .map(XKGameType::getInfo) + .findFirst(); + return system.orElse(null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/enums/XjPayStatus.java b/ff-base/src/main/java/com/ff/base/enums/XjPayStatus.java new file mode 100644 index 0000000..247dda8 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/enums/XjPayStatus.java @@ -0,0 +1,41 @@ +package com.ff.base.enums; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Optional; +import java.util.stream.Stream; + +/** + * xjpay支付状态 + * + * @author liukang + * @date 2024/10/22 + */ +@Getter +@AllArgsConstructor +public enum XjPayStatus { + + PROCESSING(0, 0, "待支付"), + SUCCESS(1, 1, "支付成功"), + FAIL(2, 2, "支付失败"); + + private final Integer status; + private final Integer code; + private final String info; + + /** + * 按code查找状态 + * + * @param code 代码 + * @return {@link String } + */ + public static Integer findStatusByCode(Integer code) { + Optional system = Stream.of(XjPayStatus.values()) + .filter(fyPayStatus -> fyPayStatus.getCode().equals(code)) + .map(XjPayStatus::getStatus) + .findFirst(); + return system.orElse(null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/DemoModeException.java b/ff-base/src/main/java/com/ff/base/exception/DemoModeException.java new file mode 100644 index 0000000..813694c --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/DemoModeException.java @@ -0,0 +1,15 @@ +package com.ff.base.exception; + +/** + * 演示模式异常 + * + * @author ff + */ +public class DemoModeException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public DemoModeException() + { + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/GlobalException.java b/ff-base/src/main/java/com/ff/base/exception/GlobalException.java new file mode 100644 index 0000000..d956eb7 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/GlobalException.java @@ -0,0 +1,58 @@ +package com.ff.base.exception; + +/** + * 全局异常 + * + * @author ff + */ +public class GlobalException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + * 和 {@link CommonResult#getDetailMessage()} 一致的设计 + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public GlobalException() + { + } + + public GlobalException(String message) + { + this.message = message; + } + + public String getDetailMessage() + { + return detailMessage; + } + + public GlobalException setDetailMessage(String detailMessage) + { + this.detailMessage = detailMessage; + return this; + } + + @Override + public String getMessage() + { + return message; + } + + public GlobalException setMessage(String message) + { + this.message = message; + return this; + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/ServiceException.java b/ff-base/src/main/java/com/ff/base/exception/ServiceException.java new file mode 100644 index 0000000..c1adf3b --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/ServiceException.java @@ -0,0 +1,74 @@ +package com.ff.base.exception; + +/** + * 业务异常 + * + * @author ff + */ +public final class ServiceException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误码 + */ + private Integer code; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + * 和 {@link CommonResult#getDetailMessage()} 一致的设计 + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public ServiceException() + { + } + + public ServiceException(String message) + { + this.message = message; + } + + public ServiceException(String message, Integer code) + { + this.message = message; + this.code = code; + } + + public String getDetailMessage() + { + return detailMessage; + } + + @Override + public String getMessage() + { + return message; + } + + public Integer getCode() + { + return code; + } + + public ServiceException setMessage(String message) + { + this.message = message; + return this; + } + + public ServiceException setDetailMessage(String detailMessage) + { + this.detailMessage = detailMessage; + return this; + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/UtilException.java b/ff-base/src/main/java/com/ff/base/exception/UtilException.java new file mode 100644 index 0000000..51eb985 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/UtilException.java @@ -0,0 +1,26 @@ +package com.ff.base.exception; + +/** + * 工具类异常 + * + * @author ff + */ +public class UtilException extends RuntimeException +{ + private static final long serialVersionUID = 8247610319171014183L; + + public UtilException(Throwable e) + { + super(e.getMessage(), e); + } + + public UtilException(String message) + { + super(message); + } + + public UtilException(String message, Throwable throwable) + { + super(message, throwable); + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/base/BaseException.java b/ff-base/src/main/java/com/ff/base/exception/base/BaseException.java new file mode 100644 index 0000000..5b0cd74 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/base/BaseException.java @@ -0,0 +1,97 @@ +package com.ff.base.exception.base; + +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.StringUtils; + +/** + * 基础异常 + * + * @author ff + */ +public class BaseException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 所属模块 + */ + private String module; + + /** + * 错误码 + */ + private String code; + + /** + * 错误码对应的参数 + */ + private Object[] args; + + /** + * 错误消息 + */ + private String defaultMessage; + + public BaseException(String module, String code, Object[] args, String defaultMessage) + { + this.module = module; + this.code = code; + this.args = args; + this.defaultMessage = defaultMessage; + } + + public BaseException(String module, String code, Object[] args) + { + this(module, code, args, null); + } + + public BaseException(String module, String defaultMessage) + { + this(module, null, null, defaultMessage); + } + + public BaseException(String code, Object[] args) + { + this(null, code, args, null); + } + + public BaseException(String defaultMessage) + { + this(null, null, null, defaultMessage); + } + + @Override + public String getMessage() + { + String message = null; + if (!StringUtils.isEmpty(code)) + { + message = MessageUtils.message(code, args); + } + if (message == null) + { + message = defaultMessage; + } + return message; + } + + public String getModule() + { + return module; + } + + public String getCode() + { + return code; + } + + public Object[] getArgs() + { + return args; + } + + public String getDefaultMessage() + { + return defaultMessage; + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/file/FileException.java b/ff-base/src/main/java/com/ff/base/exception/file/FileException.java new file mode 100644 index 0000000..95bddb4 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/file/FileException.java @@ -0,0 +1,19 @@ +package com.ff.base.exception.file; + +import com.ff.base.exception.base.BaseException; + +/** + * 文件信息异常类 + * + * @author ff + */ +public class FileException extends BaseException +{ + private static final long serialVersionUID = 1L; + + public FileException(String code, Object[] args) + { + super("file", code, args, null); + } + +} diff --git a/ff-base/src/main/java/com/ff/base/exception/file/FileNameLengthLimitExceededException.java b/ff-base/src/main/java/com/ff/base/exception/file/FileNameLengthLimitExceededException.java new file mode 100644 index 0000000..a9920ac --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/file/FileNameLengthLimitExceededException.java @@ -0,0 +1,16 @@ +package com.ff.base.exception.file; + +/** + * 文件名称超长限制异常类 + * + * @author ff + */ +public class FileNameLengthLimitExceededException extends FileException +{ + private static final long serialVersionUID = 1L; + + public FileNameLengthLimitExceededException(int defaultFileNameLength) + { + super("upload.filename.exceed.length", new Object[] { defaultFileNameLength }); + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/file/FileSizeLimitExceededException.java b/ff-base/src/main/java/com/ff/base/exception/file/FileSizeLimitExceededException.java new file mode 100644 index 0000000..0b2747e --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/file/FileSizeLimitExceededException.java @@ -0,0 +1,16 @@ +package com.ff.base.exception.file; + +/** + * 文件名大小限制异常类 + * + * @author ff + */ +public class FileSizeLimitExceededException extends FileException +{ + private static final long serialVersionUID = 1L; + + public FileSizeLimitExceededException(long defaultMaxSize) + { + super("upload.exceed.maxSize", new Object[] { defaultMaxSize }); + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/file/FileUploadException.java b/ff-base/src/main/java/com/ff/base/exception/file/FileUploadException.java new file mode 100644 index 0000000..a1107fa --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/file/FileUploadException.java @@ -0,0 +1,61 @@ +package com.ff.base.exception.file; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * 文件上传异常类 + * + * @author ff + */ +public class FileUploadException extends Exception +{ + + private static final long serialVersionUID = 1L; + + private final Throwable cause; + + public FileUploadException() + { + this(null, null); + } + + public FileUploadException(final String msg) + { + this(msg, null); + } + + public FileUploadException(String msg, Throwable cause) + { + super(msg); + this.cause = cause; + } + + @Override + public void printStackTrace(PrintStream stream) + { + super.printStackTrace(stream); + if (cause != null) + { + stream.println("Caused by:"); + cause.printStackTrace(stream); + } + } + + @Override + public void printStackTrace(PrintWriter writer) + { + super.printStackTrace(writer); + if (cause != null) + { + writer.println("Caused by:"); + cause.printStackTrace(writer); + } + } + + @Override + public Throwable getCause() + { + return cause; + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/file/InvalidExtensionException.java b/ff-base/src/main/java/com/ff/base/exception/file/InvalidExtensionException.java new file mode 100644 index 0000000..37087b8 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/file/InvalidExtensionException.java @@ -0,0 +1,80 @@ +package com.ff.base.exception.file; + +import java.util.Arrays; + +/** + * 文件上传 误异常类 + * + * @author ff + */ +public class InvalidExtensionException extends FileUploadException +{ + private static final long serialVersionUID = 1L; + + private String[] allowedExtension; + private String extension; + private String filename; + + public InvalidExtensionException(String[] allowedExtension, String extension, String filename) + { + super("文件[" + filename + "]后缀[" + extension + "]不正确,请上传" + Arrays.toString(allowedExtension) + "格式"); + this.allowedExtension = allowedExtension; + this.extension = extension; + this.filename = filename; + } + + public String[] getAllowedExtension() + { + return allowedExtension; + } + + public String getExtension() + { + return extension; + } + + public String getFilename() + { + return filename; + } + + public static class InvalidImageExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidFlashExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidMediaExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidVideoExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/job/TaskException.java b/ff-base/src/main/java/com/ff/base/exception/job/TaskException.java new file mode 100644 index 0000000..0281336 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/job/TaskException.java @@ -0,0 +1,34 @@ +package com.ff.base.exception.job; + +/** + * 计划策略异常 + * + * @author ff + */ +public class TaskException extends Exception +{ + private static final long serialVersionUID = 1L; + + private Code code; + + public TaskException(String msg, Code code) + { + this(msg, code, null); + } + + public TaskException(String msg, Code code, Exception nestedEx) + { + super(msg, nestedEx); + this.code = code; + } + + public Code getCode() + { + return code; + } + + public enum Code + { + TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/user/BlackListException.java b/ff-base/src/main/java/com/ff/base/exception/user/BlackListException.java new file mode 100644 index 0000000..10b2beb --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/user/BlackListException.java @@ -0,0 +1,16 @@ +package com.ff.base.exception.user; + +/** + * 黑名单IP异常类 + * + * @author ff + */ +public class BlackListException extends UserException +{ + private static final long serialVersionUID = 1L; + + public BlackListException() + { + super("login.blocked", null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/user/CaptchaException.java b/ff-base/src/main/java/com/ff/base/exception/user/CaptchaException.java new file mode 100644 index 0000000..78d7a0a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/user/CaptchaException.java @@ -0,0 +1,16 @@ +package com.ff.base.exception.user; + +/** + * 验证码错误异常类 + * + * @author ff + */ +public class CaptchaException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaException() + { + super("user.jcaptcha.error", null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/user/CaptchaExpireException.java b/ff-base/src/main/java/com/ff/base/exception/user/CaptchaExpireException.java new file mode 100644 index 0000000..fedd22f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/user/CaptchaExpireException.java @@ -0,0 +1,18 @@ +package com.ff.base.exception.user; + +import com.ff.base.exception.user.UserException; + +/** + * 验证码失效异常类 + * + * @author ff + */ +public class CaptchaExpireException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaExpireException() + { + super("user.jcaptcha.expire", null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/user/UserException.java b/ff-base/src/main/java/com/ff/base/exception/user/UserException.java new file mode 100644 index 0000000..6680a95 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/user/UserException.java @@ -0,0 +1,18 @@ +package com.ff.base.exception.user; + +import com.ff.base.exception.base.BaseException; + +/** + * 用户信息异常类 + * + * @author ff + */ +public class UserException extends BaseException +{ + private static final long serialVersionUID = 1L; + + public UserException(String code, Object[] args) + { + super("user", code, args, null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/user/UserNotExistsException.java b/ff-base/src/main/java/com/ff/base/exception/user/UserNotExistsException.java new file mode 100644 index 0000000..6029c63 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/user/UserNotExistsException.java @@ -0,0 +1,16 @@ +package com.ff.base.exception.user; + +/** + * 用户不存在异常类 + * + * @author ff + */ +public class UserNotExistsException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserNotExistsException() + { + super("user.not.exists", null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/user/UserPasswordNotMatchException.java b/ff-base/src/main/java/com/ff/base/exception/user/UserPasswordNotMatchException.java new file mode 100644 index 0000000..44f7646 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/user/UserPasswordNotMatchException.java @@ -0,0 +1,18 @@ +package com.ff.base.exception.user; + +import com.ff.base.exception.user.UserException; + +/** + * 用户密码不正确或不符合规范异常类 + * + * @author ff + */ +public class UserPasswordNotMatchException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserPasswordNotMatchException() + { + super("user.password.not.match", null); + } +} diff --git a/ff-base/src/main/java/com/ff/base/exception/user/UserPasswordRetryLimitExceedException.java b/ff-base/src/main/java/com/ff/base/exception/user/UserPasswordRetryLimitExceedException.java new file mode 100644 index 0000000..e867112 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/exception/user/UserPasswordRetryLimitExceedException.java @@ -0,0 +1,18 @@ +package com.ff.base.exception.user; + +import com.ff.base.exception.user.UserException; + +/** + * 用户错误最大次数异常类 + * + * @author ff + */ +public class UserPasswordRetryLimitExceedException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime) + { + super("user.password.retry.limit.exceed", new Object[] { retryLimitCount, lockTime }); + } +} diff --git a/ff-base/src/main/java/com/ff/base/filter/PropertyPreExcludeFilter.java b/ff-base/src/main/java/com/ff/base/filter/PropertyPreExcludeFilter.java new file mode 100644 index 0000000..47950d5 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/filter/PropertyPreExcludeFilter.java @@ -0,0 +1,24 @@ +package com.ff.base.filter; + +import com.alibaba.fastjson2.filter.SimplePropertyPreFilter; + +/** + * 排除JSON敏感属性 + * + * @author ff + */ +public class PropertyPreExcludeFilter extends SimplePropertyPreFilter +{ + public PropertyPreExcludeFilter() + { + } + + public PropertyPreExcludeFilter addExcludes(String... filters) + { + for (int i = 0; i < filters.length; i++) + { + this.getExcludes().add(filters[i]); + } + return this; + } +} diff --git a/ff-base/src/main/java/com/ff/base/filter/RepeatableFilter.java b/ff-base/src/main/java/com/ff/base/filter/RepeatableFilter.java new file mode 100644 index 0000000..5f6a972 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/filter/RepeatableFilter.java @@ -0,0 +1,48 @@ +package com.ff.base.filter; + +import com.ff.base.utils.StringUtils; +import org.springframework.http.MediaType; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +/** + * Repeatable 过滤器 + * + * @author ff + */ +public class RepeatableFilter implements Filter +{ + @Override + public void init(FilterConfig filterConfig) throws ServletException + { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + ServletRequest requestWrapper = null; + if (request instanceof HttpServletRequest + && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) + { + requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response); + } + if (null == requestWrapper) + { + chain.doFilter(request, response); + } + else + { + chain.doFilter(requestWrapper, response); + } + } + + @Override + public void destroy() + { + + } +} diff --git a/ff-base/src/main/java/com/ff/base/filter/RepeatedlyRequestWrapper.java b/ff-base/src/main/java/com/ff/base/filter/RepeatedlyRequestWrapper.java new file mode 100644 index 0000000..6a9804f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/filter/RepeatedlyRequestWrapper.java @@ -0,0 +1,77 @@ +package com.ff.base.filter; + +import com.ff.base.constant.Constants; +import com.ff.base.utils.http.HttpHelper; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; + +/** + * 构建可重复读取inputStream的request + * + * @author ff + */ +public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper +{ + private final byte[] body; + + public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException + { + super(request); + request.setCharacterEncoding(Constants.UTF8); + response.setCharacterEncoding(Constants.UTF8); + + body = HttpHelper.getBodyString(request).getBytes(Constants.UTF8); + } + + @Override + public BufferedReader getReader() throws IOException + { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + @Override + public ServletInputStream getInputStream() throws IOException + { + final ByteArrayInputStream bais = new ByteArrayInputStream(body); + return new ServletInputStream() + { + @Override + public int read() throws IOException + { + return bais.read(); + } + + @Override + public int available() throws IOException + { + return body.length; + } + + @Override + public boolean isFinished() + { + return false; + } + + @Override + public boolean isReady() + { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) + { + + } + }; + } +} diff --git a/ff-base/src/main/java/com/ff/base/filter/XssFilter.java b/ff-base/src/main/java/com/ff/base/filter/XssFilter.java new file mode 100644 index 0000000..c0ccba2 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/filter/XssFilter.java @@ -0,0 +1,72 @@ +package com.ff.base.filter; + +import com.ff.base.enums.HttpMethod; +import com.ff.base.filter.XssHttpServletRequestWrapper; +import com.ff.base.utils.StringUtils; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * 防止XSS攻击的过滤器 + * + * @author ff + */ +public class XssFilter implements Filter +{ + /** + * 排除链接 + */ + public List excludes = new ArrayList<>(); + + @Override + public void init(FilterConfig filterConfig) throws ServletException + { + String tempExcludes = filterConfig.getInitParameter("excludes"); + if (StringUtils.isNotEmpty(tempExcludes)) + { + String[] urls = tempExcludes.split(","); + for (String url : urls) + { + excludes.add(url); + } + } + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse resp = (HttpServletResponse) response; + if (handleExcludeURL(req, resp)) + { + chain.doFilter(request, response); + return; + } + XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request); + chain.doFilter(xssRequest, response); + } + + private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) + { + String url = request.getServletPath(); + String method = request.getMethod(); + // GET DELETE 不过滤 + if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method)) + { + return true; + } + return StringUtils.matches(url, excludes); + } + + @Override + public void destroy() + { + + } +} diff --git a/ff-base/src/main/java/com/ff/base/filter/XssHttpServletRequestWrapper.java b/ff-base/src/main/java/com/ff/base/filter/XssHttpServletRequestWrapper.java new file mode 100644 index 0000000..9380d7b --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/filter/XssHttpServletRequestWrapper.java @@ -0,0 +1,112 @@ +package com.ff.base.filter; + +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.html.EscapeUtil; +import org.apache.commons.io.IOUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.ByteArrayInputStream; +import java.io.IOException; + +/** + * XSS过滤处理 + * + * @author ff + */ +public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper +{ + /** + * @param request + */ + public XssHttpServletRequestWrapper(HttpServletRequest request) + { + super(request); + } + + @Override + public String[] getParameterValues(String name) + { + String[] values = super.getParameterValues(name); + if (values != null) + { + int length = values.length; + String[] escapesValues = new String[length]; + for (int i = 0; i < length; i++) + { + // 防xss攻击和过滤前后空格 + escapesValues[i] = EscapeUtil.clean(values[i]).trim(); + } + return escapesValues; + } + return super.getParameterValues(name); + } + + @Override + public ServletInputStream getInputStream() throws IOException + { + // 非json类型,直接返回 + if (!isJsonRequest()) + { + return super.getInputStream(); + } + + // 为空,直接返回 + String json = IOUtils.toString(super.getInputStream(), "utf-8"); + if (StringUtils.isEmpty(json)) + { + return super.getInputStream(); + } + + // xss过滤 + json = EscapeUtil.clean(json).trim(); + byte[] jsonBytes = json.getBytes("utf-8"); + final ByteArrayInputStream bis = new ByteArrayInputStream(jsonBytes); + return new ServletInputStream() + { + @Override + public boolean isFinished() + { + return true; + } + + @Override + public boolean isReady() + { + return true; + } + + @Override + public int available() throws IOException + { + return jsonBytes.length; + } + + @Override + public void setReadListener(ReadListener readListener) + { + } + + @Override + public int read() throws IOException + { + return bis.read(); + } + }; + } + + /** + * 是否是Json请求 + * + * @param request + */ + public boolean isJsonRequest() + { + String header = super.getHeader(HttpHeaders.CONTENT_TYPE); + return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE); + } +} diff --git a/ff-base/src/main/java/com/ff/base/interceptor/DataSourceSwitchInterceptor.java b/ff-base/src/main/java/com/ff/base/interceptor/DataSourceSwitchInterceptor.java new file mode 100644 index 0000000..b602cb8 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/interceptor/DataSourceSwitchInterceptor.java @@ -0,0 +1,52 @@ +package com.ff.base.interceptor; + +import com.ff.base.constant.Constants; +import com.ff.base.datasource.DynamicDataSourceContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 数据源切换拦截器 + * + * @author liukang + */ +@Component +public class DataSourceSwitchInterceptor implements HandlerInterceptor { + + /** + * 请求前切换数据源 + * + * @param request 请求对象 + * @param response 响应对象 + * @param handler 请求处理器 + * @return boolean + * @throws Exception 异常 + */ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + // 切换数据源 + String tenantId = request.getHeader(Constants.TENANT_ID); + if (tenantId != null) { + DynamicDataSourceContextHolder.setDataSourceType(tenantId); + } + return true; + } + + /** + * 请求结束后清除数据源 + * + * @param request 请求对象 + * @param response 响应对象 + * @param handler 请求处理器 + * @param ex 异常 + */ + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + DynamicDataSourceContextHolder.clearDataSourceType(); + } + + +} diff --git a/ff-base/src/main/java/com/ff/base/interceptor/RepeatSubmitInterceptor.java b/ff-base/src/main/java/com/ff/base/interceptor/RepeatSubmitInterceptor.java new file mode 100644 index 0000000..3227d41 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/interceptor/RepeatSubmitInterceptor.java @@ -0,0 +1,57 @@ +package com.ff.base.interceptor; + +import com.alibaba.fastjson2.JSON; +import com.ff.base.annotation.RepeatSubmit; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.utils.ServletUtils; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; + +/** + * 防止重复提交拦截器 + * + * @author ff + */ +@Component +public abstract class RepeatSubmitInterceptor implements HandlerInterceptor +{ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception + { + if (handler instanceof HandlerMethod) + { + HandlerMethod handlerMethod = (HandlerMethod) handler; + Method method = handlerMethod.getMethod(); + RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); + if (annotation != null) + { + if (this.isRepeatSubmit(request, annotation)) + { + AjaxResult ajaxResult = AjaxResult.error(annotation.message()); + ServletUtils.renderString(response, JSON.toJSONString(ajaxResult)); + return false; + } + } + return true; + } + else + { + return true; + } + } + + /** + * 验证是否重复提交由子类实现具体的防重复提交的规则 + * + * @param request 请求信息 + * @param annotation 防重复注解参数 + * @return 结果 + * @throws Exception + */ + public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation); +} diff --git a/ff-base/src/main/java/com/ff/base/interceptor/impl/SameUrlDataInterceptor.java b/ff-base/src/main/java/com/ff/base/interceptor/impl/SameUrlDataInterceptor.java new file mode 100644 index 0000000..6272255 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/interceptor/impl/SameUrlDataInterceptor.java @@ -0,0 +1,111 @@ +package com.ff.base.interceptor.impl; + +import com.alibaba.fastjson2.JSON; +import com.ff.base.annotation.RepeatSubmit; +import com.ff.base.constant.CacheConstants; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.filter.RepeatedlyRequestWrapper; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.http.HttpHelper; +import com.ff.base.interceptor.RepeatSubmitInterceptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * 判断请求url和数据是否和上一次相同, + * 如果和上次相同,则是重复提交表单。 有效时间为10秒内。 + * + * @author ff + */ +@Component +public class SameUrlDataInterceptor extends RepeatSubmitInterceptor +{ + public final String REPEAT_PARAMS = "repeatParams"; + + public final String REPEAT_TIME = "repeatTime"; + + // 令牌自定义标识 + @Value("${token.header}") + private String header; + + @Autowired + private RedisCache redisCache; + + @SuppressWarnings("unchecked") + @Override + public boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation) + { + String nowParams = ""; + if (request instanceof RepeatedlyRequestWrapper) + { + RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request; + nowParams = HttpHelper.getBodyString(repeatedlyRequest); + } + + // body参数为空,获取Parameter的数据 + if (StringUtils.isEmpty(nowParams)) + { + nowParams = JSON.toJSONString(request.getParameterMap()); + } + Map nowDataMap = new HashMap(); + nowDataMap.put(REPEAT_PARAMS, nowParams); + nowDataMap.put(REPEAT_TIME, System.currentTimeMillis()); + + // 请求地址(作为存放cache的key值) + String url = request.getRequestURI(); + + // 唯一值(没有消息头则使用请求地址) + String submitKey = StringUtils.trimToEmpty(request.getHeader(header)); + + // 唯一标识(指定key + url + 消息头) + String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey; + + Object sessionObj = redisCache.getCacheObject(cacheRepeatKey); + if (sessionObj != null) + { + Map sessionMap = (Map) sessionObj; + if (sessionMap.containsKey(url)) + { + Map preDataMap = (Map) sessionMap.get(url); + if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, annotation.interval())) + { + return true; + } + } + } + Map cacheMap = new HashMap(); + cacheMap.put(url, nowDataMap); + redisCache.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS); + return false; + } + + /** + * 判断参数是否相同 + */ + private boolean compareParams(Map nowMap, Map preMap) + { + String nowParams = (String) nowMap.get(REPEAT_PARAMS); + String preParams = (String) preMap.get(REPEAT_PARAMS); + return nowParams.equals(preParams); + } + + /** + * 判断两次间隔时间 + */ + private boolean compareTime(Map nowMap, Map preMap, int interval) + { + long time1 = (Long) nowMap.get(REPEAT_TIME); + long time2 = (Long) preMap.get(REPEAT_TIME); + if ((time1 - time2) < interval) + { + return true; + } + return false; + } +} diff --git a/ff-base/src/main/java/com/ff/base/manager/AsyncManager.java b/ff-base/src/main/java/com/ff/base/manager/AsyncManager.java new file mode 100644 index 0000000..4e2458f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/manager/AsyncManager.java @@ -0,0 +1,75 @@ +package com.ff.base.manager; + +import com.ff.base.utils.Threads; +import com.ff.base.utils.spring.SpringUtils; +import java.util.TimerTask; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * 异步任务管理器 + * + * @author ff + */ +public class AsyncManager { + /** + * 操作延迟10毫秒 + */ + private final int OPERATE_DELAY_TIME = 10; + + /** + * 异步操作任务调度线程池 + */ + private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService"); + + /** + * 单例模式 + */ + private AsyncManager() { + } + + private static AsyncManager me = new AsyncManager(); + + public static AsyncManager me() { + return me; + } + + /** + * 执行任务 + * + * @param task 任务 + */ + public void execute(TimerTask task) { + executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS); + } + + + /** + * 执行任务 + * + * @param command 任务 + */ + public void execute(Runnable command) { + executor.execute(command); + + } + + /** + * 执行任务 + * + * @param task 任务 + */ + public Future submit(Callable task) { + return executor.submit(task); + } + + + /** + * 停止任务线程池 + */ + public void shutdown() { + Threads.shutdownAndAwaitTermination(executor); + } +} diff --git a/ff-base/src/main/java/com/ff/base/manager/ShutdownManager.java b/ff-base/src/main/java/com/ff/base/manager/ShutdownManager.java new file mode 100644 index 0000000..357ab61 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/manager/ShutdownManager.java @@ -0,0 +1,40 @@ +package com.ff.base.manager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.annotation.PreDestroy; + +/** + * 确保应用退出时能关闭后台线程 + * + * @author ff + */ +@Component +public class ShutdownManager +{ + private static final Logger logger = LoggerFactory.getLogger("sys-user"); + + @PreDestroy + public void destroy() + { + shutdownAsyncManager(); + } + + /** + * 停止异步执行任务 + */ + private void shutdownAsyncManager() + { + try + { + logger.info("====关闭后台任务任务线程池===="); + AsyncManager.me().shutdown(); + } + catch (Exception e) + { + logger.error(e.getMessage(), e); + } + } +} diff --git a/ff-base/src/main/java/com/ff/base/manager/factory/AsyncFactory.java b/ff-base/src/main/java/com/ff/base/manager/factory/AsyncFactory.java new file mode 100644 index 0000000..c3f1ea8 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/manager/factory/AsyncFactory.java @@ -0,0 +1,103 @@ +package com.ff.base.manager.factory; + +import com.ff.base.constant.Constants; +import com.ff.base.utils.LogUtils; +import com.ff.base.utils.ServletUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.ip.AddressUtils; +import com.ff.base.utils.ip.IpUtils; +import com.ff.base.utils.spring.SpringUtils; +import com.ff.base.system.domain.SysLogininfor; +import com.ff.base.system.domain.SysOperLog; +import com.ff.base.system.service.ISysLogininforService; +import com.ff.base.system.service.ISysOperLogService; +import eu.bitwalker.useragentutils.UserAgent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.TimerTask; + +/** + * 异步工厂(产生任务用) + * + * @author ff + */ +public class AsyncFactory +{ + private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user"); + + /** + * 记录登录信息 + * + * @param username 用户名 + * @param status 状态 + * @param message 消息 + * @param args 列表 + * @return 任务task + */ + public static TimerTask recordLogininfor(final String username, final String status, final String message, + final Object... args) + { + final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); + final String ip = IpUtils.getIpAddr(); + return new TimerTask() + { + @Override + public void run() + { + String address = AddressUtils.getRealAddressByIP(ip); + StringBuilder s = new StringBuilder(); + s.append(LogUtils.getBlock(ip)); + s.append(address); + s.append(LogUtils.getBlock(username)); + s.append(LogUtils.getBlock(status)); + s.append(LogUtils.getBlock(message)); + // 打印信息到日志 + sys_user_logger.info(s.toString(), args); + // 获取客户端操作系统 + String os = userAgent.getOperatingSystem().getName(); + // 获取客户端浏览器 + String browser = userAgent.getBrowser().getName(); + // 封装对象 + SysLogininfor logininfor = new SysLogininfor(); + logininfor.setUserName(username); + logininfor.setIpaddr(ip); + logininfor.setLoginLocation(address); + logininfor.setBrowser(browser); + logininfor.setOs(os); + logininfor.setMsg(message); + // 日志状态 + if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) + { + logininfor.setStatus(Constants.SUCCESS); + } + else if (Constants.LOGIN_FAIL.equals(status)) + { + logininfor.setStatus(Constants.FAIL); + } + // 插入数据 + SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor); + } + }; + } + + /** + * 操作日志记录 + * + * @param operLog 操作日志信息 + * @return 任务task + */ + public static TimerTask recordOper(final SysOperLog operLog) + { + return new TimerTask() + { + @Override + public void run() + { + // 远程查询操作地点 + operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp())); + SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog); + } + }; + } +} diff --git a/ff-base/src/main/java/com/ff/base/security/context/AuthenticationContextHolder.java b/ff-base/src/main/java/com/ff/base/security/context/AuthenticationContextHolder.java new file mode 100644 index 0000000..5da2c53 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/security/context/AuthenticationContextHolder.java @@ -0,0 +1,28 @@ +package com.ff.base.security.context; + +import org.springframework.security.core.Authentication; + +/** + * 身份验证信息 + * + * @author ff + */ +public class AuthenticationContextHolder +{ + private static final ThreadLocal contextHolder = new ThreadLocal<>(); + + public static Authentication getContext() + { + return contextHolder.get(); + } + + public static void setContext(Authentication context) + { + contextHolder.set(context); + } + + public static void clearContext() + { + contextHolder.remove(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/security/context/PermissionContextHolder.java b/ff-base/src/main/java/com/ff/base/security/context/PermissionContextHolder.java new file mode 100644 index 0000000..68426a8 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/security/context/PermissionContextHolder.java @@ -0,0 +1,27 @@ +package com.ff.base.security.context; + +import com.ff.base.core.text.Convert; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; + +/** + * 权限信息 + * + * @author ff + */ +public class PermissionContextHolder +{ + private static final String PERMISSION_CONTEXT_ATTRIBUTES = "PERMISSION_CONTEXT"; + + public static void setContext(String permission) + { + RequestContextHolder.currentRequestAttributes().setAttribute(PERMISSION_CONTEXT_ATTRIBUTES, permission, + RequestAttributes.SCOPE_REQUEST); + } + + public static String getContext() + { + return Convert.toStr(RequestContextHolder.currentRequestAttributes().getAttribute(PERMISSION_CONTEXT_ATTRIBUTES, + RequestAttributes.SCOPE_REQUEST)); + } +} diff --git a/ff-base/src/main/java/com/ff/base/security/encode/CustomMd5PasswordEncoder.java b/ff-base/src/main/java/com/ff/base/security/encode/CustomMd5PasswordEncoder.java new file mode 100644 index 0000000..fd44ab3 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/security/encode/CustomMd5PasswordEncoder.java @@ -0,0 +1,38 @@ +package com.ff.base.security.encode; + +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.sign.Md5Utils; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + + +/** + * md5密码加密方法 + * + * @author liukang + */ +@Component +public class CustomMd5PasswordEncoder implements PasswordEncoder { + + + /** + * 重写security加密算法 + * @param rawPassword + * @return + */ + @Override + public String encode(CharSequence rawPassword) { + return Md5Utils.hash(rawPassword.toString()); + } + + /** + * 重写security密码比对方法 + * @param rawPassword the raw password to encode and match + * @param encodedPassword the encoded password from storage to compare with + * @return + */ + @Override + public boolean matches(CharSequence rawPassword, String encodedPassword) { + return StringUtils.equals(Md5Utils.hash(rawPassword.toString()), encodedPassword); + } +} diff --git a/ff-base/src/main/java/com/ff/base/security/filter/JwtAuthenticationTokenFilter.java b/ff-base/src/main/java/com/ff/base/security/filter/JwtAuthenticationTokenFilter.java new file mode 100644 index 0000000..3a359a6 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/security/filter/JwtAuthenticationTokenFilter.java @@ -0,0 +1,90 @@ +package com.ff.base.security.filter; + +import com.alibaba.fastjson2.JSON; +import com.ff.base.constant.HttpStatus; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.datasource.DynamicDataSourceContextHolder; +import com.ff.base.enums.MemberStatus; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.ServletUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.web.service.TokenService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * token过滤器 验证token有效性 + * + * @author ff + */ +@Component +public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { + @Autowired + private TokenService tokenService; + + @Autowired + private RedisCache redisCache; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws ServletException, IOException { + LoginUser loginUser = tokenService.getLoginUser(request); + if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) { + int result = verifyStatus(loginUser, response); + if (result == 0) { + return; + } + tokenService.verifyToken(loginUser); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } + chain.doFilter(request, response); + } + + /** + * 验证会员状态 + * + * @param loginUser 登录信息 + * @param response 响应信息 + * @return 结果 0.不正常 1.正常 + */ + private int verifyStatus(LoginUser loginUser, HttpServletResponse response) { + int result = 1; + Object cacheObject = redisCache.getCacheObject("memberStatus:" + loginUser.getUserId()); + if (cacheObject != null && loginUser.getUser().getLoginType().equals(1)) { + int code = HttpStatus.ERROR; + String status = cacheObject.toString(); + if (status.equals(MemberStatus.MemberStatus_1.getCode()) || status.equals(MemberStatus.MemberStatus_2.getCode())) { + result = 0; + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, "账号已被冻结"))); + } + if (status.equals(MemberStatus.MemberStatus_5.getCode())) { + result = 0; + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, "账号已被拉黑"))); + } + if (status.equals(MemberStatus.MemberStatus_6.getCode())) { + result = 0; + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, "账号已被停用"))); + } + if (status.equals(MemberStatus.MemberStatus_10.getCode())) { + result = 0; + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, "账号已被限制登录"))); + } + } + return result; + + } +} diff --git a/ff-base/src/main/java/com/ff/base/security/handle/AuthenticationEntryPointImpl.java b/ff-base/src/main/java/com/ff/base/security/handle/AuthenticationEntryPointImpl.java new file mode 100644 index 0000000..fdca058 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/security/handle/AuthenticationEntryPointImpl.java @@ -0,0 +1,35 @@ +package com.ff.base.security.handle; + +import com.alibaba.fastjson2.JSON; +import com.ff.base.constant.HttpStatus; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.utils.ServletUtils; +import com.ff.base.utils.StringUtils; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.Serializable; + +/** + * 认证失败处理类 返回未授权 + * + * @author ff + */ +@Component +public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable +{ + private static final long serialVersionUID = -8970718410437077606L; + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) + throws IOException + { + int code = HttpStatus.UNAUTHORIZED; + String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI()); + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg))); + } +} diff --git a/ff-base/src/main/java/com/ff/base/security/handle/LogoutSuccessHandlerImpl.java b/ff-base/src/main/java/com/ff/base/security/handle/LogoutSuccessHandlerImpl.java new file mode 100644 index 0000000..fedf15d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/security/handle/LogoutSuccessHandlerImpl.java @@ -0,0 +1,54 @@ +package com.ff.base.security.handle; + +import com.alibaba.fastjson2.JSON; +import com.ff.base.constant.Constants; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.ServletUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.manager.AsyncManager; +import com.ff.base.manager.factory.AsyncFactory; +import com.ff.base.web.service.TokenService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 自定义退出处理类 返回成功 + * + * @author ff + */ +@Configuration +public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler +{ + @Autowired + private TokenService tokenService; + + /** + * 退出处理 + * + * @return + */ + @Override + public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) + throws IOException, ServletException + { + LoginUser loginUser = tokenService.getLoginUser(request); + if (StringUtils.isNotNull(loginUser)) + { + String userName = loginUser.getUsername(); + // 删除用户缓存记录 + tokenService.delLoginUser(loginUser.getToken()); + // 记录用户退出日志 + AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, MessageUtils.message("user.logout.success"))); + } + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success(MessageUtils.message("user.logout.success")))); + } +} diff --git a/ff-base/src/main/java/com/ff/base/security/provider/MyDaoAuthenticationProvider.java b/ff-base/src/main/java/com/ff/base/security/provider/MyDaoAuthenticationProvider.java new file mode 100644 index 0000000..5059437 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/security/provider/MyDaoAuthenticationProvider.java @@ -0,0 +1,141 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by FernFlower decompiler) +// + +package com.ff.base.security.provider; + +import com.ff.base.core.domain.model.LoginForm; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.InternalAuthenticationServiceException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsPasswordService; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.util.Assert; + +import java.util.List; + +/** + * 重写spring security 权限校验类(指定权限认证器) + * + * @author liukang + */ +public class MyDaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { + private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword"; + private PasswordEncoder passwordEncoder; + private volatile String userNotFoundEncodedPassword; + private UserDetailsService userDetailsService; + private UserDetailsPasswordService userDetailsPasswordService; + private List userDetailsServices; + + public MyDaoAuthenticationProvider() { + this.setPasswordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()); + } + + protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { + if (authentication.getCredentials() == null) { + this.logger.debug("Failed to authenticate since no credentials provided"); + throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); + } else { + // 验证密码 + LoginForm credentials = (LoginForm) authentication.getCredentials(); + String presentedPassword = credentials.getPassword(); + if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) { + this.logger.debug("Failed to authenticate since password does not match stored value"); + throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); + } + } + } + + protected void doAfterPropertiesSet() { + Assert.notNull(this.userDetailsService, "A UserDetailsService must be set"); + } + + protected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { + this.prepareTimingAttackProtection(); + + try { + LoginForm loginForm = (LoginForm) authentication.getCredentials(); + // 获取对应登录类型的验证器 + UserDetails loadedUser = this.getUserDetailsServices().get(loginForm.getLoginType()).loadUserByUsername(username); + if (loadedUser == null) { + throw new InternalAuthenticationServiceException("UserDetailsService returned null, which is an interface contract violation"); + } else { + return loadedUser; + } + } catch (UsernameNotFoundException var4) { + UsernameNotFoundException ex = var4; + this.mitigateAgainstTimingAttack(authentication); + throw ex; + } catch (InternalAuthenticationServiceException var5) { + InternalAuthenticationServiceException ex = var5; + throw ex; + } catch (Exception var6) { + Exception ex = var6; + throw new InternalAuthenticationServiceException(ex.getMessage(), ex); + } + } + + protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) { + boolean upgradeEncoding = this.userDetailsPasswordService != null && this.passwordEncoder.upgradeEncoding(user.getPassword()); + if (upgradeEncoding) { + String presentedPassword = authentication.getCredentials().toString(); + String newPassword = this.passwordEncoder.encode(presentedPassword); + user = this.userDetailsPasswordService.updatePassword(user, newPassword); + } + + return super.createSuccessAuthentication(principal, authentication, user); + } + + private void prepareTimingAttackProtection() { + if (this.userNotFoundEncodedPassword == null) { + this.userNotFoundEncodedPassword = this.passwordEncoder.encode("userNotFoundPassword"); + } + + } + + private void mitigateAgainstTimingAttack(UsernamePasswordAuthenticationToken authentication) { + if (authentication.getCredentials() != null) { + String presentedPassword = authentication.getCredentials().toString(); + this.passwordEncoder.matches(presentedPassword, this.userNotFoundEncodedPassword); + } + + } + + public void setPasswordEncoder(PasswordEncoder passwordEncoder) { + Assert.notNull(passwordEncoder, "passwordEncoder cannot be null"); + this.passwordEncoder = passwordEncoder; + this.userNotFoundEncodedPassword = null; + } + + protected PasswordEncoder getPasswordEncoder() { + return this.passwordEncoder; + } + + public void setUserDetailsService(UserDetailsService userDetailsService) { + this.userDetailsService = userDetailsService; + } + + protected UserDetailsService getUserDetailsService() { + return this.userDetailsService; + } + + public void setUserDetailsPasswordService(UserDetailsPasswordService userDetailsPasswordService) { + this.userDetailsPasswordService = userDetailsPasswordService; + } + + public List getUserDetailsServices() { + return userDetailsServices; + } + + public void setUserDetailsServices(List userDetailsServices) { + this.userDetailsServices = userDetailsServices; + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysConfig.java b/ff-base/src/main/java/com/ff/base/system/domain/SysConfig.java new file mode 100644 index 0000000..8efd44a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysConfig.java @@ -0,0 +1,112 @@ +package com.ff.base.system.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.annotation.Excel.ColumnType; +import com.ff.base.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +/** + * 参数配置表 sys_config + * + * @author ff + */ +public class SysConfig extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 参数主键 */ + @Excel(name = "参数主键", cellType = ColumnType.NUMERIC) + private Long configId; + + /** 参数名称 */ + @Excel(name = "参数名称") + private String configName; + + /** 参数键名 */ + @Excel(name = "参数键名") + private String configKey; + + /** 参数键值 */ + @Excel(name = "参数键值") + private String configValue; + + /** 系统内置(Y是 N否) */ + @Excel(name = "系统内置", readConverterExp = "Y=是,N=否") + private String configType; + + public Long getConfigId() + { + return configId; + } + + public void setConfigId(Long configId) + { + this.configId = configId; + } + + @NotBlank(message = "参数名称不能为空") + @Size(min = 0, max = 100, message = "参数名称不能超过100个字符") + public String getConfigName() + { + return configName; + } + + public void setConfigName(String configName) + { + this.configName = configName; + } + + @NotBlank(message = "参数键名长度不能为空") + @Size(min = 0, max = 100, message = "参数键名长度不能超过100个字符") + public String getConfigKey() + { + return configKey; + } + + public void setConfigKey(String configKey) + { + this.configKey = configKey; + } + + @NotBlank(message = "参数键值不能为空") + @Size(min = 0, max = 500, message = "参数键值长度不能超过500个字符") + public String getConfigValue() + { + return configValue; + } + + public void setConfigValue(String configValue) + { + this.configValue = configValue; + } + + public String getConfigType() + { + return configType; + } + + public void setConfigType(String configType) + { + this.configType = configType; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("configId", getConfigId()) + .append("configName", getConfigName()) + .append("configKey", getConfigKey()) + .append("configValue", getConfigValue()) + .append("configType", getConfigType()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysDatasource.java b/ff-base/src/main/java/com/ff/base/system/domain/SysDatasource.java new file mode 100644 index 0000000..aa9bed8 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysDatasource.java @@ -0,0 +1,52 @@ +package com.ff.base.system.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; +import lombok.Data; +/** + * 租户数据源对象 sys_datasource + * + * @author liukang + * @date 2024-11-20 + */ +@Data +public class SysDatasource extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long id; + + /** 租户id */ + @Excel(name = "租户id") + private String tenantId; + + /** 连接地址 */ + @Excel(name = "连接地址") + private String url; + + /** 用户名 */ + @Excel(name = "用户名") + private String username; + + /** 密码 */ + @Excel(name = "密码") + private String password; + + /** 数据库驱动 */ + @Excel(name = "数据库驱动") + private String driverClassName; + + /** 时区 */ + @Excel(name = "时区") + private String timeZone; + + /** 状态(0 停用 1 启用) */ + @Excel(name = "状态", readConverterExp = "0=,停=用,1=,启=用") + private String status; + + /** 时区名称 */ + private String timeZoneName; + + +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysDept.java b/ff-base/src/main/java/com/ff/base/system/domain/SysDept.java new file mode 100644 index 0000000..8395dba --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysDept.java @@ -0,0 +1,204 @@ +package com.ff.base.system.domain; + +import com.ff.base.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.ArrayList; +import java.util.List; + +/** + * 部门表 sys_dept + * + * @author ff + */ +public class SysDept extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 部门ID */ + private Long deptId; + + /** 父部门ID */ + private Long parentId; + + /** 祖级列表 */ + private String ancestors; + + /** 部门名称 */ + private String deptName; + + /** 显示顺序 */ + private Integer orderNum; + + /** 负责人 */ + private String leader; + + /** 联系电话 */ + private String phone; + + /** 邮箱 */ + private String email; + + /** 部门状态:0正常,1停用 */ + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 父部门名称 */ + private String parentName; + + /** 子部门 */ + private List children = new ArrayList(); + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + public String getAncestors() + { + return ancestors; + } + + public void setAncestors(String ancestors) + { + this.ancestors = ancestors; + } + + @NotBlank(message = "部门名称不能为空") + @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符") + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + public String getLeader() + { + return leader; + } + + public void setLeader(String leader) + { + this.leader = leader; + } + + @Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符") + public String getPhone() + { + return phone; + } + + public void setPhone(String phone) + { + this.phone = phone; + } + + @Email(message = "邮箱格式不正确") + @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("deptId", getDeptId()) + .append("parentId", getParentId()) + .append("ancestors", getAncestors()) + .append("deptName", getDeptName()) + .append("orderNum", getOrderNum()) + .append("leader", getLeader()) + .append("phone", getPhone()) + .append("email", getEmail()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysDictData.java b/ff-base/src/main/java/com/ff/base/system/domain/SysDictData.java new file mode 100644 index 0000000..8c45a31 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysDictData.java @@ -0,0 +1,199 @@ +package com.ff.base.system.domain; + +import com.fasterxml.jackson.annotation.JsonView; +import com.ff.base.annotation.Excel; +import com.ff.base.annotation.Excel.ColumnType; +import com.ff.base.constant.UserConstants; +import com.ff.base.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +/** + * 字典数据表 sys_dict_data + * + * @author ff + */ +public class SysDictData extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + public interface DictDataSimpleView {}; + /** 字典编码 */ + @Excel(name = "字典编码", cellType = ColumnType.NUMERIC) + @JsonView(DictDataSimpleView.class) + private Long dictCode; + + /** 字典排序 */ + @Excel(name = "字典排序", cellType = ColumnType.NUMERIC) + @JsonView(DictDataSimpleView.class) + private Long dictSort; + + /** 字典标签 */ + @Excel(name = "字典标签") + @JsonView(DictDataSimpleView.class) + private String dictLabel; + + /** 字典键值 */ + @Excel(name = "字典键值") + @JsonView(DictDataSimpleView.class) + private String dictValue; + + /** 字典类型 */ + @Excel(name = "字典类型") + @JsonView(DictDataSimpleView.class) + private String dictType; + + /** 样式属性(其他样式扩展) */ + @JsonView(DictDataSimpleView.class) + private String cssClass; + + /** 表格字典样式 */ + @JsonView(DictDataSimpleView.class) + private String listClass; + + /** 是否默认(Y是 N否) */ + @Excel(name = "是否默认", readConverterExp = "Y=是,N=否") + @JsonView(DictDataSimpleView.class) + private String isDefault; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + @Override + public String getRemark() { + return remark; + } + + @Override + public void setRemark(String remark) { + this.remark = remark; + } + @JsonView(DictDataSimpleView.class) + private String remark; + + public Long getDictCode() + { + return dictCode; + } + + public void setDictCode(Long dictCode) + { + this.dictCode = dictCode; + } + + public Long getDictSort() + { + return dictSort; + } + + public void setDictSort(Long dictSort) + { + this.dictSort = dictSort; + } + + @NotBlank(message = "字典标签不能为空") + @Size(min = 0, max = 200, message = "字典标签长度不能超过200个字符") + public String getDictLabel() + { + return dictLabel; + } + + public void setDictLabel(String dictLabel) + { + this.dictLabel = dictLabel; + } + + @NotBlank(message = "字典键值不能为空") + @Size(min = 0, max = 200, message = "字典键值长度不能超过200个字符") + public String getDictValue() + { + return dictValue; + } + + public void setDictValue(String dictValue) + { + this.dictValue = dictValue; + } + + @NotBlank(message = "字典类型不能为空") + @Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符") + public String getDictType() + { + return dictType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + @Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符") + public String getCssClass() + { + return cssClass; + } + + public void setCssClass(String cssClass) + { + this.cssClass = cssClass; + } + + public String getListClass() + { + return listClass; + } + + public void setListClass(String listClass) + { + this.listClass = listClass; + } + + public boolean getDefault() + { + return UserConstants.YES.equals(this.isDefault); + } + + public String getIsDefault() + { + return isDefault; + } + + public void setIsDefault(String isDefault) + { + this.isDefault = isDefault; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("dictCode", getDictCode()) + .append("dictSort", getDictSort()) + .append("dictLabel", getDictLabel()) + .append("dictValue", getDictValue()) + .append("dictType", getDictType()) + .append("cssClass", getCssClass()) + .append("listClass", getListClass()) + .append("isDefault", getIsDefault()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysDictType.java b/ff-base/src/main/java/com/ff/base/system/domain/SysDictType.java new file mode 100644 index 0000000..a124a75 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysDictType.java @@ -0,0 +1,97 @@ +package com.ff.base.system.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.annotation.Excel.ColumnType; +import com.ff.base.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; + +/** + * 字典类型表 sys_dict_type + * + * @author ff + */ +public class SysDictType extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 字典主键 */ + @Excel(name = "字典主键", cellType = ColumnType.NUMERIC) + private Long dictId; + + /** 字典名称 */ + @Excel(name = "字典名称") + private String dictName; + + /** 字典类型 */ + @Excel(name = "字典类型") + private String dictType; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + public Long getDictId() + { + return dictId; + } + + public void setDictId(Long dictId) + { + this.dictId = dictId; + } + + @NotBlank(message = "字典名称不能为空") + @Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符") + public String getDictName() + { + return dictName; + } + + public void setDictName(String dictName) + { + this.dictName = dictName; + } + + @NotBlank(message = "字典类型不能为空") + @Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符") + @Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)") + public String getDictType() + { + return dictType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("dictId", getDictId()) + .append("dictName", getDictName()) + .append("dictType", getDictType()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysLogininfor.java b/ff-base/src/main/java/com/ff/base/system/domain/SysLogininfor.java new file mode 100644 index 0000000..67686de --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysLogininfor.java @@ -0,0 +1,144 @@ +package com.ff.base.system.domain; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.ff.base.annotation.Excel; +import com.ff.base.annotation.Excel.ColumnType; +import com.ff.base.core.domain.BaseEntity; + +/** + * 系统访问记录表 sys_logininfor + * + * @author ff + */ +public class SysLogininfor extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Excel(name = "序号", cellType = ColumnType.NUMERIC) + private Long infoId; + + /** 用户账号 */ + @Excel(name = "用户账号") + private String userName; + + /** 登录状态 0成功 1失败 */ + @Excel(name = "登录状态", readConverterExp = "0=成功,1=失败") + private String status; + + /** 登录IP地址 */ + @Excel(name = "登录地址") + private String ipaddr; + + /** 登录地点 */ + @Excel(name = "登录地点") + private String loginLocation; + + /** 浏览器类型 */ + @Excel(name = "浏览器") + private String browser; + + /** 操作系统 */ + @Excel(name = "操作系统") + private String os; + + /** 提示消息 */ + @Excel(name = "提示消息") + private String msg; + + /** 访问时间 */ + @JsonSerialize(using = ToStringSerializer.class) + @Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Long loginTime; + + public Long getInfoId() + { + return infoId; + } + + public void setInfoId(Long infoId) + { + this.infoId = infoId; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysMenu.java b/ff-base/src/main/java/com/ff/base/system/domain/SysMenu.java new file mode 100644 index 0000000..369ba10 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysMenu.java @@ -0,0 +1,275 @@ +package com.ff.base.system.domain; + +import com.ff.base.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.ArrayList; +import java.util.List; + +/** + * 菜单权限表 sys_menu + * + * @author ff + */ +public class SysMenu extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 菜单ID */ + private Long menuId; + + /** 菜单名称 */ + private String menuName; + + /** 父菜单名称 */ + private String parentName; + + /** 父菜单ID */ + private Long parentId; + + /** 显示顺序 */ + private Integer orderNum; + + /** 路由地址 */ + private String path; + + /** 组件路径 */ + private String component; + + /** 路由参数 */ + private String query; + + /** 路由名称,默认和路由地址相同的驼峰格式(注意:因为vue3版本的router会删除名称相同路由,为避免名字的冲突,特殊情况可以自定义) */ + private String routeName; + + /** 是否为外链(0是 1否) */ + private String isFrame; + + /** 是否缓存(0缓存 1不缓存) */ + private String isCache; + + /** 类型(M目录 C菜单 F按钮) */ + private String menuType; + + /** 显示状态(0显示 1隐藏) */ + private String visible; + + /** 菜单状态(0正常 1停用) */ + private String status; + + /** 权限字符串 */ + private String perms; + + /** 菜单图标 */ + private String icon; + + /** 子菜单 */ + private List children = new ArrayList(); + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @NotBlank(message = "菜单名称不能为空") + @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符") + public String getMenuName() + { + return menuName; + } + + public void setMenuName(String menuName) + { + this.menuName = menuName; + } + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + @Size(min = 0, max = 200, message = "路由地址不能超过200个字符") + public String getPath() + { + return path; + } + + public void setPath(String path) + { + this.path = path; + } + + @Size(min = 0, max = 200, message = "组件路径不能超过255个字符") + public String getComponent() + { + return component; + } + + public void setComponent(String component) + { + this.component = component; + } + + public String getQuery() + { + return query; + } + + public void setQuery(String query) + { + this.query = query; + } + + public String getRouteName() + { + return routeName; + } + + public void setRouteName(String routeName) + { + this.routeName = routeName; + } + + public String getIsFrame() + { + return isFrame; + } + + public void setIsFrame(String isFrame) + { + this.isFrame = isFrame; + } + + public String getIsCache() + { + return isCache; + } + + public void setIsCache(String isCache) + { + this.isCache = isCache; + } + + @NotBlank(message = "菜单类型不能为空") + public String getMenuType() + { + return menuType; + } + + public void setMenuType(String menuType) + { + this.menuType = menuType; + } + + public String getVisible() + { + return visible; + } + + public void setVisible(String visible) + { + this.visible = visible; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符") + public String getPerms() + { + return perms; + } + + public void setPerms(String perms) + { + this.perms = perms; + } + + public String getIcon() + { + return icon; + } + + public void setIcon(String icon) + { + this.icon = icon; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("menuId", getMenuId()) + .append("menuName", getMenuName()) + .append("parentId", getParentId()) + .append("orderNum", getOrderNum()) + .append("path", getPath()) + .append("component", getComponent()) + .append("query", getQuery()) + .append("routeName", getRouteName()) + .append("isFrame", getIsFrame()) + .append("IsCache", getIsCache()) + .append("menuType", getMenuType()) + .append("visible", getVisible()) + .append("status ", getStatus()) + .append("perms", getPerms()) + .append("icon", getIcon()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysOperLog.java b/ff-base/src/main/java/com/ff/base/system/domain/SysOperLog.java new file mode 100644 index 0000000..751c7f9 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysOperLog.java @@ -0,0 +1,269 @@ +package com.ff.base.system.domain; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.ff.base.annotation.Excel; +import com.ff.base.annotation.Excel.ColumnType; +import com.ff.base.core.domain.BaseEntity; + +/** + * 操作日志记录表 oper_log + * + * @author ff + */ +public class SysOperLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 日志主键 */ + @Excel(name = "操作序号", cellType = ColumnType.NUMERIC) + private Long operId; + + /** 操作模块 */ + @Excel(name = "操作模块") + private String title; + + /** 业务类型(0其它 1新增 2修改 3删除) */ + @Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据") + private Integer businessType; + + /** 业务类型数组 */ + private Integer[] businessTypes; + + /** 请求方法 */ + @Excel(name = "请求方法") + private String method; + + /** 请求方式 */ + @Excel(name = "请求方式") + private String requestMethod; + + /** 操作类别(0其它 1后台用户 2手机端用户) */ + @Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户") + private Integer operatorType; + + /** 操作人员 */ + @Excel(name = "操作人员") + private String operName; + + /** 部门名称 */ + @Excel(name = "部门名称") + private String deptName; + + /** 请求url */ + @Excel(name = "请求地址") + private String operUrl; + + /** 操作地址 */ + @Excel(name = "操作地址") + private String operIp; + + /** 操作地点 */ + @Excel(name = "操作地点") + private String operLocation; + + /** 请求参数 */ + @Excel(name = "请求参数") + private String operParam; + + /** 返回参数 */ + @Excel(name = "返回参数") + private String jsonResult; + + /** 操作状态(0正常 1异常) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=异常") + private Integer status; + + /** 错误消息 */ + @Excel(name = "错误消息") + private String errorMsg; + + /** 操作时间 */ + @JsonSerialize(using = ToStringSerializer.class) + @Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Long operTime; + + /** 消耗时间 */ + @Excel(name = "消耗时间", suffix = "毫秒") + private Long costTime; + + public Long getOperId() + { + return operId; + } + + public void setOperId(Long operId) + { + this.operId = operId; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public Integer getBusinessType() + { + return businessType; + } + + public void setBusinessType(Integer businessType) + { + this.businessType = businessType; + } + + public Integer[] getBusinessTypes() + { + return businessTypes; + } + + public void setBusinessTypes(Integer[] businessTypes) + { + this.businessTypes = businessTypes; + } + + public String getMethod() + { + return method; + } + + public void setMethod(String method) + { + this.method = method; + } + + public String getRequestMethod() + { + return requestMethod; + } + + public void setRequestMethod(String requestMethod) + { + this.requestMethod = requestMethod; + } + + public Integer getOperatorType() + { + return operatorType; + } + + public void setOperatorType(Integer operatorType) + { + this.operatorType = operatorType; + } + + public String getOperName() + { + return operName; + } + + public void setOperName(String operName) + { + this.operName = operName; + } + + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + public String getOperUrl() + { + return operUrl; + } + + public void setOperUrl(String operUrl) + { + this.operUrl = operUrl; + } + + public String getOperIp() + { + return operIp; + } + + public void setOperIp(String operIp) + { + this.operIp = operIp; + } + + public String getOperLocation() + { + return operLocation; + } + + public void setOperLocation(String operLocation) + { + this.operLocation = operLocation; + } + + public String getOperParam() + { + return operParam; + } + + public void setOperParam(String operParam) + { + this.operParam = operParam; + } + + public String getJsonResult() + { + return jsonResult; + } + + public void setJsonResult(String jsonResult) + { + this.jsonResult = jsonResult; + } + + public Integer getStatus() + { + return status; + } + + public void setStatus(Integer status) + { + this.status = status; + } + + public String getErrorMsg() + { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) + { + this.errorMsg = errorMsg; + } + + public Long getOperTime() + { + return operTime; + } + + public void setOperTime(Long operTime) + { + this.operTime = operTime; + } + + public Long getCostTime() + { + return costTime; + } + + public void setCostTime(Long costTime) + { + this.costTime = costTime; + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysPost.java b/ff-base/src/main/java/com/ff/base/system/domain/SysPost.java new file mode 100644 index 0000000..1000220 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysPost.java @@ -0,0 +1,125 @@ +package com.ff.base.system.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.annotation.Excel.ColumnType; +import com.ff.base.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +/** + * 岗位表 sys_post + * + * @author ff + */ +public class SysPost extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 岗位序号 */ + @Excel(name = "岗位序号", cellType = ColumnType.NUMERIC) + private Long postId; + + /** 岗位编码 */ + @Excel(name = "岗位编码") + private String postCode; + + /** 岗位名称 */ + @Excel(name = "岗位名称") + private String postName; + + /** 岗位排序 */ + @Excel(name = "岗位排序") + private Integer postSort; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 用户是否存在此岗位标识 默认不存在 */ + private boolean flag = false; + + public Long getPostId() + { + return postId; + } + + public void setPostId(Long postId) + { + this.postId = postId; + } + + @NotBlank(message = "岗位编码不能为空") + @Size(min = 0, max = 64, message = "岗位编码长度不能超过64个字符") + public String getPostCode() + { + return postCode; + } + + public void setPostCode(String postCode) + { + this.postCode = postCode; + } + + @NotBlank(message = "岗位名称不能为空") + @Size(min = 0, max = 50, message = "岗位名称长度不能超过50个字符") + public String getPostName() + { + return postName; + } + + public void setPostName(String postName) + { + this.postName = postName; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getPostSort() + { + return postSort; + } + + public void setPostSort(Integer postSort) + { + this.postSort = postSort; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public boolean isFlag() + { + return flag; + } + + public void setFlag(boolean flag) + { + this.flag = flag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("postId", getPostId()) + .append("postCode", getPostCode()) + .append("postName", getPostName()) + .append("postSort", getPostSort()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysRole.java b/ff-base/src/main/java/com/ff/base/system/domain/SysRole.java new file mode 100644 index 0000000..22382bc --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysRole.java @@ -0,0 +1,242 @@ +package com.ff.base.system.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.annotation.Excel.ColumnType; +import com.ff.base.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.Set; + +/** + * 角色表 sys_role + * + * @author ff + */ +public class SysRole extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 角色ID */ + @Excel(name = "角色序号", cellType = ColumnType.NUMERIC) + private Long roleId; + + /** 角色名称 */ + @Excel(name = "角色名称") + private String roleName; + + /** 角色权限 */ + @Excel(name = "角色权限") + private String roleKey; + + /** 角色排序 */ + @Excel(name = "角色排序") + private Integer roleSort; + + /** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */ + @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限") + private String dataScope; + + /** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */ + private boolean menuCheckStrictly; + + /** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */ + private boolean deptCheckStrictly; + + /** 角色状态(0正常 1停用) */ + @Excel(name = "角色状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 用户是否存在此角色标识 默认不存在 */ + private boolean flag = false; + + /** 菜单组 */ + private Long[] menuIds; + + /** 部门组(数据权限) */ + private Long[] deptIds; + + /** 角色菜单权限 */ + private Set permissions; + + public SysRole() + { + + } + + public SysRole(Long roleId) + { + this.roleId = roleId; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public boolean isAdmin() + { + return isAdmin(this.roleId); + } + + public static boolean isAdmin(Long roleId) + { + return roleId != null && 1L == roleId; + } + + @NotBlank(message = "角色名称不能为空") + @Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符") + public String getRoleName() + { + return roleName; + } + + public void setRoleName(String roleName) + { + this.roleName = roleName; + } + + @NotBlank(message = "权限字符不能为空") + @Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符") + public String getRoleKey() + { + return roleKey; + } + + public void setRoleKey(String roleKey) + { + this.roleKey = roleKey; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getRoleSort() + { + return roleSort; + } + + public void setRoleSort(Integer roleSort) + { + this.roleSort = roleSort; + } + + public String getDataScope() + { + return dataScope; + } + + public void setDataScope(String dataScope) + { + this.dataScope = dataScope; + } + + public boolean isMenuCheckStrictly() + { + return menuCheckStrictly; + } + + public void setMenuCheckStrictly(boolean menuCheckStrictly) + { + this.menuCheckStrictly = menuCheckStrictly; + } + + public boolean isDeptCheckStrictly() + { + return deptCheckStrictly; + } + + public void setDeptCheckStrictly(boolean deptCheckStrictly) + { + this.deptCheckStrictly = deptCheckStrictly; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public boolean isFlag() + { + return flag; + } + + public void setFlag(boolean flag) + { + this.flag = flag; + } + + public Long[] getMenuIds() + { + return menuIds; + } + + public void setMenuIds(Long[] menuIds) + { + this.menuIds = menuIds; + } + + public Long[] getDeptIds() + { + return deptIds; + } + + public void setDeptIds(Long[] deptIds) + { + this.deptIds = deptIds; + } + + public Set getPermissions() + { + return permissions; + } + + public void setPermissions(Set permissions) + { + this.permissions = permissions; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("roleName", getRoleName()) + .append("roleKey", getRoleKey()) + .append("roleSort", getRoleSort()) + .append("dataScope", getDataScope()) + .append("menuCheckStrictly", isMenuCheckStrictly()) + .append("deptCheckStrictly", isDeptCheckStrictly()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysRoleDept.java b/ff-base/src/main/java/com/ff/base/system/domain/SysRoleDept.java new file mode 100644 index 0000000..ef6a0ef --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysRoleDept.java @@ -0,0 +1,46 @@ +package com.ff.base.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和部门关联 sys_role_dept + * + * @author ff + */ +public class SysRoleDept +{ + /** 角色ID */ + private Long roleId; + + /** 部门ID */ + private Long deptId; + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("deptId", getDeptId()) + .toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysRoleMenu.java b/ff-base/src/main/java/com/ff/base/system/domain/SysRoleMenu.java new file mode 100644 index 0000000..76860b1 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysRoleMenu.java @@ -0,0 +1,46 @@ +package com.ff.base.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和菜单关联 sys_role_menu + * + * @author ff + */ +public class SysRoleMenu +{ + /** 角色ID */ + private Long roleId; + + /** 菜单ID */ + private Long menuId; + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("menuId", getMenuId()) + .toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysUser.java b/ff-base/src/main/java/com/ff/base/system/domain/SysUser.java new file mode 100644 index 0000000..192826d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysUser.java @@ -0,0 +1,352 @@ +package com.ff.base.system.domain; + +import com.ff.base.annotation.Excel; +import com.ff.base.annotation.Excel.ColumnType; +import com.ff.base.annotation.Excel.Type; +import com.ff.base.annotation.Excels; +import com.ff.base.core.domain.BaseEntity; +import com.ff.base.xss.Xss; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * 用户对象 sys_user + * + * @author ff + */ +public class SysUser extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 用户ID */ + @Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号") + private Long userId; + + /** 部门ID */ + @Excel(name = "部门编号", type = Type.IMPORT) + private Long deptId; + + /** 用户账号 */ + @Excel(name = "登录名称") + private String userName; + + /** 用户昵称 */ + @Excel(name = "用户名称") + private String nickName; + + /** 用户邮箱 */ + @Excel(name = "用户邮箱") + private String email; + + /** 手机号码 */ + @Excel(name = "手机号码", cellType = ColumnType.TEXT) + private String phonenumber; + + /** 用户性别 */ + @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知") + private String sex; + + /** 用户头像 */ + private String avatar; + + /** 密码 */ + private String password; + + /** 帐号状态(0正常 1停用) */ + @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 最后登录IP */ + @Excel(name = "最后登录IP", type = Type.EXPORT) + private String loginIp; + + /** 最后登录时间 */ + @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT) + private Long loginDate; + + /** 部门对象 */ + @Excels({ + @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT), + @Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT) + }) + private SysDept dept; + + /** 角色对象 */ + private List roles; + + /** 角色组 */ + private Long[] roleIds; + + /** 岗位组 */ + private Long[] postIds; + + /** 角色ID */ + private Long roleId; + + /** + * 登录类型 0.后台登录 1.前端网页登录 + */ + private Integer loginType; + + /** + * 真实姓名 + */ + private String realName; + + public SysUser() + { + + } + + public SysUser(Long userId) + { + this.userId = userId; + } + + public String getRealName() { + return realName; + } + + public void setRealName(String realName) { + this.realName = realName; + } + + public Integer getLoginType() { + return loginType; + } + + public void setLoginType(Integer loginType) { + this.loginType = loginType; + } + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public boolean isAdmin() + { + return isAdmin(this.userId); + } + + public static boolean isAdmin(Long userId) + { + return userId != null && 1L == userId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + @Xss(message = "用户昵称不能包含脚本字符") + @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符") + public String getNickName() + { + return nickName; + } + + public void setNickName(String nickName) + { + this.nickName = nickName; + } + + @Xss(message = "用户账号不能包含脚本字符") + @NotBlank(message = "用户账号不能为空") + @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符") + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + @Email(message = "邮箱格式不正确") + @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + + @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符") + public String getPhonenumber() + { + return phonenumber; + } + + public void setPhonenumber(String phonenumber) + { + this.phonenumber = phonenumber; + } + + public String getSex() + { + return sex; + } + + public void setSex(String sex) + { + this.sex = sex; + } + + public String getAvatar() + { + return avatar; + } + + public void setAvatar(String avatar) + { + this.avatar = avatar; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getLoginIp() + { + return loginIp; + } + + public void setLoginIp(String loginIp) + { + this.loginIp = loginIp; + } + + public Long getLoginDate() + { + return loginDate; + } + + public void setLoginDate(Long loginDate) + { + this.loginDate = loginDate; + } + + public SysDept getDept() + { + return dept; + } + + public void setDept(SysDept dept) + { + this.dept = dept; + } + + public List getRoles() + { + return roles; + } + + public void setRoles(List roles) + { + this.roles = roles; + } + + public Long[] getRoleIds() + { + return roleIds; + } + + public void setRoleIds(Long[] roleIds) + { + this.roleIds = roleIds; + } + + public Long[] getPostIds() + { + return postIds; + } + + public void setPostIds(Long[] postIds) + { + this.postIds = postIds; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("deptId", getDeptId()) + .append("userName", getUserName()) + .append("nickName", getNickName()) + .append("email", getEmail()) + .append("phonenumber", getPhonenumber()) + .append("sex", getSex()) + .append("avatar", getAvatar()) + .append("password", getPassword()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("loginIp", getLoginIp()) + .append("loginDate", getLoginDate()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .append("dept", getDept()) + .toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysUserOnline.java b/ff-base/src/main/java/com/ff/base/system/domain/SysUserOnline.java new file mode 100644 index 0000000..8d879d2 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysUserOnline.java @@ -0,0 +1,113 @@ +package com.ff.base.system.domain; + +/** + * 当前在线会话 + * + * @author ff + */ +public class SysUserOnline +{ + /** 会话编号 */ + private String tokenId; + + /** 部门名称 */ + private String deptName; + + /** 用户名称 */ + private String userName; + + /** 登录IP地址 */ + private String ipaddr; + + /** 登录地址 */ + private String loginLocation; + + /** 浏览器类型 */ + private String browser; + + /** 操作系统 */ + private String os; + + /** 登录时间 */ + private Long loginTime; + + public String getTokenId() + { + return tokenId; + } + + public void setTokenId(String tokenId) + { + this.tokenId = tokenId; + } + + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysUserPost.java b/ff-base/src/main/java/com/ff/base/system/domain/SysUserPost.java new file mode 100644 index 0000000..0cf5688 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysUserPost.java @@ -0,0 +1,46 @@ +package com.ff.base.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和岗位关联 sys_user_post + * + * @author ff + */ +public class SysUserPost +{ + /** 用户ID */ + private Long userId; + + /** 岗位ID */ + private Long postId; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getPostId() + { + return postId; + } + + public void setPostId(Long postId) + { + this.postId = postId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("postId", getPostId()) + .toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/SysUserRole.java b/ff-base/src/main/java/com/ff/base/system/domain/SysUserRole.java new file mode 100644 index 0000000..5563642 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/SysUserRole.java @@ -0,0 +1,46 @@ +package com.ff.base.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和角色关联 sys_user_role + * + * @author ff + */ +public class SysUserRole +{ + /** 用户ID */ + private Long userId; + + /** 角色ID */ + private Long roleId; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("roleId", getRoleId()) + .toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/vo/MetaVo.java b/ff-base/src/main/java/com/ff/base/system/domain/vo/MetaVo.java new file mode 100644 index 0000000..cebed56 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/vo/MetaVo.java @@ -0,0 +1,106 @@ +package com.ff.base.system.domain.vo; + +import com.ff.base.utils.StringUtils; + +/** + * 路由显示信息 + * + * @author ff + */ +public class MetaVo +{ + /** + * 设置该路由在侧边栏和面包屑中展示的名字 + */ + private String title; + + /** + * 设置该路由的图标,对应路径src/assets/icons/svg + */ + private String icon; + + /** + * 设置为true,则不会被 缓存 + */ + private boolean noCache; + + /** + * 内链地址(http(s)://开头) + */ + private String link; + + public MetaVo() + { + } + + public MetaVo(String title, String icon) + { + this.title = title; + this.icon = icon; + } + + public MetaVo(String title, String icon, boolean noCache) + { + this.title = title; + this.icon = icon; + this.noCache = noCache; + } + + public MetaVo(String title, String icon, String link) + { + this.title = title; + this.icon = icon; + this.link = link; + } + + public MetaVo(String title, String icon, boolean noCache, String link) + { + this.title = title; + this.icon = icon; + this.noCache = noCache; + if (StringUtils.ishttp(link)) + { + this.link = link; + } + } + + public boolean isNoCache() + { + return noCache; + } + + public void setNoCache(boolean noCache) + { + this.noCache = noCache; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getIcon() + { + return icon; + } + + public void setIcon(String icon) + { + this.icon = icon; + } + + public String getLink() + { + return link; + } + + public void setLink(String link) + { + this.link = link; + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/domain/vo/RouterVo.java b/ff-base/src/main/java/com/ff/base/system/domain/vo/RouterVo.java new file mode 100644 index 0000000..352cf6e --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/domain/vo/RouterVo.java @@ -0,0 +1,149 @@ +package com.ff.base.system.domain.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import java.util.List; + +/** + * 路由配置信息 + * + * @author ff + */ +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class RouterVo +{ + /** + * 路由名字 + */ + private String name; + + /** + * 路由地址 + */ + private String path; + + /** + * 是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现 + */ + private boolean hidden; + + /** + * 重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 + */ + private String redirect; + + /** + * 组件地址 + */ + private String component; + + /** + * 路由参数:如 {"id": 1, "name": "ry"} + */ + private String query; + + /** + * 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 + */ + private Boolean alwaysShow; + + /** + * 其他元素 + */ + private MetaVo meta; + + /** + * 子路由 + */ + private List children; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getPath() + { + return path; + } + + public void setPath(String path) + { + this.path = path; + } + + public boolean getHidden() + { + return hidden; + } + + public void setHidden(boolean hidden) + { + this.hidden = hidden; + } + + public String getRedirect() + { + return redirect; + } + + public void setRedirect(String redirect) + { + this.redirect = redirect; + } + + public String getComponent() + { + return component; + } + + public void setComponent(String component) + { + this.component = component; + } + + public String getQuery() + { + return query; + } + + public void setQuery(String query) + { + this.query = query; + } + + public Boolean getAlwaysShow() + { + return alwaysShow; + } + + public void setAlwaysShow(Boolean alwaysShow) + { + this.alwaysShow = alwaysShow; + } + + public MetaVo getMeta() + { + return meta; + } + + public void setMeta(MetaVo meta) + { + this.meta = meta; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysConfigMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysConfigMapper.java new file mode 100644 index 0000000..10e0888 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysConfigMapper.java @@ -0,0 +1,85 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysConfig; + +import java.util.List; + +/** + * 参数配置 数据层 + * + * @author ff + */ +public interface SysConfigMapper +{ + /** + * 查询参数配置信息 + * + * @param config 参数配置信息 + * @return 参数配置信息 + */ + public SysConfig selectConfig(SysConfig config); + + /** + * 通过ID查询配置 + * + * @param configId 参数ID + * @return 参数配置信息 + */ + public SysConfig selectConfigById(Long configId); + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + public List selectConfigList(SysConfig config); + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数键名 + * @return 参数配置信息 + */ + public SysConfig checkConfigKeyUnique(String configKey); + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int insertConfig(SysConfig config); + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int updateConfig(SysConfig config); + + /** + * 删除参数配置 + * + * @param configId 参数ID + * @return 结果 + */ + public int deleteConfigById(Long configId); + + /** + * 按键更新配置 + * + * @param config config + * @return int + */ + int updateConfigByKey(SysConfig config); + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + * @return 结果 + */ + public int deleteConfigByIds(Long[] configIds); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysDatasourceMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysDatasourceMapper.java new file mode 100644 index 0000000..7f014a3 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysDatasourceMapper.java @@ -0,0 +1,70 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysDatasource; + +import java.util.List; + +/** + * 租户数据源Mapper接口 + * + * @author liukang + * @date 2024-11-20 + */ +public interface SysDatasourceMapper +{ + /** + * 查询租户数据源 + * + * @param id 租户数据源主键 + * @return 租户数据源 + */ + public SysDatasource selectSysDatasourceById(Long id); + + /** + * 按租户id选择sys数据源 + * + * @param id 身份证件 + * @return {@link SysDatasource } + */ + SysDatasource selectSysDatasourceByTenantId(String id); + + /** + * 查询租户数据源列表 + * + * @param sysDatasource 租户数据源 + * @return 租户数据源集合 + */ + public List selectSysDatasourceList(SysDatasource sysDatasource); + + /** + * 新增租户数据源 + * + * @param sysDatasource 租户数据源 + * @return 结果 + */ + public int insertSysDatasource(SysDatasource sysDatasource); + + /** + * 修改租户数据源 + * + * @param sysDatasource 租户数据源 + * @return 结果 + */ + public int updateSysDatasource(SysDatasource sysDatasource); + + /** + * 删除租户数据源 + * + * @param id 租户数据源主键 + * @return 结果 + */ + public int deleteSysDatasourceById(Long id); + + /** + * 批量删除租户数据源 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysDatasourceByIds(Long[] ids); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysDeptMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysDeptMapper.java new file mode 100644 index 0000000..738d484 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysDeptMapper.java @@ -0,0 +1,119 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysDept; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 部门管理 数据层 + * + * @author ff + */ +public interface SysDeptMapper +{ + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + public List selectDeptList(SysDept dept); + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @param deptCheckStrictly 部门树选择项是否关联显示 + * @return 选中部门列表 + */ + public List selectDeptListByRoleId(@Param("roleId") Long roleId, @Param("deptCheckStrictly") boolean deptCheckStrictly); + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 根据ID查询所有子部门 + * + * @param deptId 部门ID + * @return 部门列表 + */ + public List selectChildrenDeptById(Long deptId); + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + public int selectNormalChildrenDeptById(Long deptId); + + /** + * 是否存在子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + public int hasChildByDeptId(Long deptId); + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 + */ + public int checkDeptExistUser(Long deptId); + + /** + * 校验部门名称是否唯一 + * + * @param deptName 部门名称 + * @param parentId 父部门ID + * @return 结果 + */ + public SysDept checkDeptNameUnique(@Param("deptName") String deptName, @Param("parentId") Long parentId); + + /** + * 新增部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int insertDept(SysDept dept); + + /** + * 修改部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int updateDept(SysDept dept); + + /** + * 修改所在部门正常状态 + * + * @param deptIds 部门ID组 + */ + public void updateDeptStatusNormal(Long[] deptIds); + + /** + * 修改子元素关系 + * + * @param depts 子元素 + * @return 结果 + */ + public int updateDeptChildren(@Param("depts") List depts); + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + public int deleteDeptById(Long deptId); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysDictDataMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysDictDataMapper.java new file mode 100644 index 0000000..6d27f87 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysDictDataMapper.java @@ -0,0 +1,96 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysDictData; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 字典表 数据层 + * + * @author ff + */ +public interface SysDictDataMapper +{ + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + public List selectDictDataList(SysDictData dictData); + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + public List selectDictDataByType(String dictType); + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + public String selectDictLabel(@Param("dictType") String dictType, @Param("dictValue") String dictValue); + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + public SysDictData selectDictDataById(Long dictCode); + + /** + * 查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据 + */ + public int countDictDataByType(String dictType); + + /** + * 通过字典ID删除字典数据信息 + * + * @param dictCode 字典数据ID + * @return 结果 + */ + public int deleteDictDataById(Long dictCode); + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + * @return 结果 + */ + public int deleteDictDataByIds(Long[] dictCodes); + + /** + * 新增字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int insertDictData(SysDictData dictData); + + /** + * 修改字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int updateDictData(SysDictData dictData); + + /** + * 同步修改字典类型 + * + * @param oldDictType 旧字典类型 + * @param newDictType 新旧字典类型 + * @return 结果 + */ + public int updateDictDataType(@Param("oldDictType") String oldDictType, @Param("newDictType") String newDictType); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysDictTypeMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysDictTypeMapper.java new file mode 100644 index 0000000..426509a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysDictTypeMapper.java @@ -0,0 +1,84 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysDictType; + +import java.util.List; + +/** + * 字典表 数据层 + * + * @author ff + */ +public interface SysDictTypeMapper +{ + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + public List selectDictTypeList(SysDictType dictType); + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + public List selectDictTypeAll(); + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + public SysDictType selectDictTypeById(Long dictId); + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + public SysDictType selectDictTypeByType(String dictType); + + /** + * 通过字典ID删除字典信息 + * + * @param dictId 字典ID + * @return 结果 + */ + public int deleteDictTypeById(Long dictId); + + /** + * 批量删除字典类型信息 + * + * @param dictIds 需要删除的字典ID + * @return 结果 + */ + public int deleteDictTypeByIds(Long[] dictIds); + + /** + * 新增字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int insertDictType(SysDictType dictType); + + /** + * 修改字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int updateDictType(SysDictType dictType); + + /** + * 校验字典类型称是否唯一 + * + * @param dictType 字典类型 + * @return 结果 + */ + public SysDictType checkDictTypeUnique(String dictType); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysLogininforMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysLogininforMapper.java new file mode 100644 index 0000000..de4ab84 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysLogininforMapper.java @@ -0,0 +1,43 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysLogininfor; + +import java.util.List; + +/** + * 系统访问日志情况信息 数据层 + * + * @author ff + */ +public interface SysLogininforMapper +{ + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + public void insertLogininfor(SysLogininfor logininfor); + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + public List selectLogininforList(SysLogininfor logininfor); + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 清空系统登录日志 + * + * @return 结果 + */ + public int cleanLogininfor(); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysMenuMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysMenuMapper.java new file mode 100644 index 0000000..37b24b5 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysMenuMapper.java @@ -0,0 +1,126 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysMenu; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 菜单表 数据层 + * + * @author ff + */ +public interface SysMenuMapper +{ + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuList(SysMenu menu); + + /** + * 根据用户所有权限 + * + * @return 权限列表 + */ + public List selectMenuPerms(); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuListByUserId(SysMenu menu); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public List selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public List selectMenuPermsByUserId(Long userId); + + /** + * 根据用户ID查询菜单 + * + * @return 菜单列表 + */ + public List selectMenuTreeAll(); + + /** + * 根据用户ID查询菜单 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @param menuCheckStrictly 菜单树选择项是否关联显示 + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly); + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + public SysMenu selectMenuById(Long menuId); + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int hasChildByMenuId(Long menuId); + + /** + * 新增菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int insertMenu(SysMenu menu); + + /** + * 修改菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int updateMenu(SysMenu menu); + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int deleteMenuById(Long menuId); + + /** + * 校验菜单名称是否唯一 + * + * @param menuName 菜单名称 + * @param parentId 父菜单ID + * @return 结果 + */ + public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysOperLogMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysOperLogMapper.java new file mode 100644 index 0000000..394ea97 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysOperLogMapper.java @@ -0,0 +1,49 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysOperLog; + +import java.util.List; + +/** + * 操作日志 数据层 + * + * @author ff + */ +public interface SysOperLogMapper +{ + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + */ + public void insertOperlog(SysOperLog operLog); + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + public List selectOperLogList(SysOperLog operLog); + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + public int deleteOperLogByIds(Long[] operIds); + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + public SysOperLog selectOperLogById(Long operId); + + /** + * 清空操作日志 + */ + public void cleanOperLog(); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysPostMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysPostMapper.java new file mode 100644 index 0000000..3fb4b4d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysPostMapper.java @@ -0,0 +1,100 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysPost; + +import java.util.List; + +/** + * 岗位信息 数据层 + * + * @author ff + */ +public interface SysPostMapper +{ + /** + * 查询岗位数据集合 + * + * @param post 岗位信息 + * @return 岗位数据集合 + */ + public List selectPostList(SysPost post); + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + public List selectPostAll(); + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + public SysPost selectPostById(Long postId); + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + public List selectPostListByUserId(Long userId); + + /** + * 查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + public List selectPostsByUserName(String userName); + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + public int deletePostById(Long postId); + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + public int deletePostByIds(Long[] postIds); + + /** + * 修改岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int updatePost(SysPost post); + + /** + * 新增岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int insertPost(SysPost post); + + /** + * 校验岗位名称 + * + * @param postName 岗位名称 + * @return 结果 + */ + public SysPost checkPostNameUnique(String postName); + + /** + * 校验岗位编码 + * + * @param postCode 岗位编码 + * @return 结果 + */ + public SysPost checkPostCodeUnique(String postCode); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysRoleDeptMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysRoleDeptMapper.java new file mode 100644 index 0000000..206c13c --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysRoleDeptMapper.java @@ -0,0 +1,45 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysRoleDept; + +import java.util.List; + +/** + * 角色与部门关联表 数据层 + * + * @author ff + */ +public interface SysRoleDeptMapper +{ + /** + * 通过角色ID删除角色和部门关联 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleDeptByRoleId(Long roleId); + + /** + * 批量删除角色部门关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteRoleDept(Long[] ids); + + /** + * 查询部门使用数量 + * + * @param deptId 部门ID + * @return 结果 + */ + public int selectCountRoleDeptByDeptId(Long deptId); + + /** + * 批量新增角色部门信息 + * + * @param roleDeptList 角色部门列表 + * @return 结果 + */ + public int batchRoleDept(List roleDeptList); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysRoleMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysRoleMapper.java new file mode 100644 index 0000000..d3f0838 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysRoleMapper.java @@ -0,0 +1,108 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysRole; + +import java.util.List; + +/** + * 角色表 数据层 + * + * @author ff + */ +public interface SysRoleMapper +{ + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + public List selectRoleList(SysRole role); + + /** + * 根据用户ID查询角色 + * + * @param userId 用户ID + * @return 角色列表 + */ + public List selectRolePermissionByUserId(Long userId); + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + public List selectRoleAll(); + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + public List selectRoleListByUserId(Long userId); + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 根据用户ID查询角色 + * + * @param userName 用户名 + * @return 角色列表 + */ + public List selectRolesByUserName(String userName); + + /** + * 校验角色名称是否唯一 + * + * @param roleName 角色名称 + * @return 角色信息 + */ + public SysRole checkRoleNameUnique(String roleName); + + /** + * 校验角色权限是否唯一 + * + * @param roleKey 角色权限 + * @return 角色信息 + */ + public SysRole checkRoleKeyUnique(String roleKey); + + /** + * 修改角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRole(SysRole role); + + /** + * 新增角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int insertRole(SysRole role); + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleById(Long roleId); + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + public int deleteRoleByIds(Long[] roleIds); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysRoleMenuMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysRoleMenuMapper.java new file mode 100644 index 0000000..4dea34c --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysRoleMenuMapper.java @@ -0,0 +1,45 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysRoleMenu; + +import java.util.List; + +/** + * 角色与菜单关联表 数据层 + * + * @author ff + */ +public interface SysRoleMenuMapper +{ + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int checkMenuExistRole(Long menuId); + + /** + * 通过角色ID删除角色和菜单关联 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleMenuByRoleId(Long roleId); + + /** + * 批量删除角色菜单关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteRoleMenu(Long[] ids); + + /** + * 批量新增角色菜单信息 + * + * @param roleMenuList 角色菜单列表 + * @return 结果 + */ + public int batchRoleMenu(List roleMenuList); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysUserMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysUserMapper.java new file mode 100644 index 0000000..c00d956 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysUserMapper.java @@ -0,0 +1,135 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysUser; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 用户表 数据层 + * + * @author ff + */ +public interface SysUserMapper +{ + /** + * 根据条件分页查询用户列表 + * + * @param sysUser 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser sysUser); + + /** + * 根据条件分页查询已配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + public SysUser selectUserById(Long userId); + + /** + * 新增用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int insertUser(SysUser user); + + /** + * 修改用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUser(SysUser user); + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar); + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + public int resetUserPwd(@Param("userName") String userName, @Param("password") String password); + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserById(Long userId); + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 校验用户名称是否唯一 + * + * @param userName 用户名称 + * @return 结果 + */ + public SysUser checkUserNameUnique(String userName); + + /** + * 校验手机号码是否唯一 + * + * @param phonenumber 手机号码 + * @return 结果 + */ + public SysUser checkPhoneUnique(String phonenumber); + + /** + * 校验email是否唯一 + * + * @param email 用户邮箱 + * @return 结果 + */ + public SysUser checkEmailUnique(String email); + + /** + * 根据账号名/手机号查询会员用户 + * @param accountName 账号名/手机号 + * @return 会员用户 + */ + SysUser selectMemberUserByUserName(String accountName); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysUserPostMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysUserPostMapper.java new file mode 100644 index 0000000..780aa49 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysUserPostMapper.java @@ -0,0 +1,45 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysUserPost; + +import java.util.List; + +/** + * 用户与岗位关联表 数据层 + * + * @author ff + */ +public interface SysUserPostMapper +{ + /** + * 通过用户ID删除用户和岗位关联 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserPostByUserId(Long userId); + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + public int countUserPostById(Long postId); + + /** + * 批量删除用户和岗位关联 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteUserPost(Long[] ids); + + /** + * 批量新增用户岗位信息 + * + * @param userPostList 用户岗位列表 + * @return 结果 + */ + public int batchUserPost(List userPostList); +} diff --git a/ff-base/src/main/java/com/ff/base/system/mapper/SysUserRoleMapper.java b/ff-base/src/main/java/com/ff/base/system/mapper/SysUserRoleMapper.java new file mode 100644 index 0000000..b632820 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/mapper/SysUserRoleMapper.java @@ -0,0 +1,63 @@ +package com.ff.base.system.mapper; + +import com.ff.base.system.domain.SysUserRole; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 用户与角色关联表 数据层 + * + * @author ff + */ +public interface SysUserRoleMapper +{ + /** + * 通过用户ID删除用户和角色关联 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserRoleByUserId(Long userId); + + /** + * 批量删除用户和角色关联 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteUserRole(Long[] ids); + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + public int countUserRoleByRoleId(Long roleId); + + /** + * 批量新增用户角色信息 + * + * @param userRoleList 用户角色列表 + * @return 结果 + */ + public int batchUserRole(List userRoleList); + + /** + * 删除用户和角色关联信息 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + public int deleteUserRoleInfo(SysUserRole userRole); + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要删除的用户数据ID + * @return 结果 + */ + public int deleteUserRoleInfos(@Param("roleId") Long roleId, @Param("userIds") Long[] userIds); +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/ISysConfigService.java b/ff-base/src/main/java/com/ff/base/system/service/ISysConfigService.java new file mode 100644 index 0000000..36cb477 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/ISysConfigService.java @@ -0,0 +1,98 @@ +package com.ff.base.system.service; + +import com.ff.base.system.domain.SysConfig; + +import java.util.List; + +/** + * 参数配置 服务层 + * + * @author ff + */ +public interface ISysConfigService +{ + /** + * 查询参数配置信息 + * + * @param configId 参数配置ID + * @return 参数配置信息 + */ + public SysConfig selectConfigById(Long configId); + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数键名 + * @return 参数键值 + */ + public String selectConfigByKey(String configKey); + + /** + * 获取验证码开关 + * + * @return true开启,false关闭 + */ + public boolean selectCaptchaEnabled(); + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + public List selectConfigList(SysConfig config); + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int insertConfig(SysConfig config); + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int updateConfig(SysConfig config); + + /** + * 按键更新配置 + * + * @param config config + * @return int + */ + int updateConfigByKey(SysConfig config); + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + */ + public void deleteConfigByIds(Long[] configIds); + + /** + * 加载参数缓存数据 + */ + public void loadingConfigCache(); + + /** + * 清空参数缓存数据 + */ + public void clearConfigCache(); + + /** + * 重置参数缓存数据 + */ + public void resetConfigCache(); + + /** + * 校验参数键名是否唯一 + * + * @param config 参数信息 + * @return 结果 + */ + public boolean checkConfigKeyUnique(SysConfig config); +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/ISysDatasourceService.java b/ff-base/src/main/java/com/ff/base/system/service/ISysDatasourceService.java new file mode 100644 index 0000000..fd31416 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/ISysDatasourceService.java @@ -0,0 +1,78 @@ +package com.ff.base.system.service; + +import com.ff.base.system.domain.SysDatasource; + +import java.util.List; + +/** + * 租户数据源Service接口 + * + * @author liukang + * @date 2024-11-20 + */ +public interface ISysDatasourceService +{ + /** + * 查询租户数据源 + * + * @param id 租户数据源主键 + * @return 租户数据源 + */ + public SysDatasource selectSysDatasourceById(Long id); + + + /** + * 按租户id选择sys数据源 + * + * @param id 身份证件 + * @return {@link SysDatasource } + */ + String selectSysDatasourceByTenantId(String id); + + /** + * 获取租户时区名称 + * @param id 租户id + * @return 时区名称 + */ + String selectTimeZoneNameByTenantId(String id); + + /** + * 查询租户数据源列表 + * + * @param sysDatasource 租户数据源 + * @return 租户数据源集合 + */ + public List selectSysDatasourceList(SysDatasource sysDatasource); + + /** + * 新增租户数据源 + * + * @param sysDatasource 租户数据源 + * @return 结果 + */ + public int insertSysDatasource(SysDatasource sysDatasource); + + /** + * 修改租户数据源 + * + * @param sysDatasource 租户数据源 + * @return 结果 + */ + public int updateSysDatasource(SysDatasource sysDatasource); + + /** + * 批量删除租户数据源 + * + * @param ids 需要删除的租户数据源主键集合 + * @return 结果 + */ + public int deleteSysDatasourceByIds(Long[] ids); + + /** + * 删除租户数据源信息 + * + * @param id 租户数据源主键 + * @return 结果 + */ + public int deleteSysDatasourceById(Long id); +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/ISysDeptService.java b/ff-base/src/main/java/com/ff/base/system/service/ISysDeptService.java new file mode 100644 index 0000000..7ba88fc --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/ISysDeptService.java @@ -0,0 +1,125 @@ +package com.ff.base.system.service; + +import com.ff.base.core.domain.TreeSelect; +import com.ff.base.system.domain.SysDept; + +import java.util.List; + +/** + * 部门管理 服务层 + * + * @author ff + */ +public interface ISysDeptService +{ + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + public List selectDeptList(SysDept dept); + + /** + * 查询部门树结构信息 + * + * @param dept 部门信息 + * @return 部门树信息集合 + */ + public List selectDeptTreeList(SysDept dept); + + /** + * 构建前端所需要树结构 + * + * @param depts 部门列表 + * @return 树结构列表 + */ + public List buildDeptTree(List depts); + + /** + * 构建前端所需要下拉树结构 + * + * @param depts 部门列表 + * @return 下拉树结构列表 + */ + public List buildDeptTreeSelect(List depts); + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @return 选中部门列表 + */ + public List selectDeptListByRoleId(Long roleId); + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + public int selectNormalChildrenDeptById(Long deptId); + + /** + * 是否存在部门子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + public boolean hasChildByDeptId(Long deptId); + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 true 存在 false 不存在 + */ + public boolean checkDeptExistUser(Long deptId); + + /** + * 校验部门名称是否唯一 + * + * @param dept 部门信息 + * @return 结果 + */ + public boolean checkDeptNameUnique(SysDept dept); + + /** + * 校验部门是否有数据权限 + * + * @param deptId 部门id + */ + public void checkDeptDataScope(Long deptId); + + /** + * 新增保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int insertDept(SysDept dept); + + /** + * 修改保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int updateDept(SysDept dept); + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + public int deleteDeptById(Long deptId); +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/ISysDictDataService.java b/ff-base/src/main/java/com/ff/base/system/service/ISysDictDataService.java new file mode 100644 index 0000000..cacaf1b --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/ISysDictDataService.java @@ -0,0 +1,61 @@ +package com.ff.base.system.service; + +import com.ff.base.system.domain.SysDictData; + +import java.util.List; + +/** + * 字典 业务层 + * + * @author ff + */ +public interface ISysDictDataService +{ + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + public List selectDictDataList(SysDictData dictData); + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + public String selectDictLabel(String dictType, String dictValue); + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + public SysDictData selectDictDataById(Long dictCode); + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + */ + public void deleteDictDataByIds(Long[] dictCodes); + + /** + * 新增保存字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int insertDictData(SysDictData dictData); + + /** + * 修改保存字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int updateDictData(SysDictData dictData); +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/ISysDictTypeService.java b/ff-base/src/main/java/com/ff/base/system/service/ISysDictTypeService.java new file mode 100644 index 0000000..aa52ae2 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/ISysDictTypeService.java @@ -0,0 +1,99 @@ +package com.ff.base.system.service; + +import com.ff.base.system.domain.SysDictData; +import com.ff.base.system.domain.SysDictType; + +import java.util.List; + +/** + * 字典 业务层 + * + * @author ff + */ +public interface ISysDictTypeService +{ + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + public List selectDictTypeList(SysDictType dictType); + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + public List selectDictTypeAll(); + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + public List selectDictDataByType(String dictType); + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + public SysDictType selectDictTypeById(Long dictId); + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + public SysDictType selectDictTypeByType(String dictType); + + /** + * 批量删除字典信息 + * + * @param dictIds 需要删除的字典ID + */ + public void deleteDictTypeByIds(Long[] dictIds); + + /** + * 加载字典缓存数据 + */ + public void loadingDictCache(); + + /** + * 清空字典缓存数据 + */ + public void clearDictCache(); + + /** + * 重置字典缓存数据 + */ + public void resetDictCache(); + + /** + * 新增保存字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int insertDictType(SysDictType dictType); + + /** + * 修改保存字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int updateDictType(SysDictType dictType); + + /** + * 校验字典类型称是否唯一 + * + * @param dictType 字典类型 + * @return 结果 + */ + public boolean checkDictTypeUnique(SysDictType dictType); +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/ISysLogininforService.java b/ff-base/src/main/java/com/ff/base/system/service/ISysLogininforService.java new file mode 100644 index 0000000..a5c9ec4 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/ISysLogininforService.java @@ -0,0 +1,41 @@ +package com.ff.base.system.service; + +import com.ff.base.system.domain.SysLogininfor; + +import java.util.List; + +/** + * 系统访问日志情况信息 服务层 + * + * @author ff + */ +public interface ISysLogininforService +{ + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + public void insertLogininfor(SysLogininfor logininfor); + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + public List selectLogininforList(SysLogininfor logininfor); + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 清空系统登录日志 + */ + public void cleanLogininfor(); +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/ISysMenuService.java b/ff-base/src/main/java/com/ff/base/system/service/ISysMenuService.java new file mode 100644 index 0000000..55d9f89 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/ISysMenuService.java @@ -0,0 +1,145 @@ +package com.ff.base.system.service; + +import com.ff.base.core.domain.TreeSelect; +import com.ff.base.system.domain.SysMenu; +import com.ff.base.system.domain.vo.RouterVo; + +import java.util.List; +import java.util.Set; + +/** + * 菜单 业务层 + * + * @author ff + */ +public interface ISysMenuService +{ + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(Long userId); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(SysMenu menu, Long userId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public Set selectMenuPermsByUserId(Long userId); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public Set selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询菜单树信息 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(Long roleId); + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + public List buildMenus(List menus); + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + public List buildMenuTree(List menus); + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + public List buildMenuTreeSelect(List menus); + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + public SysMenu selectMenuById(Long menuId); + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 true 存在 false 不存在 + */ + public boolean hasChildByMenuId(Long menuId); + + /** + * 查询菜单是否存在角色 + * + * @param menuId 菜单ID + * @return 结果 true 存在 false 不存在 + */ + public boolean checkMenuExistRole(Long menuId); + + /** + * 新增保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int insertMenu(SysMenu menu); + + /** + * 修改保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int updateMenu(SysMenu menu); + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int deleteMenuById(Long menuId); + + /** + * 校验菜单名称是否唯一 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean checkMenuNameUnique(SysMenu menu); +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/ISysOperLogService.java b/ff-base/src/main/java/com/ff/base/system/service/ISysOperLogService.java new file mode 100644 index 0000000..6b2dce5 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/ISysOperLogService.java @@ -0,0 +1,49 @@ +package com.ff.base.system.service; + +import com.ff.base.system.domain.SysOperLog; + +import java.util.List; + +/** + * 操作日志 服务层 + * + * @author ff + */ +public interface ISysOperLogService +{ + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + */ + public void insertOperlog(SysOperLog operLog); + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + public List selectOperLogList(SysOperLog operLog); + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + public int deleteOperLogByIds(Long[] operIds); + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + public SysOperLog selectOperLogById(Long operId); + + /** + * 清空操作日志 + */ + public void cleanOperLog(); +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/ISysPostService.java b/ff-base/src/main/java/com/ff/base/system/service/ISysPostService.java new file mode 100644 index 0000000..a4fcb78 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/ISysPostService.java @@ -0,0 +1,100 @@ +package com.ff.base.system.service; + +import com.ff.base.system.domain.SysPost; + +import java.util.List; + +/** + * 岗位信息 服务层 + * + * @author ff + */ +public interface ISysPostService +{ + /** + * 查询岗位信息集合 + * + * @param post 岗位信息 + * @return 岗位列表 + */ + public List selectPostList(SysPost post); + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + public List selectPostAll(); + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + public SysPost selectPostById(Long postId); + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + public List selectPostListByUserId(Long userId); + + /** + * 校验岗位名称 + * + * @param post 岗位信息 + * @return 结果 + */ + public boolean checkPostNameUnique(SysPost post); + + /** + * 校验岗位编码 + * + * @param post 岗位信息 + * @return 结果 + */ + public boolean checkPostCodeUnique(SysPost post); + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + public int countUserPostById(Long postId); + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + public int deletePostById(Long postId); + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + public int deletePostByIds(Long[] postIds); + + /** + * 新增保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int insertPost(SysPost post); + + /** + * 修改保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int updatePost(SysPost post); +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/ISysRoleService.java b/ff-base/src/main/java/com/ff/base/system/service/ISysRoleService.java new file mode 100644 index 0000000..b2dac0d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/ISysRoleService.java @@ -0,0 +1,174 @@ +package com.ff.base.system.service; + +import com.ff.base.system.domain.SysRole; +import com.ff.base.system.domain.SysUserRole; + +import java.util.List; +import java.util.Set; + +/** + * 角色业务层 + * + * @author ff + */ +public interface ISysRoleService +{ + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + public List selectRoleList(SysRole role); + + /** + * 根据用户ID查询角色列表 + * + * @param userId 用户ID + * @return 角色列表 + */ + public List selectRolesByUserId(Long userId); + + /** + * 根据用户ID查询角色权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public Set selectRolePermissionByUserId(Long userId); + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + public List selectRoleAll(); + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + public List selectRoleListByUserId(Long userId); + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 校验角色名称是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + public boolean checkRoleNameUnique(SysRole role); + + /** + * 校验角色权限是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + public boolean checkRoleKeyUnique(SysRole role); + + /** + * 校验角色是否允许操作 + * + * @param role 角色信息 + */ + public void checkRoleAllowed(SysRole role); + + /** + * 校验角色是否有数据权限 + * + * @param roleIds 角色id + */ + public void checkRoleDataScope(Long... roleIds); + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + public int countUserRoleByRoleId(Long roleId); + + /** + * 新增保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int insertRole(SysRole role); + + /** + * 修改保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRole(SysRole role); + + /** + * 修改角色状态 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRoleStatus(SysRole role); + + /** + * 修改数据权限信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int authDataScope(SysRole role); + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleById(Long roleId); + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + public int deleteRoleByIds(Long[] roleIds); + + /** + * 取消授权用户角色 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + public int deleteAuthUser(SysUserRole userRole); + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要取消授权的用户数据ID + * @return 结果 + */ + public int deleteAuthUsers(Long roleId, Long[] userIds); + + /** + * 批量选择授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要删除的用户数据ID + * @return 结果 + */ + public int insertAuthUsers(Long roleId, Long[] userIds); +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/ISysUserOnlineService.java b/ff-base/src/main/java/com/ff/base/system/service/ISysUserOnlineService.java new file mode 100644 index 0000000..2163693 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/ISysUserOnlineService.java @@ -0,0 +1,48 @@ +package com.ff.base.system.service; + +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.system.domain.SysUserOnline; + +/** + * 在线用户 服务层 + * + * @author ff + */ +public interface ISysUserOnlineService +{ + /** + * 通过登录地址查询信息 + * + * @param ipaddr 登录地址 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user); + + /** + * 通过用户名称查询信息 + * + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByUserName(String userName, LoginUser user); + + /** + * 通过登录地址/用户名称查询信息 + * + * @param ipaddr 登录地址 + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user); + + /** + * 设置在线用户信息 + * + * @param user 用户信息 + * @return 在线用户 + */ + public SysUserOnline loginUserToUserOnline(LoginUser user); +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/ISysUserService.java b/ff-base/src/main/java/com/ff/base/system/service/ISysUserService.java new file mode 100644 index 0000000..883627d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/ISysUserService.java @@ -0,0 +1,214 @@ +package com.ff.base.system.service; + +import com.ff.base.system.domain.SysUser; + +import java.util.List; + +/** + * 用户 业务层 + * + * @author ff + */ +public interface ISysUserService +{ + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser user); + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + public SysUser selectUserById(Long userId); + + /** + * 根据用户ID查询用户所属角色组 + * + * @param userName 用户名 + * @return 结果 + */ + public String selectUserRoleGroup(String userName); + + /** + * 根据用户ID查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + public String selectUserPostGroup(String userName); + + /** + * 校验用户名称是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkUserNameUnique(SysUser user); + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkPhoneUnique(SysUser user); + + /** + * 校验email是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkEmailUnique(SysUser user); + + /** + * 校验用户是否允许操作 + * + * @param user 用户信息 + */ + public void checkUserAllowed(SysUser user); + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + public void checkUserDataScope(Long userId); + + /** + * 新增用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int insertUser(SysUser user); + + /** + * 注册用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean registerUser(SysUser user); + + /** + * 修改用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUser(SysUser user); + + /** + * 用户授权角色 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserAuth(Long userId, Long[] roleIds); + + /** + * 修改用户状态 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUserStatus(SysUser user); + + /** + * 修改用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUserProfile(SysUser user); + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + public boolean updateUserAvatar(String userName, String avatar); + + /** + * 重置用户密码 + * + * @param user 用户信息 + * @return 结果 + */ + public int resetPwd(SysUser user); + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + public int resetUserPwd(String userName, String password); + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserById(Long userId); + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + public String importUser(List userList, Boolean isUpdateSupport, String operName); + + /** + * 查看会员用户根据账号名/手机号 + * @param accountName 账号名/手机号 + * @return 用户 + */ + SysUser selectMemberUserByUserName(String accountName); +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/impl/SysConfigServiceImpl.java b/ff-base/src/main/java/com/ff/base/system/service/impl/SysConfigServiceImpl.java new file mode 100644 index 0000000..f8bca85 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/impl/SysConfigServiceImpl.java @@ -0,0 +1,227 @@ +package com.ff.base.system.service.impl; + +import com.ff.base.constant.CacheConstants; +import com.ff.base.constant.UserConstants; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.core.text.Convert; +import com.ff.base.datasource.DynamicDataSourceContextHolder; +import com.ff.base.exception.ServiceException; +import com.ff.base.system.domain.SysConfig; +import com.ff.base.system.mapper.SysConfigMapper; +import com.ff.base.system.service.ISysConfigService; +import com.ff.base.utils.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.sql.DataSource; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 参数配置 服务层实现 + * + * @author ff + */ +@Service +public class SysConfigServiceImpl implements ISysConfigService { + @Autowired + private SysConfigMapper configMapper; + + @Autowired + private RedisCache redisCache; + + + /** + * 查询参数配置信息 + * + * @param configId 参数配置ID + * @return 参数配置信息 + */ + @Override + public SysConfig selectConfigById(Long configId) { + SysConfig config = new SysConfig(); + config.setConfigId(configId); + return configMapper.selectConfig(config); + } + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数key + * @return 参数键值 + */ + @Override + public String selectConfigByKey(String configKey) { + String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configKey))); + if (StringUtils.isNotEmpty(configValue)) { + return configValue; + } + SysConfig config = new SysConfig(); + config.setConfigKey(configKey); + SysConfig retConfig = configMapper.selectConfig(config); + if (StringUtils.isNotNull(retConfig)) { + redisCache.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue()); + return retConfig.getConfigValue(); + } + return StringUtils.EMPTY; + } + + /** + * 获取验证码开关 + * + * @return true开启,false关闭 + */ + @Override + public boolean selectCaptchaEnabled() { + String captchaEnabled = selectConfigByKey("sys.account.captchaEnabled"); + if (StringUtils.isEmpty(captchaEnabled)) { + return true; + } + return Convert.toBool(captchaEnabled); + } + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + @Override + public List selectConfigList(SysConfig config) { + return configMapper.selectConfigList(config); + } + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public int insertConfig(SysConfig config) { + int row = configMapper.insertConfig(config); + if (row > 0) { + redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + return row; + } + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public int updateConfig(SysConfig config) { + SysConfig temp = configMapper.selectConfigById(config.getConfigId()); + if (!StringUtils.equals(temp.getConfigKey(), config.getConfigKey())) { + redisCache.deleteObject(getCacheKey(temp.getConfigKey())); + } + + int row = configMapper.updateConfig(config); + if (row > 0) { + redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + return row; + } + + /** + * 按键更新配置 + * + * @param config config + * @return int + */ + @Override + public int updateConfigByKey(SysConfig config) { + SysConfig temp = configMapper.checkConfigKeyUnique(config.getConfigKey()); + if (!StringUtils.equals(temp.getConfigKey(), config.getConfigKey())) { + redisCache.deleteObject(getCacheKey(temp.getConfigKey())); + } + + int row = configMapper.updateConfigByKey(config); + if (row > 0) { + redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + return row; + } + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + */ + @Override + public void deleteConfigByIds(Long[] configIds) { + for (Long configId : configIds) { + SysConfig config = selectConfigById(configId); + if (StringUtils.equals(UserConstants.YES, config.getConfigType())) { + throw new ServiceException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey())); + } + configMapper.deleteConfigById(configId); + redisCache.deleteObject(getCacheKey(config.getConfigKey())); + } + } + + /** + * 加载参数缓存数据 + */ + @Override + public void loadingConfigCache() { + Map resolvedDataSources = DynamicDataSourceContextHolder.getAllDataSource(); + for (Map.Entry entry : resolvedDataSources.entrySet()) { + Object key = entry.getKey(); + // 设置数据源类型 + DynamicDataSourceContextHolder.setDataSourceType(key.toString()); + List configsList = configMapper.selectConfigList(new SysConfig()); + for (SysConfig config : configsList) { + redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + } + } + + /** + * 清空参数缓存数据 + */ + @Override + public void clearConfigCache() { + Collection keys = redisCache.keys(CacheConstants.SYS_CONFIG_KEY + "*"); + redisCache.deleteObject(keys); + } + + /** + * 重置参数缓存数据 + */ + @Override + public void resetConfigCache() { + clearConfigCache(); + loadingConfigCache(); + } + + /** + * 校验参数键名是否唯一 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public boolean checkConfigKeyUnique(SysConfig config) { + Long configId = StringUtils.isNull(config.getConfigId()) ? -1L : config.getConfigId(); + SysConfig info = configMapper.checkConfigKeyUnique(config.getConfigKey()); + if (StringUtils.isNotNull(info) && info.getConfigId().longValue() != configId.longValue()) { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + private String getCacheKey(String configKey) { + return CacheConstants.SYS_CONFIG_KEY + configKey; + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/impl/SysDatasourceServiceImpl.java b/ff-base/src/main/java/com/ff/base/system/service/impl/SysDatasourceServiceImpl.java new file mode 100644 index 0000000..14a789c --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/impl/SysDatasourceServiceImpl.java @@ -0,0 +1,129 @@ +package com.ff.base.system.service.impl; + +import com.ff.base.system.domain.SysDatasource; +import com.ff.base.system.mapper.SysDatasourceMapper; +import com.ff.base.system.service.ISysDatasourceService; +import com.ff.base.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; + +import java.util.List; + +/** + * 租户数据源Service业务层处理 + * + * @author liukang + * @date 2024-11-20 + */ +@Service +public class SysDatasourceServiceImpl implements ISysDatasourceService +{ + @Autowired + private SysDatasourceMapper sysDatasourceMapper; + + /** + * 查询租户数据源 + * + * @param id 租户数据源主键 + * @return 租户数据源 + */ + @Override + public SysDatasource selectSysDatasourceById(Long id) + { + return sysDatasourceMapper.selectSysDatasourceById(id); + } + + /** + * 按租户id选择sys数据源 + * + * @param id 身份证件 + * @return {@link String } + */ + @Override + public String selectSysDatasourceByTenantId(String id) { + SysDatasource sysDatasource = sysDatasourceMapper.selectSysDatasourceByTenantId(id); + if (ObjectUtils.isEmpty(sysDatasource)){ + return "Asia/Shanghai"; + }else { + return sysDatasource.getTimeZone(); + } + } + + /** + * 获取租户时区名称 + * @param id 租户id + * @return 时区名称 + */ + @Override + public String selectTimeZoneNameByTenantId(String id) { + SysDatasource sysDatasource = sysDatasourceMapper.selectSysDatasourceByTenantId(id); + if (ObjectUtils.isEmpty(sysDatasource)){ + return "UTC+8"; + }else { + return sysDatasource.getTimeZoneName(); + } + } + + /** + * 查询租户数据源列表 + * + * @param sysDatasource 租户数据源 + * @return 租户数据源 + */ + @Override + public List selectSysDatasourceList(SysDatasource sysDatasource) + { + return sysDatasourceMapper.selectSysDatasourceList(sysDatasource); + } + + /** + * 新增租户数据源 + * + * @param sysDatasource 租户数据源 + * @return 结果 + */ + @Override + public int insertSysDatasource(SysDatasource sysDatasource) + { + sysDatasource.setCreateTime(DateUtils.getNowDate()); + return sysDatasourceMapper.insertSysDatasource(sysDatasource); + } + + /** + * 修改租户数据源 + * + * @param sysDatasource 租户数据源 + * @return 结果 + */ + @Override + public int updateSysDatasource(SysDatasource sysDatasource) + { + sysDatasource.setUpdateTime(DateUtils.getNowDate()); + return sysDatasourceMapper.updateSysDatasource(sysDatasource); + } + + /** + * 批量删除租户数据源 + * + * @param ids 需要删除的租户数据源主键 + * @return 结果 + */ + @Override + public int deleteSysDatasourceByIds(Long[] ids) + { + return sysDatasourceMapper.deleteSysDatasourceByIds(ids); + } + + /** + * 删除租户数据源信息 + * + * @param id 租户数据源主键 + * @return 结果 + */ + @Override + public int deleteSysDatasourceById(Long id) + { + return sysDatasourceMapper.deleteSysDatasourceById(id); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/impl/SysDeptServiceImpl.java b/ff-base/src/main/java/com/ff/base/system/service/impl/SysDeptServiceImpl.java new file mode 100644 index 0000000..6d04a25 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/impl/SysDeptServiceImpl.java @@ -0,0 +1,339 @@ +package com.ff.base.system.service.impl; + +import com.ff.base.annotation.DataScope; +import com.ff.base.constant.UserConstants; +import com.ff.base.core.domain.TreeSelect; +import com.ff.base.system.domain.SysDept; +import com.ff.base.system.domain.SysRole; +import com.ff.base.system.domain.SysUser; +import com.ff.base.core.text.Convert; +import com.ff.base.exception.ServiceException; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.spring.SpringUtils; +import com.ff.base.system.mapper.SysDeptMapper; +import com.ff.base.system.mapper.SysRoleMapper; +import com.ff.base.system.service.ISysDeptService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 部门管理 服务实现 + * + * @author ff + */ +@Service +public class SysDeptServiceImpl implements ISysDeptService +{ + @Autowired + private SysDeptMapper deptMapper; + + @Autowired + private SysRoleMapper roleMapper; + + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + @Override + @DataScope(deptAlias = "d") + public List selectDeptList(SysDept dept) + { + return deptMapper.selectDeptList(dept); + } + + /** + * 查询部门树结构信息 + * + * @param dept 部门信息 + * @return 部门树信息集合 + */ + @Override + public List selectDeptTreeList(SysDept dept) + { + List depts = SpringUtils.getAopProxy(this).selectDeptList(dept); + return buildDeptTreeSelect(depts); + } + + /** + * 构建前端所需要树结构 + * + * @param depts 部门列表 + * @return 树结构列表 + */ + @Override + public List buildDeptTree(List depts) + { + List returnList = new ArrayList(); + List tempList = depts.stream().map(SysDept::getDeptId).collect(Collectors.toList()); + for (SysDept dept : depts) + { + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(dept.getParentId())) + { + recursionFn(depts, dept); + returnList.add(dept); + } + } + if (returnList.isEmpty()) + { + returnList = depts; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param depts 部门列表 + * @return 下拉树结构列表 + */ + @Override + public List buildDeptTreeSelect(List depts) + { + List deptTrees = buildDeptTree(depts); + return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @return 选中部门列表 + */ + @Override + public List selectDeptListByRoleId(Long roleId) + { + SysRole role = roleMapper.selectRoleById(roleId); + return deptMapper.selectDeptListByRoleId(roleId, role.isDeptCheckStrictly()); + } + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + @Override + public SysDept selectDeptById(Long deptId) + { + return deptMapper.selectDeptById(deptId); + } + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + @Override + public int selectNormalChildrenDeptById(Long deptId) + { + return deptMapper.selectNormalChildrenDeptById(deptId); + } + + /** + * 是否存在子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + @Override + public boolean hasChildByDeptId(Long deptId) + { + int result = deptMapper.hasChildByDeptId(deptId); + return result > 0; + } + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 true 存在 false 不存在 + */ + @Override + public boolean checkDeptExistUser(Long deptId) + { + int result = deptMapper.checkDeptExistUser(deptId); + return result > 0; + } + + /** + * 校验部门名称是否唯一 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public boolean checkDeptNameUnique(SysDept dept) + { + Long deptId = StringUtils.isNull(dept.getDeptId()) ? -1L : dept.getDeptId(); + SysDept info = deptMapper.checkDeptNameUnique(dept.getDeptName(), dept.getParentId()); + if (StringUtils.isNotNull(info) && info.getDeptId().longValue() != deptId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验部门是否有数据权限 + * + * @param deptId 部门id + */ + @Override + public void checkDeptDataScope(Long deptId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId()) && StringUtils.isNotNull(deptId)) + { + SysDept dept = new SysDept(); + dept.setDeptId(deptId); + List depts = SpringUtils.getAopProxy(this).selectDeptList(dept); + if (StringUtils.isEmpty(depts)) + { + throw new ServiceException("没有权限访问部门数据!"); + } + } + } + + /** + * 新增保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public int insertDept(SysDept dept) + { + SysDept info = deptMapper.selectDeptById(dept.getParentId()); + // 如果父节点不为正常状态,则不允许新增子节点 + if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) + { + throw new ServiceException("部门停用,不允许新增"); + } + dept.setAncestors(info.getAncestors() + "," + dept.getParentId()); + return deptMapper.insertDept(dept); + } + + /** + * 修改保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public int updateDept(SysDept dept) + { + SysDept newParentDept = deptMapper.selectDeptById(dept.getParentId()); + SysDept oldDept = deptMapper.selectDeptById(dept.getDeptId()); + if (StringUtils.isNotNull(newParentDept) && StringUtils.isNotNull(oldDept)) + { + String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId(); + String oldAncestors = oldDept.getAncestors(); + dept.setAncestors(newAncestors); + updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors); + } + int result = deptMapper.updateDept(dept); + if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors()) + && !StringUtils.equals("0", dept.getAncestors())) + { + // 如果该部门是启用状态,则启用该部门的所有上级部门 + updateParentDeptStatusNormal(dept); + } + return result; + } + + /** + * 修改该部门的父级部门状态 + * + * @param dept 当前部门 + */ + private void updateParentDeptStatusNormal(SysDept dept) + { + String ancestors = dept.getAncestors(); + Long[] deptIds = Convert.toLongArray(ancestors); + deptMapper.updateDeptStatusNormal(deptIds); + } + + /** + * 修改子元素关系 + * + * @param deptId 被修改的部门ID + * @param newAncestors 新的父ID集合 + * @param oldAncestors 旧的父ID集合 + */ + public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) + { + List children = deptMapper.selectChildrenDeptById(deptId); + for (SysDept child : children) + { + child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors)); + } + if (children.size() > 0) + { + deptMapper.updateDeptChildren(children); + } + } + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + @Override + public int deleteDeptById(Long deptId) + { + return deptMapper.deleteDeptById(deptId); + } + + /** + * 递归列表 + */ + private void recursionFn(List list, SysDept t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysDept tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysDept t) + { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) + { + SysDept n = (SysDept) it.next(); + if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysDept t) + { + return getChildList(list, t).size() > 0; + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/impl/SysDictDataServiceImpl.java b/ff-base/src/main/java/com/ff/base/system/service/impl/SysDictDataServiceImpl.java new file mode 100644 index 0000000..dafa9ce --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/impl/SysDictDataServiceImpl.java @@ -0,0 +1,112 @@ +package com.ff.base.system.service.impl; + +import com.ff.base.system.domain.SysDictData; +import com.ff.base.utils.DictUtils; +import com.ff.base.system.mapper.SysDictDataMapper; +import com.ff.base.system.service.ISysDictDataService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 字典 业务层处理 + * + * @author ff + */ +@Service +public class SysDictDataServiceImpl implements ISysDictDataService +{ + @Autowired + private SysDictDataMapper dictDataMapper; + + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + @Override + public List selectDictDataList(SysDictData dictData) + { + return dictDataMapper.selectDictDataList(dictData); + } + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + @Override + public String selectDictLabel(String dictType, String dictValue) + { + return dictDataMapper.selectDictLabel(dictType, dictValue); + } + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + @Override + public SysDictData selectDictDataById(Long dictCode) + { + return dictDataMapper.selectDictDataById(dictCode); + } + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + */ + @Override + public void deleteDictDataByIds(Long[] dictCodes) + { + for (Long dictCode : dictCodes) + { + SysDictData data = selectDictDataById(dictCode); + dictDataMapper.deleteDictDataById(dictCode); + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + } + + /** + * 新增保存字典数据信息 + * + * @param data 字典数据信息 + * @return 结果 + */ + @Override + public int insertDictData(SysDictData data) + { + int row = dictDataMapper.insertDictData(data); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + return row; + } + + /** + * 修改保存字典数据信息 + * + * @param data 字典数据信息 + * @return 结果 + */ + @Override + public int updateDictData(SysDictData data) + { + int row = dictDataMapper.updateDictData(data); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + return row; + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/impl/SysDictTypeServiceImpl.java b/ff-base/src/main/java/com/ff/base/system/service/impl/SysDictTypeServiceImpl.java new file mode 100644 index 0000000..0c673f0 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/impl/SysDictTypeServiceImpl.java @@ -0,0 +1,204 @@ +package com.ff.base.system.service.impl; + +import com.ff.base.constant.UserConstants; +import com.ff.base.datasource.DynamicDataSourceContextHolder; +import com.ff.base.exception.ServiceException; +import com.ff.base.system.domain.SysDictData; +import com.ff.base.system.domain.SysDictType; +import com.ff.base.system.mapper.SysDictDataMapper; +import com.ff.base.system.mapper.SysDictTypeMapper; +import com.ff.base.system.service.ISysDictTypeService; +import com.ff.base.utils.DictUtils; +import com.ff.base.utils.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.sql.DataSource; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 字典 业务层处理 + * + * @author ff + */ +@Service +public class SysDictTypeServiceImpl implements ISysDictTypeService { + @Autowired + private SysDictTypeMapper dictTypeMapper; + + @Autowired + private SysDictDataMapper dictDataMapper; + + + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + @Override + public List selectDictTypeList(SysDictType dictType) { + return dictTypeMapper.selectDictTypeList(dictType); + } + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + @Override + public List selectDictTypeAll() { + return dictTypeMapper.selectDictTypeAll(); + } + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + @Override + public List selectDictDataByType(String dictType) { + List dictDatas = DictUtils.getDictCache(dictType); + if (StringUtils.isNotEmpty(dictDatas)) { + return dictDatas; + } + dictDatas = dictDataMapper.selectDictDataByType(dictType); + if (StringUtils.isNotEmpty(dictDatas)) { + DictUtils.setDictCache(dictType, dictDatas); + return dictDatas; + } + return null; + } + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + @Override + public SysDictType selectDictTypeById(Long dictId) { + return dictTypeMapper.selectDictTypeById(dictId); + } + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + @Override + public SysDictType selectDictTypeByType(String dictType) { + return dictTypeMapper.selectDictTypeByType(dictType); + } + + /** + * 批量删除字典类型信息 + * + * @param dictIds 需要删除的字典ID + */ + @Override + public void deleteDictTypeByIds(Long[] dictIds) { + for (Long dictId : dictIds) { + SysDictType dictType = selectDictTypeById(dictId); + if (dictDataMapper.countDictDataByType(dictType.getDictType()) > 0) { + throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName())); + } + dictTypeMapper.deleteDictTypeById(dictId); + DictUtils.removeDictCache(dictType.getDictType()); + } + } + + /** + * 加载字典缓存数据 + */ + @Override + public void loadingDictCache() { + Map resolvedDataSources = DynamicDataSourceContextHolder.getAllDataSource(); + for (Map.Entry dataSourceEntry : resolvedDataSources.entrySet()) { + Object key = dataSourceEntry.getKey(); + // 设置数据源类型 + DynamicDataSourceContextHolder.setDataSourceType(key.toString()); + + SysDictData dictData = new SysDictData(); + dictData.setStatus("0"); + Map> dictDataMap = dictDataMapper.selectDictDataList(dictData).stream().collect(Collectors.groupingBy(SysDictData::getDictType)); + for (Map.Entry> entry : dictDataMap.entrySet()) { + DictUtils.setDictCache(entry.getKey(), entry.getValue().stream().sorted(Comparator.comparing(SysDictData::getDictSort)).collect(Collectors.toList())); + } + } + + } + + /** + * 清空字典缓存数据 + */ + @Override + public void clearDictCache() { + DictUtils.clearDictCache(); + } + + /** + * 重置字典缓存数据 + */ + @Override + public void resetDictCache() { + clearDictCache(); + loadingDictCache(); + } + + /** + * 新增保存字典类型信息 + * + * @param dict 字典类型信息 + * @return 结果 + */ + @Override + public int insertDictType(SysDictType dict) { + int row = dictTypeMapper.insertDictType(dict); + if (row > 0) { + DictUtils.setDictCache(dict.getDictType(), null); + } + return row; + } + + /** + * 修改保存字典类型信息 + * + * @param dict 字典类型信息 + * @return 结果 + */ + @Override + @Transactional + public int updateDictType(SysDictType dict) { + SysDictType oldDict = dictTypeMapper.selectDictTypeById(dict.getDictId()); + dictDataMapper.updateDictDataType(oldDict.getDictType(), dict.getDictType()); + int row = dictTypeMapper.updateDictType(dict); + if (row > 0) { + List dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType()); + DictUtils.setDictCache(dict.getDictType(), dictDatas); + } + return row; + } + + /** + * 校验字典类型称是否唯一 + * + * @param dict 字典类型 + * @return 结果 + */ + @Override + public boolean checkDictTypeUnique(SysDictType dict) { + Long dictId = StringUtils.isNull(dict.getDictId()) ? -1L : dict.getDictId(); + SysDictType dictType = dictTypeMapper.checkDictTypeUnique(dict.getDictType()); + if (StringUtils.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue()) { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/impl/SysLogininforServiceImpl.java b/ff-base/src/main/java/com/ff/base/system/service/impl/SysLogininforServiceImpl.java new file mode 100644 index 0000000..22f85d7 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/impl/SysLogininforServiceImpl.java @@ -0,0 +1,66 @@ +package com.ff.base.system.service.impl; + +import com.ff.base.system.domain.SysLogininfor; +import com.ff.base.system.mapper.SysLogininforMapper; +import com.ff.base.system.service.ISysLogininforService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 系统访问日志情况信息 服务层处理 + * + * @author ff + */ +@Service +public class SysLogininforServiceImpl implements ISysLogininforService +{ + + @Autowired + private SysLogininforMapper logininforMapper; + + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + @Override + public void insertLogininfor(SysLogininfor logininfor) + { + logininforMapper.insertLogininfor(logininfor); + } + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + @Override + public List selectLogininforList(SysLogininfor logininfor) + { + return logininforMapper.selectLogininforList(logininfor); + } + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + @Override + public int deleteLogininforByIds(Long[] infoIds) + { + return logininforMapper.deleteLogininforByIds(infoIds); + } + + /** + * 清空系统登录日志 + */ + @Override + public void cleanLogininfor() + { + logininforMapper.cleanLogininfor(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/impl/SysMenuServiceImpl.java b/ff-base/src/main/java/com/ff/base/system/service/impl/SysMenuServiceImpl.java new file mode 100644 index 0000000..1f20b6e --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/impl/SysMenuServiceImpl.java @@ -0,0 +1,538 @@ +package com.ff.base.system.service.impl; + +import com.ff.base.constant.Constants; +import com.ff.base.constant.UserConstants; +import com.ff.base.core.domain.TreeSelect; +import com.ff.base.system.domain.SysMenu; +import com.ff.base.system.domain.SysRole; +import com.ff.base.system.domain.SysUser; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.system.domain.vo.MetaVo; +import com.ff.base.system.domain.vo.RouterVo; +import com.ff.base.system.mapper.SysMenuMapper; +import com.ff.base.system.mapper.SysRoleMapper; +import com.ff.base.system.mapper.SysRoleMenuMapper; +import com.ff.base.system.service.ISysMenuService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 菜单 业务层处理 + * + * @author ff + */ +@Service +public class SysMenuServiceImpl implements ISysMenuService +{ + public static final String PREMISSION_STRING = "perms[\"{0}\"]"; + + @Autowired + private SysMenuMapper menuMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysRoleMenuMapper roleMenuMapper; + + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + @Override + public List selectMenuList(Long userId) + { + return selectMenuList(new SysMenu(), userId); + } + + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + @Override + public List selectMenuList(SysMenu menu, Long userId) + { + List menuList = null; + // 管理员显示所有菜单信息 + if (SysUser.isAdmin(userId)) + { + menuList = menuMapper.selectMenuList(menu); + } + else + { + menu.getParams().put("userId", userId); + menuList = menuMapper.selectMenuListByUserId(menu); + } + return menuList; + } + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + @Override + public Set selectMenuPermsByUserId(Long userId) + { + List perms = menuMapper.selectMenuPermsByUserId(userId); + Set permsSet = new HashSet<>(); + for (String perm : perms) + { + if (StringUtils.isNotEmpty(perm)) + { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + @Override + public Set selectMenuPermsByRoleId(Long roleId) + { + List perms = menuMapper.selectMenuPermsByRoleId(roleId); + Set permsSet = new HashSet<>(); + for (String perm : perms) + { + if (StringUtils.isNotEmpty(perm)) + { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 根据用户ID查询菜单 + * + * @param userId 用户名称 + * @return 菜单列表 + */ + @Override + public List selectMenuTreeByUserId(Long userId) + { + List menus = null; + if (SecurityUtils.isAdmin(userId)) + { + menus = menuMapper.selectMenuTreeAll(); + } + else + { + menus = menuMapper.selectMenuTreeByUserId(userId); + } + return getChildPerms(menus, 0); + } + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + @Override + public List selectMenuListByRoleId(Long roleId) + { + SysRole role = roleMapper.selectRoleById(roleId); + return menuMapper.selectMenuListByRoleId(roleId, role.isMenuCheckStrictly()); + } + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + @Override + public List buildMenus(List menus) + { + List routers = new LinkedList(); + for (SysMenu menu : menus) + { + RouterVo router = new RouterVo(); + router.setHidden("1".equals(menu.getVisible())); + router.setName(getRouteName(menu)); + router.setPath(getRouterPath(menu)); + router.setComponent(getComponent(menu)); + router.setQuery(menu.getQuery()); + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + List cMenus = menu.getChildren(); + if (StringUtils.isNotEmpty(cMenus) && UserConstants.TYPE_DIR.equals(menu.getMenuType())) + { + router.setAlwaysShow(true); + router.setRedirect("noRedirect"); + router.setChildren(buildMenus(cMenus)); + } + else if (isMenuFrame(menu)) + { + router.setMeta(null); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + children.setPath(menu.getPath()); + children.setComponent(menu.getComponent()); + children.setName(getRouteName(menu.getRouteName(), menu.getPath())); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + children.setQuery(menu.getQuery()); + childrenList.add(children); + router.setChildren(childrenList); + } + else if (menu.getParentId().intValue() == 0 && isInnerLink(menu)) + { + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon())); + router.setPath("/"); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + String routerPath = innerLinkReplaceEach(menu.getPath()); + children.setPath(routerPath); + children.setComponent(UserConstants.INNER_LINK); + children.setName(getRouteName(menu.getRouteName(), routerPath)); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath())); + childrenList.add(children); + router.setChildren(childrenList); + } + routers.add(router); + } + return routers; + } + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + @Override + public List buildMenuTree(List menus) + { + List returnList = new ArrayList(); + List tempList = menus.stream().map(SysMenu::getMenuId).collect(Collectors.toList()); + for (Iterator iterator = menus.iterator(); iterator.hasNext();) + { + SysMenu menu = (SysMenu) iterator.next(); + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(menu.getParentId())) + { + recursionFn(menus, menu); + returnList.add(menu); + } + } + if (returnList.isEmpty()) + { + returnList = menus; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + @Override + public List buildMenuTreeSelect(List menus) + { + List menuTrees = buildMenuTree(menus); + return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + @Override + public SysMenu selectMenuById(Long menuId) + { + return menuMapper.selectMenuById(menuId); + } + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public boolean hasChildByMenuId(Long menuId) + { + int result = menuMapper.hasChildByMenuId(menuId); + return result > 0; + } + + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public boolean checkMenuExistRole(Long menuId) + { + int result = roleMenuMapper.checkMenuExistRole(menuId); + return result > 0; + } + + /** + * 新增保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public int insertMenu(SysMenu menu) + { + return menuMapper.insertMenu(menu); + } + + /** + * 修改保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public int updateMenu(SysMenu menu) + { + return menuMapper.updateMenu(menu); + } + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public int deleteMenuById(Long menuId) + { + return menuMapper.deleteMenuById(menuId); + } + + /** + * 校验菜单名称是否唯一 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public boolean checkMenuNameUnique(SysMenu menu) + { + Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId(); + SysMenu info = menuMapper.checkMenuNameUnique(menu.getMenuName(), menu.getParentId()); + if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 获取路由名称 + * + * @param menu 菜单信息 + * @return 路由名称 + */ + public String getRouteName(SysMenu menu) + { + // 非外链并且是一级目录(类型为目录) + if (isMenuFrame(menu)) + { + return StringUtils.EMPTY; + } + return getRouteName(menu.getRouteName(), menu.getPath()); + } + + /** + * 获取路由名称,如没有配置路由名称则取路由地址 + * + * @param routerName 路由名称 + * @param path 路由地址 + * @return 路由名称(驼峰格式) + */ + public String getRouteName(String name, String path) + { + String routerName = StringUtils.isNotEmpty(name) ? name : path; + return StringUtils.capitalize(routerName); + } + + /** + * 获取路由地址 + * + * @param menu 菜单信息 + * @return 路由地址 + */ + public String getRouterPath(SysMenu menu) + { + String routerPath = menu.getPath(); + // 内链打开外网方式 + if (menu.getParentId().intValue() != 0 && isInnerLink(menu)) + { + routerPath = innerLinkReplaceEach(routerPath); + } + // 非外链并且是一级目录(类型为目录) + if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType()) + && UserConstants.NO_FRAME.equals(menu.getIsFrame())) + { + routerPath = "/" + menu.getPath(); + } + // 非外链并且是一级目录(类型为菜单) + else if (isMenuFrame(menu)) + { + routerPath = "/"; + } + return routerPath; + } + + /** + * 获取组件信息 + * + * @param menu 菜单信息 + * @return 组件信息 + */ + public String getComponent(SysMenu menu) + { + String component = UserConstants.LAYOUT; + if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu)) + { + component = menu.getComponent(); + } + else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu)) + { + component = UserConstants.INNER_LINK; + } + else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu)) + { + component = UserConstants.PARENT_VIEW; + } + return component; + } + + /** + * 是否为菜单内部跳转 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isMenuFrame(SysMenu menu) + { + return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType()) + && menu.getIsFrame().equals(UserConstants.NO_FRAME); + } + + /** + * 是否为内链组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isInnerLink(SysMenu menu) + { + return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath()); + } + + /** + * 是否为parent_view组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isParentView(SysMenu menu) + { + return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType()); + } + + /** + * 根据父节点的ID获取所有子节点 + * + * @param list 分类表 + * @param parentId 传入的父节点ID + * @return String + */ + public List getChildPerms(List list, int parentId) + { + List returnList = new ArrayList(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) + { + SysMenu t = (SysMenu) iterator.next(); + // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点 + if (t.getParentId() == parentId) + { + recursionFn(list, t); + returnList.add(t); + } + } + return returnList; + } + + /** + * 递归列表 + * + * @param list 分类表 + * @param t 子节点 + */ + private void recursionFn(List list, SysMenu t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysMenu tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysMenu t) + { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) + { + SysMenu n = (SysMenu) it.next(); + if (n.getParentId().longValue() == t.getMenuId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysMenu t) + { + return getChildList(list, t).size() > 0; + } + + /** + * 内链域名特殊字符替换 + * + * @return 替换后的内链域名 + */ + public String innerLinkReplaceEach(String path) + { + return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", ":" }, + new String[] { "", "", "", "/", "/" }); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/impl/SysOperLogServiceImpl.java b/ff-base/src/main/java/com/ff/base/system/service/impl/SysOperLogServiceImpl.java new file mode 100644 index 0000000..08dfd59 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/impl/SysOperLogServiceImpl.java @@ -0,0 +1,77 @@ +package com.ff.base.system.service.impl; + +import com.ff.base.system.domain.SysOperLog; +import com.ff.base.system.mapper.SysOperLogMapper; +import com.ff.base.system.service.ISysOperLogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 操作日志 服务层处理 + * + * @author ff + */ +@Service +public class SysOperLogServiceImpl implements ISysOperLogService +{ + @Autowired + private SysOperLogMapper operLogMapper; + + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + */ + @Override + public void insertOperlog(SysOperLog operLog) + { + operLogMapper.insertOperlog(operLog); + } + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + @Override + public List selectOperLogList(SysOperLog operLog) + { + return operLogMapper.selectOperLogList(operLog); + } + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + @Override + public int deleteOperLogByIds(Long[] operIds) + { + return operLogMapper.deleteOperLogByIds(operIds); + } + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + @Override + public SysOperLog selectOperLogById(Long operId) + { + return operLogMapper.selectOperLogById(operId); + } + + /** + * 清空操作日志 + */ + @Override + public void cleanOperLog() + { + operLogMapper.cleanOperLog(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/impl/SysPostServiceImpl.java b/ff-base/src/main/java/com/ff/base/system/service/impl/SysPostServiceImpl.java new file mode 100644 index 0000000..d7fe293 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/impl/SysPostServiceImpl.java @@ -0,0 +1,179 @@ +package com.ff.base.system.service.impl; + +import com.ff.base.constant.UserConstants; +import com.ff.base.exception.ServiceException; +import com.ff.base.utils.StringUtils; +import com.ff.base.system.domain.SysPost; +import com.ff.base.system.mapper.SysPostMapper; +import com.ff.base.system.mapper.SysUserPostMapper; +import com.ff.base.system.service.ISysPostService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 岗位信息 服务层处理 + * + * @author ff + */ +@Service +public class SysPostServiceImpl implements ISysPostService +{ + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + /** + * 查询岗位信息集合 + * + * @param post 岗位信息 + * @return 岗位信息集合 + */ + @Override + public List selectPostList(SysPost post) + { + return postMapper.selectPostList(post); + } + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + @Override + public List selectPostAll() + { + return postMapper.selectPostAll(); + } + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + @Override + public SysPost selectPostById(Long postId) + { + return postMapper.selectPostById(postId); + } + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + @Override + public List selectPostListByUserId(Long userId) + { + return postMapper.selectPostListByUserId(userId); + } + + /** + * 校验岗位名称是否唯一 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public boolean checkPostNameUnique(SysPost post) + { + Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId(); + SysPost info = postMapper.checkPostNameUnique(post.getPostName()); + if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验岗位编码是否唯一 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public boolean checkPostCodeUnique(SysPost post) + { + Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId(); + SysPost info = postMapper.checkPostCodeUnique(post.getPostCode()); + if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + @Override + public int countUserPostById(Long postId) + { + return userPostMapper.countUserPostById(postId); + } + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + @Override + public int deletePostById(Long postId) + { + return postMapper.deletePostById(postId); + } + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + @Override + public int deletePostByIds(Long[] postIds) + { + for (Long postId : postIds) + { + SysPost post = selectPostById(postId); + if (countUserPostById(postId) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", post.getPostName())); + } + } + return postMapper.deletePostByIds(postIds); + } + + /** + * 新增保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public int insertPost(SysPost post) + { + return postMapper.insertPost(post); + } + + /** + * 修改保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public int updatePost(SysPost post) + { + return postMapper.updatePost(post); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/impl/SysRoleServiceImpl.java b/ff-base/src/main/java/com/ff/base/system/service/impl/SysRoleServiceImpl.java new file mode 100644 index 0000000..47ecadf --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,424 @@ +package com.ff.base.system.service.impl; + +import com.ff.base.annotation.DataScope; +import com.ff.base.constant.UserConstants; +import com.ff.base.system.domain.SysRole; +import com.ff.base.system.domain.SysUser; +import com.ff.base.exception.ServiceException; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.spring.SpringUtils; +import com.ff.base.system.domain.SysRoleDept; +import com.ff.base.system.domain.SysRoleMenu; +import com.ff.base.system.domain.SysUserRole; +import com.ff.base.system.mapper.SysRoleDeptMapper; +import com.ff.base.system.mapper.SysRoleMapper; +import com.ff.base.system.mapper.SysRoleMenuMapper; +import com.ff.base.system.mapper.SysUserRoleMapper; +import com.ff.base.system.service.ISysRoleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; + +/** + * 角色 业务层处理 + * + * @author ff + */ +@Service +public class SysRoleServiceImpl implements ISysRoleService +{ + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysRoleMenuMapper roleMenuMapper; + + @Autowired + private SysUserRoleMapper userRoleMapper; + + @Autowired + private SysRoleDeptMapper roleDeptMapper; + + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + @Override + @DataScope(deptAlias = "d") + public List selectRoleList(SysRole role) + { + return roleMapper.selectRoleList(role); + } + + /** + * 根据用户ID查询角色 + * + * @param userId 用户ID + * @return 角色列表 + */ + @Override + public List selectRolesByUserId(Long userId) + { + List userRoles = roleMapper.selectRolePermissionByUserId(userId); + List roles = selectRoleAll(); + for (SysRole role : roles) + { + for (SysRole userRole : userRoles) + { + if (role.getRoleId().longValue() == userRole.getRoleId().longValue()) + { + role.setFlag(true); + break; + } + } + } + return roles; + } + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + @Override + public Set selectRolePermissionByUserId(Long userId) + { + List perms = roleMapper.selectRolePermissionByUserId(userId); + Set permsSet = new HashSet<>(); + for (SysRole perm : perms) + { + if (StringUtils.isNotNull(perm)) + { + permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(","))); + } + } + return permsSet; + } + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + @Override + public List selectRoleAll() + { + return SpringUtils.getAopProxy(this).selectRoleList(new SysRole()); + } + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + @Override + public List selectRoleListByUserId(Long userId) + { + return roleMapper.selectRoleListByUserId(userId); + } + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + @Override + public SysRole selectRoleById(Long roleId) + { + return roleMapper.selectRoleById(roleId); + } + + /** + * 校验角色名称是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public boolean checkRoleNameUnique(SysRole role) + { + Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId(); + SysRole info = roleMapper.checkRoleNameUnique(role.getRoleName()); + if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验角色权限是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public boolean checkRoleKeyUnique(SysRole role) + { + Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId(); + SysRole info = roleMapper.checkRoleKeyUnique(role.getRoleKey()); + if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验角色是否允许操作 + * + * @param role 角色信息 + */ + @Override + public void checkRoleAllowed(SysRole role) + { + if (StringUtils.isNotNull(role.getRoleId()) && role.isAdmin()) + { + throw new ServiceException("不允许操作超级管理员角色"); + } + } + + /** + * 校验角色是否有数据权限 + * + * @param roleIds 角色id + */ + @Override + public void checkRoleDataScope(Long... roleIds) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + for (Long roleId : roleIds) + { + SysRole role = new SysRole(); + role.setRoleId(roleId); + List roles = SpringUtils.getAopProxy(this).selectRoleList(role); + if (StringUtils.isEmpty(roles)) + { + throw new ServiceException("没有权限访问角色数据!"); + } + } + } + } + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + @Override + public int countUserRoleByRoleId(Long roleId) + { + return userRoleMapper.countUserRoleByRoleId(roleId); + } + + /** + * 新增保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional + public int insertRole(SysRole role) + { + // 新增角色信息 + roleMapper.insertRole(role); + return insertRoleMenu(role); + } + + /** + * 修改保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional + public int updateRole(SysRole role) + { + // 修改角色信息 + roleMapper.updateRole(role); + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenuByRoleId(role.getRoleId()); + return insertRoleMenu(role); + } + + /** + * 修改角色状态 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public int updateRoleStatus(SysRole role) + { + return roleMapper.updateRole(role); + } + + /** + * 修改数据权限信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional + public int authDataScope(SysRole role) + { + // 修改角色信息 + roleMapper.updateRole(role); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDeptByRoleId(role.getRoleId()); + // 新增角色和部门信息(数据权限) + return insertRoleDept(role); + } + + /** + * 新增角色菜单信息 + * + * @param role 角色对象 + */ + public int insertRoleMenu(SysRole role) + { + int rows = 1; + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long menuId : role.getMenuIds()) + { + SysRoleMenu rm = new SysRoleMenu(); + rm.setRoleId(role.getRoleId()); + rm.setMenuId(menuId); + list.add(rm); + } + if (list.size() > 0) + { + rows = roleMenuMapper.batchRoleMenu(list); + } + return rows; + } + + /** + * 新增角色部门信息(数据权限) + * + * @param role 角色对象 + */ + public int insertRoleDept(SysRole role) + { + int rows = 1; + // 新增角色与部门(数据权限)管理 + List list = new ArrayList(); + for (Long deptId : role.getDeptIds()) + { + SysRoleDept rd = new SysRoleDept(); + rd.setRoleId(role.getRoleId()); + rd.setDeptId(deptId); + list.add(rd); + } + if (list.size() > 0) + { + rows = roleDeptMapper.batchRoleDept(list); + } + return rows; + } + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + @Override + @Transactional + public int deleteRoleById(Long roleId) + { + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenuByRoleId(roleId); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDeptByRoleId(roleId); + return roleMapper.deleteRoleById(roleId); + } + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + @Override + @Transactional + public int deleteRoleByIds(Long[] roleIds) + { + for (Long roleId : roleIds) + { + checkRoleAllowed(new SysRole(roleId)); + checkRoleDataScope(roleId); + SysRole role = selectRoleById(roleId); + if (countUserRoleByRoleId(roleId) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", role.getRoleName())); + } + } + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenu(roleIds); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDept(roleIds); + return roleMapper.deleteRoleByIds(roleIds); + } + + /** + * 取消授权用户角色 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + @Override + public int deleteAuthUser(SysUserRole userRole) + { + return userRoleMapper.deleteUserRoleInfo(userRole); + } + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要取消授权的用户数据ID + * @return 结果 + */ + @Override + public int deleteAuthUsers(Long roleId, Long[] userIds) + { + return userRoleMapper.deleteUserRoleInfos(roleId, userIds); + } + + /** + * 批量选择授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要授权的用户数据ID + * @return 结果 + */ + @Override + public int insertAuthUsers(Long roleId, Long[] userIds) + { + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long userId : userIds) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(userId); + ur.setRoleId(roleId); + list.add(ur); + } + return userRoleMapper.batchUserRole(list); + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/impl/SysUserOnlineServiceImpl.java b/ff-base/src/main/java/com/ff/base/system/service/impl/SysUserOnlineServiceImpl.java new file mode 100644 index 0000000..49f0fc9 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/impl/SysUserOnlineServiceImpl.java @@ -0,0 +1,96 @@ +package com.ff.base.system.service.impl; + +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.utils.StringUtils; +import com.ff.base.system.domain.SysUserOnline; +import com.ff.base.system.service.ISysUserOnlineService; +import org.springframework.stereotype.Service; + +/** + * 在线用户 服务层处理 + * + * @author ff + */ +@Service +public class SysUserOnlineServiceImpl implements ISysUserOnlineService +{ + /** + * 通过登录地址查询信息 + * + * @param ipaddr 登录地址 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user) + { + if (StringUtils.equals(ipaddr, user.getIpaddr())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 通过用户名称查询信息 + * + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByUserName(String userName, LoginUser user) + { + if (StringUtils.equals(userName, user.getUsername())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 通过登录地址/用户名称查询信息 + * + * @param ipaddr 登录地址 + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user) + { + if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 设置在线用户信息 + * + * @param user 用户信息 + * @return 在线用户 + */ + @Override + public SysUserOnline loginUserToUserOnline(LoginUser user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUser())) + { + return null; + } + SysUserOnline sysUserOnline = new SysUserOnline(); + sysUserOnline.setTokenId(user.getToken()); + sysUserOnline.setUserName(user.getUsername()); + sysUserOnline.setIpaddr(user.getIpaddr()); + sysUserOnline.setLoginLocation(user.getLoginLocation()); + sysUserOnline.setBrowser(user.getBrowser()); + sysUserOnline.setOs(user.getOs()); + sysUserOnline.setLoginTime(user.getLoginTime()); + if (StringUtils.isNotNull(user.getUser().getDept())) + { + sysUserOnline.setDeptName(user.getUser().getDept().getDeptName()); + } + return sysUserOnline; + } +} diff --git a/ff-base/src/main/java/com/ff/base/system/service/impl/SysUserServiceImpl.java b/ff-base/src/main/java/com/ff/base/system/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..9f612fd --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/system/service/impl/SysUserServiceImpl.java @@ -0,0 +1,557 @@ +package com.ff.base.system.service.impl; + +import com.ff.base.annotation.DataScope; +import com.ff.base.constant.UserConstants; +import com.ff.base.system.domain.SysRole; +import com.ff.base.system.domain.SysUser; +import com.ff.base.exception.ServiceException; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.bean.BeanValidators; +import com.ff.base.utils.spring.SpringUtils; +import com.ff.base.system.domain.SysPost; +import com.ff.base.system.domain.SysUserPost; +import com.ff.base.system.domain.SysUserRole; +import com.ff.base.system.mapper.*; +import com.ff.base.system.service.ISysConfigService; +import com.ff.base.system.service.ISysDeptService; +import com.ff.base.system.service.ISysUserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import javax.validation.Validator; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 用户 业务层处理 + * + * @author ff + */ +@Service +public class SysUserServiceImpl implements ISysUserService +{ + private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class); + + @Autowired + private SysUserMapper userMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserRoleMapper userRoleMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + @Autowired + private ISysConfigService configService; + + @Autowired + private ISysDeptService deptService; + + @Autowired + protected Validator validator; + + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUserList(SysUser user) + { + return userMapper.selectUserList(user); + } + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectAllocatedList(SysUser user) + { + return userMapper.selectAllocatedList(user); + } + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUnallocatedList(SysUser user) + { + return userMapper.selectUnallocatedList(user); + } + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + @Override + public SysUser selectUserByUserName(String userName) + { + return userMapper.selectUserByUserName(userName); + } + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + @Override + public SysUser selectUserById(Long userId) + { + return userMapper.selectUserById(userId); + } + + /** + * 查询用户所属角色组 + * + * @param userName 用户名 + * @return 结果 + */ + @Override + public String selectUserRoleGroup(String userName) + { + List list = roleMapper.selectRolesByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(",")); + } + + /** + * 查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + @Override + public String selectUserPostGroup(String userName) + { + List list = postMapper.selectPostsByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysPost::getPostName).collect(Collectors.joining(",")); + } + + /** + * 校验用户名称是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public boolean checkUserNameUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkUserNameUnique(user.getUserName()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return + */ + @Override + public boolean checkPhoneUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验email是否唯一 + * + * @param user 用户信息 + * @return + */ + @Override + public boolean checkEmailUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkEmailUnique(user.getEmail()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验用户是否允许操作 + * + * @param user 用户信息 + */ + @Override + public void checkUserAllowed(SysUser user) + { + if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) + { + throw new ServiceException("不允许操作超级管理员用户"); + } + } + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + @Override + public void checkUserDataScope(Long userId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + SysUser user = new SysUser(); + user.setUserId(userId); + List users = SpringUtils.getAopProxy(this).selectUserList(user); + if (StringUtils.isEmpty(users)) + { + throw new ServiceException("没有权限访问用户数据!"); + } + } + } + + /** + * 新增保存用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + @Transactional + public int insertUser(SysUser user) + { + // 新增用户信息 + int rows = userMapper.insertUser(user); + // 新增用户岗位关联 + insertUserPost(user); + // 新增用户与角色管理 + insertUserRole(user); + return rows; + } + + /** + * 注册用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public boolean registerUser(SysUser user) + { + return userMapper.insertUser(user) > 0; + } + + /** + * 修改保存用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + @Transactional + public int updateUser(SysUser user) + { + Long userId = user.getUserId(); + // 删除用户与角色关联 + userRoleMapper.deleteUserRoleByUserId(userId); + // 新增用户与角色管理 + insertUserRole(user); + // 删除用户与岗位关联 + userPostMapper.deleteUserPostByUserId(userId); + // 新增用户与岗位管理 + insertUserPost(user); + return userMapper.updateUser(user); + } + + /** + * 用户授权角色 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + @Override + @Transactional + public void insertUserAuth(Long userId, Long[] roleIds) + { + userRoleMapper.deleteUserRoleByUserId(userId); + insertUserRole(userId, roleIds); + } + + /** + * 修改用户状态 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int updateUserStatus(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 修改用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int updateUserProfile(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + @Override + public boolean updateUserAvatar(String userName, String avatar) + { + return userMapper.updateUserAvatar(userName, avatar) > 0; + } + + /** + * 重置用户密码 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int resetPwd(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + @Override + public int resetUserPwd(String userName, String password) + { + return userMapper.resetUserPwd(userName, password); + } + + /** + * 新增用户角色信息 + * + * @param user 用户对象 + */ + public void insertUserRole(SysUser user) + { + this.insertUserRole(user.getUserId(), user.getRoleIds()); + } + + /** + * 新增用户岗位信息 + * + * @param user 用户对象 + */ + public void insertUserPost(SysUser user) + { + Long[] posts = user.getPostIds(); + if (StringUtils.isNotEmpty(posts)) + { + // 新增用户与岗位管理 + List list = new ArrayList(posts.length); + for (Long postId : posts) + { + SysUserPost up = new SysUserPost(); + up.setUserId(user.getUserId()); + up.setPostId(postId); + list.add(up); + } + userPostMapper.batchUserPost(list); + } + } + + /** + * 新增用户角色信息 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserRole(Long userId, Long[] roleIds) + { + if (StringUtils.isNotEmpty(roleIds)) + { + // 新增用户与角色管理 + List list = new ArrayList(roleIds.length); + for (Long roleId : roleIds) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(userId); + ur.setRoleId(roleId); + list.add(ur); + } + userRoleMapper.batchUserRole(list); + } + } + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + @Override + @Transactional + public int deleteUserById(Long userId) + { + // 删除用户与角色关联 + userRoleMapper.deleteUserRoleByUserId(userId); + // 删除用户与岗位表 + userPostMapper.deleteUserPostByUserId(userId); + return userMapper.deleteUserById(userId); + } + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + @Override + @Transactional + public int deleteUserByIds(Long[] userIds) + { + for (Long userId : userIds) + { + checkUserAllowed(new SysUser(userId)); + checkUserDataScope(userId); + } + // 删除用户与角色关联 + userRoleMapper.deleteUserRole(userIds); + // 删除用户与岗位关联 + userPostMapper.deleteUserPost(userIds); + return userMapper.deleteUserByIds(userIds); + } + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + @Override + public String importUser(List userList, Boolean isUpdateSupport, String operName) + { + if (StringUtils.isNull(userList) || userList.size() == 0) + { + throw new ServiceException("导入用户数据不能为空!"); + } + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + for (SysUser user : userList) + { + try + { + // 验证是否存在这个用户 + SysUser u = userMapper.selectUserByUserName(user.getUserName()); + if (StringUtils.isNull(u)) + { + BeanValidators.validateWithException(validator, user); + deptService.checkDeptDataScope(user.getDeptId()); + String password = configService.selectConfigByKey("sys.user.initPassword"); + user.setPassword(SecurityUtils.encryptPassword(password)); + user.setCreateBy(operName); + userMapper.insertUser(user); + successNum++; + successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 导入成功"); + } + else if (isUpdateSupport) + { + BeanValidators.validateWithException(validator, user); + checkUserAllowed(u); + checkUserDataScope(u.getUserId()); + deptService.checkDeptDataScope(user.getDeptId()); + user.setUserId(u.getUserId()); + user.setUpdateBy(operName); + userMapper.updateUser(user); + successNum++; + successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 更新成功"); + } + else + { + failureNum++; + failureMsg.append("
" + failureNum + "、账号 " + user.getUserName() + " 已存在"); + } + } + catch (Exception e) + { + failureNum++; + String msg = "
" + failureNum + "、账号 " + user.getUserName() + " 导入失败:"; + failureMsg.append(msg + e.getMessage()); + log.error(msg, e); + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } + + /** + * 根据账号名/手机号查询会员用户 + * @param accountName 账号名/手机号 + * @return 会员用户 + */ + @Override + public SysUser selectMemberUserByUserName(String accountName) { + return userMapper.selectMemberUserByUserName(accountName); + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/Arith.java b/ff-base/src/main/java/com/ff/base/utils/Arith.java new file mode 100644 index 0000000..35311af --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/Arith.java @@ -0,0 +1,114 @@ +package com.ff.base.utils; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * 精确的浮点数运算 + * + * @author ff + */ +public class Arith +{ + + /** 默认除法运算精度 */ + private static final int DEF_DIV_SCALE = 10; + + /** 这个类不能实例化 */ + private Arith() + { + } + + /** + * 提供精确的加法运算。 + * @param v1 被加数 + * @param v2 加数 + * @return 两个参数的和 + */ + public static double add(double v1, double v2) + { + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.add(b2).doubleValue(); + } + + /** + * 提供精确的减法运算。 + * @param v1 被减数 + * @param v2 减数 + * @return 两个参数的差 + */ + public static double sub(double v1, double v2) + { + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.subtract(b2).doubleValue(); + } + + /** + * 提供精确的乘法运算。 + * @param v1 被乘数 + * @param v2 乘数 + * @return 两个参数的积 + */ + public static double mul(double v1, double v2) + { + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.multiply(b2).doubleValue(); + } + + /** + * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 + * 小数点以后10位,以后的数字四舍五入。 + * @param v1 被除数 + * @param v2 除数 + * @return 两个参数的商 + */ + public static double div(double v1, double v2) + { + return div(v1, v2, DEF_DIV_SCALE); + } + + /** + * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 + * 定精度,以后的数字四舍五入。 + * @param v1 被除数 + * @param v2 除数 + * @param scale 表示表示需要精确到小数点以后几位。 + * @return 两个参数的商 + */ + public static double div(double v1, double v2, int scale) + { + if (scale < 0) + { + throw new IllegalArgumentException( + "The scale must be a positive integer or zero"); + } + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + if (b1.compareTo(BigDecimal.ZERO) == 0) + { + return BigDecimal.ZERO.doubleValue(); + } + return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue(); + } + + /** + * 提供精确的小数位四舍五入处理。 + * @param v 需要四舍五入的数字 + * @param scale 小数点后保留几位 + * @return 四舍五入后的结果 + */ + public static double round(double v, int scale) + { + if (scale < 0) + { + throw new IllegalArgumentException( + "The scale must be a positive integer or zero"); + } + BigDecimal b = new BigDecimal(Double.toString(v)); + BigDecimal one = BigDecimal.ONE; + return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/DateUtils.java b/ff-base/src/main/java/com/ff/base/utils/DateUtils.java new file mode 100644 index 0000000..3015c0f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/DateUtils.java @@ -0,0 +1,896 @@ +package com.ff.base.utils; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.lang.management.ManagementFactory; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAdjusters; +import java.util.*; + + +/** + * 时间工具类 + * + * @author ff + */ +public class DateUtils extends org.apache.commons.lang3.time.DateUtils { + public static String YYYY = "yyyy"; + + public static String YYYY_MM = "yyyy-MM"; + + public static String YYYY_MM_DD = "yyyy-MM-dd"; + + public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + + public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + public static String[] parsePatterns = { + "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", + "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", + "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; + + public static String HHMMSS = "HH:mm:ss"; + + public static String DAY_START_TIME = "00:00:00"; + + public static String DAY_END_TIME = "23:59:59"; + + /** + * 获取当前Date型日期 + * + * @return Date() 当前日期 + */ + public static Long getNowDate() { + return Instant.now().toEpochMilli(); + } + + + /** + * 获取当前日期 + * + * @return {@link Long } + */ + public static Date getCurrentDate() { + return new Date(); + } + + /** + * 获取当前日期, 默认格式为yyyy-MM-dd + * + * @return String + */ + public static String getDate() { + return dateTimeNow(YYYY_MM_DD); + } + + public static final String getTime() { + return dateTimeNow(YYYY_MM_DD_HH_MM_SS); + } + + public static final String dateTimeNow() { + return dateTimeNow(YYYYMMDDHHMMSS); + } + + public static final String dateTimeNow(final String format) { + return parseDateToStr(format, new Date()); + } + + public static final String dateTime(final Date date) { + return parseDateToStr(YYYY_MM_DD, date); + } + + public static final String parseDateToStr(final String format, final Date date) { + return new SimpleDateFormat(format).format(date); + } + + public static final Date dateTime(final String format, final String ts) { + try { + return new SimpleDateFormat(format).parse(ts); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + + /** + * 日期路径 即年/月/日 如2018/08/08 + */ + public static final String datePath() { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyy/MM/dd"); + } + + /** + * 日期路径 即年/月/日 如20180808 + */ + public static final String dateTime() { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyyMMdd"); + } + + /** + * 日期型字符串转化为日期 格式 + */ + public static Date parseDate(Object str) { + if (str == null) { + return null; + } + try { + return parseDate(str.toString(), parsePatterns); + } catch (ParseException e) { + return null; + } + } + + /** + * 获取服务器启动时间 + */ + public static Date getServerStartDate() { + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + return new Date(time); + } + + /** + * 计算相差天数 + */ + public static int differentDaysByMillisecond(Date date1, Date date2) { + return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24))); + } + + /** + * 计算时间差 + * + * @param endDate 最后时间 + * @param startTime 开始时间 + * @return 时间差(天/小时/分钟) + */ + public static String timeDistance(Date endDate, Date startTime) { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - startTime.getTime(); + // 计算差多少天 + long day = diff / nd; + // 计算差多少小时 + long hour = diff % nd / nh; + // 计算差多少分钟 + long min = diff % nd % nh / nm; + // 计算差多少秒//输出结果 + // long sec = diff % nd % nh % nm / ns; + return day + "天" + hour + "小时" + min + "分钟"; + } + + /** + * 增加 LocalDateTime ==> Date + */ + public static Date toDate(LocalDateTime temporalAccessor) { + ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } + + /** + * 获取格式化日期yymmd + * + * @return {@link String } + */ + public static String getFormattedDate() { + ZonedDateTime nowUtcMinus4 = ZonedDateTime.now(ZoneId.of("UTC-4")); + + String year = String.format("%02d", nowUtcMinus4.getYear() % 100); + String month = String.format("%02d", nowUtcMinus4.getMonthValue()); + String day = String.valueOf(nowUtcMinus4.getDayOfMonth()); + + return year + month + day; + } + + /** + * 将日期格式化为gmt4 + * + * @param date 日期 + * @return {@link String } + */ + public static String formatDateToGMT4(Date date) { + // 将 Date 转换为 ZonedDateTime + ZonedDateTime zdt = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of("GMT-4")); + // 定义日期时间格式 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); + // 格式化并返回字符串 + return zdt.format(formatter); + } + + /** + * 增加 LocalDate ==> Date + */ + public static Date toDate(LocalDate temporalAccessor) { + LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0)); + ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } + + + /** + * 给定毫秒级时间戳,增加或扣除指定分钟 + * + * @param timestampMillis 初始时间戳(毫秒级) + * @param minutes 要增加或扣除的分钟数(正值为增加,负值为扣除) + * @return long 结果时间戳(毫秒级) + */ + public static long addOrSubtractMinutes(long timestampMillis, int minutes) { + // 将分钟转换为毫秒,并加到时间戳上 + return timestampMillis + minutes * 60 * 1000L; + } + + /** + * 加或减一天 + * + * @param timestampDay 时间戳日期 + * @param day 白天 + * @return long + */ + public static long addOrSubtractDay(long timestampDay, int day) { + // 将分钟转换为毫秒,并加到时间戳上 + return timestampDay + day * 60 * 1000L * 60 * 24; + } + + + /** + * 获取给定日期 + * + * @return 不带时区的给定日期的起始时间戳(毫秒) + */ + public static Long getDayStart(Calendar calendar) { + // 设置时间为当天的 00:00:00 + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTimeInMillis(); + } + + /** + * 获取指定时间戳指定时区的一天的开始时间 + * + * @param timestamp 时间戳 + * @param timeZoneId 时区 + * @return 时间戳 + */ + public static Long getDayStart(long timestamp, String timeZoneId) { + ZoneId zoneId = ZoneId.of(timeZoneId); + ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(java.time.Instant.ofEpochMilli(timestamp), zoneId); + LocalDate localDate = zonedDateTime.toLocalDate(); + LocalDateTime startOfDay = localDate.atStartOfDay(); + ZonedDateTime startOfDayZoned = startOfDay.atZone(zoneId); + return startOfDayZoned.toInstant().toEpochMilli(); + } + + /** + * 获取给定日期 + * + * @return 不带时区的给定日期的结束时间戳(毫秒) + */ + public static Long getDayEnd(Calendar calendar) { + // 设置时间为当天的 23:59:59 + calendar.set(Calendar.HOUR_OF_DAY, 23); + calendar.set(Calendar.MINUTE, 59); + calendar.set(Calendar.SECOND, 59); + calendar.set(Calendar.MILLISECOND, 999); + return calendar.getTimeInMillis(); + } + + /** + * 获取指定时间戳指定时区的一天的结束时间 + * + * @param timestamp 时间戳 + * @param timeZoneId 时区 + * @return 时间戳 + */ + public static Long getDayEnd(long timestamp, String timeZoneId) { + ZoneId zoneId = ZoneId.of(timeZoneId); + ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(java.time.Instant.ofEpochMilli(timestamp), zoneId); + LocalDate localDate = zonedDateTime.toLocalDate(); + LocalDateTime endOfDay = localDate.atTime(23, 59, 59, 999999999); + ZonedDateTime endOfDayZoned = endOfDay.atZone(zoneId); + return endOfDayZoned.toInstant().toEpochMilli(); + } + + /** + * 获取昨天的开始时间(不带时区) + * + * @return 时间戳 + */ + public static Long getYesterdayStart() { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + // 回溯一天 + calendar.add(Calendar.DAY_OF_MONTH, -1); + // 设置时间为当天的 00:00:00 + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTimeInMillis(); + } + + /** + * 获取昨天的结束时间(不带时区) + * + * @return 时间戳 + */ + public static Long getYesterdayEnd() { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + // 回溯一天 + calendar.add(Calendar.DAY_OF_MONTH, -1); + // 设置时间为当天的 23:59:59 + calendar.set(Calendar.HOUR_OF_DAY, 23); + calendar.set(Calendar.MINUTE, 59); + calendar.set(Calendar.SECOND, 59); + calendar.set(Calendar.MILLISECOND, 999); + return calendar.getTimeInMillis(); + } + + /** + * 获取上周的开始时间(不带时区) + * + * @return 时间戳 + */ + public static Long getLastWeekBegin() { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + // 计算上周的起始日期(周一) + calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + calendar.add(Calendar.WEEK_OF_YEAR, -1); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTimeInMillis(); + } + + + /** + * 获取上周的结束时间(不带时区) + * + * @return 时间戳 + */ + public static Long getLastWeekEnd() { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + // 计算上周的结束日期(周日) + calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); + calendar.set(Calendar.HOUR_OF_DAY, 23); + calendar.set(Calendar.MINUTE, 59); + calendar.set(Calendar.SECOND, 59); + calendar.set(Calendar.MILLISECOND, 999); + return calendar.getTimeInMillis(); + } + + /** + * 获取一周的开始时间 + * + * @return 时间戳 + */ + public static Long getWeekBegin(Calendar calendar) { + // 设置一周的第一天为星期一 + calendar.setFirstDayOfWeek(Calendar.MONDAY); + // 获取当前日期在本周的位置 + int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); + // 计算需要回溯的天数 + int daysToSubtract = (dayOfWeek == Calendar.SUNDAY ? 6 : dayOfWeek - 2); + calendar.add(Calendar.DAY_OF_MONTH, -daysToSubtract); + // 设置时间为当天的 00:00:00 + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTimeInMillis(); + } + + /** + * 获取一周的结束时间 + * + * @return 时间戳 + */ + public static Long getWeekEnd(Calendar calendar) { + // 设置一周的第一天为星期一 + calendar.setFirstDayOfWeek(Calendar.MONDAY); + // 获取当前日期在本周的位置 + int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); + // 计算需要前进的天数 + int daysToAdd = (dayOfWeek == Calendar.SUNDAY ? 0 : 7 - (dayOfWeek - 1)); + calendar.add(Calendar.DAY_OF_MONTH, daysToAdd); + // 设置时间为当天的 23:59:59 + calendar.set(Calendar.HOUR_OF_DAY, 23); + calendar.set(Calendar.MINUTE, 59); + calendar.set(Calendar.SECOND, 59); + calendar.set(Calendar.MILLISECOND, 999); + return calendar.getTimeInMillis(); + } + + /** + * 获取当前月份的开始时间 + * + * @return 时间戳 + */ + public static Long getMonthStart(Calendar calendar) { + // 设置时间为当月的第一天 + calendar.set(Calendar.DAY_OF_MONTH, 1); + // 设置时间为当天的 00:00:00 + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTimeInMillis(); + } + + /** + * 获取当前月份的结束时间(不带时区) + * + * @return 时间戳 + */ + public static Long getMonthEnd(Calendar calendar) { + // 设置时间为当月的最后一天 + calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); + // 设置时间为当天的 23:59:59 + calendar.set(Calendar.HOUR_OF_DAY, 23); + calendar.set(Calendar.MINUTE, 59); + calendar.set(Calendar.SECOND, 59); + calendar.set(Calendar.MILLISECOND, 999); + return calendar.getTimeInMillis(); + } + + /** + * 获取上个月的开始时间(不带时区) + * + * @return 时间戳 + */ + public static Long getLastMonthStart() { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + // 计算上个月的起始日期(1号) + calendar.add(Calendar.MONTH, -1); + calendar.set(Calendar.DAY_OF_MONTH, 1); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTimeInMillis(); + } + + /** + * 获取上个月的结束时间(不带时区) + * + * @return 时间戳 + */ + public static Long getLastMonthEnd() { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendar.add(Calendar.MONTH, -1); // 回退一个月 + + // 计算上个月的结束日期(最后一天) + calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); // 设置日期为当月最后一天 + calendar.set(Calendar.HOUR_OF_DAY, 23); // 设置小时为23 + calendar.set(Calendar.MINUTE, 59); // 设置分钟为59 + calendar.set(Calendar.SECOND, 59); // 设置秒为59 + calendar.set(Calendar.MILLISECOND, 999); // 设置毫秒为999 + return calendar.getTimeInMillis(); + } + + + /** + * 判断时间戳 A 距离时间戳 B 近还是距离时间戳 C 近 + * + * @param timestampA 时间戳 A + * @param timestampB 时间戳 B + * @param timestampC 时间戳 C + * @return 返回 true 表示时间戳 A 更接近时间戳 B,返回 false 表示时间戳 A 更接近时间戳 C + */ + public static boolean isCloserToB(long timestampA, long timestampB, long timestampC) { + long diffAB = Math.abs(timestampA - timestampB); + long diffAC = Math.abs(timestampA - timestampC); + return diffAB < diffAC; + } + + + /** + * 获取指定时间戳次日指定时区指定时间的时间戳 + * + * @param utcTimestamp utc时间戳 + * @param date 具体时间 + * @param timeZonId 指定时区 + * @return 只改变时区 不改变具体日期的时间戳 + */ + public static long getTomorrowTimeByZonId(long utcTimestamp, Date date, String timeZonId) { + SimpleDateFormat sdf = new SimpleDateFormat(HHMMSS); + String format = sdf.format(date); + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(HHMMSS); + LocalTime localTime = LocalTime.parse(format, timeFormatter); + // 将时间戳转换为 Instant + Instant instant = Instant.ofEpochMilli(addOrSubtractDay(utcTimestamp, 1)); + ZoneId zoneId = ZoneId.of(timeZonId); + LocalDate localDate = instant.atZone(zoneId).toLocalDate(); + LocalDateTime tomorrowDrawStartTime = localDate.atTime(localTime); + return tomorrowDrawStartTime.atZone(zoneId).toInstant().toEpochMilli(); + } + + + /** + * 指定时区并具体时间的的实时时间戳 + * + * @param date 具体时间 + * @param timeZonId 时区 + * @return 只改变时区 不改变具体日期的时间戳 + */ + public static long getTodayTimeByZonId(Date date, String timeZonId) { + // 获取今日指定时间后的时间戳 + SimpleDateFormat sdf = new SimpleDateFormat(HHMMSS); + String format = sdf.format(date); + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(HHMMSS); + LocalTime localTime = LocalTime.parse(format, timeFormatter); + LocalDate currentDate = LocalDate.now(); + LocalDateTime todayDrawStartTime = currentDate.atTime(localTime); + ZoneId zoneId = ZoneId.of(timeZonId); + return todayDrawStartTime.atZone(zoneId).toInstant().toEpochMilli(); + } + + /** + * 获取下周指定周几的几点的指定时区时间戳 + * + * @param dayOfWeek 周几,1-7表示周一到周日 + * @param date 具体时间,Date对象 + * @return UTC时间戳(毫秒) + */ + public static long getNextWeekTimestamp(int dayOfWeek, Date date, ZoneId zoneId) { + // 将Date对象转换为LocalDateTime对象 + SimpleDateFormat sdf = new SimpleDateFormat(HHMMSS); + String format = sdf.format(date); + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(HHMMSS); + LocalTime localTime = LocalTime.parse(format, timeFormatter); + // 获取当前日期时间 + ZonedDateTime now = ZonedDateTime.now(zoneId); + // 找到本周的周几 + ZonedDateTime startOfWeek = now.with(dayOfWeek < now.getDayOfWeek().getValue() ? TemporalAdjusters.previousOrSame(DayOfWeek.of(dayOfWeek)) : TemporalAdjusters.nextOrSame(DayOfWeek.of(dayOfWeek))); + + // 加上一个完整的星期,得到下周的周几 + ZonedDateTime nextWeekStart = startOfWeek.plusWeeks(1); + + // 设置指定的时间 + ZonedDateTime targetDateTime = nextWeekStart.withHour(localTime.getHour()).withMinute(localTime.getMinute()).withSecond(localTime.getSecond()).withNano(0); + + // 转换为时间戳(毫秒) + return targetDateTime.toInstant().toEpochMilli(); + } + + /** + * 获取指定时区当前周指定周几的几点的时间戳 + * + * @param dayOfWeek 周几,1-7表示周一到周日 + * @param date 具体时间,Date对象 + * @return 时间戳(毫秒) + */ + public static long getCurrentWeekTimestamp(int dayOfWeek, Date date, ZoneId zoneId) { + // 将Date对象转换为LocalDateTime对象 + SimpleDateFormat sdf = new SimpleDateFormat(HHMMSS); + String format = sdf.format(date); + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(HHMMSS); + LocalTime localTime = LocalTime.parse(format, timeFormatter); + + // 获取当前日期时间 + LocalDateTime now = LocalDateTime.now(); + + // 获取当前周的指定周几的日期时间 + LocalDateTime currentWeekDateTime = now.with(dayOfWeek < now.getDayOfWeek().getValue() ? TemporalAdjusters.previousOrSame(DayOfWeek.of(dayOfWeek)) : TemporalAdjusters.nextOrSame(DayOfWeek.of(dayOfWeek))) + .withHour(localTime.getHour()) + .withMinute(localTime.getMinute()) + .withSecond(localTime.getSecond()) + .withNano(0); + + // 将LocalDateTime转换为ZonedDateTime,使用UTC时区 + ZonedDateTime zonedDateTime = currentWeekDateTime.atZone(zoneId); + + // 将ZonedDateTime转换为时间戳(毫秒) + return zonedDateTime.toInstant().toEpochMilli(); + } + + /** + * 获取下月指定日的几点的时间戳 + * + * @param dayOfMonth 指定日,1-31表示 + * @param date 具体时间,Date对象 + * @param month 下几月 + * @return 时间戳(毫秒) + */ + public static long getNextMonthTimestamp(int dayOfMonth, Date date, ZoneId zoneId, int month) { + // 将Date对象转换为LocalDateTime对象 + SimpleDateFormat sdf = new SimpleDateFormat(HHMMSS); + String format = sdf.format(date); + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(HHMMSS); + LocalTime localTime = LocalTime.parse(format, timeFormatter); + + // 获取当前日期时间 + LocalDateTime now = LocalDateTime.now(); + + // 获取下个月的年份和月份 + YearMonth nextMonth = YearMonth.from(now).plusMonths(month); + int maxDayNum = nextMonth.lengthOfMonth(); + if (dayOfMonth > maxDayNum) { + dayOfMonth = maxDayNum; + } + + // 创建下个月指定日的LocalDateTime对象 + LocalDateTime nextMonthDateTime = LocalDateTime.of(nextMonth.getYear(), nextMonth.getMonth(), dayOfMonth, + localTime.getHour(), localTime.getMinute(), localTime.getSecond(), 0); + + // 将LocalDateTime转换为ZonedDateTime,使用UTC时区 + ZonedDateTime zonedDateTime = nextMonthDateTime.atZone(zoneId); + + // 将ZonedDateTime转换为时间戳(毫秒) + return zonedDateTime.toInstant().toEpochMilli(); + } + + /** + * 获取本月指定日的几点的时间戳 + * + * @param dayOfMonth 指定日,1-31表示 + * @param date 具体时间,Date对象 + * @return 时间戳(毫秒) + */ + public static long getCurrentMonthTimestamp(int dayOfMonth, Date date, ZoneId zoneId) { + // 将Date对象转换为LocalDateTime对象 + SimpleDateFormat sdf = new SimpleDateFormat(HHMMSS); + String format = sdf.format(date); + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(HHMMSS); + LocalTime localTime = LocalTime.parse(format, timeFormatter); + + // 获取当前日期时间 + LocalDateTime now = LocalDateTime.now(); + // 获取本月的年份和月份 + YearMonth currentMonth = YearMonth.from(now); + int maxDayNum = currentMonth.lengthOfMonth(); + if (dayOfMonth > maxDayNum) { + dayOfMonth = maxDayNum; + } + + // 创建本月指定日的LocalDateTime对象 + LocalDateTime currentMonthDateTime = LocalDateTime.of(currentMonth.getYear(), currentMonth.getMonth(), dayOfMonth, + localTime.getHour(), localTime.getMinute(), localTime.getSecond(), 0); + + // 将LocalDateTime转换为ZonedDateTime,使用UTC时区 + ZonedDateTime zonedDateTime = currentMonthDateTime.atZone(zoneId); + + // 将ZonedDateTime转换为时间戳(毫秒) + return zonedDateTime.toInstant().toEpochMilli(); + } + + + /** + * 将时间戳转换为UTC0时区的时间戳 + * + * @param timeZoneId 时区id + * @param timestamp 时间戳 + * @return UTC0时区的时间戳 + */ + public static long covertToUTCtimestamp(String timeZoneId, long timestamp) { + // 将时间戳转换为 Instant 对象 + Instant instant = Instant.ofEpochMilli(timestamp); + + // 使用指定的时区将 Instant 对象转换为 ZonedDateTime 对象 + ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of(timeZoneId)); + ZonedDateTime zonedDateTime1 = zonedDateTime.withZoneSameLocal(ZoneOffset.UTC); + // 将 ZonedDateTime 对象转换为 UTC0 时区的 Instant 对象 + + // 获取 UTC0 时区的时间戳(以毫秒为单位) + return zonedDateTime1.toInstant().toEpochMilli(); + } + + /** + * 将UTC时间戳转换为指定时区的时间戳 + * + * @param timeZoneId 时区id + * @param timestamp 时间戳 + * @return 指定时区的时间戳 + */ + public static long covertUTCTotimeZonetimestamp(String timeZoneId, long timestamp) { + // 将时间戳转换为 Instant 对象 + Instant instant = Instant.ofEpochMilli(timestamp); + + // 使用指定的时区将 Instant 对象转换为 ZonedDateTime 对象 + ZonedDateTime zonedDateTime = instant.atZone(ZoneOffset.UTC); + ZonedDateTime zonedDateTime1 = zonedDateTime.withZoneSameLocal(ZoneId.of(timeZoneId)); + // 获取 指定 时区的时间戳(以毫秒为单位) + return zonedDateTime1.toInstant().toEpochMilli(); + } + + /** + * 判断是否是指定时区的当天的0点 + * + * @param timestamp + * @param timeZone + * @return + */ + public static boolean isMidnight(long timestamp, TimeZone timeZone) { + Calendar calendar = Calendar.getInstance(timeZone); + calendar.setTimeInMillis(timestamp); + + return calendar.get(Calendar.HOUR_OF_DAY) == 0 && + calendar.get(Calendar.MINUTE) == 0 && + calendar.get(Calendar.SECOND) == 0 && + calendar.get(Calendar.MILLISECOND) == 0; + } + + /** + * 判断是否是指定时区的周一的0点 + * + * @param timestamp 时间戳 + * @param timeZone 指定时区 + * @return 是否是周一的0点 + */ + public static boolean isMondayMidnight(long timestamp, TimeZone timeZone) { + Calendar calendar = Calendar.getInstance(timeZone); + calendar.setTimeInMillis(timestamp); + + return isMidnight(timestamp, timeZone) && calendar.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY; + } + + /** + * 将 ISO 8601 格式的时间字符串转换为毫秒时间戳 + * + * @param isoDate ISO 8601 格式的时间字符串,例如 "2025-05-10T08:23:34Z" + * @return 从 Unix epoch 开始的毫秒时间戳 + */ + public static long convertToMilliseconds(String isoDate) { + Instant instant = Instant.parse(isoDate); + return instant.toEpochMilli(); + } + + + /** + * 将 ZoneId 转换为 TimeZone + * + * @param zoneId 要转换的 ZoneId + * @return 对应的 TimeZone + */ + public static TimeZone zoneIdToTimeZone(ZoneId zoneId) { + return TimeZone.getTimeZone(zoneId.getId()); + } + + /** + * 获取指定星期几的开始和结束UTC时间戳 + * + * @param dayOfWeek 星期几,1-7,1表示星期一,7表示星期日 + * @return 包含开始和结束UTC时间戳的数组,第一个元素是开始时间戳,第二个元素是结束时间戳 + */ + public static Map getStartAndEndUTCTimestampOfDayOfWeek(int dayOfWeek) { + if (dayOfWeek < 1 || dayOfWeek > 7) { + throw new IllegalArgumentException("dayOfWeek must be between 1 and 7"); + } + + // 获取当前日期 + LocalDate today = LocalDate.now(ZoneOffset.UTC); + // 计算本周的开始日期(星期一) + LocalDate monday = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); + // 计算指定星期几的日期 + LocalDate targetDay = monday.plusDays(dayOfWeek - 1); + + // 计算指定星期几的开始时间(00:00:00 UTC) + ZonedDateTime startOfDay = targetDay.atStartOfDay(ZoneOffset.UTC); + // 计算指定星期几的结束时间(23:59:59 UTC) + ZonedDateTime endOfDay = targetDay.atTime(LocalTime.MAX).atZone(ZoneOffset.UTC); + + // 获取开始和结束时间戳 + long startTimestamp = startOfDay.toInstant().toEpochMilli(); + long endTimestamp = endOfDay.toInstant().toEpochMilli(); + + Map map = new HashMap<>(); + map.put("beginTime", startTimestamp); + map.put("endTime", endTimestamp); + return map; + } + + /** + * 获取本月指定月几号的开始和结束UTC时间戳 + * + * @param dayOfMonth 本月几号,1-31 + * @return 包含开始和结束UTC时间戳的Map,键分别为"beginTime"和"endTime" + */ + public static Map getStartAndEndUTCTimestampOfDayOfMonth(int dayOfMonth) { + // 获取当前日期 + LocalDate today = LocalDate.now(ZoneOffset.UTC); + // 获取本月的年份和月份 + YearMonth currentMonth = YearMonth.from(today); + int maxDayNum = currentMonth.lengthOfMonth(); + if (dayOfMonth > maxDayNum) { + dayOfMonth = maxDayNum; + } + // 获取当前年份和月份 + int year = today.getYear(); + int month = today.getMonthValue(); + + // 构建指定月几号的日期 + LocalDate targetDay; + try { + targetDay = LocalDate.of(year, month, dayOfMonth); + } catch (DateTimeException e) { + throw new IllegalArgumentException("Invalid dayOfMonth for the current month", e); + } + + // 计算指定月几号的开始时间(00:00:00 UTC) + ZonedDateTime startOfDay = targetDay.atStartOfDay(ZoneOffset.UTC); + // 计算指定月几号的结束时间(23:59:59 UTC) + ZonedDateTime endOfDay = targetDay.atTime(LocalTime.MAX).atZone(ZoneOffset.UTC); + + // 获取开始和结束时间戳 + long startTimestamp = startOfDay.toInstant().toEpochMilli(); + long endTimestamp = endOfDay.toInstant().toEpochMilli(); + + Map map = new HashMap<>(); + map.put("beginTime", startTimestamp); + map.put("endTime", endTimestamp); + return map; + } + + /** + * 判断两个毫秒级时间戳是否为同一天 + * + * @param timestamp1 第一个时间戳 + * @param timestamp2 第二个时间戳 + * @return 如果两个时间戳属于同一天,返回true;否则返回false + */ + public static boolean isSameDay(long timestamp1, long timestamp2) { + // 将时间戳转换为 LocalDate + LocalDate date1 = Instant.ofEpochMilli(timestamp1) + .atZone(ZoneId.systemDefault()) // 使用系统默认时区 + .toLocalDate(); + + LocalDate date2 = Instant.ofEpochMilli(timestamp2) + .atZone(ZoneId.systemDefault()) // 使用系统默认时区 + .toLocalDate(); + + // 比较日期部分是否相同 + return date1.isEqual(date2); + } + + /** + * 获取 UTC 时区的当前日期,并返回 java.util.Date 类型 + * + * @return java.util.Date 对象,表示 UTC 时区的当前日期 + */ + public static Date getUTCDate() { + // 获取 UTC 时区的当前时间 + ZonedDateTime utcTime = ZonedDateTime.now(ZoneId.of("UTC")); + + // 提取 UTC 时区的日期部分 + ZonedDateTime utcDateTime = utcTime.toLocalDate().atStartOfDay(ZoneId.of("UTC")); + + // 将 ZonedDateTime 转换为 java.util.Date + return Date.from(utcDateTime.toInstant()); + } + + /** + * 将 LocalTime 转换为 Date + * + * @param localTime LocalTime对象 + * @return Date对象 + */ + public static Date convertToDate(LocalTime localTime) { + // 使用当前日期作为参考日期 + LocalDate today = LocalDate.now(); + + // 将 LocalTime 和 LocalDate 结合成 LocalDateTime + LocalDateTime localDateTime = LocalDateTime.of(today, localTime); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + String format = localDateTime.format(formatter); + // 将 LocalDateTime 转换为 Date + return DateUtils.parseDate(format); + } + + /** + * 判断是否在指定时间段内 + * + * @param value 要判断的时间戳 + * @param minValue 开始时间戳 + * @param maxValue 结束时间戳 + * @return 是否在指定时间段内 + */ + public static boolean isBetween(Long value, Long minValue, Long maxValue) { + return value >= minValue && value <= maxValue; + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/DesensitizedUtil.java b/ff-base/src/main/java/com/ff/base/utils/DesensitizedUtil.java new file mode 100644 index 0000000..eb48a3f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/DesensitizedUtil.java @@ -0,0 +1,51 @@ +package com.ff.base.utils; + +import com.ff.base.utils.StringUtils; + +/** + * 脱敏工具类 + * + * @author ff + */ +public class DesensitizedUtil +{ + /** + * 密码的全部字符都用*代替,比如:****** + * + * @param password 密码 + * @return 脱敏后的密码 + */ + public static String password(String password) + { + if (StringUtils.isBlank(password)) + { + return StringUtils.EMPTY; + } + return StringUtils.repeat('*', password.length()); + } + + /** + * 车牌中间用*代替,如果是错误的车牌,不处理 + * + * @param carLicense 完整的车牌号 + * @return 脱敏后的车牌 + */ + public static String carLicense(String carLicense) + { + if (StringUtils.isBlank(carLicense)) + { + return StringUtils.EMPTY; + } + // 普通车牌 + if (carLicense.length() == 7) + { + carLicense = StringUtils.hide(carLicense, 3, 6); + } + else if (carLicense.length() == 8) + { + // 新能源车牌 + carLicense = StringUtils.hide(carLicense, 3, 7); + } + return carLicense; + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/DictUtils.java b/ff-base/src/main/java/com/ff/base/utils/DictUtils.java new file mode 100644 index 0000000..fd73253 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/DictUtils.java @@ -0,0 +1,240 @@ +package com.ff.base.utils; + +import com.alibaba.fastjson2.JSONArray; +import com.ff.base.constant.CacheConstants; +import com.ff.base.system.domain.SysDictData; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.utils.spring.SpringUtils; + +import java.util.Collection; +import java.util.List; + +/** + * 字典工具类 + * + * @author ff + */ +public class DictUtils +{ + /** + * 分隔符 + */ + public static final String SEPARATOR = ","; + + /** + * 设置字典缓存 + * + * @param key 参数键 + * @param dictDatas 字典数据列表 + */ + public static void setDictCache(String key, List dictDatas) + { + SpringUtils.getBean(RedisCache.class).setCacheObject(getCacheKey(key), dictDatas); + } + + /** + * 获取字典缓存 + * + * @param key 参数键 + * @return dictDatas 字典数据列表 + */ + public static List getDictCache(String key) + { + JSONArray arrayCache = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key)); + if (StringUtils.isNotNull(arrayCache)) + { + return arrayCache.toList(SysDictData.class); + } + return null; + } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @return 字典标签 + */ + public static String getDictLabel(String dictType, String dictValue) + { + if (StringUtils.isEmpty(dictValue)) + { + return StringUtils.EMPTY; + } + return getDictLabel(dictType, dictValue, SEPARATOR); + } + + /** + * 根据字典类型和字典标签获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel 字典标签 + * @return 字典值 + */ + public static String getDictValue(String dictType, String dictLabel) + { + if (StringUtils.isEmpty(dictLabel)) + { + return StringUtils.EMPTY; + } + return getDictValue(dictType, dictLabel, SEPARATOR); + } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @param separator 分隔符 + * @return 字典标签 + */ + public static String getDictLabel(String dictType, String dictValue, String separator) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + if (StringUtils.isNull(datas)) + { + return StringUtils.EMPTY; + } + if (StringUtils.containsAny(separator, dictValue)) + { + for (SysDictData dict : datas) + { + for (String value : dictValue.split(separator)) + { + if (value.equals(dict.getDictValue())) + { + propertyString.append(dict.getDictLabel()).append(separator); + break; + } + } + } + } + else + { + for (SysDictData dict : datas) + { + if (dictValue.equals(dict.getDictValue())) + { + return dict.getDictLabel(); + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 根据字典类型和字典标签获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel 字典标签 + * @param separator 分隔符 + * @return 字典值 + */ + public static String getDictValue(String dictType, String dictLabel, String separator) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + if (StringUtils.isNull(datas)) + { + return StringUtils.EMPTY; + } + if (StringUtils.containsAny(separator, dictLabel)) + { + for (SysDictData dict : datas) + { + for (String label : dictLabel.split(separator)) + { + if (label.equals(dict.getDictLabel())) + { + propertyString.append(dict.getDictValue()).append(separator); + break; + } + } + } + } + else + { + for (SysDictData dict : datas) + { + if (dictLabel.equals(dict.getDictLabel())) + { + return dict.getDictValue(); + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 根据字典类型获取字典所有值 + * + * @param dictType 字典类型 + * @return 字典值 + */ + public static String getDictValues(String dictType) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + if (StringUtils.isNull(datas)) + { + return StringUtils.EMPTY; + } + for (SysDictData dict : datas) + { + propertyString.append(dict.getDictValue()).append(SEPARATOR); + } + return StringUtils.stripEnd(propertyString.toString(), SEPARATOR); + } + + /** + * 根据字典类型获取字典所有标签 + * + * @param dictType 字典类型 + * @return 字典值 + */ + public static String getDictLabels(String dictType) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + if (StringUtils.isNull(datas)) + { + return StringUtils.EMPTY; + } + for (SysDictData dict : datas) + { + propertyString.append(dict.getDictLabel()).append(SEPARATOR); + } + return StringUtils.stripEnd(propertyString.toString(), SEPARATOR); + } + + /** + * 删除指定字典缓存 + * + * @param key 字典键 + */ + public static void removeDictCache(String key) + { + SpringUtils.getBean(RedisCache.class).deleteObject(getCacheKey(key)); + } + + /** + * 清空字典缓存 + */ + public static void clearDictCache() + { + Collection keys = SpringUtils.getBean(RedisCache.class).keys(CacheConstants.SYS_DICT_KEY + "*"); + SpringUtils.getBean(RedisCache.class).deleteObject(keys); + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + public static String getCacheKey(String configKey) + { + return CacheConstants.SYS_DICT_KEY + configKey; + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/ExceptionUtil.java b/ff-base/src/main/java/com/ff/base/utils/ExceptionUtil.java new file mode 100644 index 0000000..92f0a8f --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/ExceptionUtil.java @@ -0,0 +1,40 @@ +package com.ff.base.utils; + +import org.apache.commons.lang3.exception.ExceptionUtils; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * 错误信息处理类。 + * + * @author ff + */ +public class ExceptionUtil +{ + /** + * 获取exception的详细错误信息。 + */ + public static String getExceptionMessage(Throwable e) + { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw, true)); + return sw.toString(); + } + + public static String getRootErrorMessage(Exception e) + { + Throwable root = ExceptionUtils.getRootCause(e); + root = (root == null ? e : root); + if (root == null) + { + return ""; + } + String msg = root.getMessage(); + if (msg == null) + { + return "null"; + } + return StringUtils.defaultString(msg); + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/JsonUtil.java b/ff-base/src/main/java/com/ff/base/utils/JsonUtil.java new file mode 100644 index 0000000..f87c94e --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/JsonUtil.java @@ -0,0 +1,118 @@ +package com.ff.base.utils; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +import java.text.SimpleDateFormat; +import java.util.Map; +import java.util.stream.Collectors; + +public class JsonUtil { + + /** + * 定义映射对象 + */ + public static ObjectMapper objectMapper = new ObjectMapper(); + + /** + * 日期格式化 + */ + private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + + static { + //对象的所有字段全部列入 + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + //取消默认转换timestamps形式 + objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + //忽略空Bean转json的错误 + objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + //所有的日期格式都统一为以下的样式,即yyyy-MM-dd HH:mm:ss + objectMapper.setDateFormat(new SimpleDateFormat(DATE_FORMAT)); + //忽略 在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误 + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + } + + /** + * string转JsonNode + * + * @param jsonString + * @return com.fasterxml.jackson.databind.JsonNode + */ + public static JsonNode stringToJsonNode(String jsonString) throws JsonProcessingException { + + return objectMapper.readTree(jsonString); + + } + + /** + * 对象转json字符串 + * + * @param obj + * @param + */ + public static String objToString(T obj) { + + if (obj == null) { + return null; + } + try { + return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj); + } catch (JsonProcessingException e) { + return null; + } + } + + /** + * 对象转格式化的字符串字符串 + * + * @param obj + * @param + * @return + */ + public static String objToPrettyString(T obj) { + if (obj == null) { + return null; + } + try { + return obj instanceof String ? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj); + } catch (JsonProcessingException e) { + return null; + } + } + + /** + * json字符串转对象 + * + * @param jsonString + * @param cls + * @param + */ + public static T stringToObj(String jsonString, Class cls) { + if (StringUtils.isEmpty(jsonString) || cls == null) { + return null; + } + try { + return cls.equals(String.class) ? (T) jsonString : objectMapper.readValue(jsonString, cls); + } catch (JsonProcessingException e) { + return null; + } + } + + /** + * 映射到查询字符串 + * + * @param map 地图 + * @return {@link String } + */// 将LinkedHashMap转换为查询字符串 + public static String mapToQueryString(Map map) { + return map.entrySet().stream() + .map(entry -> entry.getKey() + "=" + entry.getValue()) + .collect(Collectors.joining("&")); + } + +} diff --git a/ff-base/src/main/java/com/ff/base/utils/LogUtils.java b/ff-base/src/main/java/com/ff/base/utils/LogUtils.java new file mode 100644 index 0000000..fe1a031 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/LogUtils.java @@ -0,0 +1,18 @@ +package com.ff.base.utils; + +/** + * 处理并记录日志文件 + * + * @author ff + */ +public class LogUtils +{ + public static String getBlock(Object msg) + { + if (msg == null) + { + msg = ""; + } + return "[" + msg.toString() + "]"; + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/MessageUtils.java b/ff-base/src/main/java/com/ff/base/utils/MessageUtils.java new file mode 100644 index 0000000..7f9ff8d --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/MessageUtils.java @@ -0,0 +1,26 @@ +package com.ff.base.utils; + +import com.ff.base.utils.spring.SpringUtils; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; + +/** + * 获取i18n资源文件 + * + * @author ff + */ +public class MessageUtils +{ + /** + * 根据消息键和参数 获取消息 委托给spring messageSource + * + * @param code 消息键 + * @param args 参数 + * @return 获取国际化翻译值 + */ + public static String message(String code, Object... args) + { + MessageSource messageSource = SpringUtils.getBean(MessageSource.class); + return messageSource.getMessage(code, args, LocaleContextHolder.getLocale()); + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/NumberUtils.java b/ff-base/src/main/java/com/ff/base/utils/NumberUtils.java new file mode 100644 index 0000000..2559d2e --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/NumberUtils.java @@ -0,0 +1,60 @@ +package com.ff.base.utils; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; + +public class NumberUtils { + + + + /** + * 计算比例 + * + * @param totalCount 总计数 + * @param remainingCount 剩余计数 + * @param scale 规模 + * @return {@link BigDecimal } + */ + public static BigDecimal calculateProportion(Number totalCount, Number remainingCount, int scale) { + BigDecimal total = Optional.ofNullable(totalCount) + .map(val -> new BigDecimal(val.toString())) + .orElse(BigDecimal.ZERO); + BigDecimal remaining = Optional.ofNullable(remainingCount) + .map(val -> new BigDecimal(val.toString())) + .orElse(BigDecimal.ZERO); + + if (total.compareTo(BigDecimal.ZERO) != 0) { + return remaining.divide(total, scale, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2, RoundingMode.DOWN); + } else { + return BigDecimal.ZERO; + } + } + + /** + * 在两个 BigDecimal 数值之间生成一个随机数 + * + * @param min 最小值 + * @param max 最大值 + * @return 随机生成的 BigDecimal 数值 + */ + public static BigDecimal getRandomBigDecimal(BigDecimal min, BigDecimal max) { + // 确保 min 小于 max + if (min.compareTo(max) > 0) { + throw new IllegalArgumentException("最小值应小于最大值"); + } + + // 计算范围的差值 + BigDecimal range = max.subtract(min); + + // 使用 ThreadLocalRandom 生成 [0, 1) 之间的随机数 + double randomDouble = ThreadLocalRandom.current().nextDouble(); + + // 计算随机值 + BigDecimal randomValue = min.add(range.multiply(BigDecimal.valueOf(randomDouble))); + + // 设置保留两位小数 + return randomValue.setScale(2, RoundingMode.HALF_UP); + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/PageUtils.java b/ff-base/src/main/java/com/ff/base/utils/PageUtils.java new file mode 100644 index 0000000..8c6182e --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/PageUtils.java @@ -0,0 +1,35 @@ +package com.ff.base.utils; + +import com.github.pagehelper.PageHelper; +import com.ff.base.core.page.PageDomain; +import com.ff.base.core.page.TableSupport; +import com.ff.base.utils.sql.SqlUtil; + +/** + * 分页工具类 + * + * @author ff + */ +public class PageUtils extends PageHelper +{ + /** + * 设置请求分页数据 + */ + public static void startPage() + { + PageDomain pageDomain = TableSupport.buildPageRequest(); + Integer pageNum = pageDomain.getPageNum(); + Integer pageSize = pageDomain.getPageSize(); + String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); + Boolean reasonable = pageDomain.getReasonable(); + PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable); + } + + /** + * 清理分页的线程变量 + */ + public static void clearPage() + { + PageHelper.clearPage(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/SecurityUtils.java b/ff-base/src/main/java/com/ff/base/utils/SecurityUtils.java new file mode 100644 index 0000000..65cc993 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/SecurityUtils.java @@ -0,0 +1,243 @@ +package com.ff.base.utils; + +import com.ff.base.constant.Constants; +import com.ff.base.constant.HttpStatus; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.exception.ServiceException; +import com.ff.base.system.domain.SysRole; +import com.ff.base.utils.bean.BeanUtils; +import com.ff.base.utils.sign.Md5Utils; +import com.ff.base.utils.spring.SpringUtils; +import com.ff.base.web.service.TokenService; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.util.PatternMatchUtils; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 安全服务工具类 + * + * @author ff + */ +public class SecurityUtils +{ + + /** + * 获取当前登录用户币种 + * @return {@link String } + */ + public static String getUserCurrencyType(){ + return getLoginUser().getCurrencyType(); + } + + + /** + * 获取用户id或null + * + * @return {@link Long } + */ + public static Long getUserIdOrNull() + { + try + { + return getLoginUser().getUserId(); + } + catch (Exception e) + { + return null; + } + } + + /** + * 用户ID + **/ + public static Long getUserId() + { + try + { + return getLoginUser().getUserId(); + } + catch (Exception e) + { + throw new ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取部门ID + **/ + public static Long getDeptId() + { + try + { + return getLoginUser().getDeptId(); + } + catch (Exception e) + { + throw new ServiceException("获取部门ID异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取用户账户 + **/ + public static String getUsername() + { + try + { + return getLoginUser().getUsername(); + } + catch (Exception e) + { + throw new ServiceException("获取用户账户异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取用户账户 + **/ + public static String getUsernameOrNull() + { + try + { + return getLoginUser().getUsername(); + } + catch (Exception e) + { + return null; + } + } + + + /** + * 获取用户 + **/ + public static LoginUser getLoginUser() + { + try + { + return (LoginUser) getAuthentication().getPrincipal(); + } + catch (Exception e) + { + throw new ServiceException("获取用户信息异常", HttpStatus.UNAUTHORIZED); + } + } + + public static void setLoginUser(LoginUser loginUser) + { + try + { + LoginUser principal = (LoginUser) getAuthentication().getPrincipal(); + BeanUtils.copyProperties(loginUser,principal); + UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); + UsernamePasswordAuthenticationToken copy = new UsernamePasswordAuthenticationToken(principal,null); + // 修改原对象为空的字段不修改 + BeanUtils.nullAwareCopyProperties(copy,authentication); + SecurityContextHolder.getContext().setAuthentication(authentication); + SpringUtils.getBean(TokenService.class).setLoginUser(loginUser); + + } + catch (Exception e) + { + throw new ServiceException("获取用户信息异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取Authentication + */ + public static Authentication getAuthentication() + { + return SecurityContextHolder.getContext().getAuthentication(); + } + + /** + * 生成BCryptPasswordEncoder密码 + * + * @param password 密码 + * @return 加密字符串 + */ + public static String encryptPassword(String password) + { + return Md5Utils.hash(password); + } + + /** + * 判断密码是否相同 + * + * @param rawPassword 真实密码 + * @param encodedPassword 加密后字符 + * @return 结果 + */ + public static boolean matchesPassword(String rawPassword, String encodedPassword) + { + return StringUtils.equals(Md5Utils.hash(rawPassword), encodedPassword); + } + + /** + * 是否为管理员 + * + * @param userId 用户ID + * @return 结果 + */ + public static boolean isAdmin(Long userId) + { + return userId != null && 1L == userId; + } + + /** + * 验证用户是否具备某权限 + * + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public static boolean hasPermi(String permission) + { + return hasPermi(getLoginUser().getPermissions(), permission); + } + + /** + * 判断是否包含权限 + * + * @param authorities 权限列表 + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public static boolean hasPermi(Collection authorities, String permission) + { + return authorities.stream().filter(StringUtils::hasText) + .anyMatch(x -> Constants.ALL_PERMISSION.equals(x) || PatternMatchUtils.simpleMatch(x, permission)); + } + + /** + * 验证用户是否拥有某个角色 + * + * @param role 角色标识 + * @return 用户是否具备某角色 + */ + public static boolean hasRole(String role) + { + List roleList = getLoginUser().getUser().getRoles(); + Collection roles = roleList.stream().map(SysRole::getRoleKey).collect(Collectors.toSet()); + return hasRole(roles, role); + } + + /** + * 判断是否包含角色 + * + * @param roles 角色列表 + * @param role 角色 + * @return 用户是否具备某角色权限 + */ + public static boolean hasRole(Collection roles, String role) + { + return roles.stream().filter(StringUtils::hasText) + .anyMatch(x -> Constants.SUPER_ADMIN.equals(x) || PatternMatchUtils.simpleMatch(x, role)); + } + +} diff --git a/ff-base/src/main/java/com/ff/base/utils/ServletUtils.java b/ff-base/src/main/java/com/ff/base/utils/ServletUtils.java new file mode 100644 index 0000000..e90caa0 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/ServletUtils.java @@ -0,0 +1,220 @@ +package com.ff.base.utils; + +import com.ff.base.constant.Constants; +import com.ff.base.core.text.Convert; +import com.ff.base.utils.StringUtils; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * 客户端工具类 + * + * @author ff + */ +public class ServletUtils +{ + /** + * 获取String参数 + */ + public static String getParameter(String name) + { + return getRequest().getParameter(name); + } + + /** + * 获取String参数 + */ + public static String getParameter(String name, String defaultValue) + { + return Convert.toStr(getRequest().getParameter(name), defaultValue); + } + + /** + * 获取Integer参数 + */ + public static Integer getParameterToInt(String name) + { + return Convert.toInt(getRequest().getParameter(name)); + } + + /** + * 获取Integer参数 + */ + public static Integer getParameterToInt(String name, Integer defaultValue) + { + return Convert.toInt(getRequest().getParameter(name), defaultValue); + } + + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name) + { + return Convert.toBool(getRequest().getParameter(name)); + } + + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name, Boolean defaultValue) + { + return Convert.toBool(getRequest().getParameter(name), defaultValue); + } + + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParams(ServletRequest request) + { + final Map map = request.getParameterMap(); + return Collections.unmodifiableMap(map); + } + + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParamMap(ServletRequest request) + { + Map params = new HashMap<>(); + for (Map.Entry entry : getParams(request).entrySet()) + { + params.put(entry.getKey(), StringUtils.join(entry.getValue(), ",")); + } + return params; + } + + /** + * 获取request + */ + public static HttpServletRequest getRequest() + { + return getRequestAttributes().getRequest(); + } + + /** + * 获取response + */ + public static HttpServletResponse getResponse() + { + return getRequestAttributes().getResponse(); + } + + /** + * 获取session + */ + public static HttpSession getSession() + { + return getRequest().getSession(); + } + + public static ServletRequestAttributes getRequestAttributes() + { + RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); + return (ServletRequestAttributes) attributes; + } + + /** + * 将字符串渲染到客户端 + * + * @param response 渲染对象 + * @param string 待渲染的字符串 + */ + public static void renderString(HttpServletResponse response, String string) + { + try + { + response.setStatus(200); + response.setContentType("application/json"); + response.setCharacterEncoding("utf-8"); + response.getWriter().print(string); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + /** + * 是否是Ajax异步请求 + * + * @param request + */ + public static boolean isAjaxRequest(HttpServletRequest request) + { + String accept = request.getHeader("accept"); + if (accept != null && accept.contains("application/json")) + { + return true; + } + + String xRequestedWith = request.getHeader("X-Requested-With"); + if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) + { + return true; + } + + String uri = request.getRequestURI(); + if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) + { + return true; + } + + String ajax = request.getParameter("__ajax"); + return StringUtils.inStringIgnoreCase(ajax, "json", "xml"); + } + + /** + * 内容编码 + * + * @param str 内容 + * @return 编码后的内容 + */ + public static String urlEncode(String str) + { + try + { + return URLEncoder.encode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } + + /** + * 内容解码 + * + * @param str 内容 + * @return 解码后的内容 + */ + public static String urlDecode(String str) + { + try + { + return URLDecoder.decode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/SnowflakeIdGenerator.java b/ff-base/src/main/java/com/ff/base/utils/SnowflakeIdGenerator.java new file mode 100644 index 0000000..38d1579 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/SnowflakeIdGenerator.java @@ -0,0 +1,73 @@ +package com.ff.base.utils; +/** + * 雪花算法id + * + * @author liukang + * @date 2024-11-04 + */ +public class SnowflakeIdGenerator { + + private static final long EPOCH = 1609459200000L; // 自定义起始时间戳,例如2021-01-01 00:00:00 + private static final long WORKER_ID_BITS = 5L; + private static final long DATA_CENTER_ID_BITS = 5L; + private static final long SEQUENCE_BITS = 12L; + + private static final long MAX_WORKER_ID = -1L ^ (-1L << WORKER_ID_BITS); + private static final long MAX_DATA_CENTER_ID = -1L ^ (-1L << DATA_CENTER_ID_BITS); + private static final long SEQUENCE_MASK = -1L ^ (-1L << SEQUENCE_BITS); + + private static final long WORKER_ID_SHIFT = SEQUENCE_BITS; + private static final long DATA_CENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS; + private static final long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATA_CENTER_ID_BITS; + + private long workerId; + private long dataCenterId; + private long sequence = 0L; + private long lastTimestamp = -1L; + + public SnowflakeIdGenerator(long workerId, long dataCenterId) { + if (workerId > MAX_WORKER_ID || workerId < 0) { + throw new IllegalArgumentException("worker Id can't be greater than " + MAX_WORKER_ID + " or less than 0"); + } + if (dataCenterId > MAX_DATA_CENTER_ID || dataCenterId < 0) { + throw new IllegalArgumentException("data center Id can't be greater than " + MAX_DATA_CENTER_ID + " or less than 0"); + } + this.workerId = workerId; + this.dataCenterId = dataCenterId; + } + + public synchronized long nextId() { + long timestamp = timeGen(); + if (timestamp < lastTimestamp) { + throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); + } + + if (lastTimestamp == timestamp) { + sequence = (sequence + 1) & SEQUENCE_MASK; + if (sequence == 0) { + timestamp = tilNextMillis(lastTimestamp); + } + } else { + sequence = 0L; + } + + lastTimestamp = timestamp; + + return ((timestamp - EPOCH) << TIMESTAMP_LEFT_SHIFT) | + (dataCenterId << DATA_CENTER_ID_SHIFT) | + (workerId << WORKER_ID_SHIFT) | + sequence; + } + + protected long tilNextMillis(long lastTimestamp) { + long timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + protected long timeGen() { + return System.currentTimeMillis(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/StringUtils.java b/ff-base/src/main/java/com/ff/base/utils/StringUtils.java new file mode 100644 index 0000000..721c628 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/StringUtils.java @@ -0,0 +1,610 @@ +package com.ff.base.utils; + +import com.ff.base.constant.ConfigConstants; +import com.ff.base.constant.Constants; +import com.ff.base.core.text.StrFormatter; +import org.springframework.util.AntPathMatcher; + +import java.util.*; + +/** + * 字符串工具类 + * + * @author ff + */ +public class StringUtils extends org.apache.commons.lang3.StringUtils { + /** + * 空字符串 + */ + private static final String NULLSTR = ""; + + /** + * 下划线 + */ + private static final char SEPARATOR = '_'; + + /** + * 星号 + */ + private static final char ASTERISK = '*'; + + /** + * 获取参数不为空值 + * + * @param value defaultValue 要判断的value + * @return value 返回值 + */ + public static T nvl(T value, T defaultValue) { + return value != null ? value : defaultValue; + } + + /** + * * 判断一个Collection是否为空, 包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Collection coll) { + return isNull(coll) || coll.isEmpty(); + } + + /** + * * 判断一个Collection是否非空,包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Collection coll) { + return !isEmpty(coll); + } + + /** + * * 判断一个对象数组是否为空 + * + * @param objects 要判断的对象数组 + * * @return true:为空 false:非空 + */ + public static boolean isEmpty(Object[] objects) { + return isNull(objects) || (objects.length == 0); + } + + /** + * * 判断一个对象数组是否非空 + * + * @param objects 要判断的对象数组 + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Object[] objects) { + return !isEmpty(objects); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Map map) { + return isNull(map) || map.isEmpty(); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Map map) { + return !isEmpty(map); + } + + /** + * * 判断一个字符串是否为空串 + * + * @param str String + * @return true:为空 false:非空 + */ + public static boolean isEmpty(String str) { + return isNull(str) || NULLSTR.equals(str.trim()); + } + + /** + * * 判断一个字符串是否为非空串 + * + * @param str String + * @return true:非空串 false:空串 + */ + public static boolean isNotEmpty(String str) { + return !isEmpty(str); + } + + /** + * * 判断一个对象是否为空 + * + * @param object Object + * @return true:为空 false:非空 + */ + public static boolean isNull(Object object) { + return object == null; + } + + /** + * * 判断一个对象是否非空 + * + * @param object Object + * @return true:非空 false:空 + */ + public static boolean isNotNull(Object object) { + return !isNull(object); + } + + /** + * * 判断一个对象是否是数组类型(Java基本型别的数组) + * + * @param object 对象 + * @return true:是数组 false:不是数组 + */ + public static boolean isArray(Object object) { + return isNotNull(object) && object.getClass().isArray(); + } + + /** + * 去空格 + */ + public static String trim(String str) { + return (str == null ? "" : str.trim()); + } + + /** + * 替换指定字符串的指定区间内字符为"*" + * + * @param str 字符串 + * @param startInclude 开始位置(包含) + * @param endExclude 结束位置(不包含) + * @return 替换后的字符串 + */ + public static String hide(CharSequence str, int startInclude, int endExclude) { + if (isEmpty(str)) { + return NULLSTR; + } + final int strLength = str.length(); + if (startInclude > strLength) { + return NULLSTR; + } + if (endExclude > strLength) { + endExclude = strLength; + } + if (startInclude > endExclude) { + // 如果起始位置大于结束位置,不替换 + return NULLSTR; + } + final char[] chars = new char[strLength]; + for (int i = 0; i < strLength; i++) { + if (i >= startInclude && i < endExclude) { + chars[i] = ASTERISK; + } else { + chars[i] = str.charAt(i); + } + } + return new String(chars); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @return 结果 + */ + public static String substring(final String str, int start) { + if (str == null) { + return NULLSTR; + } + + if (start < 0) { + start = str.length() + start; + } + + if (start < 0) { + start = 0; + } + if (start > str.length()) { + return NULLSTR; + } + + return str.substring(start); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @param end 结束 + * @return 结果 + */ + public static String substring(final String str, int start, int end) { + if (str == null) { + return NULLSTR; + } + + if (end < 0) { + end = str.length() + end; + } + if (start < 0) { + start = str.length() + start; + } + + if (end > str.length()) { + end = str.length(); + } + + if (start > end) { + return NULLSTR; + } + + if (start < 0) { + start = 0; + } + if (end < 0) { + end = 0; + } + + return str.substring(start, end); + } + + /** + * 判断是否为空,并且不是空白字符 + * + * @param str 要判断的value + * @return 结果 + */ + public static boolean hasText(String str) { + return (str != null && !str.isEmpty() && containsText(str)); + } + + private static boolean containsText(CharSequence str) { + int strLen = str.length(); + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(str.charAt(i))) { + return true; + } + } + return false; + } + + /** + * 格式化文本, {} 表示占位符
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @param template 文本模板,被替换的部分用 {} 表示 + * @param params 参数值 + * @return 格式化后的文本 + */ + public static String format(String template, Object... params) { + if (isEmpty(params) || isEmpty(template)) { + return template; + } + return StrFormatter.format(template, params); + } + + /** + * 是否为http(s)://开头 + * + * @param link 链接 + * @return 结果 + */ + public static boolean ishttp(String link) { + return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS); + } + + /** + * 字符串转set + * + * @param str 字符串 + * @param sep 分隔符 + * @return set集合 + */ + public static final Set str2Set(String str, String sep) { + return new HashSet(str2List(str, sep, true, false)); + } + + /** + * 字符串转list + * + * @param str 字符串 + * @param sep 分隔符 + * @param filterBlank 过滤纯空白 + * @param trim 去掉首尾空白 + * @return list集合 + */ + public static final List str2List(String str, String sep, boolean filterBlank, boolean trim) { + List list = new ArrayList(); + if (StringUtils.isEmpty(str)) { + return list; + } + + // 过滤空白字符串 + if (filterBlank && StringUtils.isBlank(str)) { + return list; + } + String[] split = str.split(sep); + for (String string : split) { + if (filterBlank && StringUtils.isBlank(string)) { + continue; + } + if (trim) { + string = string.trim(); + } + list.add(string); + } + + return list; + } + + /** + * 判断给定的collection列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value + * + * @param collection 给定的集合 + * @param array 给定的数组 + * @return boolean 结果 + */ + public static boolean containsAny(Collection collection, String... array) { + if (isEmpty(collection) || isEmpty(array)) { + return false; + } else { + for (String str : array) { + if (collection.contains(str)) { + return true; + } + } + return false; + } + } + + /** + * 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写 + * + * @param cs 指定字符串 + * @param searchCharSequences 需要检查的字符串数组 + * @return 是否包含任意一个字符串 + */ + public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences) { + if (isEmpty(cs) || isEmpty(searchCharSequences)) { + return false; + } + for (CharSequence testStr : searchCharSequences) { + if (containsIgnoreCase(cs, testStr)) { + return true; + } + } + return false; + } + + /** + * 驼峰转下划线命名 + */ + public static String toUnderScoreCase(String str) { + if (str == null) { + return null; + } + StringBuilder sb = new StringBuilder(); + // 前置字符是否大写 + boolean preCharIsUpperCase = true; + // 当前字符是否大写 + boolean curreCharIsUpperCase = true; + // 下一字符是否大写 + boolean nexteCharIsUpperCase = true; + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (i > 0) { + preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1)); + } else { + preCharIsUpperCase = false; + } + + curreCharIsUpperCase = Character.isUpperCase(c); + + if (i < (str.length() - 1)) { + nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1)); + } + + if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) { + sb.append(SEPARATOR); + } else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) { + sb.append(SEPARATOR); + } + sb.append(Character.toLowerCase(c)); + } + + return sb.toString(); + } + + /** + * 是否包含字符串 + * + * @param str 验证字符串 + * @param strs 字符串组 + * @return 包含返回true + */ + public static boolean inStringIgnoreCase(String str, String... strs) { + if (str != null && strs != null) { + for (String s : strs) { + if (str.equalsIgnoreCase(trim(s))) { + return true; + } + } + } + return false; + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld + * + * @param name 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String convertToCamelCase(String name) { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) { + // 没必要转换 + return ""; + } else if (!name.contains("_")) { + // 不含下划线,仅将首字母大写 + return name.substring(0, 1).toUpperCase() + name.substring(1); + } + // 用下划线将原始字符串分割 + String[] camels = name.split("_"); + for (String camel : camels) { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) { + continue; + } + // 首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + return result.toString(); + } + + /** + * 驼峰式命名法 + * 例如:user_name->userName + */ + public static String toCamelCase(String s) { + if (s == null) { + return null; + } + if (s.indexOf(SEPARATOR) == -1) { + return s; + } + s = s.toLowerCase(); + StringBuilder sb = new StringBuilder(s.length()); + boolean upperCase = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + if (c == SEPARATOR) { + upperCase = true; + } else if (upperCase) { + sb.append(Character.toUpperCase(c)); + upperCase = false; + } else { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串 + * + * @param str 指定字符串 + * @param strs 需要检查的字符串数组 + * @return 是否匹配 + */ + public static boolean matches(String str, List strs) { + if (isEmpty(str) || isEmpty(strs)) { + return false; + } + for (String pattern : strs) { + if (isMatch(pattern, str)) { + return true; + } + } + return false; + } + + /** + * 判断url是否与规则配置: + * ? 表示单个字符; + * * 表示一层路径内的任意字符串,不可跨层级; + * ** 表示任意层路径; + * + * @param pattern 匹配规则 + * @param url 需要匹配的url + * @return + */ + public static boolean isMatch(String pattern, String url) { + AntPathMatcher matcher = new AntPathMatcher(); + return matcher.match(pattern, url); + } + + @SuppressWarnings("unchecked") + public static T cast(Object obj) { + return (T) obj; + } + + /** + * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。 + * + * @param num 数字对象 + * @param size 字符串指定长度 + * @return 返回数字的字符串格式,该字符串为指定长度。 + */ + public static final String padl(final Number num, final int size) { + return padl(num.toString(), size, '0'); + } + + /** + * 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。 + * + * @param s 原始字符串 + * @param size 字符串指定长度 + * @param c 用于补齐的字符 + * @return 返回指定长度的字符串,由原字符串左补齐或截取得到。 + */ + public static final String padl(final String s, final int size, final char c) { + final StringBuilder sb = new StringBuilder(size); + if (s != null) { + final int len = s.length(); + if (s.length() <= size) { + for (int i = size - len; i > 0; i--) { + sb.append(c); + } + sb.append(s); + } else { + return s.substring(len - size, len); + } + } else { + for (int i = size; i > 0; i--) { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * 加后缀 + * + * @param account 账户 + * @param suffix 后缀 + * @return {@link String } + */ + public static String addSuffix(String account, String suffix) { + return account + "_" + suffix; + } + + /** + * 移除字符串中最后一个指定的子字符串 + * + * @param original 原始字符串 + * @return 移除后的字符串 + */ + public static String removeLastOccurrence(String original) { + // 查找下划线的位置 + int index = original.indexOf('_'); + if (index != -1) { + // 返回下划线前面的部分 + return original.substring(0, index); + } + return original; + } + +} diff --git a/ff-base/src/main/java/com/ff/base/utils/TenantUtils.java b/ff-base/src/main/java/com/ff/base/utils/TenantUtils.java new file mode 100644 index 0000000..fbacf30 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/TenantUtils.java @@ -0,0 +1,53 @@ +package com.ff.base.utils; + +import com.ff.base.constant.Constants; +import com.ff.base.datasource.DynamicDataSourceContextHolder; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; + +/** + * 持有Utils + * + * @author shi + * @date 2024/12/10 + */ +public class TenantUtils { + + public static String getTenantId() { + // 获取当前请求的 ServletRequestAttributes 对象 + ServletRequestAttributes attributes = + (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + + if (attributes == null) { + // 当前线程中无法获取请求上下文,返回默认数据源 + return Constants.DATA_SOURCE; + } + + HttpServletRequest request = attributes.getRequest(); + + // 从请求头中获取 tenantId + String tenantId = request.getHeader(Constants.TENANT_ID); + + // 如果 tenantId 为空或缺失,返回默认数据源 + if (StringUtils.isEmpty(tenantId)) { + return Constants.DATA_SOURCE; + } + // 返回有效的 tenantId + return tenantId; + + } + + /** + * 获取租户id redis + * + * @return {@link String } + */ + public static String getTenantIdRedis(String key) { + String dataSourceType = DynamicDataSourceContextHolder.getDataSourceType(); + dataSourceType = StringUtils.hasText(dataSourceType) ? dataSourceType : Constants.DATA_SOURCE; + return dataSourceType.toLowerCase()+":"+key; + + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/Threads.java b/ff-base/src/main/java/com/ff/base/utils/Threads.java new file mode 100644 index 0000000..1500231 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/Threads.java @@ -0,0 +1,96 @@ +package com.ff.base.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.*; + +/** + * 线程相关工具类. + * + * @author ff + */ +public class Threads +{ + private static final Logger logger = LoggerFactory.getLogger(Threads.class); + + /** + * sleep等待,单位为毫秒 + */ + public static void sleep(long milliseconds) + { + try + { + Thread.sleep(milliseconds); + } + catch (InterruptedException e) + { + return; + } + } + + /** + * 停止线程池 + * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务. + * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数. + * 如果仍然超時,則強制退出. + * 另对在shutdown时线程本身被调用中断做了处理. + */ + public static void shutdownAndAwaitTermination(ExecutorService pool) + { + if (pool != null && !pool.isShutdown()) + { + pool.shutdown(); + try + { + if (!pool.awaitTermination(120, TimeUnit.SECONDS)) + { + pool.shutdownNow(); + if (!pool.awaitTermination(120, TimeUnit.SECONDS)) + { + logger.info("Pool did not terminate"); + } + } + } + catch (InterruptedException ie) + { + pool.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + } + + /** + * 打印线程异常信息 + */ + public static void printException(Runnable r, Throwable t) + { + if (t == null && r instanceof Future) + { + try + { + Future future = (Future) r; + if (future.isDone()) + { + future.get(); + } + } + catch (CancellationException ce) + { + t = ce; + } + catch (ExecutionException ee) + { + t = ee.getCause(); + } + catch (InterruptedException ie) + { + Thread.currentThread().interrupt(); + } + } + if (t != null) + { + logger.error(t.getMessage(), t); + } + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/bean/BeanUtils.java b/ff-base/src/main/java/com/ff/base/utils/bean/BeanUtils.java new file mode 100644 index 0000000..a03480a --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/bean/BeanUtils.java @@ -0,0 +1,143 @@ +package com.ff.base.utils.bean; + +import org.springframework.beans.BeanWrapper; +import org.springframework.beans.BeanWrapperImpl; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Bean 工具类 + * + * @author ff + */ +public class BeanUtils extends org.springframework.beans.BeanUtils +{ + /** Bean方法名中属性名开始的下标 */ + private static final int BEAN_METHOD_PROP_INDEX = 3; + + /** * 匹配getter方法的正则表达式 */ + private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)"); + + /** * 匹配setter方法的正则表达式 */ + private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)"); + + /** + * Bean属性复制工具方法。 + * + * @param dest 目标对象 + * @param src 源对象 + */ + public static void copyBeanProp(Object dest, Object src) + { + try + { + copyProperties(src, dest); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * 获取对象的setter方法。 + * + * @param obj 对象 + * @return 对象的setter方法列表 + */ + public static List getSetterMethods(Object obj) + { + // setter方法列表 + List setterMethods = new ArrayList(); + + // 获取所有方法 + Method[] methods = obj.getClass().getMethods(); + + // 查找setter方法 + + for (Method method : methods) + { + Matcher m = SET_PATTERN.matcher(method.getName()); + if (m.matches() && (method.getParameterTypes().length == 1)) + { + setterMethods.add(method); + } + } + // 返回setter方法列表 + return setterMethods; + } + + /** + * 获取对象的getter方法。 + * + * @param obj 对象 + * @return 对象的getter方法列表 + */ + + public static List getGetterMethods(Object obj) + { + // getter方法列表 + List getterMethods = new ArrayList(); + // 获取所有方法 + Method[] methods = obj.getClass().getMethods(); + // 查找getter方法 + for (Method method : methods) + { + Matcher m = GET_PATTERN.matcher(method.getName()); + if (m.matches() && (method.getParameterTypes().length == 0)) + { + getterMethods.add(method); + } + } + // 返回getter方法列表 + return getterMethods; + } + + /** + * 检查Bean方法名中的属性名是否相等。
+ * 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。 + * + * @param m1 方法名1 + * @param m2 方法名2 + * @return 属性名一样返回true,否则返回false + */ + + public static boolean isMethodPropEquals(String m1, String m2) + { + return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX)); + } + + /** + * 拷贝属性值,忽略空值。 + * @param source 源对象 + * @param target 目标对象 + */ + public static void nullAwareCopyProperties(Object source, Object target) { + copyProperties(source, target, new String[0]); + } + + public static void nullAwareCopyProperties(Object source, Object target, String... ignoreProperties) { + BeanUtils.copyProperties(source, target, getPropertyNamesToIgnore(source, ignoreProperties)); + } + + private static String[] getPropertyNamesToIgnore(Object source, String[] ignoreProperties) { + Set ignoreSet = new HashSet<>(Arrays.asList(ignoreProperties)); + + BeanWrapper src = new BeanWrapperImpl(source); + PropertyDescriptor[] pds = src.getPropertyDescriptors(); + + for (PropertyDescriptor pd : pds) { + Object srcValue = src.getPropertyValue(pd.getName()); + if (srcValue == null) { + ignoreSet.add(pd.getName()); + } + } + + String[] result = new String[ignoreSet.size()]; + return ignoreSet.toArray(result); + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/bean/BeanValidators.java b/ff-base/src/main/java/com/ff/base/utils/bean/BeanValidators.java new file mode 100644 index 0000000..db6986e --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/bean/BeanValidators.java @@ -0,0 +1,24 @@ +package com.ff.base.utils.bean; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validator; +import java.util.Set; + +/** + * bean对象属性验证 + * + * @author ff + */ +public class BeanValidators +{ + public static void validateWithException(Validator validator, Object object, Class... groups) + throws ConstraintViolationException + { + Set> constraintViolations = validator.validate(object, groups); + if (!constraintViolations.isEmpty()) + { + throw new ConstraintViolationException(constraintViolations); + } + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/domain/DomainInfo.java b/ff-base/src/main/java/com/ff/base/utils/domain/DomainInfo.java new file mode 100644 index 0000000..f140e76 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/domain/DomainInfo.java @@ -0,0 +1,142 @@ +package com.ff.base.utils.domain; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@NoArgsConstructor +@Data +public class DomainInfo { + + /** + * 域名的名称。 + * 例如,`baidu.com`。 + */ + private String domain; + + /** + * 域名是否可用。 + * `no` 表示域名可用 + */ + private String available; + + /** + * 域名的类型。 + * 例如,`Commercial Sites` 表示这是商业站点类型的域名。 + */ + private String type; + + /** + * 注册商信息。 + * 例如,`MarkMonitor Inc.` 表示域名由 MarkMonitor 注册。 + */ + private String registrar; + + /** + * 域名的状态列表。 + * 例如,`clientDeleteProhibited` 表示域名禁止客户端删除等。 + */ + private List statuses; + + /** + * 域名创建的时间戳。 + * 以 Unix 时间戳的形式表示,单位为秒。 + */ + private Long created; + + /** + * 域名信息更新的时间戳。 + * 以 Unix 时间戳的形式表示,单位为秒。 + */ + private Long updated; + + /** + * 域名过期的时间戳。 + * 以 Unix 时间戳的形式表示,单位为秒。 + */ + private Long expires; + + /** + * WHOIS 信息。 + * 包含域名的注册、更新、过期时间、注册商信息、域名状态等。 + */ + private String whois; + + /** + * 域名的状态信息,封装了 WHOIS 数据的部分信息。 + */ + @Data + public static class WhoisInfo { + + /** + * 域名注册的 ID。 + */ + private String domainName; + + /** + * 域名注册的时间戳。 + */ + private String creationDate; + + /** + * 域名的过期时间戳。 + */ + private String registryExpiryDate; + + /** + * 域名的更新时间戳。 + */ + private String updatedDate; + + /** + * 域名的注册商信息。 + */ + private String registrar; + + /** + * 域名的 WHOIS 服务器。 + */ + private String registrarWhoisServer; + + /** + * 域名的注册商 URL。 + */ + private String registrarUrl; + + /** + * 域名的注册商 IANA ID。 + */ + private String registrarIanaId; + + /** + * 域名的注册商滥用联系邮件。 + */ + private String registrarAbuseContactEmail; + + /** + * 域名的注册商滥用联系电话。 + */ + private String registrarAbuseContactPhone; + + /** + * 域名的各类状态。 + */ + private List domainStatuses; + + /** + * 域名的名称服务器列表。 + */ + private List nameServers; + + /** + * 是否支持 DNSSEC。 + */ + private String dnssec; + + /** + * WHOIS 数据问题报告 URL。 + */ + private String icannWhoisInaccuracyUrl; + } +} diff --git a/ff-base/src/main/java/com/ff/base/utils/domain/DomainUtils.java b/ff-base/src/main/java/com/ff/base/utils/domain/DomainUtils.java new file mode 100644 index 0000000..b4bd211 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/domain/DomainUtils.java @@ -0,0 +1,178 @@ +package com.ff.base.utils.domain; + +import com.ff.base.enums.DomainType; +import com.ff.base.exception.base.BaseException; +import com.ff.base.utils.JsonUtil; +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.http.HttpClientSslUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.ObjectUtils; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Map; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 域有用 + * + * @author shi + * @date 2025/01/02 + */ +@Slf4j +public class DomainUtils { + + + /** + * 查询域信息 + * + * @param domainName 域名 + * @return {@link DomainInfo } + */ + public static DomainInfo queryDomainInfo(String domainName) { + try { + String result = HttpClientSslUtils.doGet("https://api.whois.vu/?q="+domainName+"&output=json"); + DomainInfo domainInfo = JsonUtil.stringToObj(result, DomainInfo.class); + if (ObjectUtils.isEmpty(domainInfo)|| ObjectUtils.isEmpty(domainInfo.getExpires())) { + throw new BaseException(MessageUtils.message("operation.domain.resolve.failed", domainName)); + } + return domainInfo; + } catch (Exception e) { + throw new BaseException(MessageUtils.message("operation.domain.resolve.failed", domainName)); + } + + } + + /** + * 生成一个随机域名 + * + * @return 随机生成的域名 + */ + public static String getRandomDomain() { + // 生成随机字符串(UUID 去掉 `-`) + String randomString = UUID.randomUUID().toString().replace("-", ""); + // 限制域名主体长度(如前 10 个字符) + randomString = randomString.substring(0, 10); + // 拼接顶级域名 + String domain = randomString + ".example.com"; + return domain; + } + + /** + * 判断域名类型 + * + * @param domain 域名字符串 + * @return 域名类型:"根域名"、"子域名"、"泛解析域名" 或 "无效域名" + */ + public static Integer determineDomainType(String domain) { + if (domain == null || domain.isEmpty()) { + return null; + } + + // 验证是否是泛解析域名 + if (isWildcardDomain(domain)) { + return DomainType.WILDCARD_DOMAIN.getValue(); + } + + // 验证是否是根域名 + if (isRootDomain(domain)) { + return DomainType.ROOT_DOMAIN.getValue(); + } + + // 验证是否是子域名 + if (isSubDomain(domain)) { + return DomainType.SUB_DOMAIN.getValue(); + } + + return null; + } + + /** + * 验证是否是泛解析域名(如 *.example.com) + */ + private static boolean isWildcardDomain(String domain) { + String wildcardRegex = "^\\*\\.([a-zA-Z0-9-]+\\.[a-zA-Z]{2,})$"; + return domain.matches(wildcardRegex); + } + + /** + * 验证是否是根域名(如 example.com) + */ + private static boolean isRootDomain(String domain) { + String rootDomainRegex = "^[a-zA-Z0-9-]+\\.[a-zA-Z]{2,}$"; + return domain.matches(rootDomainRegex); + } + + /** + * 验证是否是子域名(如 sub.example.com) + */ + private static boolean isSubDomain(String domain) { + String subDomainRegex = "^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+\\.[a-zA-Z]{2,}$"; + if (!domain.matches(subDomainRegex)) { + return false; + } + + // 确保根域名有效 + String rootDomain = extractRootDomain(domain); + return rootDomain != null && !domain.equals(rootDomain); + } + + /** + * 提取根域名(如从 sub.example.com 提取 example.com) + */ + private static String extractRootDomain(String domain) { + String rootDomainRegex = "([a-zA-Z0-9-]+\\.[a-zA-Z]{2,})$"; + Matcher matcher = Pattern.compile(rootDomainRegex).matcher(domain); + if (matcher.find()) { + return matcher.group(1); + } + return null; + } + + /** + * 自动向域名拼接参数 + * + * @param baseUrl 域名(基础 URL) + * @param params 参数集合(Map 类型) + * @return 拼接后的完整 URL + */ + public static String buildUrlWithParams(String baseUrl, Map params) { + if (StringUtils.isEmpty(baseUrl)) { + return null; + } + StringBuilder urlBuilder = new StringBuilder(baseUrl); + + // 检查是否已有查询参数,如果没有则添加 "?" + if (baseUrl.contains("?")) { + urlBuilder.append("&"); + } else { + urlBuilder.append("?"); + } + + // 遍历参数 Map,逐一添加到 URL 中 + for (Map.Entry entry : params.entrySet()) { + try { + // 使用 URL 编码确保特殊字符处理 + String encodedKey = URLEncoder.encode(entry.getKey(), "UTF-8"); + String encodedValue = URLEncoder.encode(String.valueOf(entry.getValue()), "UTF-8"); + urlBuilder.append(encodedKey) + .append("=") + .append(encodedValue) + .append("&"); + } catch (UnsupportedEncodingException e) { + log.error("URL 编码失败:{}", e.getMessage()); + } + } + + // 删除最后一个多余的 "&" + if (urlBuilder.charAt(urlBuilder.length() - 1) == '&') { + urlBuilder.deleteCharAt(urlBuilder.length() - 1); + } + + return urlBuilder.toString(); + } + +} diff --git a/ff-base/src/main/java/com/ff/base/utils/file/FileTypeUtils.java b/ff-base/src/main/java/com/ff/base/utils/file/FileTypeUtils.java new file mode 100644 index 0000000..86a2457 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/utils/file/FileTypeUtils.java @@ -0,0 +1,77 @@ +package com.ff.base.utils.file; + +import org.apache.commons.lang3.StringUtils; + +import java.io.File; + +/** + * 文件类型工具类 + * + * @author ff + */ +public class FileTypeUtils +{ + /** + * 获取文件类型 + *

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

+ * 如果两个 UUID 不同,且第一个 UUID 的最高有效字段大于第二个 UUID 的对应字段,则第一个 UUID 大于第二个 UUID。 + * + * @param val 与此 UUID 比较的 UUID + * + * @return 在此 UUID 小于、等于或大于 val 时,分别返回 -1、0 或 1。 + * + */ + @Override + public int compareTo(UUID val) + { + // The ordering is intentionally set up so that the UUIDs + // can simply be numerically compared as two numbers + return (this.mostSigBits < val.mostSigBits ? -1 : // + (this.mostSigBits > val.mostSigBits ? 1 : // + (this.leastSigBits < val.leastSigBits ? -1 : // + (this.leastSigBits > val.leastSigBits ? 1 : // + 0)))); + } + + // ------------------------------------------------------------------------------------------------------------------- + // Private method start + /** + * 返回指定数字对应的hex值 + * + * @param val 值 + * @param digits 位 + * @return 值 + */ + private static String digits(long val, int digits) + { + long hi = 1L << (digits * 4); + return Long.toHexString(hi | (val & (hi - 1))).substring(1); + } + + /** + * 检查是否为time-based版本UUID + */ + private void checkTimeBase() + { + if (version() != 1) + { + throw new UnsupportedOperationException("Not a time-based UUID"); + } + } + + /** + * 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG) + * + * @return {@link SecureRandom} + */ + public static SecureRandom getSecureRandom() + { + try + { + return SecureRandom.getInstance("SHA1PRNG"); + } + catch (NoSuchAlgorithmException e) + { + throw new UtilException(e); + } + } + + /** + * 获取随机数生成器对象
+ * ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。 + * + * @return {@link ThreadLocalRandom} + */ + public static ThreadLocalRandom getRandom() + { + return ThreadLocalRandom.current(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/domain/server/Cpu.java b/ff-base/src/main/java/com/ff/base/web/domain/server/Cpu.java new file mode 100644 index 0000000..b406e58 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/domain/server/Cpu.java @@ -0,0 +1,101 @@ +package com.ff.base.web.domain.server; + +import com.ff.base.utils.Arith; + +/** + * CPU相关信息 + * + * @author ff + */ +public class Cpu +{ + /** + * 核心数 + */ + private int cpuNum; + + /** + * CPU总的使用率 + */ + private double total; + + /** + * CPU系统使用率 + */ + private double sys; + + /** + * CPU用户使用率 + */ + private double used; + + /** + * CPU当前等待率 + */ + private double wait; + + /** + * CPU当前空闲率 + */ + private double free; + + public int getCpuNum() + { + return cpuNum; + } + + public void setCpuNum(int cpuNum) + { + this.cpuNum = cpuNum; + } + + public double getTotal() + { + return Arith.round(Arith.mul(total, 100), 2); + } + + public void setTotal(double total) + { + this.total = total; + } + + public double getSys() + { + return Arith.round(Arith.mul(sys / total, 100), 2); + } + + public void setSys(double sys) + { + this.sys = sys; + } + + public double getUsed() + { + return Arith.round(Arith.mul(used / total, 100), 2); + } + + public void setUsed(double used) + { + this.used = used; + } + + public double getWait() + { + return Arith.round(Arith.mul(wait / total, 100), 2); + } + + public void setWait(double wait) + { + this.wait = wait; + } + + public double getFree() + { + return Arith.round(Arith.mul(free / total, 100), 2); + } + + public void setFree(double free) + { + this.free = free; + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/domain/server/Jvm.java b/ff-base/src/main/java/com/ff/base/web/domain/server/Jvm.java new file mode 100644 index 0000000..0a9f481 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/domain/server/Jvm.java @@ -0,0 +1,131 @@ +package com.ff.base.web.domain.server; + +import com.ff.base.utils.Arith; +import com.ff.base.utils.DateUtils; + +import java.lang.management.ManagementFactory; + +/** + * JVM相关信息 + * + * @author ff + */ +public class Jvm +{ + /** + * 当前JVM占用的内存总数(M) + */ + private double total; + + /** + * JVM最大可用内存总数(M) + */ + private double max; + + /** + * JVM空闲内存(M) + */ + private double free; + + /** + * JDK版本 + */ + private String version; + + /** + * JDK路径 + */ + private String home; + + public double getTotal() + { + return Arith.div(total, (1024 * 1024), 2); + } + + public void setTotal(double total) + { + this.total = total; + } + + public double getMax() + { + return Arith.div(max, (1024 * 1024), 2); + } + + public void setMax(double max) + { + this.max = max; + } + + public double getFree() + { + return Arith.div(free, (1024 * 1024), 2); + } + + public void setFree(double free) + { + this.free = free; + } + + public double getUsed() + { + return Arith.div(total - free, (1024 * 1024), 2); + } + + public double getUsage() + { + return Arith.mul(Arith.div(total - free, total, 4), 100); + } + + /** + * 获取JDK名称 + */ + public String getName() + { + return ManagementFactory.getRuntimeMXBean().getVmName(); + } + + public String getVersion() + { + return version; + } + + public void setVersion(String version) + { + this.version = version; + } + + public String getHome() + { + return home; + } + + public void setHome(String home) + { + this.home = home; + } + + /** + * JDK启动时间 + */ + public String getStartTime() + { + return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate()); + } + + /** + * JDK运行时间 + */ + public String getRunTime() + { + return DateUtils.timeDistance(DateUtils.getCurrentDate(), DateUtils.getServerStartDate()); + } + + /** + * 运行参数 + */ + public String getInputArgs() + { + return ManagementFactory.getRuntimeMXBean().getInputArguments().toString(); + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/domain/server/Mem.java b/ff-base/src/main/java/com/ff/base/web/domain/server/Mem.java new file mode 100644 index 0000000..24429f1 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/domain/server/Mem.java @@ -0,0 +1,61 @@ +package com.ff.base.web.domain.server; + +import com.ff.base.utils.Arith; + +/** + * 內存相关信息 + * + * @author ff + */ +public class Mem +{ + /** + * 内存总量 + */ + private double total; + + /** + * 已用内存 + */ + private double used; + + /** + * 剩余内存 + */ + private double free; + + public double getTotal() + { + return Arith.div(total, (1024 * 1024 * 1024), 2); + } + + public void setTotal(long total) + { + this.total = total; + } + + public double getUsed() + { + return Arith.div(used, (1024 * 1024 * 1024), 2); + } + + public void setUsed(long used) + { + this.used = used; + } + + public double getFree() + { + return Arith.div(free, (1024 * 1024 * 1024), 2); + } + + public void setFree(long free) + { + this.free = free; + } + + public double getUsage() + { + return Arith.mul(Arith.div(used, total, 4), 100); + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/domain/server/Sys.java b/ff-base/src/main/java/com/ff/base/web/domain/server/Sys.java new file mode 100644 index 0000000..d2e3b50 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/domain/server/Sys.java @@ -0,0 +1,84 @@ +package com.ff.base.web.domain.server; + +/** + * 系统相关信息 + * + * @author ff + */ +public class Sys +{ + /** + * 服务器名称 + */ + private String computerName; + + /** + * 服务器Ip + */ + private String computerIp; + + /** + * 项目路径 + */ + private String userDir; + + /** + * 操作系统 + */ + private String osName; + + /** + * 系统架构 + */ + private String osArch; + + public String getComputerName() + { + return computerName; + } + + public void setComputerName(String computerName) + { + this.computerName = computerName; + } + + public String getComputerIp() + { + return computerIp; + } + + public void setComputerIp(String computerIp) + { + this.computerIp = computerIp; + } + + public String getUserDir() + { + return userDir; + } + + public void setUserDir(String userDir) + { + this.userDir = userDir; + } + + public String getOsName() + { + return osName; + } + + public void setOsName(String osName) + { + this.osName = osName; + } + + public String getOsArch() + { + return osArch; + } + + public void setOsArch(String osArch) + { + this.osArch = osArch; + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/domain/server/SysFile.java b/ff-base/src/main/java/com/ff/base/web/domain/server/SysFile.java new file mode 100644 index 0000000..9866a0b --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/domain/server/SysFile.java @@ -0,0 +1,114 @@ +package com.ff.base.web.domain.server; + +/** + * 系统文件相关信息 + * + * @author ff + */ +public class SysFile +{ + /** + * 盘符路径 + */ + private String dirName; + + /** + * 盘符类型 + */ + private String sysTypeName; + + /** + * 文件类型 + */ + private String typeName; + + /** + * 总大小 + */ + private String total; + + /** + * 剩余大小 + */ + private String free; + + /** + * 已经使用量 + */ + private String used; + + /** + * 资源的使用率 + */ + private double usage; + + public String getDirName() + { + return dirName; + } + + public void setDirName(String dirName) + { + this.dirName = dirName; + } + + public String getSysTypeName() + { + return sysTypeName; + } + + public void setSysTypeName(String sysTypeName) + { + this.sysTypeName = sysTypeName; + } + + public String getTypeName() + { + return typeName; + } + + public void setTypeName(String typeName) + { + this.typeName = typeName; + } + + public String getTotal() + { + return total; + } + + public void setTotal(String total) + { + this.total = total; + } + + public String getFree() + { + return free; + } + + public void setFree(String free) + { + this.free = free; + } + + public String getUsed() + { + return used; + } + + public void setUsed(String used) + { + this.used = used; + } + + public double getUsage() + { + return usage; + } + + public void setUsage(double usage) + { + this.usage = usage; + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/exception/GlobalExceptionHandler.java b/ff-base/src/main/java/com/ff/base/web/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..a8500de --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/exception/GlobalExceptionHandler.java @@ -0,0 +1,146 @@ +package com.ff.base.web.exception; + +import com.ff.base.constant.HttpStatus; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.text.Convert; +import com.ff.base.exception.DemoModeException; +import com.ff.base.exception.ServiceException; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.html.EscapeUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.validation.BindException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingPathVariableException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; + +import javax.servlet.http.HttpServletRequest; + +/** + * 全局异常处理器 + * + * @author ff + */ +@RestControllerAdvice +public class GlobalExceptionHandler +{ + private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + /** + * 权限校验异常 + */ + @ExceptionHandler(AccessDeniedException.class) + public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage()); + return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权"); + } + + /** + * 请求方式不支持 + */ + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, + HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); + return AjaxResult.error(e.getMessage()); + } + + /** + * 业务异常 + */ + @ExceptionHandler(ServiceException.class) + public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) + { + log.error(e.getMessage(), e); + Integer code = e.getCode(); + return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage()); + } + + /** + * 请求路径中缺少必需的路径变量 + */ + @ExceptionHandler(MissingPathVariableException.class) + public AjaxResult handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName())); + } + + /** + * 请求参数类型不匹配 + */ + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + String value = Convert.toStr(e.getValue()); + if (StringUtils.isNotEmpty(value)) + { + value = EscapeUtil.clean(value); + } + log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value)); + } + + /** + * 拦截未知的运行时异常 + */ + @ExceptionHandler(RuntimeException.class) + public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生未知异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 系统异常 + */ + @ExceptionHandler(Exception.class) + public AjaxResult handleException(Exception e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(BindException.class) + public AjaxResult handleBindException(BindException e) + { + log.error(e.getMessage(), e); + String message = e.getAllErrors().get(0).getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) + { + log.error(e.getMessage(), e); + String message = e.getBindingResult().getFieldError().getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 演示模式异常 + */ + @ExceptionHandler(DemoModeException.class) + public AjaxResult handleDemoModeException(DemoModeException e) + { + return AjaxResult.error("演示模式,不允许操作"); + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/service/MemberDetailsServiceImpl.java b/ff-base/src/main/java/com/ff/base/web/service/MemberDetailsServiceImpl.java new file mode 100644 index 0000000..1eebc62 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/service/MemberDetailsServiceImpl.java @@ -0,0 +1,59 @@ +package com.ff.base.web.service; + +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.enums.MemberStatus; +import com.ff.base.exception.ServiceException; +import com.ff.base.system.domain.SysUser; +import com.ff.base.system.service.ISysConfigService; +import com.ff.base.system.service.ISysUserService; +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +/** + * 会员验证处理 + * + * @author ff + */ +@Service +public class MemberDetailsServiceImpl implements UserDetailsService { + + @Autowired + private ISysUserService userService; + + @Autowired + private SysPasswordService passwordService; + + @Autowired + private ISysConfigService sysConfigService; + + + private static final Logger log = LoggerFactory.getLogger(MemberDetailsServiceImpl.class); + + @Override + public UserDetails loadUserByUsername(String accountName) throws UsernameNotFoundException { + SysUser user = userService.selectMemberUserByUserName(accountName); + if (StringUtils.isNull(user)) { + log.info("登录用户:{} 不存在.", accountName); + throw new ServiceException(MessageUtils.message("user.not.exists")); + } else if (MemberStatus.MemberStatus_6.getCode().equals(user.getStatus())) { + log.info("登录用户:{} 已被停用.", accountName); + throw new ServiceException(MessageUtils.message("user.blocked")); + } + + passwordService.validate(user); + String defaultCurrency = sysConfigService.selectConfigByKey("default.currency"); + return createLoginUser(user,defaultCurrency); + } + + + public UserDetails createLoginUser(SysUser user,String defaultCurrency) { + return new LoginUser(user.getUserId(),defaultCurrency, user); + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/service/PermissionService.java b/ff-base/src/main/java/com/ff/base/web/service/PermissionService.java new file mode 100644 index 0000000..5ac8c15 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/service/PermissionService.java @@ -0,0 +1,160 @@ +package com.ff.base.web.service; + +import com.ff.base.constant.Constants; +import com.ff.base.system.domain.SysRole; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.security.context.PermissionContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Set; + +/** + * ff首创 自定义权限实现,ss取自SpringSecurity首字母 + * + * @author ff + */ +@Service("ss") +public class PermissionService +{ + /** + * 验证用户是否具备某权限 + * + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public boolean hasPermi(String permission) + { + if (StringUtils.isEmpty(permission)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) + { + return false; + } + PermissionContextHolder.setContext(permission); + return hasPermissions(loginUser.getPermissions(), permission); + } + + /** + * 验证用户是否不具备某权限,与 hasPermi逻辑相反 + * + * @param permission 权限字符串 + * @return 用户是否不具备某权限 + */ + public boolean lacksPermi(String permission) + { + return hasPermi(permission) != true; + } + + /** + * 验证用户是否具有以下任意一个权限 + * + * @param permissions 以 PERMISSION_DELIMETER 为分隔符的权限列表 + * @return 用户是否具有以下任意一个权限 + */ + public boolean hasAnyPermi(String permissions) + { + if (StringUtils.isEmpty(permissions)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) + { + return false; + } + PermissionContextHolder.setContext(permissions); + Set authorities = loginUser.getPermissions(); + for (String permission : permissions.split(Constants.PERMISSION_DELIMETER)) + { + if (permission != null && hasPermissions(authorities, permission)) + { + return true; + } + } + return false; + } + + /** + * 判断用户是否拥有某个角色 + * + * @param role 角色字符串 + * @return 用户是否具备某角色 + */ + public boolean hasRole(String role) + { + if (StringUtils.isEmpty(role)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) + { + return false; + } + for (SysRole sysRole : loginUser.getUser().getRoles()) + { + String roleKey = sysRole.getRoleKey(); + if (Constants.SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))) + { + return true; + } + } + return false; + } + + /** + * 验证用户是否不具备某角色,与 isRole逻辑相反。 + * + * @param role 角色名称 + * @return 用户是否不具备某角色 + */ + public boolean lacksRole(String role) + { + return hasRole(role) != true; + } + + /** + * 验证用户是否具有以下任意一个角色 + * + * @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表 + * @return 用户是否具有以下任意一个角色 + */ + public boolean hasAnyRoles(String roles) + { + if (StringUtils.isEmpty(roles)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) + { + return false; + } + for (String role : roles.split(Constants.ROLE_DELIMETER)) + { + if (hasRole(role)) + { + return true; + } + } + return false; + } + + /** + * 判断是否包含权限 + * + * @param permissions 权限列表 + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + private boolean hasPermissions(Set permissions, String permission) + { + return permissions.contains(Constants.ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission)); + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/service/SysLoginService.java b/ff-base/src/main/java/com/ff/base/web/service/SysLoginService.java new file mode 100644 index 0000000..350cf1e --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/service/SysLoginService.java @@ -0,0 +1,183 @@ +package com.ff.base.web.service; + +import com.ff.base.constant.CacheConstants; +import com.ff.base.constant.Constants; +import com.ff.base.constant.UserConstants; +import com.ff.base.core.domain.model.LoginForm; +import com.ff.base.system.domain.SysUser; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.exception.ServiceException; +import com.ff.base.exception.user.*; +import com.ff.base.utils.DateUtils; +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.ip.IpUtils; +import com.ff.base.manager.AsyncManager; +import com.ff.base.manager.factory.AsyncFactory; +import com.ff.base.security.context.AuthenticationContextHolder; +import com.ff.base.system.service.ISysConfigService; +import com.ff.base.system.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 登录校验方法 + * + * @author ff + */ +@Component +public class SysLoginService +{ + @Autowired + private TokenService tokenService; + + @Resource + private AuthenticationManager authenticationManager; + + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysConfigService configService; + + /** + * 登录验证 + * + * @param username 用户名 + * @param password 密码 + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public String login(String username, String password, String code, String uuid) + { + // 验证码校验 + validateCaptcha(username, code, uuid); + // 登录前置校验 + loginPreCheck(username, password); + // 用户验证 + Authentication authentication = null; + try + { + LoginForm loginForm = new LoginForm(); + loginForm.setAccountName(username); + loginForm.setPassword(password); + loginForm.setLoginType(0); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, loginForm); + AuthenticationContextHolder.setContext(authenticationToken); + // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername + authentication = authenticationManager.authenticate(authenticationToken); + } + catch (Exception e) + { + if (e instanceof BadCredentialsException) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + else + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage())); + throw new ServiceException(e.getMessage()); + } + } + finally + { + AuthenticationContextHolder.clearContext(); + } + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + recordLoginInfo(loginUser.getUserId()); + // 生成token + return tokenService.createToken(loginUser); + } + + /** + * 校验验证码 + * + * @param username 用户名 + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public void validateCaptcha(String username, String code, String uuid) + { + boolean captchaEnabled = configService.selectCaptchaEnabled(); + if (captchaEnabled) + { + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); + String captcha = redisCache.getCacheObject(verifyKey); + if (captcha == null) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"))); + throw new CaptchaExpireException(); + } + redisCache.deleteObject(verifyKey); + if (!code.equalsIgnoreCase(captcha)) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); + throw new CaptchaException(); + } + } + } + + /** + * 登录前置校验 + * @param username 用户名 + * @param password 用户密码 + */ + public void loginPreCheck(String username, String password) + { + // 用户名或密码为空 错误 + if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); + throw new UserNotExistsException(); + } + // 密码如果不在指定范围内 错误 + if (password.length() < UserConstants.PASSWORD_MIN_LENGTH + || password.length() > UserConstants.PASSWORD_MAX_LENGTH) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + // 用户名不在指定范围内 错误 + if (username.length() < UserConstants.USERNAME_MIN_LENGTH + || username.length() > UserConstants.USERNAME_MAX_LENGTH) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + // IP黑名单校验 + String blackStr = configService.selectConfigByKey("sys.login.blackIPList"); + if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked"))); + throw new BlackListException(); + } + } + + /** + * 记录登录信息 + * + * @param userId 用户ID + */ + public void recordLoginInfo(Long userId) + { + SysUser sysUser = new SysUser(); + sysUser.setUserId(userId); + sysUser.setLoginIp(IpUtils.getIpAddr()); + sysUser.setLoginDate(DateUtils.getNowDate()); + userService.updateUserProfile(sysUser); + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/service/SysPasswordService.java b/ff-base/src/main/java/com/ff/base/web/service/SysPasswordService.java new file mode 100644 index 0000000..17981d4 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/service/SysPasswordService.java @@ -0,0 +1,89 @@ +package com.ff.base.web.service; + +import com.ff.base.constant.CacheConstants; +import com.ff.base.core.domain.model.LoginForm; +import com.ff.base.system.domain.SysUser; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.exception.user.UserPasswordNotMatchException; +import com.ff.base.exception.user.UserPasswordRetryLimitExceedException; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.security.context.AuthenticationContextHolder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +/** + * 登录密码方法 + * + * @author ff + */ +@Component +public class SysPasswordService +{ + @Autowired + private RedisCache redisCache; + + @Value(value = "${user.password.maxRetryCount}") + private int maxRetryCount; + + @Value(value = "${user.password.lockTime}") + private int lockTime; + + /** + * 登录账户密码错误次数缓存键名 + * + * @param username 用户名 + * @return 缓存键key + */ + private String getCacheKey(String username) + { + return CacheConstants.PWD_ERR_CNT_KEY + username; + } + + public void validate(SysUser user) + { + Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext(); + String username = usernamePasswordAuthenticationToken.getName(); + LoginForm credentials = (LoginForm) usernamePasswordAuthenticationToken.getCredentials(); + String password = credentials.getPassword(); + + Integer retryCount = redisCache.getCacheObject(getCacheKey(username)); + + if (retryCount == null) + { + retryCount = 0; + } + + if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) + { + throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime); + } + + if (!matches(user, password)) + { + retryCount = retryCount + 1; + redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES); + throw new UserPasswordNotMatchException(); + } + else + { + clearLoginRecordCache(username); + } + } + + public boolean matches(SysUser user, String rawPassword) + { + return SecurityUtils.matchesPassword(rawPassword, user.getPassword()); + } + + public void clearLoginRecordCache(String loginName) + { + if (redisCache.hasKey(getCacheKey(loginName))) + { + redisCache.deleteObject(getCacheKey(loginName)); + } + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/service/SysPermissionService.java b/ff-base/src/main/java/com/ff/base/web/service/SysPermissionService.java new file mode 100644 index 0000000..58228d6 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/service/SysPermissionService.java @@ -0,0 +1,84 @@ +package com.ff.base.web.service; + +import com.ff.base.system.domain.SysRole; +import com.ff.base.system.domain.SysUser; +import com.ff.base.system.service.ISysMenuService; +import com.ff.base.system.service.ISysRoleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * 用户权限处理 + * + * @author ff + */ +@Component +public class SysPermissionService +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysMenuService menuService; + + /** + * 获取角色数据权限 + * + * @param user 用户信息 + * @return 角色权限信息 + */ + public Set getRolePermission(SysUser user) + { + Set roles = new HashSet(); + // 管理员拥有所有权限 + if (user.isAdmin()) + { + roles.add("admin"); + } + else + { + roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId())); + } + return roles; + } + + /** + * 获取菜单数据权限 + * + * @param user 用户信息 + * @return 菜单权限信息 + */ + public Set getMenuPermission(SysUser user) + { + Set perms = new HashSet(); + // 管理员拥有所有权限 + if (user.isAdmin()) + { + perms.add("*:*:*"); + } + else + { + List roles = user.getRoles(); + if (!CollectionUtils.isEmpty(roles)) + { + // 多角色设置permissions属性,以便数据权限匹配权限 + for (SysRole role : roles) + { + Set rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId()); + role.setPermissions(rolePerms); + perms.addAll(rolePerms); + } + } + else + { + perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId())); + } + } + return perms; + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/service/SysRegisterService.java b/ff-base/src/main/java/com/ff/base/web/service/SysRegisterService.java new file mode 100644 index 0000000..ebb5b22 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/service/SysRegisterService.java @@ -0,0 +1,115 @@ +package com.ff.base.web.service; + +import com.ff.base.constant.CacheConstants; +import com.ff.base.constant.Constants; +import com.ff.base.constant.UserConstants; +import com.ff.base.system.domain.SysUser; +import com.ff.base.core.domain.model.RegisterBody; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.exception.user.CaptchaException; +import com.ff.base.exception.user.CaptchaExpireException; +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.manager.AsyncManager; +import com.ff.base.manager.factory.AsyncFactory; +import com.ff.base.system.service.ISysConfigService; +import com.ff.base.system.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 注册校验方法 + * + * @author ff + */ +@Component +public class SysRegisterService +{ + @Autowired + private ISysUserService userService; + + @Autowired + private ISysConfigService configService; + + @Autowired + private RedisCache redisCache; + + /** + * 注册 + */ + public String register(RegisterBody registerBody) + { + String msg = "", username = registerBody.getUsername(), password = registerBody.getPassword(); + SysUser sysUser = new SysUser(); + sysUser.setUserName(username); + + // 验证码开关 + boolean captchaEnabled = configService.selectCaptchaEnabled(); + if (captchaEnabled) + { + validateCaptcha(username, registerBody.getCode(), registerBody.getUuid()); + } + + if (StringUtils.isEmpty(username)) + { + msg = "用户名不能为空"; + } + else if (StringUtils.isEmpty(password)) + { + msg = "用户密码不能为空"; + } + else if (username.length() < UserConstants.USERNAME_MIN_LENGTH + || username.length() > UserConstants.USERNAME_MAX_LENGTH) + { + msg = "账户长度必须在2到20个字符之间"; + } + else if (password.length() < UserConstants.PASSWORD_MIN_LENGTH + || password.length() > UserConstants.PASSWORD_MAX_LENGTH) + { + msg = "密码长度必须在5到20个字符之间"; + } + else if (!userService.checkUserNameUnique(sysUser)) + { + msg = "保存用户'" + username + "'失败,注册账号已存在"; + } + else + { + sysUser.setNickName(username); + sysUser.setPassword(SecurityUtils.encryptPassword(password)); + boolean regFlag = userService.registerUser(sysUser); + if (!regFlag) + { + msg = "注册失败,请联系系统管理人员"; + } + else + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success"))); + } + } + return msg; + } + + /** + * 校验验证码 + * + * @param username 用户名 + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public void validateCaptcha(String username, String code, String uuid) + { + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); + String captcha = redisCache.getCacheObject(verifyKey); + redisCache.deleteObject(verifyKey); + if (captcha == null) + { + throw new CaptchaExpireException(); + } + if (!code.equalsIgnoreCase(captcha)) + { + throw new CaptchaException(); + } + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/service/TokenService.java b/ff-base/src/main/java/com/ff/base/web/service/TokenService.java new file mode 100644 index 0000000..46868bb --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/service/TokenService.java @@ -0,0 +1,232 @@ +package com.ff.base.web.service; + +import com.ff.base.constant.CacheConstants; +import com.ff.base.constant.Constants; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.core.redis.RedisCache; +import com.ff.base.utils.ServletUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.utils.ip.AddressUtils; +import com.ff.base.utils.ip.IpUtils; +import com.ff.base.utils.uuid.IdUtils; +import eu.bitwalker.useragentutils.UserAgent; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * token验证处理 + * + * @author ff + */ +@Component +public class TokenService +{ + private static final Logger log = LoggerFactory.getLogger(TokenService.class); + + // 令牌自定义标识 + @Value("${token.header}") + private String header; + + // 令牌秘钥 + @Value("${token.secret}") + private String secret; + + // 令牌有效期(默认10080分钟) + @Value("${token.expireTime}") + private int expireTime; + + protected static final long MILLIS_SECOND = 1000; + + protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; + + private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L; + + @Autowired + private RedisCache redisCache; + + /** + * 获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUser getLoginUser(HttpServletRequest request) + { + // 获取请求携带的令牌 + String token = getToken(request); + if (StringUtils.isNotEmpty(token)) + { + try + { + Claims claims = parseToken(token); + // 解析对应的权限以及用户信息 + String uuid = (String) claims.get(Constants.LOGIN_USER_KEY); + String userKey = getTokenKey(uuid); + LoginUser user = redisCache.getCacheObject(userKey); + return user; + } + catch (Exception e) + { + log.error("获取用户信息异常'{}'", e.getMessage()); + } + } + return null; + } + + /** + * 设置用户身份信息 + */ + public void setLoginUser(LoginUser loginUser) + { + if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) + { + refreshToken(loginUser); + } + } + + /** + * 删除用户身份信息 + */ + public void delLoginUser(String token) + { + if (StringUtils.isNotEmpty(token)) + { + String userKey = getTokenKey(token); + redisCache.deleteObject(userKey); + } + } + + /** + * 创建令牌 + * + * @param loginUser 用户信息 + * @return 令牌 + */ + public String createToken(LoginUser loginUser) + { + String token = IdUtils.fastUUID(); + loginUser.setToken(token); + setUserAgent(loginUser); + refreshToken(loginUser); + + Map claims = new HashMap<>(); + claims.put(Constants.LOGIN_USER_KEY, token); + return createToken(claims); + } + + /** + * 验证令牌有效期,相差不足20分钟,自动刷新缓存 + * + * @param loginUser + * @return 令牌 + */ + public void verifyToken(LoginUser loginUser) + { + long expireTime = loginUser.getExpireTime(); + long currentTime = System.currentTimeMillis(); + if (expireTime - currentTime <= MILLIS_MINUTE_TEN) + { + refreshToken(loginUser); + } + } + + /** + * 刷新令牌有效期 + * + * @param loginUser 登录信息 + */ + public void refreshToken(LoginUser loginUser) + { + loginUser.setLoginTime(System.currentTimeMillis()); + loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); + // 根据uuid将loginUser缓存 + String userKey = getTokenKey(loginUser.getToken()); + redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); + } + + /** + * 设置用户代理信息 + * + * @param loginUser 登录信息 + */ + public void setUserAgent(LoginUser loginUser) + { + UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); + String ip = IpUtils.getIpAddr(); + loginUser.setIpaddr(ip); + loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); + loginUser.setBrowser(userAgent.getBrowser().getName()); + loginUser.setOs(userAgent.getOperatingSystem().getName()); + } + + /** + * 从数据声明生成令牌 + * + * @param claims 数据声明 + * @return 令牌 + */ + private String createToken(Map claims) + { + String token = Jwts.builder() + .setClaims(claims) + .signWith(SignatureAlgorithm.HS512, secret).compact(); + return token; + } + + /** + * 从令牌中获取数据声明 + * + * @param token 令牌 + * @return 数据声明 + */ + private Claims parseToken(String token) + { + return Jwts.parser() + .setSigningKey(secret) + .parseClaimsJws(token) + .getBody(); + } + + /** + * 从令牌中获取用户名 + * + * @param token 令牌 + * @return 用户名 + */ + public String getUsernameFromToken(String token) + { + Claims claims = parseToken(token); + return claims.getSubject(); + } + + /** + * 获取请求token + * + * @param request + * @return token + */ + private String getToken(HttpServletRequest request) + { + String token = request.getHeader(header); + if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) + { + token = token.replace(Constants.TOKEN_PREFIX, ""); + } + return token; + } + + private String getTokenKey(String uuid) + { + return CacheConstants.LOGIN_TOKEN_KEY + uuid; + } +} diff --git a/ff-base/src/main/java/com/ff/base/web/service/UserDetailsServiceImpl.java b/ff-base/src/main/java/com/ff/base/web/service/UserDetailsServiceImpl.java new file mode 100644 index 0000000..f4fdc28 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/web/service/UserDetailsServiceImpl.java @@ -0,0 +1,66 @@ +package com.ff.base.web.service; + +import com.ff.base.system.domain.SysUser; +import com.ff.base.core.domain.model.LoginUser; +import com.ff.base.enums.UserStatus; +import com.ff.base.exception.ServiceException; +import com.ff.base.utils.MessageUtils; +import com.ff.base.utils.StringUtils; +import com.ff.base.system.service.ISysUserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +/** + * 用户验证处理 + * + * @author ff + */ +@Service +public class UserDetailsServiceImpl implements UserDetailsService +{ + private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class); + + @Autowired + private ISysUserService userService; + + @Autowired + private SysPasswordService passwordService; + + @Autowired + private SysPermissionService permissionService; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException + { + SysUser user = userService.selectUserByUserName(username); + if (StringUtils.isNull(user)) + { + log.info("登录用户:{} 不存在.", username); + throw new ServiceException(MessageUtils.message("user.not.exists")); + } + else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) + { + log.info("登录用户:{} 已被删除.", username); + throw new ServiceException(MessageUtils.message("user.password.delete")); + } + else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) + { + log.info("登录用户:{} 已被停用.", username); + throw new ServiceException(MessageUtils.message("user.blocked")); + } + + passwordService.validate(user); + + return createLoginUser(user); + } + + public UserDetails createLoginUser(SysUser user) + { + return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user)); + } +} diff --git a/ff-base/src/main/java/com/ff/base/xss/Xss.java b/ff-base/src/main/java/com/ff/base/xss/Xss.java new file mode 100644 index 0000000..5bbc1ff --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/xss/Xss.java @@ -0,0 +1,29 @@ +package com.ff.base.xss; + +import com.ff.base.xss.XssValidator; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义xss校验注解 + * + * @author ff + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(value = { ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER }) +@Constraint(validatedBy = { XssValidator.class }) +public @interface Xss +{ + String message() + + default "不允许任何脚本运行"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/ff-base/src/main/java/com/ff/base/xss/XssValidator.java b/ff-base/src/main/java/com/ff/base/xss/XssValidator.java new file mode 100644 index 0000000..85002f9 --- /dev/null +++ b/ff-base/src/main/java/com/ff/base/xss/XssValidator.java @@ -0,0 +1,40 @@ +package com.ff.base.xss; + +import com.ff.base.utils.StringUtils; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 自定义xss校验注解实现 + * + * @author ff + */ +public class XssValidator implements ConstraintValidator +{ + private static final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />"; + + @Override + public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) + { + if (StringUtils.isBlank(value)) + { + return true; + } + return !containsHtml(value); + } + + public static boolean containsHtml(String value) + { + StringBuilder sHtml = new StringBuilder(); + Pattern pattern = Pattern.compile(HTML_PATTERN); + Matcher matcher = pattern.matcher(value); + while (matcher.find()) + { + sHtml.append(matcher.group()); + } + return pattern.matcher(sHtml).matches(); + } +} diff --git a/ff-base/src/main/resources/mapper/system/SysConfigMapper.xml b/ff-base/src/main/resources/mapper/system/SysConfigMapper.xml new file mode 100644 index 0000000..3f892d3 --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysConfigMapper.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + select config_id, config_name, config_key, config_value, config_type, create_by, create_time, update_by, update_time, remark + from sys_config + + + + + + + and config_id = #{configId} + + + and config_key = #{configKey} + + + + + + + + + + + + + + insert into sys_config ( + config_name, + config_key, + config_value, + config_type, + create_by, + remark, + create_time + )values( + #{configName}, + #{configKey}, + #{configValue}, + #{configType}, + #{createBy}, + #{remark}, + UNIX_TIMESTAMP() * 1000 + ) + + + + update sys_config + + config_name = #{configName}, + config_key = #{configKey}, + config_value = #{configValue}, + config_type = #{configType}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = UNIX_TIMESTAMP() * 1000 + + where config_id = #{configId} + + + + update sys_config + + config_name = #{configName}, + config_value = #{configValue}, + config_type = #{configType}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = UNIX_TIMESTAMP() * 1000 + + where config_key = #{configKey} + + + + delete from sys_config where config_id = #{configId} + + + + delete from sys_config where config_id in + + #{configId} + + + + diff --git a/ff-base/src/main/resources/mapper/system/SysDatasourceMapper.xml b/ff-base/src/main/resources/mapper/system/SysDatasourceMapper.xml new file mode 100644 index 0000000..fe37001 --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysDatasourceMapper.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + select id, tenant_id, url,time_zone_name, username, password, driver_class_name, status, create_by, create_time, update_by, update_time, time_zone from sys_datasource + + + + + + + + + + insert into sys_datasource + + id, + tenant_id, + url, + username, + password, + driver_class_name, + status, + create_by, + create_time, + update_by, + update_time, + time_zone, + time_zone_name, + + + #{id}, + #{tenantId}, + #{url}, + #{username}, + #{password}, + #{driverClassName}, + #{status}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{timeZone}, + #{timeZoneName}, + + + + + update sys_datasource + + tenant_id = #{tenantId}, + url = #{url}, + username = #{username}, + password = #{password}, + driver_class_name = #{driverClassName}, + status = #{status}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + time_zone = #{timeZone}, + time_zone_name = #{timeZoneName}, + + where id = #{id} + + + + delete from sys_datasource where id = #{id} + + + + delete from sys_datasource where id in + + #{id} + + + + diff --git a/ff-base/src/main/resources/mapper/system/SysDeptMapper.xml b/ff-base/src/main/resources/mapper/system/SysDeptMapper.xml new file mode 100644 index 0000000..80eb339 --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysDeptMapper.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time + from sys_dept d + + + + + + + + + + + + + + + + + + + + insert into sys_dept( + dept_id, + parent_id, + dept_name, + ancestors, + order_num, + leader, + phone, + email, + status, + create_by, + create_time + )values( + #{deptId}, + #{parentId}, + #{deptName}, + #{ancestors}, + #{orderNum}, + #{leader}, + #{phone}, + #{email}, + #{status}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + + update sys_dept + + parent_id = #{parentId}, + dept_name = #{deptName}, + ancestors = #{ancestors}, + order_num = #{orderNum}, + leader = #{leader}, + phone = #{phone}, + email = #{email}, + status = #{status}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where dept_id = #{deptId} + + + + update sys_dept set ancestors = + + when #{item.deptId} then #{item.ancestors} + + where dept_id in + + #{item.deptId} + + + + + update sys_dept set status = '0' where dept_id in + + #{deptId} + + + + + update sys_dept set del_flag = '2' where dept_id = #{deptId} + + + diff --git a/ff-base/src/main/resources/mapper/system/SysDictDataMapper.xml b/ff-base/src/main/resources/mapper/system/SysDictDataMapper.xml new file mode 100644 index 0000000..ba236a1 --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysDictDataMapper.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark + from sys_dict_data + + + + + + + + + + + + + + delete from sys_dict_data where dict_code = #{dictCode} + + + + delete from sys_dict_data where dict_code in + + #{dictCode} + + + + + update sys_dict_data + + dict_sort = #{dictSort}, + dict_label = #{dictLabel}, + dict_value = #{dictValue}, + dict_type = #{dictType}, + css_class = #{cssClass}, + list_class = #{listClass}, + is_default = #{isDefault}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where dict_code = #{dictCode} + + + + update sys_dict_data set dict_type = #{newDictType} where dict_type = #{oldDictType} + + + + insert into sys_dict_data( + dict_sort, + dict_label, + dict_value, + dict_type, + css_class, + list_class, + is_default, + status, + remark, + create_by, + create_time + )values( + #{dictSort}, + #{dictLabel}, + #{dictValue}, + #{dictType}, + #{cssClass}, + #{listClass}, + #{isDefault}, + #{status}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + diff --git a/ff-base/src/main/resources/mapper/system/SysDictTypeMapper.xml b/ff-base/src/main/resources/mapper/system/SysDictTypeMapper.xml new file mode 100644 index 0000000..807f83d --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysDictTypeMapper.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + select dict_id, dict_name, dict_type, status, create_by, create_time, remark + from sys_dict_type + + + + + + + + + + + + + + delete from sys_dict_type where dict_id = #{dictId} + + + + delete from sys_dict_type where dict_id in + + #{dictId} + + + + + update sys_dict_type + + dict_name = #{dictName}, + dict_type = #{dictType}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where dict_id = #{dictId} + + + + insert into sys_dict_type( + dict_name, + dict_type, + status, + remark, + create_by, + create_time + )values( + #{dictName}, + #{dictType}, + #{status}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + diff --git a/ff-base/src/main/resources/mapper/system/SysLogininforMapper.xml b/ff-base/src/main/resources/mapper/system/SysLogininforMapper.xml new file mode 100644 index 0000000..5033e33 --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysLogininforMapper.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + insert into sys_logininfor (user_name, status, ipaddr, login_location, browser, os, msg, login_time) + values (#{userName}, #{status}, #{ipaddr}, #{loginLocation}, #{browser}, #{os}, #{msg}, UNIX_TIMESTAMP() * 1000) + + + + + + delete from sys_logininfor where info_id in + + #{infoId} + + + + + truncate table sys_logininfor + + + diff --git a/ff-base/src/main/resources/mapper/system/SysMenuMapper.xml b/ff-base/src/main/resources/mapper/system/SysMenuMapper.xml new file mode 100644 index 0000000..0274e15 --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysMenuMapper.xml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select menu_id, menu_name, parent_id, order_num, path, component, `query`, route_name, is_frame, is_cache, menu_type, visible, status, ifnull(perms,'') as perms, icon, create_time + from sys_menu + + + + + + + + + + + + + + + + + + + + + + + + + + update sys_menu + + menu_name = #{menuName}, + parent_id = #{parentId}, + order_num = #{orderNum}, + path = #{path}, + component = #{component}, + `query` = #{query}, + route_name = #{routeName}, + is_frame = #{isFrame}, + is_cache = #{isCache}, + menu_type = #{menuType}, + visible = #{visible}, + status = #{status}, + perms = #{perms}, + icon = #{icon}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where menu_id = #{menuId} + + + + insert into sys_menu( + menu_id, + parent_id, + menu_name, + order_num, + path, + component, + `query`, + route_name, + is_frame, + is_cache, + menu_type, + visible, + status, + perms, + icon, + remark, + create_by, + create_time + )values( + #{menuId}, + #{parentId}, + #{menuName}, + #{orderNum}, + #{path}, + #{component}, + #{query}, + #{routeName}, + #{isFrame}, + #{isCache}, + #{menuType}, + #{visible}, + #{status}, + #{perms}, + #{icon}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + + delete from sys_menu where menu_id = #{menuId} + + + diff --git a/ff-base/src/main/resources/mapper/system/SysOperLogMapper.xml b/ff-base/src/main/resources/mapper/system/SysOperLogMapper.xml new file mode 100644 index 0000000..1316d3f --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysOperLogMapper.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + select oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time, cost_time + from sys_oper_log + + + + insert into sys_oper_log(title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, cost_time, oper_time) + values (#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{deptName}, #{operUrl}, #{operIp}, #{operLocation}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg}, #{costTime}, UNIX_TIMESTAMP() * 1000) + + + + + + delete from sys_oper_log where oper_id in + + #{operId} + + + + + + + truncate table sys_oper_log + + + diff --git a/ff-base/src/main/resources/mapper/system/SysPostMapper.xml b/ff-base/src/main/resources/mapper/system/SysPostMapper.xml new file mode 100644 index 0000000..4083fd7 --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysPostMapper.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + select post_id, post_code, post_name, post_sort, status, create_by, create_time, remark + from sys_post + + + + + + + + + + + + + + + + + + update sys_post + + post_code = #{postCode}, + post_name = #{postName}, + post_sort = #{postSort}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where post_id = #{postId} + + + + insert into sys_post( + post_id, + post_code, + post_name, + post_sort, + status, + remark, + create_by, + create_time + )values( + #{postId}, + #{postCode}, + #{postName}, + #{postSort}, + #{status}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + + delete from sys_post where post_id = #{postId} + + + + delete from sys_post where post_id in + + #{postId} + + + + diff --git a/ff-base/src/main/resources/mapper/system/SysRoleDeptMapper.xml b/ff-base/src/main/resources/mapper/system/SysRoleDeptMapper.xml new file mode 100644 index 0000000..f3ff871 --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysRoleDeptMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_role_dept where role_id=#{roleId} + + + + + + delete from sys_role_dept where role_id in + + #{roleId} + + + + + insert into sys_role_dept(role_id, dept_id) values + + (#{item.roleId},#{item.deptId}) + + + + diff --git a/ff-base/src/main/resources/mapper/system/SysRoleMapper.xml b/ff-base/src/main/resources/mapper/system/SysRoleMapper.xml new file mode 100644 index 0000000..9560363 --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysRoleMapper.xml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.menu_check_strictly, r.dept_check_strictly, + r.status, r.del_flag, r.create_time, r.remark + from sys_role r + left join sys_user_role ur on ur.role_id = r.role_id + left join sys_user u on u.user_id = ur.user_id + left join sys_dept d on u.dept_id = d.dept_id + + + + + + + + + + + + + + + + + + + + insert into sys_role( + role_id, + role_name, + role_key, + role_sort, + data_scope, + menu_check_strictly, + dept_check_strictly, + status, + remark, + create_by, + create_time + )values( + #{roleId}, + #{roleName}, + #{roleKey}, + #{roleSort}, + #{dataScope}, + #{menuCheckStrictly}, + #{deptCheckStrictly}, + #{status}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + + update sys_role + + role_name = #{roleName}, + role_key = #{roleKey}, + role_sort = #{roleSort}, + data_scope = #{dataScope}, + menu_check_strictly = #{menuCheckStrictly}, + dept_check_strictly = #{deptCheckStrictly}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where role_id = #{roleId} + + + + update sys_role set del_flag = '2' where role_id = #{roleId} + + + + update sys_role set del_flag = '2' where role_id in + + #{roleId} + + + + diff --git a/ff-base/src/main/resources/mapper/system/SysRoleMenuMapper.xml b/ff-base/src/main/resources/mapper/system/SysRoleMenuMapper.xml new file mode 100644 index 0000000..6ad872d --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysRoleMenuMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + delete from sys_role_menu where role_id=#{roleId} + + + + delete from sys_role_menu where role_id in + + #{roleId} + + + + + insert into sys_role_menu(role_id, menu_id) values + + (#{item.roleId},#{item.menuId}) + + + + diff --git a/ff-base/src/main/resources/mapper/system/SysUserMapper.xml b/ff-base/src/main/resources/mapper/system/SysUserMapper.xml new file mode 100644 index 0000000..3c889ce --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysUserMapper.xml @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, + d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status, + r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status + from sys_user u + left join sys_dept d on u.dept_id = d.dept_id + left join sys_user_role ur on u.user_id = ur.user_id + left join sys_role r on r.role_id = ur.role_id + + + + + + + + + + + + + + + + + + + + insert into sys_user( + user_id, + dept_id, + user_name, + nick_name, + email, + avatar, + phonenumber, + sex, + password, + status, + create_by, + remark, + create_time + )values( + #{userId}, + #{deptId}, + #{userName}, + #{nickName}, + #{email}, + #{avatar}, + #{phonenumber}, + #{sex}, + #{password}, + #{status}, + #{createBy}, + #{remark}, + UNIX_TIMESTAMP() * 1000 + ) + + + + update sys_user + + dept_id = #{deptId}, + user_name = #{userName}, + nick_name = #{nickName}, + email = #{email}, + phonenumber = #{phonenumber}, + sex = #{sex}, + avatar = #{avatar}, + password = #{password}, + status = #{status}, + login_ip = #{loginIp}, + login_date = #{loginDate}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = UNIX_TIMESTAMP() * 1000 + + where user_id = #{userId} + + + + update sys_user set status = #{status} where user_id = #{userId} + + + + update sys_user set avatar = #{avatar} where user_name = #{userName} + + + + update sys_user set password = #{password} where user_name = #{userName} + + + + update sys_user set del_flag = '2' where user_id = #{userId} + + + + update sys_user set del_flag = '2' where user_id in + + #{userId} + + + + + diff --git a/ff-base/src/main/resources/mapper/system/SysUserPostMapper.xml b/ff-base/src/main/resources/mapper/system/SysUserPostMapper.xml new file mode 100644 index 0000000..288504d --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysUserPostMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_user_post where user_id=#{userId} + + + + + + delete from sys_user_post where user_id in + + #{userId} + + + + + insert into sys_user_post(user_id, post_id) values + + (#{item.userId},#{item.postId}) + + + + diff --git a/ff-base/src/main/resources/mapper/system/SysUserRoleMapper.xml b/ff-base/src/main/resources/mapper/system/SysUserRoleMapper.xml new file mode 100644 index 0000000..2604c71 --- /dev/null +++ b/ff-base/src/main/resources/mapper/system/SysUserRoleMapper.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + delete from sys_user_role where user_id=#{userId} + + + + + + delete from sys_user_role where user_id in + + #{userId} + + + + + insert into sys_user_role(user_id, role_id) values + + (#{item.userId},#{item.roleId}) + + + + + delete from sys_user_role where user_id=#{userId} and role_id=#{roleId} + + + + delete from sys_user_role where role_id=#{roleId} and user_id in + + #{userId} + + + diff --git a/ff-base/target/classes/com/ff/base/annotation/Anonymous.class b/ff-base/target/classes/com/ff/base/annotation/Anonymous.class new file mode 100644 index 0000000..93fd3db Binary files /dev/null and b/ff-base/target/classes/com/ff/base/annotation/Anonymous.class differ diff --git a/ff-base/target/classes/com/ff/base/annotation/DataScope.class b/ff-base/target/classes/com/ff/base/annotation/DataScope.class new file mode 100644 index 0000000..6ae1cd7 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/annotation/DataScope.class differ diff --git a/ff-base/target/classes/com/ff/base/annotation/DataSource.class b/ff-base/target/classes/com/ff/base/annotation/DataSource.class new file mode 100644 index 0000000..aa4059a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/annotation/DataSource.class differ diff --git a/ff-base/target/classes/com/ff/base/annotation/Excel$ColumnType.class b/ff-base/target/classes/com/ff/base/annotation/Excel$ColumnType.class new file mode 100644 index 0000000..e80feb7 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/annotation/Excel$ColumnType.class differ diff --git a/ff-base/target/classes/com/ff/base/annotation/Excel$Type.class b/ff-base/target/classes/com/ff/base/annotation/Excel$Type.class new file mode 100644 index 0000000..4a70920 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/annotation/Excel$Type.class differ diff --git a/ff-base/target/classes/com/ff/base/annotation/Excel.class b/ff-base/target/classes/com/ff/base/annotation/Excel.class new file mode 100644 index 0000000..d1257b8 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/annotation/Excel.class differ diff --git a/ff-base/target/classes/com/ff/base/annotation/Excels.class b/ff-base/target/classes/com/ff/base/annotation/Excels.class new file mode 100644 index 0000000..cd60a9a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/annotation/Excels.class differ diff --git a/ff-base/target/classes/com/ff/base/annotation/Log.class b/ff-base/target/classes/com/ff/base/annotation/Log.class new file mode 100644 index 0000000..c48aa7b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/annotation/Log.class differ diff --git a/ff-base/target/classes/com/ff/base/annotation/RateLimiter.class b/ff-base/target/classes/com/ff/base/annotation/RateLimiter.class new file mode 100644 index 0000000..602791f Binary files /dev/null and b/ff-base/target/classes/com/ff/base/annotation/RateLimiter.class differ diff --git a/ff-base/target/classes/com/ff/base/annotation/RepeatSubmit.class b/ff-base/target/classes/com/ff/base/annotation/RepeatSubmit.class new file mode 100644 index 0000000..d1b44e5 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/annotation/RepeatSubmit.class differ diff --git a/ff-base/target/classes/com/ff/base/annotation/Sensitive.class b/ff-base/target/classes/com/ff/base/annotation/Sensitive.class new file mode 100644 index 0000000..17a9f58 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/annotation/Sensitive.class differ diff --git a/ff-base/target/classes/com/ff/base/aspectj/DataScopeAspect.class b/ff-base/target/classes/com/ff/base/aspectj/DataScopeAspect.class new file mode 100644 index 0000000..7b3b7bd Binary files /dev/null and b/ff-base/target/classes/com/ff/base/aspectj/DataScopeAspect.class differ diff --git a/ff-base/target/classes/com/ff/base/aspectj/DataSourceAspect.class b/ff-base/target/classes/com/ff/base/aspectj/DataSourceAspect.class new file mode 100644 index 0000000..9dfc475 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/aspectj/DataSourceAspect.class differ diff --git a/ff-base/target/classes/com/ff/base/aspectj/LogAspect.class b/ff-base/target/classes/com/ff/base/aspectj/LogAspect.class new file mode 100644 index 0000000..9a46e75 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/aspectj/LogAspect.class differ diff --git a/ff-base/target/classes/com/ff/base/aspectj/RateLimiterAspect.class b/ff-base/target/classes/com/ff/base/aspectj/RateLimiterAspect.class new file mode 100644 index 0000000..03e3650 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/aspectj/RateLimiterAspect.class differ diff --git a/ff-base/target/classes/com/ff/base/config/ApplicationConfig.class b/ff-base/target/classes/com/ff/base/config/ApplicationConfig.class new file mode 100644 index 0000000..a238c93 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/ApplicationConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/AsyncConfig.class b/ff-base/target/classes/com/ff/base/config/AsyncConfig.class new file mode 100644 index 0000000..1e7240a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/AsyncConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/CaptchaConfig.class b/ff-base/target/classes/com/ff/base/config/CaptchaConfig.class new file mode 100644 index 0000000..c7ec438 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/CaptchaConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/DruidConfig$1.class b/ff-base/target/classes/com/ff/base/config/DruidConfig$1.class new file mode 100644 index 0000000..7c89282 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/DruidConfig$1.class differ diff --git a/ff-base/target/classes/com/ff/base/config/DruidConfig.class b/ff-base/target/classes/com/ff/base/config/DruidConfig.class new file mode 100644 index 0000000..5cb215d Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/DruidConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/FFConfig.class b/ff-base/target/classes/com/ff/base/config/FFConfig.class new file mode 100644 index 0000000..638565f Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/FFConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/FastJson2JsonRedisSerializer.class b/ff-base/target/classes/com/ff/base/config/FastJson2JsonRedisSerializer.class new file mode 100644 index 0000000..c670005 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/FastJson2JsonRedisSerializer.class differ diff --git a/ff-base/target/classes/com/ff/base/config/FilterConfig.class b/ff-base/target/classes/com/ff/base/config/FilterConfig.class new file mode 100644 index 0000000..5c2152a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/FilterConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/I18nConfig.class b/ff-base/target/classes/com/ff/base/config/I18nConfig.class new file mode 100644 index 0000000..a68da18 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/I18nConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/IdGeneratorUtil.class b/ff-base/target/classes/com/ff/base/config/IdGeneratorUtil.class new file mode 100644 index 0000000..bb0f5c7 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/IdGeneratorUtil.class differ diff --git a/ff-base/target/classes/com/ff/base/config/JacksonConfig.class b/ff-base/target/classes/com/ff/base/config/JacksonConfig.class new file mode 100644 index 0000000..1a2b4df Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/JacksonConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/KaptchaTextCreator.class b/ff-base/target/classes/com/ff/base/config/KaptchaTextCreator.class new file mode 100644 index 0000000..d40b9f8 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/KaptchaTextCreator.class differ diff --git a/ff-base/target/classes/com/ff/base/config/MyBatisConfig.class b/ff-base/target/classes/com/ff/base/config/MyBatisConfig.class new file mode 100644 index 0000000..2521733 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/MyBatisConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/RedisConfig.class b/ff-base/target/classes/com/ff/base/config/RedisConfig.class new file mode 100644 index 0000000..9563c0a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/RedisConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/ResourcesConfig.class b/ff-base/target/classes/com/ff/base/config/ResourcesConfig.class new file mode 100644 index 0000000..f9a9a67 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/ResourcesConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/SecurityConfig.class b/ff-base/target/classes/com/ff/base/config/SecurityConfig.class new file mode 100644 index 0000000..945fa79 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/SecurityConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/ServerConfig.class b/ff-base/target/classes/com/ff/base/config/ServerConfig.class new file mode 100644 index 0000000..39f09be Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/ServerConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/ThreadPoolConfig$1.class b/ff-base/target/classes/com/ff/base/config/ThreadPoolConfig$1.class new file mode 100644 index 0000000..3c11d0a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/ThreadPoolConfig$1.class differ diff --git a/ff-base/target/classes/com/ff/base/config/ThreadPoolConfig.class b/ff-base/target/classes/com/ff/base/config/ThreadPoolConfig.class new file mode 100644 index 0000000..194b772 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/ThreadPoolConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/config/properties/DruidProperties.class b/ff-base/target/classes/com/ff/base/config/properties/DruidProperties.class new file mode 100644 index 0000000..6db813b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/properties/DruidProperties.class differ diff --git a/ff-base/target/classes/com/ff/base/config/properties/PermitAllUrlProperties.class b/ff-base/target/classes/com/ff/base/config/properties/PermitAllUrlProperties.class new file mode 100644 index 0000000..07c25f6 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/properties/PermitAllUrlProperties.class differ diff --git a/ff-base/target/classes/com/ff/base/config/serializer/SensitiveJsonSerializer.class b/ff-base/target/classes/com/ff/base/config/serializer/SensitiveJsonSerializer.class new file mode 100644 index 0000000..5095c12 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/config/serializer/SensitiveJsonSerializer.class differ diff --git a/ff-base/target/classes/com/ff/base/constant/BusinessConstants.class b/ff-base/target/classes/com/ff/base/constant/BusinessConstants.class new file mode 100644 index 0000000..59be3d5 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/constant/BusinessConstants.class differ diff --git a/ff-base/target/classes/com/ff/base/constant/CacheConstants.class b/ff-base/target/classes/com/ff/base/constant/CacheConstants.class new file mode 100644 index 0000000..a3263dd Binary files /dev/null and b/ff-base/target/classes/com/ff/base/constant/CacheConstants.class differ diff --git a/ff-base/target/classes/com/ff/base/constant/ConfigConstants.class b/ff-base/target/classes/com/ff/base/constant/ConfigConstants.class new file mode 100644 index 0000000..d18c8bc Binary files /dev/null and b/ff-base/target/classes/com/ff/base/constant/ConfigConstants.class differ diff --git a/ff-base/target/classes/com/ff/base/constant/Constants.class b/ff-base/target/classes/com/ff/base/constant/Constants.class new file mode 100644 index 0000000..c469387 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/constant/Constants.class differ diff --git a/ff-base/target/classes/com/ff/base/constant/GenConstants.class b/ff-base/target/classes/com/ff/base/constant/GenConstants.class new file mode 100644 index 0000000..5948d28 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/constant/GenConstants.class differ diff --git a/ff-base/target/classes/com/ff/base/constant/HttpStatus.class b/ff-base/target/classes/com/ff/base/constant/HttpStatus.class new file mode 100644 index 0000000..2b4bd47 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/constant/HttpStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/constant/ScheduleConstants$Status.class b/ff-base/target/classes/com/ff/base/constant/ScheduleConstants$Status.class new file mode 100644 index 0000000..925cff3 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/constant/ScheduleConstants$Status.class differ diff --git a/ff-base/target/classes/com/ff/base/constant/ScheduleConstants.class b/ff-base/target/classes/com/ff/base/constant/ScheduleConstants.class new file mode 100644 index 0000000..f7aa25d Binary files /dev/null and b/ff-base/target/classes/com/ff/base/constant/ScheduleConstants.class differ diff --git a/ff-base/target/classes/com/ff/base/constant/UserConstants.class b/ff-base/target/classes/com/ff/base/constant/UserConstants.class new file mode 100644 index 0000000..1f36637 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/constant/UserConstants.class differ diff --git a/ff-base/target/classes/com/ff/base/core/controller/BaseController$1.class b/ff-base/target/classes/com/ff/base/core/controller/BaseController$1.class new file mode 100644 index 0000000..33fe81b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/controller/BaseController$1.class differ diff --git a/ff-base/target/classes/com/ff/base/core/controller/BaseController.class b/ff-base/target/classes/com/ff/base/core/controller/BaseController.class new file mode 100644 index 0000000..0f08398 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/controller/BaseController.class differ diff --git a/ff-base/target/classes/com/ff/base/core/domain/AjaxResult.class b/ff-base/target/classes/com/ff/base/core/domain/AjaxResult.class new file mode 100644 index 0000000..0bb64fb Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/domain/AjaxResult.class differ diff --git a/ff-base/target/classes/com/ff/base/core/domain/BaseEntity.class b/ff-base/target/classes/com/ff/base/core/domain/BaseEntity.class new file mode 100644 index 0000000..7aca844 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/domain/BaseEntity.class differ diff --git a/ff-base/target/classes/com/ff/base/core/domain/TreeEntity.class b/ff-base/target/classes/com/ff/base/core/domain/TreeEntity.class new file mode 100644 index 0000000..3fc0a2c Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/domain/TreeEntity.class differ diff --git a/ff-base/target/classes/com/ff/base/core/domain/TreeSelect.class b/ff-base/target/classes/com/ff/base/core/domain/TreeSelect.class new file mode 100644 index 0000000..7642cd3 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/domain/TreeSelect.class differ diff --git a/ff-base/target/classes/com/ff/base/core/domain/model/LoginBody.class b/ff-base/target/classes/com/ff/base/core/domain/model/LoginBody.class new file mode 100644 index 0000000..f2a3639 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/domain/model/LoginBody.class differ diff --git a/ff-base/target/classes/com/ff/base/core/domain/model/LoginForm.class b/ff-base/target/classes/com/ff/base/core/domain/model/LoginForm.class new file mode 100644 index 0000000..8af54db Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/domain/model/LoginForm.class differ diff --git a/ff-base/target/classes/com/ff/base/core/domain/model/LoginUser.class b/ff-base/target/classes/com/ff/base/core/domain/model/LoginUser.class new file mode 100644 index 0000000..0a05c96 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/domain/model/LoginUser.class differ diff --git a/ff-base/target/classes/com/ff/base/core/domain/model/RegisterBody.class b/ff-base/target/classes/com/ff/base/core/domain/model/RegisterBody.class new file mode 100644 index 0000000..b51b394 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/domain/model/RegisterBody.class differ diff --git a/ff-base/target/classes/com/ff/base/core/page/PageDomain.class b/ff-base/target/classes/com/ff/base/core/page/PageDomain.class new file mode 100644 index 0000000..116f7b2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/page/PageDomain.class differ diff --git a/ff-base/target/classes/com/ff/base/core/page/TableDataInfo.class b/ff-base/target/classes/com/ff/base/core/page/TableDataInfo.class new file mode 100644 index 0000000..5de01a0 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/page/TableDataInfo.class differ diff --git a/ff-base/target/classes/com/ff/base/core/page/TableSupport.class b/ff-base/target/classes/com/ff/base/core/page/TableSupport.class new file mode 100644 index 0000000..3272afc Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/page/TableSupport.class differ diff --git a/ff-base/target/classes/com/ff/base/core/redis/RedisCache.class b/ff-base/target/classes/com/ff/base/core/redis/RedisCache.class new file mode 100644 index 0000000..d3fa3c3 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/redis/RedisCache.class differ diff --git a/ff-base/target/classes/com/ff/base/core/text/CharsetKit.class b/ff-base/target/classes/com/ff/base/core/text/CharsetKit.class new file mode 100644 index 0000000..9b87775 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/text/CharsetKit.class differ diff --git a/ff-base/target/classes/com/ff/base/core/text/Convert.class b/ff-base/target/classes/com/ff/base/core/text/Convert.class new file mode 100644 index 0000000..9657c3a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/text/Convert.class differ diff --git a/ff-base/target/classes/com/ff/base/core/text/StrFormatter.class b/ff-base/target/classes/com/ff/base/core/text/StrFormatter.class new file mode 100644 index 0000000..a53c15b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/core/text/StrFormatter.class differ diff --git a/ff-base/target/classes/com/ff/base/datasource/DynamicDataSource.class b/ff-base/target/classes/com/ff/base/datasource/DynamicDataSource.class new file mode 100644 index 0000000..dc4cce2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/datasource/DynamicDataSource.class differ diff --git a/ff-base/target/classes/com/ff/base/datasource/DynamicDataSourceContextHolder.class b/ff-base/target/classes/com/ff/base/datasource/DynamicDataSourceContextHolder.class new file mode 100644 index 0000000..a4321b3 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/datasource/DynamicDataSourceContextHolder.class differ diff --git a/ff-base/target/classes/com/ff/base/decorator/ContextCopyingDecorator.class b/ff-base/target/classes/com/ff/base/decorator/ContextCopyingDecorator.class new file mode 100644 index 0000000..2ce9b79 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/decorator/ContextCopyingDecorator.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/AccountAuditStatus.class b/ff-base/target/classes/com/ff/base/enums/AccountAuditStatus.class new file mode 100644 index 0000000..db98a27 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/AccountAuditStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/AccountChangeType.class b/ff-base/target/classes/com/ff/base/enums/AccountChangeType.class new file mode 100644 index 0000000..f05257e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/AccountChangeType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/AccountType.class b/ff-base/target/classes/com/ff/base/enums/AccountType.class new file mode 100644 index 0000000..8061171 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/AccountType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityBetPlatformType.class b/ff-base/target/classes/com/ff/base/enums/ActivityBetPlatformType.class new file mode 100644 index 0000000..c9fa0f5 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityBetPlatformType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityBetSendStatus.class b/ff-base/target/classes/com/ff/base/enums/ActivityBetSendStatus.class new file mode 100644 index 0000000..f1ce95d Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityBetSendStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityBetSendWay.class b/ff-base/target/classes/com/ff/base/enums/ActivityBetSendWay.class new file mode 100644 index 0000000..76d0dc3 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityBetSendWay.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityChargeReceiveLimitType.class b/ff-base/target/classes/com/ff/base/enums/ActivityChargeReceiveLimitType.class new file mode 100644 index 0000000..30a0516 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityChargeReceiveLimitType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityChargeRepeatReceive.class b/ff-base/target/classes/com/ff/base/enums/ActivityChargeRepeatReceive.class new file mode 100644 index 0000000..cec49bb Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityChargeRepeatReceive.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityChargeRewardType.class b/ff-base/target/classes/com/ff/base/enums/ActivityChargeRewardType.class new file mode 100644 index 0000000..e71162b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityChargeRewardType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityChargeRuleType.class b/ff-base/target/classes/com/ff/base/enums/ActivityChargeRuleType.class new file mode 100644 index 0000000..aa537f1 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityChargeRuleType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityChargeSendStatus.class b/ff-base/target/classes/com/ff/base/enums/ActivityChargeSendStatus.class new file mode 100644 index 0000000..ca10f6a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityChargeSendStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityChargeSendWay.class b/ff-base/target/classes/com/ff/base/enums/ActivityChargeSendWay.class new file mode 100644 index 0000000..3179ff2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityChargeSendWay.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityExtensionAccordCondition.class b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionAccordCondition.class new file mode 100644 index 0000000..85ae1a1 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionAccordCondition.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityExtensionChargeStatus.class b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionChargeStatus.class new file mode 100644 index 0000000..aa32b53 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionChargeStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityExtensionChargeType.class b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionChargeType.class new file mode 100644 index 0000000..5eef7ce Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionChargeType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityExtensionLoginApp.class b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionLoginApp.class new file mode 100644 index 0000000..3a72046 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionLoginApp.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityExtensionRewardType.class b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionRewardType.class new file mode 100644 index 0000000..36e83b6 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionRewardType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityExtensionSendStatus.class b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionSendStatus.class new file mode 100644 index 0000000..9950e0f Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionSendStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityExtensionSendWay.class b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionSendWay.class new file mode 100644 index 0000000..644f4d7 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityExtensionSendWay.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityLimitedTimeDay.class b/ff-base/target/classes/com/ff/base/enums/ActivityLimitedTimeDay.class new file mode 100644 index 0000000..284236e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityLimitedTimeDay.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityLoopType.class b/ff-base/target/classes/com/ff/base/enums/ActivityLoopType.class new file mode 100644 index 0000000..b548c97 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityLoopType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityMainEntrance.class b/ff-base/target/classes/com/ff/base/enums/ActivityMainEntrance.class new file mode 100644 index 0000000..da8fac4 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityMainEntrance.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityReceiveCount.class b/ff-base/target/classes/com/ff/base/enums/ActivityReceiveCount.class new file mode 100644 index 0000000..54ef201 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityReceiveCount.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityReceiveLimitType.class b/ff-base/target/classes/com/ff/base/enums/ActivityReceiveLimitType.class new file mode 100644 index 0000000..dfd6952 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityReceiveLimitType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityRewardAuditStatus.class b/ff-base/target/classes/com/ff/base/enums/ActivityRewardAuditStatus.class new file mode 100644 index 0000000..ce4f2cd Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityRewardAuditStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityShowStatus.class b/ff-base/target/classes/com/ff/base/enums/ActivityShowStatus.class new file mode 100644 index 0000000..eddf2a8 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityShowStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityStatus.class b/ff-base/target/classes/com/ff/base/enums/ActivityStatus.class new file mode 100644 index 0000000..a84e5a2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ActivityTemplateType.class b/ff-base/target/classes/com/ff/base/enums/ActivityTemplateType.class new file mode 100644 index 0000000..a6329ec Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ActivityTemplateType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/AgentModelType.class b/ff-base/target/classes/com/ff/base/enums/AgentModelType.class new file mode 100644 index 0000000..f76ef68 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/AgentModelType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/AndroidForceDownload.class b/ff-base/target/classes/com/ff/base/enums/AndroidForceDownload.class new file mode 100644 index 0000000..0028822 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/AndroidForceDownload.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/AnnouncementStatus.class b/ff-base/target/classes/com/ff/base/enums/AnnouncementStatus.class new file mode 100644 index 0000000..4bbf639 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/AnnouncementStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/AppLocation.class b/ff-base/target/classes/com/ff/base/enums/AppLocation.class new file mode 100644 index 0000000..7755a94 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/AppLocation.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/AwardType.class b/ff-base/target/classes/com/ff/base/enums/AwardType.class new file mode 100644 index 0000000..d00b61e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/AwardType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/BannerStatus.class b/ff-base/target/classes/com/ff/base/enums/BannerStatus.class new file mode 100644 index 0000000..052ea10 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/BannerStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/BetTaskSource.class b/ff-base/target/classes/com/ff/base/enums/BetTaskSource.class new file mode 100644 index 0000000..8b26956 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/BetTaskSource.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/BetTaskStatus.class b/ff-base/target/classes/com/ff/base/enums/BetTaskStatus.class new file mode 100644 index 0000000..9f6bd1b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/BetTaskStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/BoxStatusType.class b/ff-base/target/classes/com/ff/base/enums/BoxStatusType.class new file mode 100644 index 0000000..1568da8 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/BoxStatusType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/BusinessStatus.class b/ff-base/target/classes/com/ff/base/enums/BusinessStatus.class new file mode 100644 index 0000000..a6c994c Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/BusinessStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/BusinessType.class b/ff-base/target/classes/com/ff/base/enums/BusinessType.class new file mode 100644 index 0000000..fee3a79 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/BusinessType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/CalcModeType.class b/ff-base/target/classes/com/ff/base/enums/CalcModeType.class new file mode 100644 index 0000000..8131026 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/CalcModeType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/CalcPerformanceType.class b/ff-base/target/classes/com/ff/base/enums/CalcPerformanceType.class new file mode 100644 index 0000000..1e5c37b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/CalcPerformanceType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/CalcRangeType.class b/ff-base/target/classes/com/ff/base/enums/CalcRangeType.class new file mode 100644 index 0000000..acd69ae Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/CalcRangeType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/CalculateType.class b/ff-base/target/classes/com/ff/base/enums/CalculateType.class new file mode 100644 index 0000000..8e9330a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/CalculateType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ChangeStatus.class b/ff-base/target/classes/com/ff/base/enums/ChangeStatus.class new file mode 100644 index 0000000..08efd84 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ChangeStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ChannelType.class b/ff-base/target/classes/com/ff/base/enums/ChannelType.class new file mode 100644 index 0000000..7affa94 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ChannelType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ChargeOrderFlag.class b/ff-base/target/classes/com/ff/base/enums/ChargeOrderFlag.class new file mode 100644 index 0000000..42c3bbf Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ChargeOrderFlag.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ChargeOrderPayStatus.class b/ff-base/target/classes/com/ff/base/enums/ChargeOrderPayStatus.class new file mode 100644 index 0000000..bfc874f Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ChargeOrderPayStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/CostType.class b/ff-base/target/classes/com/ff/base/enums/CostType.class new file mode 100644 index 0000000..eefbe96 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/CostType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DataSourceType.class b/ff-base/target/classes/com/ff/base/enums/DataSourceType.class new file mode 100644 index 0000000..fbfdf2f Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DataSourceType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DesensitizedType.class b/ff-base/target/classes/com/ff/base/enums/DesensitizedType.class new file mode 100644 index 0000000..6cb738c Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DesensitizedType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DeviceType.class b/ff-base/target/classes/com/ff/base/enums/DeviceType.class new file mode 100644 index 0000000..be56be0 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DeviceType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DirectFlagType.class b/ff-base/target/classes/com/ff/base/enums/DirectFlagType.class new file mode 100644 index 0000000..86b3ad8 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DirectFlagType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DiscountReceiveSmallType.class b/ff-base/target/classes/com/ff/base/enums/DiscountReceiveSmallType.class new file mode 100644 index 0000000..61941ef Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DiscountReceiveSmallType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DiscountReceiveSource.class b/ff-base/target/classes/com/ff/base/enums/DiscountReceiveSource.class new file mode 100644 index 0000000..4281812 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DiscountReceiveSource.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DiscountReceiveStatus.class b/ff-base/target/classes/com/ff/base/enums/DiscountReceiveStatus.class new file mode 100644 index 0000000..aab2cc1 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DiscountReceiveStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DnsRecordType.class b/ff-base/target/classes/com/ff/base/enums/DnsRecordType.class new file mode 100644 index 0000000..1d6753e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DnsRecordType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DomainCloudfareStatus.class b/ff-base/target/classes/com/ff/base/enums/DomainCloudfareStatus.class new file mode 100644 index 0000000..5a0d410 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DomainCloudfareStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DomainSonType.class b/ff-base/target/classes/com/ff/base/enums/DomainSonType.class new file mode 100644 index 0000000..5cfff63 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DomainSonType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DomainSonUsageStatus.class b/ff-base/target/classes/com/ff/base/enums/DomainSonUsageStatus.class new file mode 100644 index 0000000..bc73a08 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DomainSonUsageStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DomainStatus.class b/ff-base/target/classes/com/ff/base/enums/DomainStatus.class new file mode 100644 index 0000000..fb9a714 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DomainStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DomainType.class b/ff-base/target/classes/com/ff/base/enums/DomainType.class new file mode 100644 index 0000000..d361fe6 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DomainType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DownloadType.class b/ff-base/target/classes/com/ff/base/enums/DownloadType.class new file mode 100644 index 0000000..6250832 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DownloadType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/DrawType.class b/ff-base/target/classes/com/ff/base/enums/DrawType.class new file mode 100644 index 0000000..728a5b6 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/DrawType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/EnableStatus.class b/ff-base/target/classes/com/ff/base/enums/EnableStatus.class new file mode 100644 index 0000000..e24fa36 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/EnableStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/EventType.class b/ff-base/target/classes/com/ff/base/enums/EventType.class new file mode 100644 index 0000000..8b965a7 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/EventType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/FeedbackStatus.class b/ff-base/target/classes/com/ff/base/enums/FeedbackStatus.class new file mode 100644 index 0000000..1cb1037 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/FeedbackStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/FrameStatus.class b/ff-base/target/classes/com/ff/base/enums/FrameStatus.class new file mode 100644 index 0000000..daacab6 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/FrameStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/FreeStatus.class b/ff-base/target/classes/com/ff/base/enums/FreeStatus.class new file mode 100644 index 0000000..e2d64e5 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/FreeStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/FyPayStatus.class b/ff-base/target/classes/com/ff/base/enums/FyPayStatus.class new file mode 100644 index 0000000..509e81f Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/FyPayStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/GameCollectionStatus.class b/ff-base/target/classes/com/ff/base/enums/GameCollectionStatus.class new file mode 100644 index 0000000..c4e25e4 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/GameCollectionStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/GameEventEnum.class b/ff-base/target/classes/com/ff/base/enums/GameEventEnum.class new file mode 100644 index 0000000..7bcf7ac Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/GameEventEnum.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/GameHotStatus.class b/ff-base/target/classes/com/ff/base/enums/GameHotStatus.class new file mode 100644 index 0000000..fcc3c77 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/GameHotStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/GameOpenStatus.class b/ff-base/target/classes/com/ff/base/enums/GameOpenStatus.class new file mode 100644 index 0000000..373e235 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/GameOpenStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/GamePlatforms.class b/ff-base/target/classes/com/ff/base/enums/GamePlatforms.class new file mode 100644 index 0000000..de0c88b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/GamePlatforms.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/GamePlayStatus.class b/ff-base/target/classes/com/ff/base/enums/GamePlayStatus.class new file mode 100644 index 0000000..69b5096 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/GamePlayStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/GamePopularCategory.class b/ff-base/target/classes/com/ff/base/enums/GamePopularCategory.class new file mode 100644 index 0000000..52860c0 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/GamePopularCategory.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/GamePopularStatus.class b/ff-base/target/classes/com/ff/base/enums/GamePopularStatus.class new file mode 100644 index 0000000..8f228b2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/GamePopularStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/GamePopularType.class b/ff-base/target/classes/com/ff/base/enums/GamePopularType.class new file mode 100644 index 0000000..c07e228 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/GamePopularType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/GameStatus.class b/ff-base/target/classes/com/ff/base/enums/GameStatus.class new file mode 100644 index 0000000..ec55cb2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/GameStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/HttpMethod.class b/ff-base/target/classes/com/ff/base/enums/HttpMethod.class new file mode 100644 index 0000000..f26975c Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/HttpMethod.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/InitiatingType.class b/ff-base/target/classes/com/ff/base/enums/InitiatingType.class new file mode 100644 index 0000000..9bcc964 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/InitiatingType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/JILIGameType.class b/ff-base/target/classes/com/ff/base/enums/JILIGameType.class new file mode 100644 index 0000000..7499295 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/JILIGameType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/LangType.class b/ff-base/target/classes/com/ff/base/enums/LangType.class new file mode 100644 index 0000000..964dd66 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/LangType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/LayoutLoginType.class b/ff-base/target/classes/com/ff/base/enums/LayoutLoginType.class new file mode 100644 index 0000000..e42d81e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/LayoutLoginType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/LimitType.class b/ff-base/target/classes/com/ff/base/enums/LimitType.class new file mode 100644 index 0000000..261d914 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/LimitType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/LinkPosition.class b/ff-base/target/classes/com/ff/base/enums/LinkPosition.class new file mode 100644 index 0000000..d4e9504 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/LinkPosition.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/LoadStatus.class b/ff-base/target/classes/com/ff/base/enums/LoadStatus.class new file mode 100644 index 0000000..507df14 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/LoadStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/LoopType.class b/ff-base/target/classes/com/ff/base/enums/LoopType.class new file mode 100644 index 0000000..5460477 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/LoopType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/MarqueeStatus.class b/ff-base/target/classes/com/ff/base/enums/MarqueeStatus.class new file mode 100644 index 0000000..a6c52f2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/MarqueeStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/MemberLogOperProject.class b/ff-base/target/classes/com/ff/base/enums/MemberLogOperProject.class new file mode 100644 index 0000000..8490129 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/MemberLogOperProject.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/MemberLogOperType.class b/ff-base/target/classes/com/ff/base/enums/MemberLogOperType.class new file mode 100644 index 0000000..5c4567a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/MemberLogOperType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/MemberStatus.class b/ff-base/target/classes/com/ff/base/enums/MemberStatus.class new file mode 100644 index 0000000..2f4b782 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/MemberStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/NoticeStatus.class b/ff-base/target/classes/com/ff/base/enums/NoticeStatus.class new file mode 100644 index 0000000..c06defb Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/NoticeStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/NoticeType.class b/ff-base/target/classes/com/ff/base/enums/NoticeType.class new file mode 100644 index 0000000..6d0d7a4 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/NoticeType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/OperationType.class b/ff-base/target/classes/com/ff/base/enums/OperationType.class new file mode 100644 index 0000000..51ae468 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/OperationType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/OperatorType.class b/ff-base/target/classes/com/ff/base/enums/OperatorType.class new file mode 100644 index 0000000..71f0088 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/OperatorType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/PageType.class b/ff-base/target/classes/com/ff/base/enums/PageType.class new file mode 100644 index 0000000..e6ba33b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/PageType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/PatternSourceType.class b/ff-base/target/classes/com/ff/base/enums/PatternSourceType.class new file mode 100644 index 0000000..b8facb6 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/PatternSourceType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/PlayType.class b/ff-base/target/classes/com/ff/base/enums/PlayType.class new file mode 100644 index 0000000..e94431a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/PlayType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ReadStatus.class b/ff-base/target/classes/com/ff/base/enums/ReadStatus.class new file mode 100644 index 0000000..e37e7a8 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ReadStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/RealtimeRebateReceiveType.class b/ff-base/target/classes/com/ff/base/enums/RealtimeRebateReceiveType.class new file mode 100644 index 0000000..925c836 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/RealtimeRebateReceiveType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/RealtimeRebateSettleType.class b/ff-base/target/classes/com/ff/base/enums/RealtimeRebateSettleType.class new file mode 100644 index 0000000..c2c79ca Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/RealtimeRebateSettleType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/RebateSettlePeriodType.class b/ff-base/target/classes/com/ff/base/enums/RebateSettlePeriodType.class new file mode 100644 index 0000000..b4044d7 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/RebateSettlePeriodType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ReceiptType.class b/ff-base/target/classes/com/ff/base/enums/ReceiptType.class new file mode 100644 index 0000000..10b8add Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ReceiptType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ReceiveLimitType.class b/ff-base/target/classes/com/ff/base/enums/ReceiveLimitType.class new file mode 100644 index 0000000..b9af6e0 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ReceiveLimitType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/ReceiveTimeType.class b/ff-base/target/classes/com/ff/base/enums/ReceiveTimeType.class new file mode 100644 index 0000000..8becd7a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/ReceiveTimeType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/RegisteWay.class b/ff-base/target/classes/com/ff/base/enums/RegisteWay.class new file mode 100644 index 0000000..c034880 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/RegisteWay.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/RepairStatus.class b/ff-base/target/classes/com/ff/base/enums/RepairStatus.class new file mode 100644 index 0000000..207083b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/RepairStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/SetType.class b/ff-base/target/classes/com/ff/base/enums/SetType.class new file mode 100644 index 0000000..067fdd7 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/SetType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/SettleDurationType.class b/ff-base/target/classes/com/ff/base/enums/SettleDurationType.class new file mode 100644 index 0000000..7e7c367 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/SettleDurationType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/SettleStatus.class b/ff-base/target/classes/com/ff/base/enums/SettleStatus.class new file mode 100644 index 0000000..0abacaf Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/SettleStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/SonType.class b/ff-base/target/classes/com/ff/base/enums/SonType.class new file mode 100644 index 0000000..c24125d Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/SonType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/StopStatus.class b/ff-base/target/classes/com/ff/base/enums/StopStatus.class new file mode 100644 index 0000000..57b9129 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/StopStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/SupplierCode.class b/ff-base/target/classes/com/ff/base/enums/SupplierCode.class new file mode 100644 index 0000000..b9fb0e4 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/SupplierCode.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/SysUseType.class b/ff-base/target/classes/com/ff/base/enums/SysUseType.class new file mode 100644 index 0000000..5204a1e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/SysUseType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/TaskBindType.class b/ff-base/target/classes/com/ff/base/enums/TaskBindType.class new file mode 100644 index 0000000..aba6507 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/TaskBindType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/TaskGiveType.class b/ff-base/target/classes/com/ff/base/enums/TaskGiveType.class new file mode 100644 index 0000000..f9908e3 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/TaskGiveType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/TaskType.class b/ff-base/target/classes/com/ff/base/enums/TaskType.class new file mode 100644 index 0000000..3b90998 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/TaskType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/TimePeriodType.class b/ff-base/target/classes/com/ff/base/enums/TimePeriodType.class new file mode 100644 index 0000000..a60513b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/TimePeriodType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/TimeType.class b/ff-base/target/classes/com/ff/base/enums/TimeType.class new file mode 100644 index 0000000..82ac15e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/TimeType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/Tourist.class b/ff-base/target/classes/com/ff/base/enums/Tourist.class new file mode 100644 index 0000000..fefa09c Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/Tourist.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/TrackEventType.class b/ff-base/target/classes/com/ff/base/enums/TrackEventType.class new file mode 100644 index 0000000..7e78248 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/TrackEventType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/TransferType.class b/ff-base/target/classes/com/ff/base/enums/TransferType.class new file mode 100644 index 0000000..7a9b0e1 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/TransferType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/UsageStatus.class b/ff-base/target/classes/com/ff/base/enums/UsageStatus.class new file mode 100644 index 0000000..c34097b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/UsageStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/UserStatus.class b/ff-base/target/classes/com/ff/base/enums/UserStatus.class new file mode 100644 index 0000000..743970c Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/UserStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/WindowStatus.class b/ff-base/target/classes/com/ff/base/enums/WindowStatus.class new file mode 100644 index 0000000..9b6b48b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/WindowStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/WindowType.class b/ff-base/target/classes/com/ff/base/enums/WindowType.class new file mode 100644 index 0000000..d9094a2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/WindowType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/WithdrawAccountStatus.class b/ff-base/target/classes/com/ff/base/enums/WithdrawAccountStatus.class new file mode 100644 index 0000000..7046c0f Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/WithdrawAccountStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/WithdrawBehalfStatus.class b/ff-base/target/classes/com/ff/base/enums/WithdrawBehalfStatus.class new file mode 100644 index 0000000..aaf3769 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/WithdrawBehalfStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/WithdrawStatus.class b/ff-base/target/classes/com/ff/base/enums/WithdrawStatus.class new file mode 100644 index 0000000..969f022 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/WithdrawStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/WithdrawTipStatus.class b/ff-base/target/classes/com/ff/base/enums/WithdrawTipStatus.class new file mode 100644 index 0000000..5e15b5d Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/WithdrawTipStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/XKGameType.class b/ff-base/target/classes/com/ff/base/enums/XKGameType.class new file mode 100644 index 0000000..1363a49 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/XKGameType.class differ diff --git a/ff-base/target/classes/com/ff/base/enums/XjPayStatus.class b/ff-base/target/classes/com/ff/base/enums/XjPayStatus.class new file mode 100644 index 0000000..7dc8c67 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/enums/XjPayStatus.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/DemoModeException.class b/ff-base/target/classes/com/ff/base/exception/DemoModeException.class new file mode 100644 index 0000000..0971503 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/DemoModeException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/GlobalException.class b/ff-base/target/classes/com/ff/base/exception/GlobalException.class new file mode 100644 index 0000000..c61cde2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/GlobalException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/ServiceException.class b/ff-base/target/classes/com/ff/base/exception/ServiceException.class new file mode 100644 index 0000000..bcd3c13 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/ServiceException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/UtilException.class b/ff-base/target/classes/com/ff/base/exception/UtilException.class new file mode 100644 index 0000000..7d68803 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/UtilException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/base/BaseException.class b/ff-base/target/classes/com/ff/base/exception/base/BaseException.class new file mode 100644 index 0000000..c641ec9 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/base/BaseException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/file/FileException.class b/ff-base/target/classes/com/ff/base/exception/file/FileException.class new file mode 100644 index 0000000..441c1b4 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/file/FileException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/file/FileNameLengthLimitExceededException.class b/ff-base/target/classes/com/ff/base/exception/file/FileNameLengthLimitExceededException.class new file mode 100644 index 0000000..5cae560 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/file/FileNameLengthLimitExceededException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/file/FileSizeLimitExceededException.class b/ff-base/target/classes/com/ff/base/exception/file/FileSizeLimitExceededException.class new file mode 100644 index 0000000..fe3ada5 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/file/FileSizeLimitExceededException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/file/FileUploadException.class b/ff-base/target/classes/com/ff/base/exception/file/FileUploadException.class new file mode 100644 index 0000000..3d9e48f Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/file/FileUploadException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidFlashExtensionException.class b/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidFlashExtensionException.class new file mode 100644 index 0000000..012305f Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidFlashExtensionException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidImageExtensionException.class b/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidImageExtensionException.class new file mode 100644 index 0000000..f1aed13 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidImageExtensionException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidMediaExtensionException.class b/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidMediaExtensionException.class new file mode 100644 index 0000000..236d468 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidMediaExtensionException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidVideoExtensionException.class b/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidVideoExtensionException.class new file mode 100644 index 0000000..c4a8e4b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException$InvalidVideoExtensionException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException.class b/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException.class new file mode 100644 index 0000000..266e7d5 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/file/InvalidExtensionException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/job/TaskException$Code.class b/ff-base/target/classes/com/ff/base/exception/job/TaskException$Code.class new file mode 100644 index 0000000..41f4b11 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/job/TaskException$Code.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/job/TaskException.class b/ff-base/target/classes/com/ff/base/exception/job/TaskException.class new file mode 100644 index 0000000..e065c61 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/job/TaskException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/user/BlackListException.class b/ff-base/target/classes/com/ff/base/exception/user/BlackListException.class new file mode 100644 index 0000000..decd5b0 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/user/BlackListException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/user/CaptchaException.class b/ff-base/target/classes/com/ff/base/exception/user/CaptchaException.class new file mode 100644 index 0000000..7746abb Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/user/CaptchaException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/user/CaptchaExpireException.class b/ff-base/target/classes/com/ff/base/exception/user/CaptchaExpireException.class new file mode 100644 index 0000000..8875526 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/user/CaptchaExpireException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/user/UserException.class b/ff-base/target/classes/com/ff/base/exception/user/UserException.class new file mode 100644 index 0000000..a80767a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/user/UserException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/user/UserNotExistsException.class b/ff-base/target/classes/com/ff/base/exception/user/UserNotExistsException.class new file mode 100644 index 0000000..743e64d Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/user/UserNotExistsException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/user/UserPasswordNotMatchException.class b/ff-base/target/classes/com/ff/base/exception/user/UserPasswordNotMatchException.class new file mode 100644 index 0000000..12809ca Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/user/UserPasswordNotMatchException.class differ diff --git a/ff-base/target/classes/com/ff/base/exception/user/UserPasswordRetryLimitExceedException.class b/ff-base/target/classes/com/ff/base/exception/user/UserPasswordRetryLimitExceedException.class new file mode 100644 index 0000000..80001e9 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/exception/user/UserPasswordRetryLimitExceedException.class differ diff --git a/ff-base/target/classes/com/ff/base/filter/PropertyPreExcludeFilter.class b/ff-base/target/classes/com/ff/base/filter/PropertyPreExcludeFilter.class new file mode 100644 index 0000000..fe9f451 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/filter/PropertyPreExcludeFilter.class differ diff --git a/ff-base/target/classes/com/ff/base/filter/RepeatableFilter.class b/ff-base/target/classes/com/ff/base/filter/RepeatableFilter.class new file mode 100644 index 0000000..b7c6a1c Binary files /dev/null and b/ff-base/target/classes/com/ff/base/filter/RepeatableFilter.class differ diff --git a/ff-base/target/classes/com/ff/base/filter/RepeatedlyRequestWrapper$1.class b/ff-base/target/classes/com/ff/base/filter/RepeatedlyRequestWrapper$1.class new file mode 100644 index 0000000..f934002 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/filter/RepeatedlyRequestWrapper$1.class differ diff --git a/ff-base/target/classes/com/ff/base/filter/RepeatedlyRequestWrapper.class b/ff-base/target/classes/com/ff/base/filter/RepeatedlyRequestWrapper.class new file mode 100644 index 0000000..9da3080 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/filter/RepeatedlyRequestWrapper.class differ diff --git a/ff-base/target/classes/com/ff/base/filter/XssFilter.class b/ff-base/target/classes/com/ff/base/filter/XssFilter.class new file mode 100644 index 0000000..0e29648 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/filter/XssFilter.class differ diff --git a/ff-base/target/classes/com/ff/base/filter/XssHttpServletRequestWrapper$1.class b/ff-base/target/classes/com/ff/base/filter/XssHttpServletRequestWrapper$1.class new file mode 100644 index 0000000..2d7b1b2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/filter/XssHttpServletRequestWrapper$1.class differ diff --git a/ff-base/target/classes/com/ff/base/filter/XssHttpServletRequestWrapper.class b/ff-base/target/classes/com/ff/base/filter/XssHttpServletRequestWrapper.class new file mode 100644 index 0000000..938f8cb Binary files /dev/null and b/ff-base/target/classes/com/ff/base/filter/XssHttpServletRequestWrapper.class differ diff --git a/ff-base/target/classes/com/ff/base/interceptor/DataSourceSwitchInterceptor.class b/ff-base/target/classes/com/ff/base/interceptor/DataSourceSwitchInterceptor.class new file mode 100644 index 0000000..2ab3ae9 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/interceptor/DataSourceSwitchInterceptor.class differ diff --git a/ff-base/target/classes/com/ff/base/interceptor/RepeatSubmitInterceptor.class b/ff-base/target/classes/com/ff/base/interceptor/RepeatSubmitInterceptor.class new file mode 100644 index 0000000..05c8b49 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/interceptor/RepeatSubmitInterceptor.class differ diff --git a/ff-base/target/classes/com/ff/base/interceptor/impl/SameUrlDataInterceptor.class b/ff-base/target/classes/com/ff/base/interceptor/impl/SameUrlDataInterceptor.class new file mode 100644 index 0000000..e00d0b6 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/interceptor/impl/SameUrlDataInterceptor.class differ diff --git a/ff-base/target/classes/com/ff/base/manager/AsyncManager.class b/ff-base/target/classes/com/ff/base/manager/AsyncManager.class new file mode 100644 index 0000000..45564c2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/manager/AsyncManager.class differ diff --git a/ff-base/target/classes/com/ff/base/manager/ShutdownManager.class b/ff-base/target/classes/com/ff/base/manager/ShutdownManager.class new file mode 100644 index 0000000..36e7c9e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/manager/ShutdownManager.class differ diff --git a/ff-base/target/classes/com/ff/base/manager/factory/AsyncFactory$1.class b/ff-base/target/classes/com/ff/base/manager/factory/AsyncFactory$1.class new file mode 100644 index 0000000..f9fde85 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/manager/factory/AsyncFactory$1.class differ diff --git a/ff-base/target/classes/com/ff/base/manager/factory/AsyncFactory$2.class b/ff-base/target/classes/com/ff/base/manager/factory/AsyncFactory$2.class new file mode 100644 index 0000000..2d72cfd Binary files /dev/null and b/ff-base/target/classes/com/ff/base/manager/factory/AsyncFactory$2.class differ diff --git a/ff-base/target/classes/com/ff/base/manager/factory/AsyncFactory.class b/ff-base/target/classes/com/ff/base/manager/factory/AsyncFactory.class new file mode 100644 index 0000000..8f8236a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/manager/factory/AsyncFactory.class differ diff --git a/ff-base/target/classes/com/ff/base/security/context/AuthenticationContextHolder.class b/ff-base/target/classes/com/ff/base/security/context/AuthenticationContextHolder.class new file mode 100644 index 0000000..b674b0b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/security/context/AuthenticationContextHolder.class differ diff --git a/ff-base/target/classes/com/ff/base/security/context/PermissionContextHolder.class b/ff-base/target/classes/com/ff/base/security/context/PermissionContextHolder.class new file mode 100644 index 0000000..0accd4d Binary files /dev/null and b/ff-base/target/classes/com/ff/base/security/context/PermissionContextHolder.class differ diff --git a/ff-base/target/classes/com/ff/base/security/encode/CustomMd5PasswordEncoder.class b/ff-base/target/classes/com/ff/base/security/encode/CustomMd5PasswordEncoder.class new file mode 100644 index 0000000..df1468d Binary files /dev/null and b/ff-base/target/classes/com/ff/base/security/encode/CustomMd5PasswordEncoder.class differ diff --git a/ff-base/target/classes/com/ff/base/security/filter/JwtAuthenticationTokenFilter.class b/ff-base/target/classes/com/ff/base/security/filter/JwtAuthenticationTokenFilter.class new file mode 100644 index 0000000..8ca4be1 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/security/filter/JwtAuthenticationTokenFilter.class differ diff --git a/ff-base/target/classes/com/ff/base/security/handle/AuthenticationEntryPointImpl.class b/ff-base/target/classes/com/ff/base/security/handle/AuthenticationEntryPointImpl.class new file mode 100644 index 0000000..e2de387 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/security/handle/AuthenticationEntryPointImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/security/handle/LogoutSuccessHandlerImpl.class b/ff-base/target/classes/com/ff/base/security/handle/LogoutSuccessHandlerImpl.class new file mode 100644 index 0000000..ce425f4 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/security/handle/LogoutSuccessHandlerImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/security/provider/MyDaoAuthenticationProvider.class b/ff-base/target/classes/com/ff/base/security/provider/MyDaoAuthenticationProvider.class new file mode 100644 index 0000000..3159146 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/security/provider/MyDaoAuthenticationProvider.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysConfig.class b/ff-base/target/classes/com/ff/base/system/domain/SysConfig.class new file mode 100644 index 0000000..fe66462 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysConfig.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysDatasource.class b/ff-base/target/classes/com/ff/base/system/domain/SysDatasource.class new file mode 100644 index 0000000..1cec895 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysDatasource.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysDept.class b/ff-base/target/classes/com/ff/base/system/domain/SysDept.class new file mode 100644 index 0000000..2f0ca5b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysDept.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysDictData$DictDataSimpleView.class b/ff-base/target/classes/com/ff/base/system/domain/SysDictData$DictDataSimpleView.class new file mode 100644 index 0000000..6590cae Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysDictData$DictDataSimpleView.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysDictData.class b/ff-base/target/classes/com/ff/base/system/domain/SysDictData.class new file mode 100644 index 0000000..80c648b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysDictData.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysDictType.class b/ff-base/target/classes/com/ff/base/system/domain/SysDictType.class new file mode 100644 index 0000000..57771ce Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysDictType.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysLogininfor.class b/ff-base/target/classes/com/ff/base/system/domain/SysLogininfor.class new file mode 100644 index 0000000..d10eba3 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysLogininfor.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysMenu.class b/ff-base/target/classes/com/ff/base/system/domain/SysMenu.class new file mode 100644 index 0000000..362e1a0 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysMenu.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysOperLog.class b/ff-base/target/classes/com/ff/base/system/domain/SysOperLog.class new file mode 100644 index 0000000..351ba83 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysOperLog.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysPost.class b/ff-base/target/classes/com/ff/base/system/domain/SysPost.class new file mode 100644 index 0000000..450bc82 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysPost.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysRole.class b/ff-base/target/classes/com/ff/base/system/domain/SysRole.class new file mode 100644 index 0000000..b7cec47 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysRole.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysRoleDept.class b/ff-base/target/classes/com/ff/base/system/domain/SysRoleDept.class new file mode 100644 index 0000000..107d0e6 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysRoleDept.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysRoleMenu.class b/ff-base/target/classes/com/ff/base/system/domain/SysRoleMenu.class new file mode 100644 index 0000000..5c4217e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysRoleMenu.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysUser.class b/ff-base/target/classes/com/ff/base/system/domain/SysUser.class new file mode 100644 index 0000000..2765374 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysUser.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysUserOnline.class b/ff-base/target/classes/com/ff/base/system/domain/SysUserOnline.class new file mode 100644 index 0000000..ab9208e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysUserOnline.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysUserPost.class b/ff-base/target/classes/com/ff/base/system/domain/SysUserPost.class new file mode 100644 index 0000000..3ff6d0a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysUserPost.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/SysUserRole.class b/ff-base/target/classes/com/ff/base/system/domain/SysUserRole.class new file mode 100644 index 0000000..18ace52 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/SysUserRole.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/vo/MetaVo.class b/ff-base/target/classes/com/ff/base/system/domain/vo/MetaVo.class new file mode 100644 index 0000000..f54b4f1 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/vo/MetaVo.class differ diff --git a/ff-base/target/classes/com/ff/base/system/domain/vo/RouterVo.class b/ff-base/target/classes/com/ff/base/system/domain/vo/RouterVo.class new file mode 100644 index 0000000..6aa59aa Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/domain/vo/RouterVo.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysConfigMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysConfigMapper.class new file mode 100644 index 0000000..68dc058 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysConfigMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysDatasourceMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysDatasourceMapper.class new file mode 100644 index 0000000..ec81ae0 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysDatasourceMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysDeptMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysDeptMapper.class new file mode 100644 index 0000000..571770c Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysDeptMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysDictDataMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysDictDataMapper.class new file mode 100644 index 0000000..053e6aa Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysDictDataMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysDictTypeMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysDictTypeMapper.class new file mode 100644 index 0000000..2e0a19b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysDictTypeMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysLogininforMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysLogininforMapper.class new file mode 100644 index 0000000..455af8e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysLogininforMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysMenuMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysMenuMapper.class new file mode 100644 index 0000000..2de76cf Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysMenuMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysOperLogMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysOperLogMapper.class new file mode 100644 index 0000000..be7e651 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysOperLogMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysPostMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysPostMapper.class new file mode 100644 index 0000000..4c6f554 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysPostMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysRoleDeptMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysRoleDeptMapper.class new file mode 100644 index 0000000..5d2a478 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysRoleDeptMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysRoleMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysRoleMapper.class new file mode 100644 index 0000000..c9b6ce4 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysRoleMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysRoleMenuMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysRoleMenuMapper.class new file mode 100644 index 0000000..b402c64 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysRoleMenuMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysUserMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysUserMapper.class new file mode 100644 index 0000000..96d95fb Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysUserMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysUserPostMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysUserPostMapper.class new file mode 100644 index 0000000..1928e4e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysUserPostMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/mapper/SysUserRoleMapper.class b/ff-base/target/classes/com/ff/base/system/mapper/SysUserRoleMapper.class new file mode 100644 index 0000000..1da709b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/mapper/SysUserRoleMapper.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/ISysConfigService.class b/ff-base/target/classes/com/ff/base/system/service/ISysConfigService.class new file mode 100644 index 0000000..4c4f927 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/ISysConfigService.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/ISysDatasourceService.class b/ff-base/target/classes/com/ff/base/system/service/ISysDatasourceService.class new file mode 100644 index 0000000..c7dba61 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/ISysDatasourceService.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/ISysDeptService.class b/ff-base/target/classes/com/ff/base/system/service/ISysDeptService.class new file mode 100644 index 0000000..ac22e79 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/ISysDeptService.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/ISysDictDataService.class b/ff-base/target/classes/com/ff/base/system/service/ISysDictDataService.class new file mode 100644 index 0000000..ddc8557 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/ISysDictDataService.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/ISysDictTypeService.class b/ff-base/target/classes/com/ff/base/system/service/ISysDictTypeService.class new file mode 100644 index 0000000..33dcbb3 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/ISysDictTypeService.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/ISysLogininforService.class b/ff-base/target/classes/com/ff/base/system/service/ISysLogininforService.class new file mode 100644 index 0000000..02256c2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/ISysLogininforService.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/ISysMenuService.class b/ff-base/target/classes/com/ff/base/system/service/ISysMenuService.class new file mode 100644 index 0000000..4d13c1f Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/ISysMenuService.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/ISysOperLogService.class b/ff-base/target/classes/com/ff/base/system/service/ISysOperLogService.class new file mode 100644 index 0000000..7c71041 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/ISysOperLogService.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/ISysPostService.class b/ff-base/target/classes/com/ff/base/system/service/ISysPostService.class new file mode 100644 index 0000000..771cfcb Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/ISysPostService.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/ISysRoleService.class b/ff-base/target/classes/com/ff/base/system/service/ISysRoleService.class new file mode 100644 index 0000000..a9249e4 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/ISysRoleService.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/ISysUserOnlineService.class b/ff-base/target/classes/com/ff/base/system/service/ISysUserOnlineService.class new file mode 100644 index 0000000..ba79a3b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/ISysUserOnlineService.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/ISysUserService.class b/ff-base/target/classes/com/ff/base/system/service/ISysUserService.class new file mode 100644 index 0000000..0c847b8 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/ISysUserService.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/impl/SysConfigServiceImpl.class b/ff-base/target/classes/com/ff/base/system/service/impl/SysConfigServiceImpl.class new file mode 100644 index 0000000..d8e7020 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/impl/SysConfigServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/impl/SysDatasourceServiceImpl.class b/ff-base/target/classes/com/ff/base/system/service/impl/SysDatasourceServiceImpl.class new file mode 100644 index 0000000..029b574 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/impl/SysDatasourceServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/impl/SysDeptServiceImpl.class b/ff-base/target/classes/com/ff/base/system/service/impl/SysDeptServiceImpl.class new file mode 100644 index 0000000..63e16e6 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/impl/SysDeptServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/impl/SysDictDataServiceImpl.class b/ff-base/target/classes/com/ff/base/system/service/impl/SysDictDataServiceImpl.class new file mode 100644 index 0000000..583d316 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/impl/SysDictDataServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/impl/SysDictTypeServiceImpl.class b/ff-base/target/classes/com/ff/base/system/service/impl/SysDictTypeServiceImpl.class new file mode 100644 index 0000000..d6c1cf5 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/impl/SysDictTypeServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/impl/SysLogininforServiceImpl.class b/ff-base/target/classes/com/ff/base/system/service/impl/SysLogininforServiceImpl.class new file mode 100644 index 0000000..335e5a0 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/impl/SysLogininforServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/impl/SysMenuServiceImpl.class b/ff-base/target/classes/com/ff/base/system/service/impl/SysMenuServiceImpl.class new file mode 100644 index 0000000..2e6a23c Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/impl/SysMenuServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/impl/SysOperLogServiceImpl.class b/ff-base/target/classes/com/ff/base/system/service/impl/SysOperLogServiceImpl.class new file mode 100644 index 0000000..8f11be5 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/impl/SysOperLogServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/impl/SysPostServiceImpl.class b/ff-base/target/classes/com/ff/base/system/service/impl/SysPostServiceImpl.class new file mode 100644 index 0000000..812d624 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/impl/SysPostServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/impl/SysRoleServiceImpl.class b/ff-base/target/classes/com/ff/base/system/service/impl/SysRoleServiceImpl.class new file mode 100644 index 0000000..d27b9e4 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/impl/SysRoleServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/impl/SysUserOnlineServiceImpl.class b/ff-base/target/classes/com/ff/base/system/service/impl/SysUserOnlineServiceImpl.class new file mode 100644 index 0000000..ab6e72a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/impl/SysUserOnlineServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/system/service/impl/SysUserServiceImpl.class b/ff-base/target/classes/com/ff/base/system/service/impl/SysUserServiceImpl.class new file mode 100644 index 0000000..18d5d98 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/system/service/impl/SysUserServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/Arith.class b/ff-base/target/classes/com/ff/base/utils/Arith.class new file mode 100644 index 0000000..ba27841 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/Arith.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/DateUtils.class b/ff-base/target/classes/com/ff/base/utils/DateUtils.class new file mode 100644 index 0000000..4e79781 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/DateUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/DesensitizedUtil.class b/ff-base/target/classes/com/ff/base/utils/DesensitizedUtil.class new file mode 100644 index 0000000..834deae Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/DesensitizedUtil.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/DictUtils.class b/ff-base/target/classes/com/ff/base/utils/DictUtils.class new file mode 100644 index 0000000..d0b0cf9 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/DictUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/ExceptionUtil.class b/ff-base/target/classes/com/ff/base/utils/ExceptionUtil.class new file mode 100644 index 0000000..c9d4010 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/ExceptionUtil.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/JsonUtil.class b/ff-base/target/classes/com/ff/base/utils/JsonUtil.class new file mode 100644 index 0000000..7e3fdd8 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/JsonUtil.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/LogUtils.class b/ff-base/target/classes/com/ff/base/utils/LogUtils.class new file mode 100644 index 0000000..d7f1eaa Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/LogUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/MessageUtils.class b/ff-base/target/classes/com/ff/base/utils/MessageUtils.class new file mode 100644 index 0000000..88fbb9a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/MessageUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/NumberUtils.class b/ff-base/target/classes/com/ff/base/utils/NumberUtils.class new file mode 100644 index 0000000..4201643 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/NumberUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/PageUtils.class b/ff-base/target/classes/com/ff/base/utils/PageUtils.class new file mode 100644 index 0000000..0a1051c Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/PageUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/SecurityUtils.class b/ff-base/target/classes/com/ff/base/utils/SecurityUtils.class new file mode 100644 index 0000000..7905dab Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/SecurityUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/ServletUtils.class b/ff-base/target/classes/com/ff/base/utils/ServletUtils.class new file mode 100644 index 0000000..90f8072 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/ServletUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/SnowflakeIdGenerator.class b/ff-base/target/classes/com/ff/base/utils/SnowflakeIdGenerator.class new file mode 100644 index 0000000..6133d91 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/SnowflakeIdGenerator.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/StringUtils.class b/ff-base/target/classes/com/ff/base/utils/StringUtils.class new file mode 100644 index 0000000..3685559 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/StringUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/TenantUtils.class b/ff-base/target/classes/com/ff/base/utils/TenantUtils.class new file mode 100644 index 0000000..7a60f83 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/TenantUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/Threads.class b/ff-base/target/classes/com/ff/base/utils/Threads.class new file mode 100644 index 0000000..47c62ca Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/Threads.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/bean/BeanUtils.class b/ff-base/target/classes/com/ff/base/utils/bean/BeanUtils.class new file mode 100644 index 0000000..5c550fe Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/bean/BeanUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/bean/BeanValidators.class b/ff-base/target/classes/com/ff/base/utils/bean/BeanValidators.class new file mode 100644 index 0000000..72fbce2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/bean/BeanValidators.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/domain/DomainInfo$WhoisInfo.class b/ff-base/target/classes/com/ff/base/utils/domain/DomainInfo$WhoisInfo.class new file mode 100644 index 0000000..cf57742 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/domain/DomainInfo$WhoisInfo.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/domain/DomainInfo.class b/ff-base/target/classes/com/ff/base/utils/domain/DomainInfo.class new file mode 100644 index 0000000..bab5a28 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/domain/DomainInfo.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/domain/DomainUtils.class b/ff-base/target/classes/com/ff/base/utils/domain/DomainUtils.class new file mode 100644 index 0000000..abcfb44 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/domain/DomainUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/file/FileTypeUtils.class b/ff-base/target/classes/com/ff/base/utils/file/FileTypeUtils.class new file mode 100644 index 0000000..6d62b6e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/file/FileTypeUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/file/FileUploadUtils.class b/ff-base/target/classes/com/ff/base/utils/file/FileUploadUtils.class new file mode 100644 index 0000000..50767d9 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/file/FileUploadUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/file/FileUtils.class b/ff-base/target/classes/com/ff/base/utils/file/FileUtils.class new file mode 100644 index 0000000..a96dce1 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/file/FileUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/file/ImageUtils.class b/ff-base/target/classes/com/ff/base/utils/file/ImageUtils.class new file mode 100644 index 0000000..59b0f81 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/file/ImageUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/file/MimeTypeUtils.class b/ff-base/target/classes/com/ff/base/utils/file/MimeTypeUtils.class new file mode 100644 index 0000000..077fcf2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/file/MimeTypeUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/html/EscapeUtil.class b/ff-base/target/classes/com/ff/base/utils/html/EscapeUtil.class new file mode 100644 index 0000000..75c36b3 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/html/EscapeUtil.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/html/HTMLFilter.class b/ff-base/target/classes/com/ff/base/utils/html/HTMLFilter.class new file mode 100644 index 0000000..87376bd Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/html/HTMLFilter.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$1.class b/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$1.class new file mode 100644 index 0000000..78b3381 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$1.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$TrustAllCerts.class b/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$TrustAllCerts.class new file mode 100644 index 0000000..054db3c Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$TrustAllCerts.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$TrustAllHostnameVerifier.class b/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$TrustAllHostnameVerifier.class new file mode 100644 index 0000000..df7537e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$TrustAllHostnameVerifier.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$TrustAllX509TrustManager.class b/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$TrustAllX509TrustManager.class new file mode 100644 index 0000000..68460aa Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils$TrustAllX509TrustManager.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils.class b/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils.class new file mode 100644 index 0000000..8aef847 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/http/HttpClientSslUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/http/HttpHelper.class b/ff-base/target/classes/com/ff/base/utils/http/HttpHelper.class new file mode 100644 index 0000000..a811ef6 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/http/HttpHelper.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/http/HttpUtils$1.class b/ff-base/target/classes/com/ff/base/utils/http/HttpUtils$1.class new file mode 100644 index 0000000..da2f26a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/http/HttpUtils$1.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/http/HttpUtils$TrustAnyHostnameVerifier.class b/ff-base/target/classes/com/ff/base/utils/http/HttpUtils$TrustAnyHostnameVerifier.class new file mode 100644 index 0000000..2b3318a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/http/HttpUtils$TrustAnyHostnameVerifier.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/http/HttpUtils$TrustAnyTrustManager.class b/ff-base/target/classes/com/ff/base/utils/http/HttpUtils$TrustAnyTrustManager.class new file mode 100644 index 0000000..639d15e Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/http/HttpUtils$TrustAnyTrustManager.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/http/HttpUtils.class b/ff-base/target/classes/com/ff/base/utils/http/HttpUtils.class new file mode 100644 index 0000000..46b58a1 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/http/HttpUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/ip/AddressUtils.class b/ff-base/target/classes/com/ff/base/utils/ip/AddressUtils.class new file mode 100644 index 0000000..b508691 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/ip/AddressUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/ip/IpUtils.class b/ff-base/target/classes/com/ff/base/utils/ip/IpUtils.class new file mode 100644 index 0000000..a676f49 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/ip/IpUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/nginx/NginxUtils.class b/ff-base/target/classes/com/ff/base/utils/nginx/NginxUtils.class new file mode 100644 index 0000000..cb9e6e6 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/nginx/NginxUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/poi/ExcelHandlerAdapter.class b/ff-base/target/classes/com/ff/base/utils/poi/ExcelHandlerAdapter.class new file mode 100644 index 0000000..886edf4 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/poi/ExcelHandlerAdapter.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/poi/ExcelUtil.class b/ff-base/target/classes/com/ff/base/utils/poi/ExcelUtil.class new file mode 100644 index 0000000..d5e3647 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/poi/ExcelUtil.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/qrcode/QRCodeGenerator.class b/ff-base/target/classes/com/ff/base/utils/qrcode/QRCodeGenerator.class new file mode 100644 index 0000000..24093e6 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/qrcode/QRCodeGenerator.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/reflect/ReflectUtils.class b/ff-base/target/classes/com/ff/base/utils/reflect/ReflectUtils.class new file mode 100644 index 0000000..800f93a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/reflect/ReflectUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/sign/Base64.class b/ff-base/target/classes/com/ff/base/utils/sign/Base64.class new file mode 100644 index 0000000..a725c91 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/sign/Base64.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/sign/Md5Utils.class b/ff-base/target/classes/com/ff/base/utils/sign/Md5Utils.class new file mode 100644 index 0000000..1ab64c2 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/sign/Md5Utils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/spring/SpringUtils.class b/ff-base/target/classes/com/ff/base/utils/spring/SpringUtils.class new file mode 100644 index 0000000..104e5c4 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/spring/SpringUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/sql/SqlUtil.class b/ff-base/target/classes/com/ff/base/utils/sql/SqlUtil.class new file mode 100644 index 0000000..d7d6128 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/sql/SqlUtil.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/uuid/IdUtils.class b/ff-base/target/classes/com/ff/base/utils/uuid/IdUtils.class new file mode 100644 index 0000000..8b80106 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/uuid/IdUtils.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/uuid/Seq.class b/ff-base/target/classes/com/ff/base/utils/uuid/Seq.class new file mode 100644 index 0000000..2c63e6f Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/uuid/Seq.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/uuid/UUID$Holder.class b/ff-base/target/classes/com/ff/base/utils/uuid/UUID$Holder.class new file mode 100644 index 0000000..7a22f0b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/uuid/UUID$Holder.class differ diff --git a/ff-base/target/classes/com/ff/base/utils/uuid/UUID.class b/ff-base/target/classes/com/ff/base/utils/uuid/UUID.class new file mode 100644 index 0000000..20a425d Binary files /dev/null and b/ff-base/target/classes/com/ff/base/utils/uuid/UUID.class differ diff --git a/ff-base/target/classes/com/ff/base/web/domain/server/Cpu.class b/ff-base/target/classes/com/ff/base/web/domain/server/Cpu.class new file mode 100644 index 0000000..0b09dba Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/domain/server/Cpu.class differ diff --git a/ff-base/target/classes/com/ff/base/web/domain/server/Jvm.class b/ff-base/target/classes/com/ff/base/web/domain/server/Jvm.class new file mode 100644 index 0000000..415a7ee Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/domain/server/Jvm.class differ diff --git a/ff-base/target/classes/com/ff/base/web/domain/server/Mem.class b/ff-base/target/classes/com/ff/base/web/domain/server/Mem.class new file mode 100644 index 0000000..f4205d0 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/domain/server/Mem.class differ diff --git a/ff-base/target/classes/com/ff/base/web/domain/server/Sys.class b/ff-base/target/classes/com/ff/base/web/domain/server/Sys.class new file mode 100644 index 0000000..af9abd3 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/domain/server/Sys.class differ diff --git a/ff-base/target/classes/com/ff/base/web/domain/server/SysFile.class b/ff-base/target/classes/com/ff/base/web/domain/server/SysFile.class new file mode 100644 index 0000000..03b9668 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/domain/server/SysFile.class differ diff --git a/ff-base/target/classes/com/ff/base/web/exception/GlobalExceptionHandler.class b/ff-base/target/classes/com/ff/base/web/exception/GlobalExceptionHandler.class new file mode 100644 index 0000000..f368c9f Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/exception/GlobalExceptionHandler.class differ diff --git a/ff-base/target/classes/com/ff/base/web/service/MemberDetailsServiceImpl.class b/ff-base/target/classes/com/ff/base/web/service/MemberDetailsServiceImpl.class new file mode 100644 index 0000000..e65ed5f Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/service/MemberDetailsServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/web/service/PermissionService.class b/ff-base/target/classes/com/ff/base/web/service/PermissionService.class new file mode 100644 index 0000000..be54646 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/service/PermissionService.class differ diff --git a/ff-base/target/classes/com/ff/base/web/service/SysLoginService.class b/ff-base/target/classes/com/ff/base/web/service/SysLoginService.class new file mode 100644 index 0000000..b1ed153 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/service/SysLoginService.class differ diff --git a/ff-base/target/classes/com/ff/base/web/service/SysPasswordService.class b/ff-base/target/classes/com/ff/base/web/service/SysPasswordService.class new file mode 100644 index 0000000..0a5dc9a Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/service/SysPasswordService.class differ diff --git a/ff-base/target/classes/com/ff/base/web/service/SysPermissionService.class b/ff-base/target/classes/com/ff/base/web/service/SysPermissionService.class new file mode 100644 index 0000000..4801a5b Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/service/SysPermissionService.class differ diff --git a/ff-base/target/classes/com/ff/base/web/service/SysRegisterService.class b/ff-base/target/classes/com/ff/base/web/service/SysRegisterService.class new file mode 100644 index 0000000..e28f9e9 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/service/SysRegisterService.class differ diff --git a/ff-base/target/classes/com/ff/base/web/service/TokenService.class b/ff-base/target/classes/com/ff/base/web/service/TokenService.class new file mode 100644 index 0000000..a7316cd Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/service/TokenService.class differ diff --git a/ff-base/target/classes/com/ff/base/web/service/UserDetailsServiceImpl.class b/ff-base/target/classes/com/ff/base/web/service/UserDetailsServiceImpl.class new file mode 100644 index 0000000..4161af1 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/web/service/UserDetailsServiceImpl.class differ diff --git a/ff-base/target/classes/com/ff/base/xss/Xss.class b/ff-base/target/classes/com/ff/base/xss/Xss.class new file mode 100644 index 0000000..4af8077 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/xss/Xss.class differ diff --git a/ff-base/target/classes/com/ff/base/xss/XssValidator.class b/ff-base/target/classes/com/ff/base/xss/XssValidator.class new file mode 100644 index 0000000..100e655 Binary files /dev/null and b/ff-base/target/classes/com/ff/base/xss/XssValidator.class differ diff --git a/ff-base/target/classes/mapper/system/SysConfigMapper.xml b/ff-base/target/classes/mapper/system/SysConfigMapper.xml new file mode 100644 index 0000000..3f892d3 --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysConfigMapper.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + select config_id, config_name, config_key, config_value, config_type, create_by, create_time, update_by, update_time, remark + from sys_config + + + + + + + and config_id = #{configId} + + + and config_key = #{configKey} + + + + + + + + + + + + + + insert into sys_config ( + config_name, + config_key, + config_value, + config_type, + create_by, + remark, + create_time + )values( + #{configName}, + #{configKey}, + #{configValue}, + #{configType}, + #{createBy}, + #{remark}, + UNIX_TIMESTAMP() * 1000 + ) + + + + update sys_config + + config_name = #{configName}, + config_key = #{configKey}, + config_value = #{configValue}, + config_type = #{configType}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = UNIX_TIMESTAMP() * 1000 + + where config_id = #{configId} + + + + update sys_config + + config_name = #{configName}, + config_value = #{configValue}, + config_type = #{configType}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = UNIX_TIMESTAMP() * 1000 + + where config_key = #{configKey} + + + + delete from sys_config where config_id = #{configId} + + + + delete from sys_config where config_id in + + #{configId} + + + + diff --git a/ff-base/target/classes/mapper/system/SysDatasourceMapper.xml b/ff-base/target/classes/mapper/system/SysDatasourceMapper.xml new file mode 100644 index 0000000..fe37001 --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysDatasourceMapper.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + select id, tenant_id, url,time_zone_name, username, password, driver_class_name, status, create_by, create_time, update_by, update_time, time_zone from sys_datasource + + + + + + + + + + insert into sys_datasource + + id, + tenant_id, + url, + username, + password, + driver_class_name, + status, + create_by, + create_time, + update_by, + update_time, + time_zone, + time_zone_name, + + + #{id}, + #{tenantId}, + #{url}, + #{username}, + #{password}, + #{driverClassName}, + #{status}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{timeZone}, + #{timeZoneName}, + + + + + update sys_datasource + + tenant_id = #{tenantId}, + url = #{url}, + username = #{username}, + password = #{password}, + driver_class_name = #{driverClassName}, + status = #{status}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + time_zone = #{timeZone}, + time_zone_name = #{timeZoneName}, + + where id = #{id} + + + + delete from sys_datasource where id = #{id} + + + + delete from sys_datasource where id in + + #{id} + + + + diff --git a/ff-base/target/classes/mapper/system/SysDeptMapper.xml b/ff-base/target/classes/mapper/system/SysDeptMapper.xml new file mode 100644 index 0000000..80eb339 --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysDeptMapper.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time + from sys_dept d + + + + + + + + + + + + + + + + + + + + insert into sys_dept( + dept_id, + parent_id, + dept_name, + ancestors, + order_num, + leader, + phone, + email, + status, + create_by, + create_time + )values( + #{deptId}, + #{parentId}, + #{deptName}, + #{ancestors}, + #{orderNum}, + #{leader}, + #{phone}, + #{email}, + #{status}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + + update sys_dept + + parent_id = #{parentId}, + dept_name = #{deptName}, + ancestors = #{ancestors}, + order_num = #{orderNum}, + leader = #{leader}, + phone = #{phone}, + email = #{email}, + status = #{status}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where dept_id = #{deptId} + + + + update sys_dept set ancestors = + + when #{item.deptId} then #{item.ancestors} + + where dept_id in + + #{item.deptId} + + + + + update sys_dept set status = '0' where dept_id in + + #{deptId} + + + + + update sys_dept set del_flag = '2' where dept_id = #{deptId} + + + diff --git a/ff-base/target/classes/mapper/system/SysDictDataMapper.xml b/ff-base/target/classes/mapper/system/SysDictDataMapper.xml new file mode 100644 index 0000000..ba236a1 --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysDictDataMapper.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark + from sys_dict_data + + + + + + + + + + + + + + delete from sys_dict_data where dict_code = #{dictCode} + + + + delete from sys_dict_data where dict_code in + + #{dictCode} + + + + + update sys_dict_data + + dict_sort = #{dictSort}, + dict_label = #{dictLabel}, + dict_value = #{dictValue}, + dict_type = #{dictType}, + css_class = #{cssClass}, + list_class = #{listClass}, + is_default = #{isDefault}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where dict_code = #{dictCode} + + + + update sys_dict_data set dict_type = #{newDictType} where dict_type = #{oldDictType} + + + + insert into sys_dict_data( + dict_sort, + dict_label, + dict_value, + dict_type, + css_class, + list_class, + is_default, + status, + remark, + create_by, + create_time + )values( + #{dictSort}, + #{dictLabel}, + #{dictValue}, + #{dictType}, + #{cssClass}, + #{listClass}, + #{isDefault}, + #{status}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + diff --git a/ff-base/target/classes/mapper/system/SysDictTypeMapper.xml b/ff-base/target/classes/mapper/system/SysDictTypeMapper.xml new file mode 100644 index 0000000..807f83d --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysDictTypeMapper.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + select dict_id, dict_name, dict_type, status, create_by, create_time, remark + from sys_dict_type + + + + + + + + + + + + + + delete from sys_dict_type where dict_id = #{dictId} + + + + delete from sys_dict_type where dict_id in + + #{dictId} + + + + + update sys_dict_type + + dict_name = #{dictName}, + dict_type = #{dictType}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where dict_id = #{dictId} + + + + insert into sys_dict_type( + dict_name, + dict_type, + status, + remark, + create_by, + create_time + )values( + #{dictName}, + #{dictType}, + #{status}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + diff --git a/ff-base/target/classes/mapper/system/SysLogininforMapper.xml b/ff-base/target/classes/mapper/system/SysLogininforMapper.xml new file mode 100644 index 0000000..5033e33 --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysLogininforMapper.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + insert into sys_logininfor (user_name, status, ipaddr, login_location, browser, os, msg, login_time) + values (#{userName}, #{status}, #{ipaddr}, #{loginLocation}, #{browser}, #{os}, #{msg}, UNIX_TIMESTAMP() * 1000) + + + + + + delete from sys_logininfor where info_id in + + #{infoId} + + + + + truncate table sys_logininfor + + + diff --git a/ff-base/target/classes/mapper/system/SysMenuMapper.xml b/ff-base/target/classes/mapper/system/SysMenuMapper.xml new file mode 100644 index 0000000..0274e15 --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysMenuMapper.xml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select menu_id, menu_name, parent_id, order_num, path, component, `query`, route_name, is_frame, is_cache, menu_type, visible, status, ifnull(perms,'') as perms, icon, create_time + from sys_menu + + + + + + + + + + + + + + + + + + + + + + + + + + update sys_menu + + menu_name = #{menuName}, + parent_id = #{parentId}, + order_num = #{orderNum}, + path = #{path}, + component = #{component}, + `query` = #{query}, + route_name = #{routeName}, + is_frame = #{isFrame}, + is_cache = #{isCache}, + menu_type = #{menuType}, + visible = #{visible}, + status = #{status}, + perms = #{perms}, + icon = #{icon}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where menu_id = #{menuId} + + + + insert into sys_menu( + menu_id, + parent_id, + menu_name, + order_num, + path, + component, + `query`, + route_name, + is_frame, + is_cache, + menu_type, + visible, + status, + perms, + icon, + remark, + create_by, + create_time + )values( + #{menuId}, + #{parentId}, + #{menuName}, + #{orderNum}, + #{path}, + #{component}, + #{query}, + #{routeName}, + #{isFrame}, + #{isCache}, + #{menuType}, + #{visible}, + #{status}, + #{perms}, + #{icon}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + + delete from sys_menu where menu_id = #{menuId} + + + diff --git a/ff-base/target/classes/mapper/system/SysOperLogMapper.xml b/ff-base/target/classes/mapper/system/SysOperLogMapper.xml new file mode 100644 index 0000000..1316d3f --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysOperLogMapper.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + select oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time, cost_time + from sys_oper_log + + + + insert into sys_oper_log(title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, cost_time, oper_time) + values (#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{deptName}, #{operUrl}, #{operIp}, #{operLocation}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg}, #{costTime}, UNIX_TIMESTAMP() * 1000) + + + + + + delete from sys_oper_log where oper_id in + + #{operId} + + + + + + + truncate table sys_oper_log + + + diff --git a/ff-base/target/classes/mapper/system/SysPostMapper.xml b/ff-base/target/classes/mapper/system/SysPostMapper.xml new file mode 100644 index 0000000..4083fd7 --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysPostMapper.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + select post_id, post_code, post_name, post_sort, status, create_by, create_time, remark + from sys_post + + + + + + + + + + + + + + + + + + update sys_post + + post_code = #{postCode}, + post_name = #{postName}, + post_sort = #{postSort}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where post_id = #{postId} + + + + insert into sys_post( + post_id, + post_code, + post_name, + post_sort, + status, + remark, + create_by, + create_time + )values( + #{postId}, + #{postCode}, + #{postName}, + #{postSort}, + #{status}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + + delete from sys_post where post_id = #{postId} + + + + delete from sys_post where post_id in + + #{postId} + + + + diff --git a/ff-base/target/classes/mapper/system/SysRoleDeptMapper.xml b/ff-base/target/classes/mapper/system/SysRoleDeptMapper.xml new file mode 100644 index 0000000..f3ff871 --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysRoleDeptMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_role_dept where role_id=#{roleId} + + + + + + delete from sys_role_dept where role_id in + + #{roleId} + + + + + insert into sys_role_dept(role_id, dept_id) values + + (#{item.roleId},#{item.deptId}) + + + + diff --git a/ff-base/target/classes/mapper/system/SysRoleMapper.xml b/ff-base/target/classes/mapper/system/SysRoleMapper.xml new file mode 100644 index 0000000..9560363 --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysRoleMapper.xml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.menu_check_strictly, r.dept_check_strictly, + r.status, r.del_flag, r.create_time, r.remark + from sys_role r + left join sys_user_role ur on ur.role_id = r.role_id + left join sys_user u on u.user_id = ur.user_id + left join sys_dept d on u.dept_id = d.dept_id + + + + + + + + + + + + + + + + + + + + insert into sys_role( + role_id, + role_name, + role_key, + role_sort, + data_scope, + menu_check_strictly, + dept_check_strictly, + status, + remark, + create_by, + create_time + )values( + #{roleId}, + #{roleName}, + #{roleKey}, + #{roleSort}, + #{dataScope}, + #{menuCheckStrictly}, + #{deptCheckStrictly}, + #{status}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + + update sys_role + + role_name = #{roleName}, + role_key = #{roleKey}, + role_sort = #{roleSort}, + data_scope = #{dataScope}, + menu_check_strictly = #{menuCheckStrictly}, + dept_check_strictly = #{deptCheckStrictly}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where role_id = #{roleId} + + + + update sys_role set del_flag = '2' where role_id = #{roleId} + + + + update sys_role set del_flag = '2' where role_id in + + #{roleId} + + + + diff --git a/ff-base/target/classes/mapper/system/SysRoleMenuMapper.xml b/ff-base/target/classes/mapper/system/SysRoleMenuMapper.xml new file mode 100644 index 0000000..6ad872d --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysRoleMenuMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + delete from sys_role_menu where role_id=#{roleId} + + + + delete from sys_role_menu where role_id in + + #{roleId} + + + + + insert into sys_role_menu(role_id, menu_id) values + + (#{item.roleId},#{item.menuId}) + + + + diff --git a/ff-base/target/classes/mapper/system/SysUserMapper.xml b/ff-base/target/classes/mapper/system/SysUserMapper.xml new file mode 100644 index 0000000..3c889ce --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysUserMapper.xml @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, + d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status, + r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status + from sys_user u + left join sys_dept d on u.dept_id = d.dept_id + left join sys_user_role ur on u.user_id = ur.user_id + left join sys_role r on r.role_id = ur.role_id + + + + + + + + + + + + + + + + + + + + insert into sys_user( + user_id, + dept_id, + user_name, + nick_name, + email, + avatar, + phonenumber, + sex, + password, + status, + create_by, + remark, + create_time + )values( + #{userId}, + #{deptId}, + #{userName}, + #{nickName}, + #{email}, + #{avatar}, + #{phonenumber}, + #{sex}, + #{password}, + #{status}, + #{createBy}, + #{remark}, + UNIX_TIMESTAMP() * 1000 + ) + + + + update sys_user + + dept_id = #{deptId}, + user_name = #{userName}, + nick_name = #{nickName}, + email = #{email}, + phonenumber = #{phonenumber}, + sex = #{sex}, + avatar = #{avatar}, + password = #{password}, + status = #{status}, + login_ip = #{loginIp}, + login_date = #{loginDate}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = UNIX_TIMESTAMP() * 1000 + + where user_id = #{userId} + + + + update sys_user set status = #{status} where user_id = #{userId} + + + + update sys_user set avatar = #{avatar} where user_name = #{userName} + + + + update sys_user set password = #{password} where user_name = #{userName} + + + + update sys_user set del_flag = '2' where user_id = #{userId} + + + + update sys_user set del_flag = '2' where user_id in + + #{userId} + + + + + diff --git a/ff-base/target/classes/mapper/system/SysUserPostMapper.xml b/ff-base/target/classes/mapper/system/SysUserPostMapper.xml new file mode 100644 index 0000000..288504d --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysUserPostMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_user_post where user_id=#{userId} + + + + + + delete from sys_user_post where user_id in + + #{userId} + + + + + insert into sys_user_post(user_id, post_id) values + + (#{item.userId},#{item.postId}) + + + + diff --git a/ff-base/target/classes/mapper/system/SysUserRoleMapper.xml b/ff-base/target/classes/mapper/system/SysUserRoleMapper.xml new file mode 100644 index 0000000..2604c71 --- /dev/null +++ b/ff-base/target/classes/mapper/system/SysUserRoleMapper.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + delete from sys_user_role where user_id=#{userId} + + + + + + delete from sys_user_role where user_id in + + #{userId} + + + + + insert into sys_user_role(user_id, role_id) values + + (#{item.userId},#{item.roleId}) + + + + + delete from sys_user_role where user_id=#{userId} and role_id=#{roleId} + + + + delete from sys_user_role where role_id=#{roleId} and user_id in + + #{userId} + + + diff --git a/ff-gen/pom.xml b/ff-gen/pom.xml new file mode 100644 index 0000000..a133957 --- /dev/null +++ b/ff-gen/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + ff + com.ff + 0.0.1 + + + com.ff + ff-gen + 0.0.1 + ff-gen + ff-gen + + + + + + + org.apache.velocity + velocity-engine-core + + + + + com.ff + ff-base + + + + + com.alibaba + druid-spring-boot-starter + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/ff-gen/src/main/java/com/ff/gen/config/GenConfig.java b/ff-gen/src/main/java/com/ff/gen/config/GenConfig.java new file mode 100644 index 0000000..66e803d --- /dev/null +++ b/ff-gen/src/main/java/com/ff/gen/config/GenConfig.java @@ -0,0 +1,73 @@ +package com.ff.gen.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +/** + * 读取代码生成相关配置 + * + * @author ff + */ +@Component +@ConfigurationProperties(prefix = "gen") +@PropertySource(value = { "classpath:generator.yml" }) +public class GenConfig +{ + /** 作者 */ + public static String author; + + /** 生成包路径 */ + public static String packageName; + + /** 自动去除表前缀,默认是false */ + public static boolean autoRemovePre; + + /** 表前缀(类名不会包含表前缀) */ + public static String tablePrefix; + + public static String getAuthor() + { + return author; + } + + @Value("${author}") + public void setAuthor(String author) + { + GenConfig.author = author; + } + + public static String getPackageName() + { + return packageName; + } + + @Value("${packageName}") + public void setPackageName(String packageName) + { + GenConfig.packageName = packageName; + } + + public static boolean getAutoRemovePre() + { + return autoRemovePre; + } + + @Value("${autoRemovePre}") + public void setAutoRemovePre(boolean autoRemovePre) + { + GenConfig.autoRemovePre = autoRemovePre; + } + + public static String getTablePrefix() + { + return tablePrefix; + } + + @Value("${tablePrefix}") + public void setTablePrefix(String tablePrefix) + { + GenConfig.tablePrefix = tablePrefix; + } +} diff --git a/ff-gen/src/main/java/com/ff/gen/controller/GenController.java b/ff-gen/src/main/java/com/ff/gen/controller/GenController.java new file mode 100644 index 0000000..2890eff --- /dev/null +++ b/ff-gen/src/main/java/com/ff/gen/controller/GenController.java @@ -0,0 +1,252 @@ +package com.ff.gen.controller; + +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.core.page.TableDataInfo; +import com.ff.base.core.text.Convert; +import com.ff.base.enums.BusinessType; +import com.ff.base.utils.SecurityUtils; +import com.ff.base.utils.sql.SqlUtil; +import com.ff.gen.domain.GenTable; +import com.ff.gen.domain.GenTableColumn; +import com.ff.gen.service.IGenTableColumnService; +import com.ff.gen.service.IGenTableService; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 代码生成 操作处理 + * + * @author ff + */ +@RestController +@RequestMapping("/tool/gen") +public class GenController extends BaseController +{ + @Autowired + private IGenTableService genTableService; + + @Autowired + private IGenTableColumnService genTableColumnService; + + /** + * 查询代码生成列表 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping("/list") + public TableDataInfo genList(GenTable genTable) + { + startPage(); + List list = genTableService.selectGenTableList(genTable); + return getDataTable(list); + } + + /** + * 修改代码生成业务 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:query')") + @GetMapping(value = "/{tableId}") + public AjaxResult getInfo(@PathVariable Long tableId) + { + GenTable table = genTableService.selectGenTableById(tableId); + List tables = genTableService.selectGenTableAll(); + List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); + Map map = new HashMap(); + map.put("info", table); + map.put("rows", list); + map.put("tables", tables); + return success(map); + } + + /** + * 查询数据库列表 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping("/db/list") + public TableDataInfo dataList(GenTable genTable) + { + startPage(); + List list = genTableService.selectDbTableList(genTable); + return getDataTable(list); + } + + /** + * 查询数据表字段列表 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping(value = "/column/{tableId}") + public TableDataInfo columnList(Long tableId) + { + TableDataInfo dataInfo = new TableDataInfo(); + List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); + dataInfo.setRows(list); + dataInfo.setTotal(list.size()); + return dataInfo; + } + + /** + * 导入表结构(保存) + */ + @PreAuthorize("@ss.hasPermi('tool:gen:import')") + @Log(title = "代码生成", businessType = BusinessType.IMPORT) + @PostMapping("/importTable") + public AjaxResult importTableSave(String tables) + { + String[] tableNames = Convert.toStrArray(tables); + // 查询表信息 + List tableList = genTableService.selectDbTableListByNames(tableNames); + genTableService.importGenTable(tableList, SecurityUtils.getUsername()); + return success(); + } + + /** + * 创建表结构(保存) + */ + @PreAuthorize("@ss.hasRole('admin')") + @Log(title = "创建表", businessType = BusinessType.OTHER) + @PostMapping("/createTable") + public AjaxResult createTableSave(String sql) + { + try + { + SqlUtil.filterKeyword(sql); + List sqlStatements = SQLUtils.parseStatements(sql, DbType.mysql); + List tableNames = new ArrayList<>(); + for (SQLStatement sqlStatement : sqlStatements) + { + if (sqlStatement instanceof MySqlCreateTableStatement) + { + MySqlCreateTableStatement createTableStatement = (MySqlCreateTableStatement) sqlStatement; + if (genTableService.createTable(createTableStatement.toString())) + { + String tableName = createTableStatement.getTableName().replaceAll("`", ""); + tableNames.add(tableName); + } + } + } + List tableList = genTableService.selectDbTableListByNames(tableNames.toArray(new String[tableNames.size()])); + String operName = SecurityUtils.getUsername(); + genTableService.importGenTable(tableList, operName); + return AjaxResult.success(); + } + catch (Exception e) + { + logger.error(e.getMessage(), e); + return AjaxResult.error("创建表结构异常"); + } + } + + /** + * 修改保存代码生成业务 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:edit')") + @Log(title = "代码生成", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult editSave(@Validated @RequestBody GenTable genTable) + { + genTableService.validateEdit(genTable); + genTableService.updateGenTable(genTable); + return success(); + } + + /** + * 删除代码生成 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:remove')") + @Log(title = "代码生成", businessType = BusinessType.DELETE) + @DeleteMapping("/{tableIds}") + public AjaxResult remove(@PathVariable Long[] tableIds) + { + genTableService.deleteGenTableByIds(tableIds); + return success(); + } + + /** + * 预览代码 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:preview')") + @GetMapping("/preview/{tableId}") + public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException + { + Map dataMap = genTableService.previewCode(tableId); + return success(dataMap); + } + + /** + * 生成代码(下载方式) + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/download/{tableName}") + public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException + { + byte[] data = genTableService.downloadCode(tableName); + genCode(response, data); + } + + /** + * 生成代码(自定义路径) + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/genCode/{tableName}") + public AjaxResult genCode(@PathVariable("tableName") String tableName) + { + genTableService.generatorCode(tableName); + return success(); + } + + /** + * 同步数据库 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:edit')") + @Log(title = "代码生成", businessType = BusinessType.UPDATE) + @GetMapping("/synchDb/{tableName}") + public AjaxResult synchDb(@PathVariable("tableName") String tableName) + { + genTableService.synchDb(tableName); + return success(); + } + + /** + * 批量生成代码 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/batchGenCode") + public void batchGenCode(HttpServletResponse response, String tables) throws IOException + { + String[] tableNames = Convert.toStrArray(tables); + byte[] data = genTableService.downloadCode(tableNames); + genCode(response, data); + } + + /** + * 生成zip文件 + */ + private void genCode(HttpServletResponse response, byte[] data) throws IOException + { + response.reset(); + response.addHeader("Access-Control-Allow-Origin", "*"); + response.addHeader("Access-Control-Expose-Headers", "Content-Disposition"); + response.setHeader("Content-Disposition", "attachment; filename=\"ff.zip\""); + response.addHeader("Content-Length", "" + data.length); + response.setContentType("application/octet-stream; charset=UTF-8"); + IOUtils.write(data, response.getOutputStream()); + } +} diff --git a/ff-gen/src/main/java/com/ff/gen/domain/GenTable.java b/ff-gen/src/main/java/com/ff/gen/domain/GenTable.java new file mode 100644 index 0000000..b772826 --- /dev/null +++ b/ff-gen/src/main/java/com/ff/gen/domain/GenTable.java @@ -0,0 +1,386 @@ +package com.ff.gen.domain; + +import com.ff.base.constant.GenConstants; +import com.ff.base.core.domain.BaseEntity; +import com.ff.base.utils.StringUtils; +import org.apache.commons.lang3.ArrayUtils; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import java.util.List; + +/** + * 业务表 gen_table + * + * @author ff + */ +public class GenTable extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 编号 */ + private Long tableId; + + /** 表名称 */ + @NotBlank(message = "表名称不能为空") + private String tableName; + + /** 表描述 */ + @NotBlank(message = "表描述不能为空") + private String tableComment; + + /** 关联父表的表名 */ + private String subTableName; + + /** 本表关联父表的外键名 */ + private String subTableFkName; + + /** 实体类名称(首字母大写) */ + @NotBlank(message = "实体类名称不能为空") + private String className; + + /** 使用的模板(crud单表操作 tree树表操作 sub主子表操作) */ + private String tplCategory; + + /** 前端类型(element-ui模版 element-plus模版) */ + private String tplWebType; + + /** 生成包路径 */ + @NotBlank(message = "生成包路径不能为空") + private String packageName; + + /** 生成模块名 */ + @NotBlank(message = "生成模块名不能为空") + private String moduleName; + + /** 生成业务名 */ + @NotBlank(message = "生成业务名不能为空") + private String businessName; + + /** 生成功能名 */ + @NotBlank(message = "生成功能名不能为空") + private String functionName; + + /** 生成作者 */ + @NotBlank(message = "作者不能为空") + private String functionAuthor; + + /** 生成代码方式(0zip压缩包 1自定义路径) */ + private String genType; + + /** 生成路径(不填默认项目路径) */ + private String genPath; + + /** 主键信息 */ + private GenTableColumn pkColumn; + + /** 子表信息 */ + private GenTable subTable; + + /** 表列信息 */ + @Valid + private List columns; + + /** 其它生成选项 */ + private String options; + + /** 树编码字段 */ + private String treeCode; + + /** 树父编码字段 */ + private String treeParentCode; + + /** 树名称字段 */ + private String treeName; + + /** 上级菜单ID字段 */ + private String parentMenuId; + + /** 上级菜单名称字段 */ + private String parentMenuName; + + public Long getTableId() + { + return tableId; + } + + public void setTableId(Long tableId) + { + this.tableId = tableId; + } + + public String getTableName() + { + return tableName; + } + + public void setTableName(String tableName) + { + this.tableName = tableName; + } + + public String getTableComment() + { + return tableComment; + } + + public void setTableComment(String tableComment) + { + this.tableComment = tableComment; + } + + public String getSubTableName() + { + return subTableName; + } + + public void setSubTableName(String subTableName) + { + this.subTableName = subTableName; + } + + public String getSubTableFkName() + { + return subTableFkName; + } + + public void setSubTableFkName(String subTableFkName) + { + this.subTableFkName = subTableFkName; + } + + public String getClassName() + { + return className; + } + + public void setClassName(String className) + { + this.className = className; + } + + public String getTplCategory() + { + return tplCategory; + } + + public void setTplCategory(String tplCategory) + { + this.tplCategory = tplCategory; + } + + public String getTplWebType() + { + return tplWebType; + } + + public void setTplWebType(String tplWebType) + { + this.tplWebType = tplWebType; + } + + public String getPackageName() + { + return packageName; + } + + public void setPackageName(String packageName) + { + this.packageName = packageName; + } + + public String getModuleName() + { + return moduleName; + } + + public void setModuleName(String moduleName) + { + this.moduleName = moduleName; + } + + public String getBusinessName() + { + return businessName; + } + + public void setBusinessName(String businessName) + { + this.businessName = businessName; + } + + public String getFunctionName() + { + return functionName; + } + + public void setFunctionName(String functionName) + { + this.functionName = functionName; + } + + public String getFunctionAuthor() + { + return functionAuthor; + } + + public void setFunctionAuthor(String functionAuthor) + { + this.functionAuthor = functionAuthor; + } + + public String getGenType() + { + return genType; + } + + public void setGenType(String genType) + { + this.genType = genType; + } + + public String getGenPath() + { + return genPath; + } + + public void setGenPath(String genPath) + { + this.genPath = genPath; + } + + public GenTableColumn getPkColumn() + { + return pkColumn; + } + + public void setPkColumn(GenTableColumn pkColumn) + { + this.pkColumn = pkColumn; + } + + public GenTable getSubTable() + { + return subTable; + } + + public void setSubTable(GenTable subTable) + { + this.subTable = subTable; + } + + public List getColumns() + { + return columns; + } + + public void setColumns(List columns) + { + this.columns = columns; + } + + public String getOptions() + { + return options; + } + + public void setOptions(String options) + { + this.options = options; + } + + public String getTreeCode() + { + return treeCode; + } + + public void setTreeCode(String treeCode) + { + this.treeCode = treeCode; + } + + public String getTreeParentCode() + { + return treeParentCode; + } + + public void setTreeParentCode(String treeParentCode) + { + this.treeParentCode = treeParentCode; + } + + public String getTreeName() + { + return treeName; + } + + public void setTreeName(String treeName) + { + this.treeName = treeName; + } + + public String getParentMenuId() + { + return parentMenuId; + } + + public void setParentMenuId(String parentMenuId) + { + this.parentMenuId = parentMenuId; + } + + public String getParentMenuName() + { + return parentMenuName; + } + + public void setParentMenuName(String parentMenuName) + { + this.parentMenuName = parentMenuName; + } + + public boolean isSub() + { + return isSub(this.tplCategory); + } + + public static boolean isSub(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_SUB, tplCategory); + } + + public boolean isTree() + { + return isTree(this.tplCategory); + } + + public static boolean isTree(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory); + } + + public boolean isCrud() + { + return isCrud(this.tplCategory); + } + + public static boolean isCrud(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory); + } + + public boolean isSuperColumn(String javaField) + { + return isSuperColumn(this.tplCategory, javaField); + } + + public static boolean isSuperColumn(String tplCategory, String javaField) + { + if (isTree(tplCategory)) + { + return StringUtils.equalsAnyIgnoreCase(javaField, + ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY)); + } + return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY); + } +} diff --git a/ff-gen/src/main/java/com/ff/gen/domain/GenTableColumn.java b/ff-gen/src/main/java/com/ff/gen/domain/GenTableColumn.java new file mode 100644 index 0000000..0f87eb9 --- /dev/null +++ b/ff-gen/src/main/java/com/ff/gen/domain/GenTableColumn.java @@ -0,0 +1,374 @@ +package com.ff.gen.domain; + +import com.ff.base.core.domain.BaseEntity; +import com.ff.base.utils.StringUtils; + +import javax.validation.constraints.NotBlank; + +/** + * 代码生成业务字段表 gen_table_column + * + * @author ff + */ +public class GenTableColumn extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 编号 */ + private Long columnId; + + /** 归属表编号 */ + private Long tableId; + + /** 列名称 */ + private String columnName; + + /** 列描述 */ + private String columnComment; + + /** 列类型 */ + private String columnType; + + /** JAVA类型 */ + private String javaType; + + /** JAVA字段名 */ + @NotBlank(message = "Java属性不能为空") + private String javaField; + + /** 是否主键(1是) */ + private String isPk; + + /** 是否自增(1是) */ + private String isIncrement; + + /** 是否必填(1是) */ + private String isRequired; + + /** 是否为插入字段(1是) */ + private String isInsert; + + /** 是否编辑字段(1是) */ + private String isEdit; + + /** 是否列表字段(1是) */ + private String isList; + + /** 是否查询字段(1是) */ + private String isQuery; + + /** 查询方式(EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围) */ + private String queryType; + + /** 显示类型(input文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、datetime日期控件、image图片上传控件、upload文件上传控件、editor富文本控件) */ + private String htmlType; + + /** 字典类型 */ + private String dictType; + + /** 排序 */ + private Integer sort; + + public void setColumnId(Long columnId) + { + this.columnId = columnId; + } + + public Long getColumnId() + { + return columnId; + } + + public void setTableId(Long tableId) + { + this.tableId = tableId; + } + + public Long getTableId() + { + return tableId; + } + + public void setColumnName(String columnName) + { + this.columnName = columnName; + } + + public String getColumnName() + { + return columnName; + } + + public void setColumnComment(String columnComment) + { + this.columnComment = columnComment; + } + + public String getColumnComment() + { + return columnComment; + } + + public void setColumnType(String columnType) + { + this.columnType = columnType; + } + + public String getColumnType() + { + return columnType; + } + + public void setJavaType(String javaType) + { + this.javaType = javaType; + } + + public String getJavaType() + { + return javaType; + } + + public void setJavaField(String javaField) + { + this.javaField = javaField; + } + + public String getJavaField() + { + return javaField; + } + + public String getCapJavaField() + { + return StringUtils.capitalize(javaField); + } + + public void setIsPk(String isPk) + { + this.isPk = isPk; + } + + public String getIsPk() + { + return isPk; + } + + public boolean isPk() + { + return isPk(this.isPk); + } + + public boolean isPk(String isPk) + { + return isPk != null && StringUtils.equals("1", isPk); + } + + public String getIsIncrement() + { + return isIncrement; + } + + public void setIsIncrement(String isIncrement) + { + this.isIncrement = isIncrement; + } + + public boolean isIncrement() + { + return isIncrement(this.isIncrement); + } + + public boolean isIncrement(String isIncrement) + { + return isIncrement != null && StringUtils.equals("1", isIncrement); + } + + public void setIsRequired(String isRequired) + { + this.isRequired = isRequired; + } + + public String getIsRequired() + { + return isRequired; + } + + public boolean isRequired() + { + return isRequired(this.isRequired); + } + + public boolean isRequired(String isRequired) + { + return isRequired != null && StringUtils.equals("1", isRequired); + } + + public void setIsInsert(String isInsert) + { + this.isInsert = isInsert; + } + + public String getIsInsert() + { + return isInsert; + } + + public boolean isInsert() + { + return isInsert(this.isInsert); + } + + public boolean isInsert(String isInsert) + { + return isInsert != null && StringUtils.equals("1", isInsert); + } + + public void setIsEdit(String isEdit) + { + this.isEdit = isEdit; + } + + public String getIsEdit() + { + return isEdit; + } + + public boolean isEdit() + { + return isInsert(this.isEdit); + } + + public boolean isEdit(String isEdit) + { + return isEdit != null && StringUtils.equals("1", isEdit); + } + + public void setIsList(String isList) + { + this.isList = isList; + } + + public String getIsList() + { + return isList; + } + + public boolean isList() + { + return isList(this.isList); + } + + public boolean isList(String isList) + { + return isList != null && StringUtils.equals("1", isList); + } + + public void setIsQuery(String isQuery) + { + this.isQuery = isQuery; + } + + public String getIsQuery() + { + return isQuery; + } + + public boolean isQuery() + { + return isQuery(this.isQuery); + } + + public boolean isQuery(String isQuery) + { + return isQuery != null && StringUtils.equals("1", isQuery); + } + + public void setQueryType(String queryType) + { + this.queryType = queryType; + } + + public String getQueryType() + { + return queryType; + } + + public String getHtmlType() + { + return htmlType; + } + + public void setHtmlType(String htmlType) + { + this.htmlType = htmlType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + public String getDictType() + { + return dictType; + } + + public void setSort(Integer sort) + { + this.sort = sort; + } + + public Integer getSort() + { + return sort; + } + + public boolean isSuperColumn() + { + return isSuperColumn(this.javaField); + } + + public static boolean isSuperColumn(String javaField) + { + return StringUtils.equalsAnyIgnoreCase(javaField, + // BaseEntity + "createBy", "createTime", "updateBy", "updateTime", "remark", + // TreeEntity + "parentName", "parentId", "orderNum", "ancestors"); + } + + public boolean isUsableColumn() + { + return isUsableColumn(javaField); + } + + public static boolean isUsableColumn(String javaField) + { + // isSuperColumn()中的名单用于避免生成多余Domain属性,若某些属性在生成页面时需要用到不能忽略,则放在此处白名单 + return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark"); + } + + public String readConverterExp() + { + String remarks = StringUtils.substringBetween(this.columnComment, "(", ")"); + StringBuffer sb = new StringBuffer(); + if (StringUtils.isNotEmpty(remarks)) + { + for (String value : remarks.split(" ")) + { + if (StringUtils.isNotEmpty(value)) + { + Object startStr = value.subSequence(0, 1); + String endStr = value.substring(1); + sb.append("").append(startStr).append("=").append(endStr).append(","); + } + } + return sb.deleteCharAt(sb.length() - 1).toString(); + } + else + { + return this.columnComment; + } + } +} diff --git a/ff-gen/src/main/java/com/ff/gen/mapper/GenTableColumnMapper.java b/ff-gen/src/main/java/com/ff/gen/mapper/GenTableColumnMapper.java new file mode 100644 index 0000000..0bab27a --- /dev/null +++ b/ff-gen/src/main/java/com/ff/gen/mapper/GenTableColumnMapper.java @@ -0,0 +1,61 @@ +package com.ff.gen.mapper; + +import com.ff.gen.domain.GenTableColumn; + +import java.util.List; + +/** + * 业务字段 数据层 + * + * @author ff + */ +public interface GenTableColumnMapper +{ + /** + * 根据表名称查询列信息 + * + * @param tableName 表名称 + * @return 列信息 + */ + public List selectDbTableColumnsByName(String tableName); + + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + public List selectGenTableColumnListByTableId(Long tableId); + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int insertGenTableColumn(GenTableColumn genTableColumn); + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int updateGenTableColumn(GenTableColumn genTableColumn); + + /** + * 删除业务字段 + * + * @param genTableColumns 列数据 + * @return 结果 + */ + public int deleteGenTableColumns(List genTableColumns); + + /** + * 批量删除业务字段 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableColumnByIds(Long[] ids); +} diff --git a/ff-gen/src/main/java/com/ff/gen/mapper/GenTableMapper.java b/ff-gen/src/main/java/com/ff/gen/mapper/GenTableMapper.java new file mode 100644 index 0000000..0f84664 --- /dev/null +++ b/ff-gen/src/main/java/com/ff/gen/mapper/GenTableMapper.java @@ -0,0 +1,92 @@ +package com.ff.gen.mapper; + +import com.ff.gen.domain.GenTable; + +import java.util.List; + +/** + * 业务 数据层 + * + * @author ff + */ +public interface GenTableMapper +{ + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + public List selectGenTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + public List selectDbTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + public List selectDbTableListByNames(String[] tableNames); + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List selectGenTableAll(); + + /** + * 查询表ID业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + public GenTable selectGenTableById(Long id); + + /** + * 查询表名称业务信息 + * + * @param tableName 表名称 + * @return 业务信息 + */ + public GenTable selectGenTableByName(String tableName); + + /** + * 新增业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public int insertGenTable(GenTable genTable); + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public int updateGenTable(GenTable genTable); + + /** + * 批量删除业务 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableByIds(Long[] ids); + + /** + * 创建表 + * + * @param sql 表结构 + * @return 结果 + */ + public int createTable(String sql); +} diff --git a/ff-gen/src/main/java/com/ff/gen/service/GenTableColumnServiceImpl.java b/ff-gen/src/main/java/com/ff/gen/service/GenTableColumnServiceImpl.java new file mode 100644 index 0000000..d0f4961 --- /dev/null +++ b/ff-gen/src/main/java/com/ff/gen/service/GenTableColumnServiceImpl.java @@ -0,0 +1,69 @@ +package com.ff.gen.service; + +import com.ff.base.core.text.Convert; +import com.ff.gen.domain.GenTableColumn; +import com.ff.gen.mapper.GenTableColumnMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 业务字段 服务层实现 + * + * @author ff + */ +@Service +public class GenTableColumnServiceImpl implements IGenTableColumnService +{ + @Autowired + private GenTableColumnMapper genTableColumnMapper; + + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + @Override + public List selectGenTableColumnListByTableId(Long tableId) + { + return genTableColumnMapper.selectGenTableColumnListByTableId(tableId); + } + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + @Override + public int insertGenTableColumn(GenTableColumn genTableColumn) + { + return genTableColumnMapper.insertGenTableColumn(genTableColumn); + } + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + @Override + public int updateGenTableColumn(GenTableColumn genTableColumn) + { + return genTableColumnMapper.updateGenTableColumn(genTableColumn); + } + + /** + * 删除业务字段对象 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteGenTableColumnByIds(String ids) + { + return genTableColumnMapper.deleteGenTableColumnByIds(Convert.toLongArray(ids)); + } +} diff --git a/ff-gen/src/main/java/com/ff/gen/service/GenTableServiceImpl.java b/ff-gen/src/main/java/com/ff/gen/service/GenTableServiceImpl.java new file mode 100644 index 0000000..ae7cafb --- /dev/null +++ b/ff-gen/src/main/java/com/ff/gen/service/GenTableServiceImpl.java @@ -0,0 +1,532 @@ +package com.ff.gen.service; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ff.base.constant.Constants; +import com.ff.base.constant.GenConstants; +import com.ff.base.core.text.CharsetKit; +import com.ff.base.exception.ServiceException; +import com.ff.base.utils.StringUtils; +import com.ff.gen.domain.GenTable; +import com.ff.gen.domain.GenTableColumn; +import com.ff.gen.mapper.GenTableColumnMapper; +import com.ff.gen.mapper.GenTableMapper; +import com.ff.gen.util.GenUtils; +import com.ff.gen.util.VelocityInitializer; +import com.ff.gen.util.VelocityUtils; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * 业务 服务层实现 + * + * @author ff + */ +@Service +public class GenTableServiceImpl implements IGenTableService +{ + private static final Logger log = LoggerFactory.getLogger(GenTableServiceImpl.class); + + @Autowired + private GenTableMapper genTableMapper; + + @Autowired + private GenTableColumnMapper genTableColumnMapper; + + /** + * 查询业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + @Override + public GenTable selectGenTableById(Long id) + { + GenTable genTable = genTableMapper.selectGenTableById(id); + setTableFromOptions(genTable); + return genTable; + } + + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + @Override + public List selectGenTableList(GenTable genTable) + { + return genTableMapper.selectGenTableList(genTable); + } + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + @Override + public List selectDbTableList(GenTable genTable) + { + return genTableMapper.selectDbTableList(genTable); + } + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + @Override + public List selectDbTableListByNames(String[] tableNames) + { + return genTableMapper.selectDbTableListByNames(tableNames); + } + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + @Override + public List selectGenTableAll() + { + return genTableMapper.selectGenTableAll(); + } + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + @Override + @Transactional + public void updateGenTable(GenTable genTable) + { + String options = JSON.toJSONString(genTable.getParams()); + genTable.setOptions(options); + int row = genTableMapper.updateGenTable(genTable); + if (row > 0) + { + for (GenTableColumn cenTableColumn : genTable.getColumns()) + { + genTableColumnMapper.updateGenTableColumn(cenTableColumn); + } + } + } + + /** + * 删除业务对象 + * + * @param tableIds 需要删除的数据ID + * @return 结果 + */ + @Override + @Transactional + public void deleteGenTableByIds(Long[] tableIds) + { + genTableMapper.deleteGenTableByIds(tableIds); + genTableColumnMapper.deleteGenTableColumnByIds(tableIds); + } + + /** + * 创建表 + * + * @param sql 创建表语句 + * @return 结果 + */ + @Override + public boolean createTable(String sql) + { + return genTableMapper.createTable(sql) == 0; + } + + /** + * 导入表结构 + * + * @param tableList 导入表列表 + */ + @Override + @Transactional + public void importGenTable(List tableList, String operName) + { + try + { + for (GenTable table : tableList) + { + String tableName = table.getTableName(); + GenUtils.initTable(table, operName); + int row = genTableMapper.insertGenTable(table); + if (row > 0) + { + // 保存列信息 + List genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + for (GenTableColumn column : genTableColumns) + { + GenUtils.initColumnField(column, table); + genTableColumnMapper.insertGenTableColumn(column); + } + } + } + } + catch (Exception e) + { + throw new ServiceException("导入失败:" + e.getMessage()); + } + } + + /** + * 预览代码 + * + * @param tableId 表编号 + * @return 预览数据列表 + */ + @Override + public Map previewCode(Long tableId) + { + Map dataMap = new LinkedHashMap<>(); + // 查询表信息 + GenTable table = genTableMapper.selectGenTableById(tableId); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType()); + for (String template : templates) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + dataMap.put(template, sw.toString()); + } + return dataMap; + } + + /** + * 生成代码(下载方式) + * + * @param tableName 表名称 + * @return 数据 + */ + @Override + public byte[] downloadCode(String tableName) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + generatorCode(tableName, zip); + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + */ + @Override + public void generatorCode(String tableName) + { + // 查询表信息 + GenTable table = genTableMapper.selectGenTableByName(tableName); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType()); + for (String template : templates) + { + if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + try + { + String path = getGenPath(table, template); + FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8); + } + catch (IOException e) + { + throw new ServiceException("渲染模板失败,表名:" + table.getTableName()); + } + } + } + } + + /** + * 同步数据库 + * + * @param tableName 表名称 + */ + @Override + @Transactional + public void synchDb(String tableName) + { + GenTable table = genTableMapper.selectGenTableByName(tableName); + List tableColumns = table.getColumns(); + Map tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity())); + + List dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + if (StringUtils.isEmpty(dbTableColumns)) + { + throw new ServiceException("同步数据失败,原表结构不存在"); + } + List dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList()); + + dbTableColumns.forEach(column -> { + GenUtils.initColumnField(column, table); + if (tableColumnMap.containsKey(column.getColumnName())) + { + GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName()); + column.setColumnId(prevColumn.getColumnId()); + if (column.isList()) + { + // 如果是列表,继续保留查询方式/字典类型选项 + column.setDictType(prevColumn.getDictType()); + column.setQueryType(prevColumn.getQueryType()); + } + if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk() + && (column.isInsert() || column.isEdit()) + && ((column.isUsableColumn()) || (!column.isSuperColumn()))) + { + // 如果是(新增/修改&非主键/非忽略及父属性),继续保留必填/显示类型选项 + column.setIsRequired(prevColumn.getIsRequired()); + column.setHtmlType(prevColumn.getHtmlType()); + } + genTableColumnMapper.updateGenTableColumn(column); + } + else + { + genTableColumnMapper.insertGenTableColumn(column); + } + }); + + List delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList()); + if (StringUtils.isNotEmpty(delColumns)) + { + genTableColumnMapper.deleteGenTableColumns(delColumns); + } + } + + /** + * 批量生成代码(下载方式) + * + * @param tableNames 表数组 + * @return 数据 + */ + @Override + public byte[] downloadCode(String[] tableNames) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + for (String tableName : tableNames) + { + generatorCode(tableName, zip); + } + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 查询表信息并生成代码 + */ + private void generatorCode(String tableName, ZipOutputStream zip) + { + // 查询表信息 + GenTable table = genTableMapper.selectGenTableByName(tableName); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType()); + for (String template : templates) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + try + { + // 添加到zip + zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table))); + IOUtils.write(sw.toString(), zip, Constants.UTF8); + IOUtils.closeQuietly(sw); + zip.flush(); + zip.closeEntry(); + } + catch (IOException e) + { + log.error("渲染模板失败,表名:" + table.getTableName(), e); + } + } + } + + /** + * 修改保存参数校验 + * + * @param genTable 业务信息 + */ + @Override + public void validateEdit(GenTable genTable) + { + if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) + { + String options = JSON.toJSONString(genTable.getParams()); + JSONObject paramsObj = JSON.parseObject(options); + if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_CODE))) + { + throw new ServiceException("树编码字段不能为空"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE))) + { + throw new ServiceException("树父编码字段不能为空"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_NAME))) + { + throw new ServiceException("树名称字段不能为空"); + } + else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory())) + { + if (StringUtils.isEmpty(genTable.getSubTableName())) + { + throw new ServiceException("关联子表的表名不能为空"); + } + else if (StringUtils.isEmpty(genTable.getSubTableFkName())) + { + throw new ServiceException("子表关联的外键名不能为空"); + } + } + } + } + + /** + * 设置主键列信息 + * + * @param table 业务表信息 + */ + public void setPkColumn(GenTable table) + { + for (GenTableColumn column : table.getColumns()) + { + if (column.isPk()) + { + table.setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getPkColumn())) + { + table.setPkColumn(table.getColumns().get(0)); + } + if (GenConstants.TPL_SUB.equals(table.getTplCategory())) + { + for (GenTableColumn column : table.getSubTable().getColumns()) + { + if (column.isPk()) + { + table.getSubTable().setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getSubTable().getPkColumn())) + { + table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0)); + } + } + } + + /** + * 设置主子表信息 + * + * @param table 业务表信息 + */ + public void setSubTable(GenTable table) + { + String subTableName = table.getSubTableName(); + if (StringUtils.isNotEmpty(subTableName)) + { + table.setSubTable(genTableMapper.selectGenTableByName(subTableName)); + } + } + + /** + * 设置代码生成其他选项值 + * + * @param genTable 设置后的生成对象 + */ + public void setTableFromOptions(GenTable genTable) + { + JSONObject paramsObj = JSON.parseObject(genTable.getOptions()); + if (StringUtils.isNotNull(paramsObj)) + { + String treeCode = paramsObj.getString(GenConstants.TREE_CODE); + String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE); + String treeName = paramsObj.getString(GenConstants.TREE_NAME); + String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID); + String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME); + + genTable.setTreeCode(treeCode); + genTable.setTreeParentCode(treeParentCode); + genTable.setTreeName(treeName); + genTable.setParentMenuId(parentMenuId); + genTable.setParentMenuName(parentMenuName); + } + } + + /** + * 获取代码生成地址 + * + * @param table 业务表信息 + * @param template 模板文件路径 + * @return 生成地址 + */ + public static String getGenPath(GenTable table, String template) + { + String genPath = table.getGenPath(); + if (StringUtils.equals(genPath, "/")) + { + return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table); + } + return genPath + File.separator + VelocityUtils.getFileName(template, table); + } +} diff --git a/ff-gen/src/main/java/com/ff/gen/service/IGenTableColumnService.java b/ff-gen/src/main/java/com/ff/gen/service/IGenTableColumnService.java new file mode 100644 index 0000000..a94df23 --- /dev/null +++ b/ff-gen/src/main/java/com/ff/gen/service/IGenTableColumnService.java @@ -0,0 +1,45 @@ +package com.ff.gen.service; + +import com.ff.gen.domain.GenTableColumn; + +import java.util.List; + +/** + * 业务字段 服务层 + * + * @author ff + */ +public interface IGenTableColumnService +{ + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + public List selectGenTableColumnListByTableId(Long tableId); + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int insertGenTableColumn(GenTableColumn genTableColumn); + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int updateGenTableColumn(GenTableColumn genTableColumn); + + /** + * 删除业务字段信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableColumnByIds(String ids); +} diff --git a/ff-gen/src/main/java/com/ff/gen/service/IGenTableService.java b/ff-gen/src/main/java/com/ff/gen/service/IGenTableService.java new file mode 100644 index 0000000..5e078bb --- /dev/null +++ b/ff-gen/src/main/java/com/ff/gen/service/IGenTableService.java @@ -0,0 +1,131 @@ +package com.ff.gen.service; + +import com.ff.gen.domain.GenTable; + +import java.util.List; +import java.util.Map; + +/** + * 业务 服务层 + * + * @author ff + */ +public interface IGenTableService +{ + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + public List selectGenTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + public List selectDbTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + public List selectDbTableListByNames(String[] tableNames); + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List selectGenTableAll(); + + /** + * 查询业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + public GenTable selectGenTableById(Long id); + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public void updateGenTable(GenTable genTable); + + /** + * 删除业务信息 + * + * @param tableIds 需要删除的表数据ID + * @return 结果 + */ + public void deleteGenTableByIds(Long[] tableIds); + + /** + * 创建表 + * + * @param sql 创建表语句 + * @return 结果 + */ + public boolean createTable(String sql); + + /** + * 导入表结构 + * + * @param tableList 导入表列表 + * @param operName 操作人员 + */ + public void importGenTable(List tableList, String operName); + + /** + * 预览代码 + * + * @param tableId 表编号 + * @return 预览数据列表 + */ + public Map previewCode(Long tableId); + + /** + * 生成代码(下载方式) + * + * @param tableName 表名称 + * @return 数据 + */ + public byte[] downloadCode(String tableName); + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + * @return 数据 + */ + public void generatorCode(String tableName); + + /** + * 同步数据库 + * + * @param tableName 表名称 + */ + public void synchDb(String tableName); + + /** + * 批量生成代码(下载方式) + * + * @param tableNames 表数组 + * @return 数据 + */ + public byte[] downloadCode(String[] tableNames); + + /** + * 修改保存参数校验 + * + * @param genTable 业务信息 + */ + public void validateEdit(GenTable genTable); +} diff --git a/ff-gen/src/main/java/com/ff/gen/util/GenUtils.java b/ff-gen/src/main/java/com/ff/gen/util/GenUtils.java new file mode 100644 index 0000000..ba543f5 --- /dev/null +++ b/ff-gen/src/main/java/com/ff/gen/util/GenUtils.java @@ -0,0 +1,262 @@ +package com.ff.gen.util; + +import com.ff.base.constant.GenConstants; +import com.ff.base.utils.StringUtils; +import com.ff.gen.config.GenConfig; +import com.ff.gen.domain.GenTable; +import com.ff.gen.domain.GenTableColumn; +import org.apache.commons.lang3.RegExUtils; + +import java.util.Arrays; + +/** + * 代码生成器 工具类 + * + * @author ff + */ +public class GenUtils +{ + /** + * 初始化表信息 + */ + public static void initTable(GenTable genTable, String operName) + { + genTable.setClassName(convertClassName(genTable.getTableName())); + genTable.setPackageName(GenConfig.getPackageName()); + genTable.setModuleName(getModuleName(GenConfig.getPackageName())); + genTable.setBusinessName(getBusinessName(genTable.getTableName())); + genTable.setFunctionName(replaceText(genTable.getTableComment())); + genTable.setFunctionAuthor(GenConfig.getAuthor()); + genTable.setCreateBy(operName); + } + + /** + * 初始化列属性字段 + */ + public static void initColumnField(GenTableColumn column, GenTable table) + { + String dataType = getDbType(column.getColumnType()); + String columnName = column.getColumnName(); + column.setTableId(table.getTableId()); + column.setCreateBy(table.getCreateBy()); + // 设置java字段名 + column.setJavaField(StringUtils.toCamelCase(columnName)); + // 设置默认类型 + column.setJavaType(GenConstants.TYPE_STRING); + column.setQueryType(GenConstants.QUERY_EQ); + + if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)) + { + // 字符串长度超过500设置为文本域 + Integer columnLength = getColumnLength(column.getColumnType()); + String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT; + column.setHtmlType(htmlType); + } + else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) + { + column.setJavaType(GenConstants.TYPE_DATE); + column.setHtmlType(GenConstants.HTML_DATETIME); + } + else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) + { + column.setHtmlType(GenConstants.HTML_INPUT); + + // 如果是浮点型 统一用BigDecimal + String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ","); + if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) + { + column.setJavaType(GenConstants.TYPE_BIGDECIMAL); + }else if ("bit".equalsIgnoreCase(dataType)){ + column.setJavaType(GenConstants.BOOL); + } + // 如果是整形 + else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10) + { + column.setJavaType(GenConstants.TYPE_INTEGER); + }else if ("tinyint".equalsIgnoreCase(dataType)||dataType.equals("int")){ + column.setJavaType(GenConstants.TYPE_INTEGER); + } + // 长整形 + else + { + column.setJavaType(GenConstants.TYPE_LONG); + } + } + + // 插入字段(默认所有字段都需要插入) + column.setIsInsert(GenConstants.REQUIRE); + + // 编辑字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName) && !column.isPk()) + { + column.setIsEdit(GenConstants.REQUIRE); + } + // 列表字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName) && !column.isPk()) + { + column.setIsList(GenConstants.REQUIRE); + } + // 查询字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()) + { + column.setIsQuery(GenConstants.REQUIRE); + } + + // 查询字段类型 + if (StringUtils.endsWithIgnoreCase(columnName, "name")) + { + column.setQueryType(GenConstants.QUERY_LIKE); + } + // 状态字段设置单选框 + if (StringUtils.endsWithIgnoreCase(columnName, "status")) + { + column.setHtmlType(GenConstants.HTML_RADIO); + } + // 类型&性别字段设置下拉框 + else if (StringUtils.endsWithIgnoreCase(columnName, "type") + || StringUtils.endsWithIgnoreCase(columnName, "sex")) + { + column.setHtmlType(GenConstants.HTML_SELECT); + } + // 图片字段设置图片上传控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "image")) + { + column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD); + } + // 文件字段设置文件上传控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "file")) + { + column.setHtmlType(GenConstants.HTML_FILE_UPLOAD); + } + // 内容字段设置富文本控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "content")) + { + column.setHtmlType(GenConstants.HTML_EDITOR); + } + } + + /** + * 校验数组是否包含指定值 + * + * @param arr 数组 + * @param targetValue 值 + * @return 是否包含 + */ + public static boolean arraysContains(String[] arr, String targetValue) + { + return Arrays.asList(arr).contains(targetValue); + } + + /** + * 获取模块名 + * + * @param packageName 包名 + * @return 模块名 + */ + public static String getModuleName(String packageName) + { + int lastIndex = packageName.lastIndexOf("."); + int nameLength = packageName.length(); + return StringUtils.substring(packageName, lastIndex + 1, nameLength); + } + + /** + * 获取业务名 + * + * @param tableName 表名 + * @return 业务名 + */ + public static String getBusinessName(String tableName) + { + int lastIndex = tableName.lastIndexOf("_"); + int nameLength = tableName.length(); + return StringUtils.substring(tableName, lastIndex + 1, nameLength); + } + + /** + * 表名转换成Java类名 + * + * @param tableName 表名称 + * @return 类名 + */ + public static String convertClassName(String tableName) + { + boolean autoRemovePre = GenConfig.getAutoRemovePre(); + String tablePrefix = GenConfig.getTablePrefix(); + if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) + { + String[] searchList = StringUtils.split(tablePrefix, ","); + tableName = replaceFirst(tableName, searchList); + } + return StringUtils.convertToCamelCase(tableName); + } + + /** + * 批量替换前缀 + * + * @param replacementm 替换值 + * @param searchList 替换列表 + * @return + */ + public static String replaceFirst(String replacementm, String[] searchList) + { + String text = replacementm; + for (String searchString : searchList) + { + if (replacementm.startsWith(searchString)) + { + text = replacementm.replaceFirst(searchString, ""); + break; + } + } + return text; + } + + /** + * 关键字替换 + * + * @param text 需要被替换的名字 + * @return 替换后的名字 + */ + public static String replaceText(String text) + { + return RegExUtils.replaceAll(text, "(?:表|若依)", ""); + } + + /** + * 获取数据库类型字段 + * + * @param columnType 列类型 + * @return 截取后的列类型 + */ + public static String getDbType(String columnType) + { + if (StringUtils.indexOf(columnType, "(") > 0) + { + return StringUtils.substringBefore(columnType, "("); + } + else + { + return columnType; + } + } + + /** + * 获取字段长度 + * + * @param columnType 列类型 + * @return 截取后的列类型 + */ + public static Integer getColumnLength(String columnType) + { + if (StringUtils.indexOf(columnType, "(") > 0) + { + String length = StringUtils.substringBetween(columnType, "(", ")"); + return Integer.valueOf(length); + } + else + { + return 0; + } + } +} diff --git a/ff-gen/src/main/java/com/ff/gen/util/VelocityInitializer.java b/ff-gen/src/main/java/com/ff/gen/util/VelocityInitializer.java new file mode 100644 index 0000000..227a463 --- /dev/null +++ b/ff-gen/src/main/java/com/ff/gen/util/VelocityInitializer.java @@ -0,0 +1,35 @@ +package com.ff.gen.util; + +import com.ff.base.constant.Constants; +import org.apache.velocity.app.Velocity; + +import java.util.Properties; + +/** + * VelocityEngine工厂 + * + * @author ff + */ +public class VelocityInitializer +{ + /** + * 初始化vm方法 + */ + public static void initVelocity() + { + Properties p = new Properties(); + try + { + // 加载classpath目录下的vm文件 + p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + // 定义字符集 + p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8); + // 初始化Velocity引擎,指定配置Properties + Velocity.init(p); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } +} diff --git a/ff-gen/src/main/java/com/ff/gen/util/VelocityUtils.java b/ff-gen/src/main/java/com/ff/gen/util/VelocityUtils.java new file mode 100644 index 0000000..b94bcd0 --- /dev/null +++ b/ff-gen/src/main/java/com/ff/gen/util/VelocityUtils.java @@ -0,0 +1,409 @@ +package com.ff.gen.util; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ff.base.constant.GenConstants; +import com.ff.base.utils.DateUtils; +import com.ff.base.utils.StringUtils; +import com.ff.gen.domain.GenTable; +import com.ff.gen.domain.GenTableColumn; +import org.apache.velocity.VelocityContext; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * 模板处理工具类 + * + * @author ff + */ +public class VelocityUtils +{ + /** 项目空间路径 */ + private static final String PROJECT_PATH = "main/java"; + + /** mybatis空间路径 */ + private static final String MYBATIS_PATH = "main/resources/mapper"; + + /** 默认上级菜单,系统工具 */ + private static final String DEFAULT_PARENT_MENU_ID = "3"; + + /** + * 设置模板变量信息 + * + * @return 模板列表 + */ + public static VelocityContext prepareContext(GenTable genTable) + { + String moduleName = genTable.getModuleName(); + String businessName = genTable.getBusinessName(); + String packageName = genTable.getPackageName(); + String tplCategory = genTable.getTplCategory(); + String functionName = genTable.getFunctionName(); + + VelocityContext velocityContext = new VelocityContext(); + velocityContext.put("tplCategory", genTable.getTplCategory()); + velocityContext.put("tableName", genTable.getTableName()); + velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】"); + velocityContext.put("ClassName", genTable.getClassName()); + velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName())); + velocityContext.put("moduleName", genTable.getModuleName()); + velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName())); + velocityContext.put("businessName", genTable.getBusinessName()); + velocityContext.put("basePackage", getPackagePrefix(packageName)); + velocityContext.put("packageName", packageName); + velocityContext.put("author", genTable.getFunctionAuthor()); + velocityContext.put("datetime", DateUtils.getDate()); + velocityContext.put("pkColumn", genTable.getPkColumn()); + velocityContext.put("importList", getImportList(genTable)); + velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); + velocityContext.put("columns", genTable.getColumns()); + velocityContext.put("table", genTable); + velocityContext.put("dicts", getDicts(genTable)); + setMenuVelocityContext(velocityContext, genTable); + if (GenConstants.TPL_TREE.equals(tplCategory)) + { + setTreeVelocityContext(velocityContext, genTable); + } + if (GenConstants.TPL_SUB.equals(tplCategory)) + { + setSubVelocityContext(velocityContext, genTable); + } + return velocityContext; + } + + public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String parentMenuId = getParentMenuId(paramsObj); + context.put("parentMenuId", parentMenuId); + } + + public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String treeCode = getTreecode(paramsObj); + String treeParentCode = getTreeParentCode(paramsObj); + String treeName = getTreeName(paramsObj); + + context.put("treeCode", treeCode); + context.put("treeParentCode", treeParentCode); + context.put("treeName", treeName); + context.put("expandColumn", getExpandColumn(genTable)); + if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) + { + context.put("tree_parent_code", paramsObj.getString(GenConstants.TREE_PARENT_CODE)); + } + if (paramsObj.containsKey(GenConstants.TREE_NAME)) + { + context.put("tree_name", paramsObj.getString(GenConstants.TREE_NAME)); + } + } + + public static void setSubVelocityContext(VelocityContext context, GenTable genTable) + { + GenTable subTable = genTable.getSubTable(); + String subTableName = genTable.getSubTableName(); + String subTableFkName = genTable.getSubTableFkName(); + String subClassName = genTable.getSubTable().getClassName(); + String subTableFkClassName = StringUtils.convertToCamelCase(subTableFkName); + + context.put("subTable", subTable); + context.put("subTableName", subTableName); + context.put("subTableFkName", subTableFkName); + context.put("subTableFkClassName", subTableFkClassName); + context.put("subTableFkclassName", StringUtils.uncapitalize(subTableFkClassName)); + context.put("subClassName", subClassName); + context.put("subclassName", StringUtils.uncapitalize(subClassName)); + context.put("subImportList", getImportList(genTable.getSubTable())); + } + + /** + * 获取模板信息 + * @param tplCategory 生成的模板 + * @param tplWebType 前端类型 + * @return 模板列表 + */ + public static List getTemplateList(String tplCategory, String tplWebType) + { + String useWebType = "vm/vue"; + if ("element-plus".equals(tplWebType)) + { + useWebType = "vm/vue/v3"; + } + List templates = new ArrayList(); + templates.add("vm/java/domain.java.vm"); + templates.add("vm/java/mapper.java.vm"); + templates.add("vm/java/service.java.vm"); + templates.add("vm/java/serviceImpl.java.vm"); + templates.add("vm/java/controller.java.vm"); + templates.add("vm/xml/mapper.xml.vm"); + templates.add("vm/sql/sql.vm"); + templates.add("vm/js/api.js.vm"); + if (GenConstants.TPL_CRUD.equals(tplCategory)) + { + templates.add(useWebType + "/index.vue.vm"); + } + else if (GenConstants.TPL_TREE.equals(tplCategory)) + { + templates.add(useWebType + "/index-tree.vue.vm"); + } + else if (GenConstants.TPL_SUB.equals(tplCategory)) + { + templates.add(useWebType + "/index.vue.vm"); + templates.add("vm/java/sub-domain.java.vm"); + } + return templates; + } + + /** + * 获取文件名 + */ + public static String getFileName(String template, GenTable genTable) + { + // 文件名称 + String fileName = ""; + // 包路径 + String packageName = genTable.getPackageName(); + // 模块名 + String moduleName = genTable.getModuleName(); + // 大写类名 + String className = genTable.getClassName(); + // 业务名称 + String businessName = genTable.getBusinessName(); + + String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/"); + String mybatisPath = MYBATIS_PATH + "/" + moduleName; + String vuePath = "vue"; + + if (template.contains("domain.java.vm")) + { + fileName = StringUtils.format("{}/domain/{}.java", javaPath, className); + } + if (template.contains("sub-domain.java.vm") && StringUtils.equals(GenConstants.TPL_SUB, genTable.getTplCategory())) + { + fileName = StringUtils.format("{}/domain/{}.java", javaPath, genTable.getSubTable().getClassName()); + } + else if (template.contains("mapper.java.vm")) + { + fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); + } + else if (template.contains("service.java.vm")) + { + fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className); + } + else if (template.contains("serviceImpl.java.vm")) + { + fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className); + } + else if (template.contains("controller.java.vm")) + { + fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className); + } + else if (template.contains("mapper.xml.vm")) + { + fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className); + } + else if (template.contains("sql.vm")) + { + fileName = businessName + "Menu.sql"; + } + else if (template.contains("api.js.vm")) + { + fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName); + } + else if (template.contains("index.vue.vm")) + { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); + } + else if (template.contains("index-tree.vue.vm")) + { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); + } + return fileName; + } + + /** + * 获取包前缀 + * + * @param packageName 包名称 + * @return 包前缀名称 + */ + public static String getPackagePrefix(String packageName) + { + int lastIndex = packageName.lastIndexOf("."); + return StringUtils.substring(packageName, 0, lastIndex); + } + + /** + * 根据列类型获取导入包 + * + * @param genTable 业务表对象 + * @return 返回需要导入的包列表 + */ + public static HashSet getImportList(GenTable genTable) + { + List columns = genTable.getColumns(); + GenTable subGenTable = genTable.getSubTable(); + HashSet importList = new HashSet(); + if (StringUtils.isNotNull(subGenTable)) + { + importList.add("java.util.List"); + } + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) + { + importList.add("java.util.Date"); + importList.add("com.fasterxml.jackson.annotation.JsonFormat"); + } + else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) + { + importList.add("java.math.BigDecimal"); + } + } + return importList; + } + + /** + * 根据列类型获取字典组 + * + * @param genTable 业务表对象 + * @return 返回字典组 + */ + public static String getDicts(GenTable genTable) + { + List columns = genTable.getColumns(); + Set dicts = new HashSet(); + addDicts(dicts, columns); + if (StringUtils.isNotNull(genTable.getSubTable())) + { + List subColumns = genTable.getSubTable().getColumns(); + addDicts(dicts, subColumns); + } + return StringUtils.join(dicts, ", "); + } + + /** + * 添加字典列表 + * + * @param dicts 字典列表 + * @param columns 列集合 + */ + public static void addDicts(Set dicts, List columns) + { + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( + column.getHtmlType(), + new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) + { + dicts.add("'" + column.getDictType() + "'"); + } + } + } + + /** + * 获取权限前缀 + * + * @param moduleName 模块名称 + * @param businessName 业务名称 + * @return 返回权限前缀 + */ + public static String getPermissionPrefix(String moduleName, String businessName) + { + return StringUtils.format("{}:{}", moduleName, businessName); + } + + /** + * 获取上级菜单ID字段 + * + * @param paramsObj 生成其他选项 + * @return 上级菜单ID字段 + */ + public static String getParentMenuId(JSONObject paramsObj) + { + if (StringUtils.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID) + && StringUtils.isNotEmpty(paramsObj.getString(GenConstants.PARENT_MENU_ID))) + { + return paramsObj.getString(GenConstants.PARENT_MENU_ID); + } + return DEFAULT_PARENT_MENU_ID; + } + + /** + * 获取树编码 + * + * @param paramsObj 生成其他选项 + * @return 树编码 + */ + public static String getTreecode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_CODE)); + } + return StringUtils.EMPTY; + } + + /** + * 获取树父编码 + * + * @param paramsObj 生成其他选项 + * @return 树父编码 + */ + public static String getTreeParentCode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_PARENT_CODE)); + } + return StringUtils.EMPTY; + } + + /** + * 获取树名称 + * + * @param paramsObj 生成其他选项 + * @return 树名称 + */ + public static String getTreeName(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_NAME)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_NAME)); + } + return StringUtils.EMPTY; + } + + /** + * 获取需要在哪一列上面显示展开按钮 + * + * @param genTable 业务表对象 + * @return 展开按钮列序号 + */ + public static int getExpandColumn(GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String treeName = paramsObj.getString(GenConstants.TREE_NAME); + int num = 0; + for (GenTableColumn column : genTable.getColumns()) + { + if (column.isList()) + { + num++; + String columnName = column.getColumnName(); + if (columnName.equals(treeName)) + { + break; + } + } + } + return num; + } +} diff --git a/ff-gen/src/main/resources/generator.yml b/ff-gen/src/main/resources/generator.yml new file mode 100644 index 0000000..e0e4dad --- /dev/null +++ b/ff-gen/src/main/resources/generator.yml @@ -0,0 +1,10 @@ +# 代码生成 +gen: + # 作者 + author: shi + # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool + packageName: com.ff.operation + # 自动去除表前缀,默认是false + autoRemovePre: true + # 表前缀(生成类名不会包含表前缀,多个用逗号分隔) + tablePrefix: ff_ diff --git a/ff-gen/src/main/resources/mapper/gen/GenTableColumnMapper.xml b/ff-gen/src/main/resources/mapper/gen/GenTableColumnMapper.xml new file mode 100644 index 0000000..7bd06d9 --- /dev/null +++ b/ff-gen/src/main/resources/mapper/gen/GenTableColumnMapper.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column + + + + + + + + insert into gen_table_column ( + table_id, + column_name, + column_comment, + column_type, + java_type, + java_field, + is_pk, + is_increment, + is_required, + is_insert, + is_edit, + is_list, + is_query, + query_type, + html_type, + dict_type, + sort, + create_by, + create_time + )values( + #{tableId}, + #{columnName}, + #{columnComment}, + #{columnType}, + #{javaType}, + #{javaField}, + #{isPk}, + #{isIncrement}, + #{isRequired}, + #{isInsert}, + #{isEdit}, + #{isList}, + #{isQuery}, + #{queryType}, + #{htmlType}, + #{dictType}, + #{sort}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + + update gen_table_column + + column_comment = #{columnComment}, + java_type = #{javaType}, + java_field = #{javaField}, + is_insert = #{isInsert}, + is_edit = #{isEdit}, + is_list = #{isList}, + is_query = #{isQuery}, + is_required = #{isRequired}, + query_type = #{queryType}, + html_type = #{htmlType}, + dict_type = #{dictType}, + sort = #{sort}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where column_id = #{columnId} + + + + delete from gen_table_column where table_id in + + #{tableId} + + + + + delete from gen_table_column where column_id in + + #{item.columnId} + + + + diff --git a/ff-gen/src/main/resources/mapper/gen/GenTableMapper.xml b/ff-gen/src/main/resources/mapper/gen/GenTableMapper.xml new file mode 100644 index 0000000..ebafd96 --- /dev/null +++ b/ff-gen/src/main/resources/mapper/gen/GenTableMapper.xml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, tpl_web_type, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table + + + + + + + + + + + + + + + + + + insert into gen_table ( + table_name, + table_comment, + class_name, + tpl_category, + tpl_web_type, + package_name, + module_name, + business_name, + function_name, + function_author, + gen_type, + gen_path, + remark, + create_by, + create_time + )values( + #{tableName}, + #{tableComment}, + #{className}, + #{tplCategory}, + #{tplWebType}, + #{packageName}, + #{moduleName}, + #{businessName}, + #{functionName}, + #{functionAuthor}, + #{genType}, + #{genPath}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + + ${sql} + + + + update gen_table + + table_name = #{tableName}, + table_comment = #{tableComment}, + sub_table_name = #{subTableName}, + sub_table_fk_name = #{subTableFkName}, + class_name = #{className}, + function_author = #{functionAuthor}, + gen_type = #{genType}, + gen_path = #{genPath}, + tpl_category = #{tplCategory}, + tpl_web_type = #{tplWebType}, + package_name = #{packageName}, + module_name = #{moduleName}, + business_name = #{businessName}, + function_name = #{functionName}, + options = #{options}, + update_by = #{updateBy}, + remark = #{remark}, + update_time =UNIX_TIMESTAMP() * 1000 + + where table_id = #{tableId} + + + + delete from gen_table where table_id in + + #{tableId} + + + + diff --git a/ff-gen/src/main/resources/vm/java/controller.java.vm b/ff-gen/src/main/resources/vm/java/controller.java.vm new file mode 100644 index 0000000..64ff426 --- /dev/null +++ b/ff-gen/src/main/resources/vm/java/controller.java.vm @@ -0,0 +1,115 @@ +package ${packageName}.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; +import com.ff.base.utils.poi.ExcelUtil; +#if($table.crud || $table.sub) +import com.ff.base.core.page.TableDataInfo; +#elseif($table.tree) +#end + +/** + * ${functionName}Controller + * + * @author ${author} + * @date ${datetime} + */ +@RestController +@RequestMapping("/${moduleName}/${businessName}") +public class ${ClassName}Controller extends BaseController +{ + @Autowired + private I${ClassName}Service ${className}Service; + + /** + * 查询${functionName}列表 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')") + @GetMapping("/list") +#if($table.crud || $table.sub) + public TableDataInfo list(${ClassName} ${className}) + { + startPage(); + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + return getDataTable(list); + } +#elseif($table.tree) + public AjaxResult list(${ClassName} ${className}) + { + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + return success(list); + } +#end + + /** + * 导出${functionName}列表 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')") + @Log(title = "${functionName}", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, ${ClassName} ${className}) + { + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class); + util.exportExcel(response, list, "${functionName}数据"); + } + + /** + * 获取${functionName}详细信息 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')") + @GetMapping(value = "/{${pkColumn.javaField}}") + public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) + { + return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField})); + } + + /** + * 新增${functionName} + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')") + @Log(title = "${functionName}", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.insert${ClassName}(${className})); + } + + /** + * 修改${functionName} + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')") + @Log(title = "${functionName}", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.update${ClassName}(${className})); + } + + /** + * 删除${functionName} + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')") + @Log(title = "${functionName}", businessType = BusinessType.DELETE) + @DeleteMapping("/{${pkColumn.javaField}s}") + public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) + { + return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s)); + } +} diff --git a/ff-gen/src/main/resources/vm/java/domain.java.vm b/ff-gen/src/main/resources/vm/java/domain.java.vm new file mode 100644 index 0000000..c7d5b9f --- /dev/null +++ b/ff-gen/src/main/resources/vm/java/domain.java.vm @@ -0,0 +1,58 @@ +package ${packageName}.domain; + +#foreach ($import in $importList) +import ${import}; +#end +import com.ff.base.annotation.Excel; +#if($table.crud || $table.sub) +import com.ff.base.core.domain.BaseEntity; +#elseif($table.tree) +import com.ff.base.core.domain.TreeEntity; +#end +import lombok.Data; +/** + * ${functionName}对象 ${tableName} + * + * @author ${author} + * @date ${datetime} + */ +#if($table.crud || $table.sub) +#set($Entity="BaseEntity") +#elseif($table.tree) +#set($Entity="TreeEntity") +#end +@Data +public class ${ClassName} extends ${Entity} +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $columns) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date') + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#if($table.sub) + /** $table.subTable.functionName信息 */ + private List<${subClassName}> ${subclassName}List; + +#end + +} diff --git a/ff-gen/src/main/resources/vm/java/mapper.java.vm b/ff-gen/src/main/resources/vm/java/mapper.java.vm new file mode 100644 index 0000000..7f0a5b1 --- /dev/null +++ b/ff-gen/src/main/resources/vm/java/mapper.java.vm @@ -0,0 +1,91 @@ +package ${packageName}.mapper; + +import java.util.List; +import ${packageName}.domain.${ClassName}; +#if($table.sub) +import ${packageName}.domain.${subClassName}; +#end + +/** + * ${functionName}Mapper接口 + * + * @author ${author} + * @date ${datetime} + */ +public interface ${ClassName}Mapper +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName}集合 + */ + List<${ClassName}> select${ClassName}List(${ClassName} ${className}); + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + int insert${ClassName}(${ClassName} ${className}); + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + int update${ClassName}(${ClassName} ${className}); + + /** + * 删除${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); +#if($table.sub) + + /** + * 批量删除${subTable.functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + int delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 批量新增${subTable.functionName} + * + * @param ${subclassName}List ${subTable.functionName}列表 + * @return 结果 + */ + int batch${subClassName}(List<${subClassName}> ${subclassName}List); + + + /** + * 通过${functionName}主键删除${subTable.functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}ID + * @return 结果 + */ + int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField}); +#end +} diff --git a/ff-gen/src/main/resources/vm/java/service.java.vm b/ff-gen/src/main/resources/vm/java/service.java.vm new file mode 100644 index 0000000..eba6fbf --- /dev/null +++ b/ff-gen/src/main/resources/vm/java/service.java.vm @@ -0,0 +1,61 @@ +package ${packageName}.service; + +import java.util.List; +import ${packageName}.domain.${ClassName}; + +/** + * ${functionName}Service接口 + * + * @author ${author} + * @date ${datetime} + */ +public interface I${ClassName}Service +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName}集合 + */ + List<${ClassName}> select${ClassName}List(${ClassName} ${className}); + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + int insert${ClassName}(${ClassName} ${className}); + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + int update${ClassName}(${ClassName} ${className}); + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合 + * @return 结果 + */ + int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); +} diff --git a/ff-gen/src/main/resources/vm/java/serviceImpl.java.vm b/ff-gen/src/main/resources/vm/java/serviceImpl.java.vm new file mode 100644 index 0000000..6a686f0 --- /dev/null +++ b/ff-gen/src/main/resources/vm/java/serviceImpl.java.vm @@ -0,0 +1,169 @@ +package ${packageName}.service.impl; + +import java.util.List; +#foreach ($column in $columns) +#if($column.javaField == 'createTime' || $column.javaField == 'updateTime') +import com.ff.base.utils.DateUtils; +#break +#end +#end +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +#if($table.sub) +import java.util.ArrayList; +import com.ff.base.utils.StringUtils; +import org.springframework.transaction.annotation.Transactional; +import ${packageName}.domain.${subClassName}; +#end +import ${packageName}.mapper.${ClassName}Mapper; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; + +/** + * ${functionName}Service业务层处理 + * + * @author ${author} + * @date ${datetime} + */ +@Service +public class ${ClassName}ServiceImpl implements I${ClassName}Service +{ + @Autowired + private ${ClassName}Mapper ${className}Mapper; + + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + @Override + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { + return ${className}Mapper.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); + } + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName} + */ + @Override + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}) + { + return ${className}Mapper.select${ClassName}List(${className}); + } + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int insert${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'createTime') + ${className}.setCreateTime(DateUtils.getNowDate()); +#end +#end +#if($table.sub) + int rows = ${className}Mapper.insert${ClassName}(${className}); + insert${subClassName}(${className}); + return rows; +#else + return ${className}Mapper.insert${ClassName}(${className}); +#end + } + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int update${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'updateTime') + ${className}.setUpdateTime(DateUtils.getNowDate()); +#end +#end +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${className}.get${pkColumn.capJavaField}()); + insert${subClassName}(${className}); +#end + return ${className}Mapper.update${ClassName}(${className}); + } + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaField}s); +#end + return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s); + } + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField}); +#end + return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); + } +#if($table.sub) + + /** + * 新增${subTable.functionName}信息 + * + * @param ${className} ${functionName}对象 + */ + public void insert${subClassName}(${ClassName} ${className}) + { + List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List(); + ${pkColumn.javaType} ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}(); + if (StringUtils.isNotNull(${subclassName}List)) + { + List<${subClassName}> list = new ArrayList<${subClassName}>(); + for (${subClassName} ${subclassName} : ${subclassName}List) + { + ${subclassName}.set${subTableFkClassName}(${pkColumn.javaField}); + list.add(${subclassName}); + } + if (list.size() > 0) + { + ${className}Mapper.batch${subClassName}(list); + } + } + } +#end +} diff --git a/ff-gen/src/main/resources/vm/java/sub-domain.java.vm b/ff-gen/src/main/resources/vm/java/sub-domain.java.vm new file mode 100644 index 0000000..9840cbf --- /dev/null +++ b/ff-gen/src/main/resources/vm/java/sub-domain.java.vm @@ -0,0 +1,76 @@ +package ${packageName}.domain; + +#foreach ($import in $subImportList) +import ${import}; +#end +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; + +/** + * ${subTable.functionName}对象 ${subTableName} + * + * @author ${author} + * @date ${datetime} + */ +public class ${subClassName} extends BaseEntity +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date') + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + public void set${AttrName}($column.javaType $column.javaField) + { + this.$column.javaField = $column.javaField; + } + + public $column.javaType get${AttrName}() + { + return $column.javaField; + } +#end +#end + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) +#foreach ($column in $subTable.columns) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + .append("${column.javaField}", get${AttrName}()) +#end + .toString(); + } +} diff --git a/ff-gen/src/main/resources/vm/js/api.js.vm b/ff-gen/src/main/resources/vm/js/api.js.vm new file mode 100644 index 0000000..9295524 --- /dev/null +++ b/ff-gen/src/main/resources/vm/js/api.js.vm @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询${functionName}列表 +export function list${BusinessName}(query) { + return request({ + url: '/${moduleName}/${businessName}/list', + method: 'get', + params: query + }) +} + +// 查询${functionName}详细 +export function get${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'get' + }) +} + +// 新增${functionName} +export function add${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'post', + data: data + }) +} + +// 修改${functionName} +export function update${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'put', + data: data + }) +} + +// 删除${functionName} +export function del${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'delete' + }) +} diff --git a/ff-gen/src/main/resources/vm/sql/sql.vm b/ff-gen/src/main/resources/vm/sql/sql.vm new file mode 100644 index 0000000..2ad2f0b --- /dev/null +++ b/ff-gen/src/main/resources/vm/sql/sql.vm @@ -0,0 +1,22 @@ +-- 菜单 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', UNIX_TIMESTAMP() * 1000, '', null, '${functionName}菜单'); + +-- 按钮父菜单ID +SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query', '#', 'admin', UNIX_TIMESTAMP() * 1000, '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add', '#', 'admin', UNIX_TIMESTAMP() * 1000, '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit', '#', 'admin', UNIX_TIMESTAMP() * 1000, '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove', '#', 'admin', UNIX_TIMESTAMP() * 1000, '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export', '#', 'admin', UNIX_TIMESTAMP() * 1000, '', null, ''); \ No newline at end of file diff --git a/ff-gen/src/main/resources/vm/vue/index-tree.vue.vm b/ff-gen/src/main/resources/vm/vue/index-tree.vue.vm new file mode 100644 index 0000000..4819c2a --- /dev/null +++ b/ff-gen/src/main/resources/vm/vue/index-tree.vue.vm @@ -0,0 +1,505 @@ + + + diff --git a/ff-gen/src/main/resources/vm/vue/index.vue.vm b/ff-gen/src/main/resources/vm/vue/index.vue.vm new file mode 100644 index 0000000..6296014 --- /dev/null +++ b/ff-gen/src/main/resources/vm/vue/index.vue.vm @@ -0,0 +1,602 @@ + + + diff --git a/ff-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm b/ff-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm new file mode 100644 index 0000000..c54d62b --- /dev/null +++ b/ff-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm @@ -0,0 +1,474 @@ + + + diff --git a/ff-gen/src/main/resources/vm/vue/v3/index.vue.vm b/ff-gen/src/main/resources/vm/vue/v3/index.vue.vm new file mode 100644 index 0000000..8b25665 --- /dev/null +++ b/ff-gen/src/main/resources/vm/vue/v3/index.vue.vm @@ -0,0 +1,590 @@ + + + diff --git a/ff-gen/src/main/resources/vm/xml/mapper.xml.vm b/ff-gen/src/main/resources/vm/xml/mapper.xml.vm new file mode 100644 index 0000000..1f68d09 --- /dev/null +++ b/ff-gen/src/main/resources/vm/xml/mapper.xml.vm @@ -0,0 +1,140 @@ + + + + + +#foreach ($column in $columns) + +#end + +#if($table.sub) + + + + + + +#foreach ($column in $subTable.columns) + +#end + +#end + + + select#foreach($column in $columns) $column.columnName#if($foreach.count != $columns.size()),#end#end from ${tableName} + + + + + +#if($table.sub) + + +#end + + + insert into ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + $column.columnName, +#end +#end + + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + #{$column.javaField}, +#end +#end + + + + + update ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName) + $column.columnName = #{$column.javaField}, +#end +#end + + where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} in + + #{${pkColumn.javaField}} + + +#if($table.sub) + + + delete from ${subTableName} where ${subTableFkName} in + + #{${subTableFkclassName}} + + + + + delete from ${subTableName} where ${subTableFkName} = #{${subTableFkclassName}} + + + + insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end) values + + (#foreach($column in $subTable.columns) #{item.$column.javaField}#if($foreach.count != $subTable.columns.size()),#end#end) + + +#end + \ No newline at end of file diff --git a/ff-gen/target/classes/com/ff/gen/config/GenConfig.class b/ff-gen/target/classes/com/ff/gen/config/GenConfig.class new file mode 100644 index 0000000..0492b24 Binary files /dev/null and b/ff-gen/target/classes/com/ff/gen/config/GenConfig.class differ diff --git a/ff-gen/target/classes/com/ff/gen/controller/GenController.class b/ff-gen/target/classes/com/ff/gen/controller/GenController.class new file mode 100644 index 0000000..567a1fa Binary files /dev/null and b/ff-gen/target/classes/com/ff/gen/controller/GenController.class differ diff --git a/ff-gen/target/classes/com/ff/gen/domain/GenTable.class b/ff-gen/target/classes/com/ff/gen/domain/GenTable.class new file mode 100644 index 0000000..eb5449b Binary files /dev/null and b/ff-gen/target/classes/com/ff/gen/domain/GenTable.class differ diff --git a/ff-gen/target/classes/com/ff/gen/domain/GenTableColumn.class b/ff-gen/target/classes/com/ff/gen/domain/GenTableColumn.class new file mode 100644 index 0000000..58e067a Binary files /dev/null and b/ff-gen/target/classes/com/ff/gen/domain/GenTableColumn.class differ diff --git a/ff-gen/target/classes/com/ff/gen/mapper/GenTableColumnMapper.class b/ff-gen/target/classes/com/ff/gen/mapper/GenTableColumnMapper.class new file mode 100644 index 0000000..4b74063 Binary files /dev/null and b/ff-gen/target/classes/com/ff/gen/mapper/GenTableColumnMapper.class differ diff --git a/ff-gen/target/classes/com/ff/gen/mapper/GenTableMapper.class b/ff-gen/target/classes/com/ff/gen/mapper/GenTableMapper.class new file mode 100644 index 0000000..1f54c3c Binary files /dev/null and b/ff-gen/target/classes/com/ff/gen/mapper/GenTableMapper.class differ diff --git a/ff-gen/target/classes/com/ff/gen/service/GenTableColumnServiceImpl.class b/ff-gen/target/classes/com/ff/gen/service/GenTableColumnServiceImpl.class new file mode 100644 index 0000000..8ab2ff7 Binary files /dev/null and b/ff-gen/target/classes/com/ff/gen/service/GenTableColumnServiceImpl.class differ diff --git a/ff-gen/target/classes/com/ff/gen/service/GenTableServiceImpl.class b/ff-gen/target/classes/com/ff/gen/service/GenTableServiceImpl.class new file mode 100644 index 0000000..8427865 Binary files /dev/null and b/ff-gen/target/classes/com/ff/gen/service/GenTableServiceImpl.class differ diff --git a/ff-gen/target/classes/com/ff/gen/service/IGenTableColumnService.class b/ff-gen/target/classes/com/ff/gen/service/IGenTableColumnService.class new file mode 100644 index 0000000..6fbb4af Binary files /dev/null and b/ff-gen/target/classes/com/ff/gen/service/IGenTableColumnService.class differ diff --git a/ff-gen/target/classes/com/ff/gen/service/IGenTableService.class b/ff-gen/target/classes/com/ff/gen/service/IGenTableService.class new file mode 100644 index 0000000..41fc336 Binary files /dev/null and b/ff-gen/target/classes/com/ff/gen/service/IGenTableService.class differ diff --git a/ff-gen/target/classes/com/ff/gen/util/GenUtils.class b/ff-gen/target/classes/com/ff/gen/util/GenUtils.class new file mode 100644 index 0000000..7dd1f43 Binary files /dev/null and b/ff-gen/target/classes/com/ff/gen/util/GenUtils.class differ diff --git a/ff-gen/target/classes/com/ff/gen/util/VelocityInitializer.class b/ff-gen/target/classes/com/ff/gen/util/VelocityInitializer.class new file mode 100644 index 0000000..44ac730 Binary files /dev/null and b/ff-gen/target/classes/com/ff/gen/util/VelocityInitializer.class differ diff --git a/ff-gen/target/classes/com/ff/gen/util/VelocityUtils.class b/ff-gen/target/classes/com/ff/gen/util/VelocityUtils.class new file mode 100644 index 0000000..9d8d85b Binary files /dev/null and b/ff-gen/target/classes/com/ff/gen/util/VelocityUtils.class differ diff --git a/ff-gen/target/classes/generator.yml b/ff-gen/target/classes/generator.yml new file mode 100644 index 0000000..e0e4dad --- /dev/null +++ b/ff-gen/target/classes/generator.yml @@ -0,0 +1,10 @@ +# 代码生成 +gen: + # 作者 + author: shi + # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool + packageName: com.ff.operation + # 自动去除表前缀,默认是false + autoRemovePre: true + # 表前缀(生成类名不会包含表前缀,多个用逗号分隔) + tablePrefix: ff_ diff --git a/ff-gen/target/classes/mapper/gen/GenTableColumnMapper.xml b/ff-gen/target/classes/mapper/gen/GenTableColumnMapper.xml new file mode 100644 index 0000000..7bd06d9 --- /dev/null +++ b/ff-gen/target/classes/mapper/gen/GenTableColumnMapper.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column + + + + + + + + insert into gen_table_column ( + table_id, + column_name, + column_comment, + column_type, + java_type, + java_field, + is_pk, + is_increment, + is_required, + is_insert, + is_edit, + is_list, + is_query, + query_type, + html_type, + dict_type, + sort, + create_by, + create_time + )values( + #{tableId}, + #{columnName}, + #{columnComment}, + #{columnType}, + #{javaType}, + #{javaField}, + #{isPk}, + #{isIncrement}, + #{isRequired}, + #{isInsert}, + #{isEdit}, + #{isList}, + #{isQuery}, + #{queryType}, + #{htmlType}, + #{dictType}, + #{sort}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + + update gen_table_column + + column_comment = #{columnComment}, + java_type = #{javaType}, + java_field = #{javaField}, + is_insert = #{isInsert}, + is_edit = #{isEdit}, + is_list = #{isList}, + is_query = #{isQuery}, + is_required = #{isRequired}, + query_type = #{queryType}, + html_type = #{htmlType}, + dict_type = #{dictType}, + sort = #{sort}, + update_by = #{updateBy}, + update_time = UNIX_TIMESTAMP() * 1000 + + where column_id = #{columnId} + + + + delete from gen_table_column where table_id in + + #{tableId} + + + + + delete from gen_table_column where column_id in + + #{item.columnId} + + + + diff --git a/ff-gen/target/classes/mapper/gen/GenTableMapper.xml b/ff-gen/target/classes/mapper/gen/GenTableMapper.xml new file mode 100644 index 0000000..ebafd96 --- /dev/null +++ b/ff-gen/target/classes/mapper/gen/GenTableMapper.xml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, tpl_web_type, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table + + + + + + + + + + + + + + + + + + insert into gen_table ( + table_name, + table_comment, + class_name, + tpl_category, + tpl_web_type, + package_name, + module_name, + business_name, + function_name, + function_author, + gen_type, + gen_path, + remark, + create_by, + create_time + )values( + #{tableName}, + #{tableComment}, + #{className}, + #{tplCategory}, + #{tplWebType}, + #{packageName}, + #{moduleName}, + #{businessName}, + #{functionName}, + #{functionAuthor}, + #{genType}, + #{genPath}, + #{remark}, + #{createBy}, + UNIX_TIMESTAMP() * 1000 + ) + + + + ${sql} + + + + update gen_table + + table_name = #{tableName}, + table_comment = #{tableComment}, + sub_table_name = #{subTableName}, + sub_table_fk_name = #{subTableFkName}, + class_name = #{className}, + function_author = #{functionAuthor}, + gen_type = #{genType}, + gen_path = #{genPath}, + tpl_category = #{tplCategory}, + tpl_web_type = #{tplWebType}, + package_name = #{packageName}, + module_name = #{moduleName}, + business_name = #{businessName}, + function_name = #{functionName}, + options = #{options}, + update_by = #{updateBy}, + remark = #{remark}, + update_time =UNIX_TIMESTAMP() * 1000 + + where table_id = #{tableId} + + + + delete from gen_table where table_id in + + #{tableId} + + + + diff --git a/ff-gen/target/classes/vm/java/controller.java.vm b/ff-gen/target/classes/vm/java/controller.java.vm new file mode 100644 index 0000000..64ff426 --- /dev/null +++ b/ff-gen/target/classes/vm/java/controller.java.vm @@ -0,0 +1,115 @@ +package ${packageName}.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ff.base.annotation.Log; +import com.ff.base.core.controller.BaseController; +import com.ff.base.core.domain.AjaxResult; +import com.ff.base.enums.BusinessType; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; +import com.ff.base.utils.poi.ExcelUtil; +#if($table.crud || $table.sub) +import com.ff.base.core.page.TableDataInfo; +#elseif($table.tree) +#end + +/** + * ${functionName}Controller + * + * @author ${author} + * @date ${datetime} + */ +@RestController +@RequestMapping("/${moduleName}/${businessName}") +public class ${ClassName}Controller extends BaseController +{ + @Autowired + private I${ClassName}Service ${className}Service; + + /** + * 查询${functionName}列表 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')") + @GetMapping("/list") +#if($table.crud || $table.sub) + public TableDataInfo list(${ClassName} ${className}) + { + startPage(); + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + return getDataTable(list); + } +#elseif($table.tree) + public AjaxResult list(${ClassName} ${className}) + { + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + return success(list); + } +#end + + /** + * 导出${functionName}列表 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')") + @Log(title = "${functionName}", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, ${ClassName} ${className}) + { + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class); + util.exportExcel(response, list, "${functionName}数据"); + } + + /** + * 获取${functionName}详细信息 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')") + @GetMapping(value = "/{${pkColumn.javaField}}") + public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) + { + return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField})); + } + + /** + * 新增${functionName} + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')") + @Log(title = "${functionName}", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.insert${ClassName}(${className})); + } + + /** + * 修改${functionName} + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')") + @Log(title = "${functionName}", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.update${ClassName}(${className})); + } + + /** + * 删除${functionName} + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')") + @Log(title = "${functionName}", businessType = BusinessType.DELETE) + @DeleteMapping("/{${pkColumn.javaField}s}") + public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) + { + return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s)); + } +} diff --git a/ff-gen/target/classes/vm/java/domain.java.vm b/ff-gen/target/classes/vm/java/domain.java.vm new file mode 100644 index 0000000..c7d5b9f --- /dev/null +++ b/ff-gen/target/classes/vm/java/domain.java.vm @@ -0,0 +1,58 @@ +package ${packageName}.domain; + +#foreach ($import in $importList) +import ${import}; +#end +import com.ff.base.annotation.Excel; +#if($table.crud || $table.sub) +import com.ff.base.core.domain.BaseEntity; +#elseif($table.tree) +import com.ff.base.core.domain.TreeEntity; +#end +import lombok.Data; +/** + * ${functionName}对象 ${tableName} + * + * @author ${author} + * @date ${datetime} + */ +#if($table.crud || $table.sub) +#set($Entity="BaseEntity") +#elseif($table.tree) +#set($Entity="TreeEntity") +#end +@Data +public class ${ClassName} extends ${Entity} +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $columns) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date') + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#if($table.sub) + /** $table.subTable.functionName信息 */ + private List<${subClassName}> ${subclassName}List; + +#end + +} diff --git a/ff-gen/target/classes/vm/java/mapper.java.vm b/ff-gen/target/classes/vm/java/mapper.java.vm new file mode 100644 index 0000000..7f0a5b1 --- /dev/null +++ b/ff-gen/target/classes/vm/java/mapper.java.vm @@ -0,0 +1,91 @@ +package ${packageName}.mapper; + +import java.util.List; +import ${packageName}.domain.${ClassName}; +#if($table.sub) +import ${packageName}.domain.${subClassName}; +#end + +/** + * ${functionName}Mapper接口 + * + * @author ${author} + * @date ${datetime} + */ +public interface ${ClassName}Mapper +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName}集合 + */ + List<${ClassName}> select${ClassName}List(${ClassName} ${className}); + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + int insert${ClassName}(${ClassName} ${className}); + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + int update${ClassName}(${ClassName} ${className}); + + /** + * 删除${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); +#if($table.sub) + + /** + * 批量删除${subTable.functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + int delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 批量新增${subTable.functionName} + * + * @param ${subclassName}List ${subTable.functionName}列表 + * @return 结果 + */ + int batch${subClassName}(List<${subClassName}> ${subclassName}List); + + + /** + * 通过${functionName}主键删除${subTable.functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}ID + * @return 结果 + */ + int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField}); +#end +} diff --git a/ff-gen/target/classes/vm/java/service.java.vm b/ff-gen/target/classes/vm/java/service.java.vm new file mode 100644 index 0000000..eba6fbf --- /dev/null +++ b/ff-gen/target/classes/vm/java/service.java.vm @@ -0,0 +1,61 @@ +package ${packageName}.service; + +import java.util.List; +import ${packageName}.domain.${ClassName}; + +/** + * ${functionName}Service接口 + * + * @author ${author} + * @date ${datetime} + */ +public interface I${ClassName}Service +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName}集合 + */ + List<${ClassName}> select${ClassName}List(${ClassName} ${className}); + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + int insert${ClassName}(${ClassName} ${className}); + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + int update${ClassName}(${ClassName} ${className}); + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合 + * @return 结果 + */ + int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); +} diff --git a/ff-gen/target/classes/vm/java/serviceImpl.java.vm b/ff-gen/target/classes/vm/java/serviceImpl.java.vm new file mode 100644 index 0000000..6a686f0 --- /dev/null +++ b/ff-gen/target/classes/vm/java/serviceImpl.java.vm @@ -0,0 +1,169 @@ +package ${packageName}.service.impl; + +import java.util.List; +#foreach ($column in $columns) +#if($column.javaField == 'createTime' || $column.javaField == 'updateTime') +import com.ff.base.utils.DateUtils; +#break +#end +#end +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +#if($table.sub) +import java.util.ArrayList; +import com.ff.base.utils.StringUtils; +import org.springframework.transaction.annotation.Transactional; +import ${packageName}.domain.${subClassName}; +#end +import ${packageName}.mapper.${ClassName}Mapper; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; + +/** + * ${functionName}Service业务层处理 + * + * @author ${author} + * @date ${datetime} + */ +@Service +public class ${ClassName}ServiceImpl implements I${ClassName}Service +{ + @Autowired + private ${ClassName}Mapper ${className}Mapper; + + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + @Override + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { + return ${className}Mapper.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); + } + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName} + */ + @Override + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}) + { + return ${className}Mapper.select${ClassName}List(${className}); + } + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int insert${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'createTime') + ${className}.setCreateTime(DateUtils.getNowDate()); +#end +#end +#if($table.sub) + int rows = ${className}Mapper.insert${ClassName}(${className}); + insert${subClassName}(${className}); + return rows; +#else + return ${className}Mapper.insert${ClassName}(${className}); +#end + } + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int update${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'updateTime') + ${className}.setUpdateTime(DateUtils.getNowDate()); +#end +#end +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${className}.get${pkColumn.capJavaField}()); + insert${subClassName}(${className}); +#end + return ${className}Mapper.update${ClassName}(${className}); + } + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaField}s); +#end + return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s); + } + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField}); +#end + return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); + } +#if($table.sub) + + /** + * 新增${subTable.functionName}信息 + * + * @param ${className} ${functionName}对象 + */ + public void insert${subClassName}(${ClassName} ${className}) + { + List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List(); + ${pkColumn.javaType} ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}(); + if (StringUtils.isNotNull(${subclassName}List)) + { + List<${subClassName}> list = new ArrayList<${subClassName}>(); + for (${subClassName} ${subclassName} : ${subclassName}List) + { + ${subclassName}.set${subTableFkClassName}(${pkColumn.javaField}); + list.add(${subclassName}); + } + if (list.size() > 0) + { + ${className}Mapper.batch${subClassName}(list); + } + } + } +#end +} diff --git a/ff-gen/target/classes/vm/java/sub-domain.java.vm b/ff-gen/target/classes/vm/java/sub-domain.java.vm new file mode 100644 index 0000000..9840cbf --- /dev/null +++ b/ff-gen/target/classes/vm/java/sub-domain.java.vm @@ -0,0 +1,76 @@ +package ${packageName}.domain; + +#foreach ($import in $subImportList) +import ${import}; +#end +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ff.base.annotation.Excel; +import com.ff.base.core.domain.BaseEntity; + +/** + * ${subTable.functionName}对象 ${subTableName} + * + * @author ${author} + * @date ${datetime} + */ +public class ${subClassName} extends BaseEntity +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date') + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + public void set${AttrName}($column.javaType $column.javaField) + { + this.$column.javaField = $column.javaField; + } + + public $column.javaType get${AttrName}() + { + return $column.javaField; + } +#end +#end + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) +#foreach ($column in $subTable.columns) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + .append("${column.javaField}", get${AttrName}()) +#end + .toString(); + } +} diff --git a/ff-gen/target/classes/vm/js/api.js.vm b/ff-gen/target/classes/vm/js/api.js.vm new file mode 100644 index 0000000..9295524 --- /dev/null +++ b/ff-gen/target/classes/vm/js/api.js.vm @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询${functionName}列表 +export function list${BusinessName}(query) { + return request({ + url: '/${moduleName}/${businessName}/list', + method: 'get', + params: query + }) +} + +// 查询${functionName}详细 +export function get${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'get' + }) +} + +// 新增${functionName} +export function add${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'post', + data: data + }) +} + +// 修改${functionName} +export function update${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'put', + data: data + }) +} + +// 删除${functionName} +export function del${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'delete' + }) +} diff --git a/ff-gen/target/classes/vm/sql/sql.vm b/ff-gen/target/classes/vm/sql/sql.vm new file mode 100644 index 0000000..2ad2f0b --- /dev/null +++ b/ff-gen/target/classes/vm/sql/sql.vm @@ -0,0 +1,22 @@ +-- 菜单 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', UNIX_TIMESTAMP() * 1000, '', null, '${functionName}菜单'); + +-- 按钮父菜单ID +SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query', '#', 'admin', UNIX_TIMESTAMP() * 1000, '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add', '#', 'admin', UNIX_TIMESTAMP() * 1000, '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit', '#', 'admin', UNIX_TIMESTAMP() * 1000, '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove', '#', 'admin', UNIX_TIMESTAMP() * 1000, '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export', '#', 'admin', UNIX_TIMESTAMP() * 1000, '', null, ''); \ No newline at end of file diff --git a/ff-gen/target/classes/vm/vue/index-tree.vue.vm b/ff-gen/target/classes/vm/vue/index-tree.vue.vm new file mode 100644 index 0000000..4819c2a --- /dev/null +++ b/ff-gen/target/classes/vm/vue/index-tree.vue.vm @@ -0,0 +1,505 @@ + + + diff --git a/ff-gen/target/classes/vm/vue/index.vue.vm b/ff-gen/target/classes/vm/vue/index.vue.vm new file mode 100644 index 0000000..6296014 --- /dev/null +++ b/ff-gen/target/classes/vm/vue/index.vue.vm @@ -0,0 +1,602 @@ + + + diff --git a/ff-gen/target/classes/vm/vue/v3/index-tree.vue.vm b/ff-gen/target/classes/vm/vue/v3/index-tree.vue.vm new file mode 100644 index 0000000..c54d62b --- /dev/null +++ b/ff-gen/target/classes/vm/vue/v3/index-tree.vue.vm @@ -0,0 +1,474 @@ + + + diff --git a/ff-gen/target/classes/vm/vue/v3/index.vue.vm b/ff-gen/target/classes/vm/vue/v3/index.vue.vm new file mode 100644 index 0000000..8b25665 --- /dev/null +++ b/ff-gen/target/classes/vm/vue/v3/index.vue.vm @@ -0,0 +1,590 @@ + + + diff --git a/ff-gen/target/classes/vm/xml/mapper.xml.vm b/ff-gen/target/classes/vm/xml/mapper.xml.vm new file mode 100644 index 0000000..1f68d09 --- /dev/null +++ b/ff-gen/target/classes/vm/xml/mapper.xml.vm @@ -0,0 +1,140 @@ + + + + + +#foreach ($column in $columns) + +#end + +#if($table.sub) + + + + + + +#foreach ($column in $subTable.columns) + +#end + +#end + + + select#foreach($column in $columns) $column.columnName#if($foreach.count != $columns.size()),#end#end from ${tableName} + + + + + +#if($table.sub) + + +#end + + + insert into ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + $column.columnName, +#end +#end + + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + #{$column.javaField}, +#end +#end + + + + + update ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName) + $column.columnName = #{$column.javaField}, +#end +#end + + where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} in + + #{${pkColumn.javaField}} + + +#if($table.sub) + + + delete from ${subTableName} where ${subTableFkName} in + + #{${subTableFkclassName}} + + + + + delete from ${subTableName} where ${subTableFkName} = #{${subTableFkclassName}} + + + + insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end) values + + (#foreach($column in $subTable.columns) #{item.$column.javaField}#if($foreach.count != $subTable.columns.size()),#end#end) + + +#end + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..72c2d9a --- /dev/null +++ b/pom.xml @@ -0,0 +1,254 @@ + + + 4.0.0 + + com.ff + ff + 0.0.1 + + ff + FF管理系统 + + + 0.0.1 + UTF-8 + UTF-8 + 1.8 + 3.1.1 + 5.3.33 + 5.7.12 + 1.2.23 + 1.21 + 3.0.0 + 2.3.3 + 1.4.7 + 2.0.43 + 6.6.1 + 2.13.0 + 4.1.2 + 2.3 + 0.9.1 + 4.5.10 + 3.4.1 + 3.4.1 + + + + + + + + + org.springframework + spring-framework-bom + ${spring-framework.version} + pom + import + + + + + org.springframework.security + spring-security-bom + ${spring-security.version} + pom + import + + + + + org.springframework.boot + spring-boot-dependencies + 2.5.15 + pom + import + + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + + eu.bitwalker + UserAgentUtils + ${bitwalker.version} + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper.boot.version} + + + + + com.github.oshi + oshi-core + ${oshi.version} + + + + + io.springfox + springfox-boot-starter + ${swagger.version} + + + io.swagger + swagger-models + + + + + + + commons-io + commons-io + ${commons.io.version} + + + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + + org.apache.httpcomponents + httpclient + ${http.version} + + + + com.squareup.okhttp3 + okhttp + ${okhttp.version} + + + + + org.apache.velocity + velocity-engine-core + ${velocity.version} + + + + + com.alibaba.fastjson2 + fastjson2 + ${fastjson.version} + + + + + io.jsonwebtoken + jjwt + ${jwt.version} + + + + + pro.fessional + kaptcha + ${kaptcha.version} + + + + + com.google.zxing + core + ${zxing.version} + + + com.google.zxing + javase + ${zxing.version} + + + + + com.ff + ff-gen + ${ff.version} + + + + + com.ff + ff-base + ${ff.version} + + + + + com.ff + ff-admin + ${ff.version} + + + + cn.licoy + encrypt-body-spring-boot-starter + ${encrypt.version} + + + + + + + ff-admin + ff-gen + ff-base + + pom + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + false + + + + + diff --git a/sh/linux/create.sh b/sh/linux/create.sh new file mode 100644 index 0000000..2d0a9c6 --- /dev/null +++ b/sh/linux/create.sh @@ -0,0 +1,6 @@ +mkdir -p /opt/sever/dist/ff-admin/config +mkdir -p /opt/sever/dist/ff-admin/dumps +cp start.bat /opt/sever/dist/ff-admin/ +cd .. +cd .. +cp ff-admin/src/main/resources/application-prod.yml /opt/sever/dist/ff-admin/config diff --git a/sh/linux/nginx.sh b/sh/linux/nginx.sh new file mode 100644 index 0000000..8942938 --- /dev/null +++ b/sh/linux/nginx.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# 检查是否提供了所有必要参数 +if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then + echo "Error: All three parameters are required." + exit 1 +fi + +# 域名 +rootUrl=$1 +# 租户名称 +tenantName=$2 +# 前端路径 +packUrl=$3 + + +# 执行构建命令 +cd "$packUrl" || { echo "Error: Failed to change directory to $packUrl"; exit 1; } + + +# 检查 $packUrl/dist 路径是否存在存在就不需要打包 +if [ ! -d "$packUrl/dist" ]; then + + +# 执行构建命令 +npm install + +npm run build -- --tenant="$tenantName" + +fi + + +# 删除目标目录下的所有文件和子目录 +rm -rf "$rootUrl" + +# 执行复制命令 +cp -r "$packUrl/dist/" "$rootUrl" + +sudo nginx -s reload +# 打印成功信息 +echo "Build and copy completed for server: $rootUrl and tenant: $tenantName" diff --git a/sh/linux/publish.sh b/sh/linux/publish.sh new file mode 100644 index 0000000..05c273f --- /dev/null +++ b/sh/linux/publish.sh @@ -0,0 +1,15 @@ +cd .. +cd .. +if [ $# -gt 0 ]; then + git pull + echo "切换分支$1" + git checkout $1 +fi +git pull +mvn -Dmaven.test.skip=true clean package +if [ $? -eq 0 ]; then + cp ff-admin/target/ff-*.jar /opt/sever/dist/ff-admin/ + +else + echo "fail" +fi diff --git a/sh/linux/start-manager-api.sh b/sh/linux/start-manager-api.sh new file mode 100644 index 0000000..4258a45 --- /dev/null +++ b/sh/linux/start-manager-api.sh @@ -0,0 +1,20 @@ +export JAVA_HOME=/usr/local/jdk1.8.0_171 +export PATH=$JAVA_HOME/bin:$PATH + +pids=$(jps| grep ff-admin.jar|awk '{print $1}') +for pid in $pids +do + kill -9 $pid +done + + +nohup java -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/sever/dist/ff-admin/gc.log \ +-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/sever/dist/ff-admin/dumps \ +-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -Xms1g -Xmx2g -Xmn1g -Xss256k \ +-XX:SurvivorRatio=8 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 \ +-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 \ +-jar /opt/sever/dist/ff-admin/ff-admin.jar --spring.profiles.active=prod & + + + + diff --git a/sh/win/create.bat b/sh/win/create.bat new file mode 100644 index 0000000..4ea2829 --- /dev/null +++ b/sh/win/create.bat @@ -0,0 +1,6 @@ +mkdir \opt\sever\dist\ff-admin\config +mkdir \opt\sever\dist\ff-admin\dumps +copy start.bat \opt\sever\dist\ff-admin\ +cd .. +cd .. +copy ff-admin\src\main\resources\application-prod.yml \opt\sever\dist\ff-admin\config \ No newline at end of file diff --git a/sh/win/publish.bat b/sh/win/publish.bat new file mode 100644 index 0000000..4d532c7 --- /dev/null +++ b/sh/win/publish.bat @@ -0,0 +1,23 @@ +@echo off + +REM 退回到上级目录 +cd .. +cd .. + +set DRIVE=%~d0 + +REM 切换到发布分支 +git checkout prod + +REM 更新代码 +git pull + +REM 执行 Maven 打包命令,跳过测试 +mvn -Dmaven.test.skip=true clean package + + +REM 复制目标文件到 /app/ 目录 + copy ff-admin\target\ff-*.jar D:\opt\sever\dist\ff-admin\ + +REM 防止窗口关闭 +pause diff --git a/sh/win/start.bat b/sh/win/start.bat new file mode 100644 index 0000000..c7a9659 --- /dev/null +++ b/sh/win/start.bat @@ -0,0 +1,23 @@ +@echo off + + +REM 查找并终止运行中的 ff-admin.jar 进程 +for /f "tokens=1" %%i in ('jps ^| findstr ff-admin.jar') do ( + echo 正在终止进程 ID %%i + taskkill /PID %%i /F +) + +REM 启动新进程 +echo 启动 ff-admin.jar... +start /b java ^ + -XX:+PrintGCDetails -XX:+PrintGCDateStamps ^ + -Xloggc:/opt/sever/dist/ff-admin/gc.log ^ + -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/sever/dist/ff-admin/dumps ^ + -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m ^ + -Xms1g -Xmx2g -Xmn1g -Xss256k ^ + -XX:SurvivorRatio=8 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 ^ + -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 ^ + -jar /opt/sever/dist/ff-admin/ff-admin.jar ^ + --spring.profiles.active=prod ^ + + diff --git a/sql/ff-admin.sql b/sql/ff-admin.sql new file mode 100644 index 0000000..02503af --- /dev/null +++ b/sql/ff-admin.sql @@ -0,0 +1,2186 @@ +/* + Navicat Premium Data Transfer + + Source Server : 本地 + Source Server Type : MySQL + Source Server Version : 80039 + Source Host : 192.168.1.29:3306 + Source Schema : ff-admin + + Target Server Type : MySQL + Target Server Version : 80039 + File Encoding : 65001 + + Date: 21/10/2024 10:26:04 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for ff_currency +-- ---------------------------- +DROP TABLE IF EXISTS `ff_currency`; +CREATE TABLE `ff_currency` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id', + `currency_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '币种编码', + `market_currency_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '市场币种编码', + `currency_sign` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '币种符号', + `game_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '游戏汇率', + `currency_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '币种类型(字典ff_currency)', + `currency_aisle` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '币种通道', + `currency_display` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '币种展示内容', + `currency_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '币种名称', + `full_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '币种全称', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '币种表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_currency +-- ---------------------------- +INSERT INTO `ff_currency` VALUES (1, 'USDT', 'USDT', 'U', 1.00, '1', 'USD', 'USDT', 'USDT', 'Tether', '', '2024-10-17 17:24:35', '', '2024-10-17 17:29:18', 'USDT'); +INSERT INTO `ff_currency` VALUES (2, 'VND', 'VND', '₫', 1000.00, '2', NULL, 'VND1000:1', '越南盾', 'Vietnamese Dong', '', '2024-10-17 17:30:03', '', NULL, '越南盾'); + +-- ---------------------------- +-- Table structure for ff_member +-- ---------------------------- +DROP TABLE IF EXISTS `ff_member`; +CREATE TABLE `ff_member` ( + `id` bigint NOT NULL COMMENT '主键id', + `currency_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '币种(字典ff_currency)', + `member_account` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '会员账号', + `real_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '会员姓名', + `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '账号密码', + `withdraw_password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '提现密码', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '账号状态(0正常 1手动冻结 2异常冻结 3禁止领取优惠 4禁止提现 5黑名单 6停用 7禁止进入游戏 8自我禁止-限制游戏 9自我禁止-限制参与优惠 10自我禁止-限制登录)', + `vip_id` bigint NULL DEFAULT NULL COMMENT 'vip id', + `level_id` bigint NULL DEFAULT NULL COMMENT '会员层级id', + `label_id` bigint NULL DEFAULT NULL COMMENT '会员标签id', + `agent_id` bigint NULL DEFAULT NULL COMMENT '上级代理id', + `agent_account` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '上级代理账号', + `channel_id` bigint NULL DEFAULT NULL COMMENT '渠道id', + `registe_way` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '注册方式(字典ff_registe_way)', + `registe_time` datetime NULL DEFAULT NULL COMMENT '注册时间', + `registe_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '注册IP', + `registe_ip_city` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '注册ip的城市', + `registe_domain` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '注册域名', + `registe_device_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '注册设备类型(字典ff_device_type)', + `registe_device_num` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '注册设备号', + `registe_browser` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '注册浏览器信息', + `registe_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '注册链接url', + `registe_fingerprint` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '注册浏览器指纹', + `sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '男:1 女:2', + `birthday` date NULL DEFAULT NULL COMMENT '生日', + `area_code` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '手机号区号', + `phone_number` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '手机号', + `first_charge_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '首充金额', + `first_charge_time` datetime NULL DEFAULT NULL COMMENT '首充时间', + `last_login_date` datetime NULL DEFAULT NULL COMMENT '上次登录时间', + `last_login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '上次登录IP', + `login_date` datetime NULL DEFAULT NULL COMMENT '最后登录时间', + `login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '最后登录IP', + `login_ip_city` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '最后登录ip的城市', + `login_domain` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '最后登录域名', + `login_device_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '最后登录设备类型(字典ff_device_type)', + `login_device_num` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '最后登录设备号', + `login_browser` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '最后登录浏览器信息', + `login_fingerprint` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '最后登录浏览器指纹', + `verify_way` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '验证方式(字典ff_verify_way)', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '会员邮箱', + `face_book_account` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'facebook账号', + `telegram_account` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'telegram账号', + `whatsapp_account` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'whatsapp账号', + `zalo_account` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'zalo账号', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '会员备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '会员表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_member +-- ---------------------------- + +-- ---------------------------- +-- Table structure for ff_member_account +-- ---------------------------- +DROP TABLE IF EXISTS `ff_member_account`; +CREATE TABLE `ff_member_account` ( + `id` bigint NOT NULL COMMENT '主键id', + `account_type` tinyint NULL DEFAULT NULL COMMENT '账户类型(0.余额钱包 1.奖励钱包)', + `member_id` bigint NOT NULL COMMENT '会员id', + `member_account` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '会员账号', + `real_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '会员姓名', + `version` bigint NULL DEFAULT NULL COMMENT '版本号', + `currency_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '币种', + `balance` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '余额', + `block_balance` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '冻结余额', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '会员账户表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_member_account +-- ---------------------------- + +-- ---------------------------- +-- Table structure for ff_member_account_detail +-- ---------------------------- +DROP TABLE IF EXISTS `ff_member_account_detail`; +CREATE TABLE `ff_member_account_detail` ( + `id` bigint NOT NULL COMMENT '主键id', + `account_id` bigint NULL DEFAULT NULL COMMENT '账户id', + `member_id` bigint NULL DEFAULT NULL COMMENT '用户id', + `account_type` tinyint NULL DEFAULT NULL COMMENT '账户类型(0.余额钱包 1.奖励钱包)', + `change_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '账变大类(字典 \r\nff_account_change_type)', + `change_small_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '账变小类', + `change_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '变动金额', + `before_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '变动前余额', + `after_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '变动后余额', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '会员账户明细表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_member_account_detail +-- ---------------------------- + +-- ---------------------------- +-- Table structure for ff_member_charge +-- ---------------------------- +DROP TABLE IF EXISTS `ff_member_charge`; +CREATE TABLE `ff_member_charge` ( + `id` bigint NOT NULL COMMENT '主键id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '会员充值表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_member_charge +-- ---------------------------- + +-- ---------------------------- +-- Table structure for ff_member_label +-- ---------------------------- +DROP TABLE IF EXISTS `ff_member_label`; +CREATE TABLE `ff_member_label` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id', + `order_num` int NULL DEFAULT 0 COMMENT '显示顺序', + `label_name` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '标签名称', + `icon_color` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '图标颜色', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '会员标签表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_member_label +-- ---------------------------- +INSERT INTO `ff_member_label` VALUES (2, 1, '默认标签', '#1677fd', 'admin', '2024-10-14 14:18:31', 'admin', '2024-10-18 09:34:00', '默认标签'); + +-- ---------------------------- +-- Table structure for ff_member_level +-- ---------------------------- +DROP TABLE IF EXISTS `ff_member_level`; +CREATE TABLE `ff_member_level` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id', + `level_type` tinyint NULL DEFAULT NULL COMMENT '0.自动层级 1.固定层级', + `level_name` varchar(24) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '层级名称', + `label_id` bigint NULL DEFAULT NULL COMMENT '会员标签表id', + `charge_count` int NULL DEFAULT NULL COMMENT '充值次数', + `charge_amount` decimal(10, 0) NULL DEFAULT NULL COMMENT '累计充值金额', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '会员层级表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_member_level +-- ---------------------------- +INSERT INTO `ff_member_level` VALUES (3, 1, '测试测试', 2, NULL, NULL, 'admin', '2024-10-16 16:17:16', '', NULL, '1123123'); +INSERT INTO `ff_member_level` VALUES (4, 1, '刷子玩家', NULL, NULL, NULL, 'admin', '2024-10-16 16:30:57', '', NULL, '破解验证注册的玩家'); +INSERT INTO `ff_member_level` VALUES (5, 0, '默认层级', NULL, 0, 0, 'admin', '2024-10-16 16:32:41', '', NULL, '默认层级'); + +-- ---------------------------- +-- Table structure for ff_member_log +-- ---------------------------- +DROP TABLE IF EXISTS `ff_member_log`; +CREATE TABLE `ff_member_log` ( + `id` bigint NOT NULL COMMENT '主键id', + `member_id` bigint NULL DEFAULT NULL COMMENT '会员id', + `member_account` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '会员账号', + `operate_time` datetime NULL DEFAULT NULL COMMENT '操作时间', + `operate_project` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '操作项目(字典ff_log_operproject)', + `operate_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '操作类型(字典ff_oper_type)', + `before_data` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '变更前', + `after_data` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '变更后', + `login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '登录IP', + `login_ip_city` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '最后登录ip的城市', + `login_device_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '登录设备类型(字典ff_device_type)', + `login_device_num` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '登录设备号', + `login_browser` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '登录浏览器信息', + `result` tinyint NULL DEFAULT NULL COMMENT '结果(0.成功 1.失败)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '会员日志表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_member_log +-- ---------------------------- + +-- ---------------------------- +-- Table structure for ff_member_vip +-- ---------------------------- +DROP TABLE IF EXISTS `ff_member_vip`; +CREATE TABLE `ff_member_vip` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id', + `grade` int NOT NULL COMMENT '等级', + `currency_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '币种', + `icon_parent_style` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '图标父样式(字典ff_vip_icon_parent_style )', + `icon_style` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '图标样式(字典ff_vip_icon_style)', + `icon_color` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '图标颜色(字典ff_vip_icon_color)', + `day_draw_top` decimal(10, 2) NULL DEFAULT NULL COMMENT '每日提现金额上限(0 表示不限制)', + `day_draw_count_top` int NULL DEFAULT NULL COMMENT '每日提现笔数上限(0 表示不限制)', + `day_service_fee_free_count` int NULL DEFAULT NULL COMMENT '每日免手续费笔数', + `promotion_charge` decimal(10, 0) NULL DEFAULT NULL COMMENT '晋级需再充值', + `promotion_pour` decimal(10, 0) NULL DEFAULT NULL COMMENT '晋级需再打码', + `promotion_bonus` decimal(10, 0) NULL DEFAULT NULL COMMENT '晋级奖金', + `month_charge` decimal(10, 2) NULL DEFAULT NULL COMMENT '当月充值', + `month_pour` decimal(10, 2) NULL DEFAULT NULL COMMENT '当月打码', + `month_salary` decimal(10, 2) NULL DEFAULT NULL COMMENT '当月俸禄', + `month_top` decimal(10, 2) NULL DEFAULT NULL COMMENT '当月累计封顶', + `week_charge` decimal(10, 2) NULL DEFAULT NULL COMMENT '当周充值', + `week_pour` decimal(10, 2) NULL DEFAULT NULL COMMENT '当周打码', + `week_salary` decimal(10, 2) NULL DEFAULT NULL COMMENT '当周俸禄', + `week_top` decimal(10, 2) NULL DEFAULT NULL COMMENT '当周累计封顶', + `day_charge` decimal(10, 2) NULL DEFAULT NULL COMMENT '当日充值', + `day_pour` decimal(10, 2) NULL DEFAULT NULL COMMENT '当日打码', + `day_salary` decimal(10, 2) NULL DEFAULT NULL COMMENT '日俸禄', + `day_top` decimal(10, 2) NULL DEFAULT NULL COMMENT '日累计封顶', + `member_count` bigint NULL DEFAULT NULL COMMENT '会员人数', + `member_update_time` datetime NULL DEFAULT NULL COMMENT '会员人数更新时间', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '会员vip等级表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_member_vip +-- ---------------------------- +INSERT INTO `ff_member_vip` VALUES (1, 0, 'VND', '1', '5', '6', 0.00, 5, 5, 0, 0, 0, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0, '2024-10-21 10:00:00', 'admin', '2024-10-16 14:09:58', 'admin', '2024-10-19 17:14:46', NULL); +INSERT INTO `ff_member_vip` VALUES (2, 1, 'VND', '1', '10', '3', 2.00, 6, 5, 0, 60000, 1800, 0.00, 3000.00, 6.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0, '2024-10-21 10:00:00', 'admin', '2024-10-16 14:24:37', 'admin', '2024-10-19 17:14:46', NULL); + +-- ---------------------------- +-- Table structure for ff_member_vip_setup +-- ---------------------------- +DROP TABLE IF EXISTS `ff_member_vip_setup`; +CREATE TABLE `ff_member_vip_setup` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id', + `keep_grade` tinyint NULL DEFAULT NULL COMMENT '保级开关(0.关闭 1.开启)', + `reward_switch` tinyint NULL DEFAULT NULL COMMENT '奖励开关(0.关闭 1.开启)', + `set_type` tinyint NULL DEFAULT NULL COMMENT '设置类型(0.日俸禄 1.周俸禄 2.月俸禄 3.日/周/月 公共设置 4.其他设置(包含保级、奖励开关))', + `draw_time` tinyint NULL DEFAULT NULL COMMENT '领取时间(0.次日 1.实时领取(影响留存) 2.每日 3.下周 4.每周 5.下月 6.每月)', + `draw_start_time` time NULL DEFAULT NULL COMMENT '领取开始时间(次日 实时 每日 下周 每周 下月 每月)', + `draw_end_time` time NULL DEFAULT NULL COMMENT '领取结束时间(每日 每周 每月)', + `repeat_draw` tinyint NULL DEFAULT NULL COMMENT '晋级时是否重复领取(0.可重复领取(含跨级部分) 1.只能领取最高一档)', + `week_day` tinyint NULL DEFAULT NULL COMMENT '每周第几日', + `month_day` tinyint NULL DEFAULT NULL COMMENT '每月第几日', + `expire_reward_day` int NULL DEFAULT NULL COMMENT '奖励领取过期天数', + `distribute_way` tinyint NULL DEFAULT NULL COMMENT '派发方式(0.玩家自领(过期自动到账) 1.玩家自领(过期自动作废))', + `prohibit_level` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin NULL DEFAULT NULL COMMENT '禁止参与层级(黑名单)', + `audit_multiple` decimal(10, 2) NULL DEFAULT NULL COMMENT '稽核倍数(玩家需要达到稽核倍数的流水,才能提现)', + `appoint_platform` tinyint NULL DEFAULT NULL COMMENT '奖金稽核指定平台(0.不限制 1.仅限以下勾选平台)', + `audit_platfrom_ids` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '稽核指定平台ids', + `vip_icon` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '图标样式', + `rule_type` tinyint NULL DEFAULT NULL COMMENT '规则类型 0.自定义 1.系统翻译', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '规则说明', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '会员vip等级公共设置表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_member_vip_setup +-- ---------------------------- +INSERT INTO `ff_member_vip_setup` VALUES (1, NULL, NULL, 0, 1, '00:00:00', NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'admin', '2024-10-16 10:03:20', 'admin', '2024-10-16 13:32:45', NULL); +INSERT INTO `ff_member_vip_setup` VALUES (2, NULL, NULL, 1, 1, '00:00:00', NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'admin', '2024-10-16 10:03:20', 'admin', '2024-10-16 13:32:45', NULL); +INSERT INTO `ff_member_vip_setup` VALUES (3, NULL, NULL, 2, 1, '00:00:00', NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'admin', '2024-10-16 10:03:20', 'admin', '2024-10-16 13:32:45', NULL); +INSERT INTO `ff_member_vip_setup` VALUES (4, NULL, NULL, 3, 1, '00:00:00', NULL, 0, NULL, NULL, 30, 1, NULL, NULL, NULL, NULL, NULL, NULL, 'admin', '2024-10-16 10:10:33', 'admin', '2024-10-16 13:32:45', NULL); +INSERT INTO `ff_member_vip_setup` VALUES (5, 0, 1, 4, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1.00, 0, NULL, '1', 1, 'admin', '2024-10-16 10:19:35', 'admin', '2024-10-16 13:32:45', '1.晋级标准:满足VIP晋级要求(即充值或有效投注都满足条件),即可晋级相应VIP等级,获得相应晋级奖金,如连续晋级多级,可获得全部等级晋级奖金,奖金实时可领取;\n2.日俸禄:每日充值及有效投注满足当前等级日俸禄要求,可获得对应日俸禄奖金,如连续晋级多级,可获得全部等级日俸禄奖金,奖金实时可领取;\n3.周俸禄:每周充值及有效投注满足当前等级周俸禄要求,可获得对应周俸禄奖金,如连续晋级多级,可获得全部等级周俸禄奖金,奖金实时可领取;\n4.月俸禄:每月充值及有效投注满足当前等级月俸禄要求,可获得对应月俸禄奖金,如连续晋级多级,可获得全部等级月俸禄奖金,奖金实时可领取;\n5.奖励过期时间:获得的奖金仅保留30天,期间内未主动领取,则过期作废,例如:1月1日获得奖励,保留30天,则1月32日 00:00:00过期作废;\n6.稽核说明:VIP所赠送的奖金需1倍流水(即稽核、打码或有效投注)才能提现,打码不限游戏平台;\n7.活动声明:本功能仅限账号本人进行正常游戏投注,禁止租借账号、无风险投注(对赌、对刷、低赔刷水)、恶意套利、使用外挂程式、机器人、利用协议、漏洞、接口、群控或其他技术手段参与,一经查核属实,本平台有权终止会员登录、暂停会员使用网站、及没收奖金和不当盈利的权利,无需特别通知;\n8.解释说明:会员领取VIP奖励时,本平台将默认会员同意且遵守对应条件等相关规定,为避免文字理解歧义,本平台保有本活动最终解释权。'); + +-- ---------------------------- +-- Table structure for ff_member_withdraw +-- ---------------------------- +DROP TABLE IF EXISTS `ff_member_withdraw`; +CREATE TABLE `ff_member_withdraw` ( + `id` bigint NOT NULL COMMENT '主键id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '会员提现表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_member_withdraw +-- ---------------------------- + +-- ---------------------------- +-- Table structure for ff_payment_channel +-- ---------------------------- +DROP TABLE IF EXISTS `ff_payment_channel`; +CREATE TABLE `ff_payment_channel` ( + `id` bigint NOT NULL COMMENT '主键id', + `parent_id` bigint NULL DEFAULT NULL COMMENT '子渠道id 顶级分类该id为0', + `channel_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '渠道名称', + `channel_icon` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '大类图标', + `blacklist_status` tinyint NULL DEFAULT NULL COMMENT '充值黑名单状态 0.关闭 1.开启', + `switch_status` tinyint NULL DEFAULT NULL COMMENT '开启状态 0.关闭 1.开启', + `custom_tag` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '大类角标', + `order_num` int NULL DEFAULT 0 COMMENT '显示顺序', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '通道表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_payment_channel +-- ---------------------------- + +-- ---------------------------- +-- Table structure for ff_payment_third_channel +-- ---------------------------- +DROP TABLE IF EXISTS `ff_payment_third_channel`; +CREATE TABLE `ff_payment_third_channel` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id', + `currency_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '币种', + `channel_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '渠道名称', + `merch_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '商户名称', + `merch_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '商户code', + `merch_privateKey` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '商户私钥', + `merch_publicKey` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '商户公钥', + `notify_white_ips` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '三方回调ip(多个逗号隔开)', + `pay_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '下单地址', + `query_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '查询地址', + `show_encrypted_field` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '加密字段(如:merchant_key,platform_public_key,merchant_private_key,merchant_public_key,extended_info)', + `success_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '成功code(如:{\\\"message\\\":\\\"success\\\",\\\"success\\\":true} 、SUCCESS 、success 、OK 、ok)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '第三方支付渠道表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_payment_third_channel +-- ---------------------------- + +-- ---------------------------- +-- Table structure for ff_payment_third_channel_way +-- ---------------------------- +DROP TABLE IF EXISTS `ff_payment_third_channel_way`; +CREATE TABLE `ff_payment_third_channel_way` ( + `id` bigint NOT NULL COMMENT '主键id', + `third_channel_id` bigint NULL DEFAULT NULL COMMENT '第三方通道id', + `channel_way_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '第三方通道方式code', + `channel_way_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '第三方通道方式名称', + `channel_way_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '第三方通道类型', + `money_max` decimal(10, 2) NULL DEFAULT NULL COMMENT '最大限额', + `money_min` decimal(10, 2) NULL DEFAULT NULL COMMENT '最小限额', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '第三方通道方式表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of ff_payment_third_channel_way +-- ---------------------------- + +-- ---------------------------- +-- Table structure for gen_table +-- ---------------------------- +DROP TABLE IF EXISTS `gen_table`; +CREATE TABLE `gen_table` ( + `table_id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', + `table_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '表名称', + `table_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '表描述', + `sub_table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '关联子表的表名', + `sub_table_fk_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '子表关联的外键名', + `class_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '实体类名称', + `tpl_category` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'crud' COMMENT '使用的模板(crud单表操作 tree树表操作)', + `tpl_web_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '前端模板类型(element-ui模版 element-plus模版)', + `package_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成包路径', + `module_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成模块名', + `business_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成业务名', + `function_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成功能名', + `function_author` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成功能作者', + `gen_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '生成代码方式(0zip压缩包 1自定义路径)', + `gen_path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '/' COMMENT '生成路径(不填默认项目路径)', + `options` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '其它生成选项', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`table_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代码生成业务表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of gen_table +-- ---------------------------- +INSERT INTO `gen_table` VALUES (2, 'ff_member_label', '会员标签表', NULL, NULL, 'MemberLabel', 'crud', 'element-plus', 'com.ff.member', 'member', 'label', '会员标签', 'liukang', '0', '/', '{\"parentMenuId\":3006}', 'admin', '2024-10-14 09:53:09', '', '2024-10-14 14:26:12', NULL); +INSERT INTO `gen_table` VALUES (3, 'ff_member_level', '会员层级表', NULL, NULL, 'MemberLevel', 'crud', 'element-plus', 'com.ff.member', 'member', 'level', '会员层级', 'liukang', '0', '/', '{\"parentMenuId\":3006}', 'admin', '2024-10-14 14:24:30', '', '2024-10-14 14:25:49', NULL); +INSERT INTO `gen_table` VALUES (4, 'ff_member_vip', '会员vip等级表', NULL, NULL, 'MemberVip', 'crud', 'element-plus', 'com.ff.member', 'member', 'vip', 'vip等级', 'liukang', '0', '/', '{\"parentMenuId\":3006}', 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46', NULL); +INSERT INTO `gen_table` VALUES (6, 'ff_member_vip_setup', '会员vip等级公共设置表', NULL, NULL, 'MemberVipSetup', 'crud', 'element-plus', 'com.ff.member', 'member', 'vipSetup', '会员vip等级公共设置', 'liukang', '0', '/', '{\"parentMenuId\":\"\"}', 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23', NULL); +INSERT INTO `gen_table` VALUES (7, 'ff_member_log', '会员日志表', NULL, NULL, 'MemberLog', 'crud', 'element-plus', 'com.ff.member', 'member', 'log', '会员日志', 'liukang', '0', '/', '{\"parentMenuId\":3006}', 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18', NULL); +INSERT INTO `gen_table` VALUES (8, 'ff_member', '会员表', NULL, NULL, 'Member', 'crud', 'element-plus', 'com.ff.member', 'member', 'member', '所有会员', 'liukang', '0', '/', '{\"parentMenuId\":3006}', 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42', NULL); +INSERT INTO `gen_table` VALUES (12, 'ff_currency', '币种表', NULL, NULL, 'Currency', 'crud', 'element-plus', 'com.ff.operation', 'operation', 'currency', '币种管理', 'liukang', '0', '/', '{\"parentMenuId\":3044}', 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08', NULL); + +-- ---------------------------- +-- Table structure for gen_table_column +-- ---------------------------- +DROP TABLE IF EXISTS `gen_table_column`; +CREATE TABLE `gen_table_column` ( + `column_id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', + `table_id` bigint NULL DEFAULT NULL COMMENT '归属表编号', + `column_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '列名称', + `column_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '列描述', + `column_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '列类型', + `java_type` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'JAVA类型', + `java_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'JAVA字段名', + `is_pk` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否主键(1是)', + `is_increment` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否自增(1是)', + `is_required` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否必填(1是)', + `is_insert` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否为插入字段(1是)', + `is_edit` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否编辑字段(1是)', + `is_list` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否列表字段(1是)', + `is_query` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否查询字段(1是)', + `query_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'EQ' COMMENT '查询方式(等于、不等于、大于、小于、范围)', + `html_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)', + `dict_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典类型', + `sort` int NULL DEFAULT NULL COMMENT '排序', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`column_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 252 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代码生成业务表字段' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of gen_table_column +-- ---------------------------- +INSERT INTO `gen_table_column` VALUES (11, 2, 'id', '主键id', 'bigint', 'Long', 'id', '1', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2024-10-14 09:53:09', '', '2024-10-14 14:26:12'); +INSERT INTO `gen_table_column` VALUES (12, 2, 'label_name', '标签名称', 'varchar(16)', 'String', 'labelName', '0', '0', '0', '1', '1', '1', '1', 'LIKE', 'input', '', 3, 'admin', '2024-10-14 09:53:09', '', '2024-10-14 14:26:12'); +INSERT INTO `gen_table_column` VALUES (13, 2, 'icon_color', '图标颜色', 'varchar(100)', 'String', 'iconColor', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, 'admin', '2024-10-14 09:53:09', '', '2024-10-14 14:26:12'); +INSERT INTO `gen_table_column` VALUES (14, 2, 'create_by', '创建者', 'varchar(64)', 'String', 'createBy', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 5, 'admin', '2024-10-14 09:53:09', '', '2024-10-14 14:26:12'); +INSERT INTO `gen_table_column` VALUES (15, 2, 'create_time', '创建时间', 'datetime', 'Date', 'createTime', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 6, 'admin', '2024-10-14 09:53:09', '', '2024-10-14 14:26:12'); +INSERT INTO `gen_table_column` VALUES (16, 2, 'update_by', '更新者', 'varchar(64)', 'String', 'updateBy', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'input', '', 7, 'admin', '2024-10-14 09:53:09', '', '2024-10-14 14:26:12'); +INSERT INTO `gen_table_column` VALUES (17, 2, 'update_time', '更新时间', 'datetime', 'Date', 'updateTime', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 8, 'admin', '2024-10-14 09:53:09', '', '2024-10-14 14:26:12'); +INSERT INTO `gen_table_column` VALUES (18, 2, 'remark', '描述', 'varchar(500)', 'String', 'remark', '0', '0', '0', '1', '1', '1', NULL, 'EQ', 'textarea', '', 9, 'admin', '2024-10-14 09:53:09', '', '2024-10-14 14:26:12'); +INSERT INTO `gen_table_column` VALUES (19, 2, 'order_num', '显示顺序', 'int', 'Long', 'orderNum', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 2, '', '2024-10-14 10:52:39', '', '2024-10-14 14:26:12'); +INSERT INTO `gen_table_column` VALUES (20, 3, 'id', '主键id', 'bigint', 'Long', 'id', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2024-10-14 14:24:30', '', '2024-10-14 14:25:49'); +INSERT INTO `gen_table_column` VALUES (21, 3, 'level_type', '0.自动层级 1.固定层级', 'tinyint', 'Integer', 'levelType', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', '', 2, 'admin', '2024-10-14 14:24:30', '', '2024-10-14 14:25:49'); +INSERT INTO `gen_table_column` VALUES (22, 3, 'level_name', '层级名称', 'varchar(24)', 'String', 'levelName', '0', '0', '0', '1', '1', '1', '1', 'LIKE', 'input', '', 3, 'admin', '2024-10-14 14:24:30', '', '2024-10-14 14:25:49'); +INSERT INTO `gen_table_column` VALUES (23, 3, 'label_id', '会员标签表id', 'bigint', 'Long', 'labelId', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, 'admin', '2024-10-14 14:24:30', '', '2024-10-14 14:25:49'); +INSERT INTO `gen_table_column` VALUES (24, 3, 'label_name', '会员标签名称', 'varchar(16)', 'String', 'labelName', '0', '0', '0', '1', '1', '1', '1', 'LIKE', 'input', '', 5, 'admin', '2024-10-14 14:24:30', '', '2024-10-14 14:25:49'); +INSERT INTO `gen_table_column` VALUES (25, 3, 'charge_count', '充值次数', 'int', 'Integer', 'chargeCount', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 6, 'admin', '2024-10-14 14:24:30', '', '2024-10-14 14:25:49'); +INSERT INTO `gen_table_column` VALUES (26, 3, 'charge_amount', '累计充值金额', 'decimal(10,0)', 'Long', 'chargeAmount', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, 'admin', '2024-10-14 14:24:30', '', '2024-10-14 14:25:49'); +INSERT INTO `gen_table_column` VALUES (27, 3, 'create_by', '创建者', 'varchar(64)', 'String', 'createBy', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 8, 'admin', '2024-10-14 14:24:30', '', '2024-10-14 14:25:49'); +INSERT INTO `gen_table_column` VALUES (28, 3, 'create_time', '创建时间', 'datetime', 'Date', 'createTime', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 9, 'admin', '2024-10-14 14:24:30', '', '2024-10-14 14:25:49'); +INSERT INTO `gen_table_column` VALUES (29, 3, 'update_by', '更新者', 'varchar(64)', 'String', 'updateBy', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'input', '', 10, 'admin', '2024-10-14 14:24:30', '', '2024-10-14 14:25:49'); +INSERT INTO `gen_table_column` VALUES (30, 3, 'update_time', '更新时间', 'datetime', 'Date', 'updateTime', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 11, 'admin', '2024-10-14 14:24:30', '', '2024-10-14 14:25:49'); +INSERT INTO `gen_table_column` VALUES (31, 3, 'remark', '描述', 'varchar(500)', 'String', 'remark', '0', '0', '0', '1', '1', '1', NULL, 'EQ', 'textarea', '', 12, 'admin', '2024-10-14 14:24:30', '', '2024-10-14 14:25:49'); +INSERT INTO `gen_table_column` VALUES (32, 4, 'id', '主键id', 'bigint', 'Long', 'id', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (33, 4, 'grade', '等级', 'int', 'Integer', 'grade', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 2, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (34, 4, 'currency_type', '币种(字典ff_currency)', 'varchar(10)', 'String', 'currencyType', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'select', 'ff_currency', 3, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (35, 4, 'icon_parent_style', '图标父样式(字典ff_vip_icon_parent_style )', 'varchar(200)', 'String', 'iconParentStyle', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', 'ff_vip_icon_parent_style', 4, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (36, 4, 'icon_style', '图标样式(字典ff_vip_icon_style)', 'varchar(200)', 'String', 'iconStyle', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', 'ff_vip_icon_style', 5, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (37, 4, 'icon_color', '图标颜色(字典ff_vip_icon_color)', 'varchar(200)', 'String', 'iconColor', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', 'ff_vip_icon_color', 6, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (38, 4, 'promotion_charge', '晋级需再充值', 'decimal(10,0)', 'BigDecimal', 'promotionCharge', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 10, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (39, 4, 'promotion_pour', '晋级需再打码', 'decimal(10,0)', 'BigDecimal', 'promotionPour', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 11, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (40, 4, 'promotion_bonus', '晋级奖金', 'decimal(10,0)', 'BigDecimal', 'promotionBonus', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 12, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (41, 4, 'month_charge', '当月充值', 'decimal(10,2)', 'BigDecimal', 'monthCharge', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 13, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (42, 4, 'month_pour', '当月打码', 'decimal(10,2)', 'BigDecimal', 'monthPour', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 14, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (43, 4, 'month_salary', '当月俸禄', 'decimal(10,2)', 'BigDecimal', 'monthSalary', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 15, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (44, 4, 'month_top', '当月累计封顶', 'decimal(10,2)', 'BigDecimal', 'monthTop', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 16, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (45, 4, 'week_charge', '当周充值', 'decimal(10,2)', 'BigDecimal', 'weekCharge', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 17, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (46, 4, 'week_pour', '当周打码', 'decimal(10,2)', 'BigDecimal', 'weekPour', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 18, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (47, 4, 'week_salary', '当周俸禄', 'decimal(10,2)', 'BigDecimal', 'weekSalary', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 19, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (48, 4, 'week_top', '当周累计封顶', 'decimal(10,2)', 'BigDecimal', 'weekTop', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 20, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (49, 4, 'day_charge', '当日充值', 'decimal(10,2)', 'BigDecimal', 'dayCharge', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 21, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (50, 4, 'day_pour', '当日打码', 'decimal(10,2)', 'BigDecimal', 'dayPour', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 22, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (51, 4, 'day_salary', '日俸禄', 'decimal(10,2)', 'BigDecimal', 'daySalary', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 23, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (52, 4, 'day_top', '日累计封顶', 'decimal(10,2)', 'BigDecimal', 'dayTop', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 24, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (53, 4, 'create_by', '创建者', 'varchar(64)', 'String', 'createBy', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 27, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (54, 4, 'create_time', '创建时间', 'datetime', 'Date', 'createTime', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 28, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (55, 4, 'update_by', '更新者', 'varchar(64)', 'String', 'updateBy', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'input', '', 29, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (56, 4, 'update_time', '更新时间', 'datetime', 'Date', 'updateTime', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 30, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (57, 4, 'remark', '描述', 'varchar(500)', 'String', 'remark', '0', '0', '0', '1', '1', '1', NULL, 'EQ', 'textarea', '', 31, 'admin', '2024-10-15 16:07:03', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (72, 6, 'id', '主键id', 'bigint', 'Long', 'id', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (73, 6, 'keep_grade', '保级开关(0.关闭 1.开启)', 'tinyint', 'Integer', 'keepGrade', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 2, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (74, 6, 'reward_switch', '奖励开关(0.关闭 1.开启)', 'tinyint', 'Integer', 'rewardSwitch', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 3, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (76, 6, 'draw_time', '领取时间(0.次日 1.实时领取(影响留存) 2.每日 3.下周 4.每周 5.下月 6.每月)', 'tinyint', 'Integer', 'drawTime', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 5, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (77, 6, 'draw_start_time', '领取开始时间(次日 实时 每日 下周 每周 下月 每月)', 'time', 'Date', 'drawStartTime', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 6, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (78, 6, 'draw_end_time', '领取结束时间(每日 每周 每月)', 'time', 'Date', 'drawEndTime', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 7, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (79, 6, 'repeat_draw', '晋级时是否重复领取(0.可重复领取(含跨级部分) 1.只能领取最高一档)', 'tinyint', 'Integer', 'repeatDraw', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (80, 6, 'week_day', '每周第几日', 'tinyint', 'Integer', 'weekDay', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 9, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (81, 6, 'month_day', '每月第几日', 'tinyint', 'Integer', 'monthDay', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 10, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (82, 6, 'expire_reward_day', '奖励领取过期天数', 'int', 'Integer', 'expireRewardDay', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 11, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (83, 6, 'distribute_way', '派发方式(0.玩家自领(过期自动到账) 1.玩家自领(过期自动作废))', 'tinyint', 'Integer', 'distributeWay', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 12, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (84, 6, 'prohibit_level', '禁止参与层级(黑名单)', 'varchar(1000)', 'String', 'prohibitLevel', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'textarea', '', 13, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (85, 6, 'audit_multiple', '稽核倍数(玩家需要达到稽核倍数的流水,才能提现)', 'decimal(10,2)', 'BigDecimal', 'auditMultiple', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 14, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (86, 6, 'appoint_platform', '奖金稽核指定平台(0.不限制 1.仅限以下勾选平台)', 'tinyint', 'Integer', 'appointPlatform', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 15, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (87, 6, 'audit_platfrom_ids', '稽核指定平台ids', 'varchar(1000)', 'String', 'auditPlatfromIds', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'textarea', '', 16, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (88, 6, 'vip_icon', '图标样式', 'varchar(10)', 'String', 'vipIcon', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 17, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (89, 6, 'create_by', '创建者', 'varchar(64)', 'String', 'createBy', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 19, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (90, 6, 'create_time', '创建时间', 'datetime', 'Date', 'createTime', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 20, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (91, 6, 'update_by', '更新者', 'varchar(64)', 'String', 'updateBy', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'input', '', 21, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (92, 6, 'update_time', '更新时间', 'datetime', 'Date', 'updateTime', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 22, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (93, 6, 'remark', '规则说明', 'varchar(2000)', 'String', 'remark', '0', '0', '0', '1', '1', '1', NULL, 'EQ', 'textarea', '', 23, 'admin', '2024-10-15 16:31:37', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (94, 7, 'id', '主键id', 'bigint', 'Long', 'id', '1', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (95, 7, 'member_id', '会员id', 'bigint', 'Long', 'memberId', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 2, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (96, 7, 'member_account', '会员账号', 'varchar(16)', 'String', 'memberAccount', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 3, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (97, 7, 'operate_time', '操作时间', 'datetime', 'Date', 'operateTime', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 4, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (98, 7, 'operate_project', '操作项目(字典ff_log_operproject)', 'varchar(50)', 'String', 'operateProject', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', 'ff_log_operproject', 5, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (99, 7, 'operate_type', '操作类型(字典ff_oper_type)', 'varchar(50)', 'String', 'operateType', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', 'ff_oper_type', 6, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (100, 7, 'before_data', '变更前', 'varchar(255)', 'String', 'beforeData', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (101, 7, 'after_data', '变更后', 'varchar(255)', 'String', 'afterData', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (102, 7, 'login_ip', '登录IP', 'varchar(128)', 'String', 'loginIp', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 9, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (103, 7, 'login_ip_city', '最后登录ip的城市', 'varchar(100)', 'String', 'loginIpCity', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 10, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (104, 7, 'login_device_type', '登录设备类型(字典ff_device_type)', 'varchar(100)', 'String', 'loginDeviceType', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', 'ff_device_type', 11, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (105, 7, 'login_device_num', '登录设备号', 'varchar(100)', 'String', 'loginDeviceNum', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 12, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (106, 7, 'login_browser', '登录浏览器信息', 'varchar(100)', 'String', 'loginBrowser', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 13, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (107, 7, 'result', '结果(0.成功 1.失败)', 'tinyint', 'Integer', 'result', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 14, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (108, 7, 'create_by', '创建者', 'varchar(64)', 'String', 'createBy', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 15, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (109, 7, 'create_time', '创建时间', 'datetime', 'Date', 'createTime', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 16, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (110, 7, 'update_by', '更新者', 'varchar(64)', 'String', 'updateBy', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'input', '', 17, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (111, 7, 'update_time', '更新时间', 'datetime', 'Date', 'updateTime', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 18, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (112, 7, 'remark', '备注', 'varchar(500)', 'String', 'remark', '0', '0', '0', '1', '1', '1', NULL, 'EQ', 'textarea', '', 19, 'admin', '2024-10-15 16:40:47', '', '2024-10-15 16:43:18'); +INSERT INTO `gen_table_column` VALUES (113, 8, 'id', '主键id', 'bigint', 'Long', 'id', '1', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (114, 8, 'currency_type', '币种(字典ff_currency)', 'varchar(10)', 'String', 'currencyType', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'select', 'ff_currency', 2, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (115, 8, 'member_account', '会员账号', 'varchar(16)', 'String', 'memberAccount', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 3, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (116, 8, 'real_name', '会员姓名', 'varchar(50)', 'String', 'realName', '0', '0', '0', '1', '1', '1', '1', 'LIKE', 'input', '', 4, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (117, 8, 'password', '账号密码', 'varchar(100)', 'String', 'password', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 5, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (118, 8, 'withdraw_password', '提现密码', 'varchar(100)', 'String', 'withdrawPassword', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 6, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (119, 8, 'status', '账号状态(0正常 1手动冻结 2异常冻结 3禁止领取优惠 4禁止提现 5黑名单 6停用 7禁止进入游戏 8自我禁止-限制游戏 9自我禁止-限制参与优惠 10自我禁止-限制登录)', 'char(1)', 'String', 'status', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'radio', '', 7, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (120, 8, 'vip_id', 'vip id', 'bigint', 'Long', 'vipId', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (121, 8, 'vip_name', 'vip等级名称', 'varchar(255)', 'String', 'vipName', '0', '0', '0', '1', '1', '1', '1', 'LIKE', 'input', '', 9, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (122, 8, 'level_id', '会员层级id', 'bigint', 'Long', 'levelId', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 10, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (123, 8, 'level_name', '层级名称', 'varchar(24)', 'String', 'levelName', '0', '0', '0', '1', '1', '1', '1', 'LIKE', 'input', '', 11, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (124, 8, 'label_id', '会员标签id', 'bigint', 'Long', 'labelId', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 12, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (125, 8, 'label_name', '标签名称', 'varchar(16)', 'String', 'labelName', '0', '0', '0', '1', '1', '1', '1', 'LIKE', 'input', '', 13, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (126, 8, 'agent_id', '上级代理id', 'bigint', 'Long', 'agentId', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 14, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (127, 8, 'agent_account', '上级代理账号', 'varchar(255)', 'String', 'agentAccount', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 15, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (128, 8, 'channel\n_id', '渠道id(注册来源)', 'bigint', 'Long', 'channel\nId', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 16, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (129, 8, 'channel_name', '渠道名称(注册来源)', 'varchar(255)', 'String', 'channelName', '0', '0', '0', '1', '1', '1', '1', 'LIKE', 'input', '', 17, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (130, 8, 'registe_way', '注册方式(字典ff_registe_way)', 'varchar(10)', 'String', 'registeWay', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', 'ff_registe_way', 18, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (131, 8, 'registe_time', '注册时间', 'datetime', 'Date', 'registeTime', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 19, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (132, 8, 'registe_ip', '注册IP', 'varchar(128)', 'String', 'registeIp', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 20, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (133, 8, 'registe_ip_city', '注册ip的城市', 'varchar(100)', 'String', 'registeIpCity', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 21, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (134, 8, 'registe_domain', '注册域名', 'varchar(128)', 'String', 'registeDomain', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 22, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (135, 8, 'registe_device_type', '注册设备类型(字典ff_device_type)', 'varchar(100)', 'String', 'registeDeviceType', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', 'ff_device_type', 23, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (136, 8, 'registe_device_num', '注册设备号', 'varchar(100)', 'String', 'registeDeviceNum', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 24, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (137, 8, 'registe_browser', '注册浏览器信息', 'varchar(100)', 'String', 'registeBrowser', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 25, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (138, 8, 'registe_url', '注册链接url', 'varchar(255)', 'String', 'registeUrl', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 26, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (139, 8, 'registe_fingerprint', '注册浏览器指纹', 'varchar(255)', 'String', 'registeFingerprint', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 27, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (140, 8, 'sex', '男:1 女:2', 'char(1)', 'String', 'sex', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', '', 28, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (141, 8, 'birthday', '生日', 'date', 'Date', 'birthday', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 29, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (142, 8, 'area_code', '手机号区号', 'varchar(10)', 'String', 'areaCode', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 30, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (143, 8, 'phone_number', '手机号', 'varchar(20)', 'String', 'phoneNumber', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 31, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (144, 8, 'first_charge_amount', '首充金额', 'decimal(10,2)', 'BigDecimal', 'firstChargeAmount', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 32, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (145, 8, 'first_charge_time', '首充时间', 'datetime', 'Date', 'firstChargeTime', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 33, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (146, 8, 'last_login_date', '上次登录时间', 'datetime', 'Date', 'lastLoginDate', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 34, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (147, 8, 'last_login_ip', '上次登录IP', 'varchar(128)', 'String', 'lastLoginIp', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 35, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (148, 8, 'login_date', '最后登录时间', 'datetime', 'Date', 'loginDate', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 36, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (149, 8, 'login_ip', '最后登录IP', 'varchar(128)', 'String', 'loginIp', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 37, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (150, 8, 'login_ip_city', '最后登录ip的城市', 'varchar(100)', 'String', 'loginIpCity', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 38, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (151, 8, 'login_domain', '最后登录域名', 'varchar(128)', 'String', 'loginDomain', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 39, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (152, 8, 'login_device_type', '最后登录设备类型(字典ff_device_type)', 'varchar(100)', 'String', 'loginDeviceType', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', 'ff_device_type', 40, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (153, 8, 'login_device_num', '最后登录设备号', 'varchar(100)', 'String', 'loginDeviceNum', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 41, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (154, 8, 'login_browser', '最后登录浏览器信息', 'varchar(100)', 'String', 'loginBrowser', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 42, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (155, 8, 'login_fingerprint', '最后登录浏览器指纹', 'varchar(255)', 'String', 'loginFingerprint', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 43, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (156, 8, 'verify_way', '验证方式(字典ff_verify_way)', 'varchar(10)', 'String', 'verifyWay', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', 'ff_verify_way', 44, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (157, 8, 'email', '会员邮箱', 'varchar(50)', 'String', 'email', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 45, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (158, 8, 'face_book_account', 'facebook账号', 'varchar(50)', 'String', 'faceBookAccount', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 46, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (159, 8, 'telegram_account', 'telegram账号', 'varchar(50)', 'String', 'telegramAccount', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 47, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (160, 8, 'whatsapp_account', 'whatsapp账号', 'varchar(50)', 'String', 'whatsappAccount', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 48, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (161, 8, 'zalo_account', 'zalo账号', 'varchar(50)', 'String', 'zaloAccount', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 49, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (162, 8, 'create_by', '创建者', 'varchar(64)', 'String', 'createBy', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 50, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (163, 8, 'create_time', '创建时间', 'datetime', 'Date', 'createTime', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 51, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (164, 8, 'update_by', '更新者', 'varchar(64)', 'String', 'updateBy', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'input', '', 52, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (165, 8, 'update_time', '更新时间', 'datetime', 'Date', 'updateTime', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 53, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (166, 8, 'remark', '会员备注', 'varchar(500)', 'String', 'remark', '0', '0', '0', '1', '1', '1', NULL, 'EQ', 'textarea', '', 54, 'admin', '2024-10-15 16:48:54', '', '2024-10-15 16:53:42'); +INSERT INTO `gen_table_column` VALUES (167, 6, 'set_type', '设置类型(0.日俸禄 1.周俸禄 2.月俸禄 3.日/周/月 公共设置 4.其他设置(包含保级、奖励开关))', 'tinyint', 'Integer', 'setType', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', '', 4, '', '2024-10-16 09:59:34', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (168, 6, 'rule_type', '规则类型 0.自定义 1.系统翻译', 'tinyint', 'Integer', 'ruleType', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', '', 18, '', '2024-10-16 10:24:43', '', '2024-10-16 10:25:23'); +INSERT INTO `gen_table_column` VALUES (169, 4, 'day_draw_top', '每日提现金额上限(0 表示不限制)', 'decimal(10,2)', 'BigDecimal', 'dayDrawTop', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, '', '2024-10-16 17:01:49', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (170, 4, 'day_draw_count_top', '每日提现笔数上限(0 表示不限制)', 'int', 'Integer', 'dayDrawCountTop', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, '', '2024-10-16 17:01:49', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (171, 4, 'day_service_fee_free_count', '每日免手续费笔数', 'int', 'Integer', 'dayServiceFeeFreeCount', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 9, '', '2024-10-16 17:01:49', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (235, 4, 'member_count', '会员人数', 'bigint', 'Long', 'memberCount', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 25, '', '2024-10-17 14:56:08', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (236, 4, 'member_update_time', '会员人数更新时间', 'datetime', 'Date', 'memberUpdateTime', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 26, '', '2024-10-17 14:56:08', '', '2024-10-17 14:56:46'); +INSERT INTO `gen_table_column` VALUES (237, 12, 'id', '主键id', 'bigint', 'Long', 'id', '1', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (238, 12, 'currency_code', '币种编码', 'varchar(50)', 'String', 'currencyCode', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 2, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (239, 12, 'market_currency_code', '市场币种编码', 'varchar(50)', 'String', 'marketCurrencyCode', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 3, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (240, 12, 'currency_sign', '币种符号', 'varchar(50)', 'String', 'currencySign', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (241, 12, 'game_rate', '游戏汇率', 'decimal(10,2)', 'BigDecimal', 'gameRate', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 5, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (242, 12, 'currency_type', '币种类型(字典ff_currency)', 'varchar(10)', 'String', 'currencyType', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', 'ff_currency', 6, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (243, 12, 'currency_aisle', '币种通道', 'varchar(50)', 'String', 'currencyAisle', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (244, 12, 'currency_display', '币种展示内容', 'varchar(100)', 'String', 'currencyDisplay', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (245, 12, 'currency_name', '币种名称', 'varchar(100)', 'String', 'currencyName', '0', '0', '0', '1', '1', '1', '1', 'LIKE', 'input', '', 9, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (246, 12, 'full_name', '币种全称', 'varchar(100)', 'String', 'fullName', '0', '0', '0', '1', '1', '1', '1', 'LIKE', 'input', '', 10, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (247, 12, 'create_by', '创建者', 'varchar(64)', 'String', 'createBy', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 11, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (248, 12, 'create_time', '创建时间', 'datetime', 'Date', 'createTime', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 12, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (249, 12, 'update_by', '更新者', 'varchar(64)', 'String', 'updateBy', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'input', '', 13, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (250, 12, 'update_time', '更新时间', 'datetime', 'Date', 'updateTime', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 14, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); +INSERT INTO `gen_table_column` VALUES (251, 12, 'remark', '描述', 'varchar(500)', 'String', 'remark', '0', '0', '0', '1', '1', '1', NULL, 'EQ', 'textarea', '', 15, 'admin', '2024-10-17 16:30:04', '', '2024-10-17 16:32:08'); + +-- ---------------------------- +-- Table structure for qrtz_blob_triggers +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_blob_triggers`; +CREATE TABLE `qrtz_blob_triggers` ( + `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称', + `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键', + `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键', + `blob_data` blob NULL COMMENT '存放持久化Trigger对象', + PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE, + CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'Blob类型的触发器表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_blob_triggers +-- ---------------------------- + +-- ---------------------------- +-- Table structure for qrtz_calendars +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_calendars`; +CREATE TABLE `qrtz_calendars` ( + `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称', + `calendar_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '日历名称', + `calendar` blob NOT NULL COMMENT '存放持久化calendar对象', + PRIMARY KEY (`sched_name`, `calendar_name`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '日历信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_calendars +-- ---------------------------- + +-- ---------------------------- +-- Table structure for qrtz_cron_triggers +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_cron_triggers`; +CREATE TABLE `qrtz_cron_triggers` ( + `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称', + `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键', + `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键', + `cron_expression` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'cron表达式', + `time_zone_id` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '时区', + PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE, + CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'Cron类型的触发器表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_cron_triggers +-- ---------------------------- + +-- ---------------------------- +-- Table structure for qrtz_fired_triggers +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_fired_triggers`; +CREATE TABLE `qrtz_fired_triggers` ( + `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称', + `entry_id` varchar(95) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度器实例id', + `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键', + `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键', + `instance_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度器实例名', + `fired_time` bigint NOT NULL COMMENT '触发的时间', + `sched_time` bigint NOT NULL COMMENT '定时器制定的时间', + `priority` int NOT NULL COMMENT '优先级', + `state` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '状态', + `job_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '任务名称', + `job_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '任务组名', + `is_nonconcurrent` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否并发', + `requests_recovery` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否接受恢复执行', + PRIMARY KEY (`sched_name`, `entry_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '已触发的触发器表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_fired_triggers +-- ---------------------------- + +-- ---------------------------- +-- Table structure for qrtz_job_details +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_job_details`; +CREATE TABLE `qrtz_job_details` ( + `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称', + `job_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务名称', + `job_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务组名', + `description` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '相关介绍', + `job_class_name` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '执行任务类名称', + `is_durable` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '是否持久化', + `is_nonconcurrent` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '是否并发', + `is_update_data` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '是否更新数据', + `requests_recovery` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '是否接受恢复执行', + `job_data` blob NULL COMMENT '存放持久化job对象', + PRIMARY KEY (`sched_name`, `job_name`, `job_group`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务详细信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_job_details +-- ---------------------------- + +-- ---------------------------- +-- Table structure for qrtz_locks +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_locks`; +CREATE TABLE `qrtz_locks` ( + `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称', + `lock_name` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '悲观锁名称', + PRIMARY KEY (`sched_name`, `lock_name`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '存储的悲观锁信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_locks +-- ---------------------------- + +-- ---------------------------- +-- Table structure for qrtz_paused_trigger_grps +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_paused_trigger_grps`; +CREATE TABLE `qrtz_paused_trigger_grps` ( + `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称', + `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键', + PRIMARY KEY (`sched_name`, `trigger_group`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '暂停的触发器表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_paused_trigger_grps +-- ---------------------------- + +-- ---------------------------- +-- Table structure for qrtz_scheduler_state +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_scheduler_state`; +CREATE TABLE `qrtz_scheduler_state` ( + `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称', + `instance_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '实例名称', + `last_checkin_time` bigint NOT NULL COMMENT '上次检查时间', + `checkin_interval` bigint NOT NULL COMMENT '检查间隔时间', + PRIMARY KEY (`sched_name`, `instance_name`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '调度器状态表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_scheduler_state +-- ---------------------------- + +-- ---------------------------- +-- Table structure for qrtz_simple_triggers +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_simple_triggers`; +CREATE TABLE `qrtz_simple_triggers` ( + `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称', + `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键', + `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键', + `repeat_count` bigint NOT NULL COMMENT '重复的次数统计', + `repeat_interval` bigint NOT NULL COMMENT '重复的间隔时间', + `times_triggered` bigint NOT NULL COMMENT '已经触发的次数', + PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE, + CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '简单触发器的信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_simple_triggers +-- ---------------------------- + +-- ---------------------------- +-- Table structure for qrtz_simprop_triggers +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_simprop_triggers`; +CREATE TABLE `qrtz_simprop_triggers` ( + `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称', + `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键', + `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键', + `str_prop_1` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'String类型的trigger的第一个参数', + `str_prop_2` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'String类型的trigger的第二个参数', + `str_prop_3` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'String类型的trigger的第三个参数', + `int_prop_1` int NULL DEFAULT NULL COMMENT 'int类型的trigger的第一个参数', + `int_prop_2` int NULL DEFAULT NULL COMMENT 'int类型的trigger的第二个参数', + `long_prop_1` bigint NULL DEFAULT NULL COMMENT 'long类型的trigger的第一个参数', + `long_prop_2` bigint NULL DEFAULT NULL COMMENT 'long类型的trigger的第二个参数', + `dec_prop_1` decimal(13, 4) NULL DEFAULT NULL COMMENT 'decimal类型的trigger的第一个参数', + `dec_prop_2` decimal(13, 4) NULL DEFAULT NULL COMMENT 'decimal类型的trigger的第二个参数', + `bool_prop_1` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'Boolean类型的trigger的第一个参数', + `bool_prop_2` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'Boolean类型的trigger的第二个参数', + PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE, + CONSTRAINT `qrtz_simprop_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '同步机制的行锁表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_simprop_triggers +-- ---------------------------- + +-- ---------------------------- +-- Table structure for qrtz_triggers +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_triggers`; +CREATE TABLE `qrtz_triggers` ( + `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称', + `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '触发器的名字', + `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '触发器所属组的名字', + `job_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_job_details表job_name的外键', + `job_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_job_details表job_group的外键', + `description` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '相关介绍', + `next_fire_time` bigint NULL DEFAULT NULL COMMENT '上一次触发时间(毫秒)', + `prev_fire_time` bigint NULL DEFAULT NULL COMMENT '下一次触发时间(默认为-1表示不触发)', + `priority` int NULL DEFAULT NULL COMMENT '优先级', + `trigger_state` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '触发器状态', + `trigger_type` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '触发器的类型', + `start_time` bigint NOT NULL COMMENT '开始时间', + `end_time` bigint NULL DEFAULT NULL COMMENT '结束时间', + `calendar_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '日程表名称', + `misfire_instr` smallint NULL DEFAULT NULL COMMENT '补偿执行的策略', + `job_data` blob NULL COMMENT '存放持久化job对象', + PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE, + INDEX `sched_name`(`sched_name`, `job_name`, `job_group`) USING BTREE, + CONSTRAINT `qrtz_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `job_name`, `job_group`) REFERENCES `qrtz_job_details` (`sched_name`, `job_name`, `job_group`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '触发器详细信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_triggers +-- ---------------------------- + +-- ---------------------------- +-- Table structure for sys_config +-- ---------------------------- +DROP TABLE IF EXISTS `sys_config`; +CREATE TABLE `sys_config` ( + `config_id` int NOT NULL AUTO_INCREMENT COMMENT '参数主键', + `config_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '参数名称', + `config_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '参数键名', + `config_value` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '参数键值', + `config_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'N' COMMENT '系统内置(Y是 N否)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`config_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '参数配置表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_config +-- ---------------------------- +INSERT INTO `sys_config` VALUES (1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', '2024-10-09 15:44:02', 'admin', '2024-10-11 15:44:07', '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow'); +INSERT INTO `sys_config` VALUES (2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', '2024-10-09 15:44:02', '', NULL, '初始化密码 123456'); +INSERT INTO `sys_config` VALUES (3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', '2024-10-09 15:44:02', '', NULL, '深色主题theme-dark,浅色主题theme-light'); +INSERT INTO `sys_config` VALUES (4, '账号自助-验证码开关', 'sys.account.captchaEnabled', 'true', 'Y', 'admin', '2024-10-09 15:44:02', '', NULL, '是否开启验证码功能(true开启,false关闭)'); +INSERT INTO `sys_config` VALUES (5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', '2024-10-09 15:44:02', '', NULL, '是否开启注册用户功能(true开启,false关闭)'); +INSERT INTO `sys_config` VALUES (6, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', '2024-10-09 15:44:02', '', NULL, '设置登录IP黑名单限制,多个匹配项以;分隔,支持匹配(*通配、网段)'); + +-- ---------------------------- +-- Table structure for sys_dept +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dept`; +CREATE TABLE `sys_dept` ( + `dept_id` bigint NOT NULL AUTO_INCREMENT COMMENT '部门id', + `parent_id` bigint NULL DEFAULT 0 COMMENT '父部门id', + `ancestors` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '祖级列表', + `dept_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '部门名称', + `order_num` int NULL DEFAULT 0 COMMENT '显示顺序', + `leader` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '负责人', + `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '联系电话', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '邮箱', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '部门状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`dept_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 200 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '部门表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_dept +-- ---------------------------- +INSERT INTO `sys_dept` VALUES (100, 0, '0', 'FF科技', 0, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2024-10-09 15:44:01', '', NULL); +INSERT INTO `sys_dept` VALUES (101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2024-10-09 15:44:01', '', NULL); +INSERT INTO `sys_dept` VALUES (102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2024-10-09 15:44:01', '', NULL); +INSERT INTO `sys_dept` VALUES (103, 101, '0,100,101', '研发部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2024-10-09 15:44:01', '', NULL); +INSERT INTO `sys_dept` VALUES (104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2024-10-09 15:44:01', '', NULL); +INSERT INTO `sys_dept` VALUES (105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2024-10-09 15:44:01', '', NULL); +INSERT INTO `sys_dept` VALUES (106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2024-10-09 15:44:01', '', NULL); +INSERT INTO `sys_dept` VALUES (107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2024-10-09 15:44:01', '', NULL); +INSERT INTO `sys_dept` VALUES (108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2024-10-09 15:44:01', '', NULL); +INSERT INTO `sys_dept` VALUES (109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2024-10-09 15:44:01', '', NULL); + +-- ---------------------------- +-- Table structure for sys_dict_data +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_data`; +CREATE TABLE `sys_dict_data` ( + `dict_code` bigint NOT NULL AUTO_INCREMENT COMMENT '字典编码', + `dict_sort` int NULL DEFAULT 0 COMMENT '字典排序', + `dict_label` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典标签', + `dict_value` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典键值', + `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典类型', + `css_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '样式属性(其他样式扩展)', + `list_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '表格回显样式', + `is_default` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'N' COMMENT '是否默认(Y是 N否)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '状态(0正常 1停用)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`dict_code`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 193 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '字典数据表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_dict_data +-- ---------------------------- +INSERT INTO `sys_dict_data` VALUES (1, 1, '男', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '性别男'); +INSERT INTO `sys_dict_data` VALUES (2, 2, '女', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '性别女'); +INSERT INTO `sys_dict_data` VALUES (3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '性别未知'); +INSERT INTO `sys_dict_data` VALUES (4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '显示菜单'); +INSERT INTO `sys_dict_data` VALUES (5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '隐藏菜单'); +INSERT INTO `sys_dict_data` VALUES (6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '正常状态'); +INSERT INTO `sys_dict_data` VALUES (7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '停用状态'); +INSERT INTO `sys_dict_data` VALUES (8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '正常状态'); +INSERT INTO `sys_dict_data` VALUES (9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '停用状态'); +INSERT INTO `sys_dict_data` VALUES (10, 1, '默认', 'DEFAULT', 'sys_job_group', '', '', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '默认分组'); +INSERT INTO `sys_dict_data` VALUES (11, 2, '系统', 'SYSTEM', 'sys_job_group', '', '', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '系统分组'); +INSERT INTO `sys_dict_data` VALUES (12, 1, '是', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '系统默认是'); +INSERT INTO `sys_dict_data` VALUES (13, 2, '否', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '系统默认否'); +INSERT INTO `sys_dict_data` VALUES (14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '通知'); +INSERT INTO `sys_dict_data` VALUES (15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '公告'); +INSERT INTO `sys_dict_data` VALUES (16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '正常状态'); +INSERT INTO `sys_dict_data` VALUES (17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '关闭状态'); +INSERT INTO `sys_dict_data` VALUES (18, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '其他操作'); +INSERT INTO `sys_dict_data` VALUES (19, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '新增操作'); +INSERT INTO `sys_dict_data` VALUES (20, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '修改操作'); +INSERT INTO `sys_dict_data` VALUES (21, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '删除操作'); +INSERT INTO `sys_dict_data` VALUES (22, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '授权操作'); +INSERT INTO `sys_dict_data` VALUES (23, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '导出操作'); +INSERT INTO `sys_dict_data` VALUES (24, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '导入操作'); +INSERT INTO `sys_dict_data` VALUES (25, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '强退操作'); +INSERT INTO `sys_dict_data` VALUES (26, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '生成操作'); +INSERT INTO `sys_dict_data` VALUES (27, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '清空操作'); +INSERT INTO `sys_dict_data` VALUES (28, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '正常状态'); +INSERT INTO `sys_dict_data` VALUES (29, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '停用状态'); +INSERT INTO `sys_dict_data` VALUES (100, 13, '#2bfa38', '#2bfa38', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:34:10', 'admin', '2024-10-14 11:02:16', '绿色'); +INSERT INTO `sys_dict_data` VALUES (101, 11, '#f59a23', '#f59a23', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:35:59', 'admin', '2024-10-14 11:03:15', '橙色'); +INSERT INTO `sys_dict_data` VALUES (102, 10, '#db301a', '#db301a', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:36:29', 'admin', '2024-10-14 11:03:18', '红色'); +INSERT INTO `sys_dict_data` VALUES (103, 9, '#4d42cf', '#4d42cf', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:37:18', 'admin', '2024-10-14 11:03:22', '深蓝'); +INSERT INTO `sys_dict_data` VALUES (104, 8, '#1677fd', '#1677fd', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:38:28', 'admin', '2024-10-14 11:03:27', '淡蓝'); +INSERT INTO `sys_dict_data` VALUES (105, 7, '#000000', '#000000', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:39:11', 'admin', '2024-10-14 11:03:31', '黑色'); +INSERT INTO `sys_dict_data` VALUES (106, 6, '#4cb5ff', '#4cb5ff', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:40:23', 'admin', '2024-10-14 11:03:35', '浅蓝'); +INSERT INTO `sys_dict_data` VALUES (107, 5, '#874ce8', '#874ce8', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:41:18', 'admin', '2024-10-14 11:03:39', '深紫'); +INSERT INTO `sys_dict_data` VALUES (108, 4, '#cd55ff', '#cd55ff', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:41:52', 'admin', '2024-10-14 11:03:43', '淡紫'); +INSERT INTO `sys_dict_data` VALUES (109, 3, '#26a17b', '#26a17b', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:42:29', 'admin', '2024-10-14 11:03:47', '墨绿'); +INSERT INTO `sys_dict_data` VALUES (110, 2, '#ea4e3d', '#ea4e3d', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:43:13', 'admin', '2024-10-14 11:03:51', '浅红'); +INSERT INTO `sys_dict_data` VALUES (111, 12, '#ff7097', '#ff7097', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:44:13', 'admin', '2024-10-14 11:03:08', '粉色 '); +INSERT INTO `sys_dict_data` VALUES (112, 0, 'USDT', '1', 'ff_currency', NULL, 'default', 'N', '0', 'admin', '2024-10-12 10:55:47', 'admin', '2024-10-17 16:55:09', 'USDT(USDT)'); +INSERT INTO `sys_dict_data` VALUES (113, 0, 'VND', '2', 'ff_currency', NULL, 'default', 'N', '0', 'admin', '2024-10-12 10:56:28', 'admin', '2024-10-17 16:55:16', '越南盾(VND1000:1)'); +INSERT INTO `sys_dict_data` VALUES (118, 0, '账号注册', '1', 'ff_registe_way', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:07:55', '', NULL, '账号注册'); +INSERT INTO `sys_dict_data` VALUES (119, 0, 'FaceBook注册', '2', 'ff_registe_way', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:08:21', '', NULL, 'FaceBook注册'); +INSERT INTO `sys_dict_data` VALUES (120, 0, 'APP-iOS', 'APP-iOS', 'ff_device_type', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:24:29', 'admin', '2024-10-15 09:35:10', 'APP-iOS'); +INSERT INTO `sys_dict_data` VALUES (121, 0, 'H5-iOS', 'H5-iOS', 'ff_device_type', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:25:18', 'admin', '2024-10-15 09:35:17', 'H5-iOS'); +INSERT INTO `sys_dict_data` VALUES (122, 0, 'APP-Android', 'APP-Android', 'ff_device_type', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:25:43', 'admin', '2024-10-15 09:35:22', 'APP-Android'); +INSERT INTO `sys_dict_data` VALUES (123, 0, 'H5-Android', 'H5-Android', 'ff_device_type', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:26:09', 'admin', '2024-10-15 09:35:27', 'H5-Android'); +INSERT INTO `sys_dict_data` VALUES (124, 0, 'PC-Windows', 'PC-Windows', 'ff_device_type', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:26:41', 'admin', '2024-10-15 09:35:33', 'PC-Windows'); +INSERT INTO `sys_dict_data` VALUES (125, 0, 'PC-Mac', 'PC-Mac', 'ff_device_type', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:27:06', 'admin', '2024-10-15 09:35:38', 'PC-Mac'); +INSERT INTO `sys_dict_data` VALUES (126, 0, '无验证', '1', 'ff_verify_way', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:42:17', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (127, 0, '短信验证', '2', 'ff_verify_way', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:42:31', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (128, 0, '谷歌验证', '3', 'ff_verify_way', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:42:43', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (130, 1, '无图标', 'NO_ICON', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-14 11:04:21', 'admin', '2024-10-14 11:04:26', NULL); +INSERT INTO `sys_dict_data` VALUES (131, 1, 'color1', '1', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:25:07', 'admin', '2024-10-14 15:51:18', NULL); +INSERT INTO `sys_dict_data` VALUES (132, 2, 'color2', '2', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:26:03', 'admin', '2024-10-14 15:51:30', NULL); +INSERT INTO `sys_dict_data` VALUES (133, 3, 'color3', '3', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:26:37', 'admin', '2024-10-14 15:51:40', NULL); +INSERT INTO `sys_dict_data` VALUES (134, 4, 'color4', '4', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:27:26', 'admin', '2024-10-14 15:51:49', NULL); +INSERT INTO `sys_dict_data` VALUES (135, 5, 'color5', '5', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:28:09', 'admin', '2024-10-14 15:51:58', NULL); +INSERT INTO `sys_dict_data` VALUES (136, 6, 'color6', '6', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:29:18', 'admin', '2024-10-14 15:52:06', NULL); +INSERT INTO `sys_dict_data` VALUES (137, 7, 'color7', '7', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:39:22', 'admin', '2024-10-14 15:52:13', NULL); +INSERT INTO `sys_dict_data` VALUES (138, 8, 'color8', '8', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:39:50', 'admin', '2024-10-14 15:52:33', NULL); +INSERT INTO `sys_dict_data` VALUES (139, 9, 'color9', '9', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:40:45', 'admin', '2024-10-14 15:52:42', NULL); +INSERT INTO `sys_dict_data` VALUES (140, 10, 'color10', '10', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:41:05', 'admin', '2024-10-14 15:52:53', NULL); +INSERT INTO `sys_dict_data` VALUES (141, 0, 'style_0', '0', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:42:52', 'admin', '2024-10-14 15:49:54', NULL); +INSERT INTO `sys_dict_data` VALUES (142, 1, 'style_1', '1', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:43:25', 'admin', '2024-10-14 15:49:59', NULL); +INSERT INTO `sys_dict_data` VALUES (143, 2, 'style_2', '2', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:44:15', 'admin', '2024-10-14 15:50:04', NULL); +INSERT INTO `sys_dict_data` VALUES (144, 3, 'style_3', '3', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:44:32', 'admin', '2024-10-14 15:50:08', NULL); +INSERT INTO `sys_dict_data` VALUES (145, 4, 'style_4', '4', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:45:13', 'admin', '2024-10-14 15:50:12', NULL); +INSERT INTO `sys_dict_data` VALUES (146, 5, 'style_5', '5', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:45:33', 'admin', '2024-10-14 15:50:16', NULL); +INSERT INTO `sys_dict_data` VALUES (147, 6, 'style_6', '6', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:46:39', 'admin', '2024-10-14 15:50:20', NULL); +INSERT INTO `sys_dict_data` VALUES (148, 7, 'style_7', '7', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:46:59', 'admin', '2024-10-14 15:50:25', NULL); +INSERT INTO `sys_dict_data` VALUES (149, 8, 'style_8', '8', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:48:13', 'admin', '2024-10-14 15:50:30', NULL); +INSERT INTO `sys_dict_data` VALUES (150, 9, 'style_9', '9', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:48:30', 'admin', '2024-10-14 15:50:35', NULL); +INSERT INTO `sys_dict_data` VALUES (151, 10, 'style_10', '10', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:48:48', 'admin', '2024-10-19 09:55:39', NULL); +INSERT INTO `sys_dict_data` VALUES (152, 1, 'style1', '1', 'ff_vip_icon_parent_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 15:48:20', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (153, 2, 'style2', '2', 'ff_vip_icon_parent_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 15:48:38', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (154, 3, 'style3', '3', 'ff_vip_icon_parent_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 15:48:50', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (155, 4, 'style4', '4', 'ff_vip_icon_parent_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 15:49:01', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (156, 0, '姓名', '姓名', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:42:38', 'admin', '2024-10-15 10:04:41', NULL); +INSERT INTO `sys_dict_data` VALUES (157, 1, '手机号', '手机号', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:43:10', 'admin', '2024-10-15 10:04:46', NULL); +INSERT INTO `sys_dict_data` VALUES (158, 2, '账号状态', '账号状态', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:44:34', 'admin', '2024-10-15 10:04:51', NULL); +INSERT INTO `sys_dict_data` VALUES (159, 3, '银行卡', '银行卡', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:45:08', 'admin', '2024-10-15 10:04:55', NULL); +INSERT INTO `sys_dict_data` VALUES (160, 4, '账号密码', '账号密码', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:46:13', 'admin', '2024-10-15 10:05:01', NULL); +INSERT INTO `sys_dict_data` VALUES (161, 5, '忘记密码', '忘记密码', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:48:37', 'admin', '2024-10-15 10:05:06', NULL); +INSERT INTO `sys_dict_data` VALUES (162, 6, '提现密码', '提现密码', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:49:06', 'admin', '2024-10-15 10:05:11', NULL); +INSERT INTO `sys_dict_data` VALUES (163, 7, 'WhatsApp', 'WhatsApp', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:50:30', 'admin', '2024-10-15 10:05:16', NULL); +INSERT INTO `sys_dict_data` VALUES (164, 8, 'Facebook', 'Facebook', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:50:57', 'admin', '2024-10-15 10:05:20', NULL); +INSERT INTO `sys_dict_data` VALUES (165, 9, 'Telegram', 'Telegram', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:51:20', 'admin', '2024-10-15 10:05:24', NULL); +INSERT INTO `sys_dict_data` VALUES (166, 10, 'Zalo', 'Zalo', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:51:40', 'admin', '2024-10-15 10:05:30', NULL); +INSERT INTO `sys_dict_data` VALUES (167, 11, '邮箱地址', '邮箱地址', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:52:30', 'admin', '2024-10-15 10:05:34', NULL); +INSERT INTO `sys_dict_data` VALUES (168, 12, '手势密码', '手势密码', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:52:54', 'admin', '2024-10-15 10:05:38', NULL); +INSERT INTO `sys_dict_data` VALUES (169, 13, '谷歌验证', '谷歌验证', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:53:19', 'admin', '2024-10-15 10:05:43', NULL); +INSERT INTO `sys_dict_data` VALUES (170, 14, '密保问题', '密保问题', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:53:55', 'admin', '2024-10-15 10:05:50', NULL); +INSERT INTO `sys_dict_data` VALUES (171, 15, '会员层级', '会员层级', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:54:29', 'admin', '2024-10-15 10:05:56', NULL); +INSERT INTO `sys_dict_data` VALUES (172, 16, '上级代理', '上级代理', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:55:06', 'admin', '2024-10-15 10:06:01', NULL); +INSERT INTO `sys_dict_data` VALUES (173, 17, '登录', '登录', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:55:25', 'admin', '2024-10-15 10:06:05', NULL); +INSERT INTO `sys_dict_data` VALUES (174, 18, '登出', '登出', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:55:37', 'admin', '2024-10-15 10:06:09', NULL); +INSERT INTO `sys_dict_data` VALUES (175, 19, 'VIP等级', 'VIP等级', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:56:18', 'admin', '2024-10-15 10:06:18', NULL); +INSERT INTO `sys_dict_data` VALUES (176, 0, '无', '无', 'ff_oper_type', NULL, 'default', 'N', '0', 'admin', '2024-10-15 10:11:57', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (177, 1, '新增', '新增', 'ff_oper_type', NULL, 'default', 'N', '0', 'admin', '2024-10-15 10:12:11', 'admin', '2024-10-15 10:12:24', NULL); +INSERT INTO `sys_dict_data` VALUES (178, 2, '修改', '修改', 'ff_oper_type', NULL, 'default', 'N', '0', 'admin', '2024-10-15 10:12:19', 'admin', '2024-10-15 10:12:32', NULL); +INSERT INTO `sys_dict_data` VALUES (179, 0, '资金切换', '0', 'ff_account_change_type', NULL, 'primary', 'N', '0', 'admin', '2024-10-18 13:06:45', 'admin', '2024-10-18 13:07:14', '资金切换'); +INSERT INTO `sys_dict_data` VALUES (180, 1, '会员充值', '1', 'ff_account_change_type', NULL, 'success', 'N', '0', 'admin', '2024-10-18 13:07:08', 'admin', '2024-10-18 13:07:18', '会员充值'); +INSERT INTO `sys_dict_data` VALUES (181, 2, '会员提现', '2', 'ff_account_change_type', NULL, 'info', 'N', '0', 'admin', '2024-10-18 13:07:39', '', NULL, '会员提现'); +INSERT INTO `sys_dict_data` VALUES (182, 3, '银商结算', '3', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:08:22', '', NULL, '银商结算'); +INSERT INTO `sys_dict_data` VALUES (183, 4, '资金修正', '4', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:08:38', 'admin', '2024-10-18 13:17:05', '资金修正'); +INSERT INTO `sys_dict_data` VALUES (184, 5, '活动', '5', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:09:03', '', NULL, '活动'); +INSERT INTO `sys_dict_data` VALUES (185, 6, '返水', '6', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:09:30', 'admin', '2024-10-18 13:09:43', '返水'); +INSERT INTO `sys_dict_data` VALUES (186, 7, '返佣', '7', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:10:02', '', NULL, '返佣'); +INSERT INTO `sys_dict_data` VALUES (187, 8, '任务', '8', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:10:31', 'admin', '2024-10-18 13:10:37', '任务'); +INSERT INTO `sys_dict_data` VALUES (188, 9, 'VIP奖励', '9', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:11:12', '', NULL, 'VIP奖励'); +INSERT INTO `sys_dict_data` VALUES (189, 10, '充值优惠', '10', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:11:31', '', NULL, '充值优惠'); +INSERT INTO `sys_dict_data` VALUES (190, 11, '俱乐部', '11', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:11:48', 'admin', '2024-10-18 13:11:52', '俱乐部'); +INSERT INTO `sys_dict_data` VALUES (191, 12, '奖励', '12', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:12:07', '', NULL, '奖励'); +INSERT INTO `sys_dict_data` VALUES (192, 13, '公积金', '13', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:12:21', '', NULL, '公积金'); + +-- ---------------------------- +-- Table structure for sys_dict_type +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_type`; +CREATE TABLE `sys_dict_type` ( + `dict_id` bigint NOT NULL AUTO_INCREMENT COMMENT '字典主键', + `dict_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典名称', + `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典类型', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '状态(0正常 1停用)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`dict_id`) USING BTREE, + UNIQUE INDEX `dict_type`(`dict_type`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 112 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '字典类型表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_dict_type +-- ---------------------------- +INSERT INTO `sys_dict_type` VALUES (1, '用户性别', 'sys_user_sex', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '用户性别列表'); +INSERT INTO `sys_dict_type` VALUES (2, '菜单状态', 'sys_show_hide', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '菜单状态列表'); +INSERT INTO `sys_dict_type` VALUES (3, '系统开关', 'sys_normal_disable', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '系统开关列表'); +INSERT INTO `sys_dict_type` VALUES (4, '任务状态', 'sys_job_status', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '任务状态列表'); +INSERT INTO `sys_dict_type` VALUES (5, '任务分组', 'sys_job_group', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '任务分组列表'); +INSERT INTO `sys_dict_type` VALUES (6, '系统是否', 'sys_yes_no', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '系统是否列表'); +INSERT INTO `sys_dict_type` VALUES (7, '通知类型', 'sys_notice_type', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '通知类型列表'); +INSERT INTO `sys_dict_type` VALUES (8, '通知状态', 'sys_notice_status', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '通知状态列表'); +INSERT INTO `sys_dict_type` VALUES (9, '操作类型', 'sys_oper_type', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '操作类型列表'); +INSERT INTO `sys_dict_type` VALUES (10, '系统状态', 'sys_common_status', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '登录状态列表'); +INSERT INTO `sys_dict_type` VALUES (100, '会员标签图标', 'ff_member_label_icon', '0', 'admin', '2024-10-12 09:30:11', '', NULL, '会员标签图标'); +INSERT INTO `sys_dict_type` VALUES (101, '币种', 'ff_currency', '0', 'admin', '2024-10-12 10:54:26', '', NULL, '币种'); +INSERT INTO `sys_dict_type` VALUES (103, '注册方式', 'ff_registe_way', '0', 'admin', '2024-10-12 16:07:28', '', NULL, '注册方式'); +INSERT INTO `sys_dict_type` VALUES (104, '设备类型', 'ff_device_type', '0', 'admin', '2024-10-12 16:23:28', '', NULL, '设备类型'); +INSERT INTO `sys_dict_type` VALUES (105, '会员验证方式', 'ff_verify_way', '0', 'admin', '2024-10-12 16:42:00', '', NULL, '会员验证方式'); +INSERT INTO `sys_dict_type` VALUES (106, 'vip等级图标颜色', 'ff_vip_icon_color', '0', 'admin', '2024-10-14 13:20:37', 'admin', '2024-10-14 15:55:14', 'vip等级图标颜色'); +INSERT INTO `sys_dict_type` VALUES (107, 'vip等级图标样式', 'ff_vip_icon_style', '0', 'admin', '2024-10-14 13:42:14', 'admin', '2024-10-14 15:55:09', 'vip等级图标样式'); +INSERT INTO `sys_dict_type` VALUES (108, 'vip等级图标父样式', 'ff_vip_icon_parent_style', '0', 'admin', '2024-10-14 15:44:59', 'admin', '2024-10-14 15:54:59', 'vip等级图标父样式'); +INSERT INTO `sys_dict_type` VALUES (109, '会员日志操作项目', 'ff_log_operproject', '0', 'admin', '2024-10-15 09:41:00', 'admin', '2024-10-15 10:09:51', '会员日志操作项目'); +INSERT INTO `sys_dict_type` VALUES (110, '会员操作类型', 'ff_oper_type', '0', 'admin', '2024-10-15 10:10:56', '', NULL, '会员操作类型'); +INSERT INTO `sys_dict_type` VALUES (111, '会员账户变动大类', 'ff_account_change_type', '0', 'admin', '2024-10-18 13:03:44', '', NULL, '会员账户变动大类'); + +-- ---------------------------- +-- Table structure for sys_job +-- ---------------------------- +DROP TABLE IF EXISTS `sys_job`; +CREATE TABLE `sys_job` ( + `job_id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务ID', + `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '任务名称', + `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'DEFAULT' COMMENT '任务组名', + `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调用目标字符串', + `cron_expression` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT 'cron执行表达式', + `misfire_policy` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '3' COMMENT '计划执行错误策略(1立即执行 2执行一次 3放弃执行)', + `concurrent` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '1' COMMENT '是否并发执行(0允许 1禁止)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '状态(0正常 1暂停)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '备注信息', + PRIMARY KEY (`job_id`, `job_name`, `job_group`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 101 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '定时任务调度表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_job +-- ---------------------------- +INSERT INTO `sys_job` VALUES (1, '系统默认(无参)', 'DEFAULT', 'ryTask.ryNoParams', '0/10 * * * * ?', '3', '1', '1', 'admin', '2024-10-09 15:44:02', '', NULL, ''); +INSERT INTO `sys_job` VALUES (2, '系统默认(有参)', 'DEFAULT', 'ryTask.ryParams(\'ry\')', '0/15 * * * * ?', '3', '1', '1', 'admin', '2024-10-09 15:44:02', '', NULL, ''); +INSERT INTO `sys_job` VALUES (3, '系统默认(多参)', 'DEFAULT', 'ryTask.ryMultipleParams(\'ry\', true, 2000L, 316.50D, 100)', '0/20 * * * * ?', '3', '1', '1', 'admin', '2024-10-09 15:44:02', '', NULL, ''); +INSERT INTO `sys_job` VALUES (100, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', '0 0/30 * ? * *', '1', '1', '0', 'admin', '2024-10-17 15:29:44', '', '2024-10-17 15:29:48', ''); + +-- ---------------------------- +-- Table structure for sys_job_log +-- ---------------------------- +DROP TABLE IF EXISTS `sys_job_log`; +CREATE TABLE `sys_job_log` ( + `job_log_id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务日志ID', + `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务名称', + `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务组名', + `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调用目标字符串', + `job_message` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '日志信息', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '执行状态(0正常 1失败)', + `exception_info` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '异常信息', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`job_log_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 106 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '定时任务调度日志表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_job_log +-- ---------------------------- +INSERT INTO `sys_job_log` VALUES (1, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:12毫秒', '0', '', '2024-10-17 15:29:51'); +INSERT INTO `sys_job_log` VALUES (2, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:12毫秒', '0', '', '2024-10-17 15:30:00'); +INSERT INTO `sys_job_log` VALUES (3, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:23毫秒', '0', '', '2024-10-17 16:00:00'); +INSERT INTO `sys_job_log` VALUES (4, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:8毫秒', '0', '', '2024-10-17 16:30:00'); +INSERT INTO `sys_job_log` VALUES (5, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:33毫秒', '0', '', '2024-10-17 17:00:00'); +INSERT INTO `sys_job_log` VALUES (6, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:6毫秒', '0', '', '2024-10-17 17:30:00'); +INSERT INTO `sys_job_log` VALUES (7, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:26毫秒', '0', '', '2024-10-17 18:00:00'); +INSERT INTO `sys_job_log` VALUES (8, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:420毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (9, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:32毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (10, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:11毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (11, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:6毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (12, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:11毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (13, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:11毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (14, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:18毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (15, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:11毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (16, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:10毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (17, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:8毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (18, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:10毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (19, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:8毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (20, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:11毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (21, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:8毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (22, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:6毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (23, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:5毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (24, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:8毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (25, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:5毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (26, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:5毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (27, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:6毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (28, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:6毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (29, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:5毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (30, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:4毫秒', '0', '', '2024-10-18 09:01:05'); +INSERT INTO `sys_job_log` VALUES (31, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:4毫秒', '0', '', '2024-10-18 09:01:06'); +INSERT INTO `sys_job_log` VALUES (32, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:9毫秒', '0', '', '2024-10-18 09:01:06'); +INSERT INTO `sys_job_log` VALUES (33, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:8毫秒', '0', '', '2024-10-18 09:01:06'); +INSERT INTO `sys_job_log` VALUES (34, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:7毫秒', '0', '', '2024-10-18 09:01:06'); +INSERT INTO `sys_job_log` VALUES (35, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:6毫秒', '0', '', '2024-10-18 09:01:06'); +INSERT INTO `sys_job_log` VALUES (36, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:4毫秒', '0', '', '2024-10-18 09:01:06'); +INSERT INTO `sys_job_log` VALUES (37, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:5毫秒', '0', '', '2024-10-18 09:01:06'); +INSERT INTO `sys_job_log` VALUES (38, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:27毫秒', '0', '', '2024-10-18 09:30:00'); +INSERT INTO `sys_job_log` VALUES (39, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:32毫秒', '0', '', '2024-10-18 10:00:00'); +INSERT INTO `sys_job_log` VALUES (40, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:29毫秒', '0', '', '2024-10-18 10:30:00'); +INSERT INTO `sys_job_log` VALUES (41, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:31毫秒', '0', '', '2024-10-18 11:00:00'); +INSERT INTO `sys_job_log` VALUES (42, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:34毫秒', '0', '', '2024-10-18 11:30:00'); +INSERT INTO `sys_job_log` VALUES (43, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:33毫秒', '0', '', '2024-10-18 12:00:00'); +INSERT INTO `sys_job_log` VALUES (44, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:30毫秒', '0', '', '2024-10-18 13:01:32'); +INSERT INTO `sys_job_log` VALUES (45, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:5毫秒', '0', '', '2024-10-18 13:01:32'); +INSERT INTO `sys_job_log` VALUES (46, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:35毫秒', '0', '', '2024-10-18 13:30:00'); +INSERT INTO `sys_job_log` VALUES (47, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:32毫秒', '0', '', '2024-10-18 14:00:00'); +INSERT INTO `sys_job_log` VALUES (48, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:36毫秒', '0', '', '2024-10-18 14:30:00'); +INSERT INTO `sys_job_log` VALUES (49, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:36毫秒', '0', '', '2024-10-18 15:00:00'); +INSERT INTO `sys_job_log` VALUES (50, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:34毫秒', '0', '', '2024-10-18 15:30:00'); +INSERT INTO `sys_job_log` VALUES (51, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:29毫秒', '0', '', '2024-10-18 16:00:00'); +INSERT INTO `sys_job_log` VALUES (52, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:31毫秒', '0', '', '2024-10-18 16:30:00'); +INSERT INTO `sys_job_log` VALUES (53, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:22毫秒', '0', '', '2024-10-18 17:00:00'); +INSERT INTO `sys_job_log` VALUES (54, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:32毫秒', '0', '', '2024-10-18 17:30:00'); +INSERT INTO `sys_job_log` VALUES (55, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:11毫秒', '0', '', '2024-10-18 18:00:00'); +INSERT INTO `sys_job_log` VALUES (56, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:20毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (57, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:3毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (58, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:2毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (59, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:2毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (60, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (61, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (62, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (63, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (64, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (65, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:2毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (66, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (67, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (68, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (69, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:2毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (70, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:2毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (71, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:2毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (72, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (73, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:2毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (74, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (75, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (76, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:2毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (77, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:2毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (78, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (79, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (80, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (81, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:2毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (82, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (83, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (84, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (85, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 09:06:49'); +INSERT INTO `sys_job_log` VALUES (86, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:10毫秒', '0', '', '2024-10-19 09:30:00'); +INSERT INTO `sys_job_log` VALUES (87, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:9毫秒', '0', '', '2024-10-19 10:00:00'); +INSERT INTO `sys_job_log` VALUES (88, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:34毫秒', '0', '', '2024-10-19 10:30:00'); +INSERT INTO `sys_job_log` VALUES (89, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:23毫秒', '0', '', '2024-10-19 11:00:00'); +INSERT INTO `sys_job_log` VALUES (90, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:29毫秒', '0', '', '2024-10-19 11:30:00'); +INSERT INTO `sys_job_log` VALUES (91, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:34毫秒', '0', '', '2024-10-19 12:00:00'); +INSERT INTO `sys_job_log` VALUES (92, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:5毫秒', '0', '', '2024-10-19 13:02:42'); +INSERT INTO `sys_job_log` VALUES (93, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:1毫秒', '0', '', '2024-10-19 13:02:42'); +INSERT INTO `sys_job_log` VALUES (94, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:30毫秒', '0', '', '2024-10-19 13:30:00'); +INSERT INTO `sys_job_log` VALUES (95, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:30毫秒', '0', '', '2024-10-19 14:00:00'); +INSERT INTO `sys_job_log` VALUES (96, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:31毫秒', '0', '', '2024-10-19 14:30:00'); +INSERT INTO `sys_job_log` VALUES (97, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:33毫秒', '0', '', '2024-10-19 15:00:00'); +INSERT INTO `sys_job_log` VALUES (98, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:33毫秒', '0', '', '2024-10-19 15:30:00'); +INSERT INTO `sys_job_log` VALUES (99, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:9毫秒', '0', '', '2024-10-19 16:00:00'); +INSERT INTO `sys_job_log` VALUES (100, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:9毫秒', '0', '', '2024-10-19 16:30:00'); +INSERT INTO `sys_job_log` VALUES (101, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:28毫秒', '0', '', '2024-10-19 17:00:00'); +INSERT INTO `sys_job_log` VALUES (102, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:28毫秒', '0', '', '2024-10-19 17:30:00'); +INSERT INTO `sys_job_log` VALUES (103, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:34毫秒', '0', '', '2024-10-19 18:00:00'); +INSERT INTO `sys_job_log` VALUES (104, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:46毫秒', '0', '', '2024-10-21 09:30:00'); +INSERT INTO `sys_job_log` VALUES (105, 'vip等级人数修改', 'SYSTEM', 'memberVipTask.updateMemberVipCount()', 'vip等级人数修改 总共耗时:34毫秒', '0', '', '2024-10-21 10:00:00'); + +-- ---------------------------- +-- Table structure for sys_logininfor +-- ---------------------------- +DROP TABLE IF EXISTS `sys_logininfor`; +CREATE TABLE `sys_logininfor` ( + `info_id` bigint NOT NULL AUTO_INCREMENT COMMENT '访问ID', + `user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '用户账号', + `ipaddr` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '登录IP地址', + `login_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '登录地点', + `browser` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '浏览器类型', + `os` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作系统', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '登录状态(0成功 1失败)', + `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '提示消息', + `login_time` datetime NULL DEFAULT NULL COMMENT '访问时间', + PRIMARY KEY (`info_id`) USING BTREE, + INDEX `idx_sys_logininfor_s`(`status`) USING BTREE, + INDEX `idx_sys_logininfor_lt`(`login_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 201 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统访问记录' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_logininfor +-- ---------------------------- +INSERT INTO `sys_logininfor` VALUES (100, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '1', '验证码错误', '2024-10-09 16:02:10'); +INSERT INTO `sys_logininfor` VALUES (101, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-09 16:02:18'); +INSERT INTO `sys_logininfor` VALUES (102, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-09 17:29:40'); +INSERT INTO `sys_logininfor` VALUES (103, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-10 09:27:44'); +INSERT INTO `sys_logininfor` VALUES (104, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-10 10:30:25'); +INSERT INTO `sys_logininfor` VALUES (105, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-10 18:06:34'); +INSERT INTO `sys_logininfor` VALUES (106, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 11:39:25'); +INSERT INTO `sys_logininfor` VALUES (107, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 11:39:33'); +INSERT INTO `sys_logininfor` VALUES (108, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 12:14:13'); +INSERT INTO `sys_logininfor` VALUES (109, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 12:15:18'); +INSERT INTO `sys_logininfor` VALUES (110, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 13:07:38'); +INSERT INTO `sys_logininfor` VALUES (111, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-11 13:11:12'); +INSERT INTO `sys_logininfor` VALUES (112, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 13:11:16'); +INSERT INTO `sys_logininfor` VALUES (113, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-11 13:25:06'); +INSERT INTO `sys_logininfor` VALUES (114, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 13:26:09'); +INSERT INTO `sys_logininfor` VALUES (115, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 15:04:16'); +INSERT INTO `sys_logininfor` VALUES (116, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '验证码错误', '2024-10-11 15:13:55'); +INSERT INTO `sys_logininfor` VALUES (117, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '验证码错误', '2024-10-11 15:13:57'); +INSERT INTO `sys_logininfor` VALUES (118, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '验证码错误', '2024-10-11 15:14:00'); +INSERT INTO `sys_logininfor` VALUES (119, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '验证码错误', '2024-10-11 15:14:03'); +INSERT INTO `sys_logininfor` VALUES (120, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 15:14:06'); +INSERT INTO `sys_logininfor` VALUES (121, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-11 15:30:51'); +INSERT INTO `sys_logininfor` VALUES (122, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 15:30:56'); +INSERT INTO `sys_logininfor` VALUES (123, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-11 15:44:13'); +INSERT INTO `sys_logininfor` VALUES (124, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 15:44:16'); +INSERT INTO `sys_logininfor` VALUES (125, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 16:12:29'); +INSERT INTO `sys_logininfor` VALUES (126, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 17:17:13'); +INSERT INTO `sys_logininfor` VALUES (127, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-11 17:29:46'); +INSERT INTO `sys_logininfor` VALUES (128, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 17:29:49'); +INSERT INTO `sys_logininfor` VALUES (129, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-11 17:29:54'); +INSERT INTO `sys_logininfor` VALUES (130, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 17:30:13'); +INSERT INTO `sys_logininfor` VALUES (131, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-11 17:32:47'); +INSERT INTO `sys_logininfor` VALUES (132, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-12 09:12:16'); +INSERT INTO `sys_logininfor` VALUES (133, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-12 09:29:16'); +INSERT INTO `sys_logininfor` VALUES (134, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-12 10:53:45'); +INSERT INTO `sys_logininfor` VALUES (135, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-12 11:16:13'); +INSERT INTO `sys_logininfor` VALUES (136, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-12 11:16:16'); +INSERT INTO `sys_logininfor` VALUES (137, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-12 11:17:06'); +INSERT INTO `sys_logininfor` VALUES (138, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '验证码错误', '2024-10-12 11:17:09'); +INSERT INTO `sys_logininfor` VALUES (139, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-12 11:17:12'); +INSERT INTO `sys_logininfor` VALUES (140, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-12 11:42:49'); +INSERT INTO `sys_logininfor` VALUES (141, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-12 13:01:32'); +INSERT INTO `sys_logininfor` VALUES (142, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-12 13:05:29'); +INSERT INTO `sys_logininfor` VALUES (143, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-12 13:22:15'); +INSERT INTO `sys_logininfor` VALUES (144, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-12 14:33:11'); +INSERT INTO `sys_logininfor` VALUES (145, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-12 16:06:50'); +INSERT INTO `sys_logininfor` VALUES (146, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-12 17:48:32'); +INSERT INTO `sys_logininfor` VALUES (147, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-14 09:39:50'); +INSERT INTO `sys_logininfor` VALUES (148, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-14 09:52:48'); +INSERT INTO `sys_logininfor` VALUES (149, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-14 10:15:29'); +INSERT INTO `sys_logininfor` VALUES (150, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-14 10:19:18'); +INSERT INTO `sys_logininfor` VALUES (151, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-14 10:19:21'); +INSERT INTO `sys_logininfor` VALUES (152, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-14 13:01:16'); +INSERT INTO `sys_logininfor` VALUES (153, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-14 13:04:50'); +INSERT INTO `sys_logininfor` VALUES (154, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-14 14:19:46'); +INSERT INTO `sys_logininfor` VALUES (155, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-14 14:19:48'); +INSERT INTO `sys_logininfor` VALUES (156, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-14 15:19:52'); +INSERT INTO `sys_logininfor` VALUES (157, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-14 15:45:39'); +INSERT INTO `sys_logininfor` VALUES (158, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-14 16:48:13'); +INSERT INTO `sys_logininfor` VALUES (159, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-14 18:11:15'); +INSERT INTO `sys_logininfor` VALUES (160, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-14 18:17:04'); +INSERT INTO `sys_logininfor` VALUES (161, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 09:16:49'); +INSERT INTO `sys_logininfor` VALUES (162, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 09:17:04'); +INSERT INTO `sys_logininfor` VALUES (163, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '验证码错误', '2024-10-15 10:03:05'); +INSERT INTO `sys_logininfor` VALUES (164, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 10:03:07'); +INSERT INTO `sys_logininfor` VALUES (165, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 10:44:56'); +INSERT INTO `sys_logininfor` VALUES (166, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 10:47:51'); +INSERT INTO `sys_logininfor` VALUES (167, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 11:18:56'); +INSERT INTO `sys_logininfor` VALUES (168, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 12:29:23'); +INSERT INTO `sys_logininfor` VALUES (169, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 13:12:30'); +INSERT INTO `sys_logininfor` VALUES (170, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 13:15:32'); +INSERT INTO `sys_logininfor` VALUES (171, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '验证码已失效', '2024-10-15 13:32:29'); +INSERT INTO `sys_logininfor` VALUES (172, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 13:32:32'); +INSERT INTO `sys_logininfor` VALUES (173, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-15 13:32:45'); +INSERT INTO `sys_logininfor` VALUES (174, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 13:32:48'); +INSERT INTO `sys_logininfor` VALUES (175, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-15 13:40:06'); +INSERT INTO `sys_logininfor` VALUES (176, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-15 13:43:45'); +INSERT INTO `sys_logininfor` VALUES (177, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-15 13:43:45'); +INSERT INTO `sys_logininfor` VALUES (178, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 13:44:42'); +INSERT INTO `sys_logininfor` VALUES (179, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 13:45:17'); +INSERT INTO `sys_logininfor` VALUES (180, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '用户不存在/密码错误', '2024-10-15 14:20:50'); +INSERT INTO `sys_logininfor` VALUES (181, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '用户不存在/密码错误', '2024-10-15 14:21:10'); +INSERT INTO `sys_logininfor` VALUES (182, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '用户不存在/密码错误', '2024-10-15 14:21:19'); +INSERT INTO `sys_logininfor` VALUES (183, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '用户不存在/密码错误', '2024-10-15 14:21:33'); +INSERT INTO `sys_logininfor` VALUES (184, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '用户不存在/密码错误', '2024-10-15 14:23:46'); +INSERT INTO `sys_logininfor` VALUES (185, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '用户不存在/密码错误', '2024-10-15 14:25:27'); +INSERT INTO `sys_logininfor` VALUES (186, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '用户不存在/密码错误', '2024-10-15 14:33:15'); +INSERT INTO `sys_logininfor` VALUES (187, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-15 14:33:15'); +INSERT INTO `sys_logininfor` VALUES (188, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '用户不存在/密码错误', '2024-10-15 14:38:11'); +INSERT INTO `sys_logininfor` VALUES (189, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '用户不存在/密码错误', '2024-10-15 14:39:20'); +INSERT INTO `sys_logininfor` VALUES (190, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 14:43:39'); +INSERT INTO `sys_logininfor` VALUES (191, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 14:43:49'); +INSERT INTO `sys_logininfor` VALUES (192, 'admin', '192.168.1.29', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 15:03:41'); +INSERT INTO `sys_logininfor` VALUES (193, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '验证码已失效', '2024-10-15 16:01:03'); +INSERT INTO `sys_logininfor` VALUES (194, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-15 16:01:07'); +INSERT INTO `sys_logininfor` VALUES (195, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '退出成功', '2024-10-17 13:16:57'); +INSERT INTO `sys_logininfor` VALUES (196, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '1', '验证码错误', '2024-10-17 13:17:14'); +INSERT INTO `sys_logininfor` VALUES (197, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-17 13:17:21'); +INSERT INTO `sys_logininfor` VALUES (198, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-17 16:30:52'); +INSERT INTO `sys_logininfor` VALUES (199, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-19 16:56:35'); +INSERT INTO `sys_logininfor` VALUES (200, 'admin', '192.168.1.34', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-21 10:03:21'); + +-- ---------------------------- +-- Table structure for sys_menu +-- ---------------------------- +DROP TABLE IF EXISTS `sys_menu`; +CREATE TABLE `sys_menu` ( + `menu_id` bigint NOT NULL AUTO_INCREMENT COMMENT '菜单ID', + `menu_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '菜单名称', + `parent_id` bigint NULL DEFAULT 0 COMMENT '父菜单ID', + `order_num` int NULL DEFAULT 0 COMMENT '显示顺序', + `path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '路由地址', + `component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '组件路径', + `query` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '路由参数', + `route_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '路由名称', + `is_frame` int NULL DEFAULT 1 COMMENT '是否为外链(0是 1否)', + `is_cache` int NULL DEFAULT 0 COMMENT '是否缓存(0缓存 1不缓存)', + `menu_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '菜单类型(M目录 C菜单 F按钮)', + `visible` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '菜单状态(0显示 1隐藏)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '菜单状态(0正常 1停用)', + `perms` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '权限标识', + `icon` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '#' COMMENT '菜单图标', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '备注', + PRIMARY KEY (`menu_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 3051 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '菜单权限表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_menu +-- ---------------------------- +INSERT INTO `sys_menu` VALUES (1, '系统管理', 0, 8, 'system', NULL, '', '', 1, 0, 'M', '0', '0', '', 'system', 'admin', '2024-10-09 15:44:01', 'admin', '2024-10-17 09:45:32', '系统管理目录'); +INSERT INTO `sys_menu` VALUES (2, '系统监控', 0, 9, 'monitor', NULL, '', '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', '2024-10-09 15:44:01', 'admin', '2024-10-17 09:45:37', '系统监控目录'); +INSERT INTO `sys_menu` VALUES (100, '用户管理', 1, 1, 'user', 'system/user/index', '', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', '2024-10-09 15:44:01', '', NULL, '用户管理菜单'); +INSERT INTO `sys_menu` VALUES (101, '角色管理', 1, 2, 'role', 'system/role/index', '', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', '2024-10-09 15:44:01', '', NULL, '角色管理菜单'); +INSERT INTO `sys_menu` VALUES (102, '菜单管理', 1, 3, 'menu', 'system/menu/index', '', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', '2024-10-09 15:44:01', '', NULL, '菜单管理菜单'); +INSERT INTO `sys_menu` VALUES (103, '部门管理', 1, 4, 'dept', 'system/dept/index', '', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', '2024-10-09 15:44:01', '', NULL, '部门管理菜单'); +INSERT INTO `sys_menu` VALUES (104, '岗位管理', 1, 5, 'post', 'system/post/index', '', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', '2024-10-09 15:44:01', '', NULL, '岗位管理菜单'); +INSERT INTO `sys_menu` VALUES (105, '字典管理', 1, 6, 'dict', 'system/dict/index', '', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', '2024-10-09 15:44:01', '', NULL, '字典管理菜单'); +INSERT INTO `sys_menu` VALUES (106, '参数设置', 1, 7, 'config', 'system/config/index', '', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', '2024-10-09 15:44:01', '', NULL, '参数设置菜单'); +INSERT INTO `sys_menu` VALUES (108, '日志管理', 1, 9, 'log', '', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', '2024-10-09 15:44:01', '', NULL, '日志管理菜单'); +INSERT INTO `sys_menu` VALUES (109, '在线用户', 2, 1, 'online', 'monitor/online/index', '', '', 1, 0, 'C', '1', '0', 'monitor:online:list', 'online', 'admin', '2024-10-09 15:44:01', 'admin', '2024-10-11 13:42:03', '在线用户菜单'); +INSERT INTO `sys_menu` VALUES (110, '定时任务', 2, 2, 'job', 'monitor/job/index', '', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', '2024-10-09 15:44:01', '', NULL, '定时任务菜单'); +INSERT INTO `sys_menu` VALUES (111, '数据监控', 2, 3, 'druid', 'monitor/druid/index', '', '', 1, 0, 'C', '1', '0', 'monitor:druid:list', 'druid', 'admin', '2024-10-09 15:44:01', 'admin', '2024-10-11 13:42:25', '数据监控菜单'); +INSERT INTO `sys_menu` VALUES (112, '服务监控', 2, 4, 'server', 'monitor/server/index', '', '', 1, 0, 'C', '1', '0', 'monitor:server:list', 'server', 'admin', '2024-10-09 15:44:01', 'admin', '2024-10-11 13:42:34', '服务监控菜单'); +INSERT INTO `sys_menu` VALUES (113, '缓存监控', 2, 5, 'cache', 'monitor/cache/index', '', '', 1, 0, 'C', '1', '0', 'monitor:cache:list', 'redis', 'admin', '2024-10-09 15:44:01', 'admin', '2024-10-11 13:42:39', '缓存监控菜单'); +INSERT INTO `sys_menu` VALUES (114, '缓存列表', 2, 6, 'cacheList', 'monitor/cache/list', '', '', 1, 0, 'C', '1', '0', 'monitor:cache:list', 'redis-list', 'admin', '2024-10-09 15:44:01', 'admin', '2024-10-11 13:42:44', '缓存列表菜单'); +INSERT INTO `sys_menu` VALUES (116, '代码生成', 2, 2, 'gen', 'tool/gen/index', '', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', '2024-10-09 15:44:01', '', NULL, '代码生成菜单'); +INSERT INTO `sys_menu` VALUES (500, '操作日志', 108, 1, 'operlog', 'monitor/operlog/index', '', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', '2024-10-09 15:44:01', '', NULL, '操作日志菜单'); +INSERT INTO `sys_menu` VALUES (501, '登录日志', 108, 2, 'logininfor', 'monitor/logininfor/index', '', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', '2024-10-09 15:44:01', '', NULL, '登录日志菜单'); +INSERT INTO `sys_menu` VALUES (1000, '用户查询', 100, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1001, '用户新增', 100, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1002, '用户修改', 100, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1003, '用户删除', 100, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1004, '用户导出', 100, 5, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1005, '用户导入', 100, 6, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1006, '重置密码', 100, 7, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1007, '角色查询', 101, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1008, '角色新增', 101, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1009, '角色修改', 101, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1010, '角色删除', 101, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1011, '角色导出', 101, 5, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1012, '菜单查询', 102, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1013, '菜单新增', 102, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1014, '菜单修改', 102, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1015, '菜单删除', 102, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1016, '部门查询', 103, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1017, '部门新增', 103, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1018, '部门修改', 103, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1019, '部门删除', 103, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1020, '岗位查询', 104, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1021, '岗位新增', 104, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1022, '岗位修改', 104, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1023, '岗位删除', 104, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1024, '岗位导出', 104, 5, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1025, '字典查询', 105, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1026, '字典新增', 105, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1027, '字典修改', 105, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1028, '字典删除', 105, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1029, '字典导出', 105, 5, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1030, '参数查询', 106, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1031, '参数新增', 106, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1032, '参数修改', 106, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1033, '参数删除', 106, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1034, '参数导出', 106, 5, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1039, '操作查询', 500, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1040, '操作删除', 500, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1041, '日志导出', 500, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1042, '登录查询', 501, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1043, '登录删除', 501, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1044, '日志导出', 501, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1045, '账户解锁', 501, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1046, '在线查询', 109, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1047, '批量强退', 109, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1048, '单条强退', 109, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1049, '任务查询', 110, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1050, '任务新增', 110, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1051, '任务修改', 110, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1052, '任务删除', 110, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1053, '状态修改', 110, 5, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1054, '任务导出', 110, 6, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2004, '接口文档', 2, 3, 'swagger', 'tool/swagger/index', NULL, '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', '2024-10-12 13:03:44', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3000, '生成查询', 116, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3001, '生成修改', 116, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3002, '生成删除', 116, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3003, '导入代码', 116, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3004, '预览代码', 116, 5, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3005, '生成代码', 116, 6, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3006, '会员管理', 0, 3, 'member', NULL, NULL, '', 1, 0, 'M', '0', '0', '', 'user', 'admin', '2024-10-14 10:29:54', 'admin', '2024-10-17 09:46:06', ''); +INSERT INTO `sys_menu` VALUES (3007, '会员标签', 3006, 1, 'label', 'member/label/index', NULL, '', 1, 0, 'C', '0', '0', 'member:label:list', '#', 'admin', '2024-10-14 10:39:51', 'admin', '2024-10-14 10:47:56', '会员标签管理菜单'); +INSERT INTO `sys_menu` VALUES (3008, '会员标签管理查询', 3007, 1, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:label:query', '#', 'admin', '2024-10-14 10:39:51', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3009, '会员标签管理新增', 3007, 2, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:label:add', '#', 'admin', '2024-10-14 10:39:51', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3010, '会员标签管理修改', 3007, 3, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:label:edit', '#', 'admin', '2024-10-14 10:39:51', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3011, '会员标签管理删除', 3007, 4, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:label:remove', '#', 'admin', '2024-10-14 10:39:51', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3012, '会员标签管理导出', 3007, 5, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:label:export', '#', 'admin', '2024-10-14 10:39:51', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3013, '会员层级', 3006, 2, 'level', 'member/level/index', NULL, '', 1, 0, 'C', '0', '0', 'member:level:list', '#', 'admin', '2024-10-14 14:29:00', 'admin', '2024-10-14 14:29:25', '会员层级菜单'); +INSERT INTO `sys_menu` VALUES (3014, '会员层级查询', 3013, 1, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:level:query', '#', 'admin', '2024-10-14 14:29:00', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3015, '会员层级新增', 3013, 2, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:level:add', '#', 'admin', '2024-10-14 14:29:00', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3016, '会员层级修改', 3013, 3, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:level:edit', '#', 'admin', '2024-10-14 14:29:00', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3017, '会员层级删除', 3013, 4, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:level:remove', '#', 'admin', '2024-10-14 14:29:00', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3018, '会员层级导出', 3013, 5, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:level:export', '#', 'admin', '2024-10-14 14:29:00', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3019, 'VIP等级', 3006, 3, 'vip', 'member/vip/index', NULL, '', 1, 0, 'C', '0', '0', 'member:vip:list', '#', 'admin', '2024-10-15 16:21:35', 'admin', '2024-10-15 16:22:45', 'vip等级菜单'); +INSERT INTO `sys_menu` VALUES (3020, 'vip等级查询', 3019, 1, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:vip:query', '#', 'admin', '2024-10-15 16:21:35', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3021, 'vip等级新增', 3019, 2, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:vip:add', '#', 'admin', '2024-10-15 16:21:35', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3022, 'vip等级修改', 3019, 3, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:vip:edit', '#', 'admin', '2024-10-15 16:21:35', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3023, 'vip等级删除', 3019, 4, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:vip:remove', '#', 'admin', '2024-10-15 16:21:35', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3024, 'vip等级导出', 3019, 5, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:vip:export', '#', 'admin', '2024-10-15 16:21:35', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3025, '会员日志', 3006, 4, 'log', 'member/log/index', NULL, '', 1, 0, 'C', '0', '0', 'member:log:list', '#', 'admin', '2024-10-15 16:45:54', 'admin', '2024-10-15 16:46:17', '会员日志菜单'); +INSERT INTO `sys_menu` VALUES (3026, '会员日志查询', 3025, 1, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:log:query', '#', 'admin', '2024-10-15 16:45:54', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3027, '会员日志新增', 3025, 2, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:log:add', '#', 'admin', '2024-10-15 16:45:54', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3028, '会员日志修改', 3025, 3, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:log:edit', '#', 'admin', '2024-10-15 16:45:54', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3029, '会员日志删除', 3025, 4, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:log:remove', '#', 'admin', '2024-10-15 16:45:54', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3030, '会员日志导出', 3025, 5, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:log:export', '#', 'admin', '2024-10-15 16:45:54', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3031, '所有会员', 3006, 0, 'member', 'member/member/index', NULL, '', 1, 0, 'C', '0', '0', 'member:member:list', '#', 'admin', '2024-10-15 16:54:31', 'admin', '2024-10-15 16:54:55', '所有会员菜单'); +INSERT INTO `sys_menu` VALUES (3032, '所有会员查询', 3031, 1, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:member:query', '#', 'admin', '2024-10-15 16:54:31', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3033, '所有会员新增', 3031, 2, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:member:add', '#', 'admin', '2024-10-15 16:54:31', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3034, '所有会员修改', 3031, 3, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:member:edit', '#', 'admin', '2024-10-15 16:54:31', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3035, '所有会员删除', 3031, 4, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:member:remove', '#', 'admin', '2024-10-15 16:54:31', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3036, '所有会员导出', 3031, 5, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'member:member:export', '#', 'admin', '2024-10-15 16:54:31', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3037, '报表统计', 0, 7, 'chart', NULL, NULL, '', 1, 0, 'M', '0', '0', NULL, 'chart', 'admin', '2024-10-17 09:47:09', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3044, '运营管理', 0, 1, 'operation', NULL, NULL, '', 1, 0, 'M', '0', '0', NULL, 'documentation', 'admin', '2024-10-17 16:28:58', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3045, '币种管理', 3044, 1, 'currency', 'operation/currency/index', NULL, '', 1, 0, 'C', '0', '0', 'operation:currency:list', '#', 'admin', '2024-10-17 16:32:41', '', NULL, '币种管理菜单'); +INSERT INTO `sys_menu` VALUES (3046, '币种管理查询', 3045, 1, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'operation:currency:query', '#', 'admin', '2024-10-17 16:32:41', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3047, '币种管理新增', 3045, 2, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'operation:currency:add', '#', 'admin', '2024-10-17 16:32:41', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3048, '币种管理修改', 3045, 3, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'operation:currency:edit', '#', 'admin', '2024-10-17 16:32:41', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3049, '币种管理删除', 3045, 4, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'operation:currency:remove', '#', 'admin', '2024-10-17 16:32:41', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (3050, '币种管理导出', 3045, 5, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'operation:currency:export', '#', 'admin', '2024-10-17 16:32:41', '', NULL, ''); + +-- ---------------------------- +-- Table structure for sys_oper_log +-- ---------------------------- +DROP TABLE IF EXISTS `sys_oper_log`; +CREATE TABLE `sys_oper_log` ( + `oper_id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志主键', + `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '模块标题', + `business_type` int NULL DEFAULT 0 COMMENT '业务类型(0其它 1新增 2修改 3删除)', + `method` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '方法名称', + `request_method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求方式', + `operator_type` int NULL DEFAULT 0 COMMENT '操作类别(0其它 1后台用户 2手机端用户)', + `oper_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作人员', + `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '部门名称', + `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求URL', + `oper_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '主机地址', + `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作地点', + `oper_param` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求参数', + `json_result` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '返回参数', + `status` int NULL DEFAULT 0 COMMENT '操作状态(0正常 1异常)', + `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '错误消息', + `oper_time` datetime NULL DEFAULT NULL COMMENT '操作时间', + `cost_time` bigint NULL DEFAULT 0 COMMENT '消耗时间', + PRIMARY KEY (`oper_id`) USING BTREE, + INDEX `idx_sys_oper_log_bt`(`business_type`) USING BTREE, + INDEX `idx_sys_oper_log_s`(`status`) USING BTREE, + INDEX `idx_sys_oper_log_ot`(`oper_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 479 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '操作日志记录' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_oper_log +-- ---------------------------- +INSERT INTO `sys_oper_log` VALUES (100, '代码生成', 6, 'com.ruoyi.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"sys_notice\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-09 16:31:15', 116); +INSERT INTO `sys_oper_log` VALUES (101, '参数管理', 9, 'com.ruoyi.web.controller.system.SysConfigController.refreshCache()', 'DELETE', 1, 'admin', '研发部门', '/system/config/refreshCache', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-10 18:11:03', 33); +INSERT INTO `sys_oper_log` VALUES (102, '参数管理', 9, 'com.ruoyi.web.controller.system.SysConfigController.refreshCache()', 'DELETE', 1, 'admin', '研发部门', '/system/config/refreshCache', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-10 18:11:03', 11); +INSERT INTO `sys_oper_log` VALUES (103, '参数管理', 9, 'com.ruoyi.web.controller.system.SysConfigController.refreshCache()', 'DELETE', 1, 'admin', '研发部门', '/system/config/refreshCache', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-10 18:11:04', 13); +INSERT INTO `sys_oper_log` VALUES (104, '参数管理', 9, 'com.ruoyi.web.controller.system.SysConfigController.refreshCache()', 'DELETE', 1, 'admin', '研发部门', '/system/config/refreshCache', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-10 18:11:04', 14); +INSERT INTO `sys_oper_log` VALUES (105, '参数管理', 9, 'com.ruoyi.web.controller.system.SysConfigController.refreshCache()', 'DELETE', 1, 'admin', '研发部门', '/system/config/refreshCache', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-10 18:11:04', 12); +INSERT INTO `sys_oper_log` VALUES (106, '参数管理', 9, 'com.ruoyi.web.controller.system.SysConfigController.refreshCache()', 'DELETE', 1, 'admin', '研发部门', '/system/config/refreshCache', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-10 18:11:04', 13); +INSERT INTO `sys_oper_log` VALUES (107, '参数管理', 9, 'com.ruoyi.web.controller.system.SysConfigController.refreshCache()', 'DELETE', 1, 'admin', '研发部门', '/system/config/refreshCache', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-10 18:11:04', 12); +INSERT INTO `sys_oper_log` VALUES (108, '参数管理', 9, 'com.ruoyi.web.controller.system.SysConfigController.refreshCache()', 'DELETE', 1, 'admin', '研发部门', '/system/config/refreshCache', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-10 18:11:05', 14); +INSERT INTO `sys_oper_log` VALUES (109, '参数管理', 2, 'com.ruoyi.web.controller.system.SysConfigController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/config', '127.0.0.1', '内网IP', '{\"configId\":1,\"configKey\":\"sys.index.skinName\",\"configName\":\"主框架页-默认皮肤样式名称\",\"configType\":\"Y\",\"configValue\":\"skin-blue\",\"createBy\":\"admin\",\"createTime\":\"2024-10-09 15:44:02\",\"params\":{},\"remark\":\"蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-10 18:11:07', 19); +INSERT INTO `sys_oper_log` VALUES (110, '角色管理', 2, 'com.ff.system.SysRoleController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/role', '127.0.0.1', '内网IP', '{\"admin\":false,\"createTime\":\"2024-10-09 15:44:01\",\"dataScope\":\"2\",\"delFlag\":\"0\",\"deptCheckStrictly\":true,\"flag\":false,\"menuCheckStrictly\":true,\"menuIds\":[1,100,1000,1001,1002,1003,1004,1005,1006,101,1007,1008,1009,1010,1011,102,1012,1013,1014,1015,103,1016,1017,1018,1019,104,1020,1021,1022,1023,1024,105,1025,1026,1027,1028,1029,106,1030,1031,1032,1033,1034,108,500,1039,1040,1041,501,1042,1043,1044,1045,2,109,1046,1047,1048,110,1049,1050,1051,1052,1053,1054,111,112,113,114,3,115,116,1055,1056,1057,1058,1059,1060,117,4],\"params\":{},\"remark\":\"普通角色\",\"roleId\":2,\"roleKey\":\"common\",\"roleName\":\"普通角色\",\"roleSort\":2,\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:22:59', 78); +INSERT INTO `sys_oper_log` VALUES (111, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/107', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"存在子菜单,不允许删除\",\"code\":601}', 0, NULL, '2024-10-11 13:23:05', 3); +INSERT INTO `sys_oper_log` VALUES (112, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/1038', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:23:13', 10); +INSERT INTO `sys_oper_log` VALUES (113, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/1037', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:23:15', 11); +INSERT INTO `sys_oper_log` VALUES (114, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/1036', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:23:18', 10); +INSERT INTO `sys_oper_log` VALUES (115, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/1035', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:23:25', 11); +INSERT INTO `sys_oper_log` VALUES (116, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/107', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:23:28', 13); +INSERT INTO `sys_oper_log` VALUES (117, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/4', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"菜单已分配,不允许删除\",\"code\":601}', 0, NULL, '2024-10-11 13:41:27', 13); +INSERT INTO `sys_oper_log` VALUES (118, '角色管理', 2, 'com.ff.system.SysRoleController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/role', '127.0.0.1', '内网IP', '{\"admin\":false,\"createTime\":\"2024-10-09 15:44:01\",\"dataScope\":\"2\",\"delFlag\":\"0\",\"deptCheckStrictly\":true,\"flag\":false,\"menuCheckStrictly\":true,\"menuIds\":[1,100,1000,1001,1002,1003,1004,1005,1006,101,1007,1008,1009,1010,1011,102,1012,1013,1014,1015,103,1016,1017,1018,1019,104,1020,1021,1022,1023,1024,105,1025,1026,1027,1028,1029,106,1030,1031,1032,1033,1034,108,500,1039,1040,1041,501,1042,1043,1044,1045,2,109,1046,1047,1048,110,1049,1050,1051,1052,1053,1054,111,112,113,114,3,115,116,1055,1056,1057,1058,1059,1060,117],\"params\":{},\"remark\":\"普通角色\",\"roleId\":2,\"roleKey\":\"common\",\"roleName\":\"普通角色\",\"roleSort\":2,\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:41:36', 70); +INSERT INTO `sys_oper_log` VALUES (119, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/4', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:41:40', 16); +INSERT INTO `sys_oper_log` VALUES (120, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"monitor/online/index\",\"createTime\":\"2024-10-09 15:44:01\",\"icon\":\"online\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":109,\"menuName\":\"在线用户\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2,\"path\":\"online\",\"perms\":\"monitor:online:list\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:42:04', 21); +INSERT INTO `sys_oper_log` VALUES (121, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"monitor/druid/index\",\"createTime\":\"2024-10-09 15:44:01\",\"icon\":\"druid\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":111,\"menuName\":\"数据监控\",\"menuType\":\"C\",\"orderNum\":3,\"params\":{},\"parentId\":2,\"path\":\"druid\",\"perms\":\"monitor:druid:list\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:42:25', 12); +INSERT INTO `sys_oper_log` VALUES (122, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"monitor/server/index\",\"createTime\":\"2024-10-09 15:44:01\",\"icon\":\"server\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":112,\"menuName\":\"服务监控\",\"menuType\":\"C\",\"orderNum\":4,\"params\":{},\"parentId\":2,\"path\":\"server\",\"perms\":\"monitor:server:list\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:42:34', 12); +INSERT INTO `sys_oper_log` VALUES (123, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"monitor/cache/index\",\"createTime\":\"2024-10-09 15:44:01\",\"icon\":\"redis\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":113,\"menuName\":\"缓存监控\",\"menuType\":\"C\",\"orderNum\":5,\"params\":{},\"parentId\":2,\"path\":\"cache\",\"perms\":\"monitor:cache:list\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:42:39', 14); +INSERT INTO `sys_oper_log` VALUES (124, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"monitor/cache/list\",\"createTime\":\"2024-10-09 15:44:01\",\"icon\":\"redis-list\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":114,\"menuName\":\"缓存列表\",\"menuType\":\"C\",\"orderNum\":6,\"params\":{},\"parentId\":2,\"path\":\"cacheList\",\"perms\":\"monitor:cache:list\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:42:44', 11); +INSERT INTO `sys_oper_log` VALUES (125, '角色管理', 2, 'com.ff.system.SysRoleController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/role', '127.0.0.1', '内网IP', '{\"admin\":false,\"createTime\":\"2024-10-09 15:44:01\",\"dataScope\":\"2\",\"delFlag\":\"0\",\"deptCheckStrictly\":true,\"flag\":false,\"menuCheckStrictly\":true,\"menuIds\":[1,100,1000,1001,1002,1003,1004,1005,1006,101,1007,1008,1009,1010,1011,102,1012,1013,1014,1015,103,1016,1017,1018,1019,104,1020,1021,1022,1023,1024,105,1025,1026,1027,1028,1029,106,1030,1031,1032,1033,1034,108,500,1039,1040,1041,501,1042,1043,1044,1045,2,109,1046,1047,1048,110,1049,1050,1051,1052,1053,1054,111,112,113,114],\"params\":{},\"remark\":\"普通角色\",\"roleId\":2,\"roleKey\":\"common\",\"roleName\":\"普通角色\",\"roleSort\":2,\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:43:54', 32); +INSERT INTO `sys_oper_log` VALUES (126, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/117', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:43:59', 11); +INSERT INTO `sys_oper_log` VALUES (127, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/115', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:44:15', 17); +INSERT INTO `sys_oper_log` VALUES (128, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/116', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"存在子菜单,不允许删除\",\"code\":601}', 0, NULL, '2024-10-11 13:44:22', 3); +INSERT INTO `sys_oper_log` VALUES (129, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/1055', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:44:25', 19); +INSERT INTO `sys_oper_log` VALUES (130, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/1056', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:44:27', 13); +INSERT INTO `sys_oper_log` VALUES (131, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/1057', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:44:30', 17); +INSERT INTO `sys_oper_log` VALUES (132, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/1058', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:44:34', 17); +INSERT INTO `sys_oper_log` VALUES (133, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/1059', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:44:36', 17); +INSERT INTO `sys_oper_log` VALUES (134, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/1060', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:44:38', 18); +INSERT INTO `sys_oper_log` VALUES (135, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/116', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:44:40', 17); +INSERT INTO `sys_oper_log` VALUES (136, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/3', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 13:44:45', 16); +INSERT INTO `sys_oper_log` VALUES (137, '参数管理', 2, 'com.ff.system.SysConfigController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/config', '192.168.1.34', '内网IP', '{\"configId\":1,\"configKey\":\"sys.index.skinName\",\"configName\":\"主框架页-默认皮肤样式名称\",\"configType\":\"Y\",\"configValue\":\"skin-green\",\"createBy\":\"admin\",\"createTime\":\"2024-10-09 15:44:02\",\"params\":{},\"remark\":\"蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow\",\"updateBy\":\"admin\",\"updateTime\":\"2024-10-10 18:11:07\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 15:30:39', 23); +INSERT INTO `sys_oper_log` VALUES (138, '参数管理', 2, 'com.ff.system.SysConfigController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/config', '192.168.1.34', '内网IP', '{\"configId\":1,\"configKey\":\"sys.index.skinName\",\"configName\":\"主框架页-默认皮肤样式名称\",\"configType\":\"Y\",\"configValue\":\"skin-blue\",\"createBy\":\"admin\",\"createTime\":\"2024-10-09 15:44:02\",\"params\":{},\"remark\":\"蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow\",\"updateBy\":\"admin\",\"updateTime\":\"2024-10-11 15:30:39\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-11 15:44:07', 17); +INSERT INTO `sys_oper_log` VALUES (139, '字典类型', 1, 'com.ff.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"会员标签图标\",\"dictType\":\"ff_member_label_icon\",\"params\":{},\"remark\":\"会员标签图标\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 09:30:11', 20); +INSERT INTO `sys_oper_log` VALUES (140, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"#2bfa38\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#2bfa38\",\"listClass\":\"default\",\"params\":{},\"remark\":\"绿色\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 09:34:11', 32); +INSERT INTO `sys_oper_log` VALUES (141, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"#f59a23\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#f59a23\",\"listClass\":\"default\",\"params\":{},\"remark\":\"橙色\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 09:35:59', 20); +INSERT INTO `sys_oper_log` VALUES (142, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"cssClass\":\"\",\"default\":false,\"dictLabel\":\"#db301a\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#db301a\",\"listClass\":\"default\",\"params\":{},\"remark\":\"红色\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 09:36:29', 14); +INSERT INTO `sys_oper_log` VALUES (143, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"#4d42cf\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#4d42cf\",\"listClass\":\"default\",\"params\":{},\"remark\":\"深蓝\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 09:37:18', 13); +INSERT INTO `sys_oper_log` VALUES (144, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"#1677fd\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#1677fd\",\"listClass\":\"default\",\"params\":{},\"remark\":\"淡蓝\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 09:38:28', 35); +INSERT INTO `sys_oper_log` VALUES (145, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"#000000\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#000000\",\"listClass\":\"default\",\"params\":{},\"remark\":\"黑色\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 09:39:11', 15); +INSERT INTO `sys_oper_log` VALUES (146, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"#4cb5ff\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#4cb5ff\",\"listClass\":\"default\",\"params\":{},\"remark\":\"浅蓝\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 09:40:23', 37); +INSERT INTO `sys_oper_log` VALUES (147, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"#874ce8\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#874ce8\",\"listClass\":\"default\",\"params\":{},\"remark\":\"深紫\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 09:41:18', 14); +INSERT INTO `sys_oper_log` VALUES (148, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"#cd55ff\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#cd55ff\",\"listClass\":\"default\",\"params\":{},\"remark\":\"淡紫\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 09:41:52', 15); +INSERT INTO `sys_oper_log` VALUES (149, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"#26a17b\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#26a17b\",\"listClass\":\"default\",\"params\":{},\"remark\":\"墨绿\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 09:42:29', 15); +INSERT INTO `sys_oper_log` VALUES (150, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"#ea4e3d\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#ea4e3d\",\"listClass\":\"default\",\"params\":{},\"remark\":\"浅红\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 09:43:13', 14); +INSERT INTO `sys_oper_log` VALUES (151, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"#ff7097\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#ff7097\",\"listClass\":\"default\",\"params\":{},\"remark\":\"粉色 \",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 09:44:13', 32); +INSERT INTO `sys_oper_log` VALUES (152, '字典类型', 1, 'com.ff.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"币种\",\"dictType\":\"ff_currency\",\"params\":{},\"remark\":\"币种\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 10:54:26', 14); +INSERT INTO `sys_oper_log` VALUES (153, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"USDT(USDT)\",\"dictSort\":0,\"dictType\":\"ff_currency\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"remark\":\"USDT(USDT)\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 10:55:47', 32); +INSERT INTO `sys_oper_log` VALUES (154, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"越南盾(VND1000:1)\",\"dictSort\":0,\"dictType\":\"ff_currency\",\"dictValue\":\"2\",\"listClass\":\"default\",\"params\":{},\"remark\":\"越南盾(VND1000:1)\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 10:56:28', 44); +INSERT INTO `sys_oper_log` VALUES (155, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"日元(JPY)\",\"dictSort\":0,\"dictType\":\"ff_currency\",\"dictValue\":\"3\",\"listClass\":\"default\",\"params\":{},\"remark\":\"日元(JPY)\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 10:57:41', 30); +INSERT INTO `sys_oper_log` VALUES (156, '菜单管理', 1, 'com.ff.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"createBy\":\"admin\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"测试菜单\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":101,\"path\":\"system/role/index\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 11:16:06', 20); +INSERT INTO `sys_oper_log` VALUES (157, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"component\":\"system/role/index\",\"createTime\":\"2024-10-12 11:16:06\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2000,\"menuName\":\"测试菜单\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":101,\"path\":\"system/role/index\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 11:16:54', 10); +INSERT INTO `sys_oper_log` VALUES (158, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/2000', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 11:18:02', 31); +INSERT INTO `sys_oper_log` VALUES (159, '菜单管理', 1, 'com.ff.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"createBy\":\"admin\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"测试\",\"menuType\":\"M\",\"orderNum\":1,\"params\":{},\"parentId\":0,\"path\":\" \",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 11:18:57', 8); +INSERT INTO `sys_oper_log` VALUES (160, '菜单管理', 1, 'com.ff.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"createBy\":\"admin\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"测试1\",\"menuType\":\"M\",\"orderNum\":1,\"params\":{},\"parentId\":2001,\"path\":\" \",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 11:19:09', 6); +INSERT INTO `sys_oper_log` VALUES (161, '菜单管理', 1, 'com.ff.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"createBy\":\"admin\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"测试2\",\"menuType\":\"M\",\"orderNum\":1,\"params\":{},\"parentId\":2002,\"path\":\"system/role/index\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 11:19:22', 14); +INSERT INTO `sys_oper_log` VALUES (162, '菜单管理', 1, 'com.ff.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"component\":\"tool/swagger/index\",\"createBy\":\"admin\",\"icon\":\"swagger\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"接口文档\",\"menuType\":\"C\",\"orderNum\":3,\"params\":{},\"parentId\":2,\"path\":\"swagger\",\"perms\":\"tool:swagger:list\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 13:03:44', 59); +INSERT INTO `sys_oper_log` VALUES (163, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/2001', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"存在子菜单,不允许删除\",\"code\":601}', 0, NULL, '2024-10-12 13:42:01', 7); +INSERT INTO `sys_oper_log` VALUES (164, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/2003', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 13:42:09', 13); +INSERT INTO `sys_oper_log` VALUES (165, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/2002', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 13:42:10', 16); +INSERT INTO `sys_oper_log` VALUES (166, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/2001', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 13:42:12', 14); +INSERT INTO `sys_oper_log` VALUES (167, '字典类型', 1, 'com.ff.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"注册来源\",\"dictType\":\"ff_registe_source\",\"params\":{},\"remark\":\"注册来源\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 14:35:14', 30); +INSERT INTO `sys_oper_log` VALUES (168, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"官网\",\"dictSort\":0,\"dictType\":\"ff_registe_source\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"remark\":\"官网\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 14:37:06', 32); +INSERT INTO `sys_oper_log` VALUES (169, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"后台添加\",\"dictSort\":0,\"dictType\":\"ff_registe_source\",\"dictValue\":\"2\",\"listClass\":\"default\",\"params\":{},\"remark\":\"后台添加\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 14:37:35', 15); +INSERT INTO `sys_oper_log` VALUES (170, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"kk1注册\",\"dictSort\":0,\"dictType\":\"ff_registe_source\",\"dictValue\":\"3\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 14:38:18', 15); +INSERT INTO `sys_oper_log` VALUES (171, '字典类型', 3, 'com.ff.system.SysDictTypeController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/dict/type/102', '192.168.1.34', '内网IP', '{}', NULL, 1, '注册来源已分配,不能删除', '2024-10-12 14:47:43', 39); +INSERT INTO `sys_oper_log` VALUES (172, '字典类型', 3, 'com.ff.system.SysDictDataController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/dict/data/117', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 14:47:49', 20); +INSERT INTO `sys_oper_log` VALUES (173, '字典类型', 3, 'com.ff.system.SysDictDataController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/dict/data/116', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 14:47:51', 17); +INSERT INTO `sys_oper_log` VALUES (174, '字典类型', 3, 'com.ff.system.SysDictDataController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/dict/data/115', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 14:47:53', 15); +INSERT INTO `sys_oper_log` VALUES (175, '字典类型', 3, 'com.ff.system.SysDictTypeController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/dict/type/102', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 14:47:58', 14); +INSERT INTO `sys_oper_log` VALUES (176, '字典类型', 1, 'com.ff.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"注册方式\",\"dictType\":\"ff_registe_way\",\"params\":{},\"remark\":\"注册方式\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:07:28', 8); +INSERT INTO `sys_oper_log` VALUES (177, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"账号注册\",\"dictSort\":0,\"dictType\":\"ff_registe_way\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"remark\":\"账号注册\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:07:55', 17); +INSERT INTO `sys_oper_log` VALUES (178, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"FaceBook注册\",\"dictSort\":0,\"dictType\":\"ff_registe_way\",\"dictValue\":\"2\",\"listClass\":\"default\",\"params\":{},\"remark\":\"FaceBook注册\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:08:21', 13); +INSERT INTO `sys_oper_log` VALUES (179, '字典类型', 1, 'com.ff.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"设备类型\",\"dictType\":\"ff_device_type\",\"params\":{},\"remark\":\"设备类型\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:23:29', 42); +INSERT INTO `sys_oper_log` VALUES (180, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"APP-iOS\",\"dictSort\":0,\"dictType\":\"ff_device_type\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"remark\":\"APP-iOS\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:24:29', 12); +INSERT INTO `sys_oper_log` VALUES (181, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"H5-iOS\",\"dictSort\":0,\"dictType\":\"ff_device_type\",\"dictValue\":\"2\",\"listClass\":\"default\",\"params\":{},\"remark\":\"H5-iOS\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:25:18', 11); +INSERT INTO `sys_oper_log` VALUES (182, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"APP-Android\",\"dictSort\":0,\"dictType\":\"ff_device_type\",\"dictValue\":\"3\",\"listClass\":\"default\",\"params\":{},\"remark\":\"APP-Android\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:25:43', 40); +INSERT INTO `sys_oper_log` VALUES (183, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"H5-Android\",\"dictSort\":0,\"dictType\":\"ff_device_type\",\"dictValue\":\"4\",\"listClass\":\"default\",\"params\":{},\"remark\":\"H5-Android\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:26:09', 13); +INSERT INTO `sys_oper_log` VALUES (184, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"PC-Windows\",\"dictSort\":0,\"dictType\":\"ff_device_type\",\"dictValue\":\"5\",\"listClass\":\"default\",\"params\":{},\"remark\":\"PC-Windows\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:26:41', 15); +INSERT INTO `sys_oper_log` VALUES (185, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"PC-Mac\",\"dictSort\":0,\"dictType\":\"ff_device_type\",\"dictValue\":\"6\",\"listClass\":\"default\",\"params\":{},\"remark\":\"PC-Mac\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:27:06', 11); +INSERT INTO `sys_oper_log` VALUES (186, '字典类型', 1, 'com.ff.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"会员验证方式\",\"dictType\":\"ff_verify_way\",\"params\":{},\"remark\":\"会员验证方式\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:42:00', 26); +INSERT INTO `sys_oper_log` VALUES (187, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"无验证\",\"dictSort\":0,\"dictType\":\"ff_verify_way\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:42:17', 15); +INSERT INTO `sys_oper_log` VALUES (188, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"短信验证\",\"dictSort\":0,\"dictType\":\"ff_verify_way\",\"dictValue\":\"2\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:42:32', 12); +INSERT INTO `sys_oper_log` VALUES (189, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"谷歌验证\",\"dictSort\":0,\"dictType\":\"ff_verify_way\",\"dictValue\":\"3\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-12 16:42:43', 12); +INSERT INTO `sys_oper_log` VALUES (190, '代码生成', 3, 'com.ff.gen.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/1', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 09:51:20', 51); +INSERT INTO `sys_oper_log` VALUES (191, '代码生成', 6, 'com.ff.gen.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_label\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 09:53:09', 56); +INSERT INTO `sys_oper_log` VALUES (192, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"FfMemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"iconColor\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CreateBy\",\"columnComment\":\"创建者\",\"columnId\":14,\"columnName\":\"create_by\",\"columnType\":\"varchar(64)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"0\",\"isRequired\":\"0\",\"javaField\":\"createBy\",\"javaType\":', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:14:21', 73); +INSERT INTO `sys_oper_log` VALUES (193, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"FfMemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:14:21\",\"usableColumn\":false},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:14:21\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"iconColor\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:14:21\",\"usableColumn\":false},{\"capJavaField\":\"CreateBy\",\"columnComment\":\"创建者\",\"columnId\":14,\"columnName\":\"create_by\",\"columnType\":\"varchar(64)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"ins', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:14:38', 88); +INSERT INTO `sys_oper_log` VALUES (194, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"FfMemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:14:38\",\"usableColumn\":false},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:14:38\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"iconColor\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:14:38\",\"usableColumn\":false},{\"capJavaField\":\"CreateBy\",\"columnComment\":\"创建者\",\"columnId\":14,\"columnName\":\"create_by\",\"columnType\":\"varchar(64)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"ins', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:21:55', 42); +INSERT INTO `sys_oper_log` VALUES (195, '用户管理', 2, 'com.ff.system.SysUserController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/user', '192.168.1.34', '内网IP', '{\"admin\":false,\"avatar\":\"\",\"createBy\":\"admin\",\"createTime\":\"2024-10-09 15:44:01\",\"delFlag\":\"0\",\"dept\":{\"ancestors\":\"0,100,101\",\"children\":[],\"deptId\":105,\"deptName\":\"测试部门\",\"leader\":\"若依\",\"orderNum\":3,\"params\":{},\"parentId\":101,\"status\":\"0\"},\"deptId\":105,\"email\":\"ry@qq.com\",\"loginDate\":\"2024-10-09 15:44:01\",\"loginIp\":\"127.0.0.1\",\"nickName\":\"若依\",\"params\":{},\"phonenumber\":\"15666666666\",\"postIds\":[2],\"remark\":\"测试员\",\"roleIds\":[2],\"roles\":[{\"admin\":false,\"dataScope\":\"2\",\"deptCheckStrictly\":false,\"flag\":false,\"menuCheckStrictly\":false,\"params\":{},\"roleId\":2,\"roleKey\":\"common\",\"roleName\":\"普通角色\",\"roleSort\":2,\"status\":\"0\"}],\"sex\":\"1\",\"status\":\"0\",\"updateBy\":\"admin\",\"userId\":2,\"userName\":\"ry\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:22:46', 38); +INSERT INTO `sys_oper_log` VALUES (196, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"FfMemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:21:55\",\"usableColumn\":false},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:21:55\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"iconColor\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:21:55\",\"usableColumn\":false},{\"capJavaField\":\"CreateBy\",\"columnComment\":\"创建者\",\"columnId\":14,\"columnName\":\"create_by\",\"columnType\":\"varchar(64)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"ins', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:23:04', 35); +INSERT INTO `sys_oper_log` VALUES (197, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"FfMemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:23:04\",\"usableColumn\":false},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:23:04\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"iconColor\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:23:04\",\"usableColumn\":false},{\"capJavaField\":\"CreateBy\",\"columnComment\":\"创建者\",\"columnId\":14,\"columnName\":\"create_by\",\"columnType\":\"varchar(64)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"ins', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:23:13', 37); +INSERT INTO `sys_oper_log` VALUES (198, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"FfMemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:23:13\",\"usableColumn\":false},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:23:13\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"iconColor\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:23:13\",\"usableColumn\":false},{\"capJavaField\":\"CreateBy\",\"columnComment\":\"创建者\",\"columnId\":14,\"columnName\":\"create_by\",\"columnType\":\"varchar(64)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"ins', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:23:30', 35); +INSERT INTO `sys_oper_log` VALUES (199, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"FfMemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:23:30\",\"usableColumn\":false},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:23:30\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"iconColor\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:23:30\",\"usableColumn\":false},{\"capJavaField\":\"CreateBy\",\"columnComment\":\"创建者\",\"columnId\":14,\"columnName\":\"create_by\",\"columnType\":\"varchar(64)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"ins', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:25:03', 30); +INSERT INTO `sys_oper_log` VALUES (200, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"FfMemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:25:03\",\"usableColumn\":false},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:25:03\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"iconColor\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:25:03\",\"usableColumn\":false},{\"capJavaField\":\"CreateBy\",\"columnComment\":\"创建者\",\"columnId\":14,\"columnName\":\"create_by\",\"columnType\":\"varchar(64)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"ins', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:27:04', 34); +INSERT INTO `sys_oper_log` VALUES (201, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"FfMemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:27:04\",\"usableColumn\":false},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:27:04\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"iconColor\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:27:04\",\"usableColumn\":false},{\"capJavaField\":\"CreateBy\",\"columnComment\":\"创建者\",\"columnId\":14,\"columnName\":\"create_by\",\"columnType\":\"varchar(64)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"ins', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:28:58', 55); +INSERT INTO `sys_oper_log` VALUES (202, '菜单管理', 1, 'com.ff.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"createBy\":\"admin\",\"icon\":\"user\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"会员管理\",\"menuType\":\"M\",\"orderNum\":0,\"params\":{},\"parentId\":0,\"path\":\"member\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:29:54', 22); +INSERT INTO `sys_oper_log` VALUES (203, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"FfMemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:28:58\",\"usableColumn\":false},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:28:58\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"iconColor\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:28:58\",\"usableColumn\":false},{\"capJavaField\":\"CreateBy\",\"columnComment\":\"创建者\",\"columnId\":14,\"columnName\":\"create_by\",\"columnType\":\"varchar(64)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"ins', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:33:19', 31); +INSERT INTO `sys_oper_log` VALUES (204, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"MemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:33:19\",\"usableColumn\":false},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:33:19\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"iconColor\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:33:19\",\"usableColumn\":false},{\"capJavaField\":\"CreateBy\",\"columnComment\":\"创建者\",\"columnId\":14,\"columnName\":\"create_by\",\"columnType\":\"varchar(64)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"inser', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:33:36', 30); +INSERT INTO `sys_oper_log` VALUES (205, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"MemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:33:36\",\"usableColumn\":false},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:33:36\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"iconColor\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:33:36\",\"usableColumn\":false},{\"capJavaField\":\"CreateBy\",\"columnComment\":\"创建者\",\"columnId\":14,\"columnName\":\"create_by\",\"columnType\":\"varchar(64)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"inser', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:36:35', 52); +INSERT INTO `sys_oper_log` VALUES (206, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_label\"}', NULL, 0, NULL, '2024-10-14 10:36:39', 341); +INSERT INTO `sys_oper_log` VALUES (207, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_label\"}', NULL, 0, NULL, '2024-10-14 10:36:50', 85); +INSERT INTO `sys_oper_log` VALUES (208, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_label\"}', NULL, 0, NULL, '2024-10-14 10:37:46', 42); +INSERT INTO `sys_oper_log` VALUES (209, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_label\"}', NULL, 0, NULL, '2024-10-14 10:38:49', 153); +INSERT INTO `sys_oper_log` VALUES (210, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_label\"}', NULL, 0, NULL, '2024-10-14 10:41:08', 110); +INSERT INTO `sys_oper_log` VALUES (211, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"component\":\"member/label/index\",\"createTime\":\"2024-10-14 10:39:51\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":3007,\"menuName\":\"会员标签\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":3006,\"path\":\"label\",\"perms\":\"member:label:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:47:56', 35); +INSERT INTO `sys_oper_log` VALUES (212, '代码生成', 2, 'com.ff.gen.controller.GenController.synchDb()', 'GET', 1, 'admin', '研发部门', '/tool/gen/synchDb/ff_member_label', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:52:39', 93); +INSERT INTO `sys_oper_log` VALUES (213, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"MemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:52:39\",\"usableColumn\":false},{\"capJavaField\":\"OrderNum\",\"columnComment\":\"显示顺序\",\"columnId\":19,\"columnName\":\"order_num\",\"columnType\":\"int\",\"createBy\":\"\",\"createTime\":\"2024-10-14 10:52:39\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"orderNum\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":true,\"tableId\":2,\"updateBy\":\"\",\"usableColumn\":true},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:52:39\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 10:53:28', 53); +INSERT INTO `sys_oper_log` VALUES (214, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_label\"}', NULL, 0, NULL, '2024-10-14 10:53:47', 97); +INSERT INTO `sys_oper_log` VALUES (215, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_label\"}', NULL, 0, NULL, '2024-10-14 10:54:42', 85); +INSERT INTO `sys_oper_log` VALUES (216, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"无图标\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"empty\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:01:08', 34); +INSERT INTO `sys_oper_log` VALUES (217, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 11:01:08\",\"default\":false,\"dictCode\":129,\"dictLabel\":\"无图标\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"empty\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:01:33', 24); +INSERT INTO `sys_oper_log` VALUES (218, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 09:34:10\",\"default\":false,\"dictCode\":100,\"dictLabel\":\"#2bfa38\",\"dictSort\":13,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#2bfa38\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"绿色\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:02:16', 18); +INSERT INTO `sys_oper_log` VALUES (219, '字典类型', 3, 'com.ff.system.SysDictDataController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/dict/data/129', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:02:50', 22); +INSERT INTO `sys_oper_log` VALUES (220, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 09:44:13\",\"default\":false,\"dictCode\":111,\"dictLabel\":\"#ff7097\",\"dictSort\":12,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#ff7097\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"粉色 \",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:03:08', 20); +INSERT INTO `sys_oper_log` VALUES (221, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 09:35:59\",\"default\":false,\"dictCode\":101,\"dictLabel\":\"#f59a23\",\"dictSort\":11,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#f59a23\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"橙色\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:03:15', 13); +INSERT INTO `sys_oper_log` VALUES (222, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 09:36:29\",\"default\":false,\"dictCode\":102,\"dictLabel\":\"#db301a\",\"dictSort\":10,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#db301a\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"红色\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:03:18', 17); +INSERT INTO `sys_oper_log` VALUES (223, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 09:37:18\",\"default\":false,\"dictCode\":103,\"dictLabel\":\"#4d42cf\",\"dictSort\":9,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#4d42cf\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"深蓝\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:03:22', 14); +INSERT INTO `sys_oper_log` VALUES (224, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 09:38:28\",\"default\":false,\"dictCode\":104,\"dictLabel\":\"#1677fd\",\"dictSort\":8,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#1677fd\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"淡蓝\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:03:27', 15); +INSERT INTO `sys_oper_log` VALUES (225, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 09:39:11\",\"default\":false,\"dictCode\":105,\"dictLabel\":\"#000000\",\"dictSort\":7,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#000000\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"黑色\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:03:31', 15); +INSERT INTO `sys_oper_log` VALUES (226, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 09:40:23\",\"default\":false,\"dictCode\":106,\"dictLabel\":\"#4cb5ff\",\"dictSort\":6,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#4cb5ff\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"浅蓝\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:03:35', 15); +INSERT INTO `sys_oper_log` VALUES (227, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 09:41:18\",\"default\":false,\"dictCode\":107,\"dictLabel\":\"#874ce8\",\"dictSort\":5,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#874ce8\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"深紫\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:03:39', 13); +INSERT INTO `sys_oper_log` VALUES (228, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 09:41:52\",\"default\":false,\"dictCode\":108,\"dictLabel\":\"#cd55ff\",\"dictSort\":4,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#cd55ff\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"淡紫\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:03:43', 16); +INSERT INTO `sys_oper_log` VALUES (229, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 09:42:29\",\"default\":false,\"dictCode\":109,\"dictLabel\":\"#26a17b\",\"dictSort\":3,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#26a17b\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"墨绿\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:03:47', 17); +INSERT INTO `sys_oper_log` VALUES (230, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 09:43:13\",\"default\":false,\"dictCode\":110,\"dictLabel\":\"#ea4e3d\",\"dictSort\":2,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"#ea4e3d\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"浅红\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:03:51', 12); +INSERT INTO `sys_oper_log` VALUES (231, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"无图标\",\"dictSort\":0,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"NO_ICON\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:04:22', 16); +INSERT INTO `sys_oper_log` VALUES (232, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 11:04:21\",\"default\":false,\"dictCode\":130,\"dictLabel\":\"无图标\",\"dictSort\":1,\"dictType\":\"ff_member_label_icon\",\"dictValue\":\"NO_ICON\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 11:04:26', 14); +INSERT INTO `sys_oper_log` VALUES (233, '字典类型', 1, 'com.ff.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"vip等级图标背景\",\"dictType\":\"ff_membervip_icon_bg\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:20:37', 19); +INSERT INTO `sys_oper_log` VALUES (234, '字典类型', 2, 'com.ff.system.SysDictTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:20:37\",\"dictId\":106,\"dictName\":\"vip等级图标背景\",\"dictType\":\"ff_membervip_icon_bg\",\"params\":{},\"remark\":\"vip等级图标背景\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:20:42', 42); +INSERT INTO `sys_oper_log` VALUES (235, '字典类型', 2, 'com.ff.system.SysDictTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:20:37\",\"dictId\":106,\"dictName\":\"vip等级图标颜色\",\"dictType\":\"ff_membervip_icon_color\",\"params\":{},\"remark\":\"vip等级图标颜色\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:21:38', 59); +INSERT INTO `sys_oper_log` VALUES (236, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"浅绿\",\"dictSort\":0,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color1.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:25:07', 25); +INSERT INTO `sys_oper_log` VALUES (237, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"深绿\",\"dictSort\":0,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color2.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:26:03', 16); +INSERT INTO `sys_oper_log` VALUES (238, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:26:03\",\"default\":false,\"dictCode\":132,\"dictLabel\":\"深绿\",\"dictSort\":1,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color2.png\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:26:11', 15); +INSERT INTO `sys_oper_log` VALUES (239, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"浅蓝\",\"dictSort\":3,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color3.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:26:37', 16); +INSERT INTO `sys_oper_log` VALUES (240, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"深蓝\",\"dictSort\":4,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color4.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:27:26', 17); +INSERT INTO `sys_oper_log` VALUES (241, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:26:03\",\"default\":false,\"dictCode\":132,\"dictLabel\":\"深绿\",\"dictSort\":2,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color2.png\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:27:32', 23); +INSERT INTO `sys_oper_log` VALUES (242, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:25:07\",\"default\":false,\"dictCode\":131,\"dictLabel\":\"浅绿\",\"dictSort\":1,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color1.png\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:27:34', 14); +INSERT INTO `sys_oper_log` VALUES (243, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"橙\",\"dictSort\":5,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color5.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:28:09', 16); +INSERT INTO `sys_oper_log` VALUES (244, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:28:09\",\"default\":false,\"dictCode\":135,\"dictLabel\":\"橙色\",\"dictSort\":5,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color5.png\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:29:08', 15); +INSERT INTO `sys_oper_log` VALUES (245, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"咖色\",\"dictSort\":6,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color6.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:29:18', 14); +INSERT INTO `sys_oper_log` VALUES (246, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"深粉\",\"dictSort\":7,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color7.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:39:22', 36); +INSERT INTO `sys_oper_log` VALUES (247, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"深紫\",\"dictSort\":0,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color8.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:39:50', 17); +INSERT INTO `sys_oper_log` VALUES (248, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:39:50\",\"default\":false,\"dictCode\":138,\"dictLabel\":\"深紫\",\"dictSort\":8,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color8.png\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:40:09', 19); +INSERT INTO `sys_oper_log` VALUES (249, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"红色\",\"dictSort\":9,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color9.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:40:45', 15); +INSERT INTO `sys_oper_log` VALUES (250, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"酷黑\",\"dictSort\":10,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconColor/style_1_vip_color10.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:41:05', 13); +INSERT INTO `sys_oper_log` VALUES (251, '字典类型', 1, 'com.ff.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"vip等级图标样式\",\"dictType\":\"ff_membervip_icon_style\",\"params\":{},\"remark\":\"vip等级图标样式\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:42:14', 34); +INSERT INTO `sys_oper_log` VALUES (252, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style_0\",\"dictSort\":0,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconStyle/style_1_vip_style0.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:42:52', 18); +INSERT INTO `sys_oper_log` VALUES (253, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style_1\",\"dictSort\":0,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconStyle/style_1_vip_style1.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:43:25', 15); +INSERT INTO `sys_oper_log` VALUES (254, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:43:25\",\"default\":false,\"dictCode\":142,\"dictLabel\":\"style_1\",\"dictSort\":1,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconStyle/style_1_vip_style1.png\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:43:34', 15); +INSERT INTO `sys_oper_log` VALUES (255, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style_2\",\"dictSort\":2,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconStyle/style_1_vip_style2.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:44:15', 11); +INSERT INTO `sys_oper_log` VALUES (256, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style_3\",\"dictSort\":3,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconStyle/style_1_vip_style3.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:44:32', 13); +INSERT INTO `sys_oper_log` VALUES (257, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style_4\",\"dictSort\":4,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconStyle/style_1_vip_style4.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:45:13', 19); +INSERT INTO `sys_oper_log` VALUES (258, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style_5\",\"dictSort\":5,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconStyle/style_1_vip_style5.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:45:33', 14); +INSERT INTO `sys_oper_log` VALUES (259, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style_6\",\"dictSort\":6,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconStyle/style_1_vip_style6.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:46:39', 34); +INSERT INTO `sys_oper_log` VALUES (260, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style_7\",\"dictSort\":7,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconStyle/style_1_vip_style7.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:46:59', 15); +INSERT INTO `sys_oper_log` VALUES (261, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style_8\",\"dictSort\":8,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconStyle/style_1_vip_style8.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:48:13', 31); +INSERT INTO `sys_oper_log` VALUES (262, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style_9\",\"dictSort\":9,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconStyle/style_1_vip_style9.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:48:30', 12); +INSERT INTO `sys_oper_log` VALUES (263, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style_10\",\"dictSort\":10,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/active/style1/iconStyle/style_1_vip_style10.png\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:48:48', 17); +INSERT INTO `sys_oper_log` VALUES (264, '会员标签', 1, 'com.ff.member.controller.MemberLabelController.add()', 'POST', 1, 'admin', '研发部门', '/member/label', '192.168.1.34', '内网IP', '{\"createTime\":\"2024-10-14 13:49:34\",\"iconColor\":\"#4cb5ff\",\"labelName\":\"测试\",\"orderNum\":1,\"params\":{},\"remark\":\"测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试测是测试\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 13:49:34', 17); +INSERT INTO `sys_oper_log` VALUES (265, '会员标签', 3, 'com.ff.member.controller.MemberLabelController.remove()', 'DELETE', 1, 'admin', '研发部门', '/member/label/1', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 14:16:57', 16); +INSERT INTO `sys_oper_log` VALUES (266, '会员标签', 1, 'com.ff.member.controller.MemberLabelController.add()', 'POST', 1, 'admin', '研发部门', '/member/label', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 14:18:30\",\"iconColor\":\"#1677fd\",\"labelName\":\"测试测试\",\"orderNum\":1,\"params\":{},\"remark\":\"这是一个普通的描述\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 14:18:30', 18); +INSERT INTO `sys_oper_log` VALUES (267, '代码生成', 6, 'com.ff.gen.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_level\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 14:24:30', 103); +INSERT INTO `sys_oper_log` VALUES (268, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"level\",\"className\":\"MemberLevel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":20,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 14:24:30\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":3,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"LevelType\",\"columnComment\":\"0.自动层级 1.固定层级\",\"columnId\":21,\"columnName\":\"level_type\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 14:24:30\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"select\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"levelType\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":3,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"LevelName\",\"columnComment\":\"层级名称\",\"columnId\":22,\"columnName\":\"level_name\",\"columnType\":\"varchar(24)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 14:24:30\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"levelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":3,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"LabelId\",\"columnComment\":\"会员标签表id\",\"columnId\":23,\"columnName\":\"label_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 14:24:30\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 14:25:07', 59); +INSERT INTO `sys_oper_log` VALUES (269, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"level\",\"className\":\"MemberLevel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":20,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 14:24:30\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":3,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 14:25:07\",\"usableColumn\":false},{\"capJavaField\":\"LevelType\",\"columnComment\":\"0.自动层级 1.固定层级\",\"columnId\":21,\"columnName\":\"level_type\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 14:24:30\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"select\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"levelType\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":3,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 14:25:07\",\"usableColumn\":false},{\"capJavaField\":\"LevelName\",\"columnComment\":\"层级名称\",\"columnId\":22,\"columnName\":\"level_name\",\"columnType\":\"varchar(24)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 14:24:30\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"levelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":3,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 14:25:07\",\"usableColumn\":false},{\"capJavaField\":\"LabelId\",\"columnComment\":\"会员标签表id\",\"columnId\":23,\"columnName\":\"label_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 14:24:30\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"inse', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 14:25:49', 48); +INSERT INTO `sys_oper_log` VALUES (270, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"MemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:53:28\",\"usableColumn\":false},{\"capJavaField\":\"OrderNum\",\"columnComment\":\"显示顺序\",\"columnId\":19,\"columnName\":\"order_num\",\"columnType\":\"int\",\"createBy\":\"\",\"createTime\":\"2024-10-14 10:52:39\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"orderNum\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":true,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:53:28\",\"usableColumn\":true},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 10:53:28\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 14:26:03', 33); +INSERT INTO `sys_oper_log` VALUES (271, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"label\",\"className\":\"MemberLabel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":11,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 14:26:03\",\"usableColumn\":false},{\"capJavaField\":\"OrderNum\",\"columnComment\":\"显示顺序\",\"columnId\":19,\"columnName\":\"order_num\",\"columnType\":\"int\",\"createBy\":\"\",\"createTime\":\"2024-10-14 10:52:39\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"orderNum\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":true,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 14:26:03\",\"usableColumn\":true},{\"capJavaField\":\"LabelName\",\"columnComment\":\"标签名称\",\"columnId\":12,\"columnName\":\"label_name\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"labelName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-10-14 14:26:03\",\"usableColumn\":false},{\"capJavaField\":\"IconColor\",\"columnComment\":\"图标颜色\",\"columnId\":13,\"columnName\":\"icon_color\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-14 09:53:09\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 14:26:12', 35); +INSERT INTO `sys_oper_log` VALUES (272, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_level\"}', NULL, 0, NULL, '2024-10-14 14:26:32', 106); +INSERT INTO `sys_oper_log` VALUES (273, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"component\":\"member/level/index\",\"createTime\":\"2024-10-14 14:29:00\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":3013,\"menuName\":\"会员层级\",\"menuType\":\"C\",\"orderNum\":2,\"params\":{},\"parentId\":3006,\"path\":\"level\",\"perms\":\"member:level:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 14:29:25', 27); +INSERT INTO `sys_oper_log` VALUES (274, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_level\"}', NULL, 0, NULL, '2024-10-14 14:44:22', 235); +INSERT INTO `sys_oper_log` VALUES (275, '字典类型', 1, 'com.ff.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"vip等级图标父样式\",\"dictType\":\"ff_membervip_icon_parent_style\",\"params\":{},\"remark\":\"vip等级图标父样式\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:44:59', 34); +INSERT INTO `sys_oper_log` VALUES (276, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style1\",\"dictSort\":1,\"dictType\":\"ff_membervip_icon_parent_style\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:48:20', 31); +INSERT INTO `sys_oper_log` VALUES (277, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style2\",\"dictSort\":2,\"dictType\":\"ff_membervip_icon_parent_style\",\"dictValue\":\"2\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:48:38', 13); +INSERT INTO `sys_oper_log` VALUES (278, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style3\",\"dictSort\":3,\"dictType\":\"ff_membervip_icon_parent_style\",\"dictValue\":\"3\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:48:50', 14); +INSERT INTO `sys_oper_log` VALUES (279, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"style4\",\"dictSort\":4,\"dictType\":\"ff_membervip_icon_parent_style\",\"dictValue\":\"4\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:49:01', 16); +INSERT INTO `sys_oper_log` VALUES (280, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:42:52\",\"default\":false,\"dictCode\":141,\"dictLabel\":\"style_0\",\"dictSort\":0,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"0\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:49:54', 19); +INSERT INTO `sys_oper_log` VALUES (281, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:43:25\",\"default\":false,\"dictCode\":142,\"dictLabel\":\"style_1\",\"dictSort\":1,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"1\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:50:00', 16); +INSERT INTO `sys_oper_log` VALUES (282, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:44:15\",\"default\":false,\"dictCode\":143,\"dictLabel\":\"style_2\",\"dictSort\":2,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"2\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:50:04', 14); +INSERT INTO `sys_oper_log` VALUES (283, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:44:32\",\"default\":false,\"dictCode\":144,\"dictLabel\":\"style_3\",\"dictSort\":3,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"3\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:50:08', 16); +INSERT INTO `sys_oper_log` VALUES (284, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:45:13\",\"default\":false,\"dictCode\":145,\"dictLabel\":\"style_4\",\"dictSort\":4,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"4\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:50:12', 14); +INSERT INTO `sys_oper_log` VALUES (285, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:45:33\",\"default\":false,\"dictCode\":146,\"dictLabel\":\"style_5\",\"dictSort\":5,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"5\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:50:16', 13); +INSERT INTO `sys_oper_log` VALUES (286, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:46:39\",\"default\":false,\"dictCode\":147,\"dictLabel\":\"style_6\",\"dictSort\":6,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"6\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:50:20', 14); +INSERT INTO `sys_oper_log` VALUES (287, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:46:59\",\"default\":false,\"dictCode\":148,\"dictLabel\":\"style_7\",\"dictSort\":7,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"7\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:50:25', 13); +INSERT INTO `sys_oper_log` VALUES (288, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:48:13\",\"default\":false,\"dictCode\":149,\"dictLabel\":\"style_8\",\"dictSort\":8,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"8\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:50:30', 15); +INSERT INTO `sys_oper_log` VALUES (289, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:48:30\",\"default\":false,\"dictCode\":150,\"dictLabel\":\"style_9\",\"dictSort\":9,\"dictType\":\"ff_membervip_icon_style\",\"dictValue\":\"9\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:50:35', 15); +INSERT INTO `sys_oper_log` VALUES (290, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:25:07\",\"default\":false,\"dictCode\":131,\"dictLabel\":\"color1\",\"dictSort\":1,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"1\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:51:18', 18); +INSERT INTO `sys_oper_log` VALUES (291, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:26:03\",\"default\":false,\"dictCode\":132,\"dictLabel\":\"color2\",\"dictSort\":2,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"2\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:51:30', 12); +INSERT INTO `sys_oper_log` VALUES (292, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:26:37\",\"default\":false,\"dictCode\":133,\"dictLabel\":\"color3\",\"dictSort\":3,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"3\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:51:40', 16); +INSERT INTO `sys_oper_log` VALUES (293, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:27:26\",\"default\":false,\"dictCode\":134,\"dictLabel\":\"color4\",\"dictSort\":4,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"4\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:51:49', 15); +INSERT INTO `sys_oper_log` VALUES (294, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:28:09\",\"default\":false,\"dictCode\":135,\"dictLabel\":\"color5\",\"dictSort\":5,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"5\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:51:58', 13); +INSERT INTO `sys_oper_log` VALUES (295, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:29:18\",\"default\":false,\"dictCode\":136,\"dictLabel\":\"color6\",\"dictSort\":6,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"6\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:52:06', 16); +INSERT INTO `sys_oper_log` VALUES (296, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:39:22\",\"default\":false,\"dictCode\":137,\"dictLabel\":\"color7\",\"dictSort\":7,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"7\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:52:13', 9); +INSERT INTO `sys_oper_log` VALUES (297, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:39:50\",\"default\":false,\"dictCode\":138,\"dictLabel\":\"color8\",\"dictSort\":8,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"8\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:52:33', 13); +INSERT INTO `sys_oper_log` VALUES (298, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:40:45\",\"default\":false,\"dictCode\":139,\"dictLabel\":\"color9\",\"dictSort\":9,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"9\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:52:42', 16); +INSERT INTO `sys_oper_log` VALUES (299, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:41:05\",\"default\":false,\"dictCode\":140,\"dictLabel\":\"color10\",\"dictSort\":10,\"dictType\":\"ff_membervip_icon_color\",\"dictValue\":\"10\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:52:53', 12); +INSERT INTO `sys_oper_log` VALUES (300, '字典类型', 2, 'com.ff.system.SysDictTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 15:44:59\",\"dictId\":108,\"dictName\":\"vip等级图标父样式\",\"dictType\":\"ff_vip_icon_parent_style\",\"params\":{},\"remark\":\"vip等级图标父样式\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:54:59', 38); +INSERT INTO `sys_oper_log` VALUES (301, '字典类型', 2, 'com.ff.system.SysDictTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:42:14\",\"dictId\":107,\"dictName\":\"vip等级图标样式\",\"dictType\":\"ff_vip_icon_style\",\"params\":{},\"remark\":\"vip等级图标样式\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:55:09', 28); +INSERT INTO `sys_oper_log` VALUES (302, '字典类型', 2, 'com.ff.system.SysDictTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:20:37\",\"dictId\":106,\"dictName\":\"vip等级图标颜色\",\"dictType\":\"ff_vip_icon_color\",\"params\":{},\"remark\":\"vip等级图标颜色\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-14 15:55:14', 33); +INSERT INTO `sys_oper_log` VALUES (303, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 16:24:29\",\"default\":false,\"dictCode\":120,\"dictLabel\":\"APP-iOS\",\"dictSort\":0,\"dictType\":\"ff_device_type\",\"dictValue\":\"APP-iOS\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"APP-iOS\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:35:11', 11); +INSERT INTO `sys_oper_log` VALUES (304, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 16:25:18\",\"default\":false,\"dictCode\":121,\"dictLabel\":\"H5-iOS\",\"dictSort\":0,\"dictType\":\"ff_device_type\",\"dictValue\":\"H5-iOS\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"H5-iOS\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:35:17', 11); +INSERT INTO `sys_oper_log` VALUES (305, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 16:25:43\",\"default\":false,\"dictCode\":122,\"dictLabel\":\"APP-Android\",\"dictSort\":0,\"dictType\":\"ff_device_type\",\"dictValue\":\"APP-Android\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"APP-Android\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:35:22', 7); +INSERT INTO `sys_oper_log` VALUES (306, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 16:26:09\",\"default\":false,\"dictCode\":123,\"dictLabel\":\"H5-Android\",\"dictSort\":0,\"dictType\":\"ff_device_type\",\"dictValue\":\"H5-Android\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"H5-Android\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:35:28', 13); +INSERT INTO `sys_oper_log` VALUES (307, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 16:26:41\",\"default\":false,\"dictCode\":124,\"dictLabel\":\"PC-Windows\",\"dictSort\":0,\"dictType\":\"ff_device_type\",\"dictValue\":\"PC-Windows\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"PC-Windows\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:35:33', 13); +INSERT INTO `sys_oper_log` VALUES (308, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 16:27:06\",\"default\":false,\"dictCode\":125,\"dictLabel\":\"PC-Mac\",\"dictSort\":0,\"dictType\":\"ff_device_type\",\"dictValue\":\"PC-Mac\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"PC-Mac\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:35:38', 19); +INSERT INTO `sys_oper_log` VALUES (309, '字典类型', 1, 'com.ff.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"会员日志操作项目\",\"dictType\":\"ff_log_oprproject\",\"params\":{},\"remark\":\"会员日志操作项目\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:41:00', 6); +INSERT INTO `sys_oper_log` VALUES (310, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"姓名\",\"dictSort\":0,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:42:38', 32); +INSERT INTO `sys_oper_log` VALUES (311, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"手机号\",\"dictSort\":1,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:43:10', 12); +INSERT INTO `sys_oper_log` VALUES (312, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:42:38\",\"default\":false,\"dictCode\":156,\"dictLabel\":\"姓名\",\"dictSort\":0,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"0\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:43:26', 8); +INSERT INTO `sys_oper_log` VALUES (313, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"账号状态\",\"dictSort\":2,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"2\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:44:34', 24); +INSERT INTO `sys_oper_log` VALUES (314, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"银行卡\",\"dictSort\":3,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"3\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:45:08', 12); +INSERT INTO `sys_oper_log` VALUES (315, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"cssClass\":\"\",\"default\":false,\"dictLabel\":\"账号密码\",\"dictSort\":4,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"4\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:46:13', 24); +INSERT INTO `sys_oper_log` VALUES (316, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"忘记密码\",\"dictSort\":5,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"5\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:48:37', 36); +INSERT INTO `sys_oper_log` VALUES (317, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"提现密码\",\"dictSort\":6,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"6\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:49:06', 11); +INSERT INTO `sys_oper_log` VALUES (318, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"WhatsApp\",\"dictSort\":7,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"7\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:50:30', 33); +INSERT INTO `sys_oper_log` VALUES (319, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"Facebook\",\"dictSort\":8,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"8\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:50:57', 13); +INSERT INTO `sys_oper_log` VALUES (320, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"Telegram\",\"dictSort\":9,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"9\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:51:20', 10); +INSERT INTO `sys_oper_log` VALUES (321, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"Zalo\",\"dictSort\":10,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"10\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:51:40', 8); +INSERT INTO `sys_oper_log` VALUES (322, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"邮箱地址\",\"dictSort\":11,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"11\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:52:30', 12); +INSERT INTO `sys_oper_log` VALUES (323, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"手势密码\",\"dictSort\":12,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"12\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:52:54', 12); +INSERT INTO `sys_oper_log` VALUES (324, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"谷歌验证\",\"dictSort\":13,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"13\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:53:19', 14); +INSERT INTO `sys_oper_log` VALUES (325, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"密保问题\",\"dictSort\":14,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"14\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:53:55', 13); +INSERT INTO `sys_oper_log` VALUES (326, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"会员层级\",\"dictSort\":15,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"15\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:54:29', 18); +INSERT INTO `sys_oper_log` VALUES (327, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"上级代理\",\"dictSort\":16,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"16\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:55:06', 12); +INSERT INTO `sys_oper_log` VALUES (328, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"登录\",\"dictSort\":17,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"17\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:55:25', 13); +INSERT INTO `sys_oper_log` VALUES (329, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"登出\",\"dictSort\":18,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"18\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:55:37', 10); +INSERT INTO `sys_oper_log` VALUES (330, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"VIP等级\",\"dictSort\":19,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"19\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 09:56:18', 11); +INSERT INTO `sys_oper_log` VALUES (331, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:42:38\",\"default\":false,\"dictCode\":156,\"dictLabel\":\"姓名\",\"dictSort\":0,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"姓名\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:04:41', 11); +INSERT INTO `sys_oper_log` VALUES (332, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:43:10\",\"default\":false,\"dictCode\":157,\"dictLabel\":\"手机号\",\"dictSort\":1,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"手机号\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:04:46', 14); +INSERT INTO `sys_oper_log` VALUES (333, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:44:34\",\"default\":false,\"dictCode\":158,\"dictLabel\":\"账号状态\",\"dictSort\":2,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"账号状态\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:04:51', 14); +INSERT INTO `sys_oper_log` VALUES (334, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:45:08\",\"default\":false,\"dictCode\":159,\"dictLabel\":\"银行卡\",\"dictSort\":3,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"银行卡\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:04:55', 12); +INSERT INTO `sys_oper_log` VALUES (335, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:46:13\",\"default\":false,\"dictCode\":160,\"dictLabel\":\"账号密码\",\"dictSort\":4,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"账号密码\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:05:01', 12); +INSERT INTO `sys_oper_log` VALUES (336, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:48:37\",\"default\":false,\"dictCode\":161,\"dictLabel\":\"忘记密码\",\"dictSort\":5,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"忘记密码\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:05:06', 11); +INSERT INTO `sys_oper_log` VALUES (337, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:49:06\",\"default\":false,\"dictCode\":162,\"dictLabel\":\"提现密码\",\"dictSort\":6,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"提现密码\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:05:11', 11); +INSERT INTO `sys_oper_log` VALUES (338, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:50:30\",\"default\":false,\"dictCode\":163,\"dictLabel\":\"WhatsApp\",\"dictSort\":7,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"WhatsApp\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:05:16', 12); +INSERT INTO `sys_oper_log` VALUES (339, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:50:57\",\"default\":false,\"dictCode\":164,\"dictLabel\":\"Facebook\",\"dictSort\":8,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"Facebook\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:05:20', 11); +INSERT INTO `sys_oper_log` VALUES (340, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:51:20\",\"default\":false,\"dictCode\":165,\"dictLabel\":\"Telegram\",\"dictSort\":9,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"Telegram\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:05:24', 10); +INSERT INTO `sys_oper_log` VALUES (341, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:51:40\",\"default\":false,\"dictCode\":166,\"dictLabel\":\"Zalo\",\"dictSort\":10,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"Zalo\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:05:30', 13); +INSERT INTO `sys_oper_log` VALUES (342, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:52:30\",\"default\":false,\"dictCode\":167,\"dictLabel\":\"邮箱地址\",\"dictSort\":11,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"邮箱地址\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:05:34', 15); +INSERT INTO `sys_oper_log` VALUES (343, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:52:54\",\"default\":false,\"dictCode\":168,\"dictLabel\":\"手势密码\",\"dictSort\":12,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"手势密码\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:05:38', 11); +INSERT INTO `sys_oper_log` VALUES (344, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:53:19\",\"default\":false,\"dictCode\":169,\"dictLabel\":\"谷歌验证\",\"dictSort\":13,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"谷歌验证\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:05:43', 12); +INSERT INTO `sys_oper_log` VALUES (345, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:53:55\",\"default\":false,\"dictCode\":170,\"dictLabel\":\"密保问题\",\"dictSort\":14,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"密保问题\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:05:50', 10); +INSERT INTO `sys_oper_log` VALUES (346, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:54:29\",\"default\":false,\"dictCode\":171,\"dictLabel\":\"会员层级\",\"dictSort\":15,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"会员层级\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:05:56', 15); +INSERT INTO `sys_oper_log` VALUES (347, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:55:06\",\"default\":false,\"dictCode\":172,\"dictLabel\":\"上级代理\",\"dictSort\":16,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"上级代理\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:06:01', 14); +INSERT INTO `sys_oper_log` VALUES (348, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:55:25\",\"default\":false,\"dictCode\":173,\"dictLabel\":\"登录\",\"dictSort\":17,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"登录\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:06:06', 10); +INSERT INTO `sys_oper_log` VALUES (349, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:55:37\",\"default\":false,\"dictCode\":174,\"dictLabel\":\"登出\",\"dictSort\":18,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"登出\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:06:09', 13); +INSERT INTO `sys_oper_log` VALUES (350, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:56:18\",\"default\":false,\"dictCode\":175,\"dictLabel\":\"VIP等级\",\"dictSort\":19,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"登出\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:06:13', 9); +INSERT INTO `sys_oper_log` VALUES (351, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:56:18\",\"default\":false,\"dictCode\":175,\"dictLabel\":\"VIP等级\",\"dictSort\":19,\"dictType\":\"ff_log_oprproject\",\"dictValue\":\"VIP等级\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:06:18', 10); +INSERT INTO `sys_oper_log` VALUES (352, '字典类型', 2, 'com.ff.system.SysDictTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 09:41:00\",\"dictId\":109,\"dictName\":\"会员日志操作项目\",\"dictType\":\"ff_log_operproject\",\"params\":{},\"remark\":\"会员日志操作项目\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:09:51', 18); +INSERT INTO `sys_oper_log` VALUES (353, '字典类型', 1, 'com.ff.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"会员操作类型\",\"dictType\":\"ff_oper_type\",\"params\":{},\"remark\":\"会员操作类型\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:10:56', 29); +INSERT INTO `sys_oper_log` VALUES (354, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"无\",\"dictSort\":0,\"dictType\":\"ff_oper_type\",\"dictValue\":\"无\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:11:57', 10); +INSERT INTO `sys_oper_log` VALUES (355, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"新增\",\"dictSort\":0,\"dictType\":\"ff_oper_type\",\"dictValue\":\"新增\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:12:11', 10); +INSERT INTO `sys_oper_log` VALUES (356, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"修改\",\"dictSort\":0,\"dictType\":\"ff_oper_type\",\"dictValue\":\"修改\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:12:19', 12); +INSERT INTO `sys_oper_log` VALUES (357, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 10:12:11\",\"default\":false,\"dictCode\":177,\"dictLabel\":\"新增\",\"dictSort\":1,\"dictType\":\"ff_oper_type\",\"dictValue\":\"新增\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:12:24', 11); +INSERT INTO `sys_oper_log` VALUES (358, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-15 10:12:19\",\"default\":false,\"dictCode\":178,\"dictLabel\":\"修改\",\"dictSort\":2,\"dictType\":\"ff_oper_type\",\"dictValue\":\"修改\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 10:12:32', 11); +INSERT INTO `sys_oper_log` VALUES (359, '个人信息', 2, 'com.ff.system.SysProfileController.updateProfile()', 'PUT', 1, 'admin', '研发部门', '/system/user/profile', '192.168.1.29', '内网IP', '{\"admin\":false,\"email\":\"ry@163.com\",\"nickName\":\"FF\",\"params\":{},\"phonenumber\":\"15888888888\",\"sex\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 15:29:26', 19); +INSERT INTO `sys_oper_log` VALUES (360, '代码生成', 6, 'com.ff.gen.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '192.168.1.29', '内网IP', '{\"tables\":\"ff_member_vip\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:07:03', 176); +INSERT INTO `sys_oper_log` VALUES (361, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.29', '内网IP', '{\"businessName\":\"vip\",\"className\":\"MemberVip\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":32,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Grade\",\"columnComment\":\"等级\",\"columnId\":33,\"columnName\":\"grade\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"grade\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CurrencyType\",\"columnComment\":\"币种(字典ff_currency)\",\"columnId\":34,\"columnName\":\"currency_type\",\"columnType\":\"varchar(10)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"select\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"currencyType\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IconParentStyle\",\"columnComment\":\"图标父样式(字典ff_vip_icon_parent_style\\t)\",\"columnId\":35,\"columnName\":\"icon_parent_style\",\"columnType\":\"varchar(200)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:09:16', 120); +INSERT INTO `sys_oper_log` VALUES (362, '代码生成', 6, 'com.ff.gen.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '192.168.1.34', '内网IP', '{\"tables\":\"sys_role\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:12:37', 65); +INSERT INTO `sys_oper_log` VALUES (363, '代码生成', 3, 'com.ff.gen.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/5', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:15:12', 21); +INSERT INTO `sys_oper_log` VALUES (364, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_vip\"}', NULL, 0, NULL, '2024-10-15 16:20:50', 159); +INSERT INTO `sys_oper_log` VALUES (365, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"component\":\"member/vip/index\",\"createTime\":\"2024-10-15 16:21:35\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":3019,\"menuName\":\"vip等级\",\"menuType\":\"C\",\"orderNum\":3,\"params\":{},\"parentId\":3006,\"path\":\"vip\",\"perms\":\"member:vip:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:22:29', 16); +INSERT INTO `sys_oper_log` VALUES (366, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"component\":\"member/vip/index\",\"createTime\":\"2024-10-15 16:21:35\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":3019,\"menuName\":\"VIP等级\",\"menuType\":\"C\",\"orderNum\":3,\"params\":{},\"parentId\":3006,\"path\":\"vip\",\"perms\":\"member:vip:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:22:45', 11); +INSERT INTO `sys_oper_log` VALUES (367, '代码生成', 6, 'com.ff.gen.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_vip_setup\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:31:37', 174); +INSERT INTO `sys_oper_log` VALUES (368, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"vipSetup\",\"className\":\"MemberVipSetup\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":72,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:31:37\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"KeepGrade\",\"columnComment\":\"保级开关(0.关闭 1.开启)\",\"columnId\":73,\"columnName\":\"keep_grade\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:31:37\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"keepGrade\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"RewardSwitch\",\"columnComment\":\"奖励开关(0.关闭 1.开启)\",\"columnId\":74,\"columnName\":\"reward_switch\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:31:37\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"rewardSwitch\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"SalaryType\",\"columnComment\":\"俸禄类型(0.日俸禄 1.周俸禄 2.月俸禄 3.日/周/月 公共设置 4.其他设置(包含保级、奖励开关))\",\"columnId\":75,\"columnName\":\"salary_type\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:31:37\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"select\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isInc', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:37:32', 155); +INSERT INTO `sys_oper_log` VALUES (369, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_vip_setup\"}', NULL, 0, NULL, '2024-10-15 16:37:38', 327); +INSERT INTO `sys_oper_log` VALUES (370, '代码生成', 6, 'com.ff.gen.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_log\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:40:47', 62); +INSERT INTO `sys_oper_log` VALUES (371, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"log\",\"className\":\"MemberLog\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":94,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:40:47\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"MemberId\",\"columnComment\":\"会员id\",\"columnId\":95,\"columnName\":\"member_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:40:47\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"memberId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"MemberAccount\",\"columnComment\":\"会员账号\",\"columnId\":96,\"columnName\":\"member_account\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:40:47\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"memberAccount\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"OperateTime\",\"columnComment\":\"操作时间\",\"columnId\":97,\"columnName\":\"operate_time\",\"columnType\":\"datetime\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:40:47\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"datetime\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:43:18', 62); +INSERT INTO `sys_oper_log` VALUES (372, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"vip\",\"className\":\"MemberVip\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":32,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-10-15 16:09:16\",\"usableColumn\":false},{\"capJavaField\":\"Grade\",\"columnComment\":\"等级\",\"columnId\":33,\"columnName\":\"grade\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"grade\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-10-15 16:09:16\",\"usableColumn\":false},{\"capJavaField\":\"CurrencyType\",\"columnComment\":\"币种(字典ff_currency)\",\"columnId\":34,\"columnName\":\"currency_type\",\"columnType\":\"varchar(10)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"ff_currency\",\"edit\":true,\"htmlType\":\"select\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"currencyType\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-10-15 16:09:16\",\"usableColumn\":false},{\"capJavaField\":\"IconParentStyle\",\"columnComment\":\"图标父样式(字典ff_vip_icon_parent_style\\t)\",\"columnId\":35,\"columnName\":\"icon_parent_style\",\"columnType\":\"varchar(200)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"ff_vip_i', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:44:40', 72); +INSERT INTO `sys_oper_log` VALUES (373, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_log\"}', NULL, 0, NULL, '2024-10-15 16:45:05', 131); +INSERT INTO `sys_oper_log` VALUES (374, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"component\":\"member/log/index\",\"createTime\":\"2024-10-15 16:45:54\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":3025,\"menuName\":\"会员日志\",\"menuType\":\"C\",\"orderNum\":4,\"params\":{},\"parentId\":3006,\"path\":\"log\",\"perms\":\"member:log:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:46:17', 23); +INSERT INTO `sys_oper_log` VALUES (375, '代码生成', 6, 'com.ff.gen.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:48:54', 144); +INSERT INTO `sys_oper_log` VALUES (376, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"member\",\"className\":\"Member\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":113,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:48:54\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CurrencyType\",\"columnComment\":\"币种(字典ff_currency)\",\"columnId\":114,\"columnName\":\"currency_type\",\"columnType\":\"varchar(10)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:48:54\",\"dictType\":\"ff_currency\",\"edit\":true,\"htmlType\":\"select\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"currencyType\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"MemberAccount\",\"columnComment\":\"会员账号\",\"columnId\":115,\"columnName\":\"member_account\",\"columnType\":\"varchar(16)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:48:54\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"memberAccount\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"RealName\",\"columnComment\":\"会员姓名\",\"columnId\":116,\"columnName\":\"real_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:48:54\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:53:42', 128); +INSERT INTO `sys_oper_log` VALUES (377, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member\"}', NULL, 0, NULL, '2024-10-15 16:53:49', 118); +INSERT INTO `sys_oper_log` VALUES (378, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"component\":\"member/member/index\",\"createTime\":\"2024-10-15 16:54:31\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":3031,\"menuName\":\"所有会员\",\"menuType\":\"C\",\"orderNum\":0,\"params\":{},\"parentId\":3006,\"path\":\"member\",\"perms\":\"member:member:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-15 16:54:55', 11); +INSERT INTO `sys_oper_log` VALUES (379, '代码生成', 2, 'com.ff.gen.controller.GenController.synchDb()', 'GET', 1, 'admin', '研发部门', '/tool/gen/synchDb/ff_member_vip_setup', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 09:54:34', 197); +INSERT INTO `sys_oper_log` VALUES (380, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_vip_setup\"}', NULL, 0, NULL, '2024-10-16 09:54:38', 304); +INSERT INTO `sys_oper_log` VALUES (381, '代码生成', 2, 'com.ff.gen.controller.GenController.synchDb()', 'GET', 1, 'admin', '研发部门', '/tool/gen/synchDb/ff_member_vip_setup', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 09:59:34', 208); +INSERT INTO `sys_oper_log` VALUES (382, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"vipSetup\",\"className\":\"MemberVipSetup\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":72,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:31:37\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-10-16 09:59:34\",\"usableColumn\":false},{\"capJavaField\":\"KeepGrade\",\"columnComment\":\"保级开关(0.关闭 1.开启)\",\"columnId\":73,\"columnName\":\"keep_grade\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:31:37\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"keepGrade\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-10-16 09:59:34\",\"usableColumn\":false},{\"capJavaField\":\"RewardSwitch\",\"columnComment\":\"奖励开关(0.关闭 1.开启)\",\"columnId\":74,\"columnName\":\"reward_switch\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:31:37\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"rewardSwitch\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-10-16 09:59:34\",\"usableColumn\":false},{\"capJavaField\":\"SetType\",\"columnComment\":\"设置类型(0.日俸禄 1.周俸禄 2.月俸禄 3.日/周/月 公共设置 4.其他设置(包含保级、奖励开关))\",\"columnId\":167,\"columnName\":\"set_type\",\"columnType\":\"tinyint\",\"createBy\":\"\",\"createTime\":\"2024-10-16 09:59:34\",\"d', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 10:00:33', 101); +INSERT INTO `sys_oper_log` VALUES (383, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_vip_setup\"}', NULL, 0, NULL, '2024-10-16 10:01:02', 280); +INSERT INTO `sys_oper_log` VALUES (384, '代码生成', 2, 'com.ff.gen.controller.GenController.synchDb()', 'GET', 1, 'admin', '研发部门', '/tool/gen/synchDb/ff_member_vip_setup', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 10:24:43', 110); +INSERT INTO `sys_oper_log` VALUES (385, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"vipSetup\",\"className\":\"MemberVipSetup\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":72,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:31:37\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-10-16 10:24:43\",\"usableColumn\":false},{\"capJavaField\":\"KeepGrade\",\"columnComment\":\"保级开关(0.关闭 1.开启)\",\"columnId\":73,\"columnName\":\"keep_grade\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:31:37\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"keepGrade\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-10-16 10:24:43\",\"usableColumn\":false},{\"capJavaField\":\"RewardSwitch\",\"columnComment\":\"奖励开关(0.关闭 1.开启)\",\"columnId\":74,\"columnName\":\"reward_switch\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:31:37\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"rewardSwitch\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-10-16 10:24:43\",\"usableColumn\":false},{\"capJavaField\":\"SetType\",\"columnComment\":\"设置类型(0.日俸禄 1.周俸禄 2.月俸禄 3.日/周/月 公共设置 4.其他设置(包含保级、奖励开关))\",\"columnId\":167,\"columnName\":\"set_type\",\"columnType\":\"tinyint\",\"createBy\":\"\",\"createTime\":\"2024-10-16 09:59:34\",\"d', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 10:25:23', 70); +INSERT INTO `sys_oper_log` VALUES (386, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_vip_setup\"}', NULL, 0, NULL, '2024-10-16 10:25:33', 133); +INSERT INTO `sys_oper_log` VALUES (387, '会员vip等级公共设置奖励开关', 2, 'com.ff.member.controller.MemberVipSetupController.editRewardSwitch()', 'PUT', 1, 'admin', '研发部门', '/member/vipSetup/editRewardSwitch', '192.168.1.29', '内网IP', '', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 11:33:11', 49); +INSERT INTO `sys_oper_log` VALUES (388, '会员vip等级公共设置奖励开关', 2, 'com.ff.member.controller.MemberVipSetupController.editRewardSwitch()', 'PUT', 1, 'admin', '研发部门', '/member/vipSetup/editRewardSwitch', '192.168.1.29', '内网IP', '', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 11:33:59', 9428); +INSERT INTO `sys_oper_log` VALUES (389, '会员vip等级公共设置奖励开关', 2, 'com.ff.member.controller.MemberVipSetupController.editRewardSwitch()', 'PUT', 1, 'admin', '研发部门', '/member/vipSetup/editRewardSwitch', '192.168.1.29', '内网IP', '', '{\"msg\":\"奖励开关不能为空\",\"code\":500}', 0, NULL, '2024-10-16 11:35:30', 7); +INSERT INTO `sys_oper_log` VALUES (390, '会员vip等级公共设置奖励开关', 2, 'com.ff.member.controller.MemberVipSetupController.editRewardSwitch()', 'PUT', 1, 'admin', '研发部门', '/member/vipSetup/editRewardSwitch', '192.168.1.29', '内网IP', '{\"rewardSwitch\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 11:35:50', 20); +INSERT INTO `sys_oper_log` VALUES (391, '会员vip等级公共设置奖励开关', 2, 'com.ff.member.controller.MemberVipSetupController.editRewardSwitch()', 'PUT', 1, 'admin', '研发部门', '/member/vipSetup/editRewardSwitch', '192.168.1.29', '内网IP', '{\"rewardSwitch\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 11:35:58', 13); +INSERT INTO `sys_oper_log` VALUES (392, '会员vip等级公共设置奖励开关', 2, 'com.ff.member.controller.MemberVipSetupController.editRewardSwitch()', 'PUT', 1, 'admin', '研发部门', '/member/vipSetup/editRewardSwitch', '192.168.1.29', '内网IP', '{\"rewardSwitch\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 11:36:02', 6); +INSERT INTO `sys_oper_log` VALUES (393, '会员vip等级公共设置', 2, 'com.ff.member.controller.MemberVipSetupController.editMemberCommonSetUp()', 'PUT', 1, 'admin', '研发部门', '/member/vipSetup/editMemberCommonSetUp', '192.168.1.29', '内网IP', '[]', '{\"msg\":\"会员vip等级公共设置列表不能为空\",\"code\":500}', 0, NULL, '2024-10-16 13:22:51', 10); +INSERT INTO `sys_oper_log` VALUES (394, '会员vip等级公共设置', 2, 'com.ff.member.controller.MemberVipSetupController.editMemberCommonSetUp()', 'PUT', 1, 'admin', '研发部门', '/member/vipSetup/editMemberCommonSetUp', '192.168.1.29', '内网IP', '[{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 10:03:20\",\"drawStartTime\":\"1970-01-01\",\"drawTime\":1,\"id\":1,\"params\":{},\"repeatDraw\":0,\"setType\":0,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-16 13:32:14\"},{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 10:03:20\",\"drawStartTime\":\"1970-01-01\",\"drawTime\":1,\"id\":2,\"params\":{},\"repeatDraw\":0,\"setType\":1,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-16 13:32:14\"},{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 10:03:20\",\"drawStartTime\":\"1970-01-01\",\"drawTime\":1,\"id\":3,\"params\":{},\"repeatDraw\":0,\"setType\":2,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-16 13:32:14\"},{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 10:10:33\",\"distributeWay\":1,\"drawStartTime\":\"1970-01-01\",\"drawTime\":1,\"expireRewardDay\":30,\"id\":4,\"params\":{},\"repeatDraw\":0,\"setType\":3,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-16 13:32:14\"},{\"appointPlatform\":0,\"auditMultiple\":1.00,\"createBy\":\"admin\",\"createTime\":\"2024-10-16 10:19:35\",\"id\":5,\"keepGrade\":1,\"params\":{},\"remark\":\"1.晋级标准:满足VIP晋级要求(即充值或有效投注都满足条件),即可晋级相应VIP等级,获得相应晋级奖金,如连续晋级多级,可获得全部等级晋级奖金,奖金实时可领取;\\n2.日俸禄:每日充值及有效投注满足当前等级日俸禄要求,可获得对应日俸禄奖金,如连续晋级多级,可获得全部等级日俸禄奖金,奖金实时可领取;\\n3.周俸禄:每周充值及有效投注满足当前等级周俸禄要求,可获得对应周俸禄奖金,如连续晋级多级,可获得全部等级周俸禄奖金,奖金实时可领取;\\n4.月俸禄:每月充值及有效投注满足当前等级月俸禄要求,可获得对应月俸禄奖金,如连续晋级多级,可获得全部等级月俸禄奖金,奖金实时可领取;\\n5.奖励过期时间:获得的奖金仅保留30天,期间内未主动领取,则过期作废,例如:1月1日获得奖励,保留30天,则1月32日 00:00:00过期作废;\\n6.稽核说明:VIP所赠送的奖金需1倍流水(即稽核、打码或有效投注)才能提现,打码不限游戏平台;\\n7.活动声明:本功能仅限账号本人进行正常游戏投注,禁止租借账号、无风险投注(对赌、对刷、低赔刷水)、恶意套利、使用外挂程式、机器人、利用协议、漏洞、接口、群控或其他技术手段参与,一经查核属实,本平台有权终止会员登录、暂停会员使用网站、及没收奖金和不当盈利的权利,无需特别通知;\\n8.解释说明:会员领取VIP奖励时,本平台将默认会员同意且遵守对应条件等相关规定,为避免文字理解歧义,本平台保有本活动最终解释权。\",\"rewardSwitch\":1,\"ruleType\":1,\"setType\":4,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-16 13:32:14\",\"vipIcon\":\"1\"}]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 13:32:14', 92); +INSERT INTO `sys_oper_log` VALUES (395, '会员vip等级公共设置', 2, 'com.ff.member.controller.MemberVipSetupController.editMemberCommonSetUp()', 'PUT', 1, 'admin', '研发部门', '/member/vipSetup/editMemberCommonSetUp', '192.168.1.29', '内网IP', '[{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 10:03:20\",\"drawStartTime\":\"1970-01-01\",\"drawTime\":1,\"id\":1,\"params\":{},\"repeatDraw\":0,\"setType\":0,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-16 13:32:44\"},{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 10:03:20\",\"drawStartTime\":\"1970-01-01\",\"drawTime\":1,\"id\":2,\"params\":{},\"repeatDraw\":0,\"setType\":1,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-16 13:32:44\"},{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 10:03:20\",\"drawStartTime\":\"1970-01-01\",\"drawTime\":1,\"id\":3,\"params\":{},\"repeatDraw\":0,\"setType\":2,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-16 13:32:44\"},{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 10:10:33\",\"distributeWay\":1,\"drawStartTime\":\"1970-01-01\",\"drawTime\":1,\"expireRewardDay\":30,\"id\":4,\"params\":{},\"repeatDraw\":0,\"setType\":3,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-16 13:32:44\"},{\"appointPlatform\":0,\"auditMultiple\":1.00,\"createBy\":\"admin\",\"createTime\":\"2024-10-16 10:19:35\",\"id\":5,\"keepGrade\":0,\"params\":{},\"remark\":\"1.晋级标准:满足VIP晋级要求(即充值或有效投注都满足条件),即可晋级相应VIP等级,获得相应晋级奖金,如连续晋级多级,可获得全部等级晋级奖金,奖金实时可领取;\\n2.日俸禄:每日充值及有效投注满足当前等级日俸禄要求,可获得对应日俸禄奖金,如连续晋级多级,可获得全部等级日俸禄奖金,奖金实时可领取;\\n3.周俸禄:每周充值及有效投注满足当前等级周俸禄要求,可获得对应周俸禄奖金,如连续晋级多级,可获得全部等级周俸禄奖金,奖金实时可领取;\\n4.月俸禄:每月充值及有效投注满足当前等级月俸禄要求,可获得对应月俸禄奖金,如连续晋级多级,可获得全部等级月俸禄奖金,奖金实时可领取;\\n5.奖励过期时间:获得的奖金仅保留30天,期间内未主动领取,则过期作废,例如:1月1日获得奖励,保留30天,则1月32日 00:00:00过期作废;\\n6.稽核说明:VIP所赠送的奖金需1倍流水(即稽核、打码或有效投注)才能提现,打码不限游戏平台;\\n7.活动声明:本功能仅限账号本人进行正常游戏投注,禁止租借账号、无风险投注(对赌、对刷、低赔刷水)、恶意套利、使用外挂程式、机器人、利用协议、漏洞、接口、群控或其他技术手段参与,一经查核属实,本平台有权终止会员登录、暂停会员使用网站、及没收奖金和不当盈利的权利,无需特别通知;\\n8.解释说明:会员领取VIP奖励时,本平台将默认会员同意且遵守对应条件等相关规定,为避免文字理解歧义,本平台保有本活动最终解释权。\",\"rewardSwitch\":1,\"ruleType\":1,\"setType\":4,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-16 13:32:44\",\"vipIcon\":\"1\"}]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 13:32:44', 34); +INSERT INTO `sys_oper_log` VALUES (396, '用户管理', 5, 'com.ff.system.SysUserController.export()', 'POST', 1, 'admin', '研发部门', '/system/user/export', '192.168.1.34', '内网IP', '{\"pageSize\":\"10\",\"pageNum\":\"1\"}', NULL, 0, NULL, '2024-10-16 16:04:45', 853); +INSERT INTO `sys_oper_log` VALUES (397, '会员层级', 1, 'com.ff.member.controller.MemberLevelController.add()', 'POST', 1, 'admin', '研发部门', '/member/level', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 16:13:45\",\"id\":1,\"labelId\":2,\"levelName\":\"测试层级\",\"params\":{},\"remark\":\"这是一个测试层级\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 16:13:45', 19); +INSERT INTO `sys_oper_log` VALUES (398, '会员层级', 1, 'com.ff.member.controller.MemberLevelController.add()', 'POST', 1, 'admin', '研发部门', '/member/level', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 16:16:40\",\"id\":2,\"labelId\":2,\"levelName\":\"测试\",\"params\":{},\"remark\":\"123123\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 16:16:40', 10); +INSERT INTO `sys_oper_log` VALUES (399, '会员层级', 1, 'com.ff.member.controller.MemberLevelController.add()', 'POST', 1, 'admin', '研发部门', '/member/level', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 16:17:15\",\"id\":3,\"labelId\":2,\"levelName\":\"测试测试\",\"levelType\":1,\"params\":{},\"remark\":\"1123123\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 16:17:15', 9); +INSERT INTO `sys_oper_log` VALUES (400, '会员层级', 1, 'com.ff.member.controller.MemberLevelController.add()', 'POST', 1, 'admin', '研发部门', '/member/level', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 16:30:57\",\"id\":4,\"levelName\":\"刷子玩家\",\"levelType\":1,\"params\":{},\"remark\":\"破解验证注册的玩家\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 16:30:57', 24); +INSERT INTO `sys_oper_log` VALUES (401, '会员层级', 1, 'com.ff.member.controller.MemberLevelController.add()', 'POST', 1, 'admin', '研发部门', '/member/level', '192.168.1.34', '内网IP', '{\"chargeAmount\":0,\"chargeCount\":0,\"createBy\":\"admin\",\"createTime\":\"2024-10-16 16:32:40\",\"id\":5,\"levelName\":\"默认层级\",\"levelType\":0,\"params\":{},\"remark\":\"默认层级\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 16:32:40', 11); +INSERT INTO `sys_oper_log` VALUES (402, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_vip\"}', NULL, 0, NULL, '2024-10-16 16:44:17', 138); +INSERT INTO `sys_oper_log` VALUES (403, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_vip_setup\"}', NULL, 0, NULL, '2024-10-16 16:44:17', 65); +INSERT INTO `sys_oper_log` VALUES (404, '代码生成', 2, 'com.ff.gen.controller.GenController.synchDb()', 'GET', 1, 'admin', '研发部门', '/tool/gen/synchDb/ff_member_vip', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 17:01:49', 190); +INSERT INTO `sys_oper_log` VALUES (405, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"vip\",\"className\":\"MemberVip\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":32,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-10-16 17:01:49\",\"usableColumn\":false},{\"capJavaField\":\"Grade\",\"columnComment\":\"等级\",\"columnId\":33,\"columnName\":\"grade\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"grade\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-10-16 17:01:49\",\"usableColumn\":false},{\"capJavaField\":\"CurrencyType\",\"columnComment\":\"币种(字典ff_currency)\",\"columnId\":34,\"columnName\":\"currency_type\",\"columnType\":\"varchar(10)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"ff_currency\",\"edit\":true,\"htmlType\":\"select\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"currencyType\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-10-16 17:01:49\",\"usableColumn\":false},{\"capJavaField\":\"IconParentStyle\",\"columnComment\":\"图标父样式(字典ff_vip_icon_parent_style\\t)\",\"columnId\":35,\"columnName\":\"icon_parent_style\",\"columnType\":\"varchar(200)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"ff_vip_i', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-16 17:02:39', 103); +INSERT INTO `sys_oper_log` VALUES (406, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_vip\"}', NULL, 0, NULL, '2024-10-16 17:02:46', 144); +INSERT INTO `sys_oper_log` VALUES (407, '代码生成', 6, 'com.ff.gen.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '192.168.1.34', '内网IP', '{\"tables\":\"sys_excel_task\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 09:19:18', 164); +INSERT INTO `sys_oper_log` VALUES (408, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"task\",\"className\":\"SysExcelTask\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":172,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:19:18\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Type\",\"columnComment\":\"类型:1-导入,2-导出\",\"columnId\":173,\"columnName\":\"type\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:19:18\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"select\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"type\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Status\",\"columnComment\":\"状态:0-初始,1-进行中,2-完成,3-失败\",\"columnId\":174,\"columnName\":\"status\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:19:18\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"radio\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"status\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"EstimateCount\",\"columnComment\":\"预估总记录数\",\"columnId\":175,\"columnName\":\"estimate_count\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:19:18\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 09:20:53', 117); +INSERT INTO `sys_oper_log` VALUES (409, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"sys_excel_task\"}', NULL, 0, NULL, '2024-10-17 09:21:49', 386); +INSERT INTO `sys_oper_log` VALUES (410, '代码生成', 3, 'com.ff.gen.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/9', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 09:34:23', 16); +INSERT INTO `sys_oper_log` VALUES (411, '代码生成', 6, 'com.ff.gen.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '192.168.1.34', '内网IP', '{\"tables\":\"excel_task\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 09:34:28', 84); +INSERT INTO `sys_oper_log` VALUES (412, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"task\",\"className\":\"ExcelTask\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":193,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:34:27\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":10,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Type\",\"columnComment\":\"类型:1-导入,2-导出\",\"columnId\":194,\"columnName\":\"type\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:34:27\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"select\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"type\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":10,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Status\",\"columnComment\":\"状态:0-初始,1-进行中,2-完成,3-失败\",\"columnId\":195,\"columnName\":\"status\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:34:27\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"radio\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"status\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":10,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"EstimateCount\",\"columnComment\":\"预估总记录数\",\"columnId\":196,\"columnName\":\"estimate_count\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:34:27\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 09:35:19', 64); +INSERT INTO `sys_oper_log` VALUES (413, '代码生成', 3, 'com.ff.gen.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/10', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 09:45:15', 38); +INSERT INTO `sys_oper_log` VALUES (414, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"createTime\":\"2024-10-09 15:44:01\",\"icon\":\"system\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":1,\"menuName\":\"系统管理\",\"menuType\":\"M\",\"orderNum\":8,\"params\":{},\"parentId\":0,\"path\":\"system\",\"perms\":\"\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 09:45:32', 12); +INSERT INTO `sys_oper_log` VALUES (415, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"createTime\":\"2024-10-09 15:44:01\",\"icon\":\"monitor\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2,\"menuName\":\"系统监控\",\"menuType\":\"M\",\"orderNum\":9,\"params\":{},\"parentId\":0,\"path\":\"monitor\",\"perms\":\"\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 09:45:37', 12); +INSERT INTO `sys_oper_log` VALUES (416, '菜单管理', 2, 'com.ff.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"createTime\":\"2024-10-14 10:29:54\",\"icon\":\"user\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":3006,\"menuName\":\"会员管理\",\"menuType\":\"M\",\"orderNum\":3,\"params\":{},\"parentId\":0,\"path\":\"member\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 09:46:06', 12); +INSERT INTO `sys_oper_log` VALUES (417, '菜单管理', 1, 'com.ff.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"createBy\":\"admin\",\"icon\":\"chart\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"报表统计\",\"menuType\":\"M\",\"orderNum\":7,\"params\":{},\"parentId\":0,\"path\":\"chart\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 09:47:09', 13); +INSERT INTO `sys_oper_log` VALUES (418, '代码生成', 6, 'com.ff.gen.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '192.168.1.34', '内网IP', '{\"tables\":\"excel_task\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 09:47:44', 87); +INSERT INTO `sys_oper_log` VALUES (419, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"task\",\"className\":\"ExcelTask\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":214,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:47:44\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":11,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"UserId\",\"columnComment\":\"用户ID\",\"columnId\":215,\"columnName\":\"user_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:47:44\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"userId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":11,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"DeptId\",\"columnComment\":\"部门ID\",\"columnId\":216,\"columnName\":\"dept_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:47:44\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"deptId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":11,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Type\",\"columnComment\":\"类型:1-导入,2-导出\",\"columnId\":217,\"columnName\":\"type\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:47:44\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"select\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"type\",\"javaType\":\"I', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 09:49:26', 58); +INSERT INTO `sys_oper_log` VALUES (420, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"task\",\"className\":\"ExcelTask\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":214,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:47:44\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":11,\"updateBy\":\"\",\"updateTime\":\"2024-10-17 09:49:26\",\"usableColumn\":false},{\"capJavaField\":\"UserId\",\"columnComment\":\"用户ID\",\"columnId\":215,\"columnName\":\"user_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:47:44\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"userId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":11,\"updateBy\":\"\",\"updateTime\":\"2024-10-17 09:49:26\",\"usableColumn\":false},{\"capJavaField\":\"DeptId\",\"columnComment\":\"部门ID\",\"columnId\":216,\"columnName\":\"dept_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:47:44\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"deptId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":11,\"updateBy\":\"\",\"updateTime\":\"2024-10-17 09:49:26\",\"usableColumn\":false},{\"capJavaField\":\"Type\",\"columnComment\":\"类型:1-导入,2-导出\",\"columnId\":217,\"columnName\":\"type\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 09:47:44\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"select\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 09:49:49', 53); +INSERT INTO `sys_oper_log` VALUES (421, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"excel_task\"}', NULL, 0, NULL, '2024-10-17 09:49:52', 78); +INSERT INTO `sys_oper_log` VALUES (422, '代码生成', 2, 'com.ff.gen.controller.GenController.synchDb()', 'GET', 1, 'admin', '研发部门', '/tool/gen/synchDb/ff_member_vip', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 14:56:08', 245); +INSERT INTO `sys_oper_log` VALUES (423, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"vip\",\"className\":\"MemberVip\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":32,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-10-17 14:56:08\",\"usableColumn\":false},{\"capJavaField\":\"Grade\",\"columnComment\":\"等级\",\"columnId\":33,\"columnName\":\"grade\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"grade\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-10-17 14:56:08\",\"usableColumn\":false},{\"capJavaField\":\"CurrencyType\",\"columnComment\":\"币种(字典ff_currency)\",\"columnId\":34,\"columnName\":\"currency_type\",\"columnType\":\"varchar(10)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"ff_currency\",\"edit\":true,\"htmlType\":\"select\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"currencyType\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-10-17 14:56:08\",\"usableColumn\":false},{\"capJavaField\":\"IconParentStyle\",\"columnComment\":\"图标父样式(字典ff_vip_icon_parent_style\\t)\",\"columnId\":35,\"columnName\":\"icon_parent_style\",\"columnType\":\"varchar(200)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-15 16:07:03\",\"dictType\":\"ff_vip_i', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 14:56:46', 127); +INSERT INTO `sys_oper_log` VALUES (424, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_member_vip\"}', NULL, 0, NULL, '2024-10-17 14:56:56', 412); +INSERT INTO `sys_oper_log` VALUES (425, '代码生成', 3, 'com.ff.gen.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/11', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 14:59:29', 37); +INSERT INTO `sys_oper_log` VALUES (426, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/3039', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 15:06:17', 30); +INSERT INTO `sys_oper_log` VALUES (427, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/3040', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 15:06:19', 18); +INSERT INTO `sys_oper_log` VALUES (428, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/3041', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 15:06:21', 14); +INSERT INTO `sys_oper_log` VALUES (429, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/3042', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 15:06:23', 23); +INSERT INTO `sys_oper_log` VALUES (430, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/3043', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 15:06:26', 15); +INSERT INTO `sys_oper_log` VALUES (431, '菜单管理', 3, 'com.ff.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/3038', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 15:06:29', 15); +INSERT INTO `sys_oper_log` VALUES (432, '定时任务', 1, 'com.ff.quartz.controller.SysJobController.add()', 'POST', 1, 'admin', '研发部门', '/monitor/job', '192.168.1.34', '内网IP', '{\"concurrent\":\"1\",\"createBy\":\"admin\",\"cronExpression\":\"0 0/30 * ? * *\",\"invokeTarget\":\"memberVipTask.updateMemberVipCount()\",\"jobGroup\":\"SYSTEM\",\"jobId\":100,\"jobName\":\"vip等级人数修改\",\"misfirePolicy\":\"1\",\"nextValidTime\":\"2024-10-17 15:30:00\",\"params\":{},\"status\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 15:29:44', 30); +INSERT INTO `sys_oper_log` VALUES (433, '定时任务', 2, 'com.ff.quartz.controller.SysJobController.changeStatus()', 'PUT', 1, 'admin', '研发部门', '/monitor/job/changeStatus', '192.168.1.34', '内网IP', '{\"jobId\":100,\"misfirePolicy\":\"0\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 15:29:48', 20); +INSERT INTO `sys_oper_log` VALUES (434, '定时任务', 2, 'com.ff.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '研发部门', '/monitor/job/run', '192.168.1.34', '内网IP', '{\"jobGroup\":\"SYSTEM\",\"jobId\":100,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 15:29:51', 18); +INSERT INTO `sys_oper_log` VALUES (435, '菜单管理', 1, 'com.ff.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '192.168.1.34', '内网IP', '{\"children\":[],\"createBy\":\"admin\",\"icon\":\"documentation\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"运营管理\",\"menuType\":\"M\",\"orderNum\":1,\"params\":{},\"parentId\":0,\"path\":\"operation\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 16:28:58', 20); +INSERT INTO `sys_oper_log` VALUES (436, '代码生成', 6, 'com.ff.gen.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '192.168.1.34', '内网IP', '{\"tables\":\"ff_currency\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 16:30:04', 94); +INSERT INTO `sys_oper_log` VALUES (437, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"currency\",\"className\":\"FfCurrency\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":237,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 16:30:04\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":12,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CurrencyCode\",\"columnComment\":\"币种编码\",\"columnId\":238,\"columnName\":\"currency_code\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 16:30:04\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"currencyCode\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":12,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"MarketCurrencyCode\",\"columnComment\":\"市场币种编码\",\"columnId\":239,\"columnName\":\"market_currency_code\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 16:30:04\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"marketCurrencyCode\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":12,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CurrencySign\",\"columnComment\":\"币种符号\",\"columnId\":240,\"columnName\":\"currency_sign\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 16:30:04\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 16:30:45', 74); +INSERT INTO `sys_oper_log` VALUES (438, '代码生成', 2, 'com.ff.gen.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '192.168.1.34', '内网IP', '{\"businessName\":\"currency\",\"className\":\"Currency\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键id\",\"columnId\":237,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 16:30:04\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":12,\"updateBy\":\"\",\"updateTime\":\"2024-10-17 16:30:45\",\"usableColumn\":false},{\"capJavaField\":\"CurrencyCode\",\"columnComment\":\"币种编码\",\"columnId\":238,\"columnName\":\"currency_code\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 16:30:04\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"currencyCode\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":12,\"updateBy\":\"\",\"updateTime\":\"2024-10-17 16:30:45\",\"usableColumn\":false},{\"capJavaField\":\"MarketCurrencyCode\",\"columnComment\":\"市场币种编码\",\"columnId\":239,\"columnName\":\"market_currency_code\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 16:30:04\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"marketCurrencyCode\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":12,\"updateBy\":\"\",\"updateTime\":\"2024-10-17 16:30:45\",\"usableColumn\":false},{\"capJavaField\":\"CurrencySign\",\"columnComment\":\"币种符号\",\"columnId\":240,\"columnName\":\"currency_sign\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-10-17 16:30:04\",\"dictType\":\"\",\"edi', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 16:32:08', 74); +INSERT INTO `sys_oper_log` VALUES (439, '代码生成', 8, 'com.ff.gen.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '192.168.1.34', '内网IP', '{\"tables\":\"ff_currency\"}', NULL, 0, NULL, '2024-10-17 16:32:14', 274); +INSERT INTO `sys_oper_log` VALUES (440, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 10:55:47\",\"default\":false,\"dictCode\":112,\"dictLabel\":\"USDT\",\"dictSort\":0,\"dictType\":\"ff_currency\",\"dictValue\":\"1\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"USDT(USDT)\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 16:55:09', 20); +INSERT INTO `sys_oper_log` VALUES (441, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 10:56:28\",\"default\":false,\"dictCode\":113,\"dictLabel\":\"VND\",\"dictSort\":0,\"dictType\":\"ff_currency\",\"dictValue\":\"2\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"越南盾(VND1000:1)\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 16:55:16', 16); +INSERT INTO `sys_oper_log` VALUES (442, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-12 10:57:41\",\"default\":false,\"dictCode\":114,\"dictLabel\":\"JPY\",\"dictSort\":0,\"dictType\":\"ff_currency\",\"dictValue\":\"3\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"日元(JPY)\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 16:55:22', 17); +INSERT INTO `sys_oper_log` VALUES (443, '币种管理', 1, 'com.ff.operation.controller.CurrencyController.add()', 'POST', 1, 'admin', '研发部门', '/operation/currency', '192.168.1.34', '内网IP', '{\"createTime\":\"2024-10-17 17:24:35\",\"currencyAisle\":\"1\",\"currencyCode\":\"USDT\",\"currencyDisplay\":\"USDT100:1\",\"currencyName\":\"测试币种\",\"currencySign\":\"b\",\"currencyType\":\"1\",\"fullName\":\"testBi\",\"gameRate\":100,\"marketCurrencyCode\":\"test\",\"params\":{},\"remark\":\"测试描述\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 17:24:35', 20); +INSERT INTO `sys_oper_log` VALUES (444, '币种管理', 2, 'com.ff.operation.controller.CurrencyController.edit()', 'PUT', 1, 'admin', '研发部门', '/operation/currency', '192.168.1.34', '内网IP', '{\"createBy\":\"\",\"createTime\":\"2024-10-17 17:24:35\",\"currencyAisle\":\"USD\",\"currencyCode\":\"USDT\",\"currencyDisplay\":\"USDT1:1\",\"currencyName\":\"USDT\",\"currencySign\":\"U\",\"currencyType\":\"1\",\"fullName\":\"Tether\",\"gameRate\":1,\"id\":1,\"marketCurrencyCode\":\"USDT\",\"params\":{},\"remark\":\"USDT\",\"updateBy\":\"\",\"updateTime\":\"2024-10-17 17:28:12\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 17:28:13', 27); +INSERT INTO `sys_oper_log` VALUES (445, '币种管理', 2, 'com.ff.operation.controller.CurrencyController.edit()', 'PUT', 1, 'admin', '研发部门', '/operation/currency', '192.168.1.34', '内网IP', '{\"createBy\":\"\",\"createTime\":\"2024-10-17 17:24:35\",\"currencyAisle\":\"USD\",\"currencyCode\":\"USDT\",\"currencyDisplay\":\"USDT\",\"currencyName\":\"USDT\",\"currencySign\":\"U\",\"currencyType\":\"1\",\"fullName\":\"Tether\",\"gameRate\":1,\"id\":1,\"marketCurrencyCode\":\"USDT\",\"params\":{},\"remark\":\"USDT\",\"updateBy\":\"\",\"updateTime\":\"2024-10-17 17:29:01\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 17:29:01', 9); +INSERT INTO `sys_oper_log` VALUES (446, '币种管理', 2, 'com.ff.operation.controller.CurrencyController.edit()', 'PUT', 1, 'admin', '研发部门', '/operation/currency', '192.168.1.34', '内网IP', '{\"createBy\":\"\",\"createTime\":\"2024-10-17 17:24:35\",\"currencyAisle\":\"USD\",\"currencyCode\":\"USDT\",\"currencyDisplay\":\"USDT\",\"currencyName\":\"USDT\",\"currencySign\":\"U\",\"currencyType\":\"1\",\"fullName\":\"Tether\",\"gameRate\":1,\"id\":1,\"marketCurrencyCode\":\"USDT\",\"params\":{},\"remark\":\"USDT\",\"updateBy\":\"\",\"updateTime\":\"2024-10-17 17:29:17\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 17:29:17', 8); +INSERT INTO `sys_oper_log` VALUES (447, '币种管理', 1, 'com.ff.operation.controller.CurrencyController.add()', 'POST', 1, 'admin', '研发部门', '/operation/currency', '192.168.1.34', '内网IP', '{\"createTime\":\"2024-10-17 17:30:02\",\"currencyCode\":\"VND\",\"currencyDisplay\":\"VND1000:1\",\"currencyName\":\"越南盾\",\"currencySign\":\"₫\",\"currencyType\":\"2\",\"fullName\":\"Vietnamese Dong\",\"gameRate\":1000,\"marketCurrencyCode\":\"VND\",\"params\":{},\"remark\":\"越南盾\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 17:30:02', 11); +INSERT INTO `sys_oper_log` VALUES (448, '字典类型', 3, 'com.ff.system.SysDictDataController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/dict/data/114', '192.168.1.34', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-17 17:30:39', 22); +INSERT INTO `sys_oper_log` VALUES (449, '会员标签', 2, 'com.ff.member.controller.MemberLabelController.edit()', 'PUT', 1, 'admin', '研发部门', '/member/label', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 14:18:31\",\"iconColor\":\"#1677fd\",\"id\":2,\"labelName\":\"默认标签\",\"orderNum\":1,\"params\":{},\"remark\":\"默认标签\",\"updateBy\":\"admin\",\"updateTime\":\"2024-10-18 09:33:59\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 09:33:59', 11); +INSERT INTO `sys_oper_log` VALUES (450, '字典类型', 1, 'com.ff.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"会员账户变动大类\",\"dictType\":\"ff_account_change_type\",\"params\":{},\"remark\":\"会员账户变动大类\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:03:44', 16); +INSERT INTO `sys_oper_log` VALUES (451, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"资金切换\",\"dictSort\":0,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"0\",\"listClass\":\"default\",\"params\":{},\"remark\":\"资金切换\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:06:45', 28); +INSERT INTO `sys_oper_log` VALUES (452, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"会员充值\",\"dictSort\":1,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"1\",\"listClass\":\"primary\",\"params\":{},\"remark\":\"会员充值\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:07:08', 13); +INSERT INTO `sys_oper_log` VALUES (453, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-18 13:06:45\",\"default\":false,\"dictCode\":179,\"dictLabel\":\"资金切换\",\"dictSort\":0,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"0\",\"isDefault\":\"N\",\"listClass\":\"primary\",\"params\":{},\"remark\":\"资金切换\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:07:14', 14); +INSERT INTO `sys_oper_log` VALUES (454, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-18 13:07:08\",\"default\":false,\"dictCode\":180,\"dictLabel\":\"会员充值\",\"dictSort\":1,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"1\",\"isDefault\":\"N\",\"listClass\":\"success\",\"params\":{},\"remark\":\"会员充值\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:07:18', 11); +INSERT INTO `sys_oper_log` VALUES (455, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"会员提现\",\"dictSort\":2,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"2\",\"listClass\":\"info\",\"params\":{},\"remark\":\"会员提现\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:07:39', 14); +INSERT INTO `sys_oper_log` VALUES (456, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"银商结算\",\"dictSort\":3,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"3\",\"listClass\":\"default\",\"params\":{},\"remark\":\"银商结算\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:08:22', 13); +INSERT INTO `sys_oper_log` VALUES (457, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"资金修正\",\"dictSort\":4,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"4\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:08:38', 12); +INSERT INTO `sys_oper_log` VALUES (458, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"活动\",\"dictSort\":5,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"5\",\"listClass\":\"default\",\"params\":{},\"remark\":\"活动\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:09:03', 11); +INSERT INTO `sys_oper_log` VALUES (459, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"返水\",\"dictSort\":0,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"6\",\"listClass\":\"default\",\"params\":{},\"remark\":\"返水\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:09:30', 18); +INSERT INTO `sys_oper_log` VALUES (460, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-18 13:09:30\",\"default\":false,\"dictCode\":185,\"dictLabel\":\"返水\",\"dictSort\":6,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"6\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"返水\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:09:43', 16); +INSERT INTO `sys_oper_log` VALUES (461, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"返佣\",\"dictSort\":7,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"7\",\"listClass\":\"default\",\"params\":{},\"remark\":\"返佣\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:10:02', 12); +INSERT INTO `sys_oper_log` VALUES (462, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"任务\",\"dictSort\":0,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"8\",\"listClass\":\"default\",\"params\":{},\"remark\":\"任务\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:10:31', 14); +INSERT INTO `sys_oper_log` VALUES (463, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-18 13:10:31\",\"default\":false,\"dictCode\":187,\"dictLabel\":\"任务\",\"dictSort\":8,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"8\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"任务\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:10:37', 13); +INSERT INTO `sys_oper_log` VALUES (464, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"VIP奖励\",\"dictSort\":9,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"9\",\"listClass\":\"default\",\"params\":{},\"remark\":\"VIP奖励\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:11:12', 10); +INSERT INTO `sys_oper_log` VALUES (465, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"充值优惠\",\"dictSort\":10,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"10\",\"listClass\":\"default\",\"params\":{},\"remark\":\"充值优惠\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:11:31', 15); +INSERT INTO `sys_oper_log` VALUES (466, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"俱乐部\",\"dictSort\":11,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"11\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:11:48', 14); +INSERT INTO `sys_oper_log` VALUES (467, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-18 13:11:48\",\"default\":false,\"dictCode\":190,\"dictLabel\":\"俱乐部\",\"dictSort\":11,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"11\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"俱乐部\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:11:52', 11); +INSERT INTO `sys_oper_log` VALUES (468, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"奖励\",\"dictSort\":12,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"12\",\"listClass\":\"default\",\"params\":{},\"remark\":\"奖励\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:12:07', 19); +INSERT INTO `sys_oper_log` VALUES (469, '字典数据', 1, 'com.ff.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"公积金\",\"dictSort\":13,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"13\",\"listClass\":\"default\",\"params\":{},\"remark\":\"公积金\",\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:12:21', 14); +INSERT INTO `sys_oper_log` VALUES (470, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-18 13:08:38\",\"default\":false,\"dictCode\":183,\"dictLabel\":\"资金修正\",\"dictSort\":4,\"dictType\":\"ff_account_change_type\",\"dictValue\":\"4\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"remark\":\"资金修正\",\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 13:17:05', 14); +INSERT INTO `sys_oper_log` VALUES (471, 'vip等级', 2, 'com.ff.member.controller.MemberVipController.edit()', 'PUT', 1, 'admin', '研发部门', '/member/vip', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 14:24:37\",\"currencyType\":\"VND\",\"dayCharge\":0,\"dayDrawCountTop\":6,\"dayDrawTop\":0,\"dayPour\":0,\"daySalary\":0,\"dayServiceFeeFreeCount\":5,\"dayTop\":0,\"grade\":1,\"iconColor\":\"2\",\"iconParentStyle\":\"1\",\"iconStyle\":\"0\",\"id\":2,\"memberCount\":0,\"memberUpdateTime\":\"2024-10-18 17:30:00\",\"monthCharge\":0,\"monthPour\":3000,\"monthSalary\":6,\"monthTop\":0,\"params\":{},\"promotionBonus\":1800,\"promotionCharge\":0,\"promotionPour\":60000,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-18 17:59:53\",\"weekCharge\":0,\"weekPour\":0,\"weekSalary\":0,\"weekTop\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-18 17:59:53', 32); +INSERT INTO `sys_oper_log` VALUES (472, '字典数据', 2, 'com.ff.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/dict/data', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-14 13:48:48\",\"default\":false,\"dictCode\":151,\"dictLabel\":\"style_10\",\"dictSort\":10,\"dictType\":\"ff_vip_icon_style\",\"dictValue\":\"10\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-19 09:55:39', 13); +INSERT INTO `sys_oper_log` VALUES (473, 'vip等级', 2, 'com.ff.member.controller.MemberVipController.edit()', 'PUT', 1, 'admin', '研发部门', '/member/vip', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 14:24:37\",\"currencyType\":\"VND\",\"dayCharge\":0,\"dayDrawCountTop\":6,\"dayDrawTop\":0,\"dayPour\":0,\"daySalary\":0,\"dayServiceFeeFreeCount\":5,\"dayTop\":0,\"grade\":1,\"iconColor\":\"3\",\"iconParentStyle\":\"1\",\"iconStyle\":\"10\",\"id\":2,\"memberCount\":0,\"memberUpdateTime\":\"2024-10-19 14:30:00\",\"monthCharge\":0,\"monthPour\":3000,\"monthSalary\":6,\"monthTop\":0,\"params\":{},\"promotionBonus\":1800,\"promotionCharge\":0,\"promotionPour\":60000,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-19 14:58:32\",\"weekCharge\":0,\"weekPour\":0,\"weekSalary\":0,\"weekTop\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-19 14:58:32', 16); +INSERT INTO `sys_oper_log` VALUES (474, 'vip等级批量修改', 2, 'com.ff.member.controller.MemberVipController.batchEdit()', 'PUT', 1, 'admin', '研发部门', '/member/vip/batchEdit', '192.168.1.34', '内网IP', '[{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 14:09:58\",\"currencyType\":\"VND\",\"dayCharge\":0,\"dayDrawCountTop\":5,\"dayDrawTop\":1,\"dayPour\":0,\"daySalary\":0,\"dayServiceFeeFreeCount\":5,\"dayTop\":0,\"grade\":0,\"iconColor\":\"1\",\"iconParentStyle\":\"1\",\"iconStyle\":\"0\",\"id\":1,\"memberCount\":0,\"memberUpdateTime\":\"2024-10-19 16:30:00\",\"monthCharge\":0,\"monthPour\":0,\"monthSalary\":0,\"monthTop\":0,\"params\":{},\"promotionBonus\":0,\"promotionCharge\":0,\"promotionPour\":0,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-19 16:33:12\",\"weekCharge\":0,\"weekPour\":0,\"weekSalary\":0,\"weekTop\":0},{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 14:24:37\",\"currencyType\":\"VND\",\"dayCharge\":0,\"dayDrawCountTop\":6,\"dayDrawTop\":2,\"dayPour\":0,\"daySalary\":0,\"dayServiceFeeFreeCount\":5,\"dayTop\":0,\"grade\":1,\"iconColor\":\"3\",\"iconParentStyle\":\"1\",\"iconStyle\":\"10\",\"id\":2,\"memberCount\":0,\"memberUpdateTime\":\"2024-10-19 16:30:00\",\"monthCharge\":0,\"monthPour\":3000,\"monthSalary\":6,\"monthTop\":0,\"params\":{},\"promotionBonus\":1800,\"promotionCharge\":0,\"promotionPour\":60000,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-19 16:33:12\",\"weekCharge\":0,\"weekPour\":0,\"weekSalary\":0,\"weekTop\":0}]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-19 16:33:12', 18); +INSERT INTO `sys_oper_log` VALUES (475, 'vip等级批量修改', 2, 'com.ff.member.controller.MemberVipController.batchEdit()', 'PUT', 1, 'admin', '研发部门', '/member/vip/batchEdit', '192.168.1.34', '内网IP', '[{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 14:09:58\",\"currencyType\":\"VND\",\"dayCharge\":0,\"dayDrawCountTop\":5,\"dayDrawTop\":0,\"dayPour\":0,\"daySalary\":0,\"dayServiceFeeFreeCount\":5,\"dayTop\":0,\"grade\":0,\"iconColor\":\"1\",\"iconParentStyle\":\"1\",\"iconStyle\":\"0\",\"id\":1,\"memberCount\":0,\"memberUpdateTime\":\"2024-10-19 16:30:00\",\"monthCharge\":0,\"monthPour\":0,\"monthSalary\":0,\"monthTop\":0,\"params\":{},\"promotionBonus\":0,\"promotionCharge\":0,\"promotionPour\":0,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-19 16:33:24\",\"weekCharge\":0,\"weekPour\":0,\"weekSalary\":0,\"weekTop\":0},{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 14:24:37\",\"currencyType\":\"VND\",\"dayCharge\":0,\"dayDrawCountTop\":6,\"dayDrawTop\":2,\"dayPour\":0,\"daySalary\":0,\"dayServiceFeeFreeCount\":5,\"dayTop\":0,\"grade\":1,\"iconColor\":\"3\",\"iconParentStyle\":\"1\",\"iconStyle\":\"10\",\"id\":2,\"memberCount\":0,\"memberUpdateTime\":\"2024-10-19 16:30:00\",\"monthCharge\":0,\"monthPour\":3000,\"monthSalary\":6,\"monthTop\":0,\"params\":{},\"promotionBonus\":1800,\"promotionCharge\":0,\"promotionPour\":60000,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-19 16:33:24\",\"weekCharge\":0,\"weekPour\":0,\"weekSalary\":0,\"weekTop\":0}]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-19 16:33:24', 13); +INSERT INTO `sys_oper_log` VALUES (476, 'vip等级', 2, 'com.ff.member.controller.MemberVipController.edit()', 'PUT', 1, 'admin', '研发部门', '/member/vip', '192.168.1.34', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 14:09:58\",\"currencyType\":\"VND\",\"dayCharge\":0,\"dayDrawCountTop\":5,\"dayDrawTop\":0,\"dayPour\":0,\"daySalary\":0,\"dayServiceFeeFreeCount\":5,\"dayTop\":0,\"grade\":0,\"iconColor\":\"6\",\"iconParentStyle\":\"1\",\"iconStyle\":\"5\",\"id\":1,\"memberCount\":0,\"memberUpdateTime\":\"2024-10-19 16:30:00\",\"monthCharge\":0,\"monthPour\":0,\"monthSalary\":0,\"monthTop\":0,\"params\":{},\"promotionBonus\":0,\"promotionCharge\":0,\"promotionPour\":0,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-19 16:56:52\",\"weekCharge\":0,\"weekPour\":0,\"weekSalary\":0,\"weekTop\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-19 16:56:52', 6); +INSERT INTO `sys_oper_log` VALUES (477, 'vip等级批量修改', 2, 'com.ff.member.controller.MemberVipController.batchEdit()', 'PUT', 1, 'admin', '研发部门', '/member/vip/batchEdit', '192.168.1.34', '内网IP', '[{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 14:09:58\",\"currencyType\":\"VND\",\"dayCharge\":0,\"dayDrawCountTop\":5,\"dayDrawTop\":0,\"dayPour\":0,\"daySalary\":0,\"dayServiceFeeFreeCount\":5,\"dayTop\":0,\"grade\":0,\"iconColor\":\"6\",\"iconParentStyle\":\"1\",\"iconStyle\":\"5\",\"id\":1,\"memberCount\":0,\"memberUpdateTime\":\"2024-10-19 16:30:00\",\"monthCharge\":0,\"monthPour\":0,\"monthSalary\":0,\"monthTop\":0,\"params\":{},\"promotionBonus\":0,\"promotionCharge\":0,\"promotionPour\":0,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-19 17:14:38\",\"weekCharge\":0,\"weekPour\":0,\"weekSalary\":0,\"weekTop\":0},{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 14:24:37\",\"currencyType\":\"VND\",\"dayCharge\":0,\"dayDrawCountTop\":6,\"dayDrawTop\":2,\"dayPour\":0,\"daySalary\":0,\"dayServiceFeeFreeCount\":5,\"dayTop\":0,\"grade\":1,\"iconColor\":\"3\",\"iconParentStyle\":\"1\",\"iconStyle\":\"10\",\"id\":2,\"memberCount\":0,\"memberUpdateTime\":\"2024-10-19 16:30:00\",\"monthCharge\":0,\"monthPour\":3000,\"monthSalary\":6,\"monthTop\":0,\"params\":{},\"promotionBonus\":1800,\"promotionCharge\":0,\"promotionPour\":60000,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-19 17:14:38\",\"weekCharge\":0,\"weekPour\":0,\"weekSalary\":0,\"weekTop\":0}]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-19 17:14:38', 30); +INSERT INTO `sys_oper_log` VALUES (478, 'vip等级批量修改', 2, 'com.ff.member.controller.MemberVipController.batchEdit()', 'PUT', 1, 'admin', '研发部门', '/member/vip/batchEdit', '192.168.1.34', '内网IP', '[{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 14:09:58\",\"currencyType\":\"VND\",\"dayCharge\":0,\"dayDrawCountTop\":5,\"dayDrawTop\":0,\"dayPour\":0,\"daySalary\":0,\"dayServiceFeeFreeCount\":5,\"dayTop\":0,\"grade\":0,\"iconColor\":\"6\",\"iconParentStyle\":\"1\",\"iconStyle\":\"5\",\"id\":1,\"memberCount\":0,\"memberUpdateTime\":\"2024-10-19 16:30:00\",\"monthCharge\":0,\"monthPour\":0,\"monthSalary\":0,\"monthTop\":0,\"params\":{},\"promotionBonus\":0,\"promotionCharge\":0,\"promotionPour\":0,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-19 17:14:46\",\"weekCharge\":0,\"weekPour\":0,\"weekSalary\":0,\"weekTop\":0},{\"createBy\":\"admin\",\"createTime\":\"2024-10-16 14:24:37\",\"currencyType\":\"VND\",\"dayCharge\":0,\"dayDrawCountTop\":6,\"dayDrawTop\":2,\"dayPour\":0,\"daySalary\":0,\"dayServiceFeeFreeCount\":5,\"dayTop\":0,\"grade\":1,\"iconColor\":\"3\",\"iconParentStyle\":\"1\",\"iconStyle\":\"10\",\"id\":2,\"memberCount\":0,\"memberUpdateTime\":\"2024-10-19 16:30:00\",\"monthCharge\":0,\"monthPour\":3000,\"monthSalary\":6,\"monthTop\":0,\"params\":{},\"promotionBonus\":1800,\"promotionCharge\":0,\"promotionPour\":60000,\"updateBy\":\"admin\",\"updateTime\":\"2024-10-19 17:14:46\",\"weekCharge\":0,\"weekPour\":0,\"weekSalary\":0,\"weekTop\":0}]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-19 17:14:46', 15); + +-- ---------------------------- +-- Table structure for sys_post +-- ---------------------------- +DROP TABLE IF EXISTS `sys_post`; +CREATE TABLE `sys_post` ( + `post_id` bigint NOT NULL AUTO_INCREMENT COMMENT '岗位ID', + `post_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '岗位编码', + `post_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '岗位名称', + `post_sort` int NOT NULL COMMENT '显示顺序', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '状态(0正常 1停用)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`post_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '岗位信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_post +-- ---------------------------- +INSERT INTO `sys_post` VALUES (1, 'ceo', '董事长', 1, '0', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_post` VALUES (2, 'se', '项目经理', 2, '0', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_post` VALUES (3, 'hr', '人力资源', 3, '0', 'admin', '2024-10-09 15:44:01', '', NULL, ''); +INSERT INTO `sys_post` VALUES (4, 'user', '普通员工', 4, '0', 'admin', '2024-10-09 15:44:01', '', NULL, ''); + +-- ---------------------------- +-- Table structure for sys_role +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role`; +CREATE TABLE `sys_role` ( + `role_id` bigint NOT NULL AUTO_INCREMENT COMMENT '角色ID', + `role_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色名称', + `role_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色权限字符串', + `role_sort` int NOT NULL COMMENT '显示顺序', + `data_scope` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '1' COMMENT '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', + `menu_check_strictly` tinyint(1) NULL DEFAULT 1 COMMENT '菜单树选择项是否关联显示', + `dept_check_strictly` tinyint(1) NULL DEFAULT 1 COMMENT '部门树选择项是否关联显示', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`role_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_role +-- ---------------------------- +INSERT INTO `sys_role` VALUES (1, '超级管理员', 'admin', 1, '1', 1, 1, '0', '0', 'admin', '2024-10-09 15:44:01', '', NULL, '超级管理员'); +INSERT INTO `sys_role` VALUES (2, '普通角色', 'common', 2, '2', 1, 1, '0', '0', 'admin', '2024-10-09 15:44:01', 'admin', '2024-10-11 13:43:54', '普通角色'); + +-- ---------------------------- +-- Table structure for sys_role_dept +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_dept`; +CREATE TABLE `sys_role_dept` ( + `role_id` bigint NOT NULL COMMENT '角色ID', + `dept_id` bigint NOT NULL COMMENT '部门ID', + PRIMARY KEY (`role_id`, `dept_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色和部门关联表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_role_dept +-- ---------------------------- +INSERT INTO `sys_role_dept` VALUES (2, 100); +INSERT INTO `sys_role_dept` VALUES (2, 101); +INSERT INTO `sys_role_dept` VALUES (2, 105); + +-- ---------------------------- +-- Table structure for sys_role_menu +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_menu`; +CREATE TABLE `sys_role_menu` ( + `role_id` bigint NOT NULL COMMENT '角色ID', + `menu_id` bigint NOT NULL COMMENT '菜单ID', + PRIMARY KEY (`role_id`, `menu_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色和菜单关联表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_role_menu +-- ---------------------------- +INSERT INTO `sys_role_menu` VALUES (2, 1); +INSERT INTO `sys_role_menu` VALUES (2, 2); +INSERT INTO `sys_role_menu` VALUES (2, 100); +INSERT INTO `sys_role_menu` VALUES (2, 101); +INSERT INTO `sys_role_menu` VALUES (2, 102); +INSERT INTO `sys_role_menu` VALUES (2, 103); +INSERT INTO `sys_role_menu` VALUES (2, 104); +INSERT INTO `sys_role_menu` VALUES (2, 105); +INSERT INTO `sys_role_menu` VALUES (2, 106); +INSERT INTO `sys_role_menu` VALUES (2, 108); +INSERT INTO `sys_role_menu` VALUES (2, 109); +INSERT INTO `sys_role_menu` VALUES (2, 110); +INSERT INTO `sys_role_menu` VALUES (2, 111); +INSERT INTO `sys_role_menu` VALUES (2, 112); +INSERT INTO `sys_role_menu` VALUES (2, 113); +INSERT INTO `sys_role_menu` VALUES (2, 114); +INSERT INTO `sys_role_menu` VALUES (2, 500); +INSERT INTO `sys_role_menu` VALUES (2, 501); +INSERT INTO `sys_role_menu` VALUES (2, 1000); +INSERT INTO `sys_role_menu` VALUES (2, 1001); +INSERT INTO `sys_role_menu` VALUES (2, 1002); +INSERT INTO `sys_role_menu` VALUES (2, 1003); +INSERT INTO `sys_role_menu` VALUES (2, 1004); +INSERT INTO `sys_role_menu` VALUES (2, 1005); +INSERT INTO `sys_role_menu` VALUES (2, 1006); +INSERT INTO `sys_role_menu` VALUES (2, 1007); +INSERT INTO `sys_role_menu` VALUES (2, 1008); +INSERT INTO `sys_role_menu` VALUES (2, 1009); +INSERT INTO `sys_role_menu` VALUES (2, 1010); +INSERT INTO `sys_role_menu` VALUES (2, 1011); +INSERT INTO `sys_role_menu` VALUES (2, 1012); +INSERT INTO `sys_role_menu` VALUES (2, 1013); +INSERT INTO `sys_role_menu` VALUES (2, 1014); +INSERT INTO `sys_role_menu` VALUES (2, 1015); +INSERT INTO `sys_role_menu` VALUES (2, 1016); +INSERT INTO `sys_role_menu` VALUES (2, 1017); +INSERT INTO `sys_role_menu` VALUES (2, 1018); +INSERT INTO `sys_role_menu` VALUES (2, 1019); +INSERT INTO `sys_role_menu` VALUES (2, 1020); +INSERT INTO `sys_role_menu` VALUES (2, 1021); +INSERT INTO `sys_role_menu` VALUES (2, 1022); +INSERT INTO `sys_role_menu` VALUES (2, 1023); +INSERT INTO `sys_role_menu` VALUES (2, 1024); +INSERT INTO `sys_role_menu` VALUES (2, 1025); +INSERT INTO `sys_role_menu` VALUES (2, 1026); +INSERT INTO `sys_role_menu` VALUES (2, 1027); +INSERT INTO `sys_role_menu` VALUES (2, 1028); +INSERT INTO `sys_role_menu` VALUES (2, 1029); +INSERT INTO `sys_role_menu` VALUES (2, 1030); +INSERT INTO `sys_role_menu` VALUES (2, 1031); +INSERT INTO `sys_role_menu` VALUES (2, 1032); +INSERT INTO `sys_role_menu` VALUES (2, 1033); +INSERT INTO `sys_role_menu` VALUES (2, 1034); +INSERT INTO `sys_role_menu` VALUES (2, 1039); +INSERT INTO `sys_role_menu` VALUES (2, 1040); +INSERT INTO `sys_role_menu` VALUES (2, 1041); +INSERT INTO `sys_role_menu` VALUES (2, 1042); +INSERT INTO `sys_role_menu` VALUES (2, 1043); +INSERT INTO `sys_role_menu` VALUES (2, 1044); +INSERT INTO `sys_role_menu` VALUES (2, 1045); +INSERT INTO `sys_role_menu` VALUES (2, 1046); +INSERT INTO `sys_role_menu` VALUES (2, 1047); +INSERT INTO `sys_role_menu` VALUES (2, 1048); +INSERT INTO `sys_role_menu` VALUES (2, 1049); +INSERT INTO `sys_role_menu` VALUES (2, 1050); +INSERT INTO `sys_role_menu` VALUES (2, 1051); +INSERT INTO `sys_role_menu` VALUES (2, 1052); +INSERT INTO `sys_role_menu` VALUES (2, 1053); +INSERT INTO `sys_role_menu` VALUES (2, 1054); + +-- ---------------------------- +-- Table structure for sys_user +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user`; +CREATE TABLE `sys_user` ( + `user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID', + `dept_id` bigint NULL DEFAULT NULL COMMENT '部门ID', + `user_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户账号', + `nick_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户昵称', + `user_type` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '00' COMMENT '用户类型(00系统用户)', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '用户邮箱', + `phonenumber` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '手机号码', + `sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)', + `avatar` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '头像地址', + `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '密码', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '帐号状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '最后登录IP', + `login_date` datetime NULL DEFAULT NULL COMMENT '最后登录时间', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_user +-- ---------------------------- +INSERT INTO `sys_user` VALUES (1, 103, 'admin', 'FF', '00', 'ry@163.com', '15888888888', '1', '', 'e016bdb8d3b8893dd05bf6124b2acf2a', '0', '0', '192.168.1.34', '2024-10-21 10:03:21', 'admin', '2024-10-09 15:44:01', '', '2024-10-21 10:03:21', '管理员'); +INSERT INTO `sys_user` VALUES (2, 105, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', 'e016bdb8d3b8893dd05bf6124b2acf2a', '0', '0', '127.0.0.1', '2024-10-09 15:44:01', 'admin', '2024-10-09 15:44:01', 'admin', '2024-10-14 10:22:46', '测试员'); + +-- ---------------------------- +-- Table structure for sys_user_post +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user_post`; +CREATE TABLE `sys_user_post` ( + `user_id` bigint NOT NULL COMMENT '用户ID', + `post_id` bigint NOT NULL COMMENT '岗位ID', + PRIMARY KEY (`user_id`, `post_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户与岗位关联表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_user_post +-- ---------------------------- +INSERT INTO `sys_user_post` VALUES (1, 1); +INSERT INTO `sys_user_post` VALUES (2, 2); + +-- ---------------------------- +-- Table structure for sys_user_role +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user_role`; +CREATE TABLE `sys_user_role` ( + `user_id` bigint NOT NULL COMMENT '用户ID', + `role_id` bigint NOT NULL COMMENT '角色ID', + PRIMARY KEY (`user_id`, `role_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户和角色关联表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_user_role +-- ---------------------------- +INSERT INTO `sys_user_role` VALUES (1, 1); +INSERT INTO `sys_user_role` VALUES (2, 2); + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/sql/update_liukang.sql b/sql/update_liukang.sql new file mode 100644 index 0000000..e504ccc --- /dev/null +++ b/sql/update_liukang.sql @@ -0,0 +1,903 @@ +drop table if exists ff_member; +CREATE TABLE `ff_member` +( + `id` bigint NOT NULL COMMENT '主键id', + `currency_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '币种(字典ff_currency)', + `account_type` tinyint DEFAULT NULL COMMENT '账号类型(0.会员 1.代理)', + `agent_level_id` bigint DEFAULT NULL COMMENT '代理等级id', + `agent_model_id` bigint DEFAULT NULL COMMENT '代理模式id', + `direct_bind_level_id` bigint DEFAULT NULL COMMENT '强制绑定层级id', + `commission_way` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '提佣方式', + `promote_link` varchar(500) DEFAULT NULL COMMENT '推广链接', + `promote_link_visits` int DEFAULT NULL COMMENT '推广链接访问次数', + `promote_status` tinyint DEFAULT NULL COMMENT '推广状态(0.关闭 1.开启)', + `join_time` datetime DEFAULT NULL COMMENT '加入代理时间', + `member_account` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '会员账号', + `real_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '会员姓名', + `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '账号密码', + `avatar` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '头像地址', + `withdraw_password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '提现密码', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '0' COMMENT '账号状态(0正常 1手动冻结 2异常冻结 3禁止领取优惠 4禁止提现 5黑名单 6停用 7禁止进入游戏 8自我禁止-限制游戏 9自我禁止-限制参与优惠 10自我禁止-限制登录)', + `vip_id` bigint DEFAULT NULL COMMENT 'vip id', + `level_id` bigint DEFAULT NULL COMMENT '会员层级id', + `label_id` bigint DEFAULT NULL COMMENT '会员标签id', + `agent_id` bigint DEFAULT NULL COMMENT '上级代理id', + `agent_account` varchar(255) DEFAULT NULL COMMENT '上级代理账号', + `channel_id` bigint DEFAULT NULL COMMENT '渠道id', + `registe_way` varchar(10) DEFAULT NULL COMMENT '注册方式(字典ff_registe_way)', + `registe_time` datetime DEFAULT NULL COMMENT '注册时间', + `registe_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '注册IP', + `registe_ip_city` varchar(100) DEFAULT NULL COMMENT '注册ip的城市', + `registe_domain` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '注册域名', + `registe_device_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '注册设备类型(字典ff_device_type)', + `registe_device_num` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '注册设备号', + `registe_browser` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '注册浏览器信息', + `registe_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '注册链接url', + `registe_fingerprint` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '注册浏览器指纹', + `sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '男:1 女:2', + `birthday` date DEFAULT NULL COMMENT '生日', + `area_code` varchar(10) DEFAULT NULL COMMENT '手机号区号', + `phone_number` varchar(20) DEFAULT NULL COMMENT '手机号', + `first_charge_amount` decimal(10, 2) DEFAULT NULL COMMENT '首充金额', + `first_charge_time` datetime DEFAULT NULL COMMENT '首充时间', + `last_login_date` datetime DEFAULT NULL COMMENT '上次登录时间', + `last_login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '上次登录IP', + `login_date` datetime DEFAULT NULL COMMENT '最后登录时间', + `login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '最后登录IP', + `login_ip_city` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '最后登录ip的城市', + `login_domain` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '最后登录域名', + `login_device_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '最后登录设备类型(字典ff_device_type)', + `login_device_num` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '最后登录设备号', + `login_browser` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '最后登录浏览器信息', + `login_fingerprint` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '最后登录浏览器指纹', + `verify_way` varchar(10) DEFAULT NULL COMMENT '验证方式(字典ff_verify_way)', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '会员邮箱', + `face_book_account` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'facebook账号', + `telegram_account` varchar(50) DEFAULT NULL COMMENT 'telegram账号', + `whatsapp_account` varchar(50) DEFAULT NULL COMMENT 'whatsapp账号', + `zalo_account` varchar(50) DEFAULT NULL COMMENT 'zalo账号', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '会员备注', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员表'; + +ALTER TABLE `ff-admin`.`ff_member_log` + MODIFY COLUMN `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id' FIRST; + +ALTER TABLE `ff-admin`.`ff_member` + MODIFY COLUMN `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id' FIRST; + + +DROP TABLE IF EXISTS `ff_payment_channel`; +CREATE TABLE `ff_payment_channel` +( + `id` bigint NOT NULL COMMENT '主键id', + `parent_id` bigint DEFAULT NULL COMMENT '子渠道id 顶级分类该id为0', + `currency_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '币种(字典ff_currency)', + `channel_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '渠道名称', + `channel_icon` varchar(500) DEFAULT NULL COMMENT '大类图标', + `blacklist_status` tinyint DEFAULT NULL COMMENT '充值黑名单状态 0.关闭 1.开启', + `switch_status` tinyint DEFAULT NULL COMMENT '开启状态 0.关闭 1.开启', + `custom_tag` varchar(50) DEFAULT NULL COMMENT '大类角标', + `order_num` int DEFAULT '0' COMMENT '显示顺序', + `level_ids` varchar(500) DEFAULT NULL COMMENT '会员层级ids', + `terminals` varchar(255) DEFAULT NULL COMMENT '终端', + `money_max` decimal(10, 2) DEFAULT NULL COMMENT '最大限额', + `money_min` decimal(10, 2) DEFAULT NULL COMMENT '最小限额', + `commission` decimal(10, 2) DEFAULT NULL COMMENT '手续费率', + `third_channel_product_id` bigint DEFAULT NULL COMMENT '第三方通道产品id', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='通道表'; +INSERT INTO `ff-admin`.`ff_payment_channel` (`id`, `parent_id`, `currency_type`, `channel_name`, `channel_icon`, + `blacklist_status`, `switch_status`, `custom_tag`, `order_num`, + `level_ids`, `terminals`, `money_max`, `money_min`, `commission`, + `third_channel_product_id`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (1, 0, NULL, 'Deposit Online', + 'https://zmidh4-1129-ppp.oss-accelerate.aliyuncs.com/siteadmin/pay-icon/icon_cz_zdy.png', 0, 1, '在线存款', 0, + NULL, NULL, NULL, NULL, NULL, NULL, '', NULL, '', NULL, NULL); +INSERT INTO `ff-admin`.`ff_payment_channel` (`id`, `parent_id`, `currency_type`, `channel_name`, `channel_icon`, + `blacklist_status`, `switch_status`, `custom_tag`, `order_num`, + `level_ids`, `terminals`, `money_max`, `money_min`, `commission`, + `third_channel_product_id`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (2, 1, 'INR', 'LSDragon', NULL, NULL, 1, 'LSDragon', 0, '3,4,5', '0,1,2', 50000.00, 100.00, 0.00, 1, 'admin', + '2024-10-25 15:33:14', '', NULL, NULL); + +DROP TABLE IF EXISTS `ff_payment_third_channel`; +CREATE TABLE `ff_payment_third_channel` +( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id', + `currency_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '币种', + `channel_name` varchar(50) DEFAULT NULL COMMENT '渠道名称', + `merch_name` varchar(50) DEFAULT NULL COMMENT '商户名称', + `merch_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '商户code', + `merch_id` varchar(50) DEFAULT NULL COMMENT '商户id', + `merch_key` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '商户密钥', + `merch_privateKey` varchar(500) DEFAULT NULL COMMENT '商户私钥', + `merch_publicKey` varchar(500) DEFAULT NULL COMMENT '商户公钥', + `notify_url` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '三方回调地址(多个用逗号隔开)', + `pay_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '支付下单地址', + `pay_query_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '支付查询地址', + `behalf_pay_url` varchar(500) DEFAULT NULL COMMENT '代付下单地址', + `behalf_query_pay_url` varchar(500) DEFAULT NULL COMMENT '代付查询地址', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='第三方支付渠道表'; +INSERT INTO `ff-admin`.`ff_payment_third_channel` (`id`, `currency_type`, `channel_name`, `merch_name`, `merch_code`, + `merch_id`, `merch_key`, `merch_privateKey`, `merch_publicKey`, + `notify_url`, `pay_url`, `pay_query_url`, `behalf_pay_url`, + `behalf_query_pay_url`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (1, 'INR', 'fypay', 'fypay', 'fypay', '1024', 'kys9s8GvsI727ISML4kZ6Rp', NULL, NULL, NULL, + 'https://fyapi.fypay.online/api/v1/payment/init', 'http://fyapi.fypay.online/api/v1/payment/query', + 'http://fyapi.fypay.online/api/v1/transfer/init', 'http://fyapi.fypay.online/api/v1/transfer/query', 'admin', + '2024-10-25 14:59:35', '', NULL, NULL); + +DROP TABLE IF EXISTS `ff_payment_third_channel_product`; +CREATE TABLE `ff_payment_third_channel_product` +( + `id` bigint NOT NULL COMMENT '主键id', + `third_channel_id` bigint DEFAULT NULL COMMENT '第三方通道id', + `channel_product_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '第三方通道方式code', + `channel_product_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '第三方通道方式名称', + `channel_product_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '第三方通道类型(0.普通 1.刮刮卡 2.网银转账 3.三方充值客服 4.钱包余额快速充值通道 5.银行卡号)', + `money_max` decimal(10, 2) DEFAULT NULL COMMENT '最大限额', + `money_min` decimal(10, 2) DEFAULT NULL COMMENT '最小限额', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='第三方通道产品表'; +INSERT INTO `ff-admin`.`ff_payment_third_channel_product` (`id`, `third_channel_id`, `channel_product_code`, + `channel_product_name`, `channel_product_type`, `money_max`, + `money_min`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (1, 1, '101', 'LSDragon-一类', '0', 50000.00, 100.00, 'admin', '2024-10-25 15:13:11', '', NULL, NULL); + +DELETE +from sys_dict_data +where dict_code BETWEEN 1 and 193; +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (1, 1, '男', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '性别男'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (2, 2, '女', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '性别女'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '性别未知'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '显示菜单'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '隐藏菜单'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '正常状态'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '停用状态'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '正常状态'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '停用状态'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (10, 1, '默认', 'DEFAULT', 'sys_job_group', '', '', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '默认分组'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (11, 2, '系统', 'SYSTEM', 'sys_job_group', '', '', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '系统分组'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (12, 1, '是', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '系统默认是'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (13, 2, '否', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, '系统默认否'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '通知'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '公告'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '正常状态'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '关闭状态'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (18, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '其他操作'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (19, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '新增操作'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (20, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '修改操作'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (21, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '删除操作'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (22, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '授权操作'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (23, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '导出操作'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (24, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '导入操作'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (25, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '强退操作'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (26, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '生成操作'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (27, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '清空操作'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (28, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '正常状态'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (29, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', '2024-10-09 15:44:02', '', NULL, + '停用状态'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (100, 13, '#2bfa38', '#2bfa38', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', + '2024-10-12 09:34:10', 'admin', '2024-10-14 11:02:16', '绿色'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (101, 11, '#f59a23', '#f59a23', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', + '2024-10-12 09:35:59', 'admin', '2024-10-14 11:03:15', '橙色'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (102, 10, '#db301a', '#db301a', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', + '2024-10-12 09:36:29', 'admin', '2024-10-14 11:03:18', '红色'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (103, 9, '#4d42cf', '#4d42cf', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:37:18', + 'admin', '2024-10-14 11:03:22', '深蓝'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (104, 8, '#1677fd', '#1677fd', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:38:28', + 'admin', '2024-10-14 11:03:27', '淡蓝'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (105, 7, '#000000', '#000000', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:39:11', + 'admin', '2024-10-14 11:03:31', '黑色'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (106, 6, '#4cb5ff', '#4cb5ff', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:40:23', + 'admin', '2024-10-14 11:03:35', '浅蓝'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (107, 5, '#874ce8', '#874ce8', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:41:18', + 'admin', '2024-10-14 11:03:39', '深紫'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (108, 4, '#cd55ff', '#cd55ff', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:41:52', + 'admin', '2024-10-14 11:03:43', '淡紫'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (109, 3, '#26a17b', '#26a17b', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:42:29', + 'admin', '2024-10-14 11:03:47', '墨绿'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (110, 2, '#ea4e3d', '#ea4e3d', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-12 09:43:13', + 'admin', '2024-10-14 11:03:51', '浅红'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (111, 12, '#ff7097', '#ff7097', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', + '2024-10-12 09:44:13', 'admin', '2024-10-14 11:03:08', '粉色 '); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (112, 0, 'USDT', '1', 'ff_currency', NULL, 'default', 'N', '0', 'admin', '2024-10-12 10:55:47', 'admin', + '2024-10-17 16:55:09', 'USDT(USDT)'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (113, 1, 'VND', '2', 'ff_currency', NULL, 'default', 'N', '0', 'admin', '2024-10-12 10:56:28', 'admin', + '2024-10-24 16:10:04', '越南盾(VND1000:1)'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (118, 0, '账号注册', '1', 'ff_registe_way', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:07:55', '', NULL, + '账号注册'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (119, 0, 'FaceBook注册', '2', 'ff_registe_way', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:08:21', '', + NULL, 'FaceBook注册'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (120, 0, 'APP-iOS', 'APP-iOS', 'ff_device_type', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:24:29', + 'admin', '2024-10-15 09:35:10', 'APP-iOS'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (121, 0, 'H5-iOS', 'H5-iOS', 'ff_device_type', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:25:18', + 'admin', '2024-10-15 09:35:17', 'H5-iOS'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (122, 0, 'APP-Android', 'APP-Android', 'ff_device_type', NULL, 'default', 'N', '0', 'admin', + '2024-10-12 16:25:43', 'admin', '2024-10-15 09:35:22', 'APP-Android'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (123, 0, 'H5-Android', 'H5-Android', 'ff_device_type', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:26:09', + 'admin', '2024-10-15 09:35:27', 'H5-Android'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (124, 0, 'PC-Windows', 'PC-Windows', 'ff_device_type', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:26:41', + 'admin', '2024-10-15 09:35:33', 'PC-Windows'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (125, 0, 'PC-Mac', 'PC-Mac', 'ff_device_type', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:27:06', + 'admin', '2024-10-15 09:35:38', 'PC-Mac'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (126, 0, '无验证', '1', 'ff_verify_way', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:42:17', '', NULL, + NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (127, 0, '短信验证', '2', 'ff_verify_way', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:42:31', '', NULL, + NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (128, 0, '谷歌验证', '3', 'ff_verify_way', NULL, 'default', 'N', '0', 'admin', '2024-10-12 16:42:43', '', NULL, + NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (130, 1, '无图标', 'NO_ICON', 'ff_member_label_icon', NULL, 'default', 'N', '0', 'admin', '2024-10-14 11:04:21', + 'admin', '2024-10-14 11:04:26', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (131, 1, 'color1', '1', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:25:07', 'admin', + '2024-10-14 15:51:18', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (132, 2, 'color2', '2', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:26:03', 'admin', + '2024-10-14 15:51:30', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (133, 3, 'color3', '3', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:26:37', 'admin', + '2024-10-14 15:51:40', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (134, 4, 'color4', '4', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:27:26', 'admin', + '2024-10-14 15:51:49', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (135, 5, 'color5', '5', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:28:09', 'admin', + '2024-10-14 15:51:58', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (136, 6, 'color6', '6', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:29:18', 'admin', + '2024-10-14 15:52:06', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (137, 7, 'color7', '7', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:39:22', 'admin', + '2024-10-14 15:52:13', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (138, 8, 'color8', '8', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:39:50', 'admin', + '2024-10-14 15:52:33', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (139, 9, 'color9', '9', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:40:45', 'admin', + '2024-10-14 15:52:42', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (140, 10, 'color10', '10', 'ff_vip_icon_color', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:41:05', + 'admin', '2024-10-14 15:52:53', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (141, 0, 'style_0', '0', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:42:52', 'admin', + '2024-10-14 15:49:54', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (142, 1, 'style_1', '1', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:43:25', 'admin', + '2024-10-14 15:49:59', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (143, 2, 'style_2', '2', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:44:15', 'admin', + '2024-10-14 15:50:04', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (144, 3, 'style_3', '3', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:44:32', 'admin', + '2024-10-14 15:50:08', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (145, 4, 'style_4', '4', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:45:13', 'admin', + '2024-10-14 15:50:12', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (146, 5, 'style_5', '5', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:45:33', 'admin', + '2024-10-14 15:50:16', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (147, 6, 'style_6', '6', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:46:39', 'admin', + '2024-10-14 15:50:20', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (148, 7, 'style_7', '7', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:46:59', 'admin', + '2024-10-14 15:50:25', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (149, 8, 'style_8', '8', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:48:13', 'admin', + '2024-10-14 15:50:30', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (150, 9, 'style_9', '9', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:48:30', 'admin', + '2024-10-14 15:50:35', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (151, 10, 'style_10', '10', 'ff_vip_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 13:48:48', + 'admin', '2024-10-19 09:55:39', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (152, 1, 'style1', '1', 'ff_vip_icon_parent_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 15:48:20', + '', NULL, NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (153, 2, 'style2', '2', 'ff_vip_icon_parent_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 15:48:38', + '', NULL, NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (154, 3, 'style3', '3', 'ff_vip_icon_parent_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 15:48:50', + '', NULL, NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (155, 4, 'style4', '4', 'ff_vip_icon_parent_style', NULL, 'default', 'N', '0', 'admin', '2024-10-14 15:49:01', + '', NULL, NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (156, 0, '姓名', '0', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:42:38', 'admin', + '2024-10-23 13:19:01', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (157, 1, '手机号', '1', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:43:10', 'admin', + '2024-10-23 13:19:05', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (158, 2, '账号状态', '2', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:44:34', + 'admin', '2024-10-23 13:19:12', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (159, 3, '银行卡', '3', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:45:08', 'admin', + '2024-10-23 13:19:19', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (160, 4, '账号密码', '4', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:46:13', + 'admin', '2024-10-23 13:19:25', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (161, 5, '忘记密码', '5', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:48:37', + 'admin', '2024-10-23 13:19:30', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (162, 6, '提现密码', '6', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:49:06', + 'admin', '2024-10-23 13:19:36', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (163, 7, 'WhatsApp', '7', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:50:30', + 'admin', '2024-10-23 13:19:40', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (164, 8, 'Facebook', '8', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:50:57', + 'admin', '2024-10-23 13:19:44', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (165, 9, 'Telegram', '9', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:51:20', + 'admin', '2024-10-23 13:19:48', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (166, 10, 'Zalo', '10', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:51:40', 'admin', + '2024-10-23 13:19:56', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (167, 11, '邮箱地址', '11', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:52:30', + 'admin', '2024-10-23 13:19:59', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (168, 12, '手势密码', '12', 'ff_log_operproject', '', 'default', 'N', '0', 'admin', '2024-10-15 09:52:54', + 'admin', '2024-10-23 13:20:07', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (169, 13, '谷歌验证', '13', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:53:19', + 'admin', '2024-10-23 13:20:14', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (170, 14, '密保问题', '14', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:53:55', + 'admin', '2024-10-23 13:20:19', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (171, 15, '会员层级', '15', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:54:29', + 'admin', '2024-10-23 13:20:25', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (172, 16, '上级代理', '16', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:55:06', + 'admin', '2024-10-23 13:20:30', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (173, 17, '登录', '17', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:55:25', 'admin', + '2024-10-23 13:20:41', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (174, 18, '登出', '18', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:55:37', 'admin', + '2024-10-23 13:20:46', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (175, 19, 'VIP等级', '19', 'ff_log_operproject', NULL, 'default', 'N', '0', 'admin', '2024-10-15 09:56:18', + 'admin', '2024-10-23 13:20:51', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (176, 0, '无', '0', 'ff_oper_type', NULL, 'default', 'N', '0', 'admin', '2024-10-15 10:11:57', 'admin', + '2024-10-23 14:54:38', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (177, 1, '新增', '1', 'ff_oper_type', NULL, 'default', 'N', '0', 'admin', '2024-10-15 10:12:11', 'admin', + '2024-10-23 14:54:42', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (178, 2, '修改', '2', 'ff_oper_type', NULL, 'default', 'N', '0', 'admin', '2024-10-15 10:12:19', 'admin', + '2024-10-23 14:54:46', NULL); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (179, 0, '资金切换', '0', 'ff_account_change_type', NULL, 'primary', 'N', '0', 'admin', '2024-10-18 13:06:45', + 'admin', '2024-10-18 13:07:14', '资金切换'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (180, 1, '会员充值', '1', 'ff_account_change_type', NULL, 'success', 'N', '0', 'admin', '2024-10-18 13:07:08', + 'admin', '2024-10-18 13:07:18', '会员充值'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (181, 2, '会员提现', '2', 'ff_account_change_type', NULL, 'info', 'N', '0', 'admin', '2024-10-18 13:07:39', '', + NULL, '会员提现'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (182, 3, '银商结算', '3', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:08:22', + '', NULL, '银商结算'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (183, 4, '资金修正', '4', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:08:38', + 'admin', '2024-10-18 13:17:05', '资金修正'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (184, 5, '活动', '5', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:09:03', '', + NULL, '活动'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (185, 6, '返水', '6', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:09:30', + 'admin', '2024-10-18 13:09:43', '返水'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (186, 7, '返佣', '7', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:10:02', '', + NULL, '返佣'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (187, 8, '任务', '8', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:10:31', + 'admin', '2024-10-18 13:10:37', '任务'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (188, 9, 'VIP奖励', '9', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:11:12', '', + NULL, 'VIP奖励'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (189, 10, '充值优惠', '10', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:11:31', + '', NULL, '充值优惠'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (190, 11, '俱乐部', '11', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:11:48', + 'admin', '2024-10-18 13:11:52', '俱乐部'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (191, 12, '奖励', '12', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:12:07', '', + NULL, '奖励'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (192, 13, '公积金', '13', 'ff_account_change_type', NULL, 'default', 'N', '0', 'admin', '2024-10-18 13:12:21', + '', NULL, '公积金'); +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (193, 2, 'INR', '3', 'ff_currency', NULL, 'default', 'N', '0', 'admin', '2024-10-24 16:09:59', '', NULL, NULL); + + +DROP TABLE IF EXISTS `ff_member_vip_setup`; +CREATE TABLE `ff_member_vip_setup` +( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id', + `keep_grade` tinyint DEFAULT NULL COMMENT '保级开关(0.关闭 1.开启)', + `reward_switch` tinyint DEFAULT NULL COMMENT '奖励开关(0.关闭 1.开启)', + `day_draw_time` tinyint DEFAULT NULL COMMENT '每日领取时间(0.次日 1.实时 2.每日)', + `day_draw_start_time` time DEFAULT NULL COMMENT '每日领取开始时间', + `day_draw_end_time` time DEFAULT NULL COMMENT '每日领取结束时间', + `day_repeat_draw` tinyint DEFAULT NULL COMMENT '每日晋级时是否重复领取(0.可重复领取(含跨级部分) 1.只能领取最高一档)', + `week_draw_time` tinyint DEFAULT NULL COMMENT '每周领取时间(0.次日 1.下周 2.实时 3.每周)', + `week_day` tinyint DEFAULT NULL COMMENT '每周第几日', + `week_draw_start_time` time DEFAULT NULL COMMENT '每周领取开始时间', + `week_draw_end_time` time DEFAULT NULL COMMENT '每周领取结束时间', + `week_repeat_draw` tinyint DEFAULT NULL COMMENT '每周晋级时是否重复领取(0.可重复领取(含跨级部分) 1.只能领取最高一档)', + `month_draw_time` tinyint DEFAULT NULL COMMENT '每月领取时间(0.次日 1.下月 2.实时 3.每月)', + `month_day` tinyint DEFAULT NULL COMMENT '每月第几日', + `month_draw_start_time` time DEFAULT NULL COMMENT '每月领取开始时间', + `month_draw_end_time` time DEFAULT NULL COMMENT '每月领取结束时间', + `month_repeat_draw` tinyint DEFAULT NULL COMMENT '每月晋级时是否重复领取(0.可重复领取(含跨级部分) 1.只能领取最高一档)', + `expire_reward_day` int DEFAULT NULL COMMENT '奖励领取过期天数', + `distribute_way` tinyint DEFAULT NULL COMMENT '派发方式(0.玩家自领(过期自动到账) 1.玩家自领(过期自动作废))', + `common_draw_time` tinyint DEFAULT NULL COMMENT '公共领取时间(0.次日 1.实时 2.每日)', + `common_draw_start_time` time DEFAULT NULL COMMENT '公共领取开始时间', + `common_draw_end_time` time DEFAULT NULL COMMENT '公共领取结束时间', + `common_repeat_draw` tinyint DEFAULT NULL COMMENT '公共晋级时是否重复领取(0.可重复领取(含跨级部分) 1.只能领取最高一档)', + `prohibit_level` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_bin DEFAULT NULL COMMENT '禁止参与层级(黑名单)', + `audit_multiple` decimal(10, 2) DEFAULT NULL COMMENT '稽核倍数(玩家需要达到稽核倍数的流水,才能提现)', + `appoint_platform` tinyint DEFAULT NULL COMMENT '奖金稽核指定平台(0.不限制 1.仅限以下勾选平台)', + `audit_platfrom_ids` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '稽核指定平台ids', + `vip_icon` varchar(10) DEFAULT NULL COMMENT '图标样式', + `rule_type` tinyint DEFAULT NULL COMMENT '规则类型 0.自定义 1.系统翻译', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '规则说明', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员vip等级公共设置表'; + +INSERT INTO `ff-admin`.`ff_member_vip_setup` (`id`, `keep_grade`, `reward_switch`, `day_draw_time`, + `day_draw_start_time`, `day_draw_end_time`, `day_repeat_draw`, + `week_draw_time`, `week_day`, `week_draw_start_time`, + `week_draw_end_time`, `week_repeat_draw`, `month_draw_time`, `month_day`, + `month_draw_start_time`, `month_draw_end_time`, `month_repeat_draw`, + `expire_reward_day`, `distribute_way`, `common_draw_time`, + `common_draw_start_time`, `common_draw_end_time`, `common_repeat_draw`, + `prohibit_level`, `audit_multiple`, `appoint_platform`, + `audit_platfrom_ids`, `vip_icon`, `rule_type`, `create_by`, `create_time`, + `update_by`, `update_time`, `remark`) +VALUES (1, 0, 1, 1, '00:00:00', NULL, 0, 3, 3, '00:00:00', NULL, 0, 5, 16, '00:00:00', NULL, 0, 30, 1, 1, '00:00:00', + NULL, 0, '4,5,3', 1.00, 0, NULL, '3', 1, 'admin', '2024-10-16 10:03:20', 'admin', '2024-10-25 10:22:25', + '1.晋级标准:满足VIP晋级要求(即充值或有效投注都满足条件),即可晋级相应VIP等级,获得相应晋级奖金,如连续晋级多级,可获得全部等级晋级奖金,奖金实时可领取;\n2.日俸禄:每日充值及有效投注满足当前等级日俸禄要求,可获得对应日俸禄奖金,如连续晋级多级,可获得全部等级日俸禄奖金,奖金实时可领取;\n3.周俸禄:每周充值及有效投注满足当前等级周俸禄要求,可获得对应周俸禄奖金,如连续晋级多级,可获得全部等级周俸禄奖金,奖金实时可领取;\n4.月俸禄:每月充值及有效投注满足当前等级月俸禄要求,可获得对应月俸禄奖金,如连续晋级多级,可获得全部等级月俸禄奖金,奖金实时可领取;\n5.奖励过期时间:获得的奖金仅保留30天,期间内未主动领取,则过期作废,例如:1月1日获得奖励,保留30天,则1月32日 00:00:00过期作废;\n6.稽核说明:VIP所赠送的奖金需1倍流水(即稽核、打码或有效投注)才能提现,打码不限游戏平台;\n7.活动声明:本功能仅限账号本人进行正常游戏投注,禁止租借账号、无风险投注(对赌、对刷、低赔刷水)、恶意套利、使用外挂程式、机器人、利用协议、漏洞、接口、群控或其他技术手段参与,一经查核属实,本平台有权终止会员登录、暂停会员使用网站、及没收奖金和不当盈利的权利,无需特别通知;\n8.解释说明:会员领取VIP奖励时,本平台将默认会员同意且遵守对应条件等相关规定,为避免文字理解歧义,本平台保有本活动最终解释权。'); + +INSERT INTO `ff-admin`.`sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, + `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, + `update_time`, `remark`) +VALUES (10024, 3, '后台添加', '3', 'ff_registe_way', NULL, 'default', 'N', '0', 'admin', '2024-10-30 09:18:13', 'admin', + '2024-10-30 09:18:35', '后台添加'); + +ALTER TABLE `ff-admin`.`ff_member` + ADD COLUMN `status_remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '会员状态备注' AFTER `remark`; + +ALTER TABLE `ff-admin`.`ff_member_account` + MODIFY COLUMN `balance` decimal (16, 2) NULL DEFAULT 0.00 COMMENT '余额' AFTER `currency_type`, + MODIFY COLUMN `block_balance` decimal (16, 2) NULL DEFAULT 0.00 COMMENT '冻结余额' AFTER `balance`; + +ALTER TABLE `ff-admin`.`ff_member_account_detail` + MODIFY COLUMN `change_amount` decimal (16, 2) NULL DEFAULT NULL COMMENT '变动金额' AFTER `change_small_type`, + MODIFY COLUMN `before_amount` decimal (16, 2) NULL DEFAULT NULL COMMENT '变动前余额' AFTER `change_amount`, + MODIFY COLUMN `after_amount` decimal (16, 2) NULL DEFAULT NULL COMMENT '变动后余额' AFTER `before_amount`; + +DROP TABLE IF EXISTS `ff_payment_channel`; +CREATE TABLE `ff_payment_channel` +( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id', + `parent_id` bigint DEFAULT NULL COMMENT '子渠道id 顶级分类该id为0', + `currency_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '币种(字典ff_currency)', + `channel_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '渠道名称', + `channel_icon` varchar(500) DEFAULT NULL COMMENT '大类图标', + `blacklist_status` tinyint DEFAULT NULL COMMENT '充值黑名单状态 0.关闭 1.开启', + `switch_status` tinyint DEFAULT NULL COMMENT '开启状态 0.关闭 1.开启', + `custom_tag` varchar(50) DEFAULT NULL COMMENT '大类角标', + `order_num` int DEFAULT '0' COMMENT '显示顺序', + `level_ids` varchar(500) DEFAULT NULL COMMENT '会员层级ids', + `terminals` varchar(255) DEFAULT NULL COMMENT '终端', + `money_max` decimal(16, 2) DEFAULT NULL COMMENT '最大限额', + `money_min` decimal(16, 2) DEFAULT NULL COMMENT '最小限额', + `commission` decimal(16, 2) DEFAULT NULL COMMENT '手续费率', + `third_channel_product_id` bigint DEFAULT NULL COMMENT '第三方通道产品id', + `deduce_rate_type` tinyint DEFAULT NULL COMMENT '赠送比例类型 0.不区分层级 1.区分会员层级', + `deduce_limit` decimal(16, 2) DEFAULT NULL COMMENT '赠送金额上限', + `deduce_count_type` tinyint DEFAULT NULL COMMENT '赠送次数类型 0.每日赠送上限次数 1.总共赠送上限次数', + `deduce_count` int DEFAULT NULL COMMENT '赠送次数', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='通道表'; + +CREATE TABLE `ff_payment_channel_charge_rate` +( + `id` bigint NOT NULL COMMENT '主键id', + `channel_id` bigint DEFAULT NULL COMMENT '通道id', + `level_id` bigint DEFAULT NULL COMMENT '会员层级id', + `deduce_limit` decimal(16, 2) DEFAULT NULL COMMENT '赠送金额上限', + `deduce_count_type` tinyint DEFAULT NULL COMMENT '赠送次数类型 0.每日赠送上限次数 1.总共赠送上限次数', + `deduce_count` int DEFAULT NULL COMMENT '赠送次数', + `min_amount` decimal(16, 2) DEFAULT NULL COMMENT '最小金额', + `max_amount` decimal(16, 2) DEFAULT NULL COMMENT '最大金额', + `charge_rate` decimal(16, 2) DEFAULT NULL COMMENT '赠送比例', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='通道充值赠送配置表'; + +CREATE TABLE `ff_payment_channel_reduce` +( + `id` bigint NOT NULL COMMENT '主键id', + `channel_id` bigint DEFAULT NULL COMMENT '通道id', + `pay_count` int DEFAULT NULL COMMENT '限前充值多少次', + `pay_amount` decimal(16, 2) DEFAULT NULL COMMENT '单笔金额小于此金额,才减免手续费', + `reduce_rate` decimal(16, 2) DEFAULT NULL COMMENT '减免百分比', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '描述', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='通道手续费减免配置'; + +ALTER TABLE `ff-admin`.`ff_payment_channel` + ADD COLUMN `recommend_amount` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '推荐金额,逗号分割' AFTER `deduce_count`; + +ALTER TABLE `ff-admin`.`ff_payment_channel` + ADD COLUMN `merch_name` varchar(50) NULL COMMENT '所属商户名称' AFTER `currency_type`; + diff --git a/sql/update_shi.sql b/sql/update_shi.sql new file mode 100644 index 0000000..5e17178 --- /dev/null +++ b/sql/update_shi.sql @@ -0,0 +1,422 @@ +DROP TABLE IF EXISTS ff_game; +DROP TABLE IF EXISTS ff_game_betting_details; +DROP TABLE IF EXISTS ff_game_category; +DROP TABLE IF EXISTS ff_game_category_rows; +DROP TABLE IF EXISTS ff_game_exchange_money; +DROP TABLE IF EXISTS ff_game_kill_rate; +DROP TABLE IF EXISTS ff_game_platform; +DROP TABLE IF EXISTS ff_game_platform_currency; +DROP TABLE IF EXISTS ff_game_pool; + +-- auto-generated definition +create table ff_game +( + id bigint auto_increment comment '主键id' + primary key, + sort_no int default 0 null comment '排序', + platform_id bigint null comment '游戏平台id', + game_code int null comment '游戏第三方id', + game_type bigint null comment '游戏类型 ff_game_type 字典', + game_name varchar(50) not null comment '游戏名称', + popular_one tinyint default 2 null comment '热门1 热门 1 开启 2关闭 ', + popular_two tinyint default 2 null comment '热门2 热门 1 开启 2关闭', + recommended_status tinyint default 2 null comment '推荐角标 1 开启 2关闭', + stop_status tinyint default 2 null comment '维护开关 维护状态 1 开启 2关闭', + game_status tinyint default 2 null comment '游戏开关 平台开关状态 1 开启 2关闭', + game_icon varchar(500) null comment '子游戏icon', + icon_style tinyint default 1 null comment '宣传图样式 1 默认 2 自定义 ', + game_logo varchar(500) null comment '品牌logo', + create_by varchar(64) default '' null comment '创建者', + create_time datetime null comment '创建时间', + update_by varchar(64) default '' null comment '更新者', + update_time datetime null comment '更新时间' +) + comment '平台子游戏管理' row_format = DYNAMIC; + +-- auto-generated definition +create table ff_game_betting_details +( + id bigint auto_increment comment '主键id' + primary key, + currency_code varchar(50) null comment '币种编码', + member_id bigint not null comment '会员id', + game_code int null comment '游戏id ', + game_id bigint null comment '游戏id', + game_type bigint null comment '游戏类型 ff_game_type 字典', + platform_code varchar(50) null comment '游戏平台 ', + game_name varchar(50) null comment '游戏名称', + game_status tinyint null comment '注单状态 1: 赢 2: 输 3: 平局', + game_status_type tinyint null comment '注单类型', + game_currency_code varchar(50) null comment '游戏币种类型', + account varchar(100) null comment '游戏账号', + wagers_id bigint null comment '游戏注单唯一值', + wagers_time datetime null comment '投注时间', + bet_amount decimal(16, 2) default 0.0000 null comment '投注金额', + payoff_time datetime null comment '派彩时间', + payoff_amount decimal(16, 2) default 0.0000 null comment '派彩金额', + settlement_time datetime null comment '对帐时间', + turnover decimal(16, 2) default 0.0000 null comment '有效投注金额 ※注 1', + order_no varchar(64) null comment '订单id', + settlement_status tinyint default 2 null comment '结算状态 1 未结算 2已结算 3 已撤单', + create_by varchar(64) default '' null comment '创建者', + create_time datetime null comment '创建时间', + update_by varchar(64) default '' null comment '更新者', + update_time datetime null comment '更新时间' +) + comment '会员投注细目表' row_format = DYNAMIC; + +-- auto-generated definition +create table ff_game_category +( + id bigint auto_increment comment '主键id' + primary key, + sort_no int default 0 null comment '排序', + category_name varchar(50) null comment '类型名称', + category_switch tinyint default 2 null comment '类型开关 1开启 2关闭', + open_type tinyint default 1 null comment '打开方式 1 内嵌 2 外链', + open_url varchar(250) null comment '链接访问地址', + open_url_type tinyint default 1 null comment '链接类型 ff_open_url_type字典', + icon_url varchar(500) null comment 'icon访问路径', + remark varchar(250) null comment '备注', + create_by varchar(64) default '' null comment '创建者', + create_time datetime null comment '创建时间', + update_by varchar(64) default '' null comment '更新者', + update_time datetime null comment '更新时间' +) + comment '游戏类型管理' row_format = DYNAMIC; + +-- auto-generated definition +create table ff_game_category_rows +( + id bigint auto_increment comment '主键id' + primary key, + game_category_id bigint default 0 null comment '游戏类型管理id', + currency_code varchar(50) null comment '币种编码', + h5_index_rows int null comment '首页显示行数', + h5_level_rows int null comment '首页二级页面显示行数', + remark varchar(250) null comment '备注', + create_by varchar(64) default '' null comment '创建者', + create_time datetime null comment '创建时间', + update_by varchar(64) default '' null comment '更新者', + update_time datetime null comment '更新时间' +) + comment '游戏类型币种行数管理' row_format = DYNAMIC; + +-- auto-generated definition +create table ff_game_exchange_money +( + id bigint auto_increment comment '主键id' + primary key, + currency_code varchar(50) null comment '币种编码', + transactionId varchar(64) null comment '交易id', + member_id bigint not null comment '会员id', + platform_code varchar(50) null comment '游戏平台 ', + platform_id bigint null comment '平台id', + balance decimal(16, 2) null comment '操作金额', + coin_before decimal(16, 2) null comment ' 转账前金额(游戏币)', + coin_after decimal(16, 2) null comment '转账后金额(游戏币)', + currency_before decimal(16, 2) null comment '转账前金额(指定货币)', + currency_after decimal(16, 2) null comment '转账后金额(指定货币)', + exchange_type tinyint null comment '转出类型 1游戏商转入到用户全部转出 2 用户转移到游戏商 3 游戏商转移额度到平台商', + status tinyint null comment '状态 1 成功 2失败', + create_by varchar(64) default '' null comment '创建者', + create_time datetime null comment '创建时间', + update_by varchar(64) default '' null comment '更新者', + update_time datetime null comment '更新时间' +) + comment '会员金额转移记录' row_format = DYNAMIC; + + + +-- auto-generated definition +create table ff_game_kill_rate +( + id bigint auto_increment comment '主键id' + primary key, + currency_code varchar(50) null comment '币种编码', + line_name varchar(256) null comment '线路名称', + line_id varchar(256) null comment '线路id', + sub_line_id varchar(256) null comment '子线路id', + game_id bigint null comment '游戏id', + kill_rate decimal(16, 2) null comment '游戏杀率 ff_kill_rate', + remark varchar(256) null comment '备注', + create_by varchar(64) default '' null comment '创建者', + create_time datetime null comment '创建时间', + update_by varchar(64) default '' null comment '更新者', + update_time datetime null comment '更新时间' +) + comment '原生游戏杀率' row_format = DYNAMIC; + +-- auto-generated definition +create table ff_game_platform +( + id bigint auto_increment comment '主键id' + primary key, + sort_no int default 0 null comment '排序', + platform_code varchar(50) null comment '平台编码', + platform_type bigint default 1 null comment '平台类型 ff_game_type 字典', + platform_name varchar(50) null comment '平台名称', + popular_one tinyint default 2 null comment '热门1 热门 1 开启 2关闭 ', + popular_two tinyint default 2 null comment '热门2 热门 1 开启 2关闭', + stop_status tinyint default 2 null comment '维护开关 维护状态 1 开启 2关闭', + platform_status tinyint default 2 null comment '平台开关 平台开关状态 1 开启 2关闭', + game_count int null comment '游戏数量', + ios_jump tinyint default 1 null comment 'ios跳转方式 1 内嵌 2 外链', + android_jump tinyint default 1 null comment 'android跳转方式 1 内嵌 2 外链 jump_type字典', + h5_jump tinyint default 1 null comment 'H5跳转方式 1 内嵌 2 外链', + platform_logo varchar(500) null comment '品牌logo', + promotional_style tinyint default 1 null comment '宣传图样式 1 默认 2 自定义 ', + promotional_image varchar(500) null comment '宣传图', + popular_style varchar(500) null comment '热门图预览', + create_by varchar(64) default '' null comment '创建者', + create_time datetime null comment '创建时间', + update_by varchar(64) default '' null comment '更新者', + update_time datetime null comment '更新时间' +) + comment '平台管理' row_format = DYNAMIC; + +-- auto-generated definition +create table ff_game_platform_currency +( + id bigint auto_increment comment '主键id' + primary key, + game_platform_id bigint null comment '平台管理id', + currency_code varchar(50) null comment '币种编码', + min_amount decimal(16, 2) default 0.0000 null comment '最低入场金额', + create_by varchar(64) default '' null comment '创建者', + create_time datetime null comment '创建时间', + update_by varchar(64) default '' null comment '更新者', + update_time datetime null comment '更新时间' +) + comment '平台币种管理' row_format = DYNAMIC; + +-- auto-generated definition +create table ff_game_pool +( + id bigint auto_increment comment '主键id' + primary key, + currency_code varchar(50) null comment '币种编码', + display_format tinyint null comment '展示形式 1独立模块 2多个轮播 ff_display_format', + turn_pool tinyint null comment '彩金池轮播 1新轮播 ff_turn_pool', + turn_name varchar(50) null comment '轮播名称', + display_location tinyint null comment '展示位置 ff_display_location', + click_location tinyint null comment '点击跳转位置 ff_click_location', + click_url varchar(500) null comment '点击跳转位置外部链接地址', + max_display_amount decimal(16, 2) null comment '最大展示金额', + min_display_amount decimal(16, 2) null comment '最小展示金额', + number_places tinyint null comment '小数点位数 0-2', + amount_state tinyint null comment '金额数字选择 1 默认 2自定义 ff_amount_state ', + amount_style tinyint null comment '金额数字样式 ff_amount_style', + amount_typeface tinyint null comment '金额数字字体 ff_amount_typeface ', + amount_typeface_size int null comment '金额数字大小 ', + amount_typeface_colour varchar(50) null comment '金额数字颜色 ', + amount_frame_size varchar(50) null comment '金额数字边框样式 ', + background_state tinyint null comment '背景风格 ff_background_state ', + background_style_url varchar(500) null comment '背景风格地址 ', + state tinyint null comment '状态', + remark varchar(256) null comment '备注', + create_by varchar(64) default '' null comment '创建者', + create_time datetime null comment '创建时间', + update_by varchar(64) default '' null comment '更新者', + update_time datetime null comment '更新时间' +) + comment '虚拟彩金池' row_format = DYNAMIC; +-- auto-generated definition +create table ff_game_collection +( + id bigint auto_increment comment '主键id' + primary key, + member_id bigint not null comment '用户id', + game_id bigint not null comment '游戏id', + create_by varchar(64) default '' null comment '创建者', + create_time datetime null comment '创建时间', + update_by varchar(64) default '' null comment '更新者', + update_time datetime null comment '更新时间' +) + comment '平台游戏收藏' row_format = DYNAMIC; + +-- auto-generated definition +create table ff_game_play_history +( + id bigint auto_increment comment '主键id' + primary key, + member_id bigint not null comment '用户id', + game_id bigint not null comment '游戏id', + create_by varchar(64) default '' null comment '创建者', + create_time datetime null comment '创建时间', + update_by varchar(64) default '' null comment '更新者', + update_time datetime null comment '更新时间' +) + comment '游戏访问历史管理' row_format = DYNAMIC; + + + +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5000, 0, '电子', '1', 'ff_game_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 05:39:09', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5001, 1, '棋牌', '2', 'ff_game_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 05:39:16', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5002, 2, '真人', '3', 'ff_game_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 05:39:28', 'admin', '2024-10-23 06:18:07', NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5003, 3, '捕鱼', '4', 'ff_game_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 05:39:34', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5004, 4, '彩票', '5', 'ff_game_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 05:39:42', 'admin', '2024-10-23 06:17:56', NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5005, 5, '体育', '6', 'ff_game_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 06:18:33', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5006, 6, '斗鸡', '7', 'ff_game_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 06:18:50', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5007, 7, '电竞', '8', 'ff_game_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 06:19:03', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5008, 8, '彩票', '9', 'ff_game_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 06:19:15', 'admin', '2024-10-23 06:19:21', NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5009, 9, '区块链', '10', 'ff_game_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 06:19:30', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5010, 0, '未结算', '1', 'ff_settlement_status', NULL, 'default', 'N', '0', 'admin', '2024-10-23 07:18:14', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5011, 1, '已结算', '2', 'ff_settlement_status', NULL, 'default', 'N', '0', 'admin', '2024-10-23 07:18:23', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5012, 2, '已撤单', '3', 'ff_settlement_status', NULL, 'default', 'N', '0', 'admin', '2024-10-23 07:18:33', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5013, 0, 'JILI', 'JILI', 'ff_game_platform', NULL, 'default', 'N', '0', 'admin', '2024-10-23 07:22:49', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5014, 0, '开启', '1', 'ff_popular_one', NULL, 'default', 'N', '0', 'admin', '2024-10-24 07:22:40', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5015, 1, '关闭', '2', 'ff_popular_one', NULL, 'default', 'N', '0', 'admin', '2024-10-24 07:22:48', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5016, 0, '开启', '1', 'ff_recommended_status', NULL, 'default', 'N', '0', 'admin', '2024-10-24 07:23:52', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5017, 1, '关闭', '2', 'ff_recommended_status', NULL, 'default', 'N', '0', 'admin', '2024-10-24 07:24:03', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5018, 0, '开启', '1', 'ff_stop_status', NULL, 'default', 'N', '0', 'admin', '2024-10-24 07:25:01', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5019, 1, '关闭', '2', 'ff_stop_status', NULL, 'default', 'N', '0', 'admin', '2024-10-24 07:25:11', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5020, 0, '开启', '1', 'ff_platform_status', NULL, 'default', 'N', '0', 'admin', '2024-10-24 07:25:48', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5021, 1, '关闭', '2', 'ff_platform_status', NULL, 'default', 'N', '0', 'admin', '2024-10-24 07:25:56', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5022, 0, '默认', '1', 'ff_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-24 07:26:52', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5023, 1, '自定义', '2', 'ff_icon_style', NULL, 'default', 'N', '0', 'admin', '2024-10-24 07:27:00', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5024, 0, '内嵌', '1', 'jump_type', NULL, 'default', 'N', '0', 'admin', '2024-10-24 07:30:51', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5025, 1, '外链', '2', 'jump_type', NULL, 'default', 'N', '0', 'admin', '2024-10-24 07:30:57', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5026, 0, '外部链接', '1', 'ff_open_url_type', NULL, 'default', 'N', '0', 'admin', '2024-10-25 08:46:49', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5027, 1, '分享再赠送', '2', 'ff_open_url_type', NULL, 'default', 'N', '0', 'admin', '2024-10-25 08:47:02', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5028, 0, '独立模块', '1', 'ff_display_format', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:28:28', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5029, 1, '多个轮播', '2', 'ff_display_format', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:28:38', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5031, 0, '新轮播', '1', 'ff_turn_pool', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:31:42', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5032, 2, '电子', '1', 'ff_display_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:34:04', 'admin', '2024-10-28 05:34:22', NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5033, 3, '棋牌', '2', 'ff_display_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:34:37', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5034, 5, '真人', '3', 'ff_display_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:34:49', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5035, 4, '捕鱼', '4', 'ff_display_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:35:02', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5036, 6, '彩票', '5', 'ff_display_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:35:14', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5037, 7, '体育', '6', 'ff_display_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:35:24', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5038, 8, '斗鸡', '7', 'ff_display_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:35:38', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5039, 9, '电竞', '8', 'ff_display_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:35:50', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5040, 10, '彩票', '9', 'ff_display_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:36:01', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5041, 11, '区块链', '10', 'ff_display_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:36:10', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5042, 1, '热门', '11', 'ff_display_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:36:20', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5043, 12, '试玩', '12', 'ff_display_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:36:29', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5044, 0, '每周任务', '-1', 'ff_click_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:47:28', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5045, 1, '新人福利', '-2', 'ff_click_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:47:37', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5046, 2, '神秘任务', '-3', 'ff_click_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:47:51', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5047, 3, '每日任务', '-4', 'ff_click_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:48:04', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5048, 4, '任务活跃度', '-5', 'ff_click_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:48:19', 'admin', '2024-10-28 05:48:22', NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5049, 5, '外部链接', '-6', 'ff_click_location', NULL, 'default', 'N', '0', 'admin', '2024-10-28 05:48:36', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5050, 0, '默认', '1', 'ff_amount_state', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:03:03', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5051, 1, '自定义', '2', 'ff_amount_state', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:03:16', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5052, 0, '样式一', '1', 'ff_amount_style', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:05:15', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5053, 1, '样式二', '2', 'ff_amount_style', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:05:24', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5054, 2, '样式三', '3', 'ff_amount_style', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:05:31', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5055, 3, '样式四', '4', 'ff_amount_style', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:05:37', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5056, 4, '样式五', '5', 'ff_amount_style', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:05:43', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5057, 5, '样式六', '6', 'ff_amount_style', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:05:53', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5058, 0, 'Avenir', '1', 'ff_amount_typeface', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:07:23', 'admin', '2024-10-28 06:07:33', NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5059, 1, 'EncodeBold', '2', 'ff_amount_typeface', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:07:47', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5060, 2, 'Irr3v', '3', 'ff_amount_typeface', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:07:58', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5061, 3, 'Motel', '4', 'ff_amount_typeface', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:08:07', 'admin', '2024-10-28 06:08:16', NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5062, 4, 'Ravenna', '5', 'ff_amount_typeface', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:11:34', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5063, 0, '样式一', '1', 'ff_background_state', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:15:09', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5064, 1, '样式二', '2', 'ff_background_state', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:15:19', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5065, 2, '样式三', '3', 'ff_background_state', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:15:29', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5066, 3, '自定义', '4', 'ff_background_state', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:15:38', 'admin', '2024-10-28 06:16:59', NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5067, 0, '开启', '1', 'ff_game_pool_state', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:29:55', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5068, 1, '关闭', '2', 'ff_game_pool_state', NULL, 'default', 'N', '0', 'admin', '2024-10-28 06:30:05', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5069, 0, '2.5%', '2.5', 'ff_kill_rate', NULL, 'default', 'N', '0', 'admin', '2024-10-28 07:08:25', 'admin', '2024-10-28 07:10:08', NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5070, 1, '3.50%(默认)', '3.5', 'ff_kill_rate', NULL, 'default', 'N', '0', 'admin', '2024-10-28 07:08:47', 'admin', '2024-10-28 07:10:03', NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5071, 2, '4.00%', '4', 'ff_kill_rate', NULL, 'default', 'N', '0', 'admin', '2024-10-28 07:09:06', 'admin', '2024-10-28 07:09:57', NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5072, 3, '4.50%', '4.5', 'ff_kill_rate', NULL, 'default', 'N', '0', 'admin', '2024-10-28 07:09:19', 'admin', '2024-10-28 07:09:53', NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5073, 4, '5.50%', '5.5', 'ff_kill_rate', NULL, 'default', 'N', '0', 'admin', '2024-10-28 07:09:46', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5000, '游戏类型', 'ff_game_type', '0', 'admin', '2024-10-23 05:38:52', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5001, '游戏投注结算状态', 'ff_settlement_status', '0', 'admin', '2024-10-23 07:17:11', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5002, '游戏平台', 'ff_game_platform', '0', 'admin', '2024-10-23 07:22:41', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5003, '热门状态', 'ff_popular_one', '0', 'admin', '2024-10-24 07:22:29', 'admin', '2024-10-24 07:23:05', NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5004, '推荐角标状态', 'ff_recommended_status', '0', 'admin', '2024-10-24 07:23:40', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5005, '维护开关', 'ff_stop_status', '0', 'admin', '2024-10-24 07:24:37', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5006, '平台开关', 'ff_platform_status', '0', 'admin', '2024-10-24 07:25:36', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5007, '宣传图样式选择', 'ff_icon_style', '0', 'admin', '2024-10-24 07:26:43', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5008, '游戏跳转方式', 'jump_type', '0', 'admin', '2024-10-24 07:30:31', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5009, '链接地址类型', 'ff_open_url_type', '0', 'admin', '2024-10-25 08:45:33', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5010, '展示形式', 'ff_display_format', '0', 'admin', '2024-10-28 05:26:23', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5011, '彩金池轮播', 'ff_turn_pool', '0', 'admin', '2024-10-28 05:31:29', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5012, '展示位置', 'ff_display_location', '0', 'admin', '2024-10-28 05:32:00', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5013, '点击跳转位置', 'ff_click_location', '0', 'admin', '2024-10-28 05:36:53', 'admin', '2024-10-28 06:16:47', NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5014, '金额数字选择', 'ff_amount_state', '0', 'admin', '2024-10-28 06:02:52', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5015, '金额数字样式', 'ff_amount_style', '0', 'admin', '2024-10-28 06:03:51', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5016, '金额数字字体', 'ff_amount_typeface', '0', 'admin', '2024-10-28 06:07:05', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5017, '背景风格', 'ff_background_state', '0', 'admin', '2024-10-28 06:14:54', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5018, '彩金池状态', 'ff_game_pool_state', '0', 'admin', '2024-10-28 06:29:45', '', NULL, NULL); +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5019, '游戏杀率', 'ff_kill_rate', '0', 'admin', '2024-10-28 07:07:43', '', NULL, NULL); +INSERT INTO `sys_job` (`job_id`, `job_name`, `job_group`, `invoke_target`, `cron_expression`, `misfire_policy`, `concurrent`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5001, '游戏投注信息同步', 'DEFAULT', 'gameTask.insertGameBettingDetails', '0 0/50 * * * ?', '1', '1', '0', 'admin', '2024-10-22 10:49:07', '', '2024-10-22 10:49:13', ''); +INSERT INTO `sys_job` (`job_id`, `job_name`, `job_group`, `invoke_target`, `cron_expression`, `misfire_policy`, `concurrent`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5002, '更新游戏信息', 'SYSTEM', 'gameTask.updateGameInfo', '* 0/1 * 1 * ?', '1', '1', '1', 'admin', '2024-10-24 05:34:16', '', NULL, ''); +INSERT INTO `sys_config` (`config_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5001, 'JILI游戏请求接口URl', 'jili.api.base.url', 'https://uat-wb-api-2.jiscc77s.com/api1', 'Y', 'admin', '2024-10-22 02:15:04', 'admin', '2024-10-24 09:13:58', NULL); +INSERT INTO `sys_config` (`config_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5002, '游戏限制-首充', 'game.recharge', '1', 'Y', 'admin', '2024-10-24 09:12:09', '', '2024-10-29 06:34:21', '已首充才能进入游戏(未充值无法进入) 1 不限制 2 限制'); +INSERT INTO `sys_config` (`config_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5003, '游戏限制-下载App', 'game.download.app', '1', 'Y', 'admin', '2024-10-24 09:15:01', '', '2024-10-29 06:34:21', '强制要求下载APP 1 不限制 2 限制只能app玩'); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5001, '游戏管理', 0, 2, 'game', NULL, NULL, '', 1, 0, 'M', '0', '0', '', 'dict', 'admin', '2024-10-21 09:53:17', 'admin', '2024-10-31 08:19:06', ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5002, '游戏管理', 5001, 1, 'index', 'game/index', NULL, '', 1, 0, 'C', '0', '0', '', 'list', 'admin', '2024-10-28 01:30:57', 'admin', '2024-10-31 08:19:16', ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5003, '代理模式', 3051, 1, 'agentMode', 'agent/agentMode/index', NULL, '', 1, 0, 'C', '0', '0', 'agent:agentMode:list', '#', 'admin', '2024-10-29 07:25:03', '', NULL, '代理模式菜单'); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5004, '投注记录', 5001, 2, '/details', NULL, NULL, '', 1, 0, 'C', '0', '0', NULL, 'list', 'admin', '2024-10-29 08:59:44', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5005, '会员投注细目', 5001, 3, '/summary', NULL, NULL, '', 1, 0, 'C', '0', '0', NULL, 'list', 'admin', '2024-10-29 09:00:48', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5006, '虚拟彩金池', 5001, 4, '/pool', NULL, NULL, '', 1, 0, 'C', '0', '0', NULL, 'list', 'admin', '2024-10-29 09:01:23', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5007, '游戏统计', 5001, 5, '/statistics', NULL, NULL, '', 1, 0, 'C', '0', '0', NULL, 'list', 'admin', '2024-10-29 09:02:07', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5008, '原生游戏杀率调控', 5001, 6, '/rate', NULL, NULL, '', 1, 0, 'C', '0', '0', NULL, 'list', 'admin', '2024-10-29 09:02:48', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5009, '组队瓜分彩金池', 5001, 7, '/ranks', NULL, NULL, '', 1, 0, 'C', '0', '0', NULL, 'list', 'admin', '2024-10-29 09:05:52', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5010, '列表', 5002, 1, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:game:list', '#', 'admin', '2024-10-31 08:17:57', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5011, '导出', 5002, 2, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:game:export', '#', 'admin', '2024-10-31 08:18:12', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5012, '详情', 5002, 3, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:game:query', '#', 'admin', '2024-10-31 08:18:27', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5013, '新增', 5002, 4, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:game:add', '#', 'admin', '2024-10-31 08:19:34', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5014, '修改', 5002, 5, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:game:edit', '#', 'admin', '2024-10-31 08:19:52', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5015, '列表', 5004, 1, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:details:list', '#', 'admin', '2024-10-31 08:20:29', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5016, '查询会员投注统计列表', 5004, 2, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:details:statistics', '#', 'admin', '2024-10-31 08:21:30', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5017, '详情', 5007, 3, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:details:query', '#', 'admin', '2024-10-31 08:21:51', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5019, '排名', 5002, 6, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:rank:list', '#', 'admin', '2024-10-31 08:22:58', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5020, '查询游戏类型管理列表', 5002, 7, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:category:list', '#', 'admin', '2024-10-31 08:23:44', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5021, '获取游戏类型管理详细信息', 5002, 8, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:category:query', '#', 'admin', '2024-10-31 08:24:08', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5022, '新增游戏类型管理', 5002, 9, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:category:add', '#', 'admin', '2024-10-31 08:24:25', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5023, '游戏类型管理修改', 5002, 10, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:category:edit', '#', 'admin', '2024-10-31 08:24:45', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5024, '删除游戏类型管理', 5002, 11, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:category:remove', '#', 'admin', '2024-10-31 08:25:08', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5025, '查询原生游戏杀率列表', 5008, 1, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:rate:list', '#', 'admin', '2024-10-31 08:25:54', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5026, '修改原生游戏杀率', 5008, 3, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:rate:edit', '#', 'admin', '2024-10-31 08:26:31', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5027, '详情', 5008, 2, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:rate:query', '#', 'admin', '2024-10-31 08:26:52', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5028, '查询平台管理列表', 5002, 12, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:platform:list', '#', 'admin', '2024-10-31 08:27:27', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5029, '修改平台管理', 5002, 13, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:platform:edit', '#', 'admin', '2024-10-31 08:27:42', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5030, '获取平台管理详细信息', 5002, 14, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:platform:query', '#', 'admin', '2024-10-31 08:28:03', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5031, '查询虚拟彩金池列表', 5006, 1, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:pool:list', '#', 'admin', '2024-10-31 08:29:15', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5032, '获取虚拟彩金池详细信息', 5006, 2, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:pool:query', '#', 'admin', '2024-10-31 08:29:32', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5033, '新增虚拟彩金池', 5006, 3, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:pool:add', '#', 'admin', '2024-10-31 08:29:55', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5034, '修改虚拟彩金池', 5006, 4, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:pool:edit', '#', 'admin', '2024-10-31 08:30:09', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5035, '删除虚拟彩金池', 5006, 5, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:pool:remove', '#', 'admin', '2024-10-31 08:30:19', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5036, '查询会员投注细目列表', 5005, 1, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:details:list', '#', 'admin', '2024-10-31 08:30:55', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5037, '查询会员投注统计', 5005, 2, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:details:statistics', '#', 'admin', '2024-10-31 08:31:24', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5038, '查询会员投注细目列表', 5007, 1, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:details:list', '#', 'admin', '2024-10-31 08:43:39', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5039, '汇总统计', 5007, 2, '', NULL, NULL, '', 1, 0, 'F', '0', '0', 'game:details:statistics', '#', 'admin', '2024-10-31 08:44:09', '', NULL, ''); +INSERT INTO `ff_game_category` (`id`, `sort_no`, `category_name`, `category_switch`, `open_type`, `open_url`, `open_url_type`, `icon_url`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (1, 2, '电子', 2, -1, NULL, 1, NULL, NULL, 'system', '2024-10-25 15:11:47', '', NULL); +INSERT INTO `ff_game_category` (`id`, `sort_no`, `category_name`, `category_switch`, `open_type`, `open_url`, `open_url_type`, `icon_url`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (2, 3, '棋牌', 2, -1, NULL, 1, NULL, NULL, 'system', '2024-10-25 15:11:47', '', NULL); +INSERT INTO `ff_game_category` (`id`, `sort_no`, `category_name`, `category_switch`, `open_type`, `open_url`, `open_url_type`, `icon_url`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (3, 5, '真人', 2, -1, NULL, 1, NULL, NULL, 'system', '2024-10-25 15:11:47', '', NULL); +INSERT INTO `ff_game_category` (`id`, `sort_no`, `category_name`, `category_switch`, `open_type`, `open_url`, `open_url_type`, `icon_url`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (4, 4, '捕鱼', 2, -1, NULL, 1, NULL, NULL, 'system', '2024-10-25 15:11:47', '', NULL); +INSERT INTO `ff_game_category` (`id`, `sort_no`, `category_name`, `category_switch`, `open_type`, `open_url`, `open_url_type`, `icon_url`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (5, 6, '彩票', 2, -1, NULL, 1, NULL, NULL, 'system', '2024-10-25 15:11:47', '', NULL); +INSERT INTO `ff_game_category` (`id`, `sort_no`, `category_name`, `category_switch`, `open_type`, `open_url`, `open_url_type`, `icon_url`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (6, 7, '体育', 2, -1, NULL, 1, NULL, NULL, 'system', '2024-10-25 15:11:47', '', NULL); +INSERT INTO `ff_game_category` (`id`, `sort_no`, `category_name`, `category_switch`, `open_type`, `open_url`, `open_url_type`, `icon_url`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (7, 8, '斗鸡', 2, -1, NULL, 1, NULL, NULL, 'system', '2024-10-25 15:11:47', '', NULL); +INSERT INTO `ff_game_category` (`id`, `sort_no`, `category_name`, `category_switch`, `open_type`, `open_url`, `open_url_type`, `icon_url`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (8, 9, '电竞', 2, -1, NULL, 1, NULL, NULL, 'system', '2024-10-25 15:11:47', '', NULL); +INSERT INTO `ff_game_category` (`id`, `sort_no`, `category_name`, `category_switch`, `open_type`, `open_url`, `open_url_type`, `icon_url`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (9, 10, '彩票', 2, -1, NULL, 1, NULL, NULL, 'system', '2024-10-25 15:11:47', '', NULL); +INSERT INTO `ff_game_category` (`id`, `sort_no`, `category_name`, `category_switch`, `open_type`, `open_url`, `open_url_type`, `icon_url`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (10, 11, '区块链', 2, -1, NULL, 1, NULL, NULL, 'system', '2024-10-25 15:11:47', '', NULL); +INSERT INTO `ff_game_category` (`id`, `sort_no`, `category_name`, `category_switch`, `open_type`, `open_url`, `open_url_type`, `icon_url`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (11, 1, '热门', 2, -1, NULL, 1, NULL, NULL, 'system', '2024-10-25 15:11:47', '', NULL); +INSERT INTO `ff_game_category` (`id`, `sort_no`, `category_name`, `category_switch`, `open_type`, `open_url`, `open_url_type`, `icon_url`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES (12, 12, '试玩', 2, -1, NULL, 1, NULL, NULL, 'system', '2024-10-25 15:11:47', '', NULL); +INSERT INTO `sys_config` (`config_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5004, '游戏限制-首充下载App', 'game.recharge.download.app', '1', 'Y', 'admin', '2024-10-24 09:15:01', '', '2024-10-29 06:34:21', '首充强制要求下载APP 1 关闭(全部限制) 2 开启(仅限已首充会员)'); +INSERT INTO `sys_config` (`config_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5005, '游戏限制-仅限Android设备强制下载APP', 'game.android.download.app', '1', 'Y', 'admin', '2024-10-24 09:15:01', '', '2024-10-29 06:34:21', '仅限Android设备强制下载AP 1 关闭(全部限制) 2 开启 '); +INSERT INTO `sys_config` (`config_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5006, '热门一', 'hot.one', '1', 'Y', 'admin', '2024-10-24 09:15:01', '', '2024-10-29 06:34:21', '热门一 1 开启 2 关闭(全部限制)'); +INSERT INTO `sys_config` (`config_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5007, '热门二', 'hot.two', '1', 'Y', 'admin', '2024-10-24 09:15:01', '', '2024-10-29 06:34:21', '热门二 1 开启 2 关闭(全部限制)'); + +create table ff_game_popular +( + id bigint auto_increment comment '主键id' + primary key, + sort_no int default 0 null comment '排序', + platform_id bigint null comment '游戏平台id', + game_id bigint null comment '游戏id', + popular_category int null comment '热门 类别 1 平台 2游戏', + popular_type int null comment '热门归属 1 热门一 2 热门二', + create_by varchar(64) default '' null comment '创建者', + create_time datetime null comment '创建时间', + update_by varchar(64) default '' null comment '更新者', + update_time datetime null comment '更新时间' +) + comment '平台热门管理' row_format = DYNAMIC; + diff --git a/sql/update_xiongshang.sql b/sql/update_xiongshang.sql new file mode 100644 index 0000000..b5e5aac --- /dev/null +++ b/sql/update_xiongshang.sql @@ -0,0 +1,359 @@ +/* + Navicat Premium Data Transfer + + Source Server : dev + Source Server Type : MySQL + Source Server Version : 80040 + Source Host : localhost:3306 + Source Schema : ff-admin + + Target Server Type : MySQL + Target Server Version : 80040 + File Encoding : 65001 + + Date: 22/10/2024 14:03:00 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for ff_agent_level +-- ---------------------------- +DROP TABLE IF EXISTS `ff_agent_level`; +CREATE TABLE `ff_agent_level` ( + `id` bigint NOT NULL COMMENT '主键id', + `level_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '代理等级名称', + `level` tinyint NULL DEFAULT NULL COMMENT '等级', + `total_commission` decimal(10, 0) NULL DEFAULT NULL COMMENT '晋升等级佣金标准', + `icon_url` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '图片地址', + `default_status` tinyint NULL DEFAULT NULL COMMENT '默认状态', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代理等级表' ROW_FORMAT = Dynamic; + +ALTER TABLE `ff_agent_level` MODIFY COLUMN `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id' FIRST; + + +-- ---------------------------- +-- Records of ff_agent_level +-- ---------------------------- +INSERT INTO `ff_agent_level` VALUES (1, 'LV1', 1, 0, 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKoAAACWCAMAAAB5EONmAAADAFBMVEUAAAABAAAIBQQAAAABAAAAAADWQB0HAgEBAAC7Oxi2OhnMRSFVHxH/hSj/2DvLRCCgNxvPQh30kCu7Px+oQSfNTCuuPR7Xk1V/LBfnkm/rZyPCdE7No3vqrI3jsYnHNxzbZ0zpXBf+9W60VTj8x6mhNx377afnezT779/4xab1xaaHOCD90D71xFf99rb/1ab//tL/0qP/+dH/2qj/+cz/3az/57n/7Lz/9sr/4LH/7sD/8MP/3KjMUSH/9MX/367/47L/9cj/ZQL/5bb//9X4qouXOy+4TTz/z6D/tpD6r5D/sY388tb//9r75cr/y57/xJ//zDX8rY3/y6n/1bX/2br/u5P/r4n0p4fdgGTXfWP/XwD63sb/vprunX387M3/0rD/x6XXdlz5kWv95sL/+Kbto4X/yJn/WQL//9/528DmnYH/Zxf//+zci3C1SjXENwj87NPPb1b/3b7zsJT4o3+7STj/zq3/YVb+/uT/rlPaRyT/iQH/9J72u5T/1Wj/Zwz/ZET/YE7/ZTGeOSn/aCT/ogL1s4relXnERzP/qBH/xJe0Oi3+7I3/hkXGTjv/UwP54br//a7/cwP///PVazzdUC7/kgP/fwHfWjjHQRH/jFX/wj6JIxn/mwXmp4z+qIS6QDL/8Zb/uUi7U0D/xC7/5oX/3HOrNST899zSY0zsr5L/43vcb1T/mC7/bAH/z17mc1P/XzrNc1z/xlfJU0D/jjX/XyX/XRD///z/68bps4nhkHPujWrEYEy/W0j/VEj/dx/+uYz/okvTNRH9RwP//Lv/r4LrlXf2mnj/eTD/oCLghmrHZ1H+pXf+ulWuTTn/UzT/+lz/lkOgQzLyxaf/ck/MXUbqtoziZ0bVjXL+mlv/bzX5163bpYv/ojn/tTH/hAz33LLvy67/5q3qg1+nPyz/kR7/tR39gmT/zUL/SyKcLx7rvZ3//Znselrz1bv8ymvLfmL/4UrfuJ7Qgmv/f1PKSRn/3Z3/9H7/5GHlRBjrTze4a07brV/qXUs2ld+4AAAAL3RSTlMACRAZLib+NSChir9Q/v7PguXRtV6tmXxqo7poNKxn/Kj45nfgR9L30b2hK9Og35Ed5c0AABouSURBVHjatNQxa9tAFAfwOp2roUspDRk6hAxtyZBPoD2DZo3hQAF1d4WFZAdrEEjDUUhARoONrEUII4Tt0cagwRpEIsjigF0oOFEhYAwFZ+o76Vya0qGDdcMhnp99P/3vfC/+f1Qq+/v7Bwdfvh4/ovPPXx+fbsjY3Nxk6dls7s9nZ5P5PJ3NYJ7MZvk0gXFG5tkKWt/n49Ph4dHR0eHhQQXGi1JGZf8DE4bc03m0eTw+P8UeoT6RKXmw+v2+9WCSmTyavwt++lAUQtoM74ZPv5yjzfH3jx/fvn1Thrayx3DzyUJfoM0mOokMb7Ner8NwDWNWn07Ht9W78Xh6ezsdj+9u6SOd4bOLxc26lzeHxgl8+wmddvVOh2M+7FV2Lq28u0+tWLdj18NRtHmSDS5LkoxhsjAdiM169UIUm416UxQvqoEIhUYT5iopBNWLob8umpOWfAIb0o5OlGka63r8tlLZeahv5rNY15YpSHG3Z0RdBxbPmJYU+kOxXm2quVRVLwCtiiBVVZDCI0jVoR+CFJo7mRx5ShtjlEx1TfPN13slUPMQzFSOkNfrIux1pBbHweLMchiAlBUbdZFlQaqyKpGyRMoCvcmywzTM8maOM+A9EWq7Ug2k1hKolR3v/8s3RGq90hEGKUbtlZRl+eLM8ppoxDqVskQqQqFaFAZQGFkMlWaKQqSKt6qB1Ndev9zbPZVIU1tHXcgUyW7Yoosz5ohm+kwKmao0U7E+8pmimev0cqmCV7UYpPbuqXtABalu655CMlVcj0q58OeAVUGaw+juEynNVAVpYxgzVCq5GBmK0o5630BaAvUFUIlUt/1VkYrsbWNK+kIhpZkGf0qbrApSUYgzKm11cbtH/lfJHUi1fimppiDVl2aeKazlbWPKlgKVPjuneQGuAbVeFVnBT6iUM2T4NkLGbAzS1CwlVSL1Tb+NZaXXRtid0MXhBmg0/i0dbAsDK6RSznMVGcldRaqB1CrprILUWmoyTSXcxsT4I9AUUjYopMFzenOUMlTagt2XZbiwwprWt2KtlFSJ1L/UDEgFwzXQK6Qw/xzRS2krbdRZWqDS6nXMUKm0ItLQw8kVkdrlXFYg1WybZup5Tr6400rMIewwzXTI80OQ8s+lgRAzVCp1EUhdhJMxSEu6AYhUs/srhEGqIM/JpY6ULAV2ADCep9KA5/m8wNKDG7BCHJJmkDpdDJnKMpLubFuzzTJSfZf6tm2bZjfCIJWxR6UStxQAxv8t5XMpD8chYFnBTFoOaXYcwwhdWZa9yRX8nPWqjFTf+RpIp5cGLtZSJtvFv/0opCMqFfg/6ETKs9dW0Qyz0oNM267bqdmXpnlZSqo2+enaZbsNJw1SCReOs5Ami/v76YjArolUGAWCQEIWnoUcjF5xVLoIiVTpyeEVkZZD/UV7/b4mEcdxACcq6kE+iR7Vg4iIHvQgCox6EJFkUW1tzLsSbKWsLaVi1DL7cWK2jLCUL17hgbjWKl04uDXCaRDM6tua0TYpfNBkJpVu3LA2xiBcq8/nzvUXdPfAB+fXu9e9/Xy/38/dQikXjLii2AK4XF+efHmN0i9ZyWS1ZgbAqEilAUoInJClGTleUpAHP4HPaNnpjPb6AiM8Sjl1UkWpUHje0+yENrCrZwJuPjExkR/zkH/SjNVK6eVs2pOQMsoJpRCI8ER5rLE8/ByksAJ44HJcYa0a1Lh86dx0AO8VeRv1gtTrzY/lRYwQuASklOaGBgcPDw43tRMCUiwHiJcIV+GxUDoRaUZpc3nMA5fTpFWhylJ3KvIWpbCxfsReGxs5kSxKKe1vajx61MBaABvqlySUyt+5X3th8FjeOxGBdhfnVZ7nuFRWUIUaBGnWI/jeyqk4p+P4woFrrQ7+fULIgEStoaP1R+uP266ct+iNncNzVkoklFozbhj8PpT33vL2Qmvt9LkiI6KQyqZUoa4JgjQtCBEfttZd0ZEOlOJa2z5A4MhIxH8MoAx7pObpSUNDzGgfnvRIGYJTLCPeulUKyV0fbqw+aK1HTCjlVaF2yFK+NwpbI7xw9AY7SqF4RzAYd6NUktLD9fWNDpZlT223nXc06PUx41DTZD+lJJOhuo7SXBweK+7vCTh9vdBaPzKBVFAn1fcoFRIfy9iw9jZHg6WQJghSv4kQKl0GaJ2ZYdm2NqDWmA8fOqS/GLM3TeYSkCzVleaUwcGeZh/WQDkupXieT6lCDaE01UemA9Ba+wKugnxzjZ8zUdo3dKeubisjS9uO1Nq2MwcbwKqPxYYmszcIpQll8FwhGOmSpQvXroM0999XAGxYt2hQmk2ZKguRqM8ZmE5XpRylTY11pwHKILSNPXXuXC1zrAFyRWxLU7YvQfs0sH6AlOOiUZevXF5Yb+VF3pMT1aCuXIdSSEJX2VyGehtJcSgtCIL/sKHOYgboojSZvHePPdbZoFhjJyZvDPQHFanAPY+CdGY94UXRkzOJm1SgLl2+MZXj4cgl6OYyrAAYk1/gPr4ybNtmNpuZf9Ca8ZmZ2Z215s5O2WqMxd796PMU5EyF9HRXc9fvN0QEabtJt27l0iVA/c/FunLZRlma40W6YbrsEmCvEUqDFsc2LUJZhLY9TT79XAyHp6ZGx2tqLYht0BuNsQcv/8y7UZpLRwOR+29MitS0Zrkc6v+PFawiSHm0+n4JqXTpar1j61azA6UIrUmeGy+G93/69Gm0OPV41ra9sVMPuSK25fv8Bp5Lp4Vfkd20KtWtWbZSDapiTbVjsu1nyYb3vH+s0aHVmg0OhkEoezJ5b3Y0HAYoUEdHi92/v9peHLQj1tgCJftsfj4nBBd20+v/pEqoKll1Is+7PTyP096g/aY1GDBSgB65l/z5Oxzev39/lXpgtLt75qeN7bRjroh9+adylq9UpbrrihSoKlnXaHTus6JOB9N+q3aXwaJAcTadmpkCKB5IReuB1u67n0/aHHa7bG3BKqhI1Uw3rFJNumhdtRne8TWDDvMercEiR8oybVeSNbeLYcV5Ewq1CNJWsAK2dXz7vnq7EYug5QFWQSUBUuvqVVini1KVrCvW8sMWZtcOBqEMQp8mbS2t4XAVWrx76cKHhw9b4QDr44fdj2dr9x4ELFjPwML1p1Lp161doaq0av3Lm/2ENBmHcQCHDgZ1Kagg6B9Uh+rg6/a2TZvTscU2dTrcnH9o1VSSJa9bphsvgiehiS9I8CbURQc7zKJDjA5DU+ggDlp0SLJBO+gQAiWRhqeg53nf97d3ui2CvfVV5/XD83u+v71jR89O3VebNE6vUHxXx6MEMx4FKGZiYiuWmt2kWnZyAtaCWC6W2rT3t492oRVWFrbgX56+TL2w1vG4tuO+ePYu1z2eX1sqgAZn5xM8wySYn0tcJOgPWjBcbO+p3TWXROvg7MiDNzNVZ4rKrzT1whWvS9MQEkYK0Faedw1vy9BIuDXB2DGwvZklLhgEKwb6ZTB7k3fBCtjZxa8zJy//s6ki9Nw1b0hjqnF44S6FPIba9wBUksa4+GaC99mlMIANEiz0y5KhaXfygYT98Hzs+FViVR563ems1agdDmcI+oS1Vw3F8mcfiw2vMQLULAWwuzkZy8WWdyhtO2Axs4Pdz8dO31Aei1t63RlqMN10eLyitCXBzm4VLOkSLCkrQikZy+9Cv8jKYr/MrlHYAuzXbPj1zNgxWFjll9R535S1eqSR3kswO58IFEYaDLcIS1rgpCjE8szPFBchk41xuadmZxKxuAVDX8dOnoLBKg1tzNZ4cEvhga+f5zeXC6FDu7zQpjyUkmKm7Py8gPVLKxsJG3SefL+6ycoq1yZnbbba4xGgIWjTwzipvdgmnvcRKGHKWB8/f6Bf0QWqrmkVrIgdhC1QamVhSb3wXKJ2iCMNudjEvZxc+y0uvsNKUIpAi7F30tNc0O8nK7tGdXQR7OLXMVxZJUZ6xaHO6gcQ6gyF7rck5sMTACUj/SK3CZ3lwjAP0xGu4C1hg3LeXQWpeHFVKbCyKG3QW6cG2mCkzhC0KYO1l6GtPPMHp0r4wZgZZjOOWIuI5dL9hvHVsIh90D1TBdYKr6hrDvWAzdNmtTqdzn6oc2Htp4ceIrQMM69UqVQi1rcTJ/2KWrhoRts4cndQyKvFmSpoV2XH725zzzV72mpqnI8ZvgC6jbXHK7+8U/qHEbV23peJSthoNMil1lc0t4UtCL96MnP8SEXUIxc8t5NznWitU/38JUMn/D1r2CaUlnPKTBnLtIajXBCwYF0G7M6Kd3UwvNplXflxET67VkI9b+tKjs7NdXrUBArS7W2ud83Hs+WdJaA0REVTPqYf+oU3VxTi59LagXd3p/TZlWTVKRhrBZ+oz8/ZbHOjo3NTGXhozp/98KsWgNpLQQmzyKkTQ9M+FvoVtIhbEI3E9daabFavfT92ohLqEaC63e7m0aQtF41+QitAvyzcE9tUeqD4UuwUrUYj/NGsLxOMRHELlpdS02mtHrLypOpE5VN1u22dXbnhJbB+ntiODPYzDLap3IIWHTw4CdRoMBghFLsbj0z7/VGgplKzWYkKy1rJVD/aMFPjQz1o3dqetPIMtumvFxScohSdJDqWzcASIHU4ntZnFaS6xxe7e4eXLVucI4FLWopZdO5y0ClJbwkxGMxMJgpUkMbTaqBqkXqkImoSoO/fI7Vn+Esw1i3UqciJr0RoZoSYDWSgkAPQOswtih+ftCyn4vG9dLVIPVYhtc9ma262SdTpiyM8XFBlnShl7esL6+vrCxtm4iwB1WrrDKzmK1L39tJWvRLUs31NzRD3+BBSJye/MSAt58Qw868DQgYZnThQzCEopo6iv09HBWpbtfqm4tTppyxQC52HwvQ/C9RjAguMEaWloBiN1kj1TSI1lx6oqVaC+h2pnUDt6UVqPytCqZL3EsVs1IOUUI0EWkKq0RiAaknFe3LpqZpqvRLUkXak4lTzVFWpedI0SHdegFSmylICJU7ILaov4l+K9/SEp6zVapMSU21qam635am+cm+ctM7MLARe1B+iFkGJ1FRHvYtYRCo8uHXcHlNgqk3NnYXUUvNEqd23GNgH5P6+SGUN8kjrhMhOkJq09Dsy1Tav11U59cdIE2xAeSpNQqm6BekLeJGo8tnLEyVQpPZNilR3G3xDoyi19yXcAD6qBBPj2xCQgf213hcF1DLQxsZGrS5PHXAoQL30Y6Rdonb3vpzGqZZwYuwb9UAN1D/knxEq6T2Byk6MxpinTjkcilCbwEqoZKr04eh0SAVpK08TKjJRehBKpA0mmerxKE99i1S6BFSkBp7Ns7SOUNEJ0JIjra1tMBmAujyMVLfHEfoH1OKR6gg10MuyBjo/1cP3kwkjQQ9QbQpS2/9E1YnxfQsMMXaDkTYSqpbc+FoJSiba0AC/Nxvz1Pc2RahvRmwHp1pKiqG+LbCUwWgooEqRJypDkXpLoPYC1f0/qDoSo/F3M/cT0sgVxwGctrtZt1vYLbbSW089Z8eYf2pNRMOOSUwGYybZksmfZmpQqTQbxyABr3FRKB42kF5U2EsqHkLZy9S0EMImgust2BTcw7oeZaVQutBLf+/NTMbZcQplRuoP9v7h+77vzRvJ7MDsAEiHHCMidbYLHRNGhiKpksrop35aXfRpUh0yFA8+RmWqrZuoDIWSClDrsLNLhbcMI6iqVGWmSgpQJRU5bV0nHsGppNYNoyq21aTKCVBsBSia0SGJOnbhfHIqoWpqyAiqN6KgqpzvXJ6VVCx1SgPO7lgUBbhaqhqKj/wRiTrpBihOVA2FUC2uQYnqM4yqLIDsFNddAQXqoJSqWwl1XXAOWyxKKm0MFWKVqeOqQDFUvuoN2aVUnd3N5FI6QQpjlanQgJR+6i6kqqKqnfLdWaa6VLtehiKqXUktGU8dlZwSVPk6MniBip0wMhNLNah9+qlQAJ9MlZ3qRGFsEvW3SSuGygepUmruUvciQKU8pdtGUCMKqsqpuOrZbSJ13KqSylCgDhtMvaOmakKFE/8CVRsKUrNFpvrqE1dAvT+q6cTSC1QLkmpBgWpDbwGYCmVljKFOXaQqnOq3EXjmy1QxUbXzCqmRlYUDkarhlJ72Tpu7S+1KLSonmjGRurDl83mZqGHUPUR99uzV/S5UZCqhTueYU6TeN6ugOEw1temLeFeMoUJZi5j6PaLKTjUUUd0XqJgpQ5Xj7qYamfIsGkyFVAe0nBiqTFWCDgtOpZVA1Aci1eNZnDGYegTUy5wSFN5G3K4uVXACtOuzKKnfi9QpT9QQ6pRHoB4IVMRUOpU3fLdTQUVQpVFN5SKIWjaEOoWpD4F6PGBXO2UojDJVOVE11XmRWjSK2sTUR0dHx6N2LSdI1VSz5hCETEUFMI66iqk/Ho9gJjjVUGGcVpkq9FObutSlegyh+jwe70WqthNf711dKqG99gQaF1BfSFRv1CDqFlAXDr4+enQ8ZFNAXcJ0oRaZ2k9oScVxIupPV0Dd24MjAKjyGaqCghRTv/vhrx+++/k+qe2EIQl3benpVVDn99DJursy8i7T9c57iGv4yZdPnjz58myA1HRiqhmoqKpXQAXrwm50xOVCTmWeypsTcYxmzEoomUpokHQOVx/AH4INo94VqdH5vdbq6urBQ7vbKjtVUDz4hd8FNiVVKQ2Sg83HL37//c+HiBqNemYMoE4JqbbQj7fau7URq8WCKBpOi9aOV0ozGXfw8dPNl6urC0D1cJwnbgQVZqu4Ob+5c9Y+b5tO7W4ziIYvhWrveGWkaxnXyvaDs/bO5vzq7y0uagi16oVUJ7gWQE/O5+YS7U6naHPB4lq0AlXGqYZCpGsk0dr+5YQ9OTnbebm6tw/UqCHUKS9djO+0T85jgUDMH2iV32RsFoT9b4HK0CBRPIIf2rFzc+cn7Z2Xe/scN2MI1TtBm/18G6DZbDYRCFTm3pROzTa8bSSmVp5qKLTUXH+0/qLNh+dgzs9PNoPTPi5uBHWCDrKV5Vl+DkkxNlFpV0tpl5sgQKt5x7tkBGjmYPvBPMuCFE87xfIW2oAC3OkwTsdkP/y1l49l/RK23z9TLnNOK8KCU52oJpTI7C09WJ3mRWgsls+g3WmmozW9f7P6sETNOkb5wSE+wedi2YpfwCYmE/FSuT5mIQGrilMbao4/Xf9jms+J0Lk88VbYnGTm1PSJPuoXhf1vR1i7jWVZng1Px/wVPwzCzr46LVUzY2aSUOapDSXNxR/Xf2oDNBbDiU6HMiDF89rSMd3U8zur9z64eadUnB0aywkTDiVjFcDCJBL9s8edv98QYwSJMFiqDYVtb155tP7rGc8CEqixwBy1ljGL0uf2qqmvB0LV853ljbsFzuHIhcUJUflEFzs+/lu5kLZaSRK0WkwBinfTr5s5DIUJxFL1epAQqK+fu6qNXvRRi84Pge4WqisOfhomDP+SFJXMLvtF7OR4vFDinBZ4pF/GxAPQNSKzsLS9muNFaDabjzRpkOIXxeev4yXT7Rv420t91ht9hcJpKJEDJ6ImUzSTqyyLVscsWyuU624zYDWhJBF/uv3niQQNZKcnmvUgKRzMdnuxY/r4nu7PBMHaAx+u9ZpKtelEOAnQZD6fp2gqtyxh4ecVHVN1zUkCllQ6JejMEewmXFIMja0cNhkkhXEPZaomU98t/Z9fQVvxh2uf3TWVuRwPVLCGQiGmHkosi5Xl+yfPOqZT0hqEIQWnDM0QxRfrv+ywOWntYwx3SFNBDHWOmGsFU+9HhnzS9h7qQA9g731s6izyrGRN0XTI38WO988UCmmzBWOlwbuJoB+u/7pjYyVoIsSlt5g1LLUMjnFl093PIFK9UrmvEOyNW30mU5VK5ERqivLRYamygOVbphJnNmcyIjaI137tYHtpNcxvSLspyaU5L81QIZDahJIKUElqULBQ2UItmQhjKgwTocOzGIsuBpOvdk3lOjx2kBZDg8HW0vbC8dCGtJvmvOl9j3cCpKGQc5B6U0AlhZbKkRoRLGBxZRul/RyfTAlYaqJJsdACHCzr6G/vNqq0OQgFXUPQ+NH2T+2hDUEa8AeYdJrzTIE0FbLa87USlFRceyw1GAuVbXQ8PBtKYSpFRZoU7C8hWNbh2HxmOs2YCXiIksUftx+d2VkEDQQC2USKAyjOlArZwnG5pIb/73vKyvJhkGIr3Wwm/ct+fIdh2QF2/stCjaNpbnf72ebg4MaGAPWHufR+FEsZKhn2GlxS7co2TKd5Pk9hKsNMHDaTFQEbAOzxw8efP378+bP5DYCyAQydK6bT0SgsPs0woTDzryU1vrKtMRakQKVpunlY36hUUK6JwAY72l74+qvNV0MiFEpKpWtxkHpBSk2naqWCZkmvprLloi2MqRMwW4f0RsUPVBQs7xgdGmUlqD+1D1AsZZh8aP/qSqp9yjaqK2ySQVQfzOFhKoCxwGOxUlj76WitNYOkEGkoH+0UdJRUV2VJG+MDKZrIYZMKVKCv8mQrbLFWiyMp1JRKet8UCjpKqreyFosvIlB9TdhfWX/XmvCzK7D2caCixU8yek9S/ZW1UlsR0KKByk4nIFgMzUJJWyBFNaVDqZaOkuqtLMb2fQ6VtTKABW4EtYA+DmTR4ysfBaiYaSof1X+S6q/sbVRZiw9jUbrNZoaAkwGVVJQyeW+1YLqtv6T6K3unUahlghEh2Xp97e3bzCGcpKLUm2JOdZTUaCxUNk4yW02BOjxy/+1hXJjoCqOnpMZXFt9iikG6iaiZ4cEBoIrSOCrp/w59t7LVIklHIFWJ2oovzqCSorX/QMfaG96Cj6Cyp2sEThUVoNVaLEJJ7+CSXgOo6pFQI99i6n6ruLZ/LUqqXdkyN/x8YPybDIFenPow9INrA1VcvG83Gp04MTrMnZoavdelpNq3mEahXGo0rlVJtfbXvd67vfc+umYlvRQLNbh168a1K+llle3puXnzZk/P9SupGgtamPevNxRjkRac1x6KBoxXAv0HIb/znYYmR9cAAAAASUVORK5CYII=', 1, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得0佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (2, 'LV2', 2, 100, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得100佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (3, 'LV3', 3, 300, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得300佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (4, 'LV4', 4, 500, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得500佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (5, 'LV5', 5, 800, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得800佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (6, 'LV6', 6, 1000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得1000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (7, 'LV7', 7, 10000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得10000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (8, 'LV8', 8, 30000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得30000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (9, 'LV9', 9, 50000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得50000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (10, 'LV10', 10, 80000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得80000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (11, 'LV11', 11, 100000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得100000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (12, 'LV12', 12, 1000000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得1000000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (13, 'LV13', 13, 3000000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得3000000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (14, 'LV14', 14, 5000000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得5000000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (15, 'LV15', 15, 8000000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得8000000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (16, 'LV16', 16, 10000000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得10000000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (17, 'LV17', 17, 100000000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得100000000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (18, 'LV18', 18, 300000000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得300000000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (19, 'LV19', 19, 500000000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得500000000佣金的代理'); +INSERT INTO `ff_agent_level` VALUES (20, 'LV20', 20, 800000000, '', 0, '', '2024-10-24 17:24:35', '', '2024-10-24 17:29:18', '晋级需再获得800000000佣金的代理'); + +SET FOREIGN_KEY_CHECKS = 1; + +DROP TABLE IF EXISTS `ff_agent_mode`; +CREATE TABLE `ff_agent_mode` ( + `id` bigint NOT NULL COMMENT '主键id', + `mode_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '代理模式名称', + `pattern_source` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模式来源', + `settle_duration` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '结算周期', + `calc_performance` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '佣金计算依据', + `apply_mode` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '申请方式', + `calc_level_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '代理佣金计算层级', + `calc_mode` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '计算方式', + `calc_range` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '业绩计算范围', + `calc_ext_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '越级额外佣金类型', + `calc_ext_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '赠送比例', + `tutorial_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '推广教程配置类型', + `tutorial_contents` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '推广教程配置自定义模式下内容', + `default_status` tinyint NULL DEFAULT 0 COMMENT '是否默认(0非默认,1默认)', + `enable_status` tinyint NULL DEFAULT 0 COMMENT '启用(0未启用,1启用)', + `last_settle_day` datetime NULL DEFAULT NULL COMMENT '上周期结算时间', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代理模式表' ROW_FORMAT = DYNAMIC; + +ALTER TABLE `ff_agent_mode` MODIFY COLUMN `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id' FIRST; + +INSERT INTO `ff_agent_mode` VALUES (1, '一级净盈利', '1', '3', '2', '0', '1', '0', '1', '0', 0.00, '0', NULL, 0, 0, NULL, '', '2024-10-23 10:24:35', '', '2024-10-23 15:54:19', NULL); +INSERT INTO `ff_agent_mode` VALUES (2, '三级净盈利', '1', '3', '2', '0', '3', '0', '1', '2', 0.00, '0', NULL, 1, 0, NULL, '', '2024-10-23 10:24:35', '', '2024-10-23 11:36:01', NULL); +INSERT INTO `ff_agent_mode` VALUES (3, '全民代理', '1', '1', '2', '0', '999', '0', '1', '2', 30.00, '0', NULL, 0, 0, NULL, '', '2024-10-23 10:24:35', '', '2024-10-23 11:36:01', NULL); +INSERT INTO `ff_agent_mode` VALUES (4, '无限极差', '1', '1', '2', '0', '999', '0', '1', '4', 0.00, '0', NULL, 0, 0, NULL, '', '2024-10-23 10:24:35', '', '2024-10-23 11:36:01', NULL); +INSERT INTO `ff_agent_mode` VALUES (5, '一级代理', '1', '1', '2', '0', '1', '0', '1', '0', 0.00, '0', NULL, 0, 0, NULL, '', '2024-10-23 10:24:35', '', '2024-10-23 11:36:01', NULL); + +-- 菜单 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('代理模式', '3051', '1', 'agentMode', 'agent/agentMode/index', 1, 0, 'C', '0', '0', 'agent:agentMode:list', '#', 'admin', sysdate(), '', null, '代理模式菜单'); + +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10000, '模式来源', 'ff_pattern_source', '0', 'admin', '2024-10-22 06:26:19', 'admin', '2024-10-22 06:26:40', '模式来源'); + +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10000, 1, '系统自带', '1', 'ff_pattern_source', NULL, 'default', 'N', '0', 'admin', '2024-10-22 06:32:33', 'admin', '2024-10-22 06:32:41', ''); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10001, 2, '自定义', '2', 'ff_pattern_source', NULL, 'default', 'N', '0', 'admin', '2024-10-22 06:33:05', '', NULL, NULL); + + +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10001, '代理佣金计算层级', 'ff_calc_level_type', '0', 'admin', '2024-10-22 06:42:11', '', NULL, '代理佣金计算层级'); + +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10002, 1, '只算一级', '1', 'ff_calc_level_type', NULL, 'default', 'N', '0', 'admin', '2024-10-22 06:43:00', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10003, 2, '最多三级', '3', 'ff_calc_level_type', NULL, 'default', 'N', '0', 'admin', '2024-10-22 06:43:14', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10004, 3, '无数级', '999', 'ff_calc_level_type', NULL, 'default', 'N', '0', 'admin', '2024-10-22 06:43:40', '', NULL, NULL); + + +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10002, '申请方式', 'ff_apply_mode', '0', 'admin', '2024-10-22 06:54:08', 'admin', '2024-10-22 06:54:13', '申请方式'); + +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10005, 0, '直接生效', '0', 'ff_apply_mode', NULL, 'default', 'N', '0', 'admin', '2024-10-22 06:54:46', '', NULL, NULL); + + +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10003, '结算周期', 'ff_settle_duration', '0', 'admin', '2024-10-22 06:59:57', '', NULL, '结算周期'); + +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10006, 0, '日结', '1', 'ff_settle_duration', NULL, 'default', 'N', '0', 'admin', '2024-10-22 07:02:37', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10007, 1, '周结', '2', 'ff_settle_duration', NULL, 'default', 'N', '0', 'admin', '2024-10-22 07:02:53', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10008, 2, '月结', '3', 'ff_settle_duration', NULL, 'default', 'N', '0', 'admin', '2024-10-22 07:03:08', '', NULL, NULL); + + +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10004, '佣金计算依据', 'ff_calc_performance', '0', 'admin', '2024-10-22 07:25:17', '', NULL, NULL); + +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10009, 0, '有效投注', '0', 'ff_calc_performance', NULL, 'default', 'N', '0', 'admin', '2024-10-22 07:26:14', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10010, 1, '亏损金额', '1', 'ff_calc_performance', NULL, 'default', 'N', '0', 'admin', '2024-10-22 07:26:37', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10011, 2, '净盈利', '2', 'ff_calc_performance', NULL, 'default', 'N', '0', 'admin', '2024-10-22 07:27:09', '', NULL, NULL); + + +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10005, '计算方式', 'ff_calc_mode', '0', 'admin', '2024-10-22 08:23:21', '', NULL, '计算方式'); + +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10012, 0, '所有会员(综合盈利会员)', '0', 'ff_calc_mode', NULL, 'default', 'N', '0', 'admin', '2024-10-22 08:24:18', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10013, 1, '仅计算亏损会员', '1', 'ff_calc_mode', NULL, 'default', 'N', '0', 'admin', '2024-10-22 08:24:37', '', NULL, NULL); + + +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10006, '业绩计算范围', 'ff_calc_range', '0', 'admin', '2024-10-22 08:26:04', '', NULL, '业绩计算范围'); + +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10014, 0, '计算全部(含无效)', '0', 'ff_calc_range', NULL, 'default', 'N', '0', 'admin', '2024-10-22 08:51:44', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10015, 1, '只计算有效会员业绩', '1', 'ff_calc_range', NULL, 'default', 'N', '0', 'admin', '2024-10-22 08:52:27', '', NULL, NULL); + +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10007, '推广教程配置', 'ff_tutorial_type', '0', 'admin', '2024-10-22 08:56:58', '', NULL, '推广教程配置'); + +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10016, 0, '系统自带', '0', 'ff_tutorial_type', NULL, 'default', 'N', '0', 'admin', '2024-10-22 08:57:35', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10017, 1, '自定义', '1', 'ff_tutorial_type', NULL, 'default', 'N', '0', 'admin', '2024-10-22 08:58:16', '', NULL, NULL); + + +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10008, '越级额外佣金类型', 'ff_calc_ext_type', '0', 'admin', '2024-10-23 05:13:35', '', NULL, '越级额外佣金类型'); + +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10018, 0, '-', '0', 'ff_calc_ext_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 05:14:46', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10019, 1, '比例中的比例(跨级部分会员承担)', '1', 'ff_calc_ext_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 05:15:40', 'admin', '2024-10-23 05:16:20', NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10020, 2, '比例中的比例(跨级部分站长承担)', '2', 'ff_calc_ext_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 05:16:16', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10021, 3, '站长额外固定赠送', '3', 'ff_calc_ext_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 05:16:44', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10022, 4, '比例中的比例(跨级部分站长承担)', '4', 'ff_calc_ext_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 05:18:59', '', NULL, NULL); + +DROP TABLE IF EXISTS `ff_settlement_setting`; +CREATE TABLE `ff_settlement_setting` ( + `id` bigint NOT NULL COMMENT '主键id', + `commission_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '佣金领取时间类型', + `receive_way` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '领取方式', + `commission_start_time` time NULL DEFAULT NULL COMMENT '佣金领取开始时间', + `commission_end_time` time NULL DEFAULT NULL COMMENT '佣金领取结束时间', + `agent_audit_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '佣金稽核倍数', + `min_valid_bet` decimal(10, 2) NULL DEFAULT NULL COMMENT '有效投注金额', + `min_valid_recharge` decimal(10, 2) NULL DEFAULT NULL COMMENT '结算周期内充值金额', + `day_commission_limit` decimal(10, 2) NULL DEFAULT NULL COMMENT '日结模式上限', + `week_commission_limit` decimal(10, 2) NULL DEFAULT NULL COMMENT '周结模式上限', + `month_commission_limit` decimal(10, 2) NULL DEFAULT NULL COMMENT '月结模式上限', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '结算设置表' ROW_FORMAT = DYNAMIC; + +ALTER TABLE `ff_settlement_setting` MODIFY COLUMN `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id' FIRST; + +-- ---------------------------- +-- Records of ff_settlement_setting +-- ---------------------------- +INSERT INTO `ff_settlement_setting` VALUES (1, '1', '08:00:00', '23:59:59', 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, '', '2024-10-24 09:14:00', '', '2024-10-24 10:00:00', NULL); + +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10009, '佣金领取时间类型', 'ff_commission_type', '0', 'admin', '2024-10-23 09:36:14', '', NULL, '佣金领取时间类型'); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10023, 0, '每天', '1', 'ff_commission_type', NULL, 'default', 'N', '0', 'admin', '2024-10-23 09:36:31', '', NULL, NULL); + +DROP TABLE IF EXISTS `ff_agent_info`; +CREATE TABLE `ff_agent_info` ( + `id` bigint NOT NULL COMMENT '主键id', + `agent_id` bigint NOT NULL COMMENT '代理id', + `root_id` bigint NULL COMMENT '顶级代理id', + `level` int COMMENT '所属层级', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代理信息表' ROW_FORMAT = Dynamic; + +ALTER TABLE `ff_agent_info` MODIFY COLUMN `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id' FIRST; + +DROP TABLE IF EXISTS `ff_agent_relation`; +CREATE TABLE `ff_agent_relation` ( + `id` bigint NOT NULL COMMENT '主键id', + `root_id` bigint NULL COMMENT '顶级代理id', + `node_relation` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '节点关系', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代理关系表' ROW_FORMAT = Dynamic; + +ALTER TABLE `ff_agent_relation` MODIFY COLUMN `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id' FIRST; + +-- 按钮 SQL +INSERT INTO `ff-admin`.`sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10007, '代理模式查询', 10006, 1, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'agent:agentMode:query', '#', 'admin', '2024-10-24 01:09:11', '', NULL, ''); +INSERT INTO `ff-admin`.`sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10008, '代理模式新增', 10006, 2, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'agent:agentMode:add', '#', 'admin', '2024-10-24 01:09:11', '', NULL, ''); +INSERT INTO `ff-admin`.`sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10009, '代理模式修改', 10006, 3, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'agent:agentMode:edit', '#', 'admin', '2024-10-24 01:09:11', '', NULL, ''); +INSERT INTO `ff-admin`.`sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10010, '代理模式删除', 10006, 4, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'agent:agentMode:remove', '#', 'admin', '2024-10-24 01:09:11', '', NULL, ''); +INSERT INTO `ff-admin`.`sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10011, '代理模式导出', 10006, 5, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'agent:agentMode:export', '#', 'admin', '2024-10-24 01:09:11', '', NULL, ''); + + +DROP TABLE IF EXISTS `ff_commission_info`; +CREATE TABLE `ff_commission_info` ( + `id` bigint NOT NULL COMMENT '主键id', + `member_id` bigint NOT NULL COMMENT '会员id', + `currency_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '币种', + `total_amount` decimal(10, 2) DEFAULT NULL COMMENT '累计佣金', + `total_withdrawn` decimal(10, 2) DEFAULT NULL COMMENT '累计提现', + `total_no_withdrawn` decimal(10, 2) DEFAULT NULL COMMENT '累计未提现', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '佣金信息表' ROW_FORMAT = Dynamic; + +ALTER TABLE `ff_commission_info` MODIFY COLUMN `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id' FIRST; + + +DROP TABLE IF EXISTS `ff_commission_flow_detail`; +CREATE TABLE `ff_commission_flow_detail` ( + `id` bigint NOT NULL COMMENT '主键id', + `member_id` bigint NOT NULL COMMENT '会员id', + `currency_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '币种', + `amount` decimal(10, 2) DEFAULT NULL COMMENT '佣金', + `withdrawn` decimal(10, 2) DEFAULT NULL COMMENT '提现金额', + `settle_status` tinyint DEFAULT 0 COMMENT '结算状态(0未提现,1已提现)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '佣金流水明细表' ROW_FORMAT = Dynamic; + +ALTER TABLE `ff_commission_flow_detail` MODIFY COLUMN `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id' FIRST; + +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10010, '领取方式', 'ff_receive_way', '0', 'admin', '2024-11-01 05:23:51', '', NULL, '领取方式'); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10024, 0, '自动派发', '1', 'ff_receive_way', NULL, 'default', 'N', '0', 'admin', '2024-11-01 05:24:20', '', NULL, NULL); + + +ALTER TABLE `ff_agent_level` + MODIFY COLUMN `total_commission` decimal(16, 2) NULL DEFAULT NULL COMMENT '晋升等级佣金标准' AFTER `level`; +ALTER TABLE `ff_settlement_setting` + MODIFY COLUMN `min_valid_bet` decimal(16, 2) NULL DEFAULT NULL COMMENT '有效投注金额' AFTER `agent_audit_rate`; +ALTER TABLE `ff_settlement_setting` + MODIFY COLUMN `min_valid_recharge` decimal(16, 2) NULL DEFAULT NULL COMMENT '结算周期内充值金额' AFTER `min_valid_bet`; +ALTER TABLE `ff_settlement_setting` + MODIFY COLUMN `day_commission_limit` decimal(16, 2) NULL DEFAULT NULL COMMENT '日结模式上限' AFTER `min_valid_recharge`; +ALTER TABLE `ff_settlement_setting` + MODIFY COLUMN `week_commission_limit` decimal(16, 2) NULL DEFAULT NULL COMMENT '周结模式上限' AFTER `day_commission_limit`; +ALTER TABLE `ff_settlement_setting` + MODIFY COLUMN `month_commission_limit` decimal(16, 2) NULL DEFAULT NULL COMMENT '月结模式上限' AFTER `week_commission_limit`; +ALTER TABLE `ff_commission_info` + MODIFY COLUMN `total_amount` decimal(16, 2) NULL DEFAULT NULL COMMENT '累计佣金' AFTER `currency_type`; +ALTER TABLE `ff_commission_info` + MODIFY COLUMN `total_withdrawn` decimal(16, 2) NULL DEFAULT NULL COMMENT '累计提现' AFTER `total_amount`; +ALTER TABLE `ff_commission_info` + MODIFY COLUMN `total_no_withdrawn` decimal(16, 2) NULL DEFAULT NULL COMMENT '累计未提现' AFTER `total_withdrawn`; +ALTER TABLE `ff_commission_flow_detail` + MODIFY COLUMN `amount` decimal(16, 2) NULL DEFAULT NULL COMMENT '佣金' AFTER `currency_type`; +ALTER TABLE `ff_commission_flow_detail` + MODIFY COLUMN `withdrawn` decimal(16, 2) NULL DEFAULT NULL COMMENT '提现金额' AFTER `amount`; + +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10011, '代理提佣方式', 'ff_commission_way', '0', 'admin', '2024-11-05 06:31:53', '', NULL, '代理提佣方式'); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10025, 0, '不限制(自由领取)', '0', 'ff_commission_way', NULL, 'default', 'N', '0', 'admin', '2024-11-05 06:32:13', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10026, 1, '禁止所有提佣(含下级,私下结算)', '1', 'ff_commission_way', NULL, 'default', 'N', '0', 'admin', '2024-11-05 06:32:23', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10027, 2, '禁止本人提佣(私下结算)', '2', 'ff_commission_way', NULL, 'default', 'N', '0', 'admin', '2024-11-05 06:32:34', '', NULL, NULL); + +INSERT INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10012, '佣金返利类型', 'ff_rebate_type', '0', 'admin', '2024-11-05 09:16:42', '', NULL, '佣金返利类型'); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10028, 1, '有效投注', '1', 'ff_rebate_type', NULL, 'default', 'N', '0', 'admin', '2024-11-05 09:17:34', '', NULL, NULL); +INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10029, 2, '净盈利', '2', 'ff_rebate_type', NULL, 'default', 'N', '0', 'admin', '2024-11-05 09:18:02', '', NULL, NULL); + + +DROP TABLE IF EXISTS `ff_rebate_setting`; +CREATE TABLE `ff_rebate_setting` ( + `id` bigint NOT NULL COMMENT '主键id', + `game_type` bigint DEFAULT NULL COMMENT '游戏类型', + `calc_performance` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '佣金计算依据', + `valid_num` int DEFAULT NULL COMMENT '有效人数', + `commission` decimal(16, 2) DEFAULT NULL COMMENT '佣金金额', + `commission_rate` decimal(10, 2) DEFAULT NULL COMMENT '佣金比例', + `min_amount` decimal(16, 2) DEFAULT NULL COMMENT '最小金额', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '返佣设置表' ROW_FORMAT = Dynamic; + +ALTER TABLE `ff_rebate_setting` MODIFY COLUMN `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id' FIRST; + +delete from sys_menu where menu_name like '返佣设置%'; + +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10018, '返佣设置', 3051, 1, 'rebateSetting', 'agent/rebateSetting/index', NULL, '', 1, 0, 'C', '0', '0', 'agent:rebateSetting:list', '#', 'admin', '2024-11-06 03:28:17', '', NULL, '返佣设置菜单'); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10019, '返佣设置查询', 10018, 1, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'agent:rebateSetting:query', '#', 'admin', '2024-11-06 03:28:17', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10020, '返佣设置新增', 10018, 2, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'agent:rebateSetting:add', '#', 'admin', '2024-11-06 03:28:17', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10021, '返佣设置修改', 10018, 3, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'agent:rebateSetting:edit', '#', 'admin', '2024-11-06 03:28:17', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10022, '返佣设置删除', 10018, 4, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'agent:rebateSetting:remove', '#', 'admin', '2024-11-06 03:28:17', '', NULL, ''); +INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `route_name`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10023, '返佣设置导出', 10018, 5, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'agent:rebateSetting:export', '#', 'admin', '2024-11-06 03:28:17', '', NULL, ''); + +ALTER TABLE ff_agent_mode ADD COLUMN agent_model_type tinyint DEFAULT NULL COMMENT '代理模式类型' AFTER `pattern_source`; + +ALTER TABLE ff_agent_info ADD COLUMN depth int COMMENT '深度(下级层数)' AFTER `level`; +ALTER TABLE ff_agent_info ADD COLUMN direct_num int COMMENT '直属数' AFTER `depth`; +ALTER TABLE ff_agent_info ADD COLUMN agent_num int COMMENT '代理总数' AFTER `direct_num`; +ALTER TABLE ff_agent_info ADD COLUMN member_num int COMMENT '所有下级的会员数量(下级总数)' AFTER `agent_num`; + + +ALTER TABLE ff_agent_level ADD COLUMN currency_type varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '币种' AFTER `level`; + +DROP TABLE IF EXISTS `ff_agent_level_relation`; +CREATE TABLE `ff_agent_level_relation` ( + `id` bigint NOT NULL COMMENT '主键id', + `member_id` bigint NOT NULL COMMENT '会员id', + `agent_level_id` bigint NOT NULL COMMENT '代理等级id', + `currency_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '币种', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代理等级关系表' ROW_FORMAT = Dynamic; + +ALTER TABLE `ff_agent_level_relation` MODIFY COLUMN `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id' FIRST; \ No newline at end of file