yujian
2019-10-09 481da0ca0ac931f6ff35dbb8d70d4450d4252c17
新版登录-绑定手机号
7个文件已修改
5个文件已添加
663 ■■■■■ 已修改文件
fanli/src/main/java/com/yeshi/fanli/controller/client/v1/UserInfoController.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/client/v2/UserAccountControllerV2.java 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/dao/user/BindRemindDao.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/BindRemind.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/UserInfo.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/BindRemindServiceImpl.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/impl/user/UserAccountServiceImpl.java 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/BindRemindService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/service/inter/user/UserAccountService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/factory/goods/GoodsDetailVOFactory.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/util/taobao/TaoKeApiUtil.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/vo/goods/GoodsDetailVO.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fanli/src/main/java/com/yeshi/fanli/controller/client/v1/UserInfoController.java
@@ -44,6 +44,7 @@
import com.yeshi.fanli.entity.AppVersionInfo;
import com.yeshi.fanli.entity.accept.AcceptData;
import com.yeshi.fanli.entity.bus.user.AccountMessage;
import com.yeshi.fanli.entity.bus.user.BindRemind;
import com.yeshi.fanli.entity.bus.user.BindingAccount;
import com.yeshi.fanli.entity.bus.user.Extract;
import com.yeshi.fanli.entity.bus.user.ExtractRecord;
@@ -54,8 +55,8 @@
import com.yeshi.fanli.entity.bus.user.UserActiveLog;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.entity.bus.user.UserInfoExtra;
import com.yeshi.fanli.entity.bus.user.WeiXinUser;
import com.yeshi.fanli.entity.bus.user.UserInfoModifyRecord.ModifyTypeEnum;
import com.yeshi.fanli.entity.bus.user.WeiXinUser;
import com.yeshi.fanli.entity.common.AdminUser;
import com.yeshi.fanli.entity.common.Config;
import com.yeshi.fanli.entity.goods.CollectionGoodsV2;
@@ -90,6 +91,7 @@
import com.yeshi.fanli.service.inter.order.config.HongBaoManageService;
import com.yeshi.fanli.service.inter.tlj.UserTaoLiJinDetailService;
import com.yeshi.fanli.service.inter.user.AccountMessageService;
import com.yeshi.fanli.service.inter.user.BindRemindService;
import com.yeshi.fanli.service.inter.user.MaskKeyService;
import com.yeshi.fanli.service.inter.user.ShamUserService;
import com.yeshi.fanli.service.inter.user.SpreadUserImgService;
@@ -221,6 +223,9 @@
    @Resource
    private UserInfoModifyRecordService userInfoModifyRecordService;
    @Resource
    private BindRemindService bindRemindService;
    private static final String PASSWORD_MAX_ERROR = "password_max_error";
    private static final String EXTRACT_MIN_MONEY = "extract_min_money";
