UserOperationController.java 15.3 KB
package com.topdraw.business.process.rest;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

import com.alibaba.fastjson.JSONObject;
import com.topdraw.annotation.AnonymousAccess;
import com.topdraw.aop.log.Log;
import com.topdraw.business.module.common.validated.CreateGroup;
import com.topdraw.business.module.common.validated.UpdateGroup;
import com.topdraw.business.module.member.service.MemberService;
import com.topdraw.business.module.member.service.dto.MemberDTO;
import com.topdraw.business.module.user.iptv.domain.UserTv;
import com.topdraw.business.module.user.iptv.service.dto.UserTvDTO;
import com.topdraw.business.module.user.weixin.domain.UserWeixin;
import com.topdraw.business.module.user.weixin.service.dto.UserWeixinDTO;
import com.topdraw.business.process.domian.weixin.*;
import com.topdraw.business.process.service.UserOperationService;
import com.topdraw.common.ResultInfo;
import com.topdraw.config.RedisKeyUtil;
import com.topdraw.exception.BadRequestException;
import com.topdraw.exception.EntityNotFoundException;
import com.topdraw.exception.GlobeExceptionMsg;
import com.topdraw.resttemplate.RestTemplateClient;
import com.topdraw.util.Base64Util;
import com.topdraw.util.JSONUtil;
import com.topdraw.utils.RedisUtils;
import com.topdraw.weixin.util.WeChatConstants;
import com.topdraw.weixin.util.WeixinUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.*;

@Api("账户处理")
@RestController
@RequestMapping(value = "/uce/userOperation")
@Slf4j
public class UserOperationController {

    @Autowired
    private MemberService memberService;
    @Autowired
    private UserOperationService userOperationService;

    @Autowired
    private RedisUtils redisUtils;

    private static final String SUBSCRIBE = "subscribe";
    private static final String UNSUBSCRIBE = "unsubscribe";
    private static final Integer SUBSCRIBE_STATUS = 1;

    @Log("新增小屏账户同时创建会员信息")
    @PostMapping(value = "/createWeixinUserAndCreateMember")
    @ApiOperation("新增小屏账户同时创建会员信息")
    @AnonymousAccess
    public ResultInfo createWeixinUserAndMember(@Validated(value = {CreateGroup.class}) @RequestBody UserWeixin resources) {
        log.info("UserOperationController ==> createWeixinUserAndMember ==> param  ==> [{}]",resources);

        UserWeixinDTO result = this.userOperationService.createWeixinUserAndMember(resources);
        return ResultInfo.success(result);
    }

    @Log("微信服务号(H5)登录")
    @PostMapping("/serviceLogin")
    @ApiOperation("微信服务号(H5)登录")
    @AnonymousAccess
    public ResultInfo serviceLogin(@Validated(value = {CreateGroup.class}) @RequestBody UserWeixin resources) {
        log.info("UserOperationController ==> serviceLogin ==>> param  ==> [{}]",resources);

        UserWeixinDTO result = this.userOperationService.serviceLogin(resources);
        return ResultInfo.success(result);
    }

    @Log("微信小程序登录")
    @PostMapping("/appletLogin")
    @ApiOperation("微信小程序登录")
    @AnonymousAccess
    public ResultInfo appletLogin(@Validated(value = {CreateGroup.class}) @RequestBody UserWeixin resources) {
        log.info("UserOperationController ==> appletLogin ==>> param  ==> [{}]",resources);

        UserWeixinDTO result = this.userOperationService.appletLogin(resources);
        return ResultInfo.success(result);
    }

    @Log("微信公众号关注")
    @PostMapping("/subscribe")
    @ApiOperation("微信公众号关注")
    @AnonymousAccess
    public ResultInfo subscribe(@Validated @RequestBody SubscribeBeanEvent data) throws IOException {
        log.info("UserOperationController ==> subscribe ==>> param  ==> [{}]",data);

        SubscribeBean subscribeBean = JSONUtil.parseMsg2Object(data.getContent(), SubscribeBean.class);
        // 解析参数
        this.parseSubscribe(subscribeBean);
        this.userOperationService.subscribe(subscribeBean);
        return ResultInfo.success();
    }

    /**
     *
     * @param subscribeBean
     * @throws IOException
     */
    private void parseSubscribe(SubscribeBean subscribeBean) throws IOException {

        String appId = subscribeBean.getAppid();
        Assert.notNull(appId, GlobeExceptionMsg.APP_ID_IS_NULL);
        // openId
        String openId = subscribeBean.getOpenid();
        Assert.notNull(openId, GlobeExceptionMsg.OPEN_ID_IS_NULL);
        // unionId
        String unionId = subscribeBean.getUnionid();
        Assert.notNull(openId, GlobeExceptionMsg.UNION_ID_IS_NULL);

        // 匹配配置文件中的微信列表信息
        Map<String, String> wxInfoMap = WeixinUtil.getWeixinInfoByAppid(appId);

        if (Objects.nonNull(wxInfoMap)) {
            // 程序类型
            String appType = wxInfoMap.get("appType");
            // 非订阅号,暂不处理。返回暂不支持
            if (ObjectUtil.notEqual(appType, WeChatConstants.WX_SUBSCRIPTION))
                throw new BadRequestException("非订阅号");
        }

        // 大屏账户信息
        JSONObject iptvUserInfo = null;
        // 缓存的大屏信息,使用unionid即可
        String content = (String) this.redisUtils.get(RedisKeyUtil.genSeSuSubscribeKey(unionId));
        if (StringUtils.isNotBlank(content)) {
            // 大屏信息
            iptvUserInfo = JSONObject.parseObject(content);

        }

        // 用户自己搜索关注就没有大屏信息,否则表示扫码关注
        if (Objects.nonNull(iptvUserInfo)) {

            subscribeBean.setIptvUserInfo(iptvUserInfo);

            String headimgurl = iptvUserInfo.get("headimgurl").toString();
            String nickname = iptvUserInfo.get("nickname").toString();
            if (StringUtils.isNotBlank(nickname)) {
                String nicknameDecode = URLDecoder.decode(nickname, "UTF-8");
                String nicknameEncode = Base64Util.encode(nicknameDecode);
                subscribeBean.setNickname(nicknameEncode);
            }

            if (StringUtils.isNotBlank(headimgurl)) {
                String headimgurlDecode = URLDecoder.decode(headimgurl, "UTF-8");
                subscribeBean.setHeadimgurl(headimgurlDecode);
            }

        }
    }

    @Log("微信公众号取关")
    @PostMapping("/unsubscribe")
    @ApiOperation("微信公众号取关")
    @AnonymousAccess
    public ResultInfo unsubscribe(@Validated @RequestBody SubscribeBeanEvent data) {
        log.info("UserOperationController ==> unsubscribe ==>> param  ==> [{}]",data);

        SubscribeBean subscribeBean = JSONUtil.parseMsg2Object(data.getContent(), SubscribeBean.class);

        String appId = subscribeBean.getAppId();
        Assert.notNull(appId, GlobeExceptionMsg.APP_ID_IS_NULL);
        // openId
        String openId = subscribeBean.getOpenId();
        Assert.notNull(openId, GlobeExceptionMsg.OPEN_ID_IS_NULL);

        subscribeBean.setAppid(appId);
        subscribeBean.setOpenid(openId);

        boolean result = this.userOperationService.unsubscribe(subscribeBean);
        return ResultInfo.success(result);
    }

    @Log("微信小程序绑定大屏")
    @PostMapping("/appletBind")
    @ApiOperation("微信小程序绑定大屏")
    @AnonymousAccess
    public ResultInfo appletBind(@Validated(value = {BindGroup.class}) @RequestBody BindBean resources) {
        log.info("UserOperationController ==> appletBind ==>> param  ==> [{}]",resources);

        boolean result = this.userOperationService.appletBind(resources);
        return ResultInfo.success(result);
    }

    @Log("暂存大小屏信息并检查关注与绑定状态")
    @PostMapping(value = "/saveUserInfo")
    @ApiOperation("暂存大小屏信息并检查关注与绑定状态")
    @AnonymousAccess
    public ResultInfo saveUserInfo(@RequestBody String data) {

        log.info("UserOperationController ==> saveUserInfo ==>> param ==>> [{}]",data);
        Assert.notNull(data, "用户数据不可为空");

        JSONObject json = JSONObject.parseObject(data);

        String unionid = json.getString("unionid");
        Assert.state(StrUtil.isNotBlank(unionid), "unionid不可为空");


        List<Object> resultList = new ArrayList<>();
        // 大屏侧通过返回值来展示对应的小程序页面
        String result = SUBSCRIBE;
        String platformAccount1 = "";

        // 保存大小屏信息到redis同时返回小屏信息
        UserWeixinDTO userWeixinDTO = this.userOperationService.saveUserInfo(data);

        // 小屏账号不存在
        if (Objects.isNull(userWeixinDTO) || Objects.isNull(userWeixinDTO.getId())) {

            result = UNSUBSCRIBE;
            resultList.add(result);
            resultList.add(platformAccount1);
            log.info("saveUserInfo ==>> result ==>> [{}]",resultList);
            return ResultInfo.success(resultList);

        } else {

            // 账号存在,未关注
            if (userWeixinDTO.getStatus() != SUBSCRIBE_STATUS) {
                result = UNSUBSCRIBE;
            }

            // 小屏会员
            MemberDTO memberDTO = this.memberService.findById(userWeixinDTO.getMemberId());

            if (Objects.nonNull(memberDTO)) {

                // 检查是否绑定,返回绑定的大屏账户
                UserTvDTO userTvDTO = this.userOperationService.checkBind(memberDTO);
                if (Objects.nonNull(userTvDTO)) {
                    // 绑定的大屏账号
                    platformAccount1 = userTvDTO.getPlatformAccount();
                }

            } else {

                // 数据异常,没有会员
                log.info("userWeixinDTO ==>> [{}]",userWeixinDTO);
                throw new EntityNotFoundException(MemberDTO.class,"code","member is null !!");

            }

            // 关注
            if (result.equalsIgnoreCase(SUBSCRIBE)) {

                // 未绑定
                if (StringUtils.isBlank(platformAccount1)) {

                    // redis中的大小屏信息
                    String content = (String) this.redisUtils.get(RedisKeyUtil.genSeSuSubscribeKey(unionid));
                    JSONObject iptvUserInfo = JSONObject.parseObject(content);
                    // redis中的大小屏信息
                    log.info("saveUserInfo ==> redis content iptvUserInfo  ==> [{}]",iptvUserInfo);

                    // 大屏账户
                    String platformAccount = iptvUserInfo.getString("platformAccount");

                    try {
                        String headimgurl = iptvUserInfo.get("headimgurl").toString();
                        String nickname = iptvUserInfo.get("nickname").toString();
                        if (StringUtils.isNotBlank(nickname)) {
                            String nicknameDecode = URLDecoder.decode(nickname, "UTF-8");
                            String nicknameEncode = Base64Util.encode(nicknameDecode);
                            memberDTO.setNickname(nicknameEncode);
                        }
                        if (StringUtils.isNotBlank(headimgurl)) {
                            String headimgurlDecode = URLDecoder.decode(headimgurl, "UTF-8");
                            String imageEncode = Base64Util.encode(headimgurlDecode);
                            String image = RestTemplateClient.chooseImage(imageEncode, "image");
                            memberDTO.setAvatarUrl(StringUtils.isNotBlank(image) == true ? image:headimgurlDecode);
                        }
                    } catch (Exception e) {
                        log.info("头像解析失败!!!");
                        e.printStackTrace();
                    }

                    // 大小屏绑定,如果已经绑定了别的大屏,则不进行处理,返回已绑定的大屏信息
                    UserTvDTO userTvDTO = this.userOperationService.bind(memberDTO, platformAccount);
                    if (userTvDTO != null) {
                        platformAccount1 = userTvDTO.getPlatformAccount();
                    }

                }

            }

        }

        resultList.add(result);
        resultList.add(platformAccount1);

        // return ["subscribe","platform_account"]
        ResultInfo<Object> success = ResultInfo.success(resultList);

        log.info("saveUserInfo ==> ResultInfo  ==> [{}]",success);
        return success;
    }


    /******************************************************* IPTV ************************************/

    @Log("保存大屏账户同时创建会员")
    @PostMapping(value = "/createTvUserAndMember")
    @ApiOperation("保存大屏账户同时创建会员信息")
    @AnonymousAccess
    public ResultInfo createTvUserAndMember(@Validated(value = {CreateGroup.class}) @RequestBody UserTv resources) {
        log.info("UserOperationController ==> createUserAndCreateMember ==>> param  ==> [{}]",resources);

        UserTvDTO result = this.userOperationService.createTvUserAndMember(resources);
        return ResultInfo.success(result);
    }

    @Log("大屏用户解绑")
    @RequestMapping(value = "/unbind")
    @ApiOperation("大屏用户解绑")
    @AnonymousAccess
    public ResultInfo unbind(@Validated(value = {UpdateGroup.class}) @RequestBody UserTv resources) {
        log.info("UserOperationController ==> unbind ==>> param  ==> [{}]",resources);

        this.userOperationService.unbind(resources);
        return ResultInfo.success();
    }

    @Log("大屏更换主账号")
    @RequestMapping(value = "/changeMainAccount")
    @ApiOperation("大屏更换主账号")
    @AnonymousAccess
    public ResultInfo changeMainAccount(@Validated(value = {UpdateGroup.class}) @RequestBody UserTv resources) {
        log.info("UserOperationController ==> changeMainAccount ==>> param  ==> [{}]",resources);

        this.userOperationService.changeMainAccount(resources);
        return ResultInfo.success();
    }

    @Log("删除全部收藏")
    @PostMapping(value = "/deleteAllCollection")
    @ApiOperation("删除全部收藏")
    @AnonymousAccess
    public ResultInfo deleteAllCollection(@RequestBody String content) {
        log.info("UserOperationController ==> deleteAllCollection ==> param  ==> [{}]",content);

        boolean result = this.userOperationService.deleteAllCollection(content);
        return ResultInfo.success(result);
    }

    @Log("删除收藏")
    @PostMapping(value = "/deleteCollection")
    @ApiOperation("删除收藏")
    @AnonymousAccess
    public ResultInfo deleteCollection(@RequestBody String content) {
        log.info("UserOperationController ==> deleteCollection ==> param  ==> [{}]",content);

        boolean result = this.userOperationService.deleteCollection(content);
        return ResultInfo.success(result);
    }

    @Log("添加收藏")
    @PostMapping(value = "/addCollection")
    @ApiOperation("添加收藏")
    @AnonymousAccess
    public ResultInfo addCollection(@RequestBody String content) {
        log.info("UserOperationController ==> addCollection ==>> param  ==> [{}]",content);

        boolean result = this.userOperationService.addCollection(content);
        return ResultInfo.success(result);
    }

}