Commit 2bf05374 2bf053742d549dd4a7a4de6e74f6fc144d232311 by xianghan@topdraw.cn

V1.0.2.REALESE

1 parent dc5e7311
Showing 22 changed files with 1291 additions and 99 deletions
1 package com.topdraw.business.module.user.weixin.collection.domain;
2
3 import cn.hutool.core.bean.BeanUtil;
4 import cn.hutool.core.bean.copier.CopyOptions;
5 import lombok.Data;
6 import lombok.experimental.Accessors;
7 import org.springframework.data.annotation.CreatedDate;
8 import org.springframework.data.annotation.LastModifiedDate;
9 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
10
11 import javax.persistence.*;
12 import java.io.Serializable;
13 import java.sql.Timestamp;
14
15 /**
16 * @author pengmengqing
17 * @date 2021-04-02
18 */
19 @Entity
20 @Data
21 @EntityListeners(AuditingEntityListener.class)
22 @Accessors(chain = true)
23 @Table(name="uc_user_collection")
24 public class UserCollection implements Serializable {
25
26 // ID
27 @Id
28 @GeneratedValue(strategy = GenerationType.IDENTITY)
29 @Column(name = "id")
30 private Long id;
31
32 // 应用ID
33 @Column(name = "app_id")
34 private Long appId;
35
36 // 用户ID
37 @Column(name = "user_id")
38 private Long userId;
39
40 // 收藏夹类型:1-收藏 2-播放记录 3-播放列表 4-评分 5-点赞/关注/订阅
41 @Column(name = "type")
42 private Integer type;
43
44 // 收藏夹名称
45 @Column(name = "name")
46 private String name;
47
48 // 数量
49 @Column(name = "count")
50 private Integer count;
51
52 // 创建时间
53 @CreatedDate
54 @Column(name = "create_time")
55 private Timestamp createTime;
56
57 // 更新时间
58 @LastModifiedDate
59 @Column(name = "update_time")
60 private Timestamp updateTime;
61
62 public void copy(UserCollection source){
63 BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
64 }
65 }
1 package com.topdraw.business.module.user.weixin.collection.domain;
2
3 import cn.hutool.core.bean.BeanUtil;
4 import cn.hutool.core.bean.copier.CopyOptions;
5 import lombok.Data;
6 import lombok.experimental.Accessors;
7 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
8
9 import javax.persistence.*;
10 import java.io.Serializable;
11 import java.sql.Timestamp;
12
13 /**
14 * @author pengmengqing
15 * @date 2021-04-02
16 */
17 @Entity
18 @Data
19 @EntityListeners(AuditingEntityListener.class)
20 @Accessors(chain = true)
21 @Table(name="uc_user_collection_detail")
22 public class UserCollectionDetail implements Serializable {
23
24 @ManyToOne(fetch = FetchType.EAGER)
25 @JoinColumn(name = "user_collection_id", insertable = false, updatable = false)
26 private UserCollection userCollection;
27
28 // ID
29 @Id
30 @GeneratedValue(strategy = GenerationType.IDENTITY)
31 @Column(name = "id")
32 private Long id;
33
34 // 收藏夹ID
35 @Column(name = "user_collection_id")
36 private Long userCollectionId;
37
38 // 自定义收藏内容的类型CODE,默认:DEFAULT
39 @Column(name = "detail_folder_code")
40 private String detailFolderCode;
41
42 // 收藏内容的类型:MEDIA|EPISODE|CATEGORY|SUBJECT|ARTICLE|ARTIST|SCHOOL
43 @Column(name = "detail_type")
44 private String detailType;
45
46 // 收藏内容的ID
47 @Column(name = "detail_id")
48 private Long detailId;
49
50 // 收藏内容的CODE
51 @Column(name = "detail_code")
52 private String detailCode;
53
54 // 收藏内容的剧集ID
55 @Column(name = "detail_episode_id")
56 private Long detailEpisodeId;
57
58 // 收藏内容的剧集CODE
59 @Column(name = "detail_episode_code")
60 private String detailEpisodeCode;
61
62 // 收藏内容的名称
63 @Column(name = "detail_name")
64 private String detailName;
65
66 // 收藏内容的标记
67 @Column(name = "detail_mark")
68 private Integer detailMark;
69
70 // 收藏内容的图片
71 @Column(name = "detail_img")
72 private String detailImg;
73
74 // 收藏内容的剧集序号
75 @Column(name = "detail_index")
76 private Integer detailIndex;
77
78 // 收藏内容的剧集总数
79 @Column(name = "detail_total_index")
80 private Integer detailTotalIndex;
81
82 // 收藏内容的播放时间
83 @Column(name = "detail_play_time")
84 private Integer detailPlayTime;
85
86 // 收藏内容的总时间
87 @Column(name = "detail_total_time")
88 private Integer detailTotalTime;
89
90 // 收藏内容在同一folder中的顺序
91 @Column(name = "detail_sequence")
92 private Integer detailSequence;
93
94 // 收藏内容的评分
95 @Column(name = "detail_score")
96 private Float detailScore;
97
98 // 收藏内容(根据文件夹和类型的不同)的点赞/关注/订阅
99 @Column(name = "detail_like")
100 private Integer detailLike;
101
102 // 收藏内容的扩展数据
103 @Column(name = "detail_ext_data")
104 private String detailExtData;
105
106 // 创建时间
107 @Column(name = "create_time")
108 private Timestamp createTime;
109
110 // 更新时间
111 @Column(name = "update_time")
112 private Timestamp updateTime;
113
114 public void copy(UserCollectionDetail source){
115 BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
116 }
117 }
1 package com.topdraw.business.module.user.weixin.collection.repository;
2
3 import com.topdraw.business.module.user.weixin.collection.domain.UserCollectionDetail;
4 import org.springframework.data.jpa.repository.JpaRepository;
5 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
6 import org.springframework.data.jpa.repository.Modifying;
7
8 import java.util.Optional;
9
10 /**
11 * @author pengmengqing
12 * @date 2021-04-02
13 */
14 public interface UserCollectionDetailRepository extends JpaRepository<UserCollectionDetail, Long>, JpaSpecificationExecutor<UserCollectionDetail> {
15
16 @Modifying
17 void deleteAllByUserCollectionId(Long userCollectionId);
18
19 Optional<UserCollectionDetail> findByDetailIdAndDetailTypeAndUserCollectionId(Long detailId, String detailType, Long userCollectionId);
20 }
1 package com.topdraw.business.module.user.weixin.collection.repository;
2
3
4 import com.topdraw.business.module.user.weixin.collection.domain.UserCollection;
5 import org.springframework.data.jpa.repository.JpaRepository;
6 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
7
8 import java.util.List;
9 import java.util.Optional;
10
11 /**
12 * @author pengmengqing
13 * @date 2021-04-02
14 */
15 public interface UserCollectionRepository extends JpaRepository<UserCollection, Long>, JpaSpecificationExecutor<UserCollection> {
16
17 Optional<UserCollection> findFirstByUserIdAndTypeAndName(Long userId, Integer type, String name);
18
19 List<UserCollection> findByUserIdAndType(Long userId, Integer type);
20
21 }
1 package com.topdraw.business.module.user.weixin.collection.service;
2
3 import com.topdraw.business.module.user.weixin.collection.domain.UserCollectionDetail;
4 import com.topdraw.business.module.user.weixin.collection.service.dto.UserCollectionDetailDTO;
5 import com.topdraw.business.module.user.weixin.collection.service.dto.UserCollectionDetailQueryCriteria;
6 import org.springframework.data.domain.Pageable;
7
8 import java.util.List;
9 import java.util.Map;
10
11 /**
12 * @author pengmengqing
13 * @date 2021-04-02
14 */
15 public interface UserCollectionDetailService {
16
17 /**
18 * 查询数据分页
19 * @param criteria 条件参数
20 * @param pageable 分页参数
21 * @return Map<String,Object>
22 */
23 Map<String,Object> queryAll(UserCollectionDetailQueryCriteria criteria, Pageable pageable);
24
25 /**
26 * 根据ID查询
27 * @param id ID
28 * @return UserCollectionDetailDTO
29 */
30 UserCollectionDetailDTO findById(Long id);
31
32 UserCollectionDetailDTO create(UserCollectionDetail resources);
33
34 void update(UserCollectionDetail resources);
35
36 void delete(Long id);
37
38 void deleteAllByUserCollectionId(Long id);
39
40 void deleteAll(List<UserCollectionDetail> userCollectionDetailOptional);
41 }
1 package com.topdraw.business.module.user.weixin.collection.service;
2
3 import com.topdraw.business.module.user.weixin.collection.domain.UserCollection;
4 import com.topdraw.business.module.user.weixin.collection.service.dto.UserCollectionDTO;
5 import com.topdraw.business.module.user.weixin.collection.service.dto.UserCollectionQueryCriteria;
6 import org.springframework.data.domain.Pageable;
7
8 import javax.servlet.http.HttpServletResponse;
9 import java.io.IOException;
10 import java.util.List;
11 import java.util.Map;
12 import java.util.Optional;
13
14 /**
15 * @author pengmengqing
16 * @date 2021-04-02
17 */
18 public interface UserCollectionService {
19
20 /**
21 * 查询数据分页
22 * @param criteria 条件参数
23 * @param pageable 分页参数
24 * @return Map<String,Object>
25 */
26 Map<String,Object> queryAll(UserCollectionQueryCriteria criteria, Pageable pageable);
27
28 /**
29 * 查询所有数据不分页
30 * @param criteria 条件参数
31 * @return List<UserCollectionDTO>
32 */
33 List<UserCollectionDTO> queryAll(UserCollectionQueryCriteria criteria);
34
35 /**
36 * 根据ID查询
37 * @param id ID
38 * @return UserCollectionDTO
39 */
40 UserCollectionDTO findById(Long id);
41
42 UserCollectionDTO create(UserCollection resources);
43
44 void update(UserCollection resources);
45
46 void delete(Long id);
47
48 void download(List<UserCollectionDTO> all, HttpServletResponse response) throws IOException;
49
50 List<UserCollection> findByUserIdAndType(Long id, Integer type);
51
52 Optional<UserCollection> findFirstByUserIdAndTypeAndName(Long id, Integer type, String name);
53
54 void save(UserCollection userCollection);
55 }
1 package com.topdraw.business.module.user.weixin.collection.service.dto;
2
3 import lombok.Data;
4
5 import java.io.Serializable;
6 import java.sql.Timestamp;
7
8
9 /**
10 * @author pengmengqing
11 * @date 2021-04-02
12 */
13 @Data
14 public class UserCollectionDTO implements Serializable {
15
16 // ID
17 private Long id;
18
19 // 应用ID
20 private Long appId;
21
22 // 用户ID
23 private Long userId;
24
25 // 收藏夹类型:1-收藏 2-播放记录 3-播放列表 4-评分 5-点赞/关注/订阅
26 private Integer type;
27
28 // 收藏夹名称
29 private String name;
30
31 // 数量
32 private Integer count;
33
34 // 创建时间
35 private Timestamp createTime;
36
37 // 更新时间
38 private Timestamp updateTime;
39 }
1 package com.topdraw.business.module.user.weixin.collection.service.dto;
2
3 import com.fasterxml.jackson.annotation.JsonFormat;
4 import lombok.Data;
5
6 import java.io.Serializable;
7 import java.sql.Timestamp;
8
9
10 /**
11 * @author pengmengqing
12 * @date 2021-04-02
13 */
14 @Data
15 public class UserCollectionDetailDTO implements Serializable {
16
17 // ID
18 private Long id;
19
20 // 收藏夹ID
21 private Long userCollectionId;
22
23 // 自定义收藏内容的类型CODE,默认:DEFAULT
24 private String detailFolderCode;
25
26 // 收藏内容的类型:MEDIA|EPISODE|CATEGORY|SUBJECT|ARTICLE|ARTIST|SCHOOL
27 private String detailType;
28
29 // 收藏内容的ID
30 private Long detailId;
31
32 // 收藏内容的CODE
33 private String detailCode;
34
35 // 收藏内容的剧集ID
36 private Long detailEpisodeId;
37
38 // 收藏内容的剧集CODE
39 private String detailEpisodeCode;
40
41 // 收藏内容的名称
42 private String detailName;
43
44 // 收藏内容的标记
45 private Integer detailMark;
46
47 // 收藏内容的图片
48 private String detailImg;
49
50 // 收藏内容的剧集序号
51 private Integer detailIndex;
52
53 // 收藏内容的剧集总数
54 private Integer detailTotalIndex;
55
56 // 收藏内容的播放时间
57 private Integer detailPlayTime;
58
59 // 收藏内容的总时间
60 private Integer detailTotalTime;
61
62 // 收藏内容在同一folder中的顺序
63 private Integer detailSequence;
64
65 // 收藏内容的评分
66 private Float detailScore;
67
68 // 收藏内容(根据文件夹和类型的不同)的点赞/关注/订阅
69 private Integer detailLike;
70
71 // 收藏内容的扩展数据
72 private String detailExtData;
73
74 // 创建时间
75 @JsonFormat(
76 pattern = "MM月dd日 HH:mm",
77 timezone = "GMT+8"
78 )
79 private Timestamp createTime;
80
81 // 更新时间
82 @JsonFormat(
83 pattern = "MM月dd日 HH:mm",
84 timezone = "GMT+8"
85 )
86 private Timestamp updateTime;
87 }
1 package com.topdraw.business.module.user.weixin.collection.service.dto;
2
3 import com.topdraw.annotation.Query;
4 import lombok.Data;
5
6 import javax.persistence.criteria.JoinType;
7
8 /**
9 * @author pengmengqing
10 * @date 2021-04-02
11 */
12 @Data
13 public class UserCollectionDetailQueryCriteria{
14
15 private Long userWeixinId;
16
17
18 @Query(joinType = JoinType.INNER, joinName = "userCollection")
19 private Long userId;
20
21 @Query(joinType = JoinType.INNER, joinName = "userCollection")
22 private Integer type;
23
24 private String detailType;
25
26 private String detailFolderCode = "DEFAULT";
27
28 private Long detailId;
29 }
1 package com.topdraw.business.module.user.weixin.collection.service.dto;
2
3 import lombok.Data;
4
5 /**
6 * @author pengmengqing
7 * @date 2021-04-02
8 */
9 @Data
10 public class UserCollectionQueryCriteria{
11 }
1 package com.topdraw.business.module.user.weixin.collection.service.impl;
2
3 import com.topdraw.business.module.user.weixin.collection.domain.UserCollectionDetail;
4 import com.topdraw.business.module.user.weixin.collection.repository.UserCollectionDetailRepository;
5 import com.topdraw.business.module.user.weixin.collection.service.UserCollectionDetailService;
6 import com.topdraw.business.module.user.weixin.collection.service.dto.UserCollectionDetailDTO;
7 import com.topdraw.business.module.user.weixin.collection.service.dto.UserCollectionDetailQueryCriteria;
8 import com.topdraw.business.module.user.weixin.collection.service.mapper.UserCollectionDetailMapper;
9 import com.topdraw.utils.*;
10 import org.springframework.beans.factory.annotation.Autowired;
11 import org.springframework.dao.EmptyResultDataAccessException;
12 import org.springframework.data.domain.Page;
13 import org.springframework.data.domain.Pageable;
14 import org.springframework.stereotype.Service;
15 import org.springframework.transaction.annotation.Propagation;
16 import org.springframework.transaction.annotation.Transactional;
17 import org.springframework.util.Assert;
18
19 import java.util.*;
20
21 /**
22 * @author pengmengqing
23 * @date 2021-04-02
24 */
25 @Service
26 @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
27 public class UserCollectionDetailServiceImpl implements UserCollectionDetailService {
28
29 @Autowired
30 private UserCollectionDetailRepository userCollectionDetailRepository;
31
32 @Autowired
33 private UserCollectionDetailMapper userCollectionDetailMapper;
34
35 @Override
36 public Map<String, Object> queryAll(UserCollectionDetailQueryCriteria criteria, Pageable pageable) {
37 Page<UserCollectionDetail> page = userCollectionDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
38 return PageUtil.toPage(page.map(userCollectionDetailMapper::toDto));
39 }
40
41 @Override
42 public UserCollectionDetailDTO findById(Long id) {
43 UserCollectionDetail userCollectionDetail = userCollectionDetailRepository.findById(id).orElseGet(UserCollectionDetail::new);
44 ValidationUtil.isNull(userCollectionDetail.getId(),"UserCollectionDetail","id",id);
45 return userCollectionDetailMapper.toDto(userCollectionDetail);
46 }
47
48 @Override
49 @Transactional(rollbackFor = Exception.class)
50 public UserCollectionDetailDTO create(UserCollectionDetail resources) {
51 return userCollectionDetailMapper.toDto(userCollectionDetailRepository.save(resources));
52 }
53
54 @Override
55 @Transactional(rollbackFor = Exception.class)
56 public void update(UserCollectionDetail resources) {
57 UserCollectionDetail userCollectionDetail = userCollectionDetailRepository.findById(resources.getId()).orElseGet(UserCollectionDetail::new);
58 ValidationUtil.isNull( userCollectionDetail.getId(),"UserCollectionDetail","id",resources.getId());
59 userCollectionDetail.copy(resources);
60 userCollectionDetailRepository.save(userCollectionDetail);
61 }
62
63 @Override
64 @Transactional(rollbackFor = Exception.class)
65 public void delete(Long id) {
66 Assert.notNull(id, "The given id must not be null!");
67 UserCollectionDetail userCollectionDetail = userCollectionDetailRepository.findById(id).orElseThrow(
68 () -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", UserCollectionDetail.class, id), 1));
69 userCollectionDetailRepository.delete(userCollectionDetail);
70 }
71
72 @Override
73 public void deleteAllByUserCollectionId(Long id) {
74 this.userCollectionDetailRepository.deleteAllByUserCollectionId(id);
75 }
76
77 @Override
78 public void deleteAll(List<UserCollectionDetail> userCollectionDetailOptional) {
79 this.userCollectionDetailRepository.deleteAll(userCollectionDetailOptional);
80 }
81
82 }
1 package com.topdraw.business.module.user.weixin.collection.service.impl;
2
3 import com.topdraw.business.module.user.weixin.collection.domain.UserCollection;
4 import com.topdraw.business.module.user.weixin.collection.repository.UserCollectionRepository;
5 import com.topdraw.business.module.user.weixin.collection.service.UserCollectionService;
6 import com.topdraw.business.module.user.weixin.collection.service.dto.UserCollectionDTO;
7 import com.topdraw.business.module.user.weixin.collection.service.dto.UserCollectionQueryCriteria;
8 import com.topdraw.business.module.user.weixin.collection.service.mapper.UserCollectionMapper;
9 import com.topdraw.utils.FileUtil;
10 import com.topdraw.utils.PageUtil;
11 import com.topdraw.utils.QueryHelp;
12 import com.topdraw.utils.ValidationUtil;
13 import org.springframework.beans.factory.annotation.Autowired;
14 import org.springframework.dao.EmptyResultDataAccessException;
15 import org.springframework.data.domain.Page;
16 import org.springframework.data.domain.Pageable;
17 import org.springframework.stereotype.Service;
18 import org.springframework.transaction.annotation.Propagation;
19 import org.springframework.transaction.annotation.Transactional;
20 import org.springframework.util.Assert;
21
22 import javax.servlet.http.HttpServletResponse;
23 import java.io.IOException;
24 import java.util.*;
25
26 /**
27 * @author pengmengqing
28 * @date 2021-04-02
29 */
30 @Service
31 @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
32 public class UserCollectionServiceImpl implements UserCollectionService {
33
34 @Autowired
35 private UserCollectionRepository userCollectionRepository;
36
37 @Autowired
38 private UserCollectionMapper userCollectionMapper;
39
40
41
42 @Override
43 public Map<String, Object> queryAll(UserCollectionQueryCriteria criteria, Pageable pageable) {
44 Page<UserCollection> page = userCollectionRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
45 return PageUtil.toPage(page.map(userCollectionMapper::toDto));
46 }
47
48 @Override
49 public List<UserCollectionDTO> queryAll(UserCollectionQueryCriteria criteria) {
50 return userCollectionMapper.toDto(userCollectionRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
51 }
52
53 @Override
54 public UserCollectionDTO findById(Long id) {
55 UserCollection userCollection = userCollectionRepository.findById(id).orElseGet(UserCollection::new);
56 ValidationUtil.isNull(userCollection.getId(),"UserCollection","id",id);
57 return userCollectionMapper.toDto(userCollection);
58 }
59
60 @Override
61 @Transactional(rollbackFor = Exception.class)
62 public UserCollectionDTO create(UserCollection resources) {
63 return userCollectionMapper.toDto(userCollectionRepository.save(resources));
64 }
65
66 @Override
67 @Transactional(rollbackFor = Exception.class)
68 public void update(UserCollection resources) {
69 UserCollection userCollection = userCollectionRepository.findById(resources.getId()).orElseGet(UserCollection::new);
70 ValidationUtil.isNull( userCollection.getId(),"UserCollection","id",resources.getId());
71 userCollection.copy(resources);
72 userCollectionRepository.save(userCollection);
73 }
74
75 @Override
76 @Transactional(rollbackFor = Exception.class)
77 public void delete(Long id) {
78 Assert.notNull(id, "The given id must not be null!");
79 UserCollection userCollection = userCollectionRepository.findById(id).orElseThrow(
80 () -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", UserCollection.class, id), 1));
81 userCollectionRepository.delete(userCollection);
82 }
83
84
85 @Override
86 public void download(List<UserCollectionDTO> all, HttpServletResponse response) throws IOException {
87 List<Map<String, Object>> list = new ArrayList<>();
88 for (UserCollectionDTO userCollection : all) {
89 Map<String, Object> map = new LinkedHashMap<>();
90 map.put("应用ID", userCollection.getAppId());
91 // map.put("用户ID", userCollection.getSubscriberId());
92 // map.put("platformAccount", userCollection.getPlatformAccount());
93 map.put("收藏夹类型:1-收藏 2-播放记录 3-播放列表 4-评分 5-点赞/关注/订阅", userCollection.getType());
94 map.put("收藏夹名称", userCollection.getName());
95 map.put("数量", userCollection.getCount());
96 map.put("创建时间", userCollection.getCreateTime());
97 map.put("更新时间", userCollection.getUpdateTime());
98 list.add(map);
99 }
100 FileUtil.downloadExcel(list, response);
101 }
102
103 @Override
104 public List<UserCollection> findByUserIdAndType(Long id, Integer type) {
105 return this.userCollectionRepository.findByUserIdAndType(id,type);
106 }
107
108 @Override
109 public Optional<UserCollection> findFirstByUserIdAndTypeAndName(Long id, Integer type, String name) {
110 return Optional.empty();
111 }
112
113 @Override
114 public void save(UserCollection userCollection) {
115
116 }
117
118
119 }
1 package com.topdraw.business.module.user.weixin.collection.service.mapper;
2
3 import com.topdraw.base.BaseMapper;
4 import com.topdraw.business.module.user.weixin.collection.domain.UserCollectionDetail;
5 import com.topdraw.business.module.user.weixin.collection.service.dto.UserCollectionDetailDTO;
6 import org.mapstruct.Mapper;
7 import org.mapstruct.ReportingPolicy;
8
9 /**
10 * @author pengmengqing
11 * @date 2021-04-02
12 */
13 @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
14 public interface UserCollectionDetailMapper extends BaseMapper<UserCollectionDetailDTO, UserCollectionDetail> {
15
16 }
1 package com.topdraw.business.module.user.weixin.collection.service.mapper;
2
3 import com.topdraw.base.BaseMapper;
4 import com.topdraw.business.module.user.weixin.collection.domain.UserCollection;
5 import com.topdraw.business.module.user.weixin.collection.service.dto.UserCollectionDTO;
6 import org.mapstruct.Mapper;
7 import org.mapstruct.ReportingPolicy;
8
9 /**
10 * @author pengmengqing
11 * @date 2021-04-02
12 */
13 @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
14 public interface UserCollectionMapper extends BaseMapper<UserCollectionDTO, UserCollection> {
15
16 }
...@@ -109,5 +109,4 @@ public class UserWeixinServiceImpl implements UserWeixinService { ...@@ -109,5 +109,4 @@ public class UserWeixinServiceImpl implements UserWeixinService {
109 return UserWeixinMapper.toDto(userWeixin); 109 return UserWeixinMapper.toDto(userWeixin);
110 } 110 }
111 111
112
113 } 112 }
......
1 package com.topdraw.business.process.domian.weixin;
2
3
4 import com.alibaba.fastjson.annotation.JSONField;
5 import com.topdraw.annotation.Query;
6 import lombok.Data;
7
8 import java.sql.Timestamp;
9
10 @Data
11 public class UserCollectionMq {
12
13 // 应用ID
14 @JSONField(name = "app_id")
15 private Long appId;
16
17 @JSONField(name = "userId")
18 private Long userId;
19
20 // 收藏夹类型:1-收藏 2-播放记录 3-播放列表 4-评分 5-点赞/关注/订阅
21 private Integer type;
22
23 // 收藏夹名称
24 private String name;
25
26 // 数量
27 private Integer count;
28
29 private String images;
30
31 // 收藏夹ID
32 @JSONField(name = "user_collection_id")
33 @Query
34 private Long userCollectionId;
35
36 // 自定义收藏内容的类型CODE,默认:DEFAULT
37 @JSONField(name = "detail_folder_code")
38 @Query
39 private String detailFolderCode;
40
41 // 收藏内容的类型:MEDIA|EPISODE|CATEGORY|SUBJECT|ARTICLE|ARTIST|SCHOOL
42 @JSONField(name = "detail_type")
43 @Query
44 private String detailType;
45
46 // 收藏内容的ID
47 @JSONField(name = "detail_id")
48 @Query
49 private Long detailId;
50
51 // 收藏内容的CODE
52 @JSONField(name = "detail_code")
53 @Query
54 private String detailCode;
55
56 // 收藏内容的剧集ID
57 @JSONField(name = "detail_episode_id")
58 @Query
59 private Long detailEpisodeId;
60
61 // 收藏内容的剧集CODE
62 @JSONField(name = "detail_episode_code")
63 @Query
64 private String detailEpisodeCode;
65
66 // 收藏内容的名称
67 @JSONField(name = "detail_name")
68 @Query
69 private String detailName;
70
71 // 收藏内容的标记
72 @JSONField(name = "detail_mark")
73 @Query
74 private Integer detailMark;
75
76 // 收藏内容的图片
77 @JSONField(name = "detail_img")
78 private String detailImg;
79
80 // 收藏内容的剧集序号
81 @JSONField(name = "detail_index")
82 @Query
83 private Integer detailIndex;
84
85 // 收藏内容的剧集总数
86 @JSONField(name = "detail_total_index")
87 @Query
88 private Integer detailTotalIndex;
89
90 // 收藏内容的播放时间
91 @JSONField(name = "detail_play_time")
92 @Query
93 private Integer detailPlayTime;
94
95 // 收藏内容的总时间
96 @JSONField(name = "detail_total_time")
97 @Query
98 private Integer detailTotalTime;
99
100 // 收藏内容在同一folder中的顺序
101 @JSONField(name = "detail_sequence")
102 @Query
103 private Integer detailSequence;
104
105 // 收藏内容的评分
106 @JSONField(name = "detail_score")
107 @Query
108 private Float detailScore;
109
110 // 收藏内容(根据文件夹和类型的不同)的点赞/关注/订阅
111 @JSONField(name = "detail_like")
112 @Query
113 private Integer detailLike;
114
115 // 收藏内容的扩展数据
116 @JSONField(name = "detail_ext_data")
117 @Query
118 private String detailExtData;
119
120 // 创建时间
121 @JSONField(name = "create_time")
122 @Query
123 private Timestamp createTime;
124
125 // 更新时间
126 @JSONField(name = "update_time")
127 private Timestamp updateTime;
128 }
1 package com.topdraw.business.process.rest; 1 package com.topdraw.business.process.rest;
2 2
3 import cn.hutool.core.util.ObjectUtil;
4 import cn.hutool.core.util.StrUtil;
3 import com.alibaba.druid.support.json.JSONUtils; 5 import com.alibaba.druid.support.json.JSONUtils;
4 import com.alibaba.fastjson.JSON; 6 import com.alibaba.fastjson.JSON;
5 import com.alibaba.fastjson.JSONObject; 7 import com.alibaba.fastjson.JSONObject;
...@@ -7,6 +9,8 @@ import com.topdraw.annotation.AnonymousAccess; ...@@ -7,6 +9,8 @@ import com.topdraw.annotation.AnonymousAccess;
7 import com.topdraw.annotation.Log; 9 import com.topdraw.annotation.Log;
8 import com.topdraw.business.module.member.profile.domain.MemberProfile; 10 import com.topdraw.business.module.member.profile.domain.MemberProfile;
9 import com.topdraw.business.module.user.iptv.domain.UserTv; 11 import com.topdraw.business.module.user.iptv.domain.UserTv;
12 import com.topdraw.business.module.user.iptv.service.dto.UserTvDTO;
13 import com.topdraw.business.module.user.weixin.domain.UserWeixin;
10 import com.topdraw.business.module.user.weixin.service.dto.UserWeixinDTO; 14 import com.topdraw.business.module.user.weixin.service.dto.UserWeixinDTO;
11 import com.topdraw.business.process.domian.TempIptvUser; 15 import com.topdraw.business.process.domian.TempIptvUser;
12 import com.topdraw.business.process.domian.UnbindGroup; 16 import com.topdraw.business.process.domian.UnbindGroup;
...@@ -15,8 +19,15 @@ import com.topdraw.business.process.domian.weixin.SubscribeBeanEvent; ...@@ -15,8 +19,15 @@ import com.topdraw.business.process.domian.weixin.SubscribeBeanEvent;
15 import com.topdraw.business.process.domian.weixin.WeiXinUserBean; 19 import com.topdraw.business.process.domian.weixin.WeiXinUserBean;
16 import com.topdraw.business.process.service.UserOperationService; 20 import com.topdraw.business.process.service.UserOperationService;
17 import com.topdraw.common.ResultInfo; 21 import com.topdraw.common.ResultInfo;
22 import com.topdraw.config.RedisKeyUtil;
23 import com.topdraw.exception.BadRequestException;
18 import com.topdraw.module.mq.DataSyncMsg; 24 import com.topdraw.module.mq.DataSyncMsg;
19 import com.topdraw.util.JSONUtil; 25 import com.topdraw.util.JSONUtil;
26 import com.topdraw.utils.RedisUtils;
27 import com.topdraw.utils.StringUtils;
28 import com.topdraw.weixin.util.WeChatConstants;
29 import com.topdraw.weixin.util.WeiXinRequestUtil;
30 import com.topdraw.weixin.util.WeixinUtil;
20 import io.swagger.annotations.Api; 31 import io.swagger.annotations.Api;
21 import io.swagger.annotations.ApiOperation; 32 import io.swagger.annotations.ApiOperation;
22 import lombok.extern.slf4j.Slf4j; 33 import lombok.extern.slf4j.Slf4j;
...@@ -25,6 +36,11 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -25,6 +36,11 @@ import org.springframework.beans.factory.annotation.Autowired;
25 import org.springframework.validation.annotation.Validated; 36 import org.springframework.validation.annotation.Validated;
26 import org.springframework.web.bind.annotation.*; 37 import org.springframework.web.bind.annotation.*;
27 38
39 import java.io.IOException;
40 import java.util.HashMap;
41 import java.util.Map;
42 import java.util.Objects;
43
28 @Api("账户处理") 44 @Api("账户处理")
29 @RestController 45 @RestController
30 @RequestMapping(value = "/ucEngine/api/userOperation") 46 @RequestMapping(value = "/ucEngine/api/userOperation")
...@@ -33,6 +49,10 @@ public class UserOperationController { ...@@ -33,6 +49,10 @@ public class UserOperationController {
33 49
34 @Autowired 50 @Autowired
35 private UserOperationService userTvOperationService; 51 private UserOperationService userTvOperationService;
52 @Autowired
53 private WeiXinRequestUtil weixinRequestUtil;
54 @Autowired
55 private RedisUtils redisUtils;
36 56
37 @Log("带参二维码") 57 @Log("带参二维码")
38 @PostMapping(value = "/sendQrCodeMessage") 58 @PostMapping(value = "/sendQrCodeMessage")
...@@ -40,7 +60,7 @@ public class UserOperationController { ...@@ -40,7 +60,7 @@ public class UserOperationController {
40 @AnonymousAccess 60 @AnonymousAccess
41 public ResultInfo sendQrCodeMessage(@RequestBody String content) { 61 public ResultInfo sendQrCodeMessage(@RequestBody String content) {
42 log.info("resources :[{}]",content); 62 log.info("resources :[{}]",content);
43 boolean result = true; 63 boolean result = this.userTvOperationService.sendQrCodeMessage(content);
44 return ResultInfo.success(result); 64 return ResultInfo.success(result);
45 } 65 }
46 66
...@@ -50,7 +70,7 @@ public class UserOperationController { ...@@ -50,7 +70,7 @@ public class UserOperationController {
50 @AnonymousAccess 70 @AnonymousAccess
51 public ResultInfo deleteAllCollection(@RequestBody String content) { 71 public ResultInfo deleteAllCollection(@RequestBody String content) {
52 log.info("resources :[{}]",content); 72 log.info("resources :[{}]",content);
53 boolean result = true; 73 boolean result = this.userTvOperationService.deleteAllCollection(content);
54 return ResultInfo.success(result); 74 return ResultInfo.success(result);
55 } 75 }
56 76
...@@ -60,7 +80,7 @@ public class UserOperationController { ...@@ -60,7 +80,7 @@ public class UserOperationController {
60 @AnonymousAccess 80 @AnonymousAccess
61 public ResultInfo deleteCollection(@RequestBody String content) { 81 public ResultInfo deleteCollection(@RequestBody String content) {
62 log.info("resources :[{}]",content); 82 log.info("resources :[{}]",content);
63 boolean result = true; 83 boolean result = this.userTvOperationService.deleteCollection(content);
64 return ResultInfo.success(result); 84 return ResultInfo.success(result);
65 } 85 }
66 86
...@@ -116,13 +136,88 @@ public class UserOperationController { ...@@ -116,13 +136,88 @@ public class UserOperationController {
116 @PostMapping("/subscribe") 136 @PostMapping("/subscribe")
117 @ApiOperation("微信公众号关注") 137 @ApiOperation("微信公众号关注")
118 @AnonymousAccess 138 @AnonymousAccess
119 public ResultInfo subscribe(@Validated @RequestBody SubscribeBeanEvent data) { 139 public ResultInfo subscribe(@Validated @RequestBody SubscribeBeanEvent data) throws IOException {
120 String content = data.getContent(); 140 String content = data.getContent();
121 SubscribeBean subscribeBean = JSONUtil.parseMsg2Object(content, SubscribeBean.class); 141 SubscribeBean subscribeBean = JSONUtil.parseMsg2Object(content, SubscribeBean.class);
142
143 this.parseSubscribe(subscribeBean);
144
122 boolean result = this.userTvOperationService.subscribe(subscribeBean); 145 boolean result = this.userTvOperationService.subscribe(subscribeBean);
123 return ResultInfo.success(result); 146 return ResultInfo.success(result);
124 } 147 }
125 148
149
150 private void parseSubscribe(SubscribeBean subscribeBean) throws IOException {
151 if (Objects.nonNull(subscribeBean)) {
152
153 String appId = subscribeBean.getAppId();
154 // appId不得为空
155 if (StringUtils.isBlank(appId))
156 throw new BadRequestException("appId 不存在!");
157
158 // openId
159 String openId = subscribeBean.getOpenId();
160 if (StringUtils.isBlank(openId))
161 throw new BadRequestException("openId 不存在!");
162
163 // unionId
164 String unionId = null;
165
166 // 匹配配置文件中的微信列表信息
167 Map<String, String> wxInfoMap = WeixinUtil.getWeixinInfoByAppid(appId);
168
169 if (Objects.nonNull(wxInfoMap)) {
170 // 程序类型
171 String appType = wxInfoMap.get("appType");
172 // 非订阅号,暂不处理。返回暂不支持
173 if (ObjectUtil.notEqual(appType, WeChatConstants.WX_SUBSCRIPTION))
174 throw new BadRequestException("非订阅号");
175
176 // 用户类型
177 JSONObject userInfo = weixinRequestUtil.getUserInfo(wxInfoMap, openId);
178 log.info("userInfo is : {}", userInfo.toJSONString());
179 unionId = userInfo.get("unionid").toString();
180
181 if (StringUtils.isBlank(unionId))
182 throw new BadRequestException("unionid 不存在!");
183 }
184
185 // unionId不得为空
186 if (StringUtils.isBlank(unionId))
187 throw new BadRequestException("unionId 不存在!");
188
189 subscribeBean.setUnionId(unionId);
190
191 // 大屏账户信息
192 JSONObject iptvUserInfo = null;
193 // 缓存的大屏信息,使用unionid即可
194 String content = (String) this.redisUtils.get(RedisKeyUtil.genSeSuSubscribeKey(unionId));
195 if (StringUtils.isNotBlank(content)) {
196 // 大屏信息
197 iptvUserInfo = JSONObject.parseObject(content);
198
199 } else {
200
201 String eventKey = subscribeBean.getEventKey();
202 // 用户扫描带参二维码关注。发消息
203 // 去除固定前缀,获取二维码参数
204 eventKey = eventKey.substring(8);
205 iptvUserInfo = com.alibaba.fastjson.JSONObject.parseObject(eventKey);
206
207 }
208
209 // 用户自己搜索关注就没有大屏信息的话,否则表示扫码关注
210 if (Objects.nonNull(iptvUserInfo)) {
211 subscribeBean.setIptvUserInfo(iptvUserInfo);
212 }
213
214
215 // 之后删除缓存信息
216 this.redisUtils.del(RedisKeyUtil.genSeSuSubscribeKey(unionId));
217
218 }
219 }
220
126 @Log("微信公众号取关") 221 @Log("微信公众号取关")
127 @PostMapping("/unsubscribe") 222 @PostMapping("/unsubscribe")
128 @ApiOperation("微信公众号取关") 223 @ApiOperation("微信公众号取关")
......
...@@ -24,4 +24,10 @@ public interface UserOperationService { ...@@ -24,4 +24,10 @@ public interface UserOperationService {
24 String saveUserInfo(String data); 24 String saveUserInfo(String data);
25 25
26 MemberProfile saveUserWeixinPhone(WeiXinUserBean resources); 26 MemberProfile saveUserWeixinPhone(WeiXinUserBean resources);
27
28 boolean sendQrCodeMessage(String content);
29
30 boolean deleteAllCollection(String content);
31
32 boolean deleteCollection(String content);
27 } 33 }
......
...@@ -20,12 +20,18 @@ import com.topdraw.business.module.user.iptv.domain.UserConstant; ...@@ -20,12 +20,18 @@ import com.topdraw.business.module.user.iptv.domain.UserConstant;
20 import com.topdraw.business.module.user.iptv.domain.UserTv; 20 import com.topdraw.business.module.user.iptv.domain.UserTv;
21 import com.topdraw.business.module.user.iptv.service.UserTvService; 21 import com.topdraw.business.module.user.iptv.service.UserTvService;
22 import com.topdraw.business.module.user.iptv.service.dto.UserTvDTO; 22 import com.topdraw.business.module.user.iptv.service.dto.UserTvDTO;
23 import com.topdraw.business.module.user.weixin.collection.domain.UserCollection;
24 import com.topdraw.business.module.user.weixin.collection.domain.UserCollectionDetail;
25 import com.topdraw.business.module.user.weixin.collection.repository.UserCollectionDetailRepository;
26 import com.topdraw.business.module.user.weixin.collection.service.UserCollectionDetailService;
27 import com.topdraw.business.module.user.weixin.collection.service.UserCollectionService;
23 import com.topdraw.business.module.user.weixin.domain.UserWeixin; 28 import com.topdraw.business.module.user.weixin.domain.UserWeixin;
24 import com.topdraw.business.module.user.weixin.service.UserWeixinService; 29 import com.topdraw.business.module.user.weixin.service.UserWeixinService;
25 import com.topdraw.business.module.user.weixin.service.dto.UserWeixinDTO; 30 import com.topdraw.business.module.user.weixin.service.dto.UserWeixinDTO;
26 import com.topdraw.business.module.user.weixin.service.dto.UserWeixinQueryCriteria; 31 import com.topdraw.business.module.user.weixin.service.dto.UserWeixinQueryCriteria;
27 import com.topdraw.business.process.domian.weixin.BuyVipBean; 32 import com.topdraw.business.process.domian.weixin.BuyVipBean;
28 import com.topdraw.business.process.domian.weixin.SubscribeBean; 33 import com.topdraw.business.process.domian.weixin.SubscribeBean;
34 import com.topdraw.business.process.domian.weixin.UserCollectionMq;
29 import com.topdraw.business.process.domian.weixin.WeiXinUserBean; 35 import com.topdraw.business.process.domian.weixin.WeiXinUserBean;
30 import com.topdraw.business.process.service.UserOperationService; 36 import com.topdraw.business.process.service.UserOperationService;
31 import com.topdraw.config.LocalConstants; 37 import com.topdraw.config.LocalConstants;
...@@ -35,14 +41,16 @@ import com.topdraw.exception.EntityNotFoundException; ...@@ -35,14 +41,16 @@ import com.topdraw.exception.EntityNotFoundException;
35 import com.topdraw.security.AESUtil; 41 import com.topdraw.security.AESUtil;
36 import com.topdraw.util.IdWorker; 42 import com.topdraw.util.IdWorker;
37 import com.topdraw.util.TimestampUtil; 43 import com.topdraw.util.TimestampUtil;
44 import com.topdraw.utils.QueryHelp;
38 import com.topdraw.utils.RedisUtils; 45 import com.topdraw.utils.RedisUtils;
39 import com.topdraw.utils.StringUtils; 46 import com.topdraw.utils.StringUtils;
40 import com.topdraw.weixin.beans.DefaultWeiXinBeanDefinition; 47 import com.topdraw.weixin.beans.*;
41 import com.topdraw.weixin.beans.WeiXinBeanDefinition;
42 import com.topdraw.weixin.beans.config.WeiXinAppListConfig; 48 import com.topdraw.weixin.beans.config.WeiXinAppListConfig;
43 import com.topdraw.weixin.util.WeChatConstants; 49 import com.topdraw.weixin.util.WeChatConstants;
44 import com.topdraw.weixin.util.WeiXinRequestUtil; 50 import com.topdraw.weixin.util.WeiXinRequestUtil;
51 import com.topdraw.weixin.util.WeixinUtil;
45 import lombok.extern.slf4j.Slf4j; 52 import lombok.extern.slf4j.Slf4j;
53 import lombok.var;
46 import org.redisson.api.RedissonClient; 54 import org.redisson.api.RedissonClient;
47 import org.springframework.beans.BeanUtils; 55 import org.springframework.beans.BeanUtils;
48 import org.springframework.beans.factory.annotation.Autowired; 56 import org.springframework.beans.factory.annotation.Autowired;
...@@ -58,10 +66,9 @@ import org.springframework.web.client.RestTemplate; ...@@ -58,10 +66,9 @@ import org.springframework.web.client.RestTemplate;
58 import javax.annotation.Resource; 66 import javax.annotation.Resource;
59 import java.io.IOException; 67 import java.io.IOException;
60 import java.time.LocalDateTime; 68 import java.time.LocalDateTime;
61 import java.util.List; 69 import java.util.*;
62 import java.util.Map; 70 import java.util.concurrent.TimeUnit;
63 import java.util.Objects; 71 import java.util.stream.Collectors;
64 import java.util.Optional;
65 72
66 @Service 73 @Service
67 @Slf4j 74 @Slf4j
...@@ -79,11 +86,19 @@ public class UserOperationServiceImpl implements UserOperationService { ...@@ -79,11 +86,19 @@ public class UserOperationServiceImpl implements UserOperationService {
79 @Autowired 86 @Autowired
80 private RedisUtils redisUtils; 87 private RedisUtils redisUtils;
81 @Autowired 88 @Autowired
82 private WeiXinRequestUtil weixinRequestUtil;
83 @Autowired
84 private WeiXinAppListConfig weiXinAppListConfig; 89 private WeiXinAppListConfig weiXinAppListConfig;
85 @Autowired 90 @Autowired
86 private MemberProfileService memberProfileService; 91 private MemberProfileService memberProfileService;
92 @Autowired
93 private WeiXinRequestUtil weixinRequestUtil;
94 @Autowired
95 private UserCollectionService userCollectionService;
96 @Autowired
97 private UserCollectionDetailService userCollectionDetailService;
98 @Autowired
99 private UserCollectionDetailRepository userCollectionDetailRepository;
100
101
87 102
88 /** 取消关注 */ 103 /** 取消关注 */
89 private static final Integer UNSUBSCRIBE_STATUS = 0; 104 private static final Integer UNSUBSCRIBE_STATUS = 0;
...@@ -92,6 +107,8 @@ public class UserOperationServiceImpl implements UserOperationService { ...@@ -92,6 +107,8 @@ public class UserOperationServiceImpl implements UserOperationService {
92 private static final String UNSUBSCRIBE = "unsubscribe"; 107 private static final String UNSUBSCRIBE = "unsubscribe";
93 private static final Integer[] PLATFORM_LIST = new Integer[]{0,1,2,3}; 108 private static final Integer[] PLATFORM_LIST = new Integer[]{0,1,2,3};
94 109
110 private static final String QR_CODE_URL = "QR_CODE_URL_";
111
95 @Value("${uc.service.platform:}") 112 @Value("${uc.service.platform:}")
96 private String platform; 113 private String platform;
97 114
...@@ -114,6 +131,12 @@ public class UserOperationServiceImpl implements UserOperationService { ...@@ -114,6 +131,12 @@ public class UserOperationServiceImpl implements UserOperationService {
114 131
115 /** 132 /**
116 * 微信公众号关注 133 * 微信公众号关注
134 * 1.未扫描大屏二维码
135 * 1). 保存、修改小屏账户,创建小屏账户会员
136 * 2.扫描大屏二维码
137 * 1). 从redis中获取大屏信息
138 * 2). 大屏账户保存小屏会员的code
139 * 3). 小屏会员中保存大屏的id
117 * @description 大小屏绑定,大屏账户保存小屏会员编码 140 * @description 大小屏绑定,大屏账户保存小屏会员编码
118 * @param resources 141 * @param resources
119 * @return 142 * @return
...@@ -130,29 +153,38 @@ public class UserOperationServiceImpl implements UserOperationService { ...@@ -130,29 +153,38 @@ public class UserOperationServiceImpl implements UserOperationService {
130 throw new RuntimeException("微信信息解析失败!"); 153 throw new RuntimeException("微信信息解析失败!");
131 } 154 }
132 155
133 UserWeixinDTO userWeixinDTO = this.findUserWeiXinByOpenIdAndAppId(appId, openId); 156 // 小屏账户
157 UserWeixinDTO userWeixinDTO = this.findFirstByUnionIdAndAppIdAndOpenId(unionId,appId, openId);
134 158
135 if (Objects.isNull(userWeixinDTO.getId())) { 159 if (Objects.isNull(userWeixinDTO.getId())) {
136 160
137 // 创建会员和账户 161 // 创建会员和账户
138 this.doCreateUserWeiXinAndMember(weiXinBeanDefinition,userWeixinDTO); 162 this.doCreateUserWeiXinAndMember(weiXinBeanDefinition);
139 163
140 } else { 164 } else {
141 165
142 // 修改会员和会员信息 166 // 修改账户和会员信息
143 this.doUpdateUserWeiXinAndMember(userWeixinDTO,appId,openId); 167 this.doUpdateUserWeiXinAndMember(userWeixinDTO,appId,openId);
144 168
145 } 169 }
146 170
147 // 小屏会员 171 // 大屏信息
148 MemberDTO memberDTO_0 = this.findMemberByAppIdAndOpenId(appId,openId); 172 JSONObject iptvUserInfo = resources.getIptvUserInfo();
173 if (Objects.nonNull(iptvUserInfo)) {
149 174
150 // 从redis中获取大屏信息 175 // 小屏会员
151 UserTvDTO userTvDTO = this.findUserTvFromRedis(unionId); 176 MemberDTO memberDTO_0 = this.findMemberByAppIdAndOpenId(appId,openId);
152 177
153 // 携带了大屏信息 178 // 账户
154 if (Objects.nonNull(userTvDTO) && StringUtils.isNotEmpty(memberDTO_0.getCode())) { 179 String platformAccount = iptvUserInfo.getString("platformAccount");
155 // 绑定主账号会员 180
181 // 大屏账户
182 UserTvDTO userTvDTO = this.userTvService.findByPlatformAccount(platformAccount);
183 if (Objects.isNull(userTvDTO)) {
184 throw new BadRequestException("大屏信息不存在!");
185 }
186
187 // 大屏账户绑定小屏会员的code
156 this.bondPriorityMember(userTvDTO,memberDTO_0); 188 this.bondPriorityMember(userTvDTO,memberDTO_0);
157 189
158 // 小屏会员绑定大屏账户id 190 // 小屏会员绑定大屏账户id
...@@ -160,6 +192,7 @@ public class UserOperationServiceImpl implements UserOperationService { ...@@ -160,6 +192,7 @@ public class UserOperationServiceImpl implements UserOperationService {
160 192
161 // 修改会员 193 // 修改会员
162 this.doUpdateMemberByMemberDTO(memberDTO_1); 194 this.doUpdateMemberByMemberDTO(memberDTO_1);
195
163 } 196 }
164 197
165 return true; 198 return true;
...@@ -167,6 +200,17 @@ public class UserOperationServiceImpl implements UserOperationService { ...@@ -167,6 +200,17 @@ public class UserOperationServiceImpl implements UserOperationService {
167 } 200 }
168 201
169 /** 202 /**
203 * 获取小屏账户
204 * @param unionId
205 * @param appId
206 * @param openId
207 * @return
208 */
209 private UserWeixinDTO findFirstByUnionIdAndAppIdAndOpenId( String unionId,String appId, String openId) {
210 return this.userWeixinService.findFirstByUnionIdAndAppIdAndOpenId(unionId,appId,openId);
211 }
212
213 /**
170 * 214 *
171 * @param userWeixinDTO 215 * @param userWeixinDTO
172 * @param appId 216 * @param appId
...@@ -185,11 +229,10 @@ public class UserOperationServiceImpl implements UserOperationService { ...@@ -185,11 +229,10 @@ public class UserOperationServiceImpl implements UserOperationService {
185 /** 229 /**
186 * 创建会员和账户 230 * 创建会员和账户
187 * @param weiXinBeanDefinition 231 * @param weiXinBeanDefinition
188 * @param userWeixinDTO
189 */ 232 */
190 private void doCreateUserWeiXinAndMember(DefaultWeiXinBeanDefinition weiXinBeanDefinition,UserWeixinDTO userWeixinDTO) { 233 private void doCreateUserWeiXinAndMember(DefaultWeiXinBeanDefinition weiXinBeanDefinition) {
191 234
192 // 创建小屏 235 // 小屏账户
193 UserWeixin userWeixin = this.generateUserWeiXin(weiXinBeanDefinition,SUBSCRIBE_STATUS); 236 UserWeixin userWeixin = this.generateUserWeiXin(weiXinBeanDefinition,SUBSCRIBE_STATUS);
194 if (Objects.isNull(userWeixin.getId())) { 237 if (Objects.isNull(userWeixin.getId())) {
195 throw new BadRequestException("创建小屏账户失败"); 238 throw new BadRequestException("创建小屏账户失败");
...@@ -223,46 +266,6 @@ public class UserOperationServiceImpl implements UserOperationService { ...@@ -223,46 +266,6 @@ public class UserOperationServiceImpl implements UserOperationService {
223 } 266 }
224 267
225 /** 268 /**
226 * 从redis中获取大屏信息
227 * @param unionId
228 * @return
229 */
230 private UserTvDTO findUserTvFromRedis(String unionId) {
231
232 // 解析大屏信息
233 JSONObject iptvUserInfo = this.parseUserTvContent(unionId);
234
235 if (Objects.nonNull(iptvUserInfo)) {
236
237 String platformAccount = iptvUserInfo.getString("platformAccount");
238
239 UserTvDTO userTvDTO = this.findByPlatformAccount(platformAccount);
240
241 if (Objects.nonNull(userTvDTO.getId()))
242 userTvDTO.setPlatformAccount(platformAccount);
243
244 return userTvDTO;
245 }
246
247 return null;
248 }
249
250 /**
251 * 解析大屏用户
252 * @param unionId
253 * @return
254 */
255 private JSONObject parseUserTvContent(String unionId) {
256 // 缓存的信息,使用unionid即可
257 String content = (String) this.redisUtils.get(RedisKeyUtil.genSeSuSubscribeKey(unionId));
258 // 之后删除缓存信息
259 redisUtils.del(RedisKeyUtil.genSeSuSubscribeKey(unionId));
260
261 JSONObject iptvUserInfo = com.alibaba.fastjson.JSONObject.parseObject(content);
262 return iptvUserInfo;
263 }
264
265 /**
266 * 绑定iptvId字段并修改会员vip字段 269 * 绑定iptvId字段并修改会员vip字段
267 * @param memberDTO 270 * @param memberDTO
268 * @param userTvDTO 271 * @param userTvDTO
...@@ -618,20 +621,6 @@ public class UserOperationServiceImpl implements UserOperationService { ...@@ -618,20 +621,6 @@ public class UserOperationServiceImpl implements UserOperationService {
618 } 621 }
619 } 622 }
620 623
621 /*if (StringUtils.isNotBlank(resources.getEncryptedData())) {
622 String decrypt = AESUtil.decrypt(resources.getEncryptedData(), key);
623 if (decrypt != null) {
624 encryptedData = decrypt.substring(16);
625 }
626 }*/
627
628 /*if (StringUtils.isNotBlank(resources.getIv())) {
629 String decrypt = AESUtil.decrypt(iv, key);
630 if (decrypt != null) {
631 iv = decrypt.substring(16);
632 }
633 }*/
634
635 String appId_ = weixinInfoMap.get("appid"); 624 String appId_ = weixinInfoMap.get("appid");
636 String secret = weixinInfoMap.get("secret"); 625 String secret = weixinInfoMap.get("secret");
637 626
...@@ -751,15 +740,6 @@ public class UserOperationServiceImpl implements UserOperationService { ...@@ -751,15 +740,6 @@ public class UserOperationServiceImpl implements UserOperationService {
751 } 740 }
752 741
753 /** 742 /**
754 * 通过账户获取大屏账户
755 * @param platformAccount
756 * @return
757 */
758 private UserTvDTO findByPlatformAccount(String platformAccount) {
759 return this.userTvService.findByPlatformAccount(platformAccount);
760 }
761
762 /**
763 * 通过编码获取会员 743 * 通过编码获取会员
764 * @param memberCode 744 * @param memberCode
765 * @return 745 * @return
...@@ -838,16 +818,6 @@ public class UserOperationServiceImpl implements UserOperationService { ...@@ -838,16 +818,6 @@ public class UserOperationServiceImpl implements UserOperationService {
838 } 818 }
839 819
840 /** 820 /**
841 * 通过大屏账户id查询大屏信息
842 * @param userTvId
843 * @return
844 */
845 private UserTvDTO findByUserTvId(Long userTvId) {
846 UserTvDTO userTvDTO = this.userTvService.findById(userTvId);
847 return userTvDTO;
848 }
849
850 /**
851 * 通过大屏账户查询大屏信息 821 * 通过大屏账户查询大屏信息
852 * @param resources 822 * @param resources
853 * @return 823 * @return
...@@ -974,6 +944,139 @@ public class UserOperationServiceImpl implements UserOperationService { ...@@ -974,6 +944,139 @@ public class UserOperationServiceImpl implements UserOperationService {
974 return this.doSaveOrUpdateMemberProfile(weiXinBeanDefinition,resources); 944 return this.doSaveOrUpdateMemberProfile(weiXinBeanDefinition,resources);
975 } 945 }
976 946
947 @Override
948 public boolean sendQrCodeMessage(String content) {
949 try {
950 log.info("receive get qrCode message, content {}", content);
951 JSONObject jsonObject = JSONObject.parseObject(content);
952 String appid = jsonObject.getString("appid");
953 String IPTVappid = jsonObject.getString("IPTVappid");
954 String platformAccount = jsonObject.getString("platformAccount");
955 String sessionId = jsonObject.getString("sessionId");
956 String key = QR_CODE_URL + appid + "_" + platformAccount + "_" + sessionId;
957 String url = (String) this.redisUtils.get(key);
958 if (StringUtils.isBlank(url)) {
959 Map<String, String> wxInfo = WeixinUtil.getWeixinInfoByAppid(appid);
960 String appType = wxInfo.get("appType");
961 // 订阅号不支持带参二维码,直接返回
962 if (StrUtil.isNotEmpty(appType) && ObjectUtil.equals(appType, WeChatConstants.WX_SUBSCRIPTION)) {
963 log.error("订阅号不支持带参二维码 || {} || {}", appid, content);
964 return false;
965 }
966 QrCode qrCode = new QrCode();
967 qrCode.setActionName(WeChatConstants.QR_STR_SCENE);
968 if (StringUtils.isNotBlank(wxInfo.get("qrCodeExpireSeconds"))) {
969 qrCode.setExpireSeconds(Integer.valueOf(wxInfo.get("qrCodeExpireSeconds")));
970 }
971 ActionInfo actionInfo = new ActionInfo();
972 Scene scene = new Scene();
973 scene.setSceneStr(content);
974 actionInfo.setScene(scene);
975 qrCode.setActionInfo(actionInfo);
976 JSONObject jsonQrCode = this.weixinRequestUtil.getQrCode(wxInfo, qrCode);
977 url = jsonQrCode.getString("url");
978 Integer expireSeconds = jsonQrCode.getInteger("expire_seconds");
979 this.redisUtils.set(key, url, expireSeconds, TimeUnit.SECONDS);
980 }
981 /* HashMap<String, Object> map = new HashMap<>();
982 map.put("sessionId", sessionId);
983 map.put("url", url);
984 map.put("appid", appid);
985 map.put("IPTVappid", IPTVappid);
986 map.put("platformAccount", platformAccount);
987 map.put("extraInfo", content);
988 messageProducer.sendQrCodeMessage(JSONObject.toJSONString(map));*/
989 } catch (Exception e) {
990 log.error("GetQrCodeConsumer || get qrCode error || {}", e.toString(), e);
991 }
992 return true;
993 }
994
995 @Override
996 public boolean deleteAllCollection(String content) {
997 try {
998 log.info("receive UserCollection delete all message, content {}", content);
999 JSONObject jsonObject = JSONObject.parseObject(content);
1000 String platformAccount = jsonObject.getString("platformAccount");
1001 Integer type = jsonObject.getInteger("collectionType");
1002 UserTvDTO userTvDTO = this.userTvService.findByPlatformAccount(platformAccount);
1003
1004 Long id = userTvDTO.getId();
1005 List<UserCollection> userCollections = this.userCollectionService.findByUserIdAndType(id, type);
1006 if (userCollections == null || userCollections.isEmpty()) {
1007 return false;
1008 }
1009 for (UserCollection userCollection : userCollections) {
1010 this.userCollectionDetailService.deleteAllByUserCollectionId(userCollection.getId());
1011 }
1012 } catch (Exception e) {
1013 log.error("CollectionDeleteConsumer || UserCollection delete all error || {}", e.toString(), e);
1014 }
1015 return true;
1016 }
1017
1018 @Override
1019 public boolean deleteCollection(String content) {
1020 try {
1021 log.info("receive UserCollection delete message, content {}", content);
1022 JSONObject jsonObject = JSONObject.parseObject(content);
1023 String platformAccount = jsonObject.getString("platformAccount");
1024 String data = jsonObject.getString("data");
1025 if (StringUtils.isBlank(data) || !data.startsWith("[")) {
1026 return false;
1027 }
1028
1029 UserTvDTO userTvDTO = this.userTvService.findByPlatformAccount(platformAccount);
1030
1031 Long id = userTvDTO.getId();
1032
1033 List<UserCollectionMq> userCollectionMqList = JSONObject.parseArray(data, UserCollectionMq.class);
1034 if (userCollectionMqList == null || userCollectionMqList.isEmpty()) {
1035 return false;
1036 }
1037 Map<Long, List<UserCollectionMq>> collect = userCollectionMqList.stream()
1038 .collect(Collectors.groupingBy(UserCollectionMq::getUserCollectionId));
1039 for (Map.Entry<Long, List<UserCollectionMq>> entry : collect.entrySet()) {
1040 List<UserCollectionMq> value = entry.getValue();
1041 UserCollectionMq userCollectionMq = value.get(0);
1042
1043 if (StringUtils.isBlank(userCollectionMq.getName())) {
1044 userCollectionMq.setName("DEFAULT");
1045 }
1046
1047 Optional<UserCollection> userCollectionOptional =
1048 this.userCollectionService.findFirstByUserIdAndTypeAndName(id, userCollectionMq.getType(),
1049 userCollectionMq.getName());
1050 UserCollection userCollection = userCollectionOptional.orElseGet(UserCollection::new);
1051
1052 int count = 0;
1053 for (UserCollectionMq collectionMq : value) {
1054
1055 collectionMq.setUserCollectionId(userCollection.getId());
1056 List<UserCollectionDetail> userCollectionDetailOptional =
1057 this.userCollectionDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) ->
1058 QueryHelp.getPredicate(root, collectionMq, criteriaBuilder));
1059 if (!userCollectionDetailOptional.isEmpty()) {
1060 this.userCollectionDetailService.deleteAll(userCollectionDetailOptional);
1061 count++;
1062 }
1063
1064 }
1065
1066 userCollection.setAppId(userCollectionMq.getAppId())
1067 .setUserId(id)
1068 .setName(userCollectionMq.getName())
1069 .setType(userCollectionMq.getType())
1070 .setCount(userCollection.getCount() - count);
1071 this.userCollectionService.save(userCollection);
1072 }
1073 } catch (Exception e) {
1074 log.error("CollectionDeleteConsumer || UserCollection delete error || {}", e.toString(), e);
1075 }
1076
1077 return true;
1078 }
1079
977 /** 1080 /**
978 * 保存、修改会员加密信息 1081 * 保存、修改会员加密信息
979 * @param resources 1082 * @param resources
......
1 package com.topdraw.config;
2
3 import lombok.Data;
4 import org.springframework.boot.context.properties.ConfigurationProperties;
5 import org.springframework.context.annotation.Configuration;
6
7 import java.util.List;
8 import java.util.Map;
9
10 @Configuration
11 @Data
12 @ConfigurationProperties(prefix = "weixin")
13 public class WeixinInfoConfig {
14
15 private List<Map<String, String>> list;
16 }
...@@ -300,6 +300,17 @@ public class WeiXinRequestUtil { ...@@ -300,6 +300,17 @@ public class WeiXinRequestUtil {
300 } 300 }
301 301
302 /** 302 /**
303 * 公众号获取用户信息,access_token错误时,重新获取进行重试
304 *
305 * @param weixinInfo 微信参数
306 * @param openid 用户openid
307 */
308 @Retryable(value = Exception.class, maxAttempts = 2, backoff = @Backoff(delay = 0L, multiplier = 0.0))
309 public JSONObject getUserInfo(Map<String, String> weixinInfo, String openid) throws IOException {
310 return this.getUserInfo(weixinInfo,openid,"");
311 }
312
313 /**
303 * @param weixinInfo 314 * @param weixinInfo
304 * @param nextOpenId 315 * @param nextOpenId
305 * @return com.alibaba.fastjson.JSONObject 316 * @return com.alibaba.fastjson.JSONObject
......
1 package com.topdraw.weixin.util;
2
3 import com.topdraw.config.WeixinInfoConfig;
4 import com.topdraw.utils.StringUtils;
5 import lombok.extern.slf4j.Slf4j;
6 import org.springframework.beans.factory.annotation.Autowired;
7 import org.springframework.stereotype.Component;
8
9 import javax.servlet.ServletOutputStream;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12 import java.io.IOException;
13 import java.io.UnsupportedEncodingException;
14 import java.security.MessageDigest;
15 import java.security.NoSuchAlgorithmException;
16 import java.util.Arrays;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Optional;
20
21
22 @Component
23 @Slf4j
24 public class WeixinUtil {
25
26
27 private static WeixinInfoConfig WEIXININFOCONFIG;
28
29 @Autowired
30 public void setWeixinInfoConfig(WeixinInfoConfig weixinInfoConfig) {
31 WEIXININFOCONFIG = weixinInfoConfig;
32 }
33
34 public static Map<String, String> getWeixinInfoByAppid(String appid) {
35 if (StringUtils.isBlank(appid)) {
36 throw new RuntimeException("wxAppid can not be null");
37 }
38 List<Map<String, String>> list = WEIXININFOCONFIG.getList();
39 Optional<Map<String, String>> weixinInfoOptional = list.stream().filter(o -> o.get("appid").equals(appid)).findFirst();
40 if (!weixinInfoOptional.isPresent()) {
41 throw new RuntimeException("wxAppid error, appid is : " + appid);
42 }
43 return weixinInfoOptional.get();
44 }
45
46
47 public static Map<String, String> getWeixinInfoByIndex(Integer index) {
48 List<Map<String, String>> list = WEIXININFOCONFIG.getList();
49 if (list.size() < index + 1) {
50 throw new RuntimeException("wxinfo error, index out of range : {}" + index);
51 }
52 return list.get(index);
53 }
54 /**
55 * 使用SHA1算法对字符串数组进行加密
56 *
57 * @param strList
58 * @return
59 */
60 public static String encodeUsingSHA1(String... strList) {
61 //将strList的值进行字典排序
62 Arrays.sort(strList);
63 StringBuilder content = new StringBuilder();
64 for (int i = 0; i < strList.length; i++) {
65 content.append(strList[i]);
66 }
67
68 return doEncodeUsingSHA1(content.toString());
69 }
70
71
72 /**
73 * SHA1实现
74 *
75 * @return sha1加密后的字符串
76 */
77 private static String doEncodeUsingSHA1(String inStr) {
78 byte[] byteArray ;
79
80 try {
81 MessageDigest sha = MessageDigest.getInstance("SHA-1");
82 byteArray = sha.digest(inStr.getBytes("UTF-8"));
83 } catch (NoSuchAlgorithmException e) {
84 throw new RuntimeException("no sha-1 algorithm");
85 } catch (UnsupportedEncodingException e) {
86 throw new RuntimeException("unsupported utf-8 encoding");
87 }
88
89 StringBuilder sb = new StringBuilder();
90 for (int i = 0; i < byteArray.length; i++) {
91 sb.append(Integer.toString((byteArray[i] & 0xff) + 0x100, 16).substring(1));
92 }
93 return sb.toString();
94 }
95
96 /**
97 * 公众号,小程序后台配置服务器,初次检验时使用
98 * @throws IOException
99 */
100 public static void doGet(HttpServletRequest request, HttpServletResponse response, Map<String, String> weixinInfo) throws IOException {
101 log.info("doGet receive WeChat server request parameters:{}", request.getParameterMap());
102 String signature = request.getParameter("signature");
103 String timestamp = request.getParameter("timestamp");
104 String nonce = request.getParameter("nonce");
105 String echoStr = request.getParameter("echostr");
106 String[] arr = new String[]{weixinInfo.get("token"), timestamp, nonce};
107 String encrypt = WeixinUtil.encodeUsingSHA1(arr);
108 if (encrypt.equals(signature)) {
109 ServletOutputStream outputStream = response.getOutputStream();
110 outputStream.write(echoStr.getBytes());
111 outputStream.flush();
112 }
113 }
114
115
116 }