feat:web模块包名调整

This commit is contained in:
曾文豪
2024-06-26 10:13:42 +08:00
parent c0ded4356f
commit 093d39a108
60 changed files with 149 additions and 162 deletions

View File

@@ -0,0 +1,44 @@
package com.tiesheng.web.service;
import com.tiesheng.web.mapper.CoreConfigEnumMapper;
import com.tiesheng.web.mapper.CoreConfigSystemMapper;
import com.tiesheng.web.pojos.dao.CoreConfigSystem;
import com.tiesheng.util.service.TsServiceBase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author hao
*/
@Service
public class CoreConfigService extends TsServiceBase<CoreConfigSystemMapper, CoreConfigSystem> {
@Autowired
CoreConfigEnumMapper coreConfigEnumMapper;
public CoreConfigEnumMapper getEnumMapper() {
return coreConfigEnumMapper;
}
/**
* 获取(或创建)一个文本类型的配置
*
* @param configKey
* @param defaultValue
* @return
*/
public CoreConfigSystem getTextOrCreate(String configKey, String defaultValue) {
CoreConfigSystem oneByColumn = getOneByColumn("config_key", configKey);
if (oneByColumn == null) {
oneByColumn = new CoreConfigSystem();
oneByColumn.setId(configKey);
oneByColumn.setConfigKey(configKey);
oneByColumn.setConfigVal(defaultValue);
oneByColumn.setRemark(defaultValue);
oneByColumn.setConfigType(0);
save(oneByColumn);
}
return oneByColumn;
}
}

View File

@@ -0,0 +1,225 @@
package com.tiesheng.web.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tiesheng.web.mapper.CoreLogLoginMapper;
import com.tiesheng.web.mapper.CoreLogMessageMapper;
import com.tiesheng.web.mapper.CoreLogOperationMapper;
import com.tiesheng.web.mapper.CoreLogProcessMapper;
import com.tiesheng.web.pojos.RequestUserInfo;
import com.tiesheng.web.pojos.dao.CoreLogLogin;
import com.tiesheng.web.pojos.dao.CoreLogOperation;
import com.tiesheng.web.pojos.dao.CoreLogProcess;
import com.tiesheng.web.pojos.dao.CorePlatformUnique;
import com.tiesheng.web.pojos.vo.ProcessDetailVo;
import com.tiesheng.web.util.ProcessImportConsumer;
import com.tiesheng.web.util.ProcessSyncConsumer;
import com.tiesheng.util.config.TsTokenConfig;
import com.tiesheng.util.pojos.TokenBean;
import com.tiesheng.util.ServletKit;
import com.tiesheng.util.config.Ip2regionConfig;
import com.tiesheng.util.exception.ApiException;
import com.tiesheng.util.service.TsServiceBase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
/**
* @author hao
*/
@Service
public class CoreLogService extends TsServiceBase<CoreLogOperationMapper, CoreLogOperation> {
@Autowired
TieshengWebConfigurer tieshengWebConfigurer;
@Autowired
CoreLogLoginMapper coreLogLoginMapper;
@Autowired
CoreLogMessageMapper coreLogMessageMapper;
@Autowired
Ip2regionConfig ip2regionConfig;
@Autowired
CoreLogProcessMapper coreLogProcessMapper;
public CoreLogLoginMapper getLogLoginMapper() {
return coreLogLoginMapper;
}
public CoreLogMessageMapper getLogMessageMapper() {
return coreLogMessageMapper;
}
public CoreLogProcessMapper getCoreLogProcessMapper() {
return coreLogProcessMapper;
}
///////////////////////////////////////////////////////////////////////////
// 导入日志
///////////////////////////////////////////////////////////////////////////
/**
* 添加导入过程
*
* @param title 标题
* @param list 要导入的数据
*/
public <T> CoreLogProcess addProcess(String title, List<T> list, ProcessImportConsumer<T> consumer) {
if (CollUtil.isEmpty(list)) {
throw new ApiException("文件中不存在数据");
}
CoreLogProcess coreLogProcess = new CoreLogProcess();
coreLogProcess.setTitle(title);
coreLogProcess.setTotal(list.size());
coreLogProcess.setType("import");
coreLogProcess.setSuccessNum(0);
coreLogProcess.setFailNum(0);
coreLogProcess.setProcess(0);
coreLogProcess.setError("");
coreLogProcessMapper.insert(coreLogProcess);
ThreadUtil.execute(() -> {
List<Exception> errorList = new ArrayList<>();
CollUtil.split(list, 100).forEach((it) -> {
int accept = 0;
try {
accept = consumer.accept(it);
} catch (Exception e) {
errorList.add(e);
}
coreLogProcess.setProcess(coreLogProcess.getProcess() + it.size());
coreLogProcess.setSuccessNum(coreLogProcess.getSuccessNum() + accept);
coreLogProcess.setFailNum(coreLogProcess.getFailNum() + it.size() - accept);
coreLogProcess.setError(JSONUtil.toJsonStr(errorList));
coreLogProcessMapper.updateById(coreLogProcess);
});
// 执行结束
coreLogProcess.setFailFile(consumer.getFailFile());
coreLogProcess.setStatus(1);
coreLogProcess.setError(JSONUtil.toJsonStr(errorList));
coreLogProcessMapper.updateById(coreLogProcess);
});
return coreLogProcess;
}
/**
* 添加同步过程
*
* @param title
* @param consumer
* @return
*/
public CoreLogProcess addProcess(String title, ProcessSyncConsumer consumer) {
CoreLogProcess coreLogProcess = new CoreLogProcess();
coreLogProcess.setTitle(title);
coreLogProcess.setType("sync");
coreLogProcess.setSuccessNum(0);
coreLogProcess.setFailNum(0);
coreLogProcess.setTotal(0);
coreLogProcess.setProcess(0);
coreLogProcess.setError("");
coreLogProcessMapper.insert(coreLogProcess);
ThreadUtil.execute(() -> {
int pageSize = 1000;
int pageNum = 1, lastCount = pageSize;
List<Exception> errorList = new ArrayList<>();
while (lastCount == pageSize) {
try {
lastCount = consumer.accept(pageNum, pageSize);
coreLogProcess.setTotal(coreLogProcess.getTotal() + lastCount);
coreLogProcess.setProcess(coreLogProcess.getTotal());
coreLogProcess.setError(JSONUtil.toJsonStr(errorList));
coreLogProcess.setSuccessNum(coreLogProcess.getSuccessNum() + lastCount);
} catch (Exception e) {
errorList.add(e);
}
coreLogProcessMapper.updateById(coreLogProcess);
pageNum++;
}
// 执行结束
coreLogProcess.setError(JSONUtil.toJsonStr(errorList));
coreLogProcess.setStatus(1);
coreLogProcessMapper.updateById(coreLogProcess);
});
return coreLogProcess;
}
/**
* 根据id 获取过程详情
*/
public ProcessDetailVo getProcessDetail(String id) {
QueryWrapper<CoreLogProcess> wrapper = new QueryWrapper<>();
wrapper.eq("id", id);
CoreLogProcess coreLogProcess = coreLogProcessMapper.selectOne(wrapper);
return BeanUtil.copyProperties(coreLogProcess, ProcessDetailVo.class);
}
///////////////////////////////////////////////////////////////////////////
// 操作日志
///////////////////////////////////////////////////////////////////////////
/**
* 添加操作日志
*/
public void addOperationLog(String title, String subject, Object params) {
TokenBean tokenBean = TsTokenConfig.getWithoutThr();
if (tokenBean == null || StrUtil.isEmpty(tokenBean.getId())) {
return;
}
RequestUserInfo requestUserInfo = tieshengWebConfigurer.getCurrentUserName(tokenBean);
CoreLogOperation operation = new CoreLogOperation();
operation.setUserId(requestUserInfo.getId());
operation.setUserName(requestUserInfo.getName());
operation.setTitle(title);
operation.setSubject(subject);
if (params != null) {
operation.setParams(JSONUtil.toJsonStr(params));
}
save(operation);
}
///////////////////////////////////////////////////////////////////////////
// 登录日志
///////////////////////////////////////////////////////////////////////////
/**
* 添加登录日志
*
* @param platformUnique
* @param tokenBean
*/
public void addLoginLog(CorePlatformUnique platformUnique, TokenBean tokenBean) {
HttpServletRequest request = ServletKit.getRequest();
String ip = ServletUtil.getClientIP(request);
CoreLogLogin login = new CoreLogLogin();
login.setUserId(tokenBean.getId());
login.setPlatform(platformUnique.getPlatform());
RequestUserInfo requestUserInfo = tieshengWebConfigurer.getCurrentUserName(tokenBean);
login.setUserName(requestUserInfo.getName());
login.setIp(ip);
login.setAddress(ip2regionConfig.search(login.getIp()));
coreLogLoginMapper.insert(login);
}
}

