提交 efb77995 authored 作者: lvbencai's avatar lvbencai

合并分支 'qa' 到 'master'

增加18:15任务和pos任务,增加导出多维表格三列 查看合并请求 !51
......@@ -7,13 +7,12 @@
<parent>
<groupId>com.wangxiaolu</groupId>
<artifactId>wangxiaolu-promotion-parent</artifactId>
<version>0.0.3</version>
<version>0.0.4</version>
</parent>
<groupId>com.wangxiaolu</groupId>
<artifactId>wangxiaolu-promotion-service</artifactId>
<version>0.2.0</version>
<version>0.2.1</version>
<name>wangxiaolu-promotion-service</name>
<description>promotion-service</description>
......@@ -24,7 +23,7 @@
<dependency>
<groupId>com.wangxiaolu</groupId>
<artifactId>wangxiaolu-promotion-common</artifactId>
<version>0.0.3</version>
<version>0.0.4</version>
<exclusions>
<exclusion>
<artifactId>spring-cloud-gateway-server</artifactId>
......@@ -90,10 +89,10 @@
</dependency>
<!-- Web 场景启动器) 来为 Web 开发予以支持。spring-boot-starter-web 为我们提供了嵌入的 Servlet 容器以及 SpringMVC 的依赖,并为 Spring MVC 提供了大量自动配置,可以适用于大多数 Web 开发场景。-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-web</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
......@@ -222,17 +221,18 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<!-- <version>${spring-cloud-gateway.version}</version>-->
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-web</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-gateway</artifactId>-->
<!--&lt;!&ndash; <version>${spring-cloud-gateway.version}</version>&ndash;&gt;-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <artifactId>spring-boot-starter-web</artifactId>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<dependency>
<groupId>com.fasterxml.uuid</groupId>
......@@ -252,6 +252,29 @@
<version>${aliyun.sts.version}</version>
</dependency>
<!-- pom.xml 中需包含以下依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-webflux</artifactId>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-tomcat</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<!-- Maven依赖示例 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.4</version> <!-- 与SpringBoot版本兼容的版本 -->
</dependency>
</dependencies>
<build>
......
......@@ -3,10 +3,9 @@ package com.wangxiaolu.promotion;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.context.request.RequestContextListener;
@EnableAsync
@EnableConfigurationProperties
......@@ -17,5 +16,4 @@ public class WangxiaoluPromotionServiceApplication {
public static void main(String[] args) {
SpringApplication.run(WangxiaoluPromotionServiceApplication.class, args);
}
}
package com.wangxiaolu.promotion.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
package com.wangxiaolu.promotion.config;
import com.wangxiaolu.promotion.websocket.JwtHandshakeInterceptor;
import com.wangxiaolu.promotion.websocket.TemporaryActivityTaskClockSocketHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.HandshakeInterceptor;
/**
* WebSocket配置类
* @author : lvbencai
* @date : 2024/4/16
*/
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry
// 注册WebSocket处理器和路径
.addHandler(webSocketHandler(), "/ws/temporary/plan")
// 允许跨域(根据实际前端域名配置)setAllowedOriginPatterns
.setAllowedOrigins("*")
// 添加握手拦截器(用于JWT验证)
.addInterceptors(handshakeInterceptor());
}
@Bean
public TemporaryActivityTaskClockSocketHandler webSocketHandler() {
return new TemporaryActivityTaskClockSocketHandler();
}
@Bean
public HandshakeInterceptor handshakeInterceptor() {
return new JwtHandshakeInterceptor();
}
}
......@@ -76,13 +76,19 @@ public class TemporaryActivityClockCoreController {
return R.success();
}
/**
* 促销员-打卡(上班卡)
* @param clockVo
* @return
*/
@PostMapping("/today/v2/clock")
public R clockInTodayActivityV2(@RequestBody TemporaryClockVo clockVo) {
clockVo.validate();
Integer clockType = clockVo.getClockType();
boolean isClockIn = ClockType.TEMPORARY_CLOCK_IN.equals(clockType);
// 上班卡必需有促销计划ID
if (isClockIn && (Objects.isNull(clockVo.getPlanId()) || clockVo.getPlanId() <= 0)) {
if (isClockIn && Objects.isNull(clockVo.getPlanId())) {
throw new ParamException(RCode.NOT_CLOCK_STORE_ERROR, null);
}
// 非上班卡必需有打卡记录ID
......@@ -109,30 +115,32 @@ public class TemporaryActivityClockCoreController {
builderClockOutData(clockVo, dto, clockTime);
}
tempActivityClockCoreService.clockInTodayPlan(dto, clockType);
return R.success();
return R.success(dto);
}
/**
* 打卡照片更换
*
* @param clockVo 更换照片信息
* @return 是否成功
*/
@PutMapping("/today/clock/update")
public R updateClockPhoto(@RequestBody TemporaryClockVo clockVo) {
if (Objects.isNull(clockVo.getTemporaryId()) ||clockVo.getTemporaryId()<=0){
if (Objects.isNull(clockVo.getTemporaryId()) || clockVo.getTemporaryId() <= 0) {
throw new ParamException(RCode.LOGIN_PARAM_ERROR, null);
}
if (StringUtils.isBlank(clockVo.getClockPhoto())){
if (StringUtils.isBlank(clockVo.getClockPhoto())) {
throw new ParamException(RCode.NOT_CLOCK_PHOTO_ERROR, null);
}
long minuteBetween = DateUtil.between(clockVo.getLastClockTime(), new Date(), DateUnit.MINUTE);
if (minuteBetween > 30){
if (minuteBetween > 30) {
throw new ParamException(RCode.UPDATE_CLOCK_PHOTO_TIME_LONG_ERROR, null);
}
TemporaryClockDto dto = new TemporaryClockDto(clockVo.getId(),clockVo.getTemporaryId(),clockVo.getClockPhoto(),clockVo.getPhotoType());
TemporaryClockDto dto = new TemporaryClockDto(clockVo.getId(), clockVo.getTemporaryId(), clockVo.getClockPhoto(), clockVo.getPhotoType());
tempActivityClockCoreService.updateClockPhoto(dto);
return R.success();
}
......
......@@ -33,7 +33,7 @@ public class TemporaryActivityClockQueryController {
* 根据促销员id查询今日打卡信息
*/
@GetMapping("/{temporary_id}")
public R findTodayTemporaryClockByTemId(@PathVariable("temporary_id") Integer temporaryId) {
public R findTodayTemporaryClockByTemId(@PathVariable("temporary_id") Long temporaryId) {
if (Objects.isNull(temporaryId) || temporaryId < 1){
throw new DataException(RCode.DATA_NOT_HAVE_ERROR);
}
......@@ -50,7 +50,7 @@ public class TemporaryActivityClockQueryController {
* @return 打卡信息
*/
@GetMapping("/date")
public R findTemporaryClockByTemIdAndDate(Integer temporaryId, String createDate) {
public R findTemporaryClockByTemIdAndDate(Long temporaryId, String createDate) {
if (Objects.isNull(temporaryId) || temporaryId < 1 || StringUtils.isBlank(createDate)){
throw new DataException(RCode.DATA_NOT_HAVE_ERROR);
}
......@@ -75,7 +75,7 @@ public class TemporaryActivityClockQueryController {
* 根据促销员id查询上次打卡信息
*/
@GetMapping("/latest")
public R findLatestClockInfo(Integer temporaryId){
public R findLatestClockInfo( Long temporaryId){
if (Objects.isNull(temporaryId)){
return R.success();
}
......
......@@ -115,7 +115,7 @@ public class TemporaryActivityCoreController {
* 当促销员取消保存活动记录时,数据进行删除
*/
@DeleteMapping("/today/reported/market_cell/del")
public R todayDeleteMarketCellReported(Integer temporaryId) {
public R todayDeleteMarketCellReported( Long temporaryId) {
tempActivityCoreService.todayActivityDeleteMarketCellReported(temporaryId);
return R.success();
}
......@@ -123,22 +123,31 @@ public class TemporaryActivityCoreController {
/**
* 促销员[今日活动]数据提交审批
* 修改审批状态
* 增加任务校验2025年11月17日16:01:47
*/
@PutMapping("/reported/approve/submit/{id}")
public R activityReportedSubmit(@PathVariable("id") Long id) {
TemporaryActivityReportedDto activityReportedDto = temporaryActivityQueryService.findTemporaryActivityById(id);
if (activityReportedDto.getApproveStatus().equals(TemActApproveStatus.APPROVED)){
return R.success();
}
Boolean posFlag = CollectionUtils.isEmpty(activityReportedDto.getPosTaskClockPhotoUrls())|| activityReportedDto.getPosTaskClockPhotoUrls().size() < 1;
if (CollectionUtils.isEmpty(activityReportedDto.getTgscPhotoInfos()) || activityReportedDto.getTgscPhotoInfos().size() < 3){
throw new DataException(RCode.NOT_TGSH_PHOTO_ERROR);
}else if (CollectionUtils.isEmpty(activityReportedDto.getTghdPhotoInfos()) || activityReportedDto.getTghdPhotoInfos().size() < 3){
throw new DataException(RCode.NOT_TGHD_PHOTO_ERROR);
}else if (CollectionUtils.isEmpty(activityReportedDto.getTgcjPhotoInfos()) || activityReportedDto.getTgcjPhotoInfos().size() < 3){
throw new DataException(RCode.NOT_TGCJ_PHOTO_ERROR);
if (activityReportedDto.getApproveStatus().equals(TemActApproveStatus.APPROVED) ){
if (posFlag) {
return R.fail(RCode.NOT_POS_TASK_PHOTO_ERROR);
}
return R.success();
}else{
if (CollectionUtils.isEmpty(activityReportedDto.getTgscPhotoInfos()) || activityReportedDto.getTgscPhotoInfos().size() < 2){
throw new DataException(RCode.NOT_TGSH_PHOTO_ERROR);
}else if (CollectionUtils.isEmpty(activityReportedDto.getTghdPhotoInfos()) || activityReportedDto.getTghdPhotoInfos().size() < 2){
throw new DataException(RCode.NOT_TGHD_PHOTO_ERROR);
}else if (CollectionUtils.isEmpty(activityReportedDto.getTgcjPhotoInfos()) || activityReportedDto.getTgcjPhotoInfos().size() < 2){
throw new DataException(RCode.NOT_TGCJ_PHOTO_ERROR);
}
tempActivityCoreService.activityReportedSubmit(id);
if (posFlag) {
return R.fail(RCode.NOT_POS_TASK_PHOTO_ERROR);
}
}
tempActivityCoreService.activityReportedSubmit(id);
return R.success();
}
......
......@@ -33,7 +33,7 @@ public class TemporaryActivityQueryController {
* @return 所有任务(分页查询)
*/
@PostMapping("/all/{temporary_id}")
public R findtemporaryIdActivityDataList(@PathVariable("temporary_id") @NotNull Integer temporaryId, @RequestBody PageInfo pageInfo) {
public R findtemporaryIdActivityDataList(@PathVariable("temporary_id") @NotNull Long temporaryId, @RequestBody PageInfo pageInfo) {
temporaryActivityQueryService.findtemporaryIdActivityDataList(temporaryId, pageInfo);
return R.success(pageInfo);
}
......@@ -42,7 +42,7 @@ public class TemporaryActivityQueryController {
* 根据促销员id查询今日任务
*/
@GetMapping("/today/{temporary_id}")
public R findTemporaryTodayActivityData(@PathVariable("temporary_id") @NotNull Integer temporaryId) {
public R findTemporaryTodayActivityData(@PathVariable("temporary_id") @NotNull Long temporaryId) {
TemporaryActivityReportedDto dto = temporaryActivityQueryService.findtemporaryIdTodayActivityData(temporaryId);
return R.success(dto);
}
......@@ -61,7 +61,7 @@ public class TemporaryActivityQueryController {
* 数据暂存到redis中,当调用保存接口时再添加到数据库中
*/
@GetMapping("/today/reported/market_cell")
public R todayActivityMarketCell(Integer temporaryId) {
public R todayActivityMarketCell( Long temporaryId) {
return R.success(temporaryActivityQueryService.findActivityMarketCell(temporaryId));
}
......
package com.wangxiaolu.promotion.controller.activity.temporary;
import com.wangxiaolu.promotion.common.enums.FlagType;
import com.wangxiaolu.promotion.pojo.activity.temporary.vo.TemporaryActivityTaskClockReq;
import com.wangxiaolu.promotion.result.basedata.R;
import com.wangxiaolu.promotion.domain.activity.mapper.entity.TemporaryActivityTaskClockDO;
import com.wangxiaolu.promotion.service.activity.temporary.TemporaryActivityTaskClockService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* 临时活动相关任务打卡核心控制层
* 包含 随机任务和pos打卡任务
*/
@RestController
@RequestMapping("/activity/task-clock/core")
public class TemporaryActivityTaskClockCoreController {
@Resource
private TemporaryActivityTaskClockService service;
/**
* 打卡更新打卡状态
*
* @param clockVo
* @return
*/
@PostMapping("/clock")
public R clock(@RequestBody TemporaryActivityTaskClockReq clockVo) {
service.taskClock(clockVo);
return R.success();
}
@PutMapping("/update")
public R update(@RequestBody TemporaryActivityTaskClockDO taskClock) {
return R.success(service.updateById(taskClock));
}
@DeleteMapping("/delete/{id}")
public R delete(@PathVariable Long id) {
TemporaryActivityTaskClockDO taskClock = new TemporaryActivityTaskClockDO();
taskClock.setClockId(id)
.setIsDelete(FlagType.NO.getType());
return R.success(service.updateById(taskClock));
}
}
package com.wangxiaolu.promotion.controller.activity.temporary;
import com.wangxiaolu.promotion.domain.activity.mapper.entity.TemporaryActivityTaskClockDO;
import com.wangxiaolu.promotion.pojo.activity.temporary.res.TemporaryActivityTaskClockRes;
import com.wangxiaolu.promotion.service.activity.temporary.TemporaryActivityTaskClockService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* @author lvbencai
* @date 2025年11月11日16:45:27
* @description: 临时活动任务打卡查询控制层
*/
@RestController
@RequestMapping("/activity/task-clock/query")
public class TemporaryActivityTaskClockQueryController {
@Resource
private TemporaryActivityTaskClockService service;
@GetMapping("/byId/{id}")
public TemporaryActivityTaskClockDO getById(@PathVariable Long id) {
return service.getById(id);
}
/**
* 查询任务打卡列表
*
* @return
*/
@GetMapping("/list")
public List<TemporaryActivityTaskClockDO> listByTemporaryId() {
return service.listByUserId();
}
/**
* 按照任务类型查询任务信息
*
* @return
*/
@GetMapping("/my/{taskType}")
public TemporaryActivityTaskClockRes queryByMyTaskType(@PathVariable Integer taskType) {
return service.queryByMyTaskType(taskType);
}
}
......@@ -40,5 +40,8 @@ public interface TemporaryActivityClockDao {
*/
void employeePage(String employeeQcId, PageInfo pageInfo,TemporaryClockWrapper tcw);
TemporaryClockDto findLatestClockByTemporaryId(Integer temporaryId);
TemporaryClockDto findLatestClockByTemporaryId( Long temporaryId);
TemporaryClockDto findClockInfo(TemporaryClockWrapper wr);
}
......@@ -9,5 +9,5 @@ import com.wangxiaolu.promotion.enums.activity.LogType;
*/
public interface TemporaryActivityLogDao {
void save(Integer temporaryId, String temporaryName, LogType typeE, Long flowDataId, Object logObj);
void save(Long temporaryId, String temporaryName, LogType typeE, Long flowDataId, Object logObj);
}
......@@ -16,28 +16,34 @@ public interface TemporaryActivityPhotoDao {
/**
* 保存活动上报照片list
*/
void saveReportedList(Integer temporaryId, Long reportedId, Integer photoType, List<String> urls, List<String> changeUrls);
void saveReportedList(Integer temporaryId, Long reportedId, Integer photoType, List<String> urls);
void saveReportedList(Long temporaryId, Long reportedId, Integer photoType, List<String> urls, List<String> changeUrls);
void saveReportedList(Long clockId,Long temporaryId, Long reportedId, Integer photoType, List<String> urls);
/**
* 保存促销员上下班打卡图片
*/
void saveClockPhoto(Integer temporaryId, Long clockId, Integer photoType, String url);
void saveClockPhoto(Long temporaryId, Long clockId, Integer photoType, String url);
/**
* 根据促销员id-活动上报id查询图片
*/
Map<Integer, List<String>> findReportedGroup(Integer temporaryId, Long reportedId);
Map<Integer, List<String>> findReportedGroup(Long temporaryId, Long reportedId);
Map<Integer, TemporaryActivityPhotoDto> findClockPhotoGroupByClockId(Long clockId);
void updateStatus(TemporaryPhotoWrapper pw, int status);
void saveClockPhotoByUpdate(Integer temporaryId, Long id, Integer photoType, String url);
void saveClockPhotoByUpdate(Long temporaryId, Long id, Integer photoType, String url);
Map<Long, Map<Integer, String>> findClockPhotoGroupByClockIds(List<Long> clockIds);
Map<Integer, List<TemporaryActivityPhotoDto>> findReportedInfoGroup(Integer temporaryId, Long reportedId);
Map<Integer, List<TemporaryActivityPhotoDto>> findReportedInfoGroup(Long temporaryId, Long reportedId);
void deleteList(Long reportedId, int type);
void saveClockTaskPhoto(TemporaryActivityPhotoDto dto, List<String> clockPhtos);
List<TemporaryActivityPhotoDto> selectPhotos(TemporaryPhotoWrapper temporaryPhotoWrapper);
void deleteListByClockId(Long clockId, Integer taskType);
}
......@@ -25,7 +25,7 @@ public interface TemporaryActivityReportedDao {
/**
* 查询当日任务
*/
TemporaryActivityReportedDto findOneByCurrentDate(Integer temporaryId);
TemporaryActivityReportedDto findOneByCurrentDate(Long temporaryId);
/**
* 根据ID查询
......
package com.wangxiaolu.promotion.domain.activity.dao;
import com.wangxiaolu.promotion.domain.activity.mapper.entity.TemporaryActivityTaskClockDO;
import com.wangxiaolu.promotion.domain.activity.wrapperQo.TemporaryActivityTaskWrapperDto;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryTaskClockDto;
import java.util.List;
public interface TemporaryActivityTaskClockDao {
List<TemporaryActivityTaskClockDO> selectList(TemporaryActivityTaskWrapperDto wrapper);
void save(TemporaryActivityTaskClockDO taskClockDO);
TemporaryActivityTaskClockDO selectById(Long id);
void update(TemporaryActivityTaskClockDO taskClockDO);
TemporaryActivityTaskClockDO selectOne(TemporaryActivityTaskWrapperDto wrapper);
void updateTaskClockByClockId(TemporaryTaskClockDto updateTaskClockDto);
void updateTaskStatusByType(int uncompleted, Long id);
}
......@@ -85,7 +85,7 @@ public class PromotionStoreDaoImpl implements PromotionStoreDao {
.setArea(jo.getString("store_mss_area"))
.setStreet(jo.getString("store_mss_street"))
.setAddress(jo.getString("store_addr"))
.setTemporaryId(0)
.setTemporaryId(0L)
.setTemporaryName("系统同步")
.setStoreManager(jo.getString("store_manager"))
.setStoreManagerWaiqin365Id(jo.getString("store_manager_waiqin365_id"));
......
......@@ -95,11 +95,20 @@ public class TemporaryActivityClockDaoImpl implements TemporaryActivityClockDao
}
@Override
public TemporaryClockDto findLatestClockByTemporaryId(Integer temporaryId) {
public TemporaryClockDto findLatestClockByTemporaryId( Long temporaryId) {
TemporaryActivityClockDO clockDO = temporaryActivityClockMapper.findLatestClockByTemporaryId(temporaryId);
return transitionDto(clockDO);
}
@Override
public TemporaryClockDto findClockInfo(TemporaryClockWrapper wr) {
TemporaryActivityClockDO clockDO = temporaryActivityClockMapper.selectOne(buildWrapper(wr));
TemporaryClockDto clockDto = transitionDto(clockDO);
return clockDto;
}
private LambdaQueryWrapper<TemporaryActivityClockDO> buildWrapper(TemporaryClockWrapper tcw) {
LambdaQueryWrapper<TemporaryActivityClockDO> qw = new LambdaQueryWrapper<>();
if (Objects.nonNull(tcw.getId())) {
......
......@@ -21,7 +21,7 @@ public class TemporaryActivityLogDaoImpl implements TemporaryActivityLogDao {
@Override
public void save(Integer temporaryId, String temporaryName, LogType typeE, Long flowDataId, Object logObj) {
public void save(Long temporaryId, String temporaryName, LogType typeE, Long flowDataId, Object logObj) {
TemporaryActivityLogDO tDo = new TemporaryActivityLogDO(temporaryId, temporaryName, typeE, flowDataId, JSONObject.toJSONString(logObj));
temporaryActivityLogMapper.insert(tDo);
}
......
package com.wangxiaolu.promotion.domain.activity.dao.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wangxiaolu.promotion.common.enums.StatusType;
import com.wangxiaolu.promotion.domain.activity.dao.TemporaryActivityPhotoDao;
import com.wangxiaolu.promotion.domain.activity.mapper.TemporaryActivityPhotoMapper;
import com.wangxiaolu.promotion.domain.activity.mapper.entity.TemporaryActivityPhotoDO;
import com.wangxiaolu.promotion.domain.activity.wrapperQo.TemporaryPhotoWrapper;
import com.wangxiaolu.promotion.enums.activity.ActivityPhotoType;
import com.wangxiaolu.promotion.exception.ParamException;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryActivityPhotoDto;
import com.wangxiaolu.promotion.result.basedata.RCode;
......@@ -32,7 +34,7 @@ public class TemporaryActivityPhotoDaoImpl implements TemporaryActivityPhotoDao
TemporaryActivityPhotoMapper temporaryActivityPhotoMapper;
@Override
public void saveReportedList(Integer temporaryId, Long reportedId, Integer photoType, List<String> urls, List<String> changeUrls) {
public void saveReportedList(Long temporaryId, Long reportedId, Integer photoType, List<String> urls, List<String> changeUrls) {
if (CollectionUtils.isEmpty(changeUrls)) {
return;
}
......@@ -64,7 +66,7 @@ public class TemporaryActivityPhotoDaoImpl implements TemporaryActivityPhotoDao
}
@Override
public void saveReportedList(Integer temporaryId, Long reportedId, Integer photoType, List<String> urls) {
public void saveReportedList(Long clockId,Long temporaryId, Long reportedId, Integer photoType, List<String> urls) {
List<TemporaryActivityPhotoDO> dos = new ArrayList<>();
for (String url : urls) {
String[] uArr = url.split("/");
......@@ -72,6 +74,7 @@ public class TemporaryActivityPhotoDaoImpl implements TemporaryActivityPhotoDao
TemporaryActivityPhotoDO photoDo = new TemporaryActivityPhotoDO()
.setTemporaryId(temporaryId)
.setReportedId(reportedId)
.setClockId(clockId)
.setType(photoType)
.setPhotoUrl(url)
.setPhotoFiledId(uId);
......@@ -85,20 +88,22 @@ public class TemporaryActivityPhotoDaoImpl implements TemporaryActivityPhotoDao
* 保存促销员上下班打卡图片
*/
@Override
public void saveClockPhoto(Integer temporaryId, Long clockId, Integer photoType, String url) {
public void saveClockPhoto(Long temporaryId, Long clockId, Integer photoType, String url) {
saveClockPhoto(temporaryId, clockId, photoType, url, null);
}
@Override
public void saveClockPhotoByUpdate(Integer temporaryId, Long id, Integer photoType, String url) {
public void saveClockPhotoByUpdate(Long temporaryId, Long id, Integer photoType, String url) {
saveClockPhoto(temporaryId, id, photoType, url, true);
}
@Override
public Map<Long, Map<Integer, String>> findClockPhotoGroupByClockIds(List<Long> clockIds) {
LambdaQueryWrapper<TemporaryActivityPhotoDO> wq = new LambdaQueryWrapper<>();
wq.in(TemporaryActivityPhotoDO::getClockId, clockIds).eq(TemporaryActivityPhotoDO::getIsDelete, StatusType.VALID.getType());
wq.in(TemporaryActivityPhotoDO::getClockId, clockIds)
.le(TemporaryActivityPhotoDO::getType, ActivityPhotoType.CLOCK_OUT.getType())
.eq(TemporaryActivityPhotoDO::getIsDelete, StatusType.VALID.getType());
List<TemporaryActivityPhotoDO> dos = temporaryActivityPhotoMapper.selectList(wq);
if (CollectionUtils.isEmpty(dos)) {
return null;
......@@ -117,9 +122,10 @@ public class TemporaryActivityPhotoDaoImpl implements TemporaryActivityPhotoDao
}
@Override
public Map<Integer, List<TemporaryActivityPhotoDto>> findReportedInfoGroup(Integer temporaryId, Long reportedId) {
public Map<Integer, List<TemporaryActivityPhotoDto>> findReportedInfoGroup(Long temporaryId, Long reportedId) {
LambdaQueryWrapper<TemporaryActivityPhotoDO> wq = new LambdaQueryWrapper<>();
wq.eq(TemporaryActivityPhotoDO::getReportedId, reportedId).eq(TemporaryActivityPhotoDO::getIsDelete, StatusType.VALID.getType());
wq.eq(TemporaryActivityPhotoDO::getReportedId, reportedId)
.eq(TemporaryActivityPhotoDO::getIsDelete, StatusType.VALID.getType());
List<TemporaryActivityPhotoDO> dos = temporaryActivityPhotoMapper.selectList(wq);
if (CollectionUtils.isEmpty(dos)) {
return null;
......@@ -134,6 +140,56 @@ public class TemporaryActivityPhotoDaoImpl implements TemporaryActivityPhotoDao
temporaryActivityPhotoMapper.deletebyReportedId(reportedId,type);
}
@Override
public void saveClockTaskPhoto(TemporaryActivityPhotoDto dto, List<String> clockPhtos) {
// 新增数据
// saveReportedList(dto.getClockId(),dto.getTemporaryId(), null, dto.getType(), clockPhtos);
List<TemporaryActivityPhotoDO> dos = new ArrayList<>();
for (String url : clockPhtos) {
String[] uArr = url.split("/");
String uId = uArr[uArr.length - 1];
TemporaryActivityPhotoDO photoDo = new TemporaryActivityPhotoDO()
.setTemporaryId(dto.getTemporaryId())
.setReportedId(dto.getReportedId())
.setClockId(dto.getClockId())
.setType(dto.getType())
.setPhotoUrl(url)
.setPhotoFiledId(uId);
dos.add(photoDo);
}
temporaryActivityPhotoMapper.insertListByClockId(dos);
temporaryActivityPhotoMapper.updateListByClockId(dto.getClockId(),dto.getType(),dos);
}
@Override
public List<TemporaryActivityPhotoDto> selectPhotos(TemporaryPhotoWrapper temporaryPhotoWrapper) {
// 根据关联的上班打卡任务,查询图片信息
LambdaQueryWrapper<TemporaryActivityPhotoDO> wrapper = new LambdaQueryWrapper<TemporaryActivityPhotoDO>()
.eq(ObjectUtil.isNotEmpty(temporaryPhotoWrapper.getClockId()), TemporaryActivityPhotoDO::getClockId, temporaryPhotoWrapper.getClockId())
.eq(ObjectUtil.isNotEmpty(temporaryPhotoWrapper.getReportedId()), TemporaryActivityPhotoDO::getReportedId, temporaryPhotoWrapper.getReportedId())
.eq(ObjectUtil.isNotEmpty(temporaryPhotoWrapper.getTemporaryId()), TemporaryActivityPhotoDO::getTemporaryId, temporaryPhotoWrapper.getTemporaryId())
.eq(ObjectUtil.isNotEmpty(temporaryPhotoWrapper.getType()), TemporaryActivityPhotoDO::getType, temporaryPhotoWrapper.getType())
.eq(TemporaryActivityPhotoDO::getIsDelete, StatusType.VALID.getType());
List<TemporaryActivityPhotoDO> dos = temporaryActivityPhotoMapper.selectList(wrapper);
List<TemporaryActivityPhotoDto> photoDtos = transitionDtos(dos);
return photoDtos;
}
@Override
public void deleteListByClockId(Long clockId, Integer taskType) {
// 根据clockId 和图片类型 删除图片
LambdaQueryWrapper<TemporaryActivityPhotoDO> wrapper = new LambdaQueryWrapper<TemporaryActivityPhotoDO>()
.eq(TemporaryActivityPhotoDO::getClockId, clockId)
.eq(TemporaryActivityPhotoDO::getType, taskType)
.eq(TemporaryActivityPhotoDO::getIsDelete, StatusType.VALID.getType());
TemporaryActivityPhotoDO photodo = new TemporaryActivityPhotoDO();
photodo.setIsDelete(StatusType.INVALID.getType());
temporaryActivityPhotoMapper.update(photodo, wrapper);
}
/**
* 活动上报图片查询
......@@ -142,7 +198,7 @@ public class TemporaryActivityPhotoDaoImpl implements TemporaryActivityPhotoDao
* @param reportedId 活动id
*/
@Override
public Map<Integer, List<String>> findReportedGroup(Integer temporaryId, Long reportedId) {
public Map<Integer, List<String>> findReportedGroup(Long temporaryId, Long reportedId) {
LambdaQueryWrapper<TemporaryActivityPhotoDO> wq = new LambdaQueryWrapper<>();
wq.eq(TemporaryActivityPhotoDO::getReportedId, reportedId).eq(TemporaryActivityPhotoDO::getIsDelete, StatusType.VALID.getType());
List<TemporaryActivityPhotoDO> dos = temporaryActivityPhotoMapper.selectList(wq);
......@@ -162,7 +218,9 @@ public class TemporaryActivityPhotoDaoImpl implements TemporaryActivityPhotoDao
@Override
public Map<Integer, TemporaryActivityPhotoDto> findClockPhotoGroupByClockId(Long clockId) {
LambdaQueryWrapper<TemporaryActivityPhotoDO> wq = new LambdaQueryWrapper<>();
wq.eq(TemporaryActivityPhotoDO::getClockId, clockId).eq(TemporaryActivityPhotoDO::getIsDelete, StatusType.VALID.getType());
wq.eq(TemporaryActivityPhotoDO::getClockId, clockId)
.le(TemporaryActivityPhotoDO::getType, ActivityPhotoType.CLOCK_OUT.getType())
.eq(TemporaryActivityPhotoDO::getIsDelete, StatusType.VALID.getType());
List<TemporaryActivityPhotoDO> dos = temporaryActivityPhotoMapper.selectList(wq);
List<TemporaryActivityPhotoDto> photoDtos = transitionDtos(dos);
Map<Integer, TemporaryActivityPhotoDto> dtoMap = photoDtos.stream().collect(Collectors.toMap(TemporaryActivityPhotoDto::getType, pDto -> pDto));
......@@ -200,7 +258,7 @@ public class TemporaryActivityPhotoDaoImpl implements TemporaryActivityPhotoDao
private void saveClockPhoto(Integer temporaryId, Long clockId, Integer photoType, String url, Boolean isUpdate) {
private void saveClockPhoto(Long temporaryId, Long clockId, Integer photoType, String url, Boolean isUpdate) {
String[] photoArr = url.split("/");
String photoFiledId = photoArr[photoArr.length - 1];
......
......@@ -67,7 +67,7 @@ public class TemporaryActivityReportedDaoImpl implements TemporaryActivityReport
* 根据促销员id查询今日任务
*/
@Override
public TemporaryActivityReportedDto findOneByCurrentDate(Integer temporaryId) {
public TemporaryActivityReportedDto findOneByCurrentDate(Long temporaryId) {
TemporaryActivityWrapper taw = new TemporaryActivityWrapper()
.setTemporaryId(temporaryId)
.setCreateDate(DateUtil.today());
......
package com.wangxiaolu.promotion.domain.activity.dao.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wangxiaolu.promotion.common.util.BeanUtils;
import com.wangxiaolu.promotion.domain.activity.dao.TemporaryActivityTaskClockDao;
import com.wangxiaolu.promotion.domain.activity.mapper.TemporaryActivityTaskClockMapper;
import com.wangxiaolu.promotion.domain.activity.mapper.entity.TemporaryActivityTaskClockDO;
import com.wangxiaolu.promotion.domain.activity.wrapperQo.TemporaryActivityTaskWrapperDto;
import com.wangxiaolu.promotion.enums.activity.ActivityClockTaskStatus;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryTaskClockDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author : liqiulin
* @date : 2024-04-23 17
* @describe :
*/
@Service
@Slf4j
public class TemporaryActivityTaskClockDaoImpl implements TemporaryActivityTaskClockDao {
@Autowired
TemporaryActivityTaskClockMapper temporaryActivityTaskClockMapper;
@Override
public List<TemporaryActivityTaskClockDO> selectList(TemporaryActivityTaskWrapperDto wrapper) {
List<TemporaryActivityTaskClockDO> temporaryActivityTaskClockDOS = temporaryActivityTaskClockMapper.selectList(new LambdaQueryWrapper<TemporaryActivityTaskClockDO>()
.eq(ObjectUtil.isNotEmpty(wrapper.getTemporaryId()), TemporaryActivityTaskClockDO::getTemporaryId, wrapper.getTemporaryId())
.eq(ObjectUtil.isNotEmpty(wrapper.getClockId()), TemporaryActivityTaskClockDO::getClockId, wrapper.getClockId())
.eq(ObjectUtil.isNotEmpty(wrapper.getUserId()), TemporaryActivityTaskClockDO::getTemporaryId, wrapper.getUserId())
.eq(ObjectUtil.isNotEmpty(wrapper.getIsDelete()), TemporaryActivityTaskClockDO::getIsDelete, wrapper.getIsDelete())
.orderByAsc(TemporaryActivityTaskClockDO::getTaskType));
return temporaryActivityTaskClockDOS;
}
@Override
public void save(TemporaryActivityTaskClockDO taskClockDO) {
temporaryActivityTaskClockMapper.insert(taskClockDO);
}
@Override
public TemporaryActivityTaskClockDO selectById(Long id) {
return temporaryActivityTaskClockMapper.selectById(id);
}
@Override
public void update(TemporaryActivityTaskClockDO taskClockDO) {
temporaryActivityTaskClockMapper.updateById(taskClockDO);
}
@Override
public TemporaryActivityTaskClockDO selectOne(TemporaryActivityTaskWrapperDto wrapper) {
TemporaryActivityTaskClockDO temporaryActivityTaskClockDO = temporaryActivityTaskClockMapper.selectOne(
new LambdaQueryWrapper<TemporaryActivityTaskClockDO>()
.eq(ObjectUtil.isNotEmpty(wrapper.getTemporaryId()),TemporaryActivityTaskClockDO::getTemporaryId, wrapper.getTemporaryId())
.eq(ObjectUtil.isNotEmpty(wrapper.getClockId()),TemporaryActivityTaskClockDO::getClockId, wrapper.getClockId())
.eq(ObjectUtil.isNotEmpty(wrapper.getReportId()),TemporaryActivityTaskClockDO::getReportedId, wrapper.getReportId())
.eq(ObjectUtil.isNotEmpty(wrapper.getTaskType()),TemporaryActivityTaskClockDO::getTaskType, wrapper.getTaskType())
.eq(ObjectUtil.isNotEmpty(wrapper.getIsDelete()),TemporaryActivityTaskClockDO::getIsDelete, wrapper.getIsDelete())
// 当天的数据
.eq(ObjectUtil.isNotEmpty(wrapper.getCreateDate()),TemporaryActivityTaskClockDO::getCreateDate, wrapper.getCreateDate())
);
return temporaryActivityTaskClockDO;
}
@Override
public void updateTaskClockByClockId(TemporaryTaskClockDto updateTaskClockDto) {
TemporaryActivityTaskClockDO updateTaskClockDo = new TemporaryActivityTaskClockDO();
BeanUtils.copyProperties(updateTaskClockDto, updateTaskClockDo);
Wrapper<TemporaryActivityTaskClockDO> wraper = new LambdaQueryWrapper<TemporaryActivityTaskClockDO>()
.eq(TemporaryActivityTaskClockDO::getClockId, updateTaskClockDto.getClockId());
temporaryActivityTaskClockMapper.update(updateTaskClockDo,wraper);
}
/**
* 根据 clockId 更新任务状态
* @param uncompleted 任务状态
* @param id clockId
*/
@Override
public void updateTaskStatusByType(int uncompleted, Long id) {
TemporaryActivityTaskClockDO updateTaskClockDo = new TemporaryActivityTaskClockDO();
updateTaskClockDo.setTaskStatus(uncompleted);
Wrapper<TemporaryActivityTaskClockDO> wraper = new LambdaQueryWrapper<TemporaryActivityTaskClockDO>()
.eq(TemporaryActivityTaskClockDO::getClockId, id)
.lt(TemporaryActivityTaskClockDO::getTaskStatus, ActivityClockTaskStatus.COMPLETED.getType());
temporaryActivityTaskClockMapper.update(updateTaskClockDo,wraper);
}
}
......@@ -23,7 +23,7 @@ public interface TemporaryActivityClockMapper extends BaseMapper<TemporaryActivi
Integer employeePageCount(@Param("employeeQcId") String employeeQcId, @Param("pageSize") int pageSize);
TemporaryActivityClockDO findLatestClockByTemporaryId(Integer temporaryId);
TemporaryActivityClockDO findLatestClockByTemporaryId( Long temporaryId);
}
......
......@@ -24,6 +24,10 @@ public interface TemporaryActivityPhotoMapper extends BaseMapper<TemporaryActivi
void updateListIsDelete(@Param("reportedId") Long reportedId,@Param("photoType") Integer photoType,@Param("dos") List<TemporaryActivityPhotoDO> dos);
void deletebyReportedId(@Param("reportedId") Long reportedId,@Param("photoType") int type);
void insertListByClockId(@Param("dos") List<TemporaryActivityPhotoDO> dos);
void updateListByClockId(@Param("clockId")Long clockId,@Param("photoType") Integer type,@Param("dos") List<TemporaryActivityPhotoDO> dos);
}
......
// 文件路径:promotion-service/src/main/java/com/wangxiaolu/promotion/domain/activity/mapper/TemporaryActivityTaskClockMapper.java
package com.wangxiaolu.promotion.domain.activity.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wangxiaolu.promotion.domain.activity.mapper.entity.TemporaryActivityTaskClockDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface TemporaryActivityTaskClockMapper extends BaseMapper<TemporaryActivityTaskClockDO> {
}
......@@ -81,7 +81,7 @@ public class PromotionStoreDO implements Serializable {
/**
* 门店提交人id
*/
private Integer temporaryId;
private Long temporaryId;
/**
* 门店提交人
......@@ -140,4 +140,4 @@ public class PromotionStoreDO implements Serializable {
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
}
......@@ -9,7 +9,7 @@ import java.util.Date;
import lombok.Data;
/**
*
*
* @TableName temporary_activity_clock
*/
@TableName(value ="temporary_activity_clock")
......@@ -24,7 +24,7 @@ public class TemporaryActivityClockDO implements Serializable {
/**
* temporary_info表id
*/
private Integer temporaryId;
private Long temporaryId;
/**
* temporary_info表name
......@@ -165,4 +165,4 @@ public class TemporaryActivityClockDO implements Serializable {
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
}
......@@ -32,7 +32,7 @@ public class TemporaryActivityLogDO implements Serializable {
/**
* temporary_info表id
*/
private Integer temporaryId;
private Long temporaryId;
/**
* 促销员姓名
......@@ -67,7 +67,7 @@ public class TemporaryActivityLogDO implements Serializable {
@TableField(exist = false)
private static final long serialVersionUID = 1L;
public TemporaryActivityLogDO(Integer temporaryId, String temporaryName, LogType typeE, Long flowDataId, Object dataDetail) {
public TemporaryActivityLogDO(Long temporaryId, String temporaryName, LogType typeE, Long flowDataId, Object dataDetail) {
this.temporaryId = temporaryId;
this.type = typeE.getType();
this.typeName = typeE.getName();
......@@ -75,4 +75,4 @@ public class TemporaryActivityLogDO implements Serializable {
this.temporaryName = temporaryName;
this.flowDataId = flowDataId;
}
}
\ No newline at end of file
}
......@@ -9,7 +9,7 @@ import java.util.Date;
import lombok.Data;
/**
*
*
* @TableName temporary_activity_market_cell
*/
@TableName(value ="temporary_activity_market_cell")
......@@ -24,7 +24,7 @@ public class TemporaryActivityMarketCellDO implements Serializable {
/**
* 关联—temporary_info表id
*/
private Integer temporaryId;
private Long temporaryId;
private Long activityReportedId;
......@@ -59,7 +59,7 @@ public class TemporaryActivityMarketCellDO implements Serializable {
private Date createTime;
/**
* 创建日期YYYY-MM-DD
* 创建日期YYYY-MM-DD
*/
private String createDate;
......@@ -76,4 +76,4 @@ public class TemporaryActivityMarketCellDO implements Serializable {
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
}
......@@ -11,7 +11,7 @@ import lombok.Data;
import lombok.experimental.Accessors;
/**
*
*
* @TableName temporary_activity_photo
*/
@TableName(value ="temporary_activity_photo")
......@@ -27,7 +27,7 @@ public class TemporaryActivityPhotoDO implements Serializable {
/**
* temporary_info表id
*/
private Integer temporaryId;
private Long temporaryId;
/**
* 活动上报ID,关联表temporary_activity_reported表主键id
......@@ -40,7 +40,9 @@ public class TemporaryActivityPhotoDO implements Serializable {
private Long clockId;
/**
* 图片所属类别:1:推广试吃;2……
* 图片所属类别:1: 推广试吃照片 2推广互动照片 3:推广成交照片4:上班打卡图片 5: 午休下班打卡图片
* 6:午休上班打卡图片 7: 下班打卡图片 8: 当日销量POS机页面凭证 9: 随机任务 10: POS照片
*
*/
private Integer type;
......@@ -69,4 +71,4 @@ public class TemporaryActivityPhotoDO implements Serializable {
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
}
......@@ -10,7 +10,7 @@ import java.io.Serializable;
import java.util.Date;
/**
*
*
* @TableName temporary_activity_reported
*/
@TableName(value ="temporary_activity_reported")
......@@ -25,7 +25,7 @@ public class TemporaryActivityReportedDO implements Serializable {
/**
* 关联—temporary_info表id
*/
private Integer temporaryId;
private Long temporaryId;
/**
* 关联—temporary_info表name
......@@ -142,4 +142,4 @@ public class TemporaryActivityReportedDO implements Serializable {
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
}
package com.wangxiaolu.promotion.domain.activity.mapper.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* @TableName temporary_activity_clock
*/
@TableName(value = "temporary_activity_task_clock")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class TemporaryActivityTaskClockDO implements Serializable {
@TableField(exist = false)
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(type = IdType.AUTO)
private Long id;
private Long temporaryId;
/**
* 活动打卡id
*/
private Long clockId;
/**
* temporary_info表name
*/
private String temporaryName;
/**
* 关联活动上报id
*/
private Long reportedId;
/**
* 任务类型 和图片的工业
* 10、随机任务 9、pos上传任务
*/
private Integer taskType;
/**
* 任务状态 0 待开始 1、进行中 2、已完成 3、未完成
*/
private Integer taskStatus;
/**
* activity_plan_info表id
*/
private Long planId;
/**
* 打卡时间
*/
private Date clockTime;
/**
* 要求打卡时间
*/
private Date requiredlockTime;
/**
* 创建日期YYYY-MM-DD
*/
private String createDate;
/**
* 创建时间
*/
private Date createTime;
/**
* 修改时间
*/
private Date modifyTime;
// 活动模式Id
private Integer activityPatternId;
// 活动模式
private String activityPattern;
/**
* 是否删除
* 1:有效;0:删除;
*/
private Integer isDelete;
/**
* 订阅状态 0:未订阅;1:已订阅
*/
private Integer subscribeStatus;
/**
* 已发送websocket消息
* 0:未发送;1:已发送
*/
private Integer isSendSubscribe;
/**
* 订阅消息发送时间
* 微信模板消息发送时间
*/
private Date subscribeTime;
}
package com.wangxiaolu.promotion.domain.activity.wrapperQo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* @author : liqiulin
* @date : 2024-04-23 19
* @describe :
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class TemporaryActivityTaskWrapperDto {
/**
* temporary_info表id
*/
private Long temporaryId;
private Long clockId;
private Long reportId;
private Long planId;
/**
* 任务类型
*/
private Integer taskType;
/**
* 用户id
*/
private Long userId;
/**
* 是否删除
* 0:删除;1:可用
*/
private Integer isDelete;
private String createDate;
}
......@@ -22,7 +22,7 @@ public class TemporaryActivityWrapper {
/**
* temporaryId
*/
private Integer temporaryId;
private Long temporaryId;
private String temporaryName;
......
......@@ -26,7 +26,7 @@ public class TemporaryClockWrapper {
/**
* temporary_info表id
*/
private Integer temporaryId;
private Long temporaryId;
/**
......
......@@ -22,6 +22,6 @@ public class TemporaryMarketCellWrapper {
private List<Long> activityIds;
private Integer temporaryId;
private Long temporaryId;
}
......@@ -22,7 +22,7 @@ public class TemporaryPhotoWrapper {
/**
* temporary_info表id
*/
private Integer temporaryId;
private Long temporaryId;
/**
* 活动上报ID,关联表temporary_activity_reported表主键id
......
......@@ -12,7 +12,6 @@ import org.springframework.stereotype.Repository;
* @Entity com.wangxiaolu.promotion.domain.examine.mapper.entity.ActivityExamineDO
*/
@Mapper
@Repository
public interface ActivityExamineMapper extends BaseMapper<ActivityExamineDO> {
ActivityExamineDO selectByPlanId(Long planId);
......
......@@ -21,7 +21,7 @@ public interface TemporaryInfoDao {
*/
WxTemporaryInfoDto selectOneByOpenId(String openId);
WxTemporaryInfoDto selectOneById(Integer id);
WxTemporaryInfoDto selectOneById(Long id);
void findPage(TemporaryWrapper tw, PageInfo pageInfo);
......
......@@ -64,7 +64,7 @@ public class TemporaryInfoDaoImpl implements TemporaryInfoDao {
}
@Override
public WxTemporaryInfoDto selectOneById(Integer id) {
public WxTemporaryInfoDto selectOneById(Long id) {
TemporaryInfoDO temDo = temporaryInfoMapper.selectById(id);
return transitionDto(temDo);
}
......
......@@ -10,12 +10,14 @@ import java.io.Serializable;
import java.util.Date;
/**
*
*
* @TableName temporary_info
*/
@Data
@TableName(value ="temporary_info")
public class TemporaryInfoDO implements Serializable {
@TableField(exist = false)
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
......@@ -87,7 +89,6 @@ public class TemporaryInfoDO implements Serializable {
*/
private Date modifyTime;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
}
package com.wangxiaolu.promotion.enums.activity;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 活动打卡任务状态
*/
@Getter
@AllArgsConstructor
public enum ActivityClockTaskStatus {
/**
* 待开始
*/
TO_BE_START(0, "待开始"),
/**
* 进行中
*/
STARTING(1, "进行中"),
/**
* 已完成
*/
COMPLETED(2, "已完成"),
/**
* 未完成
*/
UNCOMPLETED(3, "未完成"),
;
private int type;
private String typeName;
}
......@@ -42,7 +42,17 @@ public enum ActivityPhotoType {
/**
* 当日销量POS机页面凭证
*/
POS_SELL_VOUCHER(7),
POS_SELL_VOUCHER(8),
/**
* POS照片
*/
POS_PHOTO(9),
/**
* 随机任务照片
* 更改固定任务:下午18点15任务
*/
RANDOM_TASK(10)
;
private int type;
......
......@@ -14,17 +14,40 @@ public interface ClockType {
String TEMPORARY_CLOCK_IN_BEGIN_TIME = "09:30:00";
String TEMPORARY_CLOCK_IN_END_TIME = "10:00:00";
/**
* 午休下班卡
*/
Integer TEMPORARY_NOON_CLOCK_OUT = 2;
String TEMPORARY_NOON_CLOCK_OUT_BEGIN_TIME = "13:00:00";
String TEMPORARY_NOON_CLOCK_OUT_END_TIME = "13:30:00";
/**
* 午休上班卡
*/
Integer TEMPORARY_NOON_CLOCK_IN = 3;
String TEMPORARY_NOON_CLOCK_IN_BEGIN_TIME = "14:30:00";
String TEMPORARY_NOON_CLOCK_IN_END_TIME = "15:00:00";
/**
* 下班卡
*/
Integer TEMPORARY_CLOCK_OUT = 4;
String TEMPORARY_CLOCK_OUT_BEGIN_TIME = "19:00:00";
String TEMPORARY_CLOCK_OUT_END_TIME = "23:59:00";
/**
* 随机打卡
*/
Integer TEMPORARY_RAND_CLOCK = 10;
String TEMPORARY_RAND_CLOCK_BEGIN_TIME = "17:30:00";
String TEMPORARY_RAND_CLOCK_END_TIME = "19:30:00";
/**
* 随机打卡
* 11月的时候 先提示当天不拍pos数据 场次费用扣减10元
* 然后不挂接下班卡 先试行看看执行效果 大部分能拍的话 下个月就强制
*/
Integer POS_CLOCK = 9;
String POS_BEGIN_TIME = "17:30:00";
String POS_END_TIME = "19:30:00";
}
package com.wangxiaolu.promotion.enums.activity;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum TemporaryActivityTaskClockMessageType {
RANDOM_TASK_START("randomTaskStart","随机任务开始通知"),
RANDOM_TASK_UNCOMPLETED("randomTaskUncompleted","随机任务未完成通知"),
RANDOM_TASK_CLOCK("randomTaskClock","随机任务打卡"),
POS_CLOCK("posClock","Pos机任务打卡"),
TASK_CLOCK_QUERY("taskClockQuery","任务信息查询"),
TASK_DATA_APPROVE_PASS("taskDataApprovePass","任务详情查询"),
;
private String type;
private String name;
}
......@@ -23,7 +23,7 @@ public class ClockVo {
/**
* temporaryId
*/
Integer temporaryId;
Long temporaryId;
// 活动模式Id
Integer activityPatternId;
......
......@@ -78,7 +78,7 @@ public class PromotionStoreDto implements Serializable {
/**
* 门店提交人id
*/
private Integer temporaryId;
private Long temporaryId;
/**
* 门店提交人
......@@ -133,4 +133,4 @@ public class PromotionStoreDto implements Serializable {
throw new ParamException(RCode.API_DATA_ERROR,null);
}
}
}
\ No newline at end of file
}
......@@ -20,7 +20,7 @@ public class TemporaryActivityMarketCellDto {
/**
* 关联—temporary_info表id
*/
private Integer temporaryId;
private Long temporaryId;
private Long activityReportedId;
......
......@@ -7,7 +7,7 @@ import java.io.Serializable;
import java.util.Date;
/**
*
*
* @TableName temporary_activity_photo
*/
@Data
......@@ -21,7 +21,7 @@ public class TemporaryActivityPhotoDto implements Serializable {
/**
* temporary_info表id
*/
private Integer temporaryId;
private Long temporaryId;
/**
* 活动上报ID,关联表temporary_activity_reported表主键id
......@@ -62,4 +62,4 @@ public class TemporaryActivityPhotoDto implements Serializable {
private Date createTime;
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
}
......@@ -27,7 +27,7 @@ public class TemporaryActivityReportedDto {
/**
* 关联—temporary_info表id
*/
private Integer temporaryId;
private Long temporaryId;
/**
* 关联—temporary_info表name
......@@ -149,6 +149,13 @@ public class TemporaryActivityReportedDto {
private List<TemporaryActivityPhotoDto> psvPhotoInfos;
private List<String> psvChangePhotoUrls;
/**
* 随机任务打卡图片
*/
private List<TemporaryActivityPhotoDto> randTaskClockPhotoUrls;
private List<TemporaryActivityPhotoDto> posTaskClockPhotoUrls;
/**
* 创建时间
*/
......
......@@ -27,7 +27,7 @@ public class TemporaryClockDto {
/**
* temporaryId
*/
Integer temporaryId;
Long temporaryId;
String temporaryName;
......@@ -149,7 +149,7 @@ public class TemporaryClockDto {
*/
Integer isDelete;
public TemporaryClockDto(Integer clockType, Long id, Integer temporaryId, String temporaryName, String clockProvince, String clockCity) {
public TemporaryClockDto(Integer clockType, Long id, Long temporaryId, String temporaryName, String clockProvince, String clockCity) {
if (!ClockType.TEMPORARY_CLOCK_IN.equals(clockType)) {
this.id = id;
}
......@@ -159,7 +159,7 @@ public class TemporaryClockDto {
this.clockCity = clockCity;
}
public TemporaryClockDto(Long id, Integer temporaryId, String brevityClockPhoto, Integer brevityClockType) {
public TemporaryClockDto(Long id, Long temporaryId, String brevityClockPhoto, Integer brevityClockType) {
this.id = id;
this.temporaryId = temporaryId;
this.brevityClockPhoto = brevityClockPhoto;
......
package com.wangxiaolu.promotion.pojo.activity.temporary.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.wangxiaolu.promotion.enums.activity.ClockType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @author : liqiulin
* @date : 2024-04-23 14
* @describe :促销员打卡数据DTO
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public class TemporaryTaskClockDto {
/**
* 主键id
*/
private Long id;
private Long temporaryId;
/**
* 活动打卡id
*/
private Long clockId;
/**
* temporary_info表name
*/
private String temporaryName;
/**
* 关联活动上报id
*/
private Long reportedId;
/**
* 任务类型 和图片的工业
* 10、随机任务 9、pos上传任务
*/
private Integer taskType;
/**
* 任务状态 0 待开始 1、进行中 2、已完成 3、未完成
*/
private Integer taskStatus;
/**
* activity_plan_info表id
*/
private Long planId;
/**
* 打卡时间
*/
private Date clockTime;
/**
* 要求打卡时间
*/
private Date requiredlockTime;
/**
* 创建日期YYYY-MM-DD
*/
private String createDate;
/**
* 创建时间
*/
private Date createTime;
/**
* 修改时间
*/
private Date modifyTime;
// 活动模式Id
private Integer activityPatternId;
// 活动模式
private String activityPattern;
/**
* 是否删除
* 0:否 未删除;1:已删除;
*/
private Integer isDelete;
/**
* 订阅状态 0:未订阅;1:已订阅
*/
private Integer subscribeStatus;
// 已发送订阅消息
private Integer isSendSubscribe;
/**
* 订阅消息发送时间
*/
private Date subscribeTime;
}
package com.wangxiaolu.promotion.pojo.activity.temporary.res;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
import java.util.List;
/**
*
* @TableName temporary_activity_clock
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TemporaryActivityTaskClockRes {
/**
* 主键id
*/
private Long id;
/**
* 活动打卡id
*/
private Long clockId;
private Long temporaryId;
/**
* temporary_info表name
*/
private String temporaryName;
/**
* 关联活动上报id
*/
private Long reportedId;
/**
* 任务类型 和图片的工业
* 10、随机任务 9、pos上传任务
*/
private Integer taskType;
/**
* 任务状态
* 0、待开始 1、进行中 2、已完成 3、未完成
*/
private Integer taskStatus;
/**
* activity_plan_info表id
*/
private Long planId;
/**
* 打卡时间
*/
private Date clockTime;
private List<String> clockPhotos;
// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date requiredlockTime;
private Boolean editableFlag = false;
}
......@@ -22,12 +22,12 @@ public class TemporaryActivityDataVo {
* 促销员活动上报id
* 关联ID:temporary_activity_reported表id
*/
Long activityReportedId;
private Long activityReportedId;
/**
* 促销员id
* temporaryInfo表id
*/
private Integer temporaryId;
private Long temporaryId;
/**
* 促销员姓名
......@@ -66,4 +66,4 @@ public class TemporaryActivityDataVo {
*/
private List<String> psvPhotoUrls;
private List<String> psvChangePhotoUrls;
}
\ No newline at end of file
}
......@@ -24,7 +24,7 @@ public class TemporaryActivityMarketCellVo {
* 促销员id
* temporaryInfo表id
*/
private Integer temporaryId;
private Long temporaryId;
/**
* market_cell 表id
......
package com.wangxiaolu.promotion.pojo.activity.temporary.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Builder;
import lombok.Data;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
/**
*
* @TableName temporary_activity_clock
*/
@Data
@Builder
public class TemporaryActivityTaskClockReq {
/**
* 主键id
*/
private Long id;
/**
* 活动打卡id
*/
@NotNull(message = "活动打卡id不能为空")
private Long clockId;
@NotNull(message = "促销员id不能为空")
private Long temporaryId;
/**
* temporary_info表name
*/
@NotNull(message = "促销员名称不能为空")
private String temporaryName;
/**
* 关联活动上报id
*/
private Long reportedId;
/**
* 任务类型 和图片的工业
* 10、随机任务 9、pos上传任务
*/
@Min(value = 9, message = "任务类型只能是10、9")
@Max(value = 10, message = "任务类型只能是10、9")
private Integer taskType;
/**
* 任务状态
* 任务状态 0 待开始 1、进行中 2、已完成 3、未完成
*/
@Size(min = 1, max = 4, message = "任务状态只能是1、2、3、4")
private Integer taskStatus;
/**
* activity_plan_info表id
*/
private Long planId;
private List<String> clockPhotos;
}
......@@ -39,7 +39,7 @@ public class TemporaryClockVo {
/**
* temporaryId
*/
Integer temporaryId;
Long temporaryId;
String temporaryName;
......
......@@ -9,4 +9,6 @@ import com.wangxiaolu.promotion.pojo.user.dto.WxTemporaryInfoDto;
*/
public interface EmployeeCoreTemporaryInfoService {
void updateTemporaryInfoById(WxTemporaryInfoDto temporaryDto);
WxTemporaryInfoDto selectById(Long temporaryId);
}
package com.wangxiaolu.promotion.service.activity.manage.impl;
import com.wangxiaolu.promotion.common.enums.FlagType;
import com.wangxiaolu.promotion.common.enums.StatusType;
import com.wangxiaolu.promotion.domain.activity.dao.TemporaryActivityClockDao;
import com.wangxiaolu.promotion.domain.activity.dao.TemporaryActivityPhotoDao;
import com.wangxiaolu.promotion.domain.activity.dao.TemporaryActivityReportedDao;
import com.wangxiaolu.promotion.domain.activity.dao.TemporaryActivityTaskClockDao;
import com.wangxiaolu.promotion.domain.activity.wrapperQo.TemporaryClockWrapper;
import com.wangxiaolu.promotion.domain.activity.wrapperQo.TemporaryPhotoWrapper;
import com.wangxiaolu.promotion.exception.DataException;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryActivityReportedDto;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryClockDto;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryTaskClockDto;
import com.wangxiaolu.promotion.result.basedata.RCode;
import com.wangxiaolu.promotion.service.activity.manage.EmployeeCoreTemClockService;
import lombok.extern.slf4j.Slf4j;
......@@ -33,6 +36,8 @@ public class EmployeeCoreTemClockServiceImpl implements EmployeeCoreTemClockServ
TemporaryActivityReportedDao temporaryActivityReportedDao;
@Autowired
private TemporaryActivityPhotoDao temporaryActivityPhotoDao;
@Autowired
TemporaryActivityTaskClockDao taskClockDao;
@Transactional(rollbackFor = Exception.class)
......@@ -85,6 +90,11 @@ public class EmployeeCoreTemClockServiceImpl implements EmployeeCoreTemClockServ
tpw.setTemporaryId(clockDto.getTemporaryId())
.setClockId(clockDto.getId());
temporaryActivityPhotoDao.updateStatus(tpw,StatusType.INVALID.getType());
TemporaryTaskClockDto updateTaskClockDto = new TemporaryTaskClockDto();
updateTaskClockDto.setClockId(clockDto.getId())
.setIsDelete(FlagType.YES.getType());
taskClockDao.updateTaskClockByClockId(updateTaskClockDto);
return clockDto.getPlanId();
}
......
......@@ -20,4 +20,11 @@ public class EmployeeCoreTemporaryInfoServiceImpl implements EmployeeCoreTempora
public void updateTemporaryInfoById(WxTemporaryInfoDto temporaryDto) {
temporaryInfoDao.updateById(temporaryDto);
}
@Override
public WxTemporaryInfoDto selectById(Long temporaryId) {
WxTemporaryInfoDto wxTemporaryInfoDto = temporaryInfoDao.selectOneById(temporaryId);
return wxTemporaryInfoDto;
}
}
......@@ -9,14 +9,15 @@ import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryClockDto;
* @describe :
*/
public interface TemporaryActivityClockQueryService {
TemporaryClockDto findTodayTemporaryClockByTemId(Integer temporaryId);
TemporaryClockDto findTodayTemporaryClockByTemId(Long temporaryId);
TemporaryClockDto findTemporaryClockByTemIdAndDate(Integer temporaryId, String createDate);
TemporaryClockDto findTemporaryClockByTemIdAndDate(Long temporaryId, String createDate);
TemporaryClockDto findById(Long id);
TemporaryClockDto selectOne(TemporaryClockWrapper tcw);
TemporaryClockDto findLatestClockByTemporaryId(Integer temporaryId);
TemporaryClockDto findLatestClockByTemporaryId( Long temporaryId);
TemporaryClockDto findClockInfo(TemporaryClockWrapper wr);
}
......@@ -34,7 +34,7 @@ public interface TemporaryActivityCoreService {
/**
* 删除销售上报-出售单元 - 缓存
*/
void todayActivityDeleteMarketCellReported(Integer temporaryId);
void todayActivityDeleteMarketCellReported( Long temporaryId);
/**
* 修改/删除 单一出售单元
......
......@@ -17,16 +17,16 @@ public interface TemporaryActivityQueryService {
/**
* 根据促销员id查询所有任务
*/
void findtemporaryIdActivityDataList(Integer temporaryId, PageInfo pageInfo);
void findtemporaryIdActivityDataList(Long temporaryId, PageInfo pageInfo);
/**
* 根据促销员id查询今日任务
*/
TemporaryActivityReportedDto findtemporaryIdTodayActivityData(Integer temporaryId);
TemporaryActivityReportedDto findtemporaryIdTodayActivityData(Long temporaryId);
TemporaryActivityReportedDto findTemporaryActivityById(Long activityId);
JSONArray findActivityMarketCell(Integer temporaryId);
JSONArray findActivityMarketCell( Long temporaryId);
List<TemporaryActivityMarketCellDto> findActivityMarketCellByDb(Long activityId);
......
package com.wangxiaolu.promotion.service.activity.temporary;
import com.baomidou.mybatisplus.extension.service.IService;
import com.wangxiaolu.promotion.domain.activity.mapper.entity.TemporaryActivityTaskClockDO;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryClockDto;
import com.wangxiaolu.promotion.pojo.activity.temporary.res.TemporaryActivityTaskClockRes;
import com.wangxiaolu.promotion.pojo.activity.temporary.vo.TemporaryActivityTaskClockReq;
import java.util.List;
public interface TemporaryActivityTaskClockService extends IService<TemporaryActivityTaskClockDO> {
List<TemporaryActivityTaskClockDO> listByTemporaryId(Long temporaryId);
void generateRandomClockTask(TemporaryClockDto dto);
void generatePosUploadTask(TemporaryClockDto dto);
List<TemporaryActivityTaskClockDO> listByUserId();
void taskClock(TemporaryActivityTaskClockReq clockVo);
TemporaryActivityTaskClockRes queryByMyTaskType(Integer taskType);
void updateTaskStatusByType(int uncompleted, Long id);
}
package com.wangxiaolu.promotion.service.activity.temporary.impl;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.wangxiaolu.promotion.utils.WechatAccessTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
/**
* 微信订阅消息服务
*/
@Service
@Slf4j
public class SubscribeMessageService {
@Value("${wx.cx_miniapp.miniprogram_state:formal}")
private String miniprogramState;
@Autowired
private RestTemplate restTemplate;
@Autowired
private WechatAccessTokenUtil tokenUtil;
/**
* 发送订阅通知
* @param openid 用户openid
* @param templateId 订阅模板ID
* @param page 点击通知跳转的小程序页面(如 "/pages/order/detail?id=123")
* @param data 模板数据(键为模板中的字段名,值为具体内容)
* @return 发送结果
*/
public boolean sendSubscribeMessage(String openid, String templateId, String page, Map<String, String> data) {
try {
// 构建请求参数
Map<String, Object> requestBody = new HashMap<>();
// 用户openid
requestBody.put("touser", openid);
// 模板ID
requestBody.put("template_id", templateId);
// 跳转页面
requestBody.put("page", page);
// 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
requestBody.put("miniprogram_state", miniprogramState);
// 格式化模板数据(微信要求格式:{"字段名":{"value":"内容"}})
Map<String, Map<String, String>> dataMap = new HashMap<>();
for (Map.Entry<String, String> entry : data.entrySet()) {
Map<String, String> valueMap = new HashMap<>();
valueMap.put("value", entry.getValue());
dataMap.put(entry.getKey(), valueMap);
}
requestBody.put("data", dataMap);
// 获取access_token,拼接完整URL
String accessToken = tokenUtil.getStableAccessToken();
// 发送订阅通知的API地址
String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="+ accessToken;
// 发送POST请求
String response = restTemplate.postForObject(url, requestBody, String.class);
log.info("发送微信通知,url:{},requestBody:{},response:{}",url, JSON.toJSONString(requestBody),response);
JSONObject json = new JSONObject(response);
log.info("微信返回数据:{} ",json.toString());
int errcode = json.getInt("errcode");
// 0表示成功
return errcode == 0;
} catch (Exception e) {
log.error("发送微信订阅通知失败", e);
return false;
}
}
}
......@@ -7,9 +7,9 @@ import com.wangxiaolu.promotion.domain.activity.dao.TemporaryActivityLogDao;
import com.wangxiaolu.promotion.domain.activity.dao.TemporaryActivityPhotoDao;
import com.wangxiaolu.promotion.domain.activity.wrapperQo.TemporaryPhotoWrapper;
import com.wangxiaolu.promotion.domain.manage.dao.EmployeeActivityPlanInfoDao;
import com.wangxiaolu.promotion.enums.activity.ActivityClockTaskStatus;
import com.wangxiaolu.promotion.enums.activity.ActivityPhotoType;
import com.wangxiaolu.promotion.enums.activity.ClockType;
import com.wangxiaolu.promotion.enums.activity.LogType;
import com.wangxiaolu.promotion.enums.plan.PlanStatus;
import com.wangxiaolu.promotion.exception.ParamException;
import com.wangxiaolu.promotion.pojo.activity.manage.dto.EmployeeActivityPlanInfoDto;
......@@ -18,6 +18,7 @@ import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryClockDto;
import com.wangxiaolu.promotion.pojo.user.dto.ManageEmployeeInfoDto;
import com.wangxiaolu.promotion.result.basedata.RCode;
import com.wangxiaolu.promotion.service.activity.temporary.TemporaryActivityClockCoreService;
import com.wangxiaolu.promotion.service.activity.temporary.TemporaryActivityTaskClockService;
import com.wangxiaolu.promotion.service.activityplanv2.PromPlanCoreService;
import com.wangxiaolu.promotion.service.activityplanv2.PromPlanQueryService;
import com.wangxiaolu.promotion.utils.OkHttp;
......@@ -57,6 +58,9 @@ public class TemporaryActivityClockCoreServiceImpl implements TemporaryActivityC
private PromPlanQueryService promPlanQueryService;
@Autowired
private PromPlanCoreService promPlanCoreService;
@Autowired
private TemporaryActivityTaskClockService temporaryActivityTaskClockService;
/**
* 促销员当日打卡信息保存
*/
......@@ -152,8 +156,16 @@ public class TemporaryActivityClockCoreServiceImpl implements TemporaryActivityC
saveClockPhoto(dto, clockType);
// 日志保存
// tempActivityLogDao.save(dto.getTemporaryId(), dto.getTemporaryName(), LogType.t_1, dto.getId(), dto);
}
// 生成随机任务和pos上传任务
temporaryActivityTaskClockService.generateRandomClockTask(dto);
temporaryActivityTaskClockService.generatePosUploadTask(dto);
// 下班时修改任务状态
if(ClockType.TEMPORARY_CLOCK_OUT.equals(clockType)){
// 如果10随机任务、9pos任务 状态不是已完成的和未完成的,修改任务状态->未完成
temporaryActivityTaskClockService.updateTaskStatusByType(ActivityClockTaskStatus.UNCOMPLETED.getType(),dto.getId());
}
}
private void clockStoreCalDistanceByStoreQcId(String storeQcId, String clockCoordinates) {
// 查询组织架构参数、创建url
String[] clockCoordinateArr = clockCoordinates.split(",");
......
......@@ -34,7 +34,7 @@ public class TemporaryActivityClockQueryServiceImpl implements TemporaryActivity
private TemporaryInfoDao temporaryInfoDao;
@Override
public TemporaryClockDto findTodayTemporaryClockByTemId(Integer temporaryId) {
public TemporaryClockDto findTodayTemporaryClockByTemId(Long temporaryId) {
String today = DateUtil.today();
TemporaryClockWrapper tcw = new TemporaryClockWrapper()
.setTemporaryId(temporaryId)
......@@ -48,7 +48,7 @@ public class TemporaryActivityClockQueryServiceImpl implements TemporaryActivity
* 查询指定日期打卡信息
*/
@Override
public TemporaryClockDto findTemporaryClockByTemIdAndDate(Integer temporaryId, String createDate) {
public TemporaryClockDto findTemporaryClockByTemIdAndDate(Long temporaryId, String createDate) {
TemporaryClockWrapper tcw = new TemporaryClockWrapper()
.setTemporaryId(temporaryId)
.setCreateDate(createDate);
......@@ -71,7 +71,7 @@ public class TemporaryActivityClockQueryServiceImpl implements TemporaryActivity
findClockPhoto(temporaryClockDto);
if (Objects.nonNull(temporaryClockDto)) {
// 查询促销员手机号
Integer temporaryId = temporaryClockDto.getTemporaryId();
Long temporaryId = temporaryClockDto.getTemporaryId();
WxTemporaryInfoDto wxTemporaryInfoDto = temporaryInfoDao.selectOneById(temporaryId);
temporaryClockDto.setPhone(Objects.isNull(wxTemporaryInfoDto) ? null : wxTemporaryInfoDto.getPhone());
}
......@@ -79,10 +79,21 @@ public class TemporaryActivityClockQueryServiceImpl implements TemporaryActivity
}
@Override
public TemporaryClockDto findLatestClockByTemporaryId(Integer temporaryId) {
public TemporaryClockDto findLatestClockByTemporaryId( Long temporaryId) {
return temporaryActivityClockDao.findLatestClockByTemporaryId(temporaryId);
}
/**
* 查询打卡主信息
* @param wr
* @return
*/
@Override
public TemporaryClockDto findClockInfo(TemporaryClockWrapper wr) {
TemporaryClockDto temporaryClockDto = temporaryActivityClockDao.findClockInfo(wr);
return temporaryClockDto;
}
/**
* 查询打卡图片
*/
......
package com.wangxiaolu.promotion.service.activity.temporary.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.uuid.Generators;
......@@ -10,17 +11,15 @@ import com.wangxiaolu.promotion.domain.activity.dao.*;
import com.wangxiaolu.promotion.domain.activityplanv2.dao.ActivityPlanInfoDao;
import com.wangxiaolu.promotion.domain.user.dao.TemporaryInfoDao;
import com.wangxiaolu.promotion.enums.activity.ActivityPhotoType;
import com.wangxiaolu.promotion.enums.activity.LogType;
import com.wangxiaolu.promotion.enums.activity.TemActApproveStatus;
import com.wangxiaolu.promotion.exception.FlowException;
import com.wangxiaolu.promotion.exception.ParamException;
import com.wangxiaolu.promotion.pojo.activity.planv2.dto.ActivityPlanInfoDto;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.PromotionStoreDto;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryActivityMarketCellDto;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryActivityReportedDto;
import com.wangxiaolu.promotion.pojo.activity.temporary.vo.TemporaryActivityMarketCellVo;
import com.wangxiaolu.promotion.pojo.user.dto.WxTemporaryInfoDto;
import com.wangxiaolu.promotion.result.basedata.RCode;
import com.wangxiaolu.promotion.service.activity.temporary.TemporaryActivityClockQueryService;
import com.wangxiaolu.promotion.service.activity.temporary.TemporaryActivityCoreService;
import com.wangxiaolu.promotion.utils.QinCeUtils;
import lombok.extern.slf4j.Slf4j;
......@@ -61,6 +60,8 @@ public class TemporaryActivityCoreServiceImpl implements TemporaryActivityCoreSe
private TemporaryActivityMarketCellDao temporaryActivityMarketCellDao;
@Autowired
private ActivityPlanInfoDao activityPlanInfoDao;
@Autowired
private TemporaryActivityClockQueryService clockQueryService;
/**
......@@ -105,6 +106,13 @@ public class TemporaryActivityCoreServiceImpl implements TemporaryActivityCoreSe
public void activityDataReportedUpdate(TemporaryActivityReportedDto temActDto) {
// 图片增量保存
saveActivityPhotoV2(temActDto);
// 如果数量小于2 修改状态为 SUBMITTED 已保存
if(ObjectUtil.isAllNotEmpty(temActDto.getTgscPhotoUrls(),temActDto.getTghdPhotoUrls(),temActDto.getTgcjPhotoUrls())
&& temActDto.getTgscPhotoUrls().size()>=2 && temActDto.getTghdPhotoUrls().size()>=2 && temActDto.getTgcjPhotoUrls().size()>=2 ){
temActDto.setApproveStatus(TemActApproveStatus.APPROVED);
}else {
temActDto.setApproveStatus(TemActApproveStatus.SUBMITTED);
}
temporaryActivityReportedDao.updateById(temActDto);
// 售卖单元新增保存
......@@ -162,7 +170,7 @@ public class TemporaryActivityCoreServiceImpl implements TemporaryActivityCoreSe
}
@Override
public void todayActivityDeleteMarketCellReported(Integer temporaryId) {
public void todayActivityDeleteMarketCellReported(Long temporaryId) {
String key = temMarketCellRedisKey(temporaryId);
redisCache.removeKey(key);
}
......@@ -175,17 +183,17 @@ public class TemporaryActivityCoreServiceImpl implements TemporaryActivityCoreSe
}
// 修改/删除 DB库中的数据
if (Objects.nonNull(marketcellVo.getMarketCellId())){
if (Objects.nonNull(marketcellVo.getMarketCellId())) {
todayUpdateMarketCellOneToDb(marketcellVo);
}
}
private void todayUpdateMarketCellOneToDb(TemporaryActivityMarketCellVo marketcellVo) {
if (marketcellVo.operateIsDelete()){
if (marketcellVo.operateIsDelete()) {
temporaryActivityMarketCellDao.deleteById(marketcellVo.getMarketCellId());
}
if (marketcellVo.operateIsUpdate()){
if (marketcellVo.operateIsUpdate()) {
TemporaryActivityMarketCellDto dto = new TemporaryActivityMarketCellDto()
.setId(marketcellVo.getMarketCellId())
.setBag(marketcellVo.getBag())
......@@ -232,7 +240,7 @@ public class TemporaryActivityCoreServiceImpl implements TemporaryActivityCoreSe
}
}
private String temMarketCellRedisKey(Integer temporaryId) {
private String temMarketCellRedisKey(Long temporaryId) {
return RedisKeys.TemporaryKeys.TEMPORARY_ACTIVITY_MARKET_CELL.getKey() + temporaryId + "_" + DateUtil.today();
}
......@@ -242,27 +250,38 @@ public class TemporaryActivityCoreServiceImpl implements TemporaryActivityCoreSe
* @param temActDto 活动提交数据
*/
private void saveActivityPhotoV2(TemporaryActivityReportedDto temActDto) {
Integer temporaryId = temActDto.getTemporaryId();
Long temporaryId = temActDto.getTemporaryId();
Long reportedId = temActDto.getId();
// 推广试吃照片
if (CollectionUtils.isEmpty(temActDto.getTgscPhotoUrls())) {
tempActivityPhotoDao.deleteList(reportedId,ActivityPhotoType.TGSC.getType());
}else {
tempActivityPhotoDao.saveReportedList(temporaryId, reportedId, ActivityPhotoType.TGSC.getType(), temActDto.getTgscPhotoUrls());
tempActivityPhotoDao.deleteList(reportedId, ActivityPhotoType.TGSC.getType());
} else {
tempActivityPhotoDao.saveReportedList(null, temporaryId, reportedId, ActivityPhotoType.TGSC.getType(), temActDto.getTgscPhotoUrls());
}
// 推广互动照片
if (CollectionUtils.isEmpty(temActDto.getTghdPhotoUrls())) {
tempActivityPhotoDao.deleteList(reportedId,ActivityPhotoType.TGHD.getType());
}else {
tempActivityPhotoDao.saveReportedList(temporaryId, reportedId, ActivityPhotoType.TGHD.getType(), temActDto.getTghdPhotoUrls());
tempActivityPhotoDao.deleteList(reportedId, ActivityPhotoType.TGHD.getType());
} else {
// 查询打卡数据 根据上报id 查询
// TemporaryClockWrapper wr = new TemporaryClockWrapper();
// wr.setReportedId(reportedId);
// wr.setTemporaryId(temporaryId);
// TemporaryClockDto clockDto = clockQueryService.findClockInfo(wr);
tempActivityPhotoDao.saveReportedList(null, temporaryId, reportedId, ActivityPhotoType.TGHD.getType(), temActDto.getTghdPhotoUrls());
}
// 推广成交照片
if (CollectionUtils.isEmpty(temActDto.getTgcjPhotoUrls())) {
tempActivityPhotoDao.deleteList(reportedId,ActivityPhotoType.TGCJ.getType());
}else {
tempActivityPhotoDao.saveReportedList(temporaryId, reportedId, ActivityPhotoType.TGCJ.getType(), temActDto.getTgcjPhotoUrls());
tempActivityPhotoDao.deleteList(reportedId, ActivityPhotoType.TGCJ.getType());
} else {
// 查询打卡数据 根据上报id 查询
// TemporaryClockWrapper wr = new TemporaryClockWrapper();
// wr.setReportedId(reportedId);
// wr.setTemporaryId(temporaryId);
// TemporaryClockDto clockDto = clockQueryService.findClockInfo(wr);
tempActivityPhotoDao.saveReportedList(null, temporaryId, reportedId, ActivityPhotoType.TGCJ.getType(), temActDto.getTgcjPhotoUrls());
}
// POS机页面凭证
// if (!CollectionUtils.isEmpty(temActDto.getPsvPhotoUrls())) {
......@@ -271,7 +290,7 @@ public class TemporaryActivityCoreServiceImpl implements TemporaryActivityCoreSe
}
// private void saveActivityPhoto(TemporaryActivityReportedDto temActDto) {
// Integer temporaryId = temActDto.getTemporaryId();
// Long temporaryId = temActDto.getTemporaryId();
// Long reportedId = temActDto.getId();
// // 推广试吃照片
// if (!CollectionUtils.isEmpty(temActDto.getTgscPhotoUrls())) {
......
......@@ -9,12 +9,16 @@ import com.wangxiaolu.promotion.domain.activity.dao.TemporaryActivityMarketCellD
import com.wangxiaolu.promotion.domain.activity.dao.TemporaryActivityPhotoDao;
import com.wangxiaolu.promotion.domain.activity.dao.TemporaryActivityReportedDao;
import com.wangxiaolu.promotion.domain.activity.wrapperQo.TemporaryActivityWrapper;
import com.wangxiaolu.promotion.domain.activity.wrapperQo.TemporaryClockWrapper;
import com.wangxiaolu.promotion.domain.activity.wrapperQo.TemporaryMarketCellWrapper;
import com.wangxiaolu.promotion.domain.activity.wrapperQo.TemporaryPhotoWrapper;
import com.wangxiaolu.promotion.enums.activity.ActivityPhotoType;
import com.wangxiaolu.promotion.pojo.PageInfo;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryActivityMarketCellDto;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryActivityPhotoDto;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryActivityReportedDto;
import com.wangxiaolu.promotion.pojo.activity.temporary.dto.TemporaryClockDto;
import com.wangxiaolu.promotion.service.activity.temporary.TemporaryActivityClockQueryService;
import com.wangxiaolu.promotion.service.activity.temporary.TemporaryActivityQueryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -42,12 +46,13 @@ public class TemporaryActivityQueryServiceImpl implements TemporaryActivityQuery
TemporaryActivityPhotoDao temporaryActivityPhotoDao;
@Autowired
TemporaryActivityMarketCellDao temporaryActivityMarketCellDao;
@Autowired
TemporaryActivityClockQueryService temporaryActivityClockQueryService;
/**
* 根据促销员id查询所有任务
*/
@Override
public void findtemporaryIdActivityDataList(Integer temporaryId, PageInfo pageInfo) {
public void findtemporaryIdActivityDataList(Long temporaryId, PageInfo pageInfo) {
TemporaryActivityWrapper taw = JSONObject.parseObject(JSONObject.toJSONString(pageInfo.getQueryParams()), TemporaryActivityWrapper.class);
taw = Objects.isNull(taw) ? new TemporaryActivityWrapper() : taw;
taw.setTemporaryId(temporaryId);
......@@ -59,7 +64,7 @@ public class TemporaryActivityQueryServiceImpl implements TemporaryActivityQuery
* 根据促销员id查询今日任务
*/
@Override
public TemporaryActivityReportedDto findtemporaryIdTodayActivityData(Integer temporaryId) {
public TemporaryActivityReportedDto findtemporaryIdTodayActivityData(Long temporaryId) {
TemporaryActivityReportedDto dto = temporaryActivityReportedDao.findOneByCurrentDate(temporaryId);
findActivityReportedPhoto(dto);
return dto;
......@@ -69,11 +74,32 @@ public class TemporaryActivityQueryServiceImpl implements TemporaryActivityQuery
public TemporaryActivityReportedDto findTemporaryActivityById(Long activityId) {
TemporaryActivityReportedDto dto = temporaryActivityReportedDao.findOneById(activityId);
findActivityReportedPhotoInfo(dto);
// 验证随机任务照片数量 上周提到每天下午5:30~7:30的随机拍照一次的任务(客流量大的时候要保证促销员在售卖位置)
TemporaryClockWrapper wer = new TemporaryClockWrapper();
wer.setTemporaryId(dto.getTemporaryId())
.setReportedId(activityId);
TemporaryClockDto clockInfo = temporaryActivityClockQueryService.findClockInfo(wer);
// 设置 随机任务照片
TemporaryPhotoWrapper wrapper = new TemporaryPhotoWrapper();
wrapper.setTemporaryId(dto.getTemporaryId())
.setClockId(clockInfo.getId())
.setType(ActivityPhotoType.RANDOM_TASK.getType() );
List<TemporaryActivityPhotoDto> temporaryActivityPhotoDtos = temporaryActivityPhotoDao.selectPhotos(wrapper);
dto.setRandTaskClockPhotoUrls(temporaryActivityPhotoDtos);
TemporaryPhotoWrapper posWrapper = new TemporaryPhotoWrapper();
posWrapper.setTemporaryId(dto.getTemporaryId())
.setClockId(clockInfo.getId())
.setType(ActivityPhotoType.POS_PHOTO.getType() );
List<TemporaryActivityPhotoDto> posTaskClockPhotoUrls = temporaryActivityPhotoDao.selectPhotos(posWrapper);
dto.setPosTaskClockPhotoUrls(posTaskClockPhotoUrls);
return dto;
}
@Override
public JSONArray findActivityMarketCell(Integer temporaryId) {
public JSONArray findActivityMarketCell( Long temporaryId) {
/**
* 将数据保存到redis中Generators
*/
......
package com.wangxiaolu.promotion.utils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.wangxiaolu.promotion.common.constant.TokenConstants;
import com.wangxiaolu.promotion.common.util.JwtTokenUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import javax.servlet.http.HttpServletRequest;
public class AuthUtils {
private static String secret = TokenConstants.SECRET;
/**
* 获取请求token
*/
public static String getToken()
{
return getToken(ServletUtils.getRequest());
}
/**
* 根据request获取请求token
*/
public static String getToken(HttpServletRequest request)
{
// 从header获取token标识
String token = request.getHeader(TokenConstants.AUTHENTICATION);
return replaceTokenPrefix(token);
}
/**
* 裁剪token前缀
*/
public static String replaceTokenPrefix(String token)
{
// 如果前端设置了令牌前缀,则裁剪掉前缀
if (StringUtils.isNotBlank(token) && token.startsWith(TokenConstants.PREFIX))
{
token = token.replaceFirst(TokenConstants.PREFIX, "");
}
return token;
}
/**
* 从令牌中获取数据声明
*
* @param token 令牌
* @return 数据声明
*/
public static Claims parseToken(String token) {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
}
public static String getUserId(String token) {
return JwtTokenUtils.getUserId(parseToken(token));
}
}
......@@ -51,6 +51,32 @@ public class DateUtils {
return Date.from(instant);
}
public static Date parseDateByLocalTime(LocalTime localTime) {
if (localTime == null) {
return null;
}
// 1. 获取当前日期(可替换为任意日期)
LocalDate today = LocalDate.now();
// 2. 组合成 LocalDateTime
LocalDateTime localDateTime = today.atTime(localTime);
// 3. 指定时区(示例:系统默认时区)
ZoneId zoneId = ZoneId.systemDefault(); // 或 ZoneId.of("UTC")
ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
// 4. 转换为 Date
Date date = Date.from(zonedDateTime.toInstant());
// 输出结果
System.out.println("LocalTime: " + localTime);
System.out.println("Date: " + date);
return date;
}
public static LocalDate parseDateBylocalDate(Date date) {
if (date == null) {
return null;
......
package com.wangxiaolu.promotion.utils;
import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.api.R;
import com.wangxiaolu.promotion.common.constant.Constants;
import org.apache.poi.util.StringUtil;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import reactor.core.publisher.Mono;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
/**
* 客户端工具类
*
* @author ruoyi
*/
public class ServletUtils {
/**
* 获取String参数
*/
public static String getParameter(String name) {
return getRequest().getParameter(name);
}
/**
* 获取String参数
*/
public static String getParameter(String name, String defaultValue) {
return Convert.toStr(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Integer参数
*/
public static Integer getParameterToInt(String name) {
return Convert.toInt(getRequest().getParameter(name));
}
/**
* 获取Integer参数
*/
public static Integer getParameterToInt(String name, Integer defaultValue) {
return Convert.toInt(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Boolean参数
*/
public static Boolean getParameterToBool(String name) {
return Convert.toBool(getRequest().getParameter(name));
}
/**
* 获取Boolean参数
*/
public static Boolean getParameterToBool(String name, Boolean defaultValue) {
return Convert.toBool(getRequest().getParameter(name), defaultValue);
}
/**
* 获得所有请求参数
*
* @param request 请求对象{@link ServletRequest}
* @return Map
*/
public static Map<String, String[]> getParams(ServletRequest request) {
final Map<String, String[]> map = request.getParameterMap();
return Collections.unmodifiableMap(map);
}
/**
* 获得所有请求参数
*
* @param request 请求对象{@link ServletRequest}
* @return Map
*/
public static Map<String, String> getParamMap(ServletRequest request) {
Map<String, String> params = new HashMap<>();
for (Map.Entry<String, String[]> entry : getParams(request).entrySet()) {
params.put(entry.getKey(), StringUtil.join(entry.getValue(), ","));
}
return params;
}
/**
* 获取request
*/
public static HttpServletRequest getRequest() {
try {
return getRequestAttributes().getRequest();
} catch (Exception e) {
return null;
}
}
/**
* 获取response
*/
public static HttpServletResponse getResponse() {
try {
return getRequestAttributes().getResponse();
} catch (Exception e) {
return null;
}
}
/**
* 获取session
*/
public static HttpSession getSession() {
return getRequest().getSession();
}
public static ServletRequestAttributes getRequestAttributes() {
try {
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes) attributes;
} catch (Exception e) {
return null;
}
}
public static String getHeader(HttpServletRequest request, String name) {
String value = request.getHeader(name);
if (StringUtils.hasLength(value)) {
return com.baomidou.mybatisplus.core.toolkit.StringUtils.EMPTY;
}
return urlDecode(value);
}
public static Map<String, String> getHeaders(HttpServletRequest request) {
Map<String, String> map = new LinkedCaseInsensitiveMap<>();
Enumeration<String> enumeration = request.getHeaderNames();
if (enumeration != null) {
while (enumeration.hasMoreElements()) {
String key = enumeration.nextElement();
String value = request.getHeader(key);
map.put(key, value);
}
}
return map;
}
/**
* 将字符串渲染到客户端
*
* @param response 渲染对象
* @param string 待渲染的字符串
*/
public static void renderString(HttpServletResponse response, String string) {
try {
response.setStatus(200);
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().print(string);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 是否是Ajax异步请求
*
* @param request
*/
public static boolean isAjaxRequest(HttpServletRequest request) {
String accept = request.getHeader("accept");
if (accept != null && accept.contains("application/json")) {
return true;
}
String xRequestedWith = request.getHeader("X-Requested-With");
if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) {
return true;
}
String uri = request.getRequestURI();
if (uri.contains(".json") || uri.contains(".xml")) {
return true;
}
String ajax = request.getParameter("__ajax");
// return StringUtils.inStringIgnoreCase(ajax, "json", "xml");
return ajax.contains(".json") || ajax.contains(".xml");
}
/**
* 内容编码
*
* @param str 内容
* @return 编码后的内容
*/
public static String urlEncode(String str) {
try {
return URLEncoder.encode(str, Constants.UTF8);
} catch (UnsupportedEncodingException e) {
return com.baomidou.mybatisplus.core.toolkit.StringUtils.EMPTY;
}
}
/**
* 内容解码
*
* @param str 内容
* @return 解码后的内容
*/
public static String urlDecode(String str) {
try {
return URLDecoder.decode(str, Constants.UTF8);
} catch (UnsupportedEncodingException e) {
return com.baomidou.mybatisplus.core.toolkit.StringUtils.EMPTY;
}
}
}
package com.wangxiaolu.promotion.utils;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.wangxiaolu.promotion.common.constant.Constants;
import com.wangxiaolu.promotion.common.redis.service.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Component
@Slf4j
public class WechatAccessTokenUtil {
@Value("${wx.cx_miniapp.app_id}")
private String appid;
@Value("${wx.cx_miniapp.app_secret}")
private String secret;
private static final String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
private static final String STABLE_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/stable_token";
// 缓存access_token,避免频繁调用
private String accessToken;
private long expireTime;
@Resource
private WxMaService wxMaService ;
@Autowired
private RestTemplate restTemplate;
@Autowired
private RedisCache redisCache;
// 获取有效的access_token
public String getAccessToken() {
String accessTokenRedisCache = redisCache.get(Constants.REDIS_ACCESS_TOKEN);
// 检查是否过期,未过期直接返回
if (ObjectUtil.isNotEmpty(accessTokenRedisCache)) {
return accessTokenRedisCache;
}
// 过期则重新获取
String url = String.format(TOKEN_URL, appid, secret);
String response = restTemplate.getForObject(url, String.class);
// string 转json
JSONObject json = JSONObject.parseObject( response) ;
accessToken = json.getString("access_token");
// 有效期(秒)
int expiresIn = json.getIntValue("expires_in");
// 提前5分钟过期
expireTime = System.currentTimeMillis() + (expiresIn - 300) * 1000;
log.info("获取微信access_token,url:{},response:{}",url,response);
redisCache.addToSeconds(Constants.REDIS_ACCESS_TOKEN,accessToken,expiresIn - 300);
return accessToken;
}
public String getStableAccessToken() throws IOException {
String accessTokenRedisCache = redisCache.get(Constants.REDIS_ACCESS_TOKEN);
// 检查是否过期,未过期直接返回
if (ObjectUtil.isNotEmpty(accessTokenRedisCache)) {
return accessTokenRedisCache;
}
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(STABLE_TOKEN_URL);
// 2. 构建请求参数(普通模式,force_refresh=false)
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("grant_type", "client_credential");
paramMap.put("appid", appid);
paramMap.put("secret", secret);
// 普通模式,避免频繁刷新
paramMap.put("force_refresh", false);
// 3. 设置请求头(JSON格式)
httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
httpPost.setEntity(new StringEntity(JSON.toJSONString(paramMap), "UTF-8"));
// 4. 发送请求并解析响应
String response = EntityUtils.toString(httpClient.execute(httpPost).getEntity());
Map<String, Object> resultMap = JSON.parseObject(response, Map.class);
// 5. 处理响应结果(成功则更新缓存,失败则抛异常)
if (resultMap.get("errcode") != null && !"0".equals(resultMap.get("errcode").toString())) {
throw new RuntimeException("获取 access_token 失败:" + resultMap.get("errmsg"));
}
accessToken = resultMap.get("access_token").toString();
int expiresIn = Integer.parseInt(resultMap.get("expires_in").toString());
log.info("获取微信access_token,url:{},response:{}",STABLE_TOKEN_URL,response);
redisCache.addToSeconds(Constants.REDIS_ACCESS_TOKEN,accessToken,expiresIn - 300);
return accessToken;
}
}
package com.wangxiaolu.promotion.websocket;
import com.wangxiaolu.promotion.common.util.JwtTokenUtils;
import com.wangxiaolu.promotion.common.util.JwtUtils;
import io.jsonwebtoken.JwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@Slf4j
public class JwtHandshakeInterceptor implements HandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
// 从请求参数中获取token(前端连接时需携带token参数)
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
String token = servletRequest.getParameter("token");
if (token == null || token.isEmpty()) {
throw new IllegalArgumentException("Token is required");
}
try {
// 验证token并获取用户ID
// String userId = JwtUtils.validateToken(token);
String userId = JwtTokenUtils.getUserId(JwtTokenUtils.parseToken(token));
// 将用户ID存入属性,供后续WebSocket处理器使用
attributes.put("userId", userId);
return true; // 验证通过,允许握手
} catch (JwtException e) {
// 验证失败,拒绝连接
response.setStatusCode(org.springframework.http.HttpStatus.UNAUTHORIZED);
return false;
}
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler wsHandler, Exception exception) {
// 握手后操作(可选)
log.info("Handshake completed");
}
}
package com.wangxiaolu.promotion.websocket;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wangxiaolu.promotion.websocket.pojo.MessageBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.*;
@Slf4j
//@Component
public class TemporaryActivityTaskClockSocketHandler extends TextWebSocketHandler {
// 存储在线会话(用户ID -> 会话)
private static final ConcurrentHashMap<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
// 心跳检测线程池
private final ScheduledExecutorService heartBeatExecutor = new ScheduledThreadPoolExecutor(
1,
r -> {
Thread t = new Thread(r, "TemporaryActivityTaskClock-HeartBeat");
t.setDaemon(false);
return t;
},
new ThreadPoolExecutor.AbortPolicy()
);
private final ObjectMapper objectMapper = new ObjectMapper();
public TemporaryActivityTaskClockSocketHandler() {
log.info("TemporaryActivityTaskClockSocketHandler 初始化");
// 初始化心跳检测(每30秒发送一次ping)
heartBeatExecutor.scheduleAtFixedRate(this::sendHeartBeat, 30, 30, TimeUnit.SECONDS);
}
/**
* 连接建立后调用
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// 从握手属性中获取用户ID
String userId = (String) session.getAttributes().get("userId");
sessions.put(userId, session);
log.info("用户[" + userId + "]连接成功,当前在线:" + sessions.size());
// 发送连接成功消息
session.sendMessage(new TextMessage("连接成功,用户ID:" + userId));
}
/**
* 收到前端消息时调用
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
String userId = (String) session.getAttributes().get("userId");
String payload = message.getPayload();
log.info("收到用户[" + userId + "]的消息:" + payload);
// 处理心跳响应(前端收到ping后返回pong)
if ("pong".equals(payload)) {
log.info("用户[" + userId + "]心跳正常");
return;
}
// 判断payload 是否是json
if (payload.startsWith("{")) {
MessageBean messageBean = null;
try {
messageBean = objectMapper.readValue(payload, MessageBean.class);
} catch (JsonProcessingException e) {
log.error("用户[" + userId + "]消息格式错误:" + payload);
sendToUser(userId, "用户[" + userId + "]消息格式错误:" );
}
// handleMessageType(messageBean);
}
}
private void handleMessageType(MessageBean messageBean) {
switch (messageBean.getMsgType()) {
case "ACTIVITY_START":
// startActivity(messageBean.getContent());
break;
case "ACTIVITY_END":
// endActivity(messageBean.getContent());
break;
default:
log.warn("未知消息类型: {}", messageBean.getMsgType());
}
}
/**
* 连接关闭时调用
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
String userId = (String) session.getAttributes().get("userId");
sessions.remove(userId);
log.info("用户[" + userId + "]断开连接,当前在线:" + sessions.size());
}
/**
* 发送心跳(ping)
*/
private void sendHeartBeat() {
for (Map.Entry<String, WebSocketSession> entry : sessions.entrySet()) {
WebSocketSession session = entry.getValue();
String userId = entry.getKey();
if (session.isOpen()) {
try {
session.sendMessage(new TextMessage("ping"));
} catch (IOException e) {
log.error("用户[" + userId + "]心跳发送失败,强制断开");
try {
session.close();
} catch (IOException ex) {
log.error("关闭会话失败", ex);
ex.printStackTrace();
}
sessions.remove(userId);
}
}
}
}
/**
* 广播消息给所有在线用户
*/
public void broadcast(String message) throws IOException {
for (WebSocketSession session : sessions.values()) {
if (session.isOpen()) {
session.sendMessage(new TextMessage(message));
}
}
}
/**
* 向指定用户发送消息
*/
public Integer sendToUser(String userId, String message) {
WebSocketSession session = sessions.get(userId);
if (session != null && session.isOpen()) {
try {
session.sendMessage(new TextMessage(message));
} catch (IOException e) {
log.error("用户[" + userId + "]发送字符消息失败:" + message);
return 0;
}
return 1;
}
return 0;
}
public Integer sendToUser(String userId, MessageBean messageBean) {
WebSocketSession session = sessions.get(userId);
if (session != null && session.isOpen()) {
try {
String jsonMessage = objectMapper.writeValueAsString(messageBean);
session.sendMessage(new TextMessage(jsonMessage));
} catch (IOException e) {
log.error("用户[" + userId + "]发送Bean消息失败:" + e.getMessage());
return 0;
}
return 1;
}else{
log.warn("发送信息失败:用户[" + userId + "]不存在链接" );
return 0;
}
}
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
log.error("用户[" + session.getAttributes().get("userId") + "]异常断开");
}
}
package com.wangxiaolu.promotion.websocket.pojo;
import cn.hutool.json.JSONObject;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* 消息bean
* @author : lvbencai
* @date : 2025/11/13
*/
@Data
public class MessageBean {
@JsonProperty("msgType")
private String msgType;
@JsonProperty("data")
private Object data;
}
package com.wangxiaolu.promotion.xxljobtask;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wangxiaolu.promotion.common.enums.FlagType;
import com.wangxiaolu.promotion.domain.activity.mapper.entity.TemporaryActivityTaskClockDO;
import com.wangxiaolu.promotion.enums.activity.ActivityClockTaskStatus;
import com.wangxiaolu.promotion.enums.activity.ActivityPhotoType;
import com.wangxiaolu.promotion.enums.activity.TemporaryActivityTaskClockMessageType;
import com.wangxiaolu.promotion.pojo.user.dto.WxTemporaryInfoDto;
import com.wangxiaolu.promotion.service.activity.manage.EmployeeCoreTemporaryInfoService;
import com.wangxiaolu.promotion.service.activity.temporary.TemporaryActivityTaskClockService;
import com.wangxiaolu.promotion.service.activity.temporary.impl.SubscribeMessageService;
import com.wangxiaolu.promotion.websocket.TemporaryActivityTaskClockSocketHandler;
import com.wangxiaolu.promotion.websocket.pojo.MessageBean;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.wangxiaolu.promotion.common.constant.WechatConstants.RANDOM_TASK_URL;
import static com.wangxiaolu.promotion.common.constant.WechatConstants.SUBSCRIBE_MESSAGE_TEMPLATE_ID;
/**
* @author : liqiulin
* @date : 2024-09-10 12
* @describe : 活动类型操作
*/
@Component
@Slf4j
public class ActivityStautsHandler {
@Autowired
private TemporaryActivityTaskClockService taskClockService;
@Autowired
private SubscribeMessageService messageService;
@Autowired
private TemporaryActivityTaskClockSocketHandler taskClockSocketHandler;
@Autowired
private EmployeeCoreTemporaryInfoService temporaryInfoService;
/**
* 测试发送websocket消息
*/
@XxlJob("testSubscribeMessage")
public void TestSubscribeMessage() {
List<TemporaryActivityTaskClockDO> list = taskClockService.list(new LambdaQueryWrapper<TemporaryActivityTaskClockDO>()
.eq(TemporaryActivityTaskClockDO::getTaskType, ActivityPhotoType.RANDOM_TASK.getType())
.eq(TemporaryActivityTaskClockDO::getIsDelete, FlagType.NO.getType())
.eq(TemporaryActivityTaskClockDO::getCreateDate, DateUtil.format(new Date(), "yyyy-MM-dd"))
);
for (TemporaryActivityTaskClockDO taskClockDO : list) {
String msgType = TemporaryActivityTaskClockMessageType.RANDOM_TASK_START.getType();
sendWebsocketMessage(taskClockDO,msgType);
}
}
@XxlJob("sendSubscribeMessage")
public void sendSubscribeMessage() {
DateTime undoDateTime = DateUtil.offsetMinute(new Date(), -15);
/**
* 处理未开始的随机任务状态更新
* <p>
* 查询所有符合以下条件的临时活动任务:
* 1. 任务状态为【待开始】
* 2. 任务类型为【随机任务】
* 3. 未被标记为删除
* 4. 要求锁定时间小于等于指定截止时间(undoDateTime)
* <p>
* 将符合条件的任务状态更新为【未完成】,并重置订阅发送标志为【未发送】
*/
List<TemporaryActivityTaskClockDO> unstartList = taskClockService.list(new LambdaQueryWrapper<TemporaryActivityTaskClockDO>()
.eq(TemporaryActivityTaskClockDO::getTaskStatus, ActivityClockTaskStatus.TO_BE_START.getType())
.eq(TemporaryActivityTaskClockDO::getTaskType, ActivityPhotoType.RANDOM_TASK.getType())
.eq(TemporaryActivityTaskClockDO::getIsDelete, FlagType.NO.getType())
// 小于等于
.le(TemporaryActivityTaskClockDO::getRequiredlockTime, undoDateTime));
for (TemporaryActivityTaskClockDO taskClockDO : unstartList){
taskClockDO.setIsSendSubscribe(FlagType.NO.getType());
taskClockDO.setTaskStatus(ActivityClockTaskStatus.UNCOMPLETED.getType());
taskClockService.updateById(taskClockDO);
}
// 查询没有做随机任务的, 超过15分钟的,但是状态还是1进行中的 状态改成未完成,表示未拍照做任务
List<TemporaryActivityTaskClockDO> undoList = taskClockService.list(new LambdaQueryWrapper<TemporaryActivityTaskClockDO>()
.eq(TemporaryActivityTaskClockDO::getTaskStatus, ActivityClockTaskStatus.STARTING.getType())
.eq(TemporaryActivityTaskClockDO::getTaskType, ActivityPhotoType.RANDOM_TASK.getType())
.eq(TemporaryActivityTaskClockDO::getIsDelete, FlagType.NO.getType())
// 小于等于
.le(TemporaryActivityTaskClockDO::getRequiredlockTime, undoDateTime));
for (TemporaryActivityTaskClockDO taskClockDO : undoList){
taskClockDO.setIsSendSubscribe(FlagType.NO.getType());
taskClockDO.setTaskStatus(ActivityClockTaskStatus.UNCOMPLETED.getType());
taskClockService.updateById(taskClockDO);
// 未完成的
// String msgType = TemporaryActivityTaskClockMessageType.RANDOM_TASK_UNCOMPLETED.getType();
// sendWebsocketMessage(taskClockDO,msgType);
}
// 待开始的 ->进行中
List<TemporaryActivityTaskClockDO> list = taskClockService.list(new LambdaQueryWrapper<TemporaryActivityTaskClockDO>()
.eq(TemporaryActivityTaskClockDO::getTaskStatus, ActivityClockTaskStatus.TO_BE_START.getType())
.eq(TemporaryActivityTaskClockDO::getTaskType, ActivityPhotoType.RANDOM_TASK.getType())
.eq(TemporaryActivityTaskClockDO::getIsDelete, FlagType.NO.getType())
.between(TemporaryActivityTaskClockDO::getRequiredlockTime, undoDateTime ,new Date())
);
// 进行中的 还没发通知的
List<TemporaryActivityTaskClockDO> startingList = taskClockService.list(new LambdaQueryWrapper<TemporaryActivityTaskClockDO>()
.eq(TemporaryActivityTaskClockDO::getTaskStatus, ActivityClockTaskStatus.STARTING.getType())
.eq(TemporaryActivityTaskClockDO::getIsSendSubscribe, FlagType.NO.getType())
.eq(TemporaryActivityTaskClockDO::getTaskType, ActivityPhotoType.RANDOM_TASK.getType())
.eq(TemporaryActivityTaskClockDO::getIsDelete, FlagType.NO.getType())
.le(TemporaryActivityTaskClockDO::getRequiredlockTime, new Date())
.ge(TemporaryActivityTaskClockDO::getRequiredlockTime, undoDateTime)
);
list.addAll(startingList);
for (TemporaryActivityTaskClockDO taskClockDO : list) {
String msgType = TemporaryActivityTaskClockMessageType.RANDOM_TASK_START.getType();
sendWebsocketMessage(taskClockDO,msgType);
sendWxMessage(taskClockDO);
// 修改状态 待开始 -> 进行中
taskClockDO.setTaskStatus(ActivityClockTaskStatus.STARTING.getType());
taskClockService.updateById(taskClockDO);
}
}
private void sendWebsocketMessage(TemporaryActivityTaskClockDO taskClockDO, String msgType) {
// 发送websocket 通知用户
MessageBean msgBean = new MessageBean();
msgBean.setMsgType(msgType);
msgBean.setData(taskClockDO);
Integer successFlag = taskClockSocketHandler.sendToUser(taskClockDO.getTemporaryId().toString(), msgBean);
if(successFlag == 1){
log.info("完成发送websocket信息,用户id:{}", taskClockDO.getTemporaryId());
taskClockDO.setIsSendSubscribe(FlagType.YES.getType());
}
}
/**
* 发送微信模板消息
* @param taskClockDO
*/
private void sendWxMessage(TemporaryActivityTaskClockDO taskClockDO) {
if(ObjectUtil.isEmpty(taskClockDO.getSubscribeTime())){
// 2. 构建模板数据(根据小程序订阅模板的字段定义)
Map<String, String> data = new HashMap<>();
// 模板中的字段1发布人
data.put("thing2", "小卤促销平台");
// 模板中的字段2 截止时间
DateTime requiredlockTime = DateUtil.offsetMinute(taskClockDO.getRequiredlockTime(), 15);
data.put("time3", DateUtil.format(requiredlockTime,"yyyy-MM-dd HH:mm"));
// 模板中的字段3 任务名称
data.put("thing1", "请拍摄清晰的工作场景照片");
// 模板中的字段4 温馨提示
data.put("thing4", "请在15分钟内完成任务");
// 3. 发送通知
// 获取openid
WxTemporaryInfoDto wxTemporaryInfoDto = temporaryInfoService.selectById(taskClockDO.getTemporaryId());
String openid = wxTemporaryInfoDto.getOpenId();
// 3. 发送通知
String templateId = SUBSCRIBE_MESSAGE_TEMPLATE_ID;
boolean success = messageService.sendSubscribeMessage(
openid,
templateId,
// 跳转页面
RANDOM_TASK_URL,
data
);
log.info("促销员微信订阅通知发送结果:{},openid:{}", success, openid);
if (success) {
taskClockDO.setSubscribeTime(new Date());
taskClockDO.setSubscribeStatus(FlagType.YES.getType());
}
}
}
}
......@@ -100,4 +100,6 @@ public class XxlJobHandler {
log.info("[xxl-job] end === 同步昨日经销商");
}
}
......@@ -12,8 +12,7 @@ spring:
database: 0
password: QjL6H5nH
main:
web-application-type: reactive
cloud:
nacos:
......@@ -22,8 +21,7 @@ spring:
namespace: 68c8d97c-715a-4983-99b7-9df9b99f89e7
group: promotion
logging:
config: classpath:logback-spring.xml
async:
executor:
......@@ -47,6 +45,7 @@ wx:
cx_miniapp:
app_id: wxac14dc7765484d7d
app_secret: e73b574380a822c942e03ea4dc67aaa1
miniprogram_state: trial
tengxunyun:
# 腾讯云个人账号信息
......@@ -106,4 +105,4 @@ aliyun:
sts-role-arm: acs:ram::1819206190412770:role/oss-admin-role
session-name: promotion-dev-miniapp
bucket-name: link-promotion-dev
web-js-link: link-promotion-dev.oss-cn-shanghai.aliyuncs.com
\ No newline at end of file
web-js-link: link-promotion-dev.oss-cn-shanghai.aliyuncs.com
......@@ -11,8 +11,6 @@ spring:
database: 0
password: Wxl2025!@#$
main:
web-application-type: reactive
cloud:
nacos:
......@@ -21,8 +19,7 @@ spring:
namespace: a9d4d153-3d4e-4d2f-968e-dffdfcc24bab
group: promotion
logging:
config: classpath:logback-spring.xml
async:
executor:
......@@ -46,6 +43,8 @@ wx:
cx_miniapp:
app_id: wxac14dc7765484d7d
app_secret: e73b574380a822c942e03ea4dc67aaa1
miniprogram_state: fomal
tengxunyun:
# 腾讯云个人账号信息
secret_d: AKIDVt353sWyY0GXn0ANa0YyGdwDIBtjQwGS
......@@ -97,4 +96,4 @@ aliyun:
sts-role-arm: acs:ram::1819206190412770:role/oss-admin-role
session-name: promotion-live-miniapp
bucket-name: link-promotion
web-js-link: link-promotion.oss-cn-shanghai.aliyuncs.com
\ No newline at end of file
web-js-link: link-promotion.oss-cn-shanghai.aliyuncs.com
......@@ -12,8 +12,6 @@ spring:
database: 0
password: QjL6H5nH
main:
web-application-type: reactive
cloud:
nacos:
......@@ -22,8 +20,6 @@ spring:
namespace: 3b774c2d-b03b-4816-8fe8-a41f458ebbcc
group: promotion
logging:
config: classpath:logback-spring.xml
async:
executor:
......@@ -47,6 +43,8 @@ wx:
cx_miniapp:
app_id: wxac14dc7765484d7d
app_secret: e73b574380a822c942e03ea4dc67aaa1
miniprogram_state: trial
tengxunyun:
# 腾讯云个人账号信息
secret_d: AKIDVt353sWyY0GXn0ANa0YyGdwDIBtjQwGS
......@@ -104,4 +102,4 @@ aliyun:
sts-role-arm: acs:ram::1819206190412770:role/oss-admin-role
session-name: promotion-dev-miniapp
bucket-name: link-promotion-dev
web-js-link: link-promotion-dev.oss-cn-shanghai.aliyuncs.com
\ No newline at end of file
web-js-link: link-promotion-dev.oss-cn-shanghai.aliyuncs.com
......@@ -4,6 +4,12 @@ server:
spring:
application:
name: wangxiaolu-promotion-service
main:
# web-application-type: reactive
web-application-type: servlet
profiles:
active: dev
logging:
config: classpath:logback-spring.xml
......@@ -27,9 +27,9 @@
</update>
<insert id="insertList">
insert into temporary_activity_photo (temporary_id, reported_id, type, photo_url, photo_filed_id)
insert into temporary_activity_photo (temporary_id, reported_id,clock_id, type, photo_url, photo_filed_id)
<foreach collection="dos" item="item" index="index" separator=" UNION ALL ">
SELECT #{item.temporaryId}, #{item.reportedId}, #{item.type}, #{item.photoUrl}, #{item.photoFiledId} FROM dual
SELECT #{item.temporaryId}, #{item.reportedId}, #{item.clockId}, #{item.type}, #{item.photoUrl}, #{item.photoFiledId} FROM dual
WHERE NOT EXISTS( SELECT 1 FROM temporary_activity_photo WHERE reported_id = #{item.reportedId} AND type = #{item.type} AND photo_filed_id = #{item.photoFiledId} )
</foreach>
</insert>
......@@ -41,6 +41,22 @@
</foreach>
</update>
<insert id="insertListByClockId">
insert into temporary_activity_photo (temporary_id, reported_id,clock_id, type, photo_url, photo_filed_id)
<foreach collection="dos" item="item" index="index" separator=" UNION ALL ">
SELECT #{item.temporaryId}, #{item.reportedId}, #{item.clockId}, #{item.type}, #{item.photoUrl}, #{item.photoFiledId} FROM dual
WHERE NOT EXISTS( SELECT 1 FROM temporary_activity_photo WHERE clock_id = #{item.clockId} AND type = #{item.type} AND photo_filed_id = #{item.photoFiledId} )
</foreach>
</insert>
<update id="updateListByClockId">
update temporary_activity_photo set is_delete = 0 where clock_id = #{clockId} and type = #{photoType} and photo_filed_id not in
<foreach collection="dos" item="item" index="index" open="(" separator="," close=")">
#{item.photoFiledId}
</foreach>
</update>
<update id="deletebyReportedId">
update temporary_activity_photo set is_delete = 0 where reported_id = #{reportedId} and type = #{photoType};
</update>
......
......@@ -4,11 +4,16 @@ import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.tomcat.jni.Local;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
......@@ -22,6 +27,7 @@ import static org.junit.jupiter.api.Assertions.*;
*/
@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
class DateUtilsTest {
@Test
......@@ -30,6 +36,14 @@ class DateUtilsTest {
System.out.println("是否在时间范围内:" + b);
}
@Test
void parseDateByLocalTime() {
LocalTime localTime = LocalTime.of(16, 0, 0);
Date date = DateUtils.parseDateByLocalTime(localTime);
log.info("时间:{}", DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"));
log.info("时间:{}", localTime);
}
public static void main(String[] args) {
Map<String, Object> params = new HashMap<>();
// 根据来源第三方系统的员工唯一标识精确查询,id、emp_id如果同时存在优先取id
......@@ -50,4 +64,4 @@ class DateUtilsTest {
params.put("emp_mobile", "");
System.out.println(JSONObject.toJSONString(params));
}
}
\ No newline at end of file
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论