parent
6cc0da2ed0
commit
49ec7ab65d
|
|
@ -17,14 +17,19 @@ package cn.ysk.cashier.utils;
|
|||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.poi.excel.BigExcelWriter;
|
||||
import cn.hutool.poi.excel.ExcelUtil;
|
||||
import cn.hutool.poi.excel.ExcelWriter;
|
||||
import cn.ysk.cashier.exception.BadRequestException;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.xssf.streaming.SXSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
|
@ -154,7 +159,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
|
|||
/**
|
||||
* inputStream 转 File
|
||||
*/
|
||||
static File inputStreamToFile(InputStream ins, String name){
|
||||
static File inputStreamToFile(InputStream ins, String name) {
|
||||
File file = new File(SYS_TEM_DIR + name);
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
|
|
@ -215,7 +220,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
|
|||
BigExcelWriter writer = ExcelUtil.getBigWriter(file);
|
||||
// 一次性写出内容,使用默认样式,强制输出标题
|
||||
writer.write(list, true);
|
||||
SXSSFSheet sheet = (SXSSFSheet)writer.getSheet();
|
||||
SXSSFSheet sheet = (SXSSFSheet) writer.getSheet();
|
||||
//上面需要强转SXSSFSheet 不然没有trackAllColumnsForAutoSizing方法
|
||||
sheet.trackAllColumnsForAutoSizing();
|
||||
//列宽自适应
|
||||
|
|
@ -232,29 +237,71 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
|
|||
IoUtil.close(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* 输入标题到excel
|
||||
*
|
||||
* @param writer excel对象
|
||||
* @param column 当前列位置
|
||||
* @param cellValue 标题内容
|
||||
* @param requiredFlag 是否标红
|
||||
*/
|
||||
private static void writeCell(ExcelWriter writer, int column, int row, String cellValue, boolean requiredFlag) {
|
||||
// 根据x,y轴设置单元格内容
|
||||
if (StrUtil.isNotBlank(cellValue)) {
|
||||
writer.writeCellValue(column, row, cellValue);
|
||||
}
|
||||
Font font = writer.createFont();
|
||||
font.setColor(Font.COLOR_RED);
|
||||
if (requiredFlag) {
|
||||
// 根据x,y轴获取当前单元格样式
|
||||
CellStyle cellStyle = writer.createCellStyle(column, row);
|
||||
// 内容水平居中
|
||||
cellStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||
// 内容垂直居中
|
||||
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
// 设置边框
|
||||
cellStyle.setBorderBottom(BorderStyle.THIN);
|
||||
cellStyle.setBorderLeft(BorderStyle.THIN);
|
||||
cellStyle.setBorderRight(BorderStyle.THIN);
|
||||
// 字体颜色标红
|
||||
// cellStyle.setFont(font);
|
||||
cellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
|
||||
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
}
|
||||
}
|
||||
|
||||
public static void downloadExcelAndMerge(List<Map<String, Object>> list, int colSize, HttpServletResponse response, ArrayList<Integer> mergeRowIndex) throws IOException {
|
||||
String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx";
|
||||
File file = new File(tempPath);
|
||||
BigExcelWriter writer = ExcelUtil.getBigWriter(file);
|
||||
|
||||
// 合并单元格后的标题行,使用默认标题样式.
|
||||
ExcelWriter writer = ExcelUtil.getWriter(file);
|
||||
for (int i = 0; i < mergeRowIndex.size(); i++) {
|
||||
System.out.println(i);
|
||||
|
||||
int start = i == 0 ? 1 : mergeRowIndex.get(i - 1) + 1;
|
||||
for (int i1 = 0; i1 < colSize; i1++) {
|
||||
writer.merge(i == 0 ? 0 : mergeRowIndex.get(i - 1) + 1, mergeRowIndex.get(i), i1, i1, "", true);
|
||||
|
||||
if (start != mergeRowIndex.get(i)) {
|
||||
writer.merge(i == 0 ? 1 : mergeRowIndex.get(i - 1) + 1, mergeRowIndex.get(i), i1, i1, "", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 一次性写出内容,使用默认样式,强制输出标题
|
||||
writer.write(list, true);
|
||||
SXSSFSheet sheet = (SXSSFSheet)writer.getSheet();
|
||||
|
||||
XSSFSheet sheet = (XSSFSheet) writer.getSheet();
|
||||
// 设置列宽
|
||||
for (int i = 0; i < colSize + 2; i++) {
|
||||
sheet.setColumnWidth(i, 4000); // 200个字符宽度
|
||||
}
|
||||
//上面需要强转SXSSFSheet 不然没有trackAllColumnsForAutoSizing方法
|
||||
sheet.trackAllColumnsForAutoSizing();
|
||||
// sheet.trackAllColumnsForAutoSizing();
|
||||
//列宽自适应
|
||||
writer.autoSizeColumnAll();
|
||||
// writer.autoSizeColumnAll();
|
||||
//response为HttpServletResponse对象
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
|
||||
//test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
|
||||
response.setHeader("Content-Disposition", "attachment;filename=file.xlsx");
|
||||
// 将写入的Excel作为文件流写出到response
|
||||
ServletOutputStream out = response.getOutputStream();
|
||||
// 终止后删除临时文件
|
||||
file.deleteOnExit();
|
||||
|
|
@ -295,7 +342,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
|
|||
public static boolean check(File file1, File file2) {
|
||||
String img1Md5 = getMd5(file1);
|
||||
String img2Md5 = getMd5(file2);
|
||||
if(img1Md5 != null){
|
||||
if (img1Md5 != null) {
|
||||
return img1Md5.equals(img2Md5);
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
package cn.ysk.cashier.controller.product;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.ysk.cashier.annotation.AnonymousAccess;
|
||||
import cn.ysk.cashier.annotation.Log;
|
||||
import cn.ysk.cashier.annotation.rest.AnonymousPostMapping;
|
||||
import cn.ysk.cashier.dto.product.StockQueryDto;
|
||||
import cn.ysk.cashier.exception.BadRequestException;
|
||||
import cn.ysk.cashier.service.product.StockService;
|
||||
import cn.ysk.cashier.utils.BeanUtil;
|
||||
import cn.ysk.cashier.utils.SecurityUtils;
|
||||
import cn.ysk.cashier.vo.StockPageImpl;
|
||||
import cn.ysk.cashier.vo.StockUpdateValueVO;
|
||||
import cn.ysk.cashier.vo.StockUpdateWarnLineVO;
|
||||
import cn.ysk.cashier.vo.StockV2Vo;
|
||||
|
|
@ -18,15 +14,12 @@ import io.swagger.annotations.ApiOperation;
|
|||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
package cn.ysk.cashier.mybatis.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 商家openid信息表
|
||||
* @TableName tb_shop_open_id
|
||||
*/
|
||||
@Table(name="tb_shop_open_id")
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
public class TbShopOpenId implements Serializable {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 店铺id
|
||||
*/
|
||||
private Integer shopId;
|
||||
|
||||
/**
|
||||
* 已经订阅消息的商家微信号
|
||||
*/
|
||||
private String openId;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 类型 -1 任意消息 0库存预警
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package cn.ysk.cashier.mybatis.mapper;
|
||||
|
||||
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【tb_shop_open_id(商家openid信息表)】的数据库操作Mapper
|
||||
* @createDate 2024-08-02 10:00:27
|
||||
* @Entity cn.ysk.cashier.mybatis.entity.TbShopOpenId
|
||||
*/
|
||||
public interface TbShopOpenIdMapper extends BaseMapper<TbShopOpenId> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package cn.ysk.cashier.mybatis.service;
|
||||
|
||||
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【tb_shop_open_id(商家openid信息表)】的数据库操作Service
|
||||
* @createDate 2024-08-02 10:00:27
|
||||
*/
|
||||
public interface TbShopOpenIdService extends IService<TbShopOpenId> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package cn.ysk.cashier.mybatis.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
|
||||
import cn.ysk.cashier.mybatis.service.TbShopOpenIdService;
|
||||
import cn.ysk.cashier.mybatis.mapper.TbShopOpenIdMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【tb_shop_open_id(商家openid信息表)】的数据库操作Service实现
|
||||
* @createDate 2024-08-02 10:00:27
|
||||
*/
|
||||
@Service
|
||||
public class TbShopOpenIdServiceImpl extends ServiceImpl<TbShopOpenIdMapper, TbShopOpenId>
|
||||
implements TbShopOpenIdService{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -62,4 +62,6 @@ public interface TbProductRepository extends JpaRepository<TbProduct, Integer>,
|
|||
@Query("select product from TbProduct product where product.shopId=:shopId")
|
||||
List<TbProduct> selectByShopId(String shopId);
|
||||
|
||||
@Query(value = "select b.* from tb_product_sku as a left join tb_product as b on a.product_id=b.id where a.id=:skuId", nativeQuery = true)
|
||||
TbProduct selectBySkuId(@Param("skuId") Integer skuId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -467,7 +467,7 @@ public class SummaryServiceImpl implements SummaryService {
|
|||
});
|
||||
|
||||
}
|
||||
FileUtil.downloadExcelAndMerge(list, 12, response, mergeRowIndex);
|
||||
FileUtil.downloadExcelAndMerge(list, 10, response, mergeRowIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@ import cn.ysk.cashier.repository.shop.TbShopUnitRepository;
|
|||
import cn.ysk.cashier.service.TbProductStockOperateService;
|
||||
import cn.ysk.cashier.service.product.StockService;
|
||||
import cn.ysk.cashier.service.product.TbProductService;
|
||||
import cn.ysk.cashier.utils.CacheKey;
|
||||
import cn.ysk.cashier.utils.FileUtil;
|
||||
import cn.ysk.cashier.utils.RedisUtils;
|
||||
import cn.ysk.cashier.utils.StringUtils;
|
||||
import cn.ysk.cashier.utils.*;
|
||||
import cn.ysk.cashier.vo.StockUpdateValueVO;
|
||||
import cn.ysk.cashier.vo.StockUpdateWarnLineVO;
|
||||
import cn.ysk.cashier.vo.StockV2Vo;
|
||||
|
|
@ -62,6 +59,7 @@ public class StockServiceImpl implements StockService {
|
|||
private final TbShopUnitRepository shopUnitRepository;
|
||||
private final TbProductStockDetailRepository tbProductStockDetailRepository;
|
||||
private final TbProductRepository tbProductRepository;
|
||||
private final WxMsgUtils wxMsgUtils;
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
|
|
@ -349,6 +347,15 @@ public class StockServiceImpl implements StockService {
|
|||
|
||||
Query nativeQuery = em.createNativeQuery(String.valueOf(sqlQuery));
|
||||
nativeQuery.executeUpdate();
|
||||
|
||||
TbProduct product = tbProductRepository.selectBySkuId(Integer.valueOf(updateValueVO.getTargetId()));
|
||||
TbProductSku tbProductSku = tbProductSkuRepository.findById(Integer.valueOf(updateValueVO.getTargetId())).orElse(null);
|
||||
// 推送微信操作消息
|
||||
if (product != null && tbProductSku != null) {
|
||||
wxMsgUtils.aboardOperationMsg(("0".equals(updateValueVO.getUpdateValue()) ? "关闭sku售罄: " : "开启sku售罄: ") + product.getName() + "/"+ tbProductSku.getSpecSnap());
|
||||
}else {
|
||||
log.warn("推送微信操作消息失败,未查询到商品信息,skuId: {}", updateValueVO.getTargetId());
|
||||
}
|
||||
return;
|
||||
case "stock":
|
||||
sqlQuery.append(" set is_stock = ").append(updateValueVO.getUpdateValue());
|
||||
|
|
@ -358,6 +365,13 @@ public class StockServiceImpl implements StockService {
|
|||
break;
|
||||
case "pauseSale":
|
||||
sqlQuery.append(" set is_pause_sale = ").append(updateValueVO.getUpdateValue());
|
||||
TbProduct product1 = tbProductRepository.selectBySkuId(Integer.valueOf(updateValueVO.getTargetId()));
|
||||
// 推送微信操作消息
|
||||
if (product1 != null) {
|
||||
wxMsgUtils.aboardOperationMsg(("0".equals(updateValueVO.getUpdateValue()) ? "关闭售罄: " : "开启售罄: ") + product1.getName());
|
||||
}else {
|
||||
log.warn("推送微信操作消息失败,未查询到商品信息,skuId: {}", updateValueVO.getTargetId());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new BadRequestException("无效更新类型");
|
||||
|
|
@ -393,7 +407,10 @@ public class StockServiceImpl implements StockService {
|
|||
if (tbProductSku == null) {
|
||||
throw new BadRequestException("商品不存在,skuId: " + skuId);
|
||||
}
|
||||
|
||||
TbProduct product = tbProductRepository.selectByShopIdAndId(Integer.parseInt(tbProductSku.getProductId()), String.valueOf(shopId));
|
||||
// 推送微信操作消息
|
||||
wxMsgUtils.aboardOperationMsg((isGrounding ? "上架商品: " : "下架商品: ") + product.getName());
|
||||
// 共享库存下架所有sku
|
||||
if (product.getIsDistribute().equals(1)) {
|
||||
tbProductSkuRepository.updateGroundingByProId(product.getId().toString(), isGrounding ? 1 : 0);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ public class TbProductGroupServiceImpl implements TbProductGroupService {
|
|||
private final TbProductGroupRepository tbProductGroupRepository;
|
||||
private final TbProductGroupMapper tbProductGroupMapper;
|
||||
private final TbProductRepository tbProductRepository;
|
||||
private final WxMsgUtils wxMsgUtils;
|
||||
|
||||
@Resource
|
||||
private OnlineUserService onlineUserService;
|
||||
|
|
@ -104,6 +105,9 @@ public class TbProductGroupServiceImpl implements TbProductGroupService {
|
|||
ValidationUtil.isNull( tbProductGroup.getId(),"TbProductGroup","id",resources.getId());
|
||||
tbProductGroup.copy(resources);
|
||||
tbProductGroupRepository.save(tbProductGroup);
|
||||
|
||||
// 推送微信操作消息
|
||||
wxMsgUtils.aboardOperationMsg((resources.getIsShow() == 0 ? "关闭分组: " : "开启分组: ") + tbProductGroup.getName());
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
|
|
@ -224,4 +228,4 @@ public class TbProductGroupServiceImpl implements TbProductGroupService {
|
|||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ public class TbProductStocktakinServiceImpl implements TbProductStocktakinServic
|
|||
|
||||
|
||||
round = (int) Math.floor( productSku.getStockNumber());
|
||||
productStockDetail.setSpecSnap(productSku.getSpecSnap());
|
||||
|
||||
productStockDetail.setSubType(productStocktakinDTO.getStocktakinNum() > productSku.getStockNumber() ? 1 : -1);
|
||||
stockOperate.setType(productStocktakinDTO.getStocktakinNum() > productSku.getStockNumber() ? "盘点入库" : "盘点出库");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,126 @@
|
|||
package cn.ysk.cashier.utils;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@Slf4j
|
||||
@Component
|
||||
public class WxAccountUtil {
|
||||
@Value("${wx.ysk.appId}")
|
||||
private String appId = "wx212769170d2c6b2a";
|
||||
@Value("${wx.ysk.secrete}")
|
||||
private String secrete = "8492a7e8d55bbb1b57f5c8276ea1add0";
|
||||
@Value("${wx.ysk.operationMsgTmpId}")
|
||||
private String operationMsgTmpId ;
|
||||
|
||||
static LinkedHashMap<String,String> linkedHashMap=new LinkedHashMap<>();
|
||||
|
||||
static {
|
||||
|
||||
linkedHashMap.put("40001","获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口");
|
||||
linkedHashMap.put("40003","不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID");
|
||||
linkedHashMap.put("40014","不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口");
|
||||
linkedHashMap.put("40037","不合法的 template_id");
|
||||
linkedHashMap.put("43101","用户未订阅消息");
|
||||
linkedHashMap.put("43107","订阅消息能力封禁");
|
||||
linkedHashMap.put("43108","并发下发消息给同一个粉丝");
|
||||
linkedHashMap.put("45168","命中敏感词");
|
||||
linkedHashMap.put("47003","参数错误");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// sendStockWarnMsg("13213", "31123", "234", "ojC-S6n2DDlpj52iVMoiLL0Ry4HI");
|
||||
}
|
||||
|
||||
public String getRadarQrCode(Integer shopId) {
|
||||
HashMap<String, Object> req = new HashMap<>();
|
||||
req.put("expire_seconds", 300);
|
||||
req.put("action_name", "QR_STR_SCENE");
|
||||
HashMap<Object, Object> actionInfo = new HashMap<>();
|
||||
HashMap<String, Object> scene = new HashMap<>();
|
||||
scene.put("scene_str", "msg" + shopId);
|
||||
actionInfo.put("scene", scene);
|
||||
req.put("action_info", actionInfo);
|
||||
log.info("开始获取公众号二维码, 请求数据: {}", req);
|
||||
String resp = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + getAccessToken(), JSONObject.toJSONString(req));
|
||||
JSONObject respInfo = JSONObject.parseObject(resp);
|
||||
log.warn("获取微信公众号二维码结束,响应: {}", resp);
|
||||
if (!respInfo.containsKey("url")) {
|
||||
log.warn("获取微信公众号二维码失败,响应: {}", resp);
|
||||
throw new RuntimeException(resp);
|
||||
}
|
||||
return respInfo.getString("url");
|
||||
}
|
||||
|
||||
|
||||
public String getAccessToken() {
|
||||
String resp = HttpUtil.get(StrUtil.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}", appId, secrete));
|
||||
JSONObject respInfo = JSONObject.parseObject(resp);
|
||||
if (!respInfo.containsKey("access_token")) {
|
||||
log.warn("公众号获取token失败, 响应内容: {}", resp);
|
||||
throw new RuntimeException(resp);
|
||||
}
|
||||
return respInfo.getString("access_token");
|
||||
}
|
||||
|
||||
public JSONObject sendTemplateMsg(String templateId, String toUserOpenId, Map<String, Object> data) {
|
||||
log.info("开始发送微信模板消息, 接收用户openId: {}, 消息数据: {}", toUserOpenId, data);
|
||||
String accessToken = getAccessToken();
|
||||
|
||||
JSONObject object1=new JSONObject();
|
||||
|
||||
object1.put("template_id", templateId);
|
||||
object1.put("touser", toUserOpenId);
|
||||
object1.put("data",data);
|
||||
|
||||
String response= HttpRequest.post("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".concat(accessToken)).body(object1.toString()).execute().body();
|
||||
log.info("微信模板消息发送成功,响应内容:{}",response);
|
||||
JSONObject resObj=JSONObject.parseObject(response);
|
||||
if(ObjectUtil.isNotEmpty(resObj)&&ObjectUtil.isNotNull(resObj)&&"0".equals(resObj.get("errcode")+"")){
|
||||
return resObj;
|
||||
}
|
||||
|
||||
throw new RuntimeException(linkedHashMap.getOrDefault(resObj.get("errcode") + "", "未知错误"));
|
||||
}
|
||||
|
||||
@Async
|
||||
public void sendOperationMsg(List<TbShopOpenId> openIds, String userName, String operationDesc) {
|
||||
openIds.forEach(item -> {
|
||||
Map<String, Object> data = new HashMap<String, Object>() {{
|
||||
put("thing19", new HashMap<String, Object>(){{
|
||||
put("value", userName);
|
||||
}});
|
||||
put("thing8", new HashMap<String, Object>(){{
|
||||
put("value", operationDesc);
|
||||
}});
|
||||
put("time21", new HashMap<String, Object>(){{
|
||||
put("value", DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
|
||||
}});
|
||||
}};
|
||||
log.info("开始发送敏感操作消息, 接收用户openId: {}, 操作用户: {}, 操作描述: {}", item.getOpenId(), userName, operationDesc);
|
||||
try {
|
||||
sendTemplateMsg(operationMsgTmpId, item.getOpenId(), data);
|
||||
}catch (Exception e) {
|
||||
log.error("发送失败, openId: {}, 响应: {}", item.getOpenId(), e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package cn.ysk.cashier.utils;
|
||||
|
||||
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
|
||||
import cn.ysk.cashier.mybatis.service.TbShopOpenIdService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class WxMsgUtils {
|
||||
|
||||
private final TbShopOpenIdService tbShopOpenIdService;
|
||||
|
||||
private final RedisUtils redisUtils;
|
||||
|
||||
private final WxAccountUtil wxAccountUtil;
|
||||
|
||||
public WxMsgUtils(TbShopOpenIdService tbShopOpenIdService, RedisUtils redisUtils, WxAccountUtil wxAccountUtil) {
|
||||
this.tbShopOpenIdService = tbShopOpenIdService;
|
||||
this.redisUtils = redisUtils;
|
||||
this.wxAccountUtil = wxAccountUtil;
|
||||
}
|
||||
|
||||
public void aboardOperationMsg(String operationDesc) {
|
||||
HttpServletRequest request = RequestHolder.getHttpServletRequest();
|
||||
|
||||
Object o = redisUtils.get("online-token-"+getToken(request));
|
||||
JSONObject jsonObject;
|
||||
Integer shopId;
|
||||
String nickName;
|
||||
if (o != null) {
|
||||
String jsonString = JSON.toJSONString(o);
|
||||
jsonObject = JSONObject.parseObject(jsonString);
|
||||
shopId = (Integer) jsonObject.get("shopId");
|
||||
nickName = jsonObject.get("nickName") == null ? "" : jsonObject.get("nickName").toString();
|
||||
List<TbShopOpenId> openIds = tbShopOpenIdService.lambdaQuery().eq(TbShopOpenId::getShopId, shopId).list();
|
||||
log.info("即将开始推送敏感操作消息, 接收推送openId列表: {}", openIds);
|
||||
String finalNickName = nickName;
|
||||
wxAccountUtil.sendOperationMsg(openIds, finalNickName, operationDesc);
|
||||
}else {
|
||||
log.warn("发送敏感操作预警失败,未获取到登录信息");
|
||||
}
|
||||
}
|
||||
|
||||
public String getToken(HttpServletRequest request) {
|
||||
final String requestHeader = request.getHeader("Authorization");
|
||||
if (requestHeader != null && requestHeader.startsWith("Bearer")) {
|
||||
return requestHeader.substring(7);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package cn.ysk.cashier.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class TbOrderSaleVO {
|
||||
private String orderNo;
|
||||
private Integer num;
|
||||
private BigDecimal price;
|
||||
private String status;
|
||||
}
|
||||
|
|
@ -78,3 +78,9 @@ aliyun:
|
|||
oss:
|
||||
bucketname: cashier-oss
|
||||
endpoint: oss-cn-beijing.aliyuncs.com
|
||||
|
||||
wx:
|
||||
ysk:
|
||||
appId: wx212769170d2c6b2a
|
||||
secrete: 8492a7e8d55bbb1b57f5c8276ea1add0
|
||||
operationMsgTmpId: wFdoUG-dUT7bDRHq8bMJD9CF5TjyH9x_uJQgQByZqHg
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
<?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.ysk.cashier.mybatis.mapper.TbShopOpenIdMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="cn.ysk.cashier.mybatis.entity.TbShopOpenId">
|
||||
<id property="id" column="id" jdbcType="INTEGER"/>
|
||||
<result property="shop_id" column="shop_id" jdbcType="INTEGER"/>
|
||||
<result property="open_id" column="open_id" jdbcType="VARCHAR"/>
|
||||
<result property="status" column="status" jdbcType="INTEGER"/>
|
||||
<result property="create_time" column="create_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="update_time" column="update_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="type" column="type" jdbcType="TINYINT"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id,shop_id,open_id,
|
||||
status,create_time,update_time,
|
||||
type
|
||||
</sql>
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue