package com.cyksj.web.controller.user;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.annotation.NoSubmit;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.util.Jsons;
import com.cyksj.dto.Result;
import com.cyksj.enums.GatewayApiCode;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.mapper.*;
import com.cyksj.mapper.manage.coupon.CouponUserMapper;
import com.cyksj.mapper.manage.distribute.*;
import com.cyksj.mapper.mirrorshop.UserMirrorShopMapper;
import com.cyksj.model.dto.UserWhoami;
import com.cyksj.model.entity.*;
import com.cyksj.model.manage.views.GroupsRelationView;
import com.cyksj.model.request.*;
import com.cyksj.model.response.UserAuthLoginResp;
import com.cyksj.model.views.*;
import com.cyksj.service.corp.CorpInteractiveReaderFrontService;
import com.cyksj.service.corp.CropChatService;
import com.cyksj.service.exchange.ExchangeCodeService;
import com.cyksj.service.order.UserRealOrderBenefitsService;
import com.cyksj.service.shop.YhShopFrontService;
import com.cyksj.service.user.UserBindRelationService;
import com.cyksj.service.user.UserService;
import com.cyksj.service.user.WorkOrderFrontService;
import com.cyksj.web.util.StpUserUtil;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.SearchResult;
import com.ejlchina.searcher.param.Operator;
import com.ejlchina.searcher.util.MapBuilder;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author chan
 * @date 2021/10/11 下午11:05
 */
@RequestMapping("/applets/user")
@RestController
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;

    private final ExchangeCodeService exchangeCodeService;

    private final CouponUserMapper couponUserMapper;

    private final OrderDonMapper orderDonMapper;

    private final UserRealOrderBenefitsService userRealOrderBenefitsService;

    private final BeanSearcher beanSearcher;

    private final WorkOrderFrontService workOrderFrontService;

    private final HttpServletRequest request;

    private final CropChatService cropChatService;

    private final UserBindRelationService userBindRelationService;

    private final YhShopFrontService yhShopFrontService;

    private final CorpInteractiveReaderFrontService corpInteractiveReaderFrontService;

    private final UserPlatSkuDistributeRateMapper userPlatSkuDistributeRateMapper;

    private final UserPlatDistributeRateMapper userPlatDistributeRateMapper;

    private final DistributeGeneralSkuRateMapper distributeGeneralSkuRateMapper;

    private final GoodsDonSkuMapper skuMapper;

    private final UserDistributeMapper userDistributeMapper;

    private final UserDistributePosterRecordMapper userDistributePosterRecordMapper;

    private final DistributePosterGoodsMapper distributePosterGoodsMapper;

    private final UserIpRecordMapper userIpRecordMapper;

    private final BusinessDistributeDefaultRateConfigMapper businessDistributeDefaultRateConfigMapper;

    private final BusinessDistributeDefaultSkuRateConfigMapper businessDistributeDefaultSkuRateConfigMapper;

    private final UserMirrorShopMapper userMirrorShopMapper;

    private final UserGalaxyCoinRecordMapper userGalaxyCoinRecordMapper;

    @GetMapping(value = "/wx/whoami")
    public Result<UserWhoami> whoami(Long popularizeGoodsId) {
        long userId = StpUserUtil.getLoginIdAsLong();

        UserWhoami userWhoami = userService.whoami(userId, popularizeGoodsId);

        return GatewayResponse.SUCCESS.newBuilder().toResult(userWhoami);
    }

    /**
     * 兑换码兑换车票
     */
    @PostMapping("/get/ticket")
    public Result<String> getTicketByExchangeCode(@RequestBody ExchangeCodeTicket exchangeCodeTicket) throws Exception {
        Long userId = StpUserUtil.getLoginIdAsLong();
        return exchangeCodeService.getTicketByExchangeCode(exchangeCodeTicket, userId);
    }

    /**
     * 车票兑换码详情
     */
    @GetMapping("/get/ticket/code/detail")
    public Result<ExchangeCodeDetailView> getTicketCodeDetail(String code) throws Exception {
        code = URLUtil.decode(code);
        ExchangeCodeDetailView exchangeCodeDetailView = beanSearcher.searchFirst(ExchangeCodeDetailView.class, MapUtils.flatBuilder(request.getParameterMap()).field(ExchangeCodeDetailView::getCode, code).build());
        if (exchangeCodeDetailView == null) {
            throw BusinessRuntimeException.getInstance("错误兑换码");
        }
        List<Long> skuIds = Jsons.parseList(exchangeCodeDetailView.getSkuIds(), Long.class);
        exchangeCodeDetailView.setSkuDetails(skuMapper.selectExchangeTitleSkus(skuIds));
        return GatewayResponse.SUCCESS.newBuilder().toResult(exchangeCodeDetailView);
    }

    /**
     * 个人中心详情
     */
    @GetMapping("/personal")
    public Result<UserPersonalView> getPersonalView(String customId, Integer cmt) {
        long userId = StpUserUtil.getLoginIdAsLong();
        List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
        String userIds = userIdList.toString().replace("[", "(").replace("]", ")");
        MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
        if (cmt != null && cmt == 2 && StrUtil.isNotBlank(customId)) {
            UserMirrorShop userMirrorShop = userMirrorShopMapper.selectOne(Wrappers.lambdaQuery(UserMirrorShop.class)
                    .eq(UserMirrorShop::getCustomId, customId)
                    .last("limit 1"));
            if (userMirrorShop != null) {
                builder.field(RenewalView::getCmt, cmt).field(RenewalView::getYhsId, userMirrorShop.getId());
            }
        }
        if (cmt == null || cmt != 2) {
            builder.field(RenewalView::getCmt, 2).op(Operator.NotEqual);
        }
        List<RenewalView> renewalViews = beanSearcher.searchAll(RenewalView.class, builder
                .field(RenewalView::getUserId, 0).op(Operator.GreaterThan)
                .field(RenewalView::getUserId, userIdList).op(Operator.InList)
                .field(RenewalView::getStatus, List.of("validity", "overdue", "outside")).op(Operator.InList)
                .field(RenewalView::getIsVip, false)
                .orderBy(RenewalView::getExpiryTime).asc()
                .onlySelect(RenewalView::getExpiryTime)
                .build());
        DateTime now = DateTime.now();
        UserPersonalView personalView = new UserPersonalView();
        personalView.setTotalOfTickets(renewalViews.size());
        renewalViews = renewalViews.stream().filter(e -> {
            if (e.getExpiryTime() != null && e.getExpiryTime().before(now)) {
                return false;
            }
            return true;
        }).collect(Collectors.toList());
        //车票
        personalView.setNumOfTickets(renewalViews.size());
        //优惠券
        Integer couponSize = couponUserMapper.selectCount(Wrappers.lambdaQuery(CouponUser.class)
                .eq(CouponUser::getUserId, userId)
                .eq(CouponUser::getStatus, CouponUser.Status.unused)
                .le(CouponUser::getValidStartTime, now)
                .gt(CouponUser::getValidEndTime, now));
        personalView.setNumOfCoupons(couponSize);
        //积分
        User user = userService.getById(userId);
        personalView.setGalaxyCoin(user.getGalaxyCoin());
        //30天内即将过期银河币数量
        BigDecimal expiredGalaxyCoinAfterDays = userGalaxyCoinRecordMapper.selectExpiredGalaxyCoinAfterDays(userId, DateUtil.offsetDay(now, -30));
        personalView.setExpiredGalaxyCoin(expiredGalaxyCoinAfterDays);
        //推广积分
        personalView.setPopularizePoints(user.getPoints());
        personalView.setBalance(user.getBalance());
        OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
                .eq(OrderDon::getUserId, userId)
                .eq(OrderDon::getStatus, OrderDon.Status.noPayment).last("limit 1"));
        personalView.setIsNoPayment(orderDon != null ? true : false);
        //礼品卡可用数量
        Number numOfGiftCard = beanSearcher.searchCount(GiftCardUserRecordView.class, MapUtils.builder()
                .put("uid", String.format("((user_id in %s and is_send = 0) or (to_user_id in %s and is_used = 0))", userIds, userIds))
                .field(GiftCardUserRecordView::getIsPay, true)
                .build());
        personalView.setNumOfGiftCard(numOfGiftCard.intValue());
        return GatewayResponse.SUCCESS.newBuilder().toResult(personalView);
    }

    /**
     * 用户已有实物权益 可选车票
     */
    @GetMapping("/get/available/benefits/tickets")
    public Result<List<UserAvailableGoodsTicketView>> getAvailableBenefitsTickets(Long orderId, String customId, Integer cmt) {
        Long userId = StpUserUtil.getLoginIdAsLong();
        List<UserAvailableGoodsTicketView> tickets = userRealOrderBenefitsService.getAvailableBenefitsTickets(userId, orderId, customId, cmt);
        return GatewayResponse.SUCCESS.newBuilder().toResult(tickets);
    }

    /**
     * 用户领取实物权益
     */
    @PostMapping("/receive/benefits")
    public Result<List<GroupsRelationView>> receiveRealGoodsBenefits(@RequestBody List<ReceiveBenefitsReq> reqList) {
        List<GroupsRelationView> re = new ArrayList<>();
        Long userId = StpUserUtil.getLoginIdAsLong();
        reqList.forEach(req -> {
            Long benefitsId = req.getBenefitsId(), goodsId = req.getGoodsId(), skuId = req.getSkuId(), relationId = req.getRelationId();
            Assert.notNull(benefitsId, "可获取的权益不存在");
            Assert.notNull(goodsId, "请选择对应平台");
            Assert.notNull(skuId, "请选择对应权益规格");
            Assert.notNull(relationId, "请选择对应车票");
            GroupsRelationView groupsRelationView = userRealOrderBenefitsService.receiveRealGoodsBenefits(userId, benefitsId, goodsId, skuId, relationId);
            re.add(groupsRelationView);
        });
        return GatewayResponse.SUCCESS.newBuilder().toResult(re);
    }

    /**
     * 用户提交工单
     */
    @PostMapping("/workOrder/submit")
    @NoSubmit
    public Result<String> submitWorkOrder(@RequestBody @Validated WorkOrderReq workOrderReq) {
        long userId = StpUserUtil.getLoginIdAsLong();
        workOrderReq.setUserId(userId);
        workOrderFrontService.submitWorkOrder(workOrderReq);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 用户工单历史列表
     */
    @GetMapping("/workOrder/get")
    public Result<SearchResult<UserWorkOrderView>> getWorkOrder(String customId) {
        Long yhsId = yhShopFrontService.getYhsIdByCustomId(customId);
        long userId = StpUserUtil.getLoginIdAsLong();
        SearchResult<UserWorkOrderView> search = beanSearcher.search(UserWorkOrderView.class, MapUtils.flatBuilder(request.getParameterMap())
                .field(UserWorkOrderView::getUserId, userId)
                .field(UserWorkOrderView::getYhsId, yhsId)
                .orderBy(UserWorkOrderView::getCreatedTime).desc()
                .build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 用户工单详情
     */
    @GetMapping("/workOrder/get/detail/{id}")
    public Result<SearchResult<WorkOrderChatHistoryView>> getWorkOrderDetails(@PathVariable Long id) {
        long userId = StpUserUtil.getLoginIdAsLong();
        SearchResult<WorkOrderChatHistoryView> search = beanSearcher.search(WorkOrderChatHistoryView.class, MapUtils.builder()
                .field(WorkOrderChatHistoryView::getUserId, userId)
                .field(WorkOrderChatHistoryView::getWorkOrderId, id)
                .orderBy(WorkOrderChatHistoryView::getId).desc()
                .selectExclude(WorkOrderChatHistoryView::getReplyCustomerServiceId,
                        WorkOrderChatHistoryView::getCustomer)
                .build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 工单状态查询
     */
    @GetMapping("/workOrder/get/status/{id}")
    public Result<WorkOrder> getWorkOrderStatus(@PathVariable Long id) {
        long userId = StpUserUtil.getLoginIdAsLong();
        WorkOrder workOrder = beanSearcher.searchFirst(WorkOrder.class, MapUtils.builder()
                .field(WorkOrder::getUserId, userId)
                .field(WorkOrder::getId, id)
                .onlySelect(WorkOrder::getId, WorkOrder::getUserId, WorkOrder::getStatus)
                .build());
        if (workOrder == null) {
            throw BusinessRuntimeException.getInstance("该工单不存在");
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult(workOrder);
    }


    /**
     * 用户回复客服
     */
    @PostMapping("/workOrder/reply")
    public Result<String> userReplyWorkOrder(@RequestBody @Validated WorkOrderChatHistory history) {
        long userId = StpUserUtil.getLoginIdAsLong();
        history.setUserId(userId);
        workOrderFrontService.replyCustomer(history);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 修改用户信息
     */
    @PutMapping("/update/userInfo")
    public Result<String> updateHeadImg(@RequestBody UserReq request) {
        long userId = StpUserUtil.getLoginIdAsLong();
        User user = userService.getById(userId);
        if (user == null) throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
        Boolean isFlag = false;
        if (StrUtil.isNotBlank(request.getNickname())) {
            if (request.getNickname().length() > 32) {
                throw BusinessRuntimeException.getInstance("名称过长");
            }
            user.setNickname(request.getNickname());
            isFlag = true;
        }
        if (request.getSex() != null) {
            user.setSex(request.getSex());
            isFlag = true;
        }
        if (StrUtil.isNotBlank(request.getHeadimgurl())) {
            user.setHeadimgurl(request.getHeadimgurl());
            isFlag = true;
        }
        if (isFlag) {
            userService.updateById(user);
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 更新用户最后一次登录时间
     */
    @PutMapping("/update/lastTime")
    public Result<String> updateLastTime() {
        long userId = StpUserUtil.getLoginIdAsLong();
        User user = userService.getById(userId);
        if (user == null) {
            return GatewayResponse.SUCCESS.newBuilder().toResult();
        }
        user.setLastTime(DateTime.now());
        userService.updateById(user);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 查看用户所有余额
     */
    @GetMapping("/get/balance")
    public Result<User> getUserBalance() {
        long userId = StpUserUtil.getLoginIdAsLong();
        User user = userService.getOne(Wrappers.lambdaQuery(User.class)
                .eq(User::getId, userId)
                .select(User::getNickname, User::getBalance, User::getGalaxyCoin)
                .last("limit 1"));
        return GatewayResponse.SUCCESS.newBuilder().toResult(user);
    }

    /**
     * 获取群聊二维码
     */
    @GetMapping("/get/corp/ChatCode/{goodsId}")
    public Result<String> getCorpChatCode(@PathVariable Long goodsId) throws Exception {
        long userId = StpUserUtil.getLoginIdAsLong();
        //获取对应产品的企业微信客户群
        String qrCode = cropChatService.getCropWxChatGroupByGoodsId(goodsId);
        return GatewayResponse.SUCCESS.newBuilder().toResult(qrCode);
    }

    /**
     * 获取奈飞客服活码弹窗
     */
    @GetMapping("/get/corp/serviceCode/{goodsId}")
    public Result<String> getCorpServiceCode(@PathVariable Long goodsId) {
        long userId = StpUserUtil.getLoginIdAsLong();
        String qrCode = cropChatService.getCorpServiceCode(goodsId);
        return GatewayResponse.SUCCESS.newBuilder().toResult(qrCode);
    }

    /**
     * 用户账号关联列表
     */
    @GetMapping("/get/userAccounts")
    public Result<List<UserBindAccountView>> getUserBindAccountViews() {
        long userId = StpUserUtil.getLoginIdAsLong();
        List<Long> relationUserIdList = userBindRelationService.getRelationUserIdList(userId, null);
        List<UserBindAccountView> accountViews = beanSearcher.searchAll(UserBindAccountView.class, MapUtils.builder().field(UserBindAccountView::getUserId, relationUserIdList)
                .op(Operator.InList)
                .build());
        if (relationUserIdList.size() > 1) {
            for (UserBindAccountView accountView : accountViews) {
                if (accountView.getUserId().equals(userId)) {
                    accountViews.remove(accountView);
                    accountViews.add(0, accountView);
                    break;
                }
            }
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult(accountViews);
    }

    /**
     * 切换账号
     */
    @PutMapping("/switch/account")
    public Result<UserAuthLoginResp> switchOtherAccount(@RequestBody UserBindAccountView request) {
        long userId = StpUserUtil.getLoginIdAsLong();
        Long switchUserId = request.getUserId();
        List<Long> relationUserIdList = userBindRelationService.getRelationUserIdList(userId, null);
        if (!relationUserIdList.contains(switchUserId)) {
            throw BusinessRuntimeException.getInstance("切换账号异常,请刷新页面重试");
        }
        User switch_user = userService.getById(switchUserId);
        Assert.notNull(switch_user, "切换的账号不存在");
        StpUserUtil.login(switch_user.getId());
        UserAuthLoginResp loginPhoneRep = new UserAuthLoginResp(StpUserUtil.getTokenValue(), switch_user.getShowId(), switch_user.getNickname(), switch_user.getHeadimgurl());
        return GatewayResponse.SUCCESS.newBuilder().toResult(loginPhoneRep);
    }

    /**
     * 个人礼品卡列表
     * @return
     */
    @GetMapping("/get/giftCard")
    public Result<SearchResult<GiftCardUserPayFrontView>> getGiftCard() {
        long userId = StpUserUtil.getLoginIdAsLong();
        List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
        String userIds = userIdList.toString().replace("[", "(").replace("]", ")");
        String condition = String.format("and (user_id in %s or to_user_id in %s)", userIds, userIds);
        SearchResult<GiftCardUserPayFrontView> view = beanSearcher.search(GiftCardUserPayFrontView.class, MapUtils.flatBuilder(request.getParameterMap())
                .put("condition", condition)
                .put("uid", userIds)
                .orderBy(GiftCardUserRecordView::getIsUsed).asc()
                .orderBy(GiftCardUserPayFrontView::getId).desc().build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(view);
    }

    /**
     * 可用现金礼品卡列表
     */
    @GetMapping("/get/available/giftCard")
    public Result<List<GiftCardUserPayFrontView>> getAvailGiftCard() {
        long userId = StpUserUtil.getLoginIdAsLong();
        List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
        String userIds = userIdList.toString().replace("[", "(").replace("]", ")");
        String condition = String.format("and to_user_id in %s", userIds);
        List<GiftCardUserPayFrontView> view = beanSearcher.searchAll(GiftCardUserPayFrontView.class, MapUtils.builder()
                .put("condition", condition)
                .put("uid", userIds)
                //现金卡
                .field(GiftCardUserPayFrontView::getGcType, 1)
                .orderBy(GiftCardUserRecordView::getIsUsed).asc()
                .orderBy(GiftCardUserPayFrontView::getId).desc().build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(view);
    }

    /**
     * 礼品卡分享详情
     */
    @GetMapping("/get/giftCard/detail/{code}")
    public Result<GiftCardDetailFrontView> getGiftCardDetailByCode(@PathVariable String code) {
        GiftCardDetailFrontView detail = beanSearcher.searchFirst(GiftCardDetailFrontView.class, MapUtils.builder().field(GiftCardDetailFrontView::getCode, code).build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(detail);
    }

    /**
     * 领取他人礼品卡
     */
    @PostMapping("/receive/giftCard")
    public Result<String> receiveGiftCardByRc(@RequestBody GiftCardReceiveReq req) {
        long userId = StpUserUtil.getLoginIdAsLong();
        Long relationId = req.getRelationId();
        userService.receiveGiftCardByRc(userId, req.getCode(), relationId);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 点击雷达链接
     */
    @PostMapping("/click/reader/{radarId}")
    public Result<String> clickInteractiveReader(@PathVariable Long radarId) throws Exception {
        long userId = StpUserUtil.getLoginIdAsLong();
        corpInteractiveReaderFrontService.clickReader(userId, radarId);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 推广平台海报列表
     */
    @GetMapping("/get/ds/poster/goods")
    public Result<List<DistributePosterGoodsFrontView>> getPosterGoods() {
        long userId = StpUserUtil.getLoginIdAsLong();
        UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class)
                .eq(UserDistribute::getUserId, userId)
                .eq(UserDistribute::getDeleted, 1)
                .last("limit 1"));
        List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
        MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
        List<DistributePosterGoodsFrontView> searchAll = beanSearcher.searchAll(DistributePosterGoodsFrontView.class, builder.build());
        searchAll.forEach(e -> {
            if (userDistribute != null) {
                UserPlatDistributeRate userPlatDistributeRate = userPlatDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatDistributeRate.class)
                        .eq(UserPlatDistributeRate::getDistributeId, userDistribute.getId())
                        .eq(UserPlatDistributeRate::getGoodsId, e.getGoodsId())
                        .last("limit 1"));
                if (userPlatDistributeRate != null) {
                    e.setRate(userPlatDistributeRate.getRate());
                } else {
                    BusinessDistributeDefaultRateConfig businessDistributeDefaultRateConfig = businessDistributeDefaultRateConfigMapper.selectOne(Wrappers.lambdaQuery(BusinessDistributeDefaultRateConfig.class)
                            .eq(BusinessDistributeDefaultRateConfig::getGoodsId, e.getGoodsId())
                            .last("limit 1"));
                    if (businessDistributeDefaultRateConfig != null) {
                        e.setRate(businessDistributeDefaultRateConfig.getRate());
                    }
                }
            }
            if (e.getIsSkuRate()) {
                GoodsDonSku sku = skuMapper.selectOne(Wrappers.lambdaQuery(GoodsDonSku.class)
                        .eq(GoodsDonSku::getGoodsId, e.getGoodsId())
                        .eq(GoodsDonSku::getStatus, 1)
                        .orderByAsc(GoodsDonSku::getPrice)
                        .last("limit 1"));
                //先获取价格最低的规格对应的 比例
                //渠道
                if (userDistribute != null) {
                    UserPlatSkuDistributeRate minPriceSkuRate = userPlatSkuDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatSkuDistributeRate.class)
                            .eq(UserPlatSkuDistributeRate::getDistributeId, userDistribute.getId())
                            .eq(UserPlatSkuDistributeRate::getGoodsId, e.getGoodsId())
                            .eq(UserPlatSkuDistributeRate::getSkuId, sku.getId())
                            .last("limit 1"));
                    if (minPriceSkuRate != null && minPriceSkuRate.getRate() != 0) {
                        e.setRate(minPriceSkuRate.getRate());
                    } else {
                        UserPlatSkuDistributeRate userPlatSkuDistributeRate = userPlatSkuDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatSkuDistributeRate.class)
                                .eq(UserPlatSkuDistributeRate::getDistributeId, userDistribute.getId())
                                .eq(UserPlatSkuDistributeRate::getGoodsId, e.getGoodsId())
                                .ne(UserPlatSkuDistributeRate::getRate, 0)
                                //上架
                                .apply("exists (select 1 from goods_don_sku sku where sku.id = sku_id and sku.status is true limit 1)")
                                .orderByAsc(UserPlatSkuDistributeRate::getRate)
                                .last("limit 1"));
                        if (userPlatSkuDistributeRate != null) {
                            e.setRate(userPlatSkuDistributeRate.getRate());
                            sku = skuMapper.selectById(userPlatSkuDistributeRate.getSkuId());
                            e.setPrice(sku.getPrice());
                        } else {
                            BusinessDistributeDefaultSkuRateConfig businessDistributeDefaultSkuRateConfig = businessDistributeDefaultSkuRateConfigMapper.selectOne(Wrappers.lambdaQuery(BusinessDistributeDefaultSkuRateConfig.class)
                                    .eq(BusinessDistributeDefaultSkuRateConfig::getGoodsId, e.getGoodsId())
                                    .gt(BusinessDistributeDefaultSkuRateConfig::getRate, 0)
                                    .apply("exists (select 1 from goods_don_sku sku where sku.id = sku_id and sku.status is true limit 1)")
                                    .orderByAsc(BusinessDistributeDefaultSkuRateConfig::getRate)
                                    .last("limit 1"));
                            if (businessDistributeDefaultSkuRateConfig != null) {
                                e.setRate(businessDistributeDefaultSkuRateConfig.getRate());
                            }
                        }
                    }
                } else {
                    //普通
                    DistributeGeneralSkuRate minPriceRate = distributeGeneralSkuRateMapper.selectOne(Wrappers.lambdaQuery(DistributeGeneralSkuRate.class)
                            .eq(DistributeGeneralSkuRate::getGoodsId, e.getGoodsId())
                            .eq(DistributeGeneralSkuRate::getSkuId, sku.getId())
                            .last("limit 1"));
                    if (minPriceRate != null && minPriceRate.getRate() > 0) {
                        e.setRate(minPriceRate.getRate());
                    } else {
                        DistributeGeneralSkuRate distributeGeneralSkuRate = distributeGeneralSkuRateMapper.selectOne(Wrappers.lambdaQuery(DistributeGeneralSkuRate.class)
                                .eq(DistributeGeneralSkuRate::getGoodsId, e.getGoodsId())
                                .apply("exists (select 1 from goods_don_sku sku where sku.id = sku_id and sku.status is true limit 1)")
                                .ne(DistributeGeneralSkuRate::getRate, 0)
                                .orderByAsc(DistributeGeneralSkuRate::getRate)
                                .last("limit 1"));
                        if (distributeGeneralSkuRate != null) {
                            e.setRate(distributeGeneralSkuRate.getRate());
                            sku = skuMapper.selectById(distributeGeneralSkuRate.getSkuId());
                            e.setPrice(sku.getPrice());
                        }
                    }
                }
            }
            UserDistributePosterRecord distributePosterRecord = userDistributePosterRecordMapper.selectOne(Wrappers.lambdaQuery(UserDistributePosterRecord.class)
                    .eq(UserDistributePosterRecord::getPosterId, e.getId())
                    .in(UserDistributePosterRecord::getUserId, userIdList)
                    .last("limit 1"));
            if (distributePosterRecord != null) {
                e.setRid(distributePosterRecord.getId());
            }        });
        return GatewayResponse.SUCCESS.newBuilder().toResult(searchAll);
    }

    /**
     * 海报详情
     */
    @GetMapping("/get/poster/{goodsId}")
    public Result<DistributePosterGoodsFrontView> getPosterDetail(@PathVariable Long goodsId) {
        DistributePosterGoodsFrontView distributePosterGoodsView = beanSearcher.searchFirst(DistributePosterGoodsFrontView.class, MapUtils.flatBuilder(request.getParameterMap())
                .field(DistributePosterGoodsFrontView::getGoodsId, goodsId)
                .build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(distributePosterGoodsView);
    }

    /**
     * 用户下载海报记录
     */
    @PostMapping("/poster/record/{posterId}")
    public Result<Long> posterRecord(@PathVariable Long posterId) {
        long userId = StpUserUtil.getLoginIdAsLong();
        DistributePosterGoods distributePosterGoods = distributePosterGoodsMapper.selectById(posterId);
        if (distributePosterGoods == null) {
            return GatewayResponse.SUCCESS.newBuilder().toResult();
        }
        UserDistributePosterRecord distributePosterRecord = new UserDistributePosterRecord();
        distributePosterRecord.setPosterId(posterId);
        distributePosterRecord.setUserId(userId);
        try {
            userDistributePosterRecordMapper.insert(distributePosterRecord);
        } catch (DuplicateKeyException e) {
            distributePosterRecord = userDistributePosterRecordMapper.selectOne(Wrappers.lambdaQuery(UserDistributePosterRecord.class)
                    .eq(UserDistributePosterRecord::getUserId, userId)
                    .eq(UserDistributePosterRecord::getPosterId, posterId)
                    .last("limit 1"));
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult(distributePosterRecord.getId());
    }

    /**
     * 记录用户ip
     */
    @PostMapping("/user/ip/record")
    public Result<String> recordUserIpAddress() {
        long userId = StpUserUtil.getLoginIdAsLong();
        String ip = ServletUtil.getClientIP(request);
        Integer selectCount = userIpRecordMapper.selectCount(Wrappers.lambdaQuery(UserIpRecord.class)
                .eq(UserIpRecord::getUserId, userId)
                .eq(UserIpRecord::getIp, ip));
        if (selectCount == 0) {
            try {
                UserIpRecord userIpRecord = new UserIpRecord();
                userIpRecord.setUserId(userId);
                userIpRecord.setIp(ip);
                userIpRecordMapper.insert(userIpRecord);
            } catch (DuplicateKeyException e) {
            }
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 用户认证信息总览
     */
    @GetMapping("/get/cert/overview")
    public Result<UserCertInfoView> getCertOverView() {
        long userId = StpUserUtil.getLoginIdAsLong();
        UserCertInfoView userCertInfoView = userService.getCertOverView(userId);
        return GatewayResponse.SUCCESS.newBuilder().toResult(userCertInfoView);
    }

    /**
     * 用户同步功能信息
     */
    @GetMapping("/get/user/syncInfo")
    public Result<UserSyncInfoView> getUserSyncInfo() {
        long userId = StpUserUtil.getLoginIdAsLong();

        UserSyncInfoView syncInfoView = userService.getUserSyncInfo(userId);

        return GatewayResponse.SUCCESS.newBuilder().toResult(syncInfoView);
    }

}