View File

@@ -0,0 +1,99 @@
package com.tiesheng.web.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.tiesheng.web.mapper.CoreLogMessageMapper;
import com.tiesheng.web.pojos.dao.CoreLogMessage;
import com.tiesheng.message.pojos.MessageReqResp;
import com.tiesheng.message.pojos.UserChannel;
import com.tiesheng.message.service.TieshengMessageSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
/**
* @author hao
*/
@Service
public class CoreMessageService {
@Autowired
List<TieshengMessageSender> messageSenderList;
@Autowired
CoreLogMessageMapper coreLogMessageMapper;
/**
* 插入数据
*
* @param reqResp
*/
private void insertMessageLog(MessageReqResp reqResp) {
if (reqResp == null) {
return;
}
coreLogMessageMapper.insert(BeanUtil.copyProperties(reqResp, CoreLogMessage.class));
}
/**
* 发送所有消息
*
* @param userIds
* @param body
*/
public void all(List<String> userIds, JSONObject body) {
messageSenderList.stream().filter(TieshengMessageSender::support)
.forEach(sender -> {
for (String user : userIds) {
insertMessageLog(sender.send(user, body));
}
});
}
/**
* 发送消息
*
* @param channels
* @param body
* @param channels 消息通道如果为all时表示发送全部通道
*/
public void multiple(List<UserChannel> channels, JSONObject body) {
if (ArrayUtil.isEmpty(channels)) {
return;
}
messageSenderList.stream().filter(TieshengMessageSender::support)
.forEach(sender -> channels.stream().filter(it -> Objects.equals(it.getChannel(), sender.getChannel()))
.forEach(it -> insertMessageLog(sender.send(it.getUser(), body))));
}
/**
* 发送消息
*
* @param userChannel
* @param body
*/
public MessageReqResp send(UserChannel userChannel, JSONObject body) {
if (StrUtil.isEmpty(userChannel.getUser()) || StrUtil.isEmpty(userChannel.getChannel())) {
return null;
}
TieshengMessageSender messageSender = CollUtil.findOne(messageSenderList,
sender -> Objects.equals(sender.getChannel(), userChannel.getChannel()) && sender.support());
if (messageSender != null) {
MessageReqResp reqResp = messageSender.send(userChannel.getUser(), body);
insertMessageLog(reqResp);
return reqResp;
}
return null;
}
}

View File

@@ -0,0 +1,72 @@
package com.tiesheng.web.service;
import cn.hutool.core.util.StrUtil;
import com.tiesheng.web.mapper.CorePlatformUniqueMapper;
import com.tiesheng.web.pojos.dao.CorePlatformUnique;
import com.tiesheng.util.pojos.TokenBean;
import com.tiesheng.login.pojos.DoLoginInfo;
import com.tiesheng.login.service.TieshengLoginConfigurer;
import com.tiesheng.util.service.TsServiceBase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
/**
* @author hao
*/
@Service
public class CorePlatformUniqueService extends TsServiceBase<CorePlatformUniqueMapper, CorePlatformUnique> implements TieshengLoginConfigurer {
@Autowired
TieshengWebConfigurer tieshengWebConfigurer;
@Autowired
CoreLogService coreLogService;
@Override
@Transactional(rollbackFor = Exception.class)
public TokenBean doLogin(DoLoginInfo loginInfo) {
CorePlatformUnique platformUnique = getOneByColumn("unique_id", loginInfo.getUnique());
if (platformUnique == null) {
platformUnique = new CorePlatformUnique();
platformUnique.setAppId(loginInfo.getAppId());
platformUnique.setUniqueId(loginInfo.getUnique());
}
platformUnique.setPlatform(loginInfo.getPlatform());
platformUnique.setInfo(loginInfo.getInfo());
saveOrUpdate(platformUnique);
String oldUserId = platformUnique.getUserId();
TokenBean tokenBean = tieshengWebConfigurer.login(platformUnique);
if (tokenBean != null) {
// 添加登录日志
coreLogService.addLoginLog(platformUnique, tokenBean);
// 更新唯一值
if (!StrUtil.isEmpty(tokenBean.getId()) &&
!Objects.equals(oldUserId, tokenBean.getId())) {
platformUnique.setUserId(tokenBean.getId());
saveOrUpdate(platformUnique);
}
}
return tokenBean;
}
@Override
public void onLoginRedirect(TokenBean bean, String to, String extra, HttpServletResponse response) {
tieshengWebConfigurer.redirect(bean, to, extra, response);
}
@Override
public void onSignError(HttpServletResponse response) {
tieshengWebConfigurer.onSignError(response);
}
}

View File

@@ -0,0 +1,167 @@
package com.tiesheng.web.service;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.tiesheng.util.exception.ApiException;
import com.tiesheng.util.pojos.FileUploadPath;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
/**
* @author hao
*/
@Service
public class FileUploadService {
@Autowired
TieshengWebConfigurer tieshengWebConfigurer;
///////////////////////////////////////////////////////////////////////////
// 方法
///////////////////////////////////////////////////////////////////////////
/**
* 保存文件
*
* @param file
*/
public String saveMultipartFile(MultipartFile file) {
try {
String fileHttpPath = tieshengWebConfigurer.uploadFileCustomize(file);
if (!StrUtil.isEmpty(fileHttpPath)) {
return fileHttpPath;
}
String fileType = FileTypeUtil.getType(file.getInputStream(), file.getOriginalFilename());
tieshengWebConfigurer.uploadFileCheck(fileType);
FileUploadPath filePath = FileUploadPath.random(fileType);
InputStream stream = file.getInputStream();
FileUtil.writeFromStream(stream, filePath.getAbsolutePath());
IoUtil.close(stream);
return tieshengWebConfigurer.uploadFileDeal(filePath.getHttpPath());
} catch (Exception e) {
throw new ApiException("文件流读取失败:" + e.getMessage());
}
}
///////////////////////////////////////////////////////////////////////////
// 文件分包上传
///////////////////////////////////////////////////////////////////////////
/**
* 检查待上传文件是否存在
*
* @param fileExt
*/
public void chunkStart(String fileExt) {
tieshengWebConfigurer.uploadFileCheck(fileExt);
}
/**
* 检查块文件
*
* @param fileMd5
* @param chunk
* @return
*/
public boolean chunkCheck(String fileMd5, Integer chunk) {
FileUploadPath folder = FileUploadPath.folder(fileMd5);
File chunkFile = FileUtil.file(folder.getAbsolutePath(), chunk.toString());
return chunkFile.exists();
}
/**
* 块文件上传
*
* @param file
* @param fileMd5
* @param chunk
*/
public void chunkUpload(MultipartFile file, String fileMd5, Integer chunk) {
if (file == null) {
throw new ApiException("请选择文件后上传");
}
try {
// 块文件
FileUploadPath folder = FileUploadPath.folder(fileMd5);
File chunkfile = new File(folder.getAbsolutePath(), chunk.toString());
InputStream stream = file.getInputStream();
FileUtil.writeFromStream(stream, chunkfile);
IoUtil.close(stream);
} catch (Exception ignored) {
throw new ApiException("块文件上传失败");
}
}
/**
* 合并块文件
*
* @param fileMd5
*/
public String chunkMerge(String fileMd5, String fileExt) {
// 1获取文件块的目录
FileUploadPath folder = FileUploadPath.folder(fileMd5);
// 2如果目录不存在
if (!FileUtil.exist(folder.getAbsolutePath())) {
throw new ApiException("请先上传文件块");
}
// 3生成保存文件的路径
FileUploadPath uploadPath = FileUploadPath.random(fileExt);
// 4获取块文件此列表是已经排好序的列表
List<File> chunkFiles = getSortedChunkFiles(new File(folder.getAbsolutePath()));
// 5合并文件
File newFile = FileUtil.newFile(uploadPath.getAbsolutePath());
for (File file : chunkFiles) {
byte[] bytes = FileUtil.readBytes(file);
FileUtil.writeBytes(bytes, newFile, 0, bytes.length, true);
}
// 6删除块文件目录
FileUtil.del(folder.getAbsolutePath());
return tieshengWebConfigurer.uploadFileDeal(uploadPath.getHttpPath());
}
/**
* 获取所有块文件
*
* @param chunkFileFolder
* @return
*/
private List<File> getSortedChunkFiles(File chunkFileFolder) {
//获取路径下的所有块文件
File[] chunkFiles = chunkFileFolder.listFiles();
if (chunkFiles == null) {
return new ArrayList<>();
}
//将文件数组转成list并排序
List<File> chunkFileList = new ArrayList<>(Arrays.asList(chunkFiles));
//排序
chunkFileList.sort(Comparator.comparingInt(o -> Integer.parseInt(o.getName())));
return chunkFileList;
}
}

View File

@@ -0,0 +1,102 @@
package com.tiesheng.web.service;
import cn.hutool.log.LogFactory;
import com.tiesheng.web.pojos.RequestUserInfo;
import com.tiesheng.web.pojos.dao.CoreConfigSystem;
import com.tiesheng.web.pojos.dao.CorePlatformUnique;
import com.tiesheng.util.pojos.TokenBean;
import com.tiesheng.util.ServletKit;
import com.tiesheng.util.exception.ApiRespEnum;
import com.tiesheng.util.pojos.ApiResp;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
/**
* WEB配置
*
* @author hao
*/
public interface TieshengWebConfigurer {
/**
* 获取当前用户的姓名
*
* @return
*/
RequestUserInfo getCurrentUserName(TokenBean userId);
/**
* 添加其他异常处理
*
* @param e 异常
*/
default ApiResp<String> addExceptionHandler(Exception e) {
ApiResp<String> apiResp = ApiResp.respCust(ApiRespEnum.ServerError);
apiResp.setException(e);
LogFactory.get().info(apiResp.getException());
return apiResp;
}
/**
* 添加文件校验
*/
default void uploadFileCheck(String fileExt) {
}
/**
* 自定义文件上传
*
* @return
*/
default String uploadFileCustomize(MultipartFile file) {
return "";
}
/**
* 上传文件后处理文件
*
* @param uploadPath
* @return
*/
default String uploadFileDeal(String uploadPath) {
return uploadPath;
}
/**
* 系统配置验证
* 如果不符合规则,可以抛出异常
*/
default void configSystemCheck(CoreConfigSystem configSystem) {
}
/**
* 登录逻辑
*
* @param platformUnique
* @return
*/
TokenBean login(CorePlatformUnique platformUnique);
/**
* 登录重定向
*
* @param bean
* @param extra
* @param response
*/
void redirect(TokenBean bean, String to, String extra, HttpServletResponse response);
/**
* 签名错误的时候
*/
default void onSignError(HttpServletResponse response) {
ServletKit.write(response, "404", "text");
}
}

View File

@@ -0,0 +1,82 @@
package com.tiesheng.web.service;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.tiesheng.util.ServletKit;
import com.tiesheng.util.TimedCacheHelper;
import com.tiesheng.util.exception.ApiException;
import org.springframework.stereotype.Service;
/**
* @author hao
* @ProjectName cmcc
* @Copyright Hangzhou ShuoChuang Technology Co.,Ltd All Right Reserved
* @Description 这里是对文件的描述
* @data 2019-06-19
* @note 这里写文件的详细功能和改动
* @note
*/
@Service
public class TimedCacheService {
/**
* 清空数据
*
* @param key
*/
public void clearByKey(String key) {
TimedCacheHelper.getTimedCache().remove(key);
}
/**
* 放入缓存
*
* @param key
* @param val
*/
public void putCache(String key, String val) {
TimedCacheHelper.getTimedCache().put(key, val);
}
/**
* 获取缓存
*
* @param key
* @return
*/
public String getCache(String key) {
return TimedCacheHelper.getTimedCache().get(key);
}
///////////////////////////////////////////////////////////////////////////
// 图片验证码缓存
///////////////////////////////////////////////////////////////////////////
/**
* 缓存 图片验证码
*
* @param session
* @param value
*/
public void setImageCode(String captcha, String value) {
putCache(captcha, value);
}
/**
* 验证 图片验证码
*/
public void verifyImage(String value) {
String captchaKey = ServletUtil.getHeader(ServletKit.getRequest(), "captcha", "utf-8");
String cache = getCache(captchaKey);
if (StrUtil.isEmpty(cache) || !StrUtil.equals(cache, value)) {
throw new ApiException("验证码不正确");
}
clearByKey(captchaKey);
}
}