@@ -2151,12 +2156,21 @@
            // 1.6.5 之后返回 微信号提示
            if (VersionUtil.greaterThan_1_6_5(acceptData.getPlatform(), acceptData.getVersion()))
                userInfo.setWeiXinTip("添加微信号后,你的邀请人和一级队员可以通过微信与你建立联系。");
            data.put("user", JsonUtil.getConvertBigDecimalToStringBuilder(gsonBuilder).create().toJson(userInfo));
            data.put("invitCode", invitCode); // 邀请码
            data.put("welfareCenterNews", welfareCenterNews);// 福利中心消息
            // 2.0.1之后绑定手机号
            if (VersionUtil.greaterThan_2_0_1(acceptData.getPlatform(), acceptData.getVersion())) {
                boolean bindPhone = false;
                if (StringUtil.isNullOrEmpty(userInfo.getPhone()))
                    bindPhone = bindRemindService.bindRemind(uid, BindRemind.TYPE_PHONE);
                data.put("bindPhone", bindPhone);
            }
            out.print(JsonUtil.loadTrueResult(data));
            final UserInfo uuser = userInfo;
            ThreadUtil.run(new Runnable() {
                public void run() {
fanli/src/main/java/com/yeshi/fanli/controller/client/v2/UserAccountControllerV2.java
New file
@@ -0,0 +1,288 @@
package com.yeshi.fanli.controller.client.v2;
import java.io.PrintWriter;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.yeshi.utils.JsonUtil;
import com.yeshi.fanli.entity.accept.AcceptData;
import com.yeshi.fanli.entity.bus.user.SMSHistory;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.entity.push.DeviceActive;
import com.yeshi.fanli.entity.system.BusinessSystem;
import com.yeshi.fanli.exception.user.UserAccountException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.config.BusinessSystemService;
import com.yeshi.fanli.service.inter.homemodule.HomeNavbarUserService;
import com.yeshi.fanli.service.inter.money.UserMoneyService;
import com.yeshi.fanli.service.inter.order.LostOrderService;
import com.yeshi.fanli.service.inter.order.config.HongBaoManageService;
import com.yeshi.fanli.service.inter.push.DeviceActiveService;
import com.yeshi.fanli.service.inter.push.DeviceTokenHWService;
import com.yeshi.fanli.service.inter.push.DeviceTokenOPPOService;
import com.yeshi.fanli.service.inter.taobao.TaoBaoUnionConfigService;
import com.yeshi.fanli.service.inter.tlj.UserTaoLiJinOriginService;
import com.yeshi.fanli.service.inter.user.ForbiddenUserIdentifyCodeService;
import com.yeshi.fanli.service.inter.user.ShamUserService;
import com.yeshi.fanli.service.inter.user.SpreadUserImgService;
import com.yeshi.fanli.service.inter.user.TBPidService;
import com.yeshi.fanli.service.inter.user.UserAccountBindingHistoryService;
import com.yeshi.fanli.service.inter.user.UserAccountService;
import com.yeshi.fanli.service.inter.user.UserInfoDeleteRecordService;
import com.yeshi.fanli.service.inter.user.UserInfoModifyRecordService;
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.service.inter.user.UserShareGoodsRecordService;
import com.yeshi.fanli.service.inter.user.UserSystemCouponService;
import com.yeshi.fanli.service.inter.user.invite.ThreeSaleSerivce;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.RedisManager;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.ThreadUtil;
import com.yeshi.fanli.util.VersionUtil;
import com.yeshi.fanli.util.account.UserUtil;
import net.sf.json.JSONObject;
/**
 * 账户系统
 *
 * @author Administrator
 *
 */
@Controller
@RequestMapping("api/v2/user")
public class UserAccountControllerV2 {
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private BusinessSystemService businessSystemService;
    @Resource
    private ShamUserService shamUserService;
    @Resource
    private ThreeSaleSerivce threeSaleSerivce;
    @Resource
    private LostOrderService lostOrderService;
    @Resource
    private HongBaoManageService hongBaoManageService;
    @Resource
    private UserAccountService userAccountService;
    @Resource
    private RedisManager redisManager;
    @Resource
    private TBPidService tbPidService;
    @Resource
    private DeviceTokenHWService deviceTokenHWService;
    @Resource
    private DeviceTokenOPPOService deviceTokenOPPOService;
    @Resource
    private TaoBaoUnionConfigService taoBaoUnionConfigService;
    @Resource
    private SpreadUserImgService spreadUserImgService;
    @Resource
    private UserShareGoodsRecordService userShareGoodsRecordService;
    @Resource
    private ForbiddenUserIdentifyCodeService forbiddenUserIdentifyCodeService;
    @Resource
    private UserSystemCouponService userSystemCouponService;
    @Resource
    private UserMoneyService userMoneyService;
    @Resource
    private UserAccountBindingHistoryService userAccountBindingHistoryService;
    @Resource
    private HomeNavbarUserService homeNavbarUserService;
    @Resource
    private UserInfoDeleteRecordService userInfoDeleteRecordService;
    @Resource
    private UserTaoLiJinOriginService userTaoLiJinOriginService;
    @Resource
    private UserInfoModifyRecordService userInfoModifyRecordService;
    @Resource
    private DeviceActiveService deviceActiveService;
    /**
     * 新版登录 V1.5.3
     *
     * @param acceptData
     * @param vcode
     * @param phone
     * @param code
     * @param loginType
     *            登录方式: 1-手机登录 2-微信登录
     * @param request
     * @param out
     */
    @RequestMapping(value = "login", method = RequestMethod.POST)
    public void login(AcceptData acceptData, int loginType, String vcode, String phone, String code,
            HttpServletRequest request, PrintWriter out) {
        try {
            BusinessSystem system = businessSystemService.getBusinessSystemCache(acceptData.getPlatform(),
                    acceptData.getPackages());
            if (system == null) {
                out.print(JsonUtil.loadFalseResult("系统不存在"));
                return;
            }
            UserInfo userInfo = null;
            // 手机登录
            if (loginType == 1) {
                userInfo = userAccountService.loginPhone(request, loginType, vcode, phone, system.getAppid());
            }
            // 微信登录
            if (loginType == 2) {
                userInfo = userAccountService.loginWeiXinNew(request, acceptData, loginType, code, system.getAppid());
            }
            if (userInfo == null) {
                out.print(JsonUtil.loadFalseResult("登录失败"));
            } else {
                JSONObject data = new JSONObject();
                data.put("userInfo", UserUtil.filterForClientUser(userInfo));
                out.print(JsonUtil.loadTrueResult(data));
                final UserInfo uuser = userInfo;
                ThreadUtil.run(new Runnable() {
                    public void run() {
                        String device = acceptData.getDevice();
                        try {
                            // 同步自定义导航
                            homeNavbarUserService.synchroDeviceToUser(uuser.getId(), device);
                        } catch (Exception e) {
                            LogHelper.errorDetailInfo(e);
                        }
                        if (VersionUtil.greaterThan_1_5_60(acceptData.getPlatform(), acceptData.getVersion())) {
                            /* 新人红包 */
                            try {
                                userTaoLiJinOriginService.synchDeviceHongbao(uuser.getId(), device);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        // 绑定oppo推送
                        DeviceActive active = deviceActiveService.getFirstActiveInfo(acceptData.getDevice());
                        if (active != null) {
                            deviceTokenOPPOService.bindUid(uuser.getId(), active.getId());
                        }
                    }
                });
            }
        } catch (UserAccountException e) {
            int errorCode = e.getCode();
            if (errorCode == 101) { // 需要绑定手机号
                JSONObject data = new JSONObject();
                data.put("key", e.getMsg());
                JSONObject object = new JSONObject();
                object.put("code", errorCode);
                object.put("data", data);
                out.print(object.toString());
            } else {
                out.print(JsonUtil.loadFalseResult(e.getCode(), e.getMsg()));
                try {
                    LogHelper.cookieLog("登录出错:" + e.getCode() + "-" + e.getMessage());
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        } catch (Exception e) {
            out.print(JsonUtil.loadFalseResult("登录失败"));
            try {
                LogHelper.errorDetailInfo(e);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
    }
    /**
     * 绑定电话号码 V2.0.1 微信登录
     *
     * @param acceptData
     * @param vcode
     * @param phone
     * @param out
     */
    @RequestMapping(value = "bindPhoneLogin")
    public void bindPhoneLogin(AcceptData acceptData,String vcode, String phone, String key, HttpServletRequest request, PrintWriter out) {
        BusinessSystem system = businessSystemService.getBusinessSystemCache(acceptData.getPlatform(),
                acceptData.getPackages());
        if (system == null) {
            out.print(JsonUtil.loadFalseResult("系统不存在"));
            return;
        }
        if (StringUtil.isNullOrEmpty(vcode)) {
            out.print(JsonUtil.loadFalseResult("验证码不能为空"));
            return;
        }
        if (StringUtil.isNullOrEmpty(phone)) {
            out.print(JsonUtil.loadFalseResult("电话号码不能为空"));
            return;
        }
        if (StringUtil.isNullOrEmpty(key)) {
            out.print(JsonUtil.loadFalseResult("key值不能为空"));
            return;
        }
        phone = phone.replaceAll(" ", "");
        String oldVCode = redisManager.getSMSVCode(phone, SMSHistory.TYPE_BIND);
        if (Constant.IS_OUTNET) {
            if (!vcode.equalsIgnoreCase(oldVCode)) {
                out.print(JsonUtil.loadFalseResult(9001, "验证码错误,重新输入"));
                return;
            }
            redisManager.clearSMSFrequencyLimit(phone, SMSHistory.TYPE_BIND);
        }
        try {
            UserInfo userInfo = userAccountService.bindPhoneToLogin(phone, key, system.getAppid(), request);
            JSONObject data = new JSONObject();
            data.put("userInfo", UserUtil.filterForClientUser(userInfo));
            out.print(JsonUtil.loadTrueResult(data));
        } catch (UserAccountException e) {
            out.print(JsonUtil.loadFalseResult(e.getCode(), e.getMsg()));
        } catch (Exception e) {
            out.print(JsonUtil.loadFalseResult(1, "绑定失败"));
        }
    }
}
fanli/src/main/java/com/yeshi/fanli/dao/user/BindRemindDao.java
New file
@@ -0,0 +1,24 @@
package com.yeshi.fanli.dao.user;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import com.yeshi.fanli.dao.MongodbBaseDao;
import com.yeshi.fanli.entity.bus.user.BindRemind;
@Repository
public class BindRemindDao extends MongodbBaseDao<BindRemind> {
    public BindRemind getByUidAndType(Long uid, Integer type) {
        Query query = new Query();
        query.addCriteria(
                new Criteria().andOperator(
                    Criteria.where("uid").is(uid),
                    Criteria.where("type").is(type)
                    )
            );
        return mongoTemplate.findOne(query, BindRemind.class);
    }
}
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/BindRemind.java
New file
@@ -0,0 +1,68 @@
package com.yeshi.fanli.entity.bus.user;
import java.io.Serializable;
import java.util.Date;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
/**
 * 绑定提示时间
 * @author Administrator
 *
 */
@Document(collection = "bind_remind")
public class BindRemind implements Serializable{
    private static final long serialVersionUID = 1L;
    // 手机号
    public static int TYPE_PHONE = 1;
    // 微信
    public static int TYPE_WEIXXIN = 2;
    @Field("id")
    private String id;
    @Field("uid")
    private Long uid;
    @Field("type")
    private Integer type;
    @Field("createTime")
    private Date remindTime;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public Long getUid() {
        return uid;
    }
    public void setUid(Long uid) {
        this.uid = uid;
    }
    public Integer getType() {
        return type;
    }
    public void setType(Integer type) {
        this.type = type;
    }
    public Date getRemindTime() {
        return remindTime;
    }
    public void setRemindTime(Date remindTime) {
        this.remindTime = remindTime;
    }
}
fanli/src/main/java/com/yeshi/fanli/entity/bus/user/UserInfo.java
@@ -3,8 +3,6 @@
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Transient;
import org.yeshi.utils.mybatis.Table;
@@ -149,7 +147,7 @@
    private String rankNamePicture;// 等级名称图片
    @Transient
    private String taoBaoUid;// 淘宝的用户ID
    public String getTaoBaoUid() {
        return taoBaoUid;
    }
fanli/src/main/java/com/yeshi/fanli/service/impl/user/BindRemindServiceImpl.java
New file
@@ -0,0 +1,41 @@
package com.yeshi.fanli.service.impl.user;
import java.util.Date;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.yeshi.utils.DateUtil;
import com.yeshi.fanli.dao.user.BindRemindDao;
import com.yeshi.fanli.entity.bus.user.BindRemind;
import com.yeshi.fanli.service.inter.user.BindRemindService;
@Service
public class BindRemindServiceImpl implements BindRemindService {
    @Resource
    private BindRemindDao bindRemindDao;
    @Override
    public boolean bindRemind(Long uid, int type){
        BindRemind bindRemind = bindRemindDao.getByUidAndType(uid, type);
        if (bindRemind == null) {
            bindRemind = new BindRemind();
            bindRemind.setType(type);
            bindRemind.setUid(uid);
            bindRemind.setRemindTime(new Date());
            bindRemindDao.save(bindRemind);
            return true;
        }
        Date date = new Date();
        Date remindTime = bindRemind.getRemindTime();
        if (DateUtil.isSameMonth(remindTime, date)) {
            return false;
        }
        bindRemind.setRemindTime(date);
        bindRemindDao.save(bindRemind);
        return true;
    }
}
fanli/src/main/java/com/yeshi/fanli/service/impl/user/UserAccountServiceImpl.java
@@ -57,6 +57,7 @@
import com.yeshi.fanli.util.FileUtil;
import com.yeshi.fanli.util.RedisManager;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.ThreadUtil;
import com.yeshi.fanli.util.TimeUtil;
import com.yeshi.fanli.util.factory.msg.MsgAccountDetailFactory;
import com.yeshi.fanli.util.wx.WXLoginUtil;
@@ -117,7 +118,8 @@
    @Lazy
    @Resource
    private UserInfoModifyRecordService userInfoModifyRecordService;
    @Transactional
    @Override
    public LoginResult login(HttpServletRequest request, AcceptData acceptData, Boolean first, String appId,
@@ -1155,6 +1157,76 @@
        throw new UserAccountException(10, "请稍后再试");
    }
    @Transactional
    @Override
    public UserInfo loginWeiXinNew(HttpServletRequest request, AcceptData acceptData, int loginType, String wxCode, String appId) throws UserAccountException {
        // 日志信息
        JSONObject logInfo = new JSONObject();
        logInfo.put("appId", appId);
        logInfo.put("wxCode", wxCode);
        logInfo.put("loginType", loginType);
        LogHelper.lgoinInfo(logInfo.toString());
        // 通过Code换取信息
        WXAccountInfoDTO wxAccount = Constant.getWXAccount(acceptData.getPlatform(), acceptData.getVersion());
        WeiXinUser weiXinUser = WXLoginUtil.getWeiXinUserWithSavePortrait(wxCode, wxAccount.getAppId(),
                wxAccount.getAppSecret());
        if (weiXinUser == null) {
            throw new UserAccountException(1, "微信帐号授权失败");
        }
        LogHelper.test("微信授权用户信息:" + new Gson().toJson(weiXinUser));
        // 判断微信unionid是否被封禁
        ForbiddenUserIdentifyCode identifyCode = forbiddenUserIdentifyCodeService
                .listByTypeAndIdentifyCode(ForbiddenUserIdentifyCodeTypeEnum.wxUnionId, weiXinUser.getUnionid());
        if (identifyCode != null && identifyCode.getEffective() != null && identifyCode.getEffective()) {
            throw new UserAccountException(Constant.CODE_FORBIDDEN_USER, Constant.FORBIDDEN_USER_REASON_DESC);
        }
        // 采用redis事务防止一个微信号多次注册问题
        String watchKey = StringUtil.Md5("REGISTER:" + weiXinUser.getUnionid());
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.watch(watchKey);
            if (jedis.get(watchKey) != null && Integer.parseInt(jedis.get(watchKey)) > 1)
                throw new UserAccountException(10, "请稍后再试");
            Transaction tran = jedis.multi();
            tran.incr(watchKey);
            List<Object> exec = tran.exec();
            if (exec == null || exec.size() == 0)
                throw new UserAccountException(10, "请稍后再试");
            UserInfo userInfo = userInfoMapper.getEffectiveUserInfoByWXUnionId(weiXinUser.getUnionid());
            if (userInfo == null) {
                redisManager.cacheCommonString(watchKey, JsonUtil.getSimpleGson().toJson(weiXinUser), 60 * 20);
                throw new UserAccountException(101, watchKey);
            }
            LogHelper.test("微信unionID存在:" + weiXinUser.getUnionid());
            // 更新账户登录信息
            updateLonginInfo(userInfo, loginType, request);
            Long uid = userInfo.getId();
            ThreadUtil.run(new Runnable() {
                public void run() {
                    // 删除邀请分享图
                    spreadUserImgService.deleteImgUrl(uid);
                }
            });
            return userInfo;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedis.del(watchKey);
            jedis.unwatch();
            jedisPool.returnResource(jedis);
        }
        throw new UserAccountException(10, "请稍后再试");
    }
    /**
     * 更新账户登录信息
     * 
@@ -1284,6 +1356,98 @@
        userInfoModifyRecordService.addModifyRecord(uid, ModifyTypeEnum.bindWeiXin, wxUnionId);
    }
    @Override
    public UserInfo bindPhoneToLogin(String phone, String key, String appId, HttpServletRequest request) throws UserAccountException {
        UserInfo phoneUser = userInfoMapper.getEffectiveUserInfoByPhone(phone);
        if (phoneUser != null)
            throw new UserAccountException(1, "号码已经被占用");
        // 判断手机号码是否被封禁
        ForbiddenUserIdentifyCode identifyCode1 = forbiddenUserIdentifyCodeService
                .listByTypeAndIdentifyCode(ForbiddenUserIdentifyCodeTypeEnum.phone, phone);
        if (identifyCode1 != null && identifyCode1.getEffective() != null && identifyCode1.getEffective())
            throw new UserAccountException(Constant.CODE_FORBIDDEN_USER, Constant.FORBIDDEN_USER_REASON_DESC);
        String value = redisManager.getCommonString(key);
        if (StringUtil.isNullOrEmpty(value))
            throw new UserAccountException(1, "微信授权失效,请使用微信重新登录");
        WeiXinUser weiXinUser = JsonUtil.getSimpleGson().fromJson(value, WeiXinUser.class);
        if (weiXinUser == null)
            throw new UserAccountException(1, "微信授权失效,请使用微信重新登录");
        String watchKey = StringUtil.Md5("REGISTER:" + weiXinUser.getUnionid());
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.watch(watchKey);
            if (jedis.get(watchKey) != null && Integer.parseInt(jedis.get(watchKey)) > 1)
                throw new UserAccountException(10, "请稍后再试");
            Transaction tran = jedis.multi();
            tran.incr(watchKey);
            List<Object> exec = tran.exec();
            if (exec == null || exec.size() == 0)
                throw new UserAccountException(10, "请稍后再试");
            UserInfo userInfo = userInfoMapper.getEffectiveUserInfoByWXUnionId(weiXinUser.getUnionid());
            // 直接用的微信登录
            if (userInfo != null)
                throw new UserAccountException(10, "该微信号已被占用");
            // 创建新账户
            userInfo = new UserInfo();
            userInfo.setPortrait(weiXinUser.getHeadimgurl());
            userInfo.setAppId(appId);
            userInfo.setNickName(weiXinUser.getNickname());
            userInfo.setWxName(weiXinUser.getNickname());
            userInfo.setWxOpenId(weiXinUser.getOpenid());
            userInfo.setWxUnionId(weiXinUser.getUnionid());
            userInfo.setWxPic(weiXinUser.getHeadimgurl());
            userInfo.setLastLoginTime(System.currentTimeMillis());
            userInfo.setLoginType(2);
            userInfo.setLastLoginIp(request.getRemoteHost());
            userInfo.setState(UserInfo.STATE_NORMAL);
            addUser(userInfo);
            Long uid = userInfo.getId();
            ThreadUtil.run(new Runnable() {
                public void run() {
                    try {
                        // 第一次登录时创建用户额外信息
                        userInfoExtraService.createUserInfoExtra(uid);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    // 加入绑定记录
                    UserAccountBindingHistory history = new UserAccountBindingHistory();
                    history.setContent(phone);
                    history.setType(UserAccountBindingHistory.TYPE_PHONE);
                    history.setUid(uid);
                    history.setFirst(true);
                    userAccountBindingHistoryService.addUserAccountBindingHistory(history);
                    userInfoModifyRecordService.addModifyRecord(uid, ModifyTypeEnum.bindPhone, phone);
                    userInfoModifyRecordService.addModifyRecord(uid, ModifyTypeEnum.bindWeiXin,    weiXinUser.getUnionid());
                }
            });
            // 删除缓存
            redisManager.removeCommonString(key);
            return userInfo;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedis.del(watchKey);
            jedis.unwatch();
            jedisPool.returnResource(jedis);
        }
        throw new UserAccountException(10, "请稍后再试");
    }
    @Override
    public void forbiddenUserAll(Long uid, String reason) {
fanli/src/main/java/com/yeshi/fanli/service/inter/user/BindRemindService.java
New file
@@ -0,0 +1,12 @@
package com.yeshi.fanli.service.inter.user;
public interface BindRemindService {
    /**
     * 查询是否需要提示
     * @param type
     * @param uid
     * @return
     */
    public boolean bindRemind(Long uid, int type);
}
fanli/src/main/java/com/yeshi/fanli/service/inter/user/UserAccountService.java
@@ -237,4 +237,28 @@
     * @param reason
     */
    public void DeleteUserOutOfDate(Long uid, String reason);
    /**
     * 2.0.1 新登录方式 -微信
     * @param request
     * @param acceptData
     * @param loginType
     * @param wxCode
     * @param appId
     * @return
     * @throws UserAccountException
     */
    public UserInfo loginWeiXinNew(HttpServletRequest request, AcceptData acceptData, int loginType, String wxCode, String appId) throws UserAccountException;
    /**
     * 未注册之前绑定手机号
     * @param phone
     * @param key
     * @param appId
     * @param request
     * @return
     * @throws UserAccountException
     */
    public UserInfo bindPhoneToLogin(String phone, String key, String appId, HttpServletRequest request)
            throws UserAccountException;
}
fanli/src/main/java/com/yeshi/fanli/util/factory/goods/GoodsDetailVOFactory.java
@@ -287,7 +287,8 @@
        goodsInfo.setTitle(goods.getTitle());
        goodsInfo.setSalesType(1); // 默认月销量
        goodsInfo.setZkPrice(goods.getZkPrice());
        goodsInfo.setProvcity(goods.getProvcity());
        List<String> imgList = goods.getImgList();
        if (imgList != null) {
            goodsInfo.setImgList(imgList);
fanli/src/main/java/com/yeshi/fanli/util/taobao/TaoKeApiUtil.java
@@ -348,6 +348,7 @@
                    g.setId(goods.getAuctionId());
                    g.setCreatetime(new Date());
                    g.setMaterialLibType(goods.getMaterialLibType());
                    g.setProvcity(goods.getProvcity());
                    return g;
                }
            }
@@ -416,6 +417,7 @@
                    }
                    g.setCreatetime(new Date());
                    g.setMaterialLibType(goods.getMaterialLibType());
                    g.setProvcity(goods.getProvcity());
                    return g;
                }
            }
fanli/src/main/java/com/yeshi/fanli/vo/goods/GoodsDetailVO.java
@@ -68,6 +68,8 @@
    private OtherInfo otherInfo; // 其他信息
    @Expose
    private boolean baoyou; // 是否包邮
    @Expose
    private String provcity; // 商品所在地
    
    public Long getGoodsId() {
@@ -253,4 +255,13 @@
    public void setBaoyou(boolean baoyou) {
        this.baoyou = baoyou;
    }
    public String getProvcity() {
        return provcity;
    }
    public void setProvcity(String provcity) {
        this.provcity = provcity;
    }
}