Prechádzať zdrojové kódy

Merge branch 'st_identity'

# Conflicts:
#	netflix-web/src/main/resources/application-dev.yml
#	netflix-web/src/main/resources/application-prd.yml
zoujiajian 2 rokov pred
rodič
commit
3edb8281bb
29 zmenil súbory, kde vykonal 673 pridanie a 5 odobranie
  1. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/UserActivityMapper.java
  2. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/UserStudentCertRecordMapper.java
  3. 3 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/coupon/CouponUserMapper.java
  4. 2 1
      netflix-dao/src/main/java/com/cyksj/model/entity/CouponUser.java
  5. 66 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserActivity.java
  6. 1 1
      netflix-dao/src/main/java/com/cyksj/model/entity/UserCertRecord.java
  7. 18 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserStudentCertRecord.java
  8. 45 0
      netflix-dao/src/main/java/com/cyksj/model/views/CouponReceiptDetailView.java
  9. 59 0
      netflix-dao/src/main/java/com/cyksj/model/views/CouponUsedDetailView.java
  10. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/CouponView.java
  11. 53 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserActivityView.java
  12. 6 0
      netflix-dao/src/main/resources/mapper/CouponUserMapper.xml
  13. 22 0
      netflix-service/src/main/java/com/cyksj/config/YhCertMiniConfig.java
  14. 2 0
      netflix-service/src/main/java/com/cyksj/service/mini/MiniService.java
  15. 8 0
      netflix-service/src/main/java/com/cyksj/service/mini/impl/MiniServiceImpl.java
  16. 17 0
      netflix-service/src/main/java/com/cyksj/service/user/UserActivityService.java
  17. 3 0
      netflix-service/src/main/java/com/cyksj/service/user/UserIdentCertService.java
  18. 68 0
      netflix-service/src/main/java/com/cyksj/service/user/impl/UserActivityServiceImpl.java
  19. 1 1
      netflix-service/src/main/java/com/cyksj/service/user/impl/UserBindRelationServiceImpl.java
  20. 17 0
      netflix-service/src/main/java/com/cyksj/service/user/impl/UserIdentCertServiceImpl.java
  21. 2 0
      netflix-service/src/main/java/com/cyksj/service/wechat/WeChatService.java
  22. 34 0
      netflix-service/src/main/java/com/cyksj/service/wechat/impl/WeChatServiceImpl.java
  23. 74 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/active/UserActivityController.java
  24. 27 2
      netflix-web/src/main/java/com/cyksj/web/controller/manage/coupon/CouponController.java
  25. 100 0
      netflix-web/src/main/java/com/cyksj/web/controller/mini/UserStudentCertController.java
  26. 11 0
      netflix-web/src/main/java/com/cyksj/web/controller/user/UserCertController.java
  27. 0 0
      netflix-web/src/main/resources/application-dev.yml
  28. 0 0
      netflix-web/src/main/resources/application-prd.yml
  29. 5 0
      netflix-web/src/main/resources/application-pre.yml

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/UserActivityMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.UserActivity;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserActivityMapper
+ * 创建者: JavaZou
+ * 创建时间:2024/4/15 16:01
+ */
+public interface UserActivityMapper extends BaseMapper<UserActivity> {
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/UserStudentCertRecordMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.UserStudentCertRecord;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserStudentCertRecordMapper
+ * 创建者: JavaZou
+ * 创建时间:2024/4/18 11:15
+ */
+public interface UserStudentCertRecordMapper extends BaseMapper<UserStudentCertRecord> {
+}

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/coupon/CouponUserMapper.java

@@ -10,6 +10,7 @@ import com.cyksj.model.views.CouponUserView;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
+import java.util.Map;
 
 /*
  *项目名: netflix
@@ -31,4 +32,6 @@ public interface CouponUserMapper extends BaseMapper<CouponUser> {
 	CouponUser getCouponByCouponUserId(Long couponUserId);
 
 	CouponUserView getCouponDetailById(@Param("userId") long userId, @Param("couponId") Long couponId);
+
+	Map<String, Long> selectCouponUserNumData(Long couponId);
 }

+ 2 - 1
netflix-dao/src/main/java/com/cyksj/model/entity/CouponUser.java

@@ -71,7 +71,8 @@ public class CouponUser extends BaseEntity {
 		channel_popularize("channel_popularize", "渠道推广"),
 		new_welfare("new_welfare", "新人福利"),
 		corp_active_code("corp_active_code", "企业微信活码"),
-		customer_link("customer_link", "获客链接")
+		customer_link("customer_link", "获客链接"),
+		student_cert("student_cert","大学生认证")
 		;
 		private String channel;
 		private String desc;

+ 66 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserActivity.java

@@ -0,0 +1,66 @@
+package com.cyksj.model.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotEmpty;
+import java.util.Date;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserActivity
+ * 创建者: JavaZou
+ * 创建时间:2024/4/15 15:44
+ * 官网用户活动表
+ */
+@Getter
+@Setter
+public class UserActivity extends BaseEntity{
+	/**
+	 * 活动名称
+	 */
+	@NotEmpty(message = "活动名称不能为空")
+	private String name;
+
+	/**
+	 * 开始时间
+	 */
+	@TableField(updateStrategy = FieldStrategy.IGNORED)
+	private Date startTime;
+
+	/**
+	 * 结束时间
+	 */
+	@TableField(updateStrategy = FieldStrategy.IGNORED)
+	private Date endTime;
+
+	/**
+	 * 备注
+	 */
+	private String remark;
+
+	/**
+	 * 优惠券ids
+	 */
+	@TableField(updateStrategy = FieldStrategy.IGNORED)
+	private String couponIds;
+
+	/**
+	 * 图片
+	 */
+	@TableField(updateStrategy = FieldStrategy.IGNORED)
+	private String img;
+
+	/**
+	 * 规则图片
+	 */
+	@TableField(updateStrategy = FieldStrategy.IGNORED)
+	private String rules;
+
+	/**
+	 * 是否删除
+	 */
+	private Boolean deleted;
+}

+ 1 - 1
netflix-dao/src/main/java/com/cyksj/model/entity/UserCertRecord.java

@@ -5,7 +5,7 @@ import lombok.Setter;
 
 /**
  * 项目名: yhlxj2
- * 文件名: UserCert
+ * 文件名: UserCertRecord
  * 创建者: JavaZou
  * 创建时间:2024/2/21 10:00
  */

+ 18 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserStudentCertRecord.java

@@ -0,0 +1,18 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserStudentCertRecord
+ * 创建者: JavaZou
+ * 创建时间:2024/4/18 11:14
+ */
+@Getter
+@Setter
+public class UserStudentCertRecord extends BaseEntity{
+	private Long userId;
+
+	private String school;
+}

+ 45 - 0
netflix-dao/src/main/java/com/cyksj/model/views/CouponReceiptDetailView.java

@@ -0,0 +1,45 @@
+package com.cyksj.model.views;
+
+import com.cyksj.model.entity.CouponUser;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: CouponReceiptDetailView
+ * 创建者: JavaZou
+ * 创建时间:2024/4/16 16:58
+ */
+@Getter
+@Setter
+@SearchBean(tables = "(select id,name from coupon where deleted is true :cid:) c inner join coupon_user cu on cu.coupon_id = c.id inner join user u on u.id = cu.user_id")
+public class CouponReceiptDetailView {
+
+	@DbField("cu.id")
+	private Long id;
+
+	@DbField("c.id")
+	private Long couponId;
+
+	@DbField("c.name")
+	private String name;
+
+	@DbField("u.id")
+	private Long userId;
+
+	@DbField("u.nickname")
+	private String nickname;
+
+	@DbField("cu.status")
+	private CouponUser.Status status;
+
+	@DbField("cu.created_time")
+	private Date receiptTime;
+
+	@DbField("cu.valid_end_time")
+	private Date expiryTime;
+}

+ 59 - 0
netflix-dao/src/main/java/com/cyksj/model/views/CouponUsedDetailView.java

@@ -0,0 +1,59 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: CouponUsedDetailView
+ * 创建者: JavaZou
+ * 创建时间:2024/4/16 17:05
+ */
+@Getter
+@Setter
+@SearchBean(tables = "(select id,name from coupon where deleted is true :cid:) c inner join coupon_user cu on cu.coupon_id = c.id inner join user u on u.id = cu.user_id" +
+		" inner join order_don o on o.coupon_user_id = cu.id and o.status not in ('close','noPayment','refund')" +
+		" left join goods_don g on g.id = o.goods_id" +
+		" left join goods_don_sku sku on sku.id = o.sku_id")
+public class CouponUsedDetailView {
+
+	@DbField("cu.id")
+	private Long id;
+
+	@DbField("c.id")
+	private Long couponId;
+
+	@DbField("c.name")
+	private String name;
+
+	@DbField("u.id")
+	private Long userId;
+
+	@DbField("u.nickname")
+	private String nickname;
+
+	@DbField("o.order_no")
+	private String orderNo;
+
+	@DbField("cu.created_time")
+	private Date receiptTime;
+
+	@DbField("sku.id")
+	private Long skuId;
+
+	@DbField("sku.spec_val")
+	private String specVal;
+
+	@DbField("g.id")
+	private Long goodsId;
+
+	@DbField("g.title")
+	private String goodsName;
+
+	@DbField("o.created_time")
+	private Date usedTime;
+}

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/model/views/CouponView.java

@@ -124,6 +124,9 @@ public class CouponView {
 	@DbIgnore
 	private Integer usedNum;
 
+	@DbIgnore
+	private Integer receiptNum;
+
 	/**
 	 * 发放状态
 	 */

+ 53 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserActivityView.java

@@ -0,0 +1,53 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserActivityView
+ * 创建者: JavaZou
+ * 创建时间:2024/4/16 15:43
+ */
+@Getter
+@Setter
+@SearchBean(tables = "user_activity ua",
+		where = "ua.deleted is true")
+public class UserActivityView {
+
+	@DbField("ua.id")
+	private Long id;
+
+	/**
+	 * 活动名称
+	 */
+	@DbField("ua.name")
+	private String name;
+
+	@DbField("ua.start_time")
+	private Date startTime;
+
+	@DbField("ua.end_time")
+	private Date endTime;
+
+	/**
+	 * 优惠券ids
+	 */
+	@DbField("ua.coupon_ids")
+	private String couponIds;
+
+	@DbField("ua.img")
+	private String img;
+
+	@DbField("ua.rules")
+	private String rules;
+
+	@DbIgnore
+	private List<CouponView> couponViews;
+}

+ 6 - 0
netflix-dao/src/main/resources/mapper/CouponUserMapper.xml

@@ -233,4 +233,10 @@
                 and coupon_id = #{couponId} limit 1) cu
                  inner join coupon c on c.id = cu.coupon_id
     </select>
+
+    <select id="selectCouponUserNumData" resultType="java.util.Map">
+        select count(if(status = 'used', 1, NULL)) usedNum, count(*) receiptNum
+        from coupon_user
+        where coupon_id = #{couponId}
+    </select>
 </mapper>

+ 22 - 0
netflix-service/src/main/java/com/cyksj/config/YhCertMiniConfig.java

@@ -0,0 +1,22 @@
+package com.cyksj.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: CertMiniConfig
+ * 创建者: JavaZou
+ * 创建时间:2024/4/16 12:00
+ */
+@Configuration
+@ConfigurationProperties(prefix = "certmini")
+@Getter
+@Setter
+public class YhCertMiniConfig {
+	private String appId;
+
+	private String secret;
+}

+ 2 - 0
netflix-service/src/main/java/com/cyksj/service/mini/MiniService.java

@@ -19,4 +19,6 @@ public interface MiniService {
 	Result<String> markArticle(MiniArticleReq miniArticleReq);
 
 	ArticleDetailView getArticleDetailView(Long articleId, Long userId);
+
+	void getStudentIdentity(User user, String code) throws Exception;
 }

+ 8 - 0
netflix-service/src/main/java/com/cyksj/service/mini/impl/MiniServiceImpl.java

@@ -3,6 +3,7 @@ package com.cyksj.service.mini.impl;
 import cn.hutool.core.util.RandomUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.config.YhCertMiniConfig;
 import com.cyksj.config.YhMiniConfig;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
@@ -41,6 +42,8 @@ public class MiniServiceImpl implements MiniService {
 
 	private final YhMiniConfig yhMiniConfig;
 
+	private final YhCertMiniConfig certMiniConfig;
+
 	private final RedisService redisService;
 
 	private final UserMapper userMapper;
@@ -153,6 +156,11 @@ public class MiniServiceImpl implements MiniService {
 		return detailView;
 	}
 
+	@Override
+	public void getStudentIdentity(User user, String code) throws Exception {
+		weChatService.getMiniStudentIdentity(user.getOpenId(), code);
+	}
+
 	public void updateArticleMarkNum(Integer type, Long articleId, Integer offset) {
 		Integer success = 0;
 		while (success != 1) {

+ 17 - 0
netflix-service/src/main/java/com/cyksj/service/user/UserActivityService.java

@@ -0,0 +1,17 @@
+package com.cyksj.service.user;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.cyksj.model.entity.User;
+import com.cyksj.model.entity.UserActivity;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserActivityService
+ * 创建者: JavaZou
+ * 创建时间:2024/4/16 12:16
+ */
+public interface UserActivityService extends IService<UserActivity> {
+	void sendStudentCertActivity(User user, String dsCode) throws Exception;
+
+	void saveOrUpdateActivity(UserActivity userActivity) throws Exception;
+}

+ 3 - 0
netflix-service/src/main/java/com/cyksj/service/user/UserIdentCertService.java

@@ -2,6 +2,7 @@ package com.cyksj.service.user;
 
 import com.cyksj.model.dto.UserWxIndentDto;
 import com.cyksj.model.entity.UserCertRecord;
+import com.cyksj.model.entity.UserStudentCertRecord;
 import com.cyksj.model.request.UserIndentCertReq;
 import com.cyksj.model.response.WxCertAuthTokenResp;
 
@@ -21,4 +22,6 @@ public interface UserIdentCertService {
 	Boolean checkCertRecord(long userId);
 
 	UserCertRecord getUserCertRecord(long userId);
+
+	UserStudentCertRecord getUserStudentCertRecord(long userId);
 }

+ 68 - 0
netflix-service/src/main/java/com/cyksj/service/user/impl/UserActivityServiceImpl.java

@@ -0,0 +1,68 @@
+package com.cyksj.service.user.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.common.util.Jsons;
+import com.cyksj.mapper.UserActivityMapper;
+import com.cyksj.mapper.UserMapper;
+import com.cyksj.model.entity.CouponUser;
+import com.cyksj.model.entity.User;
+import com.cyksj.model.entity.UserActivity;
+import com.cyksj.service.mange.coupon.CouponCommonService;
+import com.cyksj.service.user.UserActivityService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserActivityServiceImpl
+ * 创建者: JavaZou
+ * 创建时间:2024/4/16 12:16
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class UserActivityServiceImpl extends ServiceImpl<UserActivityMapper, UserActivity> implements UserActivityService {
+	private final CouponCommonService couponCommonService;
+
+	private final UserMapper userMapper;
+
+	@Override
+	public void sendStudentCertActivity(User user, String dsCode) throws Exception {
+		UserActivity activity = getById(1);
+		Long sendUserId = user.getId();
+		if (StrUtil.isNotBlank(dsCode)) {
+			User toUser = userMapper.selectOne(Wrappers.lambdaQuery(User.class).eq(User::getShowId, dsCode).last("limit 1"));
+			if (toUser != null) {
+				sendUserId = toUser.getId();
+			}
+		}
+		if (StrUtil.isNotBlank(activity.getCouponIds())) {
+			//发送优惠券
+			List<Long> couponIds = Jsons.parseList(activity.getCouponIds(), Long.class);
+			log.info("uid:{}大学生认证成功,发放优惠券:{}", user.getId(), couponIds);
+			for (Long couponId : couponIds) {
+				couponCommonService.sendCouponToUser(sendUserId, couponId, 0l, 0l, 0l, CouponUser.Channel.student_cert);
+			}
+		}
+	}
+
+	@Override
+	public void saveOrUpdateActivity(UserActivity userActivity) throws Exception {
+		checkActivity(userActivity);
+		saveOrUpdate(userActivity);
+	}
+
+
+	public void checkActivity(UserActivity userActivity) throws Exception {
+		String couponIds = userActivity.getCouponIds();
+		if (StrUtil.isNotBlank(couponIds)) {
+			List<Long> couponidsList = Jsons.parseList(couponIds, Long.class);
+			userActivity.setCouponIds(Jsons.toJson(couponidsList));
+		}
+	}
+}

+ 1 - 1
netflix-service/src/main/java/com/cyksj/service/user/impl/UserBindRelationServiceImpl.java

@@ -38,7 +38,7 @@ public class UserBindRelationServiceImpl implements UserBindRelationService {
 
 		UserBindDetail userBindDetail;
 		//微信用户
-		if (StrUtil.isNotEmpty(user.getUnionid())) {
+		if (StrUtil.isNotEmpty(user.getOpenId())) {
 			userIds.add(userId);
 			userBindDetail = userBindDetailMapper.selectOne(Wrappers.lambdaQuery(UserBindDetail.class)
 					.eq(UserBindDetail::getUserId, userId).last("limit 1"));

+ 17 - 0
netflix-service/src/main/java/com/cyksj/service/user/impl/UserIdentCertServiceImpl.java

@@ -10,9 +10,11 @@ import com.cyksj.common.util.Jsons;
 import com.cyksj.common.util.StringUtil;
 import com.cyksj.mapper.UserCertRecordMapper;
 import com.cyksj.mapper.UserMapper;
+import com.cyksj.mapper.UserStudentCertRecordMapper;
 import com.cyksj.model.dto.UserWxIndentDto;
 import com.cyksj.model.entity.User;
 import com.cyksj.model.entity.UserCertRecord;
+import com.cyksj.model.entity.UserStudentCertRecord;
 import com.cyksj.model.request.UserIndentCertReq;
 import com.cyksj.model.response.WxCertAuthTokenResp;
 import com.cyksj.redis.RedisService;
@@ -43,6 +45,8 @@ public class UserIdentCertServiceImpl implements UserIdentCertService {
 
 	private final UserCertRecordMapper userCertRecordMapper;
 
+	private final UserStudentCertRecordMapper userStudentCertRecordMapper;
+
 	private final UserMapper userMapper;
 
 	private final RedisService redisService;
@@ -81,6 +85,19 @@ public class UserIdentCertServiceImpl implements UserIdentCertService {
 		return record;
 	}
 
+	@Override
+	public UserStudentCertRecord getUserStudentCertRecord(long userId) {
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+		UserStudentCertRecord record = userStudentCertRecordMapper.selectOne(Wrappers.lambdaQuery(UserStudentCertRecord.class)
+				.in(UserStudentCertRecord::getUserId, userIdList)
+				.select(UserStudentCertRecord::getSchool, UserStudentCertRecord::getCreatedTime)
+				.last("limit 1"));
+		if (record == null) {
+			return null;
+		}
+		return record;
+	}
+
 	@Override
 	public String bindWxUser(long userId) {
 		User user = userMapper.selectById(userId);

+ 2 - 0
netflix-service/src/main/java/com/cyksj/service/wechat/WeChatService.java

@@ -101,4 +101,6 @@ public interface WeChatService {
     String getMiniURLLink(String accessToken, MiniURLLink miniURLLink) throws Exception;
 
     MiniProgramSession code2Session(String appId, String code) throws Exception;
+
+    void getMiniStudentIdentity(String openId, String code) throws Exception;
 }

+ 34 - 0
netflix-service/src/main/java/com/cyksj/service/wechat/impl/WeChatServiceImpl.java

@@ -15,6 +15,7 @@ import com.cyksj.common.util.*;
 import com.cyksj.config.BaseWeChatConfig;
 import com.cyksj.config.WeChatConfig;
 import com.cyksj.config.WeChatFactory;
+import com.cyksj.config.YhCertMiniConfig;
 import com.cyksj.enums.WeChatAuthRedirectUrl;
 import com.cyksj.mapper.WxAppMapper;
 import com.cyksj.mapper.channel.ShopConfigMapper;
@@ -71,6 +72,8 @@ public class WeChatServiceImpl implements WeChatService {
 
     private final SysConfigService sysConfigService;
 
+    private final YhCertMiniConfig certMiniConfig;
+
     @Override
     public String createUrl(String state, String redirectUrl) {
         return createUrl(state,redirectUrl,weChatConfig.getAppid(), WeChatAuthRedirectUrl.BASE.getScope());
@@ -666,4 +669,35 @@ public class WeChatServiceImpl implements WeChatService {
         return wxMpAccountOps.miniProgramCode2Session(appId,code);
     }
 
+    @Override
+    public void getMiniStudentIdentity(String openId, String code) throws Exception {
+        String url = "https://api.weixin.qq.com/intp/quickcheckstudentidentity?access_token=" + getAccessToken(certMiniConfig.getAppId());
+
+        JSONObject params = new JSONObject();
+        params.putOpt("openid", openId);
+        params.putOpt("wx_studentcheck_code", code);
+
+        HttpResponse<String> response = J11HttpC.custom().url(url).ofPost().body(HttpRequest.BodyPublishers.ofString(params.toString())).send(HttpResponse.BodyHandlers.ofString());
+
+        JSONObject re = Jsons.parseObject(response.body(), JSONObject.class);
+        if (re.getInt("errcode") != 0) {
+            log.info("获取学生信息失败:{}", re.getStr("errmsg"));
+            throw BusinessRuntimeException.getInstance("获取认证信息失败");
+        }
+        Boolean isStudent = re.getBool("is_student");
+        if (isStudent == null || !isStudent) {
+            throw BusinessRuntimeException.getInstance("仅支持大学生用户认证");
+        }
+        Integer bindStatus = re.getInt("bind_status");
+        //绑定状态:
+        //1-未绑定
+        //2-审核中
+        //3-已绑定
+        if (bindStatus == 1) {
+            throw BusinessRuntimeException.getInstance("大学生身份未绑定");
+        }
+        if (bindStatus == 2) {
+            throw BusinessRuntimeException.getInstance("大学生身份审核中");
+        }
+    }
 }

+ 74 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/active/UserActivityController.java

@@ -0,0 +1,74 @@
+package com.cyksj.web.controller.manage.active;
+
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.model.entity.UserActivity;
+import com.cyksj.service.user.UserActivityService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserActivityController
+ * 创建者: JavaZou
+ * 创建时间:2024/4/17 12:22
+ */
+@RestController
+@RequestMapping("/manage/activity")
+@Slf4j
+@RequiredArgsConstructor
+public class UserActivityController {
+	private final UserActivityService userActivityService;
+
+	private final BeanSearcher beanSearcher;
+
+	private final HttpServletRequest request;
+
+	/**
+	 * 新建活动
+	 */
+	@PostMapping("/post")
+	public Result<String> insertActivity(@RequestBody @Validated UserActivity userActivity) throws Exception {
+		userActivityService.saveOrUpdateActivity(userActivity);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 编辑活动
+	 */
+	@PutMapping("/update")
+	public Result<String> updateActivity(@RequestBody @Validated UserActivity userActivity) throws Exception {
+		userActivityService.saveOrUpdateActivity(userActivity);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 删除活动
+	 */
+	@DeleteMapping("/delete/{id}")
+	public Result<String> deleteActivity(@PathVariable Long id) {
+		UserActivity activity = userActivityService.getById(id);
+		if (activity != null && activity.getDeleted()) {
+			activity.setDeleted(false);
+			userActivityService.updateById(activity);
+		}
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 活动列表
+	 */
+	@GetMapping("/get")
+	public Result<SearchResult<UserActivity> > get() {
+		SearchResult<UserActivity> search = beanSearcher.search(UserActivity.class, MapUtils.flatBuilder(request.getParameterMap()).field(UserActivity::getDeleted, 1).build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+}

+ 27 - 2
netflix-web/src/main/java/com/cyksj/web/controller/manage/coupon/CouponController.java

@@ -39,6 +39,7 @@ import org.springframework.web.bind.annotation.*;
 import javax.servlet.http.HttpServletRequest;
 import javax.validation.constraints.Min;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
@@ -188,9 +189,11 @@ public class CouponController {
 		search.getDataList().forEach(data -> {
 			data.setRelationNum(couponDistributePopularizeMapper.selectCount(Wrappers.lambdaQuery(CouponDistributePopularize.class).eq(CouponDistributePopularize::getCouponId, data.getId())));
 
-			Integer usedNum = couponUserMapper.selectCount(Wrappers.lambdaQuery(CouponUser.class)
-					.eq(CouponUser::getCouponId, data.getId()).eq(CouponUser::getStatus, CouponUser.Status.used));
+			Map<String, Long> couponUserNumData = couponUserMapper.selectCouponUserNumData(data.getId());
+			Integer usedNum = Integer.parseInt(couponUserNumData.get("usedNum").toString());
 			data.setUsedNum(usedNum);
+			Integer receiptNum = Integer.parseInt(couponUserNumData.get("receiptNum").toString());
+			data.setReceiptNum(receiptNum);
 
 			List<GoodsDonSkuView> skuViewList = couponSkuMapper.selectGoodsSkuViewList(data.getId());
 			data.setSkuViewList(skuViewList);
@@ -511,4 +514,26 @@ public class CouponController {
 		});
 		return GatewayResponse.SUCCESS.newBuilder().toResult();
 	}
+
+	/**
+	 * 优惠券领取详情
+	 */
+	@GetMapping("/get/receipt/detail/{couponId}")
+	public Result<SearchResult<CouponReceiptDetailView>> getReceiptDetail(@PathVariable Long couponId) {
+		SearchResult<CouponReceiptDetailView> search = beanSearcher.search(CouponReceiptDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
+				.put("cid",String.format("and id = %s", couponId))
+				.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 优惠券使用详情
+	 */
+	@GetMapping("/get/used/detail/{couponId}")
+	public Result<SearchResult<CouponUsedDetailView>> getUsedDetail(@PathVariable Long couponId) {
+		SearchResult<CouponUsedDetailView> search = beanSearcher.search(CouponUsedDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
+				.put("cid",String.format("and id = %s", couponId))
+				.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
 }

+ 100 - 0
netflix-web/src/main/java/com/cyksj/web/controller/mini/UserStudentCertController.java

@@ -0,0 +1,100 @@
+package com.cyksj.web.controller.mini;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.util.Jsons;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.UserMapper;
+import com.cyksj.mapper.UserStudentCertRecordMapper;
+import com.cyksj.model.entity.User;
+import com.cyksj.model.entity.UserStudentCertRecord;
+import com.cyksj.model.views.CouponView;
+import com.cyksj.model.views.UserActivityView;
+import com.cyksj.service.mini.MiniService;
+import com.cyksj.service.user.UserActivityService;
+import com.cyksj.service.user.UserBindRelationService;
+import com.cyksj.web.util.StpUserUtil;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.param.Operator;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: UserCertController
+ * 创建者: JavaZou
+ * 创建时间:2024/4/16 11:34
+ */
+@RestController
+@RequestMapping("/applets/mini/identity")
+@RequiredArgsConstructor
+@Slf4j
+public class UserStudentCertController {
+	private final UserMapper userMapper;
+
+	private final MiniService miniService;
+
+	private final UserActivityService userActivityService;
+
+	private final UserBindRelationService userBindRelationService;
+
+	private final BeanSearcher beanSearcher;
+
+	private final UserStudentCertRecordMapper userStudentCertRecordMapper;
+
+	/**
+	 * 获取学生身份接口
+	 */
+	@GetMapping("/get/student")
+	public Result<String> getStudentIdentity(String school, String code, String dsCode) throws Exception {
+		long userId = StpUserUtil.getLoginIdAsLong();
+		User user = userMapper.selectById(userId);
+		if (user == null || StrUtil.isEmpty(user.getOpenId())) {
+			throw BusinessRuntimeException.getInstance("用户未授权");
+		}
+		//是否认证过
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, user);
+		Integer selectCount = userStudentCertRecordMapper.selectCount(Wrappers.lambdaQuery(UserStudentCertRecord.class)
+				.in(UserStudentCertRecord::getUserId, userIdList));
+		if (selectCount > 0) {
+			throw BusinessRuntimeException.getInstance("已认证大学生身份");
+		}
+		miniService.getStudentIdentity(user, code);
+		//大学生认证活动 若有sid则发送对应用户
+		try {
+			UserStudentCertRecord record = new UserStudentCertRecord();
+			record.setUserId(userId);
+			record.setSchool(school);
+			userStudentCertRecordMapper.insert(record);
+			userActivityService.sendStudentCertActivity(user, dsCode);
+		} catch (DuplicateKeyException e) {
+		}
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 大学生认证活动详情
+	 */
+	@GetMapping("/get/activity/info")
+	public Result<UserActivityView> getIdentityAcInfo() throws Exception {
+		UserActivityView userActivityView = beanSearcher.searchFirst(UserActivityView.class, MapUtils.builder().field(UserActivityView::getId, 1).build());
+		if (userActivityView == null) {
+			return GatewayResponse.SUCCESS.newBuilder().toResult();
+		}
+		if (StrUtil.isNotBlank(userActivityView.getCouponIds())) {
+			List<Long> couponIds = Jsons.parseList(userActivityView.getCouponIds(), Long.class);
+			userActivityView.setCouponViews(beanSearcher.searchAll(CouponView.class, MapUtils.builder().field(CouponView::getId, couponIds).op(Operator.InList).build()));
+		}
+		return GatewayResponse.SUCCESS.newBuilder().toResult(userActivityView);
+	}
+
+}

+ 11 - 0
netflix-web/src/main/java/com/cyksj/web/controller/user/UserCertController.java

@@ -6,6 +6,7 @@ import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.model.dto.UserWxIndentDto;
 import com.cyksj.model.entity.UserCertRecord;
+import com.cyksj.model.entity.UserStudentCertRecord;
 import com.cyksj.model.request.UserIndentCertReq;
 import com.cyksj.model.response.WxCertAuthTokenResp;
 import com.cyksj.redis.RedisService;
@@ -89,4 +90,14 @@ public class UserCertController {
 		UserCertRecord record = userIdentCertService.getUserCertRecord(userId);
 		return GatewayResponse.SUCCESS.newBuilder().toResult(record);
 	}
+
+	/**
+	 * 查看大学生认证信息
+	 */
+	@GetMapping("/get/student/info")
+	public Result<UserStudentCertRecord> getUserStudentCertRecord() {
+		long userId = StpUserUtil.getLoginIdAsLong();
+		UserStudentCertRecord record = userIdentCertService.getUserStudentCertRecord(userId);
+		return GatewayResponse.SUCCESS.newBuilder().toResult(record);
+	}
 }

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
netflix-web/src/main/resources/application-dev.yml


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
netflix-web/src/main/resources/application-prd.yml


+ 5 - 0
netflix-web/src/main/resources/application-pre.yml

@@ -165,6 +165,11 @@ yhmini:
   appid: wx383c483d3bcf155a
   secret: bf6ca029a3102f390486a7a14b218b06
 
+#银河录像局大学生认证小程序
+certmini:
+  appid: wx16e441d61fa3fd8a
+  secret: edc2e8ed29a45d6ba266a63bc7ffc2b5
+
 #广告投放小程序
 advertisement:
   appId: wx895f960ea6b8c5d0

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov