Commit 2bf05374 2bf053742d549dd4a7a4de6e74f6fc144d232311 by xianghan@topdraw.cn

V1.0.2.REALESE

1 parent dc5e7311
Showing 22 changed files with 1094 additions and 5 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 }
......
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 }