package com.yeshi.fanli.service.impl.user; import java.io.Serializable; import java.math.BigDecimal; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.UUID; import javax.annotation.Resource; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.springframework.orm.hibernate4.HibernateCallback; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.request.AlipayFundTransToaccountTransferRequest; import com.alipay.api.response.AlipayFundTransToaccountTransferResponse; import com.yeshi.fanli.dao.mybatis.AccountDetailsMapper; import com.yeshi.fanli.dao.mybatis.AlipayAccountValidNormalHistoryMapper; import com.yeshi.fanli.dao.mybatis.BindingAccountMapper; import com.yeshi.fanli.dao.mybatis.UserInfoMapper; import com.yeshi.fanli.dao.mybatis.money.UserMoneyDetailMapper; import com.yeshi.fanli.dao.user.BindingAccountDao; import com.yeshi.fanli.entity.bus.user.AccountDetails; import com.yeshi.fanli.entity.bus.user.AlipayAccountValidNormalHistory; import com.yeshi.fanli.entity.bus.user.BindingAccount; import com.yeshi.fanli.entity.bus.user.UserInfo; import com.yeshi.fanli.entity.money.UserMoneyDetail; import com.yeshi.fanli.exception.AlipayAccountException; import com.yeshi.fanli.exception.AlipayTransferException; import com.yeshi.fanli.exception.BindingAccountException; import com.yeshi.fanli.exception.money.UserMoneyDetailException; import com.yeshi.fanli.log.LogHelper; import com.yeshi.fanli.service.inter.user.BindingAccountService; import com.yeshi.fanli.service.inter.user.UserNotificationService; import com.yeshi.fanli.util.Constant; import com.yeshi.fanli.util.StringUtil; import com.yeshi.fanli.util.factory.AccountDetailsFactory; import com.yeshi.fanli.util.factory.UserMoneyDetailFactory; import net.sf.json.JSONObject; @Service public class BindingAccountServiceImpl implements BindingAccountService { @Resource private BindingAccountDao bindingAccountDao; @Resource private BindingAccountMapper bindingAccountMapper; @Resource private AlipayAccountValidNormalHistoryMapper alipayAccountValidNormalHistoryMapper; @Resource private UserInfoMapper userInfoMapper; @Resource private AccountDetailsMapper accountDetailsMapper; @Resource private UserNotificationService userNotificationService; @Resource private UserMoneyDetailMapper userMoneyDetailMapper; public List getBindingAccountByUid(long uid) { return bindingAccountDao.list("from BindingAccount ba where ba.userInfo.id=?", new Serializable[] { uid }); } public void addBindingAccount(BindingAccount addAccount) throws BindingAccountException { List list = bindingAccountDao.list( "from BindingAccount ba where ba.userInfo.id=? and ba.type=?", new Serializable[] { addAccount.getUserInfo().getId(), addAccount.getType() }); if (list == null || list.size() == 0) { bindingAccountDao.save(addAccount); } else { throw new BindingAccountException(Constant.BA_EXIST); } } public Integer deleteBindingAccount(final BindingAccount account) { return (Integer) bindingAccountDao.excute(new HibernateCallback() { public Integer doInHibernate(Session session) throws HibernateException { Transaction transaction = session.beginTransaction(); Query delete = session.createQuery("delete BindingAccount ba where ba.userInfo.id=? and ba.type=?"); delete.setLong(0, account.getUserInfo().getId()); delete.setInteger(1, account.getType()); int update = delete.executeUpdate(); transaction.commit(); return update; } }); } public BindingAccount getBindingAccountByUidAndType(long uid, int type) { List list = bindingAccountDao .list("from BindingAccount ba where ba.userInfo.id=? and ba.type=?", new Serializable[] { uid, type }); if (list != null && list.size() != 0) { return list.get(0); } return null; } @Override public BindingAccount changeAlipayBinding(Long uid, String name, String account) { BindingAccount bindingAccount = getBindingAccountByUidAndType(uid, BindingAccount.TYPE_ALIPAY); if (bindingAccount == null)// 创建账号 { bindingAccount = new BindingAccount(); bindingAccount.setAccount(account); bindingAccount.setName(name); bindingAccount.setType(BindingAccount.TYPE_ALIPAY); bindingAccount.setUserInfo(new UserInfo(uid)); bindingAccountDao.create(bindingAccount); } else { bindingAccount.setName(name); bindingAccount.setAccount(account); bindingAccountDao.update(bindingAccount); } return bindingAccount; } @Override public int deleteByPrimaryKey(Long id) { return bindingAccountMapper.deleteByPrimaryKey(id); } @Transactional @Override public void validAlipayAccount(Long uid, String account, String name) throws AlipayTransferException, AlipayApiException, AlipayAccountException { if (uid == null) throw new AlipayAccountException(AlipayAccountException.CODE_NO_PARAMS, "用户ID不能为空"); if (StringUtil.isNullOrEmpty(account)) throw new AlipayAccountException(AlipayAccountException.CODE_NO_PARAMS, "账号不能为空"); if (StringUtil.isNullOrEmpty(name)) throw new AlipayAccountException(AlipayAccountException.CODE_NO_PARAMS, "真实姓名不能为空"); // List bindingAccountList = bindingAccountMapper.selectByAccount(account); if (bindingAccountList != null && bindingAccountList.size() > 0) { if (bindingAccountList.get(0).getUserInfo().getId().longValue() != uid) throw new AlipayAccountException(AlipayAccountException.CODE_ALREADY_BIND, "该支付宝账号已被其他账号绑定,请更换其他的支付宝账号来绑定"); } // TODO 做频率验证-每月验证一次 AlipayAccountValidNormalHistory latest = alipayAccountValidNormalHistoryMapper.selectLatestByUid(uid); if (latest != null) { Calendar caLatest = Calendar.getInstance(); caLatest.setTimeInMillis(latest.getCreateTime().getTime()); Calendar nowLatest = Calendar.getInstance(); if (caLatest.get(Calendar.MONTH) == nowLatest.get(Calendar.MONTH))// 上次更改和现在是同一个月 throw new AlipayAccountException(AlipayAccountException.CODE_TIMES_LIMIT, "每月只能更换绑定一次支付宝账号,请次月再试。"); } UserInfo userInfo = userInfoMapper.selectByPrimaryKeyForUpdate(uid); if (userInfo.getMyHongBao().compareTo(new BigDecimal("0")) <= 0) throw new AlipayAccountException(AlipayAccountException.CODE_NO_MONEY, "你的账户目前没有余额,无需绑定提现帐号。"); // 需要转账验证 BigDecimal money = new BigDecimal("0.1"); transferAlipayWithVerify(account, name); // 扣款 userInfoMapper.subHongBaoByUid(uid, money); // 转账成功 // 插入转账成功表 AlipayAccountValidNormalHistory history = new AlipayAccountValidNormalHistory(); history.setAccount(account); history.setCreateTime(new Date()); history.setName(name); history.setUid(uid); alipayAccountValidNormalHistoryMapper.insertSelective(history); // 资金记录 站内信 AccountDetails accountDetails = AccountDetailsFactory.create("-" + money.toString(), AccountDetailsFactory.VALID_ALIPAY_ACCOUNT, null, null, new UserInfo(uid)); accountDetailsMapper.insertSelective(accountDetails); // 新版资金 try { UserMoneyDetail userMoneyDetail = UserMoneyDetailFactory.createExtractAccountValid(history, money); userMoneyDetail.setId(accountDetails.getId()); userMoneyDetailMapper.insert(userMoneyDetail); } catch (UserMoneyDetailException e) { try { LogHelper.errorDetailInfo(e); } catch (Exception e1) { e1.printStackTrace(); } } userNotificationService.alipayAccountValidRight(uid, money, account); } private void transferAlipayWithVerify(String account, String name) throws AlipayTransferException, AlipayApiException { String privateKey = Constant.alipayConfig.getPrivateKey(); AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", Constant.alipayConfig.getAppId(), privateKey, "json", "gbk", null, "RSA2"); AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest(); String uuid = UUID.randomUUID().toString().replace("-", ""); String appName = Constant.systemCommonConfig.getProjectChineseName(); JSONObject json = new JSONObject(); json.put("out_biz_no", uuid); json.put("payee_type", "ALIPAY_LOGONID"); json.put("payee_account", account); json.put("amount", "0.1"); json.put("payer_show_name", appName + "支付宝验证"); json.put("payee_real_name", name); json.put("remark", "来自" + appName + "的支付宝验证打款"); request.setBizContent(json.toString()); AlipayFundTransToaccountTransferResponse response = null; response = alipayClient.execute(request); // 成功转账 if (response != null && response.isSuccess() && "10000".equals(response.getCode())) { return; } else// 转账失败 { throw new AlipayTransferException(Integer.parseInt(response.getCode()), response.getSubCode(), response.getSubMsg()); } } @Transactional @Override public BindingAccount changeAlipayBindingWithVerify(Long uid, String name, String account) throws AlipayTransferException, AlipayApiException, AlipayAccountException { try { validAlipayAccount(uid, account, name); } catch (AlipayTransferException e1) { throw new AlipayTransferException(e1.getCode(), e1.getSubCode(), e1.getMsg()); } catch (AlipayApiException e1) { throw new AlipayApiException(e1.getErrCode(), e1.getErrMsg()); } catch (AlipayAccountException e1) { throw new AlipayAccountException(e1.getCode(), e1.getMsg()); } BindingAccount bindingAccount = bindingAccountMapper.selectByUidAndType(uid, BindingAccount.TYPE_ALIPAY); if (bindingAccount == null)// 创建账号 { bindingAccount = new BindingAccount(); bindingAccount.setAccount(account); bindingAccount.setName(name); bindingAccount.setType(BindingAccount.TYPE_ALIPAY); bindingAccount.setUserInfo(new UserInfo(uid)); bindingAccountMapper.insertSelective(bindingAccount); } else { BindingAccount updateBindingAccount = new BindingAccount(); updateBindingAccount.setId(bindingAccount.getId()); updateBindingAccount.setName(name); updateBindingAccount.setAccount(account); bindingAccountMapper.updateByPrimaryKeySelective(updateBindingAccount); bindingAccount.setName(updateBindingAccount.getName()); bindingAccount.setAccount(updateBindingAccount.getAccount()); } return bindingAccount; } @Override public boolean canVerifyAlipayAccount(Long uid) throws BindingAccountException { UserInfo userInfo = userInfoMapper.selectByPrimaryKeyForUpdate(uid); if (userInfo.getMyHongBao().compareTo(new BigDecimal("0")) <= 0) throw new BindingAccountException(1, "你的账户目前没有余额,无需绑定提现帐号。"); AlipayAccountValidNormalHistory latest = alipayAccountValidNormalHistoryMapper.selectLatestByUid(uid); if (latest != null) { Calendar caLatest = Calendar.getInstance(); caLatest.setTimeInMillis(latest.getCreateTime().getTime()); Calendar nowLatest = Calendar.getInstance(); if (caLatest.get(Calendar.MONTH) == nowLatest.get(Calendar.MONTH))// 上次更改和现在是同一个月 throw new BindingAccountException(2, "每月仅可修改1次提现账号,请下月再试吧。"); } return true; } }