This commit is contained in:
oneao committed 2025-12-16 17:21:56 +08:00
1 parent 1da52dc4f4
commit 276644f473
223 files changed
+9609 -262

No files matched your search

@@ -4,7 +4,7 @@ import cn.link56.auth.code.model.AuthCodeChannel;
import cn.link56.auth.code.model.AuthCodePurpose;
import cn.link56.auth.code.model.dto.AuthCodeSendDTO;
import cn.link56.auth.code.model.dto.AuthCodeVerifyDTO;
import cn.link56.auth.code.service.VerificationCodeService;
import cn.link56.auth.code.service.AuthVerificationCodeService;
import cn.link56.common.Result;
import org.springframework.web.bind.annotation.*;
@@ -14,7 +14,7 @@ import javax.annotation.Resource;
@RequestMapping("/auth/code")
public class AuthCodeController {
@Resource
private VerificationCodeService verificationCodeService;
private AuthVerificationCodeService authVerificationCodeService;
@PostMapping("/send")
public Result<Void> send(@RequestBody AuthCodeSendDTO authCodeSendDTO) {
@@ -22,7 +22,7 @@ public class AuthCodeController {
AuthCodeChannel channel = authCodeSendDTO.getChannel();
String target = authCodeSendDTO.getTarget();
boolean flag = verificationCodeService.sendCode(purpose, channel, target);
boolean flag = authVerificationCodeService.sendCode(purpose, channel, target);
return flag ? Result.success() : Result.error();
}
@@ -34,7 +34,7 @@ public class AuthCodeController {
String target = authCodeVerifyDTO.getTarget();
String code = authCodeVerifyDTO.getCode();
boolean flag = verificationCodeService.verifyCode(purpose, channel, target, code);
boolean flag = authVerificationCodeService.verifyCode(purpose, channel, target, code);
return flag ? Result.success() : Result.error();
}
@@ -22,6 +22,7 @@ public class EmailAuthCodeSender {
if (purpose.equals(AuthCodePurpose.LOGIN)){
subject = "登录";
templateHtml = "Login.html";
}else if(purpose.equals(AuthCodePurpose.REGISTER)){
subject = "注册";
templateHtml = "Register.html";
@@ -11,7 +11,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class VerificationCodeService {
public class AuthVerificationCodeService {
@Resource
private AuthCodeStore codeStore;
@@ -3,7 +3,7 @@ package cn.link56.auth.code.store;
import cn.link56.auth.code.model.AuthCodeChannel;
import cn.link56.auth.code.model.AuthCode;
import cn.link56.auth.code.model.AuthCodePurpose;
import cn.link56.common.exception.OperationTooFrequentException;
import cn.link56.common.exception.BusinessException;
import org.springframework.stereotype.Component;
import javax.naming.OperationNotSupportedException;
@@ -29,7 +29,7 @@ public class AuthCodeStore {
AuthCode existing = store.get(key);
if (existing != null &&
existing.getLastSentAt().plusSeconds(MIN_INTERVAL_SECONDS).isAfter(now)) {
throw new OperationTooFrequentException("验证码发送过于频繁,请稍后再试");
throw new BusinessException("验证码发送过于频繁,请稍后再试");
}
AuthCode code = new AuthCode(
@@ -0,0 +1,41 @@
package cn.link56.auth.identity.controller;
import cn.link56.auth.identity.model.dto.AuthLoginEmailCodeDTO;
import cn.link56.auth.identity.model.dto.AuthLoginPasswordDTO;
import cn.link56.auth.identity.model.dto.AuthRegisterDTO;
import cn.link56.auth.identity.model.vo.AuthLoginVO;
import cn.link56.auth.identity.service.AuthIdentityService;
import cn.link56.common.Result;
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;
@RestController
@RequestMapping("/auth/identity")
public class AuthIdentityController {
@Resource
private AuthIdentityService authIdentityService;
@PostMapping("/register")
public Result<Void> register(@RequestBody AuthRegisterDTO authRegisterDTO){
authIdentityService.register(authRegisterDTO);
return Result.success();
}
@PostMapping("/login/password")
public Result<AuthLoginVO> loginByPassword(@RequestBody @Validated AuthLoginPasswordDTO loginPasswordDTO){
AuthLoginVO authLoginVO = authIdentityService.loginByPassword(loginPasswordDTO);
return Result.success(authLoginVO);
}
@PostMapping("/login/emailCode")
public Result<AuthLoginVO> loginByEmailCode(@RequestBody @Validated AuthLoginEmailCodeDTO loginEmailCodeDTO){
AuthLoginVO authLoginVO = authIdentityService.loginByEmailCode(loginEmailCodeDTO);
return Result.success(authLoginVO);
}
}
@@ -0,0 +1,20 @@
package cn.link56.auth.identity.model.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AuthLoginEmailCodeDTO {
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式有误")
private String email;
@NotBlank(message = "验证码不能为空")
private String code;
}
@@ -0,0 +1,20 @@
package cn.link56.auth.identity.model.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AuthLoginPasswordDTO {
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式有误")
private String email;
@NotBlank(message = "密码不能为空")
private String password;
}
@@ -0,0 +1,21 @@
package cn.link56.auth.identity.model.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AuthLoginVO {
private Long companyId;
private String companyLogo;
private String companyName;
private Long userId;
private Integer userRole;
private String userName;
private String userPosition;
private String token;
}
@@ -0,0 +1,135 @@
package cn.link56.auth.identity.service;
import cn.link56.auth.code.model.AuthCodeChannel;
import cn.link56.auth.code.model.AuthCodePurpose;
import cn.link56.auth.code.service.AuthVerificationCodeService;
import cn.link56.auth.identity.model.dto.AuthLoginEmailCodeDTO;
import cn.link56.auth.identity.model.dto.AuthLoginPasswordDTO;
import cn.link56.auth.identity.model.vo.AuthLoginVO;
import cn.link56.auth.token.model.AuthToken;
import cn.link56.auth.token.model.TokenPayload;
import cn.link56.auth.token.service.AuthTokenService;
import cn.link56.entity.BCompany;
import cn.link56.entity.BCompanyUser;
import cn.link56.auth.identity.model.dto.AuthRegisterDTO;
import cn.link56.base.service.BCompanyService;
import cn.link56.base.service.BCompanyUserService;
import cn.link56.common.exception.BusinessException;
import cn.link56.common.utils.snowflake.idgen.IdGenerator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
@Service
public class AuthIdentityService {
@Resource
private BCompanyService companyService;
@Resource
private BCompanyUserService companyUserService;
@Resource
private AuthTokenService tokenService;
@Resource
private AuthVerificationCodeService authVerificationCodeService;
@Transactional
public void register(AuthRegisterDTO registerDTO) {
AuthRegisterDTO.Company company = registerDTO.getCompany();
AuthRegisterDTO.Admin admin = registerDTO.getAdmin();
if (companyService.isNameExists(company.getName())) {
throw new BusinessException("公司名称已存在");
}
if(StringUtils.isNotBlank(company.getPhone()) && companyService.isPhoneExists(company.getPhone())){
throw new BusinessException("公司邮箱已被注册");
}
if (companyUserService.isEmailExists(admin.getEmail())) {
throw new BusinessException("管理员邮箱已被注册");
}
if (StringUtils.isNotBlank(admin.getPhone()) && companyUserService.isPhoneExists(admin.getPhone())) {
throw new BusinessException("管理员手机号已被注册");
}
long companyId = IdGenerator.nextId();
companyService.save(
new BCompany()
.setId(companyId)
.setName(company.getName())
.setIndustry(company.getIndustry())
.setAddress(company.getAddress())
.setPhone(company.getPhone())
.setEmail(company.getEmail())
.setProfile(company.getProfile())
);
companyUserService.save(
new BCompanyUser()
.setId(IdGenerator.nextId())
.setCompanyId(companyId)
.setName(admin.getName())
.setEmail(admin.getEmail())
.setPassword(admin.getPassword())
.setPhone(admin.getPhone())
.setPosition(admin.getPosition())
.setRole(0)
);
}
public AuthLoginVO loginByPassword(AuthLoginPasswordDTO dto) {
BCompanyUser user = companyUserService.loginByEmailAndPassword(dto.getEmail(), dto.getPassword());
if (user == null) {
throw new BusinessException("邮箱或密码错误");
}
return buildLoginVO(user);
}
public AuthLoginVO loginByEmailCode(AuthLoginEmailCodeDTO dto) {
String email = dto.getEmail();
String code = dto.getCode();
boolean valid = authVerificationCodeService.verifyCode(
AuthCodePurpose.LOGIN,
AuthCodeChannel.EMAIL,
email,
code
);
if (!valid) {
throw new BusinessException("邮箱或验证码失效");
}
BCompanyUser user = companyUserService.loginByEmail(email);
if (user == null) {
throw new BusinessException("邮箱不存在");
}
return buildLoginVO(user);
}
/**
* 公共逻辑:根据用户生成 LoginVO
*/
private AuthLoginVO buildLoginVO(BCompanyUser user) {
BCompany company = companyService.getById(user.getCompanyId());
AuthToken authToken = tokenService.generateToken(new TokenPayload(user.getCompanyId(), user.getId()));
return new AuthLoginVO(
company.getId(),
company.getLogo(),
company.getName(),
user.getId(),
user.getRole(),
user.getName(),
user.getPosition(),
authToken.getToken()
);
}
}
@@ -2,6 +2,7 @@ package cn.link56.base.controller;
import cn.link56.base.model.vo.BaseDataVO;
import cn.link56.base.service.BaseDataService;
import cn.link56.common.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -9,14 +10,13 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("/api/base")
@RequestMapping("/base")
public class BaseDataController {
@Resource
private BaseDataService baseDataService;
@GetMapping("/init")
public BaseDataVO initBaseData() {
return baseDataService.getBaseData();
public Result<BaseDataVO> initBaseData() {
return Result.success(baseDataService.getBaseData());
}
}
@@ -0,0 +1,15 @@
package cn.link56.base.mapper;
import cn.link56.entity.BArea;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface AreaMapper {
/**
* 获取所有区域信息
* @return 区域集合
*/
List<BArea> listAllArea();
}
@@ -0,0 +1,9 @@
package cn.link56.base.mapper;
import cn.link56.entity.BCompany;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BCompanyMapper extends BaseMapper<BCompany> {
}
@@ -0,0 +1,9 @@
package cn.link56.base.mapper;
import cn.link56.entity.BCompanyUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BCompanyUserMapper extends BaseMapper<BCompanyUser> {
}
@@ -1,6 +1,6 @@
package cn.link56.base.mapper;
import cn.link56.base.model.BIndustry;
import cn.link56.entity.BIndustry;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@@ -30,5 +30,6 @@ public class BaseDataVO {
private Integer xh;
private String name;
private String fatherId;
private List<Area> children;
}
}
@@ -0,0 +1,39 @@
package cn.link56.base.service;
import cn.link56.base.mapper.BCompanyMapper;
import cn.link56.entity.BCompany;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class BCompanyService extends ServiceImpl<BCompanyMapper, BCompany> {
@Resource
private BCompanyMapper companyMapper;
/**
* 检查公司名称是否重复
*/
public boolean isNameExists(String name) {
Long count = companyMapper.selectCount(
new LambdaQueryWrapper<BCompany>()
.eq(BCompany::getName, name)
);
return count > 0;
}
/**
* 检查公司手机号是否重复
*/
public boolean isPhoneExists(String phone) {
Long count = companyMapper.selectCount(
new LambdaQueryWrapper<BCompany>()
.eq(BCompany::getPhone, phone)
);
return count > 0;
}
}
@@ -0,0 +1,59 @@
package cn.link56.base.service;
import cn.link56.base.mapper.BCompanyUserMapper;
import cn.link56.entity.BCompanyUser;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class BCompanyUserService extends ServiceImpl<BCompanyUserMapper, BCompanyUser> {
@Resource
private BCompanyUserMapper companyUserMapper;
/**
* 判断邮箱是否重复
* @param email 用户邮箱
* @return true 表示邮箱已存在,false 表示可用
*/
public boolean isEmailExists(String email) {
long count = companyUserMapper.selectCount(
new LambdaQueryWrapper<BCompanyUser>()
.eq(BCompanyUser::getEmail, email)
);
return count > 0;
}
/**
* 判断手机号是否重复
* @param phone 用户手机号
* @return true 表示手机号已存在,false 表示可用
*/
public boolean isPhoneExists(String phone) {
long count = companyUserMapper.selectCount(
new LambdaQueryWrapper<BCompanyUser>()
.eq(BCompanyUser::getPhone, phone)
);
return count > 0;
}
public BCompanyUser loginByEmailAndPassword(String email, String password){
LambdaQueryWrapper<BCompanyUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(BCompanyUser::getEmail,email)
.eq(BCompanyUser::getPassword,password);
return companyUserMapper.selectOne(queryWrapper);
}
public BCompanyUser loginByEmail(String email){
LambdaQueryWrapper<BCompanyUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(BCompanyUser::getEmail,email);
return companyUserMapper.selectOne(queryWrapper);
}
}
@@ -1,19 +1,23 @@
package cn.link56.base.service;
import cn.link56.base.mapper.AreaMapper;
import cn.link56.base.mapper.IndustryMapper;
import cn.link56.base.model.BIndustry;
import cn.link56.entity.BArea;
import cn.link56.entity.BIndustry;
import cn.link56.base.model.vo.BaseDataVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class BaseDataService {
@Resource
private IndustryMapper industryMapper;
@Resource
private AreaMapper areaMapper;
public BaseDataVO getBaseData() {
BaseDataVO baseDataVO = new BaseDataVO();
@@ -30,9 +34,75 @@ public class BaseDataService {
))
.collect(Collectors.toList());
baseDataVO.setIndustries(industries);
// 地区
List<BArea> allAreas = areaMapper.listAllArea();
List<BaseDataVO.Area> areaTree = buildAreaTree(allAreas);
baseDataVO.setAreas(areaTree);
return baseDataVO;
}
/**
* BArea → BaseDataVO.Area 树
*/
private List<BaseDataVO.Area> buildAreaTree(List<BArea> areas) {
if (areas == null || areas.isEmpty()) {
return Collections.emptyList();
}
// id -> VO
Map<String, BaseDataVO.Area> map = new HashMap<>(areas.size());
// 1️⃣ 先全部转 VO
for (BArea a : areas) {
BaseDataVO.Area vo = new BaseDataVO.Area(
a.getId(),
a.getXh(),
a.getName(),
a.getFatherId(),
new ArrayList<>()
);
map.put(vo.getId(), vo);
}
// 2️⃣ 组装父子关系
List<BaseDataVO.Area> roots = new ArrayList<>();
for (BaseDataVO.Area area : map.values()) {
String parentId = area.getFatherId();
if (parentId == null || "0".equals(parentId)) {
roots.add(area);
} else {
BaseDataVO.Area parent = map.get(parentId);
if (parent != null) {
parent.getChildren().add(area);
}
}
}
// 3️⃣ 可选排序
sortTree(roots);
return roots;
}
/**
* 按 xh 排序(如果你用 order,也可以换)
*/
private void sortTree(List<BaseDataVO.Area> nodes) {
if (nodes == null || nodes.isEmpty()) {
return;
}
nodes.sort(Comparator.comparing(
BaseDataVO.Area::getXh,
Comparator.nullsLast(Integer::compareTo)
));
for (BaseDataVO.Area node : nodes) {
sortTree(node.getChildren());
}
}
}
@@ -42,10 +42,10 @@ public class Result<T> {
}
public static <T> Result<T> error(String message){
return new Result<>(ResponseStatusConstants.ERROR, message, null);
return new Result<>(ResponseStatusConstants.BUSINESS_ERROR, message, null);
}
public static <T> Result<T> error(){
return new Result<>(ResponseStatusConstants.ERROR, null,null);
return new Result<>(ResponseStatusConstants.BUSINESS_ERROR, null,null);
}
}
@@ -0,0 +1,37 @@
package cn.link56.common.config;
import cn.link56.common.context.UserContext;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;
@Component
public class AutoMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
Long userId = UserContext.getUserId();
if (ObjectUtils.isNotEmpty(userId) && userId > 0){
this.strictInsertFill(metaObject, "createBy", Long.class, userId);
}
Date date = new Date();
this.strictInsertFill(metaObject, "createTime", Date.class, date);
this.strictInsertFill(metaObject, "updateTime", Date.class, date);
}
@Override
public void updateFill(MetaObject metaObject) {
Long userId = UserContext.getUserId();
if (ObjectUtils.isNotEmpty(userId) && userId > 0){
this.strictUpdateFill(metaObject, "updateBy", Long.class, userId);
}
this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
}
}
@@ -6,10 +6,15 @@ public class ResponseStatusConstants {
*/
public static final Integer SUCCESS = 200;
/**
* 系统内部错误
/**
* 系统业务错误
*/
public static final Integer ERROR = 500;
public static final Integer BUSINESS_ERROR = 450;
/**
* 系统服务器错误
*/
public static final Integer SERVER_ERROR = 500;
/**
* 缺少参数,参数格式有误,请求路径有误等
@@ -4,4 +4,7 @@ public class BusinessException extends RuntimeException {
public BusinessException(String message) {
super(message);
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -82,8 +82,8 @@ public class GlobalExceptionHandler {
}
// 自定义异常
@ExceptionHandler(OperationTooFrequentException.class)
public Result<Void> handleOperationTooFrequentException(OperationTooFrequentException e) {
@ExceptionHandler(BusinessException.class)
public Result<Void> handleOperationTooFrequentException(BusinessException e) {
return Result.error(e.getMessage());
}
@@ -92,8 +92,7 @@ public class GlobalExceptionHandler {
*/
@ExceptionHandler(value = Exception.class)
public Result<Void> handleSystemException(Exception e) {
e.printStackTrace();
log.error("捕获到全局异常:{}",e.getMessage());
return Result.error(e.getMessage());
log.error("系统异常", e );
return Result.error(ResponseStatusConstants.SERVER_ERROR,"系统异常");
}
}
@@ -1,11 +0,0 @@
package cn.link56.common.exception;
public class OperationTooFrequentException extends BusinessException {
public OperationTooFrequentException(String message) {
super(message);
}
public OperationTooFrequentException() {
super("操作过于频繁,请稍后再试");
}
}
@@ -0,0 +1,20 @@
package cn.link56.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BArea {
private String id;
private Integer xh;
private String name;
private String fatherId;
private String canuse;
private String bz;
private String field;
private Integer order;
private String visible;
}
@@ -1,5 +1,6 @@
package cn.link56.auth.identity.model;
package cn.link56.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -19,32 +20,45 @@ import java.util.Date;
public class BCompany {
@TableId(value = "b_id")
private Long id;
@TableField("b_name")
private String name;
@TableField("b_email")
private String email;
@TableField("b_phone")
private String phone;
@TableField("b_address")
private String address;
@TableField("b_industry")
private String industry;
@TableField("b_logo")
private String logo;
@TableField("b_profile")
private String profile;
@TableField("b_description")
private String description;
@TableField("b_create_by")
private Long createBy;
@TableField("b_create_time")
@TableField(value = "b_create_time",fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@TableField("b_update_by")
private Long updateBy;
@TableField("b_update_time")
@TableField(value = "b_update_time",fill = FieldFill.INSERT_UPDATE)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@TableField("b_status")
private Integer status;
@TableField("b_canuse")
private String canuse;
@TableField("b_recommend")
private String recommend;
@TableField("b_hot_recommend")
private String hotRecommend;
}
@@ -1,5 +1,6 @@
package cn.link56.auth.identity.model;
package cn.link56.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -19,26 +20,33 @@ import java.util.Date;
public class BCompanyUser {
@TableId(value = "b_id")
private Long id;
@TableId(value = "b_company_id")
@TableField("b_company_id")
private Long companyId;
@TableField("b_email")
private String email;
@TableField("b_password")
private String password;
@TableField("b_name")
private String name;
@TableField("b_phone")
private String phone;
@TableField("b_role")
private Integer role;
@TableField("b_position")
private String position;
@TableField("b_create_by")
private Long createBy;
@TableField("b_create_time")
@TableField(value = "b_create_time",fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@TableField("b_update_by")
private Long updateBy;
@TableField("b_update_time")
@TableField(value = "b_update_time",fill = FieldFill.INSERT_UPDATE)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
@@ -1,4 +1,4 @@
package cn.link56.base.model;
package cn.link56.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -4,9 +4,11 @@ spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: net.sourceforge.jtds.jdbc.Driver
url: jdbc:jtds:sqlserver://192.168.1.189:1433;databaseName=G3-Link
# url: jdbc:jtds:sqlserver://192.168.1.189:1433;databaseName=G3-Link
url: jdbc:jtds:sqlserver://117.72.182.135:1433;databaseName=G3-Link
username: sa
password: "g3soft"
# password: "g3soft"
password: "zhang520.."
# druid 连接池管理
druid:
# 初始化时建立物理连接的个数
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.link56.base.mapper.AreaMapper">
<sql id="area_columns">
b_id AS id,
b_xh AS xh,
b_name AS name,
b_father_id AS fatherId,
b_canuse AS canuse,
b_bz AS bz,
b_field AS field,
b_order AS [order]
</sql>
<select id="listAllArea" resultType="cn.link56.entity.BArea">
SELECT <include refid="area_columns"/> FROM b_area_sheng WHERE b_canuse = '1'
UNION ALL
SELECT <include refid="area_columns"/> FROM b_area_shi WHERE b_canuse = '1'
UNION ALL
SELECT <include refid="area_columns"/> FROM b_area_qu WHERE b_canuse = '1'
ORDER BY [order]
</select>
</mapper>
@@ -0,0 +1,522 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="x-apple-disable-message-reformatting" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="color-scheme" content="light dark" />
<meta name="supported-color-schemes" content="light dark" />
<title></title>
<style type="text/css" rel="stylesheet" media="all">
/* Base ------------------------------ */
@import url("https://fonts.googleapis.com/css?family=Nunito+Sans:400,700&display=swap");
body {
width: 100% !important;
height: 100%;
margin: 0;
-webkit-text-size-adjust: none;
}
a {
color: #3869D4;
}
a img {
border: none;
}
td {
word-break: break-word;
}
.preheader {
display: none !important;
visibility: hidden;
mso-hide: all;
font-size: 1px;
line-height: 1px;
max-height: 0;
max-width: 0;
opacity: 0;
overflow: hidden;
}
/* Type ------------------------------ */
body,
td,
th {
font-family: "Nunito Sans", Helvetica, Arial, sans-serif;
}
h1 {
margin-top: 0;
color: #333333;
font-size: 22px;
font-weight: bold;
text-align: left;
}
h2 {
margin-top: 0;
color: #333333;
font-size: 16px;
font-weight: bold;
text-align: left;
}
h3 {
margin-top: 0;
color: #333333;
font-size: 14px;
font-weight: bold;
text-align: left;
}
td,
th {
font-size: 16px;
}
p,
ul,
ol,
blockquote {
margin: .4em 0 1.1875em;
font-size: 16px;
line-height: 1.625;
}
p.sub {
font-size: 13px;
}
/* Utilities ------------------------------ */
.align-right {
text-align: right;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.u-margin-bottom-none {
margin-bottom: 0;
}
/* Buttons ------------------------------ */
.button {
background-color: #3869D4;
border-top: 10px solid #3869D4;
border-right: 18px solid #3869D4;
border-bottom: 10px solid #3869D4;
border-left: 18px solid #3869D4;
display: inline-block;
color: #FFF;
text-decoration: none;
border-radius: 3px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);
-webkit-text-size-adjust: none;
box-sizing: border-box;
}
.button--green {
background-color: #22BC66;
border-top: 10px solid #22BC66;
border-right: 18px solid #22BC66;
border-bottom: 10px solid #22BC66;
border-left: 18px solid #22BC66;
}
.button--red {
background-color: #FF6136;
border-top: 10px solid #FF6136;
border-right: 18px solid #FF6136;
border-bottom: 10px solid #FF6136;
border-left: 18px solid #FF6136;
}
@media only screen and (max-width: 500px) {
.button {
width: 100% !important;
text-align: center !important;
}
}
/* Attribute list ------------------------------ */
.attributes {
margin: 0 0 21px;
}
.attributes_content {
background-color: #F4F4F7;
padding: 16px;
}
.attributes_item {
padding: 0;
}
/* Related Items ------------------------------ */
.related {
width: 100%;
margin: 0;
padding: 25px 0 0 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.related_item {
padding: 10px 0;
color: #CBCCCF;
font-size: 15px;
line-height: 18px;
}
.related_item-title {
display: block;
margin: .5em 0 0;
}
.related_item-thumb {
display: block;
padding-bottom: 10px;
}
.related_heading {
border-top: 1px solid #CBCCCF;
text-align: center;
padding: 25px 0 10px;
}
/* Discount Code ------------------------------ */
.discount {
width: 100%;
margin: 0;
padding: 24px;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #F4F4F7;
border: 2px dashed #CBCCCF;
}
.discount_heading {
text-align: center;
}
.discount_body {
text-align: center;
font-size: 15px;
}
/* Social Icons ------------------------------ */
.social {
width: auto;
}
.social td {
padding: 0;
width: auto;
}
.social_icon {
height: 20px;
margin: 0 8px 10px 8px;
padding: 0;
}
/* Data table ------------------------------ */
.purchase {
width: 100%;
margin: 0;
padding: 35px 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.purchase_content {
width: 100%;
margin: 0;
padding: 25px 0 0 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.purchase_item {
padding: 10px 0;
color: #51545E;
font-size: 15px;
line-height: 18px;
}
.purchase_heading {
padding-bottom: 8px;
border-bottom: 1px solid #EAEAEC;
}
.purchase_heading p {
margin: 0;
color: #85878E;
font-size: 12px;
}
.purchase_footer {
padding-top: 15px;
border-top: 1px solid #EAEAEC;
}
.purchase_total {
margin: 0;
text-align: right;
font-weight: bold;
color: #333333;
}
.purchase_total--label {
padding: 0 15px 0 0;
}
body {
background-color: #F2F4F6;
color: #51545E;
}
p {
color: #51545E;
}
.email-wrapper {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #F2F4F6;
}
.email-content {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
/* Masthead ----------------------- */
.email-masthead {
padding: 25px 0;
text-align: center;
}
.email-masthead_logo {
width: 94px;
}
.email-masthead_name {
font-size: 16px;
font-weight: bold;
color: #A8AAAF;
text-decoration: none;
text-shadow: 0 1px 0 white;
}
/* Body ------------------------------ */
.email-body {
width: 100%;
margin: 0;
padding: 0;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.email-body_inner {
width: 570px;
margin: 0 auto;
padding: 0;
-premailer-width: 570px;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
background-color: #FFFFFF;
}
.email-footer {
width: 570px;
margin: 0 auto;
padding: 0;
-premailer-width: 570px;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
text-align: center;
}
.email-footer p {
color: #A8AAAF;
}
.body-action {
width: 100%;
margin: 30px auto;
padding: 0;
font-size: 42px;
-premailer-width: 100%;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
text-align: center;
}
.body-sub {
margin-top: 25px;
padding-top: 25px;
border-top: 1px solid #EAEAEC;
}
.content-cell {
padding: 45px;
}
/*Media Queries ------------------------------ */
@media only screen and (max-width: 600px) {
.email-body_inner,
.email-footer {
width: 100% !important;
}
}
@media (prefers-color-scheme: dark) {
body,
.email-body,
.email-body_inner,
.email-content,
.email-wrapper,
.email-masthead,
.email-footer {
background-color: #333333 !important;
color: #FFF !important;
}
p,
ul,
ol,
blockquote,
h1,
h2,
h3,
span,
.purchase_item {
color: #FFF !important;
}
.attributes_content,
.discount {
background-color: #222 !important;
}
.email-masthead_name {
text-shadow: none !important;
}
}
:root {
color-scheme: light dark;
supported-color-schemes: light dark;
}
</style>
<!--[if mso]>
<style type="text/css">
.f-fallback {
font-family: Arial, sans-serif;
}
</style>
<![endif]-->
</head>
<body>
<span class="preheader">Use this link to reset your password. The link is only valid for 24 hours.</span>
<table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="center">
<table class="email-content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td class="email-masthead">
<a href="https://example.com" class="f-fallback email-masthead_name">
link56
</a>
</td>
</tr>
<!-- Email Body -->
<tr>
<td class="email-body" width="570" cellpadding="0" cellspacing="0">
<table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0"
role="presentation">
<!-- Body content -->
<tr>
<td class="content-cell">
<div class="f-fallback">
<h1>您好</h1>
<p>您正在登录我们的 link56 平台,系统已为您生成了登录验证码。<strong>该验证码仅在 10 分钟内有效。</strong></p>
<p class="body-action">
[[${Code}]]
</p>
<p>如果不是您本人操作,请忽略此邮件,或如有疑问,请 <a
href="{{SupportUrl}}">联系客服</a>。</p>
<p>
感谢,<br>
link56 团队
</p>
</div>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<table class="email-footer" align="center" width="570" cellpadding="0" cellspacing="0"
role="presentation">
<tr>
<td class="content-cell" align="center">
<p class="f-fallback sub align-center">
宁波江东远通计算机有限公司
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>