Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
96256c3366
26 files changed
+452
-181
No files matched your search
+12
@@ -135,12 +135,24 @@ public interface CacheConstants {
|
||||
|
||||
String WALLET_DETAIL = "wallet:detail:manage";
|
||||
|
||||
// 根据钱包id查询钱包详情
|
||||
String WALLET_DETAIL_ID = "wallet:detail:id";
|
||||
|
||||
// 根据用户id钱包类型查询钱包详情
|
||||
String WALLET_DETAIL_USER_ID_WALLET_TYPE = "wallet:detail:user_id_wallet_type";
|
||||
|
||||
String WALLET_TYPE_DETAIL = "wallet:detail:type";
|
||||
|
||||
String WALLET_SETTING_DETAIL = "wallet:detail:setting";
|
||||
|
||||
String WALLET_RULE_PRICE_CONFIG_DETAIL = "wallet:detail:rule_price_config";
|
||||
|
||||
// 用户消费机的额外价格
|
||||
String WALLET_USER_DISCOUNTS_LIST = "wallet:detail:user_discounts_list";
|
||||
|
||||
// 用户的食堂商户(从视图里查询)
|
||||
String WALLET_VIEWS_CANTEEN_MCH = "wallet:detail:view_canteen_mch";
|
||||
|
||||
/* ************************************* end 钱包相关 end ************************************* */
|
||||
|
||||
/* ************************************* start 第三方对接相关 start ************************************* */
|
||||
|
||||
+154
-134
@@ -53,159 +53,179 @@ import java.util.Map;
|
||||
@RequiredArgsConstructor
|
||||
public class DruidSqlLogFilter extends FilterEventAdapter {
|
||||
|
||||
private static final SQLUtils.FormatOption FORMAT_OPTION = new SQLUtils.FormatOption(false, false);
|
||||
private static final SQLUtils.FormatOption FORMAT_OPTION = new SQLUtils.FormatOption(false, false);
|
||||
|
||||
private final PjcloudMybatisProperties properties;
|
||||
private final PjcloudMybatisProperties properties;
|
||||
|
||||
@Override
|
||||
protected void statementExecuteBefore(StatementProxy statement, String sql) {
|
||||
statement.setLastExecuteStartNano();
|
||||
}
|
||||
@Override
|
||||
protected void statementExecuteBefore(StatementProxy statement, String sql) {
|
||||
statement.setLastExecuteStartNano();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void statementExecuteBatchBefore(StatementProxy statement) {
|
||||
statement.setLastExecuteStartNano();
|
||||
}
|
||||
@Override
|
||||
protected void statementExecuteBatchBefore(StatementProxy statement) {
|
||||
statement.setLastExecuteStartNano();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void statementExecuteUpdateBefore(StatementProxy statement, String sql) {
|
||||
statement.setLastExecuteStartNano();
|
||||
}
|
||||
@Override
|
||||
protected void statementExecuteUpdateBefore(StatementProxy statement, String sql) {
|
||||
statement.setLastExecuteStartNano();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void statementExecuteQueryBefore(StatementProxy statement, String sql) {
|
||||
statement.setLastExecuteStartNano();
|
||||
}
|
||||
@Override
|
||||
protected void statementExecuteQueryBefore(StatementProxy statement, String sql) {
|
||||
statement.setLastExecuteStartNano();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void statementExecuteAfter(StatementProxy statement, String sql, boolean firstResult) {
|
||||
statement.setLastExecuteTimeNano();
|
||||
}
|
||||
@Override
|
||||
protected void statementExecuteAfter(StatementProxy statement, String sql, boolean firstResult) {
|
||||
statement.setLastExecuteTimeNano();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void statementExecuteBatchAfter(StatementProxy statement, int[] result) {
|
||||
statement.setLastExecuteTimeNano();
|
||||
}
|
||||
@Override
|
||||
protected void statementExecuteBatchAfter(StatementProxy statement, int[] result) {
|
||||
statement.setLastExecuteTimeNano();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void statementExecuteQueryAfter(StatementProxy statement, String sql, ResultSetProxy resultSet) {
|
||||
statement.setLastExecuteTimeNano();
|
||||
}
|
||||
@Override
|
||||
protected void statementExecuteQueryAfter(StatementProxy statement, String sql, ResultSetProxy resultSet) {
|
||||
statement.setLastExecuteTimeNano();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void statementExecuteUpdateAfter(StatementProxy statement, String sql, int updateCount) {
|
||||
statement.setLastExecuteTimeNano();
|
||||
}
|
||||
@Override
|
||||
protected void statementExecuteUpdateAfter(StatementProxy statement, String sql, int updateCount) {
|
||||
statement.setLastExecuteTimeNano();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void statement_close(FilterChain chain, StatementProxy statement) throws SQLException {
|
||||
// 先调用父类关闭 statement
|
||||
super.statement_close(chain, statement);
|
||||
// 支持动态开启
|
||||
if (!properties.isShowSql()) {
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public void statement_close(FilterChain chain, StatementProxy statement) throws SQLException {
|
||||
// 先调用父类关闭 statement
|
||||
super.statement_close(chain, statement);
|
||||
// 支持动态开启
|
||||
if (!properties.isShowSql()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 是否开启调试
|
||||
if (!log.isInfoEnabled()) {
|
||||
return;
|
||||
}
|
||||
// 是否开启调试
|
||||
if (!log.isInfoEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 打印可执行的 sql
|
||||
String sql = statement.getBatchSql();
|
||||
// sql 为空直接返回
|
||||
if (StringUtils.isEmpty(sql)) {
|
||||
return;
|
||||
}
|
||||
// 打印可执行的 sql
|
||||
String sql = statement.getBatchSql();
|
||||
// sql 为空直接返回
|
||||
if (StringUtils.isEmpty(sql)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
|
||||
String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
|
||||
|
||||
// 判断表名是配置了匹配过滤
|
||||
if (CollUtil.isNotEmpty(properties.getSkipTable())) {
|
||||
List<String> skipTableList = properties.getSkipTable();
|
||||
// 判断表名是配置了匹配过滤
|
||||
if (CollUtil.isNotEmpty(properties.getSkipTable())) {
|
||||
List<String> skipTableList = properties.getSkipTable();
|
||||
|
||||
List<String> tableNameList = getTablesBydruid(sql, dbType);
|
||||
if (tableNameList.stream()
|
||||
.anyMatch(tableName -> StrUtil.containsAnyIgnoreCase(tableName,
|
||||
ArrayUtil.toArray(skipTableList, String.class)))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
List<String> tableNameList = getTablesBydruid(sql, dbType);
|
||||
if (tableNameList.stream()
|
||||
.anyMatch(tableName -> StrUtil.containsAnyIgnoreCase(tableName,
|
||||
ArrayUtil.toArray(skipTableList, String.class)))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int parametersSize = statement.getParametersSize();
|
||||
List<Object> parameters = new ArrayList<>(parametersSize);
|
||||
for (int i = 0; i < parametersSize; ++i) {
|
||||
// 转换参数,处理 java8 时间
|
||||
parameters.add(getJdbcParameter(statement.getParameter(i)));
|
||||
}
|
||||
String formattedSql = SQLUtils.format(sql, DbType.of(dbType), parameters, FORMAT_OPTION);
|
||||
printSql(formattedSql, statement);
|
||||
}
|
||||
int parametersSize = statement.getParametersSize();
|
||||
List<Object> parameters = new ArrayList<>(parametersSize);
|
||||
for (int i = 0; i < parametersSize; ++i) {
|
||||
// 转换参数,处理 java8 时间
|
||||
parameters.add(getJdbcParameter(statement.getParameter(i)));
|
||||
}
|
||||
String formattedSql = SQLUtils.format(sql, DbType.of(dbType), parameters, FORMAT_OPTION);
|
||||
printSql(formattedSql, statement);
|
||||
}
|
||||
|
||||
private static Object getJdbcParameter(JdbcParameter jdbcParam) {
|
||||
if (jdbcParam == null) {
|
||||
return null;
|
||||
}
|
||||
Object value = jdbcParam.getValue();
|
||||
// 处理 java8 时间
|
||||
if (value instanceof TemporalAccessor) {
|
||||
return value.toString();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
private static Object getJdbcParameter(JdbcParameter jdbcParam) {
|
||||
if (jdbcParam == null) {
|
||||
return null;
|
||||
}
|
||||
Object value = jdbcParam.getValue();
|
||||
// 处理 java8 时间
|
||||
if (value instanceof TemporalAccessor) {
|
||||
return value.toString();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private static void printSql(String sql, StatementProxy statement) {
|
||||
// 打印 sql
|
||||
String sqlLogger = "\n\n======= Sql Logger ======================" + "\n{}"
|
||||
+ "\n======= Sql Execute Time: {} =======\n";
|
||||
log.info(sqlLogger, sql.trim(), format(statement.getLastExecuteTimeNano()));
|
||||
}
|
||||
private static void printSql(String sql, StatementProxy statement) {
|
||||
// 打印 sql
|
||||
String sqlLogger = "\n\n======= Sql Logger ======================" + "\n{}"
|
||||
+ "\n======= Sql Execute Time: {} =======\n";
|
||||
log.info(sqlLogger, sql.trim(), format(statement.getLastExecuteTimeNano()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化执行时间,单位为 ms 和 s,保留三位小数
|
||||
* @param nanos 纳秒
|
||||
* @return 格式化后的时间
|
||||
*/
|
||||
private static String format(long nanos) {
|
||||
if (nanos < 1) {
|
||||
return "0ms";
|
||||
}
|
||||
double millis = (double) nanos / (1000 * 1000);
|
||||
// 不够 1 ms,最小单位为 ms
|
||||
if (millis > 1000) {
|
||||
return String.format("%.3fs", millis / 1000);
|
||||
}
|
||||
else {
|
||||
return String.format("%.3fms", millis);
|
||||
}
|
||||
}
|
||||
private static void printSqlV2(String sql, StatementProxy statement) {
|
||||
// 打印 sql 和调用堆栈
|
||||
StringBuilder sqlLogger = new StringBuilder();
|
||||
sqlLogger.append("\n\n======= Sql Logger V2 ======================\n");
|
||||
sqlLogger.append("{}\n"); // SQL语句占位符
|
||||
sqlLogger.append("======= Sql Execute Time: {} =======\n"); // 执行时间占位符
|
||||
sqlLogger.append("======= Call Stack ======================\n");
|
||||
|
||||
/**
|
||||
* 从SQL中提取表名(sql中出现的所有表)
|
||||
* @param sql sql语句
|
||||
* @param dbType dbType
|
||||
* @return List<String>
|
||||
*/
|
||||
public static List<String> getTablesBydruid(String sql, String dbType) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, dbType);
|
||||
for (SQLStatement stmt : stmtList) {
|
||||
// 也可以用更精确的解析器,如MySqlSchemaStatVisitor
|
||||
SchemaStatVisitor visitor;
|
||||
// SQL server 数据库特殊处理
|
||||
if (DbType.sqlserver.name().equalsIgnoreCase(dbType)) {
|
||||
visitor = new SQLServerSchemaStatVisitor();
|
||||
}
|
||||
else {
|
||||
visitor = new SchemaStatVisitor();
|
||||
}
|
||||
stmt.accept(visitor);
|
||||
Map<TableStat.Name, TableStat> tables = visitor.getTables();
|
||||
for (TableStat.Name name : tables.keySet()) {
|
||||
result.add(name.getName());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// 获取调用堆栈信息
|
||||
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
|
||||
for (int i = 3; i < stackTrace.length; i++) { // 跳过前几个内部调用
|
||||
if (stackTrace[i].getClassName().contains("com.bsd.pjcloud")) { // 只记录项目相关的调用
|
||||
sqlLogger.append(" at ").append(stackTrace[i].toString()).append("\n");
|
||||
}
|
||||
}
|
||||
sqlLogger.append("=========================================\n");
|
||||
|
||||
log.info(sqlLogger.toString(), sql.trim(), format(statement.getLastExecuteTimeNano()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化执行时间,单位为 ms 和 s,保留三位小数
|
||||
*
|
||||
* @param nanos 纳秒
|
||||
* @return 格式化后的时间
|
||||
*/
|
||||
private static String format(long nanos) {
|
||||
if (nanos < 1) {
|
||||
return "0ms";
|
||||
}
|
||||
double millis = (double) nanos / (1000 * 1000);
|
||||
// 不够 1 ms,最小单位为 ms
|
||||
if (millis > 1000) {
|
||||
return String.format("%.3fs", millis / 1000);
|
||||
} else {
|
||||
return String.format("%.3fms", millis);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从SQL中提取表名(sql中出现的所有表)
|
||||
*
|
||||
* @param sql sql语句
|
||||
* @param dbType dbType
|
||||
* @return List<String>
|
||||
*/
|
||||
public static List<String> getTablesBydruid(String sql, String dbType) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, dbType);
|
||||
for (SQLStatement stmt : stmtList) {
|
||||
// 也可以用更精确的解析器,如MySqlSchemaStatVisitor
|
||||
SchemaStatVisitor visitor;
|
||||
// SQL server 数据库特殊处理
|
||||
if (DbType.sqlserver.name().equalsIgnoreCase(dbType)) {
|
||||
visitor = new SQLServerSchemaStatVisitor();
|
||||
} else {
|
||||
visitor = new SchemaStatVisitor();
|
||||
}
|
||||
stmt.accept(visitor);
|
||||
Map<TableStat.Name, TableStat> tables = visitor.getTables();
|
||||
for (TableStat.Name name : tables.keySet()) {
|
||||
result.add(name.getName());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -53,7 +53,7 @@ public class HardApiServiceImpl implements HardApiService {
|
||||
result.setWalletBalance(wallet.getBalance());
|
||||
result.setWalletIsFreeze(wallet.getIsFreeze());
|
||||
// 查询用户食堂信息
|
||||
MchManageVo mchDetail = remoteMchService.getFirstMchByDeptId(user.getSysUser().getDeptId(), List.of(MerchantTypeEnum.CANTEEN)).getData();
|
||||
MchManageVo mchDetail = remoteMchService.getViewsCanteenMchByDeptId(user.getSysUser().getDeptId()).getData();
|
||||
if (ObjectUtil.isNotEmpty(mchDetail)) {
|
||||
result.setCanteenId(mchDetail.getId());
|
||||
}
|
||||
@@ -86,7 +86,7 @@ public class HardApiServiceImpl implements HardApiService {
|
||||
result.setWalletBalance(wallet.getBalance());
|
||||
result.setWalletIsFreeze(wallet.getIsFreeze());
|
||||
// 查询用户食堂信息
|
||||
MchManageVo mchDetail = remoteMchService.getFirstMchByDeptId(user.getSysUser().getDeptId(), List.of(MerchantTypeEnum.CANTEEN)).getData();
|
||||
MchManageVo mchDetail = remoteMchService.getViewsCanteenMchByDeptId(user.getSysUser().getDeptId()).getData();
|
||||
if (ObjectUtil.isNotEmpty(mchDetail)) {
|
||||
result.setCanteenId(mchDetail.getId());
|
||||
}
|
||||
|
||||
+1
-1
@@ -461,7 +461,7 @@ public class HardDoorFlowServiceImpl extends ServiceImpl<HardDoorFlowMapper, Har
|
||||
|
||||
private void disposeList(HardDoorFlowVo detail) {
|
||||
// 用户
|
||||
List<UserVO> usrList = remoteUserService.getUserDeptByIds(List.of(detail.getUserId())).getData();
|
||||
List<UserVO> usrList = remoteUserService.getInnerUserDeptByIds(List.of(detail.getUserId())).getData();
|
||||
if (ObjectUtil.isNotEmpty(usrList)) {
|
||||
DataUtil.convertUserDept(detail, usrList.get(0));
|
||||
}
|
||||
|
||||
+2
-1
@@ -1110,7 +1110,7 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
|
||||
List<MchRuleJoinDtoVo> list = mchRuleJoinService.innerMchRoleList(mch.getId()).getData();
|
||||
if (ObjectUtil.isEmpty(list)) return extraPrice;
|
||||
// 查询用户食堂
|
||||
MchManageVo userMch = remoteMchService.getFirstMchByDeptId(sysUser.getDeptId(), List.of(MerchantTypeEnum.CANTEEN)).getData();
|
||||
MchManageVo userMch = remoteMchService.getViewsCanteenMchByDeptId(sysUser.getDeptId()).getData();
|
||||
for (MchRuleJoinDtoVo v : list) {
|
||||
Long basePrice = v.getBasePrice();
|
||||
Long multiple = v.getMultiple();
|
||||
@@ -1762,6 +1762,7 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
|
||||
// 购物车
|
||||
if (dto.getIsFindCarList()) {
|
||||
for (HardOrderVo v : list) {
|
||||
if (ObjectUtil.isEmpty(v.getParentCarId())) continue;
|
||||
List<HardCarEntity> carList = hardCarService.getByParentCarId(v.getParentCarId());
|
||||
List<HardCarVo> carVoList = BeanUtils.toBean(carList, HardCarVo.class);
|
||||
v.setCarList(carVoList);
|
||||
|
||||
+5
-3
@@ -444,9 +444,11 @@ public class HardOrderTotalServiceImpl implements HardOrderTotalService {
|
||||
}
|
||||
}
|
||||
// 商户
|
||||
MchManageVo mchDetail = remoteMchService.getById(totalList.getMerchantId()).getData();
|
||||
if (ObjectUtil.isNotEmpty(mchDetail)) {
|
||||
WalletDataUtil.convertMch(totalList, mchDetail);
|
||||
if (ObjectUtil.isNotEmpty(totalList.getMerchantId())) {
|
||||
MchManageVo mchDetail = remoteMchService.getById(totalList.getMerchantId()).getData();
|
||||
if (ObjectUtil.isNotEmpty(mchDetail)) {
|
||||
WalletDataUtil.convertMch(totalList, mchDetail);
|
||||
}
|
||||
}
|
||||
return totalList;
|
||||
}
|
||||
|
||||
+2
-2
@@ -265,7 +265,7 @@ public class SysUser extends Model<SysUser> implements Serializable {
|
||||
@Schema(description = "编制类型")
|
||||
private String staffingType;
|
||||
|
||||
@Schema(description = "性别")
|
||||
private Integer gender;
|
||||
// @Schema(description = "性别")
|
||||
// private Integer gender;
|
||||
|
||||
}
|
||||
+5
@@ -90,6 +90,10 @@ public interface RemoteUserService {
|
||||
@PostMapping("/user/inner/list")
|
||||
R<List<SysUser>> getInnerUserById(@RequestBody List<Long> userIds);
|
||||
|
||||
@NoToken
|
||||
@PostMapping("/user/inner/user-dept")
|
||||
R<List<UserVO>> getInnerUserDeptByIds(@RequestBody List<Long> userIds);
|
||||
|
||||
@PostMapping("/user/user-dept")
|
||||
R<List<UserVO>> getUserDeptByIds(@RequestBody List<Long> userIds);
|
||||
|
||||
@@ -197,6 +201,7 @@ public interface RemoteUserService {
|
||||
|
||||
/**
|
||||
* 根据角色编码查询用户列表
|
||||
*
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
|
||||
+7
@@ -476,6 +476,13 @@ public class SysUserController {
|
||||
return R.ok(userService.list(Wrappers.<SysUser>lambdaQuery().in(SysUser::getUserId, userIds)));
|
||||
}
|
||||
|
||||
@Inner
|
||||
@PostMapping("/inner/user-dept")
|
||||
public R<List<UserVO>> getInnerUserDeptByIds(@RequestBody List<Long> userIds) {
|
||||
return R.ok(userService.getUserDeptByIds(userIds));
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/user-dept")
|
||||
public R<List<UserVO>> getUserDeptByIds(@RequestBody List<Long> userIds) {
|
||||
return R.ok(userService.getUserDeptByIds(userIds));
|
||||
|
||||
+3
@@ -239,4 +239,7 @@ public interface SysUserService extends IService<SysUser> {
|
||||
* @return
|
||||
*/
|
||||
List<SimpleUserListVO> listUserIdByDeptId(Long deptId, String name);
|
||||
|
||||
void deleteDiscountsCacheByUserId(Long userId);
|
||||
|
||||
}
|
||||
+11
-3
@@ -38,6 +38,7 @@ import com.bsd.pjcloud.admin.api.vo.DeptExcelVO;
|
||||
import com.bsd.pjcloud.admin.api.vo.OrgTreeVO;
|
||||
import com.bsd.pjcloud.admin.mapper.*;
|
||||
import com.bsd.pjcloud.admin.service.SysDeptService;
|
||||
import com.bsd.pjcloud.common.core.constant.CacheConstants;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.data.datascope.DataScope;
|
||||
import com.bsd.pjcloud.common.excel.vo.ErrorMessage;
|
||||
@@ -46,6 +47,7 @@ import com.bsd.pjcloud.common.security.util.SecurityUtils;
|
||||
import com.bsd.pjcloud.wallet.api.feign.RemoteWalletService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.BindingResult;
|
||||
@@ -112,9 +114,15 @@ public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> impl
|
||||
* 修改部门
|
||||
*/
|
||||
@Override
|
||||
public Boolean edit(SysDept sysDept) {
|
||||
boolean isEdit = updateById(sysDept);
|
||||
remoteWalletService.deptChange(sysDept.getDeptId(), Boolean.FALSE);
|
||||
@CacheEvict(
|
||||
value = CacheConstants.WALLET_VIEWS_CANTEEN_MCH,
|
||||
key = "#dto.getDeptId()",
|
||||
condition = "#dto.getDeptId() != null",
|
||||
beforeInvocation = true
|
||||
)
|
||||
public Boolean edit(SysDept dto) {
|
||||
boolean isEdit = updateById(dto);
|
||||
remoteWalletService.deptChange(dto.getDeptId(), Boolean.FALSE);
|
||||
return isEdit;
|
||||
}
|
||||
|
||||
|
||||
+33
@@ -61,6 +61,7 @@ import com.bsd.pjcloud.common.core.util.MsgUtils;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.data.datascope.DataScope;
|
||||
import com.bsd.pjcloud.common.data.resolver.ParamResolver;
|
||||
import com.bsd.pjcloud.common.data.tenant.TenantContextHolder;
|
||||
import com.bsd.pjcloud.common.excel.vo.ErrorMessage;
|
||||
import com.bsd.pjcloud.common.security.service.PjcloudUser;
|
||||
import com.bsd.pjcloud.common.security.util.SecurityUtils;
|
||||
@@ -75,10 +76,15 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.poi.ss.usermodel.PictureData;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
@@ -90,6 +96,7 @@ import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -116,6 +123,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
|
||||
private final SysDeptService sysDeptService;
|
||||
|
||||
private final StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Lazy
|
||||
private final SysUserFaceService sysUserFaceService;
|
||||
private final SysUserFaceMapper sysUserFaceMapper;
|
||||
@@ -372,6 +381,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
sysUser.setNickname(userDto.getNickname());
|
||||
sysUser.setName(userDto.getName());
|
||||
sysUser.setEmail(userDto.getEmail());
|
||||
deleteDiscountsCacheByUserId(userDto.getUserId());
|
||||
return R.ok(this.updateById(sysUser));
|
||||
}
|
||||
|
||||
@@ -425,6 +435,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
remoteWalletService.createWallet(userDto.getUserId());
|
||||
remoteWalletService.userChange(userDto.getUserId(), Boolean.FALSE);
|
||||
});
|
||||
|
||||
deleteDiscountsCacheByUserId(userDto.getUserId());
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
@@ -993,6 +1005,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
if (isConsent) {
|
||||
// 创建用户默认钱包
|
||||
remoteWalletService.createWallet(detail.getUserId());
|
||||
deleteDiscountsCacheByUserId(detail.getUserId());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -1056,4 +1069,24 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
}
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDiscountsCacheByUserId(Long userId) {
|
||||
if (ObjectUtil.isEmpty(userId)) return;
|
||||
String pattern = TenantContextHolder.getTenantId() + ":" + CacheConstants.WALLET_USER_DISCOUNTS_LIST + "::" + userId + ":*";
|
||||
Set<String> keys = new HashSet<>();
|
||||
stringRedisTemplate.execute((RedisCallback<Void>) connection -> {
|
||||
Cursor<byte[]> cursor = connection.scan(
|
||||
ScanOptions.scanOptions().match(pattern).count(1000).build()
|
||||
);
|
||||
while (cursor.hasNext()) {
|
||||
keys.add(new String(cursor.next(), StandardCharsets.UTF_8));
|
||||
}
|
||||
return null;
|
||||
});
|
||||
if (!keys.isEmpty()) {
|
||||
stringRedisTemplate.delete(keys);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
@@ -230,6 +230,7 @@ public class SysUserTransactionServiceImpl extends ServiceImpl<SysUserTransactio
|
||||
RequestContextHolder.setRequestAttributes(requestAttributes);
|
||||
remoteWalletService.userChange(detail.getUserId(), Boolean.FALSE);
|
||||
});
|
||||
sysUserService.deleteDiscountsCacheByUserId(detail.getUserId());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
+4
@@ -52,4 +52,8 @@ public interface RemoteMchService {
|
||||
@NoToken
|
||||
@GetMapping("/mch-manage/get-first-mch-by-dept-id")
|
||||
R<MchManageVo> getFirstMchByDeptId(@RequestParam Long deptId, @RequestParam List<MerchantTypeEnum> mchType);
|
||||
|
||||
@NoToken
|
||||
@GetMapping("/mch-manage/get-views-canteen-mch-by-dept-id")
|
||||
R<MchManageVo> getViewsCanteenMchByDeptId(@RequestParam Long deptId);
|
||||
}
|
||||
+14
@@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.bsd.pjcloud.common.core.constant.CacheConstants;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.data.datascope.DataScope;
|
||||
import com.bsd.pjcloud.common.data.datascope.DataScopeFuncEnum;
|
||||
@@ -23,6 +24,7 @@ import com.bsd.pjcloud.wallet.mapper.WalletManageMapper;
|
||||
import com.bsd.pjcloud.wallet.service.WalletCodeUseService;
|
||||
import com.bsd.pjcloud.wallet.service.WalletManageService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
@@ -91,6 +93,12 @@ public class WalletManageController {
|
||||
|
||||
@Inner
|
||||
@GetMapping("/get-wallet")
|
||||
// @Cacheable(
|
||||
// value = CacheConstants.WALLET_DETAIL_USER_ID_WALLET_TYPE + "#3600",
|
||||
// key = "#userId + ':' + #walletTypeCode.getCode()",
|
||||
// condition = "#userId != null && #walletTypeCode.getCode() != null",
|
||||
// unless = "#result == null || #result.data == null"
|
||||
// )
|
||||
public R getWallet(@RequestParam Long userId, @RequestParam WalletTypeEnum walletTypeCode) {
|
||||
WalletManageEntity wallet = walletManageService.getWallet(userId, walletTypeCode);
|
||||
if (ObjectUtil.isEmpty(wallet)) return R.failed("用户钱包不存在");
|
||||
@@ -99,6 +107,12 @@ public class WalletManageController {
|
||||
|
||||
@Inner
|
||||
@GetMapping("/get-wallet-by-id")
|
||||
// @Cacheable(
|
||||
// value = CacheConstants.WALLET_DETAIL_ID + "#3600",
|
||||
// key = "#walletId",
|
||||
// condition = "#walletId != null",
|
||||
// unless = "#result == null || #result.data != null"
|
||||
// )
|
||||
public R<WalletManageVo> getWalletById(@RequestParam Long walletId) {
|
||||
WalletManageVo wallet = walletManageMapper.join(walletId);
|
||||
if (ObjectUtil.isEmpty(wallet)) return R.failed("用户钱包不存在");
|
||||
|
||||
+9
@@ -1,5 +1,6 @@
|
||||
package com.bsd.pjcloud.wallet.controller;
|
||||
|
||||
import com.bsd.pjcloud.common.core.constant.CacheConstants;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.log.annotation.SysLog;
|
||||
import com.bsd.pjcloud.common.security.annotation.Inner;
|
||||
@@ -8,6 +9,7 @@ import com.bsd.pjcloud.wallet.api.vo.WalletSettingVo;
|
||||
import com.bsd.pjcloud.wallet.api.vo.WalletXfjDiscounts;
|
||||
import com.bsd.pjcloud.wallet.service.WalletSettingService;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -56,7 +58,14 @@ public class WalletSettingController {
|
||||
/* ************************************* end app end ************************************* */
|
||||
|
||||
/* ************************************* start android start ************************************* */
|
||||
|
||||
@GetMapping("/ad/get-discounts-list")
|
||||
@Cacheable(
|
||||
value = CacheConstants.WALLET_USER_DISCOUNTS_LIST,
|
||||
key = "#userId + ':' + #hardId",
|
||||
condition = "#userId != null && #hardId != null",
|
||||
unless = "#result == null || #result.data == null"
|
||||
)
|
||||
public R<List<WalletXfjDiscounts>> androidGetDiscountsList(@RequestParam String hardId, @RequestParam Long userId) {
|
||||
return R.ok(walletSettingService.androidGetDiscountsList(hardId, userId));
|
||||
}
|
||||
|
||||
+11
@@ -10,6 +10,7 @@ import com.bsd.pjcloud.admin.api.dto.UserInfo;
|
||||
import com.bsd.pjcloud.admin.api.entity.SysDept;
|
||||
import com.bsd.pjcloud.admin.api.feign.RemoteDeptService;
|
||||
import com.bsd.pjcloud.admin.api.feign.RemoteUserService;
|
||||
import com.bsd.pjcloud.common.core.constant.CacheConstants;
|
||||
import com.bsd.pjcloud.common.core.constant.enums.MerchantTypeEnum;
|
||||
import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
@@ -23,6 +24,7 @@ import com.bsd.pjcloud.wallet.api.dto.MchManageDto;
|
||||
import com.bsd.pjcloud.wallet.api.entity.mch.MchManageEntity;
|
||||
import com.bsd.pjcloud.wallet.api.vo.MchManageVo;
|
||||
import com.bsd.pjcloud.wallet.service.MchManageService;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import com.bsd.pjcloud.common.excel.annotation.ResponseExcel;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
@@ -126,6 +128,15 @@ public class MchManageController {
|
||||
if (ObjectUtil.isEmpty(mchManage)) return R.failed("商户不存在");
|
||||
return R.ok(mchManage);
|
||||
}
|
||||
|
||||
@Inner
|
||||
@GetMapping("/get-views-canteen-mch-by-dept-id")
|
||||
public R<MchManageVo> getViewsCanteenMchByDeptId(@RequestParam Long deptId) {
|
||||
MchManageVo mchManage = mchManageService.getViewsCanteenMchByDeptId(deptId);
|
||||
if (ObjectUtil.isEmpty(mchManage)) return R.failed("商户不存在");
|
||||
return R.ok(mchManage);
|
||||
}
|
||||
|
||||
/* ************************************* end 远程调用 end ************************************* */
|
||||
|
||||
/* ************************************* start app start ************************************* */
|
||||
|
||||
+1
-1
@@ -14,6 +14,6 @@ public interface MchDeptViewMapper {
|
||||
|
||||
List<WalletMchDeptViewVo> selectList(@Param("dto") WalletMchDeptViewDto dto);
|
||||
|
||||
WalletMchDeptViewVo selectByUserId(@Param("userId") Long userId);
|
||||
WalletMchDeptViewVo selectByDeptId(@Param("deptId") Long deptId);
|
||||
|
||||
}
|
||||
+8
@@ -2,12 +2,15 @@ package com.bsd.pjcloud.wallet.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.bsd.pjcloud.common.core.constant.CacheConstants;
|
||||
import com.bsd.pjcloud.common.core.constant.enums.MerchantTypeEnum;
|
||||
import com.bsd.pjcloud.common.data.datascope.DataScope;
|
||||
import com.bsd.pjcloud.common.security.service.PjcloudUser;
|
||||
import com.bsd.pjcloud.wallet.api.dto.MchManageDto;
|
||||
import com.bsd.pjcloud.wallet.api.entity.mch.MchManageEntity;
|
||||
import com.bsd.pjcloud.wallet.api.vo.MchManageVo;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -41,6 +44,11 @@ public interface MchManageService extends IService<MchManageEntity> {
|
||||
|
||||
MchManageVo getFirstMchByDeptId(Long deptId, List<MerchantTypeEnum> mchTypeList);
|
||||
|
||||
/**
|
||||
* 从视图里获取食堂商户信息
|
||||
*/
|
||||
MchManageVo getViewsCanteenMchByDeptId(Long deptId);
|
||||
|
||||
/**
|
||||
* 刷新商户二维码
|
||||
*/
|
||||
|
||||
+5
@@ -121,4 +121,9 @@ public interface WalletManageService extends IService<WalletManageEntity> {
|
||||
* 是够能够使用智能柜
|
||||
*/
|
||||
String isUseDoor(Long userId);
|
||||
|
||||
/**
|
||||
* 删除钱包缓存
|
||||
*/
|
||||
void delWalletCache(WalletManageVo wallet);
|
||||
}
|
||||
+20
-1
@@ -29,6 +29,7 @@ import com.bsd.pjcloud.common.core.util.CollectionUtils;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.data.datascope.DataScope;
|
||||
import com.bsd.pjcloud.common.data.resolver.ParamResolver;
|
||||
import com.bsd.pjcloud.common.data.tenant.TenantContextHolder;
|
||||
import com.bsd.pjcloud.wallet.api.constant.WalletTypeEnum;
|
||||
import com.bsd.pjcloud.wallet.api.dto.WalletManageBalanceDto;
|
||||
import com.bsd.pjcloud.wallet.api.dto.WalletManageDto;
|
||||
@@ -79,6 +80,7 @@ public class WalletManageServiceImpl extends ServiceImpl<WalletManageMapper, Wal
|
||||
@Lazy
|
||||
private final WalletThirdZyService walletThirdZyService;
|
||||
private final MchManageService mchManageService;
|
||||
private final StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
private final RemoteUserService userService;
|
||||
private final RemoteDeptService deptService;
|
||||
@@ -102,7 +104,7 @@ public class WalletManageServiceImpl extends ServiceImpl<WalletManageMapper, Wal
|
||||
log.info("|{}|创建用户电子钱包失败,userId:{},用户id不存在", TAG, userId);
|
||||
return;
|
||||
}
|
||||
String role = Arrays.stream(user.getRoleCodes()).filter(v -> ObjectUtil.equals(v, autoWalletRoleCode)).findFirst().get();
|
||||
String role = Arrays.stream(user.getRoleCodes()).filter(v -> ObjectUtil.equals(v, autoWalletRoleCode)).findFirst().orElse(null);
|
||||
if (ObjectUtil.isEmpty(role)) {
|
||||
log.info("|{}|创建用户电子钱包失败,userId:{},没有{}权限", TAG, userId, "WALLET_AUTO_CREATE");
|
||||
return;
|
||||
@@ -548,6 +550,23 @@ public class WalletManageServiceImpl extends ServiceImpl<WalletManageMapper, Wal
|
||||
return "消费钱包余额不足100元";
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除钱包缓存
|
||||
*/
|
||||
@Override
|
||||
public void delWalletCache(WalletManageVo wallet) {
|
||||
if (ObjectUtil.isEmpty(wallet)) return;
|
||||
Long tenantId = TenantContextHolder.getTenantId();
|
||||
if (ObjectUtil.isNotEmpty(wallet.getId())) {
|
||||
String redisKey = tenantId + ":" + CacheConstants.WALLET_DETAIL_ID + "::" + wallet.getId();
|
||||
stringRedisTemplate.delete(redisKey);
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(wallet.getUserId()) && ObjectUtil.isNotEmpty(wallet.getWalletTypeUniqueCode())) {
|
||||
String redisKey = tenantId + ":" + CacheConstants.WALLET_DETAIL_USER_ID_WALLET_TYPE + "::" + wallet.getUserId() + ":" + wallet.getWalletTypeUniqueCode();
|
||||
stringRedisTemplate.delete(redisKey);
|
||||
}
|
||||
}
|
||||
|
||||
private void disposeList(List<WalletManageVo> list) {
|
||||
if (ObjectUtil.isNotEmpty(list)) {
|
||||
// 用户
|
||||
|
||||
+30
-2
@@ -6,9 +6,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.bsd.pjcloud.admin.api.dto.UserInfo;
|
||||
import com.bsd.pjcloud.admin.api.entity.SysUser;
|
||||
import com.bsd.pjcloud.admin.api.feign.RemoteUserService;
|
||||
import com.bsd.pjcloud.common.core.constant.enums.MerchantTypeEnum;
|
||||
import com.bsd.pjcloud.common.core.constant.CacheConstants;
|
||||
import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum;
|
||||
import com.bsd.pjcloud.common.core.util.BeanUtils;
|
||||
import com.bsd.pjcloud.common.data.tenant.TenantContextHolder;
|
||||
import com.bsd.pjcloud.wallet.api.constant.WalletXfjDiscountsEnum;
|
||||
import com.bsd.pjcloud.wallet.api.dto.WalletSettingDto;
|
||||
import com.bsd.pjcloud.wallet.api.entity.WalletSettingEntity;
|
||||
@@ -23,12 +24,19 @@ import com.bsd.pjcloud.wallet.service.WalletSettingService;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 支付设置
|
||||
@@ -40,6 +48,7 @@ import java.util.List;
|
||||
public class WalletSettingServiceImpl extends ServiceImpl<WalletSettingMapper, WalletSettingEntity> implements WalletSettingService {
|
||||
|
||||
private final MchManageService mchManageService;
|
||||
private final StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
private final RemoteUserService remoteUserService;
|
||||
|
||||
@@ -60,7 +69,7 @@ public class WalletSettingServiceImpl extends ServiceImpl<WalletSettingMapper, W
|
||||
SysUser sysUser = userInfo.getSysUser();
|
||||
|
||||
// 在自营食堂
|
||||
MchManageVo userMch = mchManageService.getFirstMchByDeptId(sysUser.getDeptId(), List.of(MerchantTypeEnum.CANTEEN));
|
||||
MchManageVo userMch = mchManageService.getViewsCanteenMchByDeptId(sysUser.getDeptId());
|
||||
boolean isSelfCatering = ObjectUtil.isNotEmpty(userMch);
|
||||
|
||||
List<WalletSettingEntity.WalletXfjDiscounts> list = new ArrayList<>();
|
||||
@@ -86,6 +95,7 @@ public class WalletSettingServiceImpl extends ServiceImpl<WalletSettingMapper, W
|
||||
list = setting.getFzbDefaultXfjDiscounts();
|
||||
}
|
||||
}
|
||||
list = list.stream().filter(item -> ObjectUtil.isNotEmpty(item.getEnable()) && ObjectUtil.equals(YesNoEnum.YES.getCode(), item.getEnable())).toList();
|
||||
if (ObjectUtil.isNotEmpty(list)) {
|
||||
discountsList.addAll(
|
||||
list.stream().map(item -> {
|
||||
@@ -124,6 +134,24 @@ public class WalletSettingServiceImpl extends ServiceImpl<WalletSettingMapper, W
|
||||
}
|
||||
WalletSettingEntity updateObj = BeanUtils.toBean(dto, WalletSettingEntity.class);
|
||||
baseMapper.updateById(updateObj);
|
||||
deleteAllDiscountsCacheByUserId();
|
||||
}
|
||||
|
||||
public void deleteAllDiscountsCacheByUserId() {
|
||||
String pattern = TenantContextHolder.getTenantId() + ":" + CacheConstants.WALLET_USER_DISCOUNTS_LIST + "::" + "*";
|
||||
Set<String> keys = new HashSet<>();
|
||||
stringRedisTemplate.execute((RedisCallback<Void>) connection -> {
|
||||
Cursor<byte[]> cursor = connection.scan(
|
||||
ScanOptions.scanOptions().match(pattern).count(1000).build()
|
||||
);
|
||||
while (cursor.hasNext()) {
|
||||
keys.add(new String(cursor.next(), StandardCharsets.UTF_8));
|
||||
}
|
||||
return null;
|
||||
});
|
||||
if (!keys.isEmpty()) {
|
||||
stringRedisTemplate.delete(keys);
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
|
||||
+29
@@ -36,12 +36,16 @@ import com.bsd.pjcloud.wallet.api.entity.WalletTypeEntity;
|
||||
import com.bsd.pjcloud.wallet.api.utils.WalletDataUtil;
|
||||
import com.bsd.pjcloud.wallet.api.vo.MchManageVo;
|
||||
import com.bsd.pjcloud.wallet.api.vo.code.MchCollectionCodeVo;
|
||||
import com.bsd.pjcloud.wallet.api.vo.mch.WalletMchDeptViewVo;
|
||||
import com.bsd.pjcloud.wallet.mapper.MchManageMapper;
|
||||
import com.bsd.pjcloud.wallet.mapper.WalletTypeMapper;
|
||||
import com.bsd.pjcloud.wallet.mapper.mch.view.MchDeptViewMapper;
|
||||
import com.bsd.pjcloud.wallet.service.MchManageService;
|
||||
import com.bsd.pjcloud.wallet.service.WalletThirdZyService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
@@ -82,6 +86,7 @@ public class MchManageServiceImpl extends ServiceImpl<MchManageMapper, MchManage
|
||||
@Lazy
|
||||
private final WalletThirdZyService walletThirdZyService;
|
||||
private final WalletTypeMapper walletTypeMapper;
|
||||
private final MchDeptViewMapper mchDeptViewMapper;
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
|
||||
@@ -121,6 +126,12 @@ public class MchManageServiceImpl extends ServiceImpl<MchManageMapper, MchManage
|
||||
|
||||
@Override
|
||||
// @CacheEvict(value = CacheConstants.WALLET_MCH, key = "#dto.getId()", condition = "#dto.getId() != null")
|
||||
@CacheEvict(
|
||||
value = CacheConstants.WALLET_VIEWS_CANTEEN_MCH,
|
||||
key = "#dto.getDeptId()",
|
||||
condition = "#dto.getDeptId() != null",
|
||||
beforeInvocation = true
|
||||
)
|
||||
public void edit(MchManageEntity dto) {
|
||||
if (existName(dto.getName(), dto.getTypes(), dto.getId())) {
|
||||
throw new RuntimeException("商户名不能重复");
|
||||
@@ -311,6 +322,24 @@ public class MchManageServiceImpl extends ServiceImpl<MchManageMapper, MchManage
|
||||
return getFirstMch(deptIds, mchTypeList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从视图里获取食堂商户信息
|
||||
*/
|
||||
@Override
|
||||
@Cacheable(
|
||||
value = CacheConstants.WALLET_VIEWS_CANTEEN_MCH + "#3600",
|
||||
key = "#deptId",
|
||||
condition = "#deptId != null",
|
||||
unless = "#result == null"
|
||||
)
|
||||
public MchManageVo getViewsCanteenMchByDeptId(Long deptId) {
|
||||
WalletMchDeptViewVo walletMchDeptView = mchDeptViewMapper.selectByDeptId(deptId);
|
||||
if (ObjectUtil.isEmpty(walletMchDeptView) || ObjectUtil.isEmpty(walletMchDeptView.getDeptId())) {
|
||||
return null;
|
||||
}
|
||||
return baseMapper.join(walletMchDeptView.getMchId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新商户二维码
|
||||
*/
|
||||
|
||||
+72
-28
@@ -67,12 +67,12 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -415,42 +415,86 @@ public class WalletRechargeInvoiceServiceImpl extends ServiceImpl<WalletRecharge
|
||||
if (ObjectUtil.isEmpty(imageBaseUrl)) {
|
||||
throw new RuntimeException("请配置图片基础路径");
|
||||
}
|
||||
if (ObjectUtil.isEmpty(invoice.getPicUrl())) {
|
||||
log.error("|{}|盖章失败,发票图片为空,invoice:|{}|", TAG, JSONUtil.toJsonStr(invoice));
|
||||
return null;
|
||||
}
|
||||
// 开始盖章
|
||||
String picUrl = String.format("%s%s", imageBaseUrl, invoice.getPicUrl());
|
||||
// 发票底图宽高 3969 x 2154
|
||||
int baseMapWidth = 3969, baseMapHeight = 2154;
|
||||
// 盖章图片宽高
|
||||
int stampOrgWidth = 600, stampOrgHeight = 600;
|
||||
String picUrl = invoice.getPicUrl();
|
||||
if (!picUrl.startsWith("http://") && !picUrl.startsWith("https://")) {
|
||||
if (imageBaseUrl.endsWith("/") && picUrl.startsWith("/")) {
|
||||
picUrl = imageBaseUrl + picUrl.substring(1);
|
||||
} else if (!imageBaseUrl.endsWith("/") && !picUrl.startsWith("/")) {
|
||||
picUrl = imageBaseUrl + "/" + picUrl;
|
||||
} else {
|
||||
picUrl = imageBaseUrl + picUrl;
|
||||
}
|
||||
}
|
||||
int stampWidth = 500, stampHeight = 500;
|
||||
try {
|
||||
// 读取底图
|
||||
BufferedImage baseImage = ImageIO.read(new URL(picUrl));
|
||||
URLConnection connection = new URL(picUrl).openConnection();
|
||||
connection.setConnectTimeout(5000);
|
||||
connection.setReadTimeout(5000);
|
||||
BufferedImage baseImage;
|
||||
try (InputStream inputStream = connection.getInputStream()) {
|
||||
baseImage = ImageIO.read(inputStream);
|
||||
}
|
||||
if (ObjectUtil.isEmpty(baseImage)) {
|
||||
log.error("|{}|盖章失败,底图解析失败,picUrl:|{}|invoice:|{}|", TAG, picUrl, JSONUtil.toJsonStr(invoice));
|
||||
return null;
|
||||
}
|
||||
// 读取盖章图片
|
||||
BufferedImage stampImage = ImageIO.read(ResourceUtil.getResource("image/receiptStamp.png"));
|
||||
stampImage.getScaledInstance(stampWidth, stampHeight, Image.SCALE_SMOOTH);
|
||||
BufferedImage stampImage;
|
||||
try (InputStream inputStream = ResourceUtil.getStream("image/receiptStamp.png")) {
|
||||
stampImage = ImageIO.read(inputStream);
|
||||
}
|
||||
if (ObjectUtil.isEmpty(stampImage)) {
|
||||
log.error("|{}|盖章失败,盖章图片资源不存在,invoice:|{}|", TAG, JSONUtil.toJsonStr(invoice));
|
||||
return null;
|
||||
}
|
||||
BufferedImage scaledStamp = new BufferedImage(stampWidth, stampHeight, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D stampG2d = scaledStamp.createGraphics();
|
||||
stampG2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
stampG2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
stampG2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
stampG2d.drawImage(stampImage, 0, 0, stampWidth, stampHeight, null);
|
||||
stampG2d.dispose();
|
||||
// 创建新的图像上下文
|
||||
Graphics2D g2d = baseImage.createGraphics();
|
||||
// 设置抗锯齿
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
int baseMapWidth = baseImage.getWidth();
|
||||
int baseMapHeight = baseImage.getHeight();
|
||||
int x = (int) (stampWidth + baseMapWidth * 0.15 + 80);
|
||||
int y = baseMapHeight - stampHeight - 50;
|
||||
g2d.drawImage(stampImage, x, y, stampWidth, stampHeight, null);
|
||||
x = Math.max(0, Math.min(x, baseMapWidth - stampWidth));
|
||||
y = Math.max(0, Math.min(y, baseMapHeight - stampHeight));
|
||||
g2d.drawImage(scaledStamp, x, y, null);
|
||||
g2d.dispose();
|
||||
String newPicUrl = invoice.getPicUrl().replaceFirst("(\\.\\w+)$", "_stamped$1");
|
||||
File tempFile = File.createTempFile(newPicUrl, ".png");
|
||||
ImageIO.write(baseImage, "PNG", tempFile);
|
||||
// 保存到本地用于测试
|
||||
// ImageIO.write(baseImage, "PNG", new File("test.png"));
|
||||
|
||||
// 上传图片
|
||||
MultipartFile multipartFile = new MockMultipartFile("file", newPicUrl, "image/png", new FileInputStream(tempFile));
|
||||
R upload = remoteFileService.innerUpload(multipartFile, null, null, null);
|
||||
Map data = (Map) upload.getData();
|
||||
String url = (String) data.get("url");
|
||||
return url;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error("|{}|盖章失败,IO异常,invoice:|{}|error:|{}|", TAG, JSONUtil.toJsonStr(invoice), e.getMessage());
|
||||
String fileName = "invoice_stamped_" + invoice.getId() + ".png";
|
||||
byte[] imageBytes;
|
||||
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
||||
ImageIO.write(baseImage, "PNG", outputStream);
|
||||
imageBytes = outputStream.toByteArray();
|
||||
}
|
||||
MultipartFile multipartFile = new MockMultipartFile("file", fileName, "image/png", imageBytes);
|
||||
R<?> upload = remoteFileService.innerUpload(multipartFile, null, null, null);
|
||||
if (ObjectUtil.isEmpty(upload) || !upload.isOk() || ObjectUtil.isEmpty(upload.getData())) {
|
||||
log.error("|{}|盖章失败,上传失败,upload:|{}|invoice:|{}|", TAG, JSON.toJSONString(upload), JSONUtil.toJsonStr(invoice));
|
||||
return null;
|
||||
}
|
||||
Object dataObj = upload.getData();
|
||||
if (!(dataObj instanceof Map<?, ?> data)) {
|
||||
log.error("|{}|盖章失败,上传返回结构异常,data:|{}|invoice:|{}|", TAG, JSON.toJSONString(dataObj), JSONUtil.toJsonStr(invoice));
|
||||
return null;
|
||||
}
|
||||
Object urlObj = data.get("url");
|
||||
return ObjectUtil.isEmpty(urlObj) ? null : String.valueOf(urlObj);
|
||||
} catch (Exception e) {
|
||||
log.error("|{}|盖章失败,异常,invoice:|{}|", TAG, JSONUtil.toJsonStr(invoice), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -582,4 +626,4 @@ public class WalletRechargeInvoiceServiceImpl extends ServiceImpl<WalletRecharge
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-2
@@ -52,6 +52,14 @@
|
||||
order by a.mchDeptId, a.level
|
||||
</select>
|
||||
|
||||
<select id="selectByUserId" resultType="com.bsd.pjcloud.wallet.api.vo.mch.WalletMchDeptViewVo">
|
||||
|
||||
<select id="selectByDeptId" resultType="com.bsd.pjcloud.wallet.api.vo.mch.WalletMchDeptViewVo">
|
||||
<include refid="selectA"/>
|
||||
from v_mch_dept_tree a
|
||||
<where>
|
||||
and a.deptId = #{deptId}
|
||||
</where>
|
||||
order by a.level asc
|
||||
limit 1
|
||||
</select>
|
||||
</mapper>
|
||||
</mapper>
|
||||
@@ -22,7 +22,7 @@ public class InvoiceTest {
|
||||
@Test
|
||||
@Transactional
|
||||
public void test() {
|
||||
WalletRechargeInvoiceEntity detail = invoiceService.getById(1937849346822692865L);
|
||||
WalletRechargeInvoiceEntity detail = invoiceService.getById(2054386187932225537L);
|
||||
if (ObjectUtil.isNotEmpty(detail)) {
|
||||
invoiceService.stamp(detail);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user