| | |
| | | http.headers().frameOptions().disable(); |
| | | http.authorizeRequests() |
| | | // 配置不需要鉴权的接口 |
| | | .antMatchers("/admin/api/captcha.jpg*", "/api/**", "/webapi/**","*/agentapi/**").permitAll() |
| | | .antMatchers("/admin/api/captcha.jpg*", "/api/**", "/webapi/**","/credit/api/**","*/agentapi/**").permitAll() |
| | | //配置需要鉴权的接口 |
| | | .antMatchers("/admin/api/**", "/admin/index.html").authenticated() |
| | | .and() |
New file |
| | |
| | | package com.taoke.autopay.controller; |
| | | |
| | | import com.google.gson.Gson; |
| | | import com.google.gson.GsonBuilder; |
| | | import com.google.gson.TypeAdapter; |
| | | import com.google.gson.stream.JsonReader; |
| | | import com.google.gson.stream.JsonWriter; |
| | | import com.taoke.autopay.dao.credit.CreditExchangeRecordMapper; |
| | | import com.taoke.autopay.dao.credit.UserCreditRecordMapper; |
| | | import com.taoke.autopay.dto.admin.CreditInfoDto; |
| | | import com.taoke.autopay.entity.SystemConfigKeyEnum; |
| | | import com.taoke.autopay.entity.WxUserInfo; |
| | | import com.taoke.autopay.entity.credit.CreditExchangeRecord; |
| | | import com.taoke.autopay.entity.credit.UserAlipayBinding; |
| | | import com.taoke.autopay.entity.credit.UserCreditBalance; |
| | | import com.taoke.autopay.entity.credit.UserCreditRecord; |
| | | import com.taoke.autopay.exception.UserCreditExchangeException; |
| | | import com.taoke.autopay.manager.UserCreditExchangeManager; |
| | | import com.taoke.autopay.service.SystemConfigService; |
| | | import com.taoke.autopay.service.credit.CreditExchangeRecordService; |
| | | import com.taoke.autopay.service.credit.UserAlipayBindingService; |
| | | import com.taoke.autopay.service.credit.UserCreditBalanceService; |
| | | import com.taoke.autopay.service.credit.UserCreditRecordService; |
| | | import com.taoke.autopay.utils.Constant; |
| | | import com.taoke.autopay.utils.JsonUtil; |
| | | import com.taoke.autopay.utils.StringUtil; |
| | | import net.sf.json.JSONObject; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpSession; |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | @RestController |
| | | @RequestMapping("/credit/api") |
| | | public class CreditController { |
| | | |
| | | private static final Logger logger = LoggerFactory.getLogger(CreditController.class); |
| | | |
| | | @Resource |
| | | private UserCreditBalanceService userCreditBalanceService; |
| | | |
| | | @Resource |
| | | private UserCreditExchangeManager userCreditExchangeManager; |
| | | |
| | | @Resource |
| | | private CreditExchangeRecordService creditExchangeRecordService; |
| | | |
| | | @Resource |
| | | private UserAlipayBindingService userAlipayBindingService; |
| | | |
| | | @Resource |
| | | private UserCreditRecordService userCreditRecordService; |
| | | |
| | | @Resource |
| | | private CreditExchangeRecordService userCreditExchangeRecordService; |
| | | |
| | | @Resource |
| | | private SystemConfigService systemConfigService; |
| | | |
| | | private final Gson gson = new GsonBuilder().registerTypeAdapter(BigDecimal.class, new TypeAdapter<BigDecimal>() { |
| | | @Override |
| | | public void write(JsonWriter out, BigDecimal value) throws IOException { |
| | | String desc = ""; |
| | | if (value != null) { |
| | | out.value(value.setScale(2, RoundingMode.HALF_UP).toString()); |
| | | } else { |
| | | out.value(""); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public BigDecimal read(JsonReader in) throws IOException { |
| | | return new BigDecimal("0"); |
| | | } |
| | | }).create(); |
| | | |
| | | private Long getUserId(HttpSession session) { |
| | | WxUserInfo user = (WxUserInfo) session.getAttribute(Constant.SESSION_KEY_USER); |
| | | if (user != null) { |
| | | return user.getId(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private String getLoginLinkContent() { |
| | | String redictLink = systemConfigService.getValueCache(SystemConfigKeyEnum.WX_REDIRECT_LINK); |
| | | redictLink = redictLink.replace("snsapi_base", "snsapi_userinfo"); |
| | | // 没有登录,返回登录链接 |
| | | JSONObject root = new JSONObject(); |
| | | root.put("link", redictLink); |
| | | return JsonUtil.loadTrueResult(Constant.RESULT_CODE_NEED_LOGIN, root); |
| | | } |
| | | |
| | | /** |
| | | * 获取积分信息接口 |
| | | * 返回积分余额,剩余积分可兑换的红包,正在兑换中的积分数量 |
| | | */ |
| | | @RequestMapping("/info") |
| | | public String getCreditInfo(HttpSession session) { |
| | | Long userId = getUserId(session); |
| | | if (userId == null) { |
| | | return getLoginLinkContent(); |
| | | } |
| | | int balanceAmount = 0; |
| | | UserCreditBalance balance = userCreditBalanceService.getCreditBalanceByUserId(userId); |
| | | if (balance != null) { |
| | | balanceAmount = balance.getCreditBalance(); |
| | | } |
| | | |
| | | BigDecimal money = new BigDecimal(0); |
| | | try { |
| | | money = userCreditExchangeManager.calculateExchangeAmount(userId, balanceAmount, false); |
| | | } catch (UserCreditExchangeException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | |
| | | List<CreditExchangeRecord> recordList = creditExchangeRecordService.listExchangeRecords(CreditExchangeRecordMapper.DaoQuery.builder() |
| | | .uid(userId) |
| | | .exchangeStatus(CreditExchangeRecord.STATUS_NOT_VERIFY) |
| | | .count(100) |
| | | .build()); |
| | | int exchaningCredits = 0; |
| | | if (recordList != null) { |
| | | for (CreditExchangeRecord record : recordList) { |
| | | exchaningCredits += record.getConsumedCredits(); |
| | | } |
| | | } |
| | | |
| | | |
| | | try { |
| | | return JsonUtil.loadTrueResult(gson.toJson(CreditInfoDto.builder() |
| | | .balance(balanceAmount) |
| | | .exchangeMoney(money) |
| | | .exchangingCredits(exchaningCredits) |
| | | .build())); |
| | | } catch (Exception e) { |
| | | logger.error("获取积分信息失败", e); |
| | | return JsonUtil.loadFalseResult("获取积分信息失败"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取支付宝绑定信息 |
| | | */ |
| | | @RequestMapping("/getAlipayBinding") |
| | | public String getAlipayBinding(HttpSession session) { |
| | | Long uid = getUserId(session); |
| | | if (uid == null) { |
| | | return getLoginLinkContent(); |
| | | } |
| | | |
| | | List<UserAlipayBinding> alipayBindings = userAlipayBindingService.getBindingsByUid(uid); |
| | | if (alipayBindings == null || alipayBindings.isEmpty()) { |
| | | return JsonUtil.loadFalseResult("用户未绑定支付宝账户"); |
| | | } |
| | | try { |
| | | return JsonUtil.loadTrueResult(alipayBindings.get(0)); |
| | | } catch (Exception e) { |
| | | logger.error("获取支付宝绑定信息失败", e); |
| | | return JsonUtil.loadFalseResult("获取支付宝绑定信息失败"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 修改支付宝绑定信息 |
| | | */ |
| | | @PostMapping("/updateAlipayBinding") |
| | | public String updateAlipayBinding(String alipayName, String alipayAccount, HttpSession session) { |
| | | Long userId = getUserId(session); |
| | | if (userId == null) { |
| | | return getLoginLinkContent(); |
| | | } |
| | | |
| | | List<UserAlipayBinding> alipayBindings = userAlipayBindingService.getBindingsByUid(userId); |
| | | if (alipayBindings != null && !alipayBindings.isEmpty()) { |
| | | userAlipayBindingService.updateBinding(UserAlipayBinding.builder() |
| | | .id(alipayBindings.get(0).getId()) |
| | | .alipayName(alipayName) |
| | | .alipayAccount(alipayAccount) |
| | | .updateTime(new Date()) |
| | | .build()); |
| | | } else { |
| | | userAlipayBindingService.addBinding(UserAlipayBinding.builder() |
| | | .uid(userId) |
| | | .alipayName(alipayName) |
| | | .alipayAccount(alipayAccount) |
| | | .createTime(new Date()) |
| | | .build()); |
| | | } |
| | | return JsonUtil.loadTrueResult("修改成功"); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 获取积分记录接口(可分页) |
| | | */ |
| | | @RequestMapping("/records") |
| | | public String getCreditRecords(@RequestParam(defaultValue = "1") int page, |
| | | @RequestParam(defaultValue = "10") int pageSize, |
| | | HttpSession session) { |
| | | Long userId = getUserId(session); |
| | | if (userId == null) { |
| | | return getLoginLinkContent(); |
| | | } |
| | | UserCreditRecordMapper.DaoQuery query = UserCreditRecordMapper.DaoQuery.builder() |
| | | .uid(userId) |
| | | .start((long) (page - 1) * pageSize) |
| | | .count(pageSize) |
| | | .build(); |
| | | List<UserCreditRecord> recordList = userCreditRecordService.listCreditRecords(query); |
| | | long count = userCreditRecordService.countCreditRecords(query); |
| | | JSONObject root = new JSONObject(); |
| | | root.put("list", gson.toJson(recordList)); |
| | | root.put("count", count); |
| | | return JsonUtil.loadTrueResult(root); |
| | | } |
| | | |
| | | /** |
| | | * 积分兑换接口 |
| | | */ |
| | | @PostMapping("/exchange") |
| | | public String exchangeCredits(@RequestParam int credits, HttpSession session) { |
| | | Long userId = getUserId(session); |
| | | if (userId == null) { |
| | | return getLoginLinkContent(); |
| | | } |
| | | |
| | | try { |
| | | userCreditExchangeManager.exchangeCredit(CreditExchangeRecord.builder() |
| | | .consumedCredits(credits) |
| | | .uid(userId) |
| | | .exchangeType(CreditExchangeRecord.ExchangeType.FUND_EXCHANGE) |
| | | .createTime(new Date()) |
| | | .build()); |
| | | return JsonUtil.loadTrueResult("兑换成功"); |
| | | } catch (UserCreditExchangeException e) { |
| | | logger.error("积分兑换失败", e); |
| | | return JsonUtil.loadFalseResult(e.getMessage()); |
| | | } catch (Exception e) { |
| | | logger.error("积分兑换失败", e); |
| | | return JsonUtil.loadFalseResult("兑换失败,请稍后重试"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 积分兑换接口(可分页) |
| | | */ |
| | | @PostMapping("/exchange_records") |
| | | public String exchangeCredits( |
| | | @RequestParam(defaultValue = "1") int page, |
| | | @RequestParam(defaultValue = "10") int pageSize, |
| | | HttpSession session) { |
| | | Long userId = getUserId(session); |
| | | if (userId == null) { |
| | | return getLoginLinkContent(); |
| | | } |
| | | CreditExchangeRecordMapper.DaoQuery query = CreditExchangeRecordMapper.DaoQuery.builder() |
| | | .uid(userId) |
| | | .start((long) (page - 1) * pageSize) |
| | | .count(pageSize) |
| | | .build(); |
| | | List<CreditExchangeRecord> recordList = userCreditExchangeRecordService.listExchangeRecords(query); |
| | | long count = userCreditExchangeRecordService.countExchangeRecords(query); |
| | | JSONObject root = new JSONObject(); |
| | | root.put("list", gson.toJson(recordList)); |
| | | root.put("count", count); |
| | | return JsonUtil.loadTrueResult(root); |
| | | } |
| | | } |
| | |
| | | import net.sf.json.JSONObject; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Controller; |
| | | import org.springframework.util.AntPathMatcher; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import javax.servlet.http.HttpSession; |
| | | import java.io.IOException; |
| | | import java.util.*; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Controller |
| | | @RequestMapping("webapi") |
| | |
| | | } |
| | | |
| | | |
| | | private WxUserInfo wxLogin(String code, HttpSession session) throws Exception { |
| | | WXAppInfoDto wxApp = systemConfigService.getWxAppInfoCache(); |
| | | WxApiUtil.WXAccessTokenInfo tokenInfo = WxApiUtil.getAcessTokenInfo(code, wxApp); |
| | | if (tokenInfo != null && !StringUtil.isNullOrEmpty(tokenInfo.getOpenid())) { |
| | | WxApiUtil.WXUserInfo wxUserInfo = null; |
| | | if (tokenInfo.getScope() != null && tokenInfo.getScope().contains("snsapi_userinfo")) { |
| | | try { |
| | | wxUserInfo = WxApiUtil.getUserInfo(tokenInfo.getAccess_token(), tokenInfo.getOpenid()); |
| | | wxLogger.info("解析结果", new Gson().toJson(wxUserInfo)); |
| | | } catch (Exception e) { |
| | | wxLogger.error("解析出错", e); |
| | | } |
| | | } |
| | | if (wxUserInfo == null) { |
| | | wxUserInfo = new WxApiUtil.WXUserInfo(); |
| | | wxUserInfo.setOpenid(tokenInfo.getOpenid()); |
| | | } |
| | | WxUserInfo user = wxUserService.login(wxUserInfo); |
| | | session.setAttribute(Constant.SESSION_KEY_USER, user); |
| | | wxLogger.info("微信保存用户信息:{} id-{}", session.getId(), user.getId()); |
| | | return user; |
| | | } |
| | | throw new Exception("获取授权信息异常"); |
| | | } |
| | | |
| | | @RequestMapping(value = "wxLogin") |
| | | public void wxLogin(String code, String state, HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException { |
| | | public void wxLogin(String code, String state, HttpServletRequest request, HttpServletResponse |
| | | response, HttpSession session) throws IOException { |
| | | // 根据code获取openid |
| | | SubmitKeyInfo alipayKeyInfo = (SubmitKeyInfo) session.getAttribute(Constant.SESSION_KEY_TEMP_ALIPAY_KEY); |
| | | wxLogger.info("微信授权回调:{} code-{} referer-{}", session.getId(), code, alipayKeyInfo.getReferer()); |
| | | if (alipayKeyInfo != null) { |
| | | wxLogger.info("微信授权回调:{} code-{} referer-{}", session.getId(), code, alipayKeyInfo.getReferer()); |
| | | } |
| | | String failLink = systemConfigService.getValueCache(SystemConfigKeyEnum.WX_LOGIN_FAIL_LINK); |
| | | String referer = alipayKeyInfo.getReferer(); |
| | | String referer = alipayKeyInfo != null ? alipayKeyInfo.getReferer() : ""; |
| | | |
| | | try { |
| | | WXAppInfoDto wxApp = systemConfigService.getWxAppInfoCache(); |
| | | String successLink = systemConfigService.getValueCache(SystemConfigKeyEnum.WX_LOGIN_SUCCESS_LINK); |
| | | if (!StringUtil.isNullOrEmpty(referer)) { |
| | | Map<String, String> params = HttpUtil.getPramsFromUrl(referer); |
| | |
| | | successLink = HttpUtil.getWholeUrl(HttpUtil.getUrlWithoutParams(referer), params); |
| | | } |
| | | |
| | | WxApiUtil.WXAccessTokenInfo tokenInfo = WxApiUtil.getAcessTokenInfo(code, wxApp); |
| | | if (tokenInfo != null && !StringUtil.isNullOrEmpty(tokenInfo.getOpenid())) { |
| | | WxApiUtil.WXUserInfo wxUserInfo = null; |
| | | if (tokenInfo.getScope() != null && tokenInfo.getScope().contains("snsapi_userinfo")) { |
| | | try { |
| | | wxUserInfo = WxApiUtil.getUserInfo(tokenInfo.getAccess_token(), tokenInfo.getOpenid()); |
| | | wxLogger.info("解析结果", new Gson().toJson(wxUserInfo)); |
| | | } catch (Exception e) { |
| | | wxLogger.error("解析出错", e); |
| | | } |
| | | } |
| | | if (wxUserInfo == null) { |
| | | wxUserInfo = new WxApiUtil.WXUserInfo(); |
| | | wxUserInfo.setOpenid(tokenInfo.getOpenid()); |
| | | } |
| | | WxUserInfo user = wxUserService.login(wxUserInfo); |
| | | session.setAttribute(Constant.SESSION_KEY_USER, user); |
| | | wxLogger.info("微信保存用户信息:{} id-{}", session.getId(), user.getId()); |
| | | |
| | | wxLogger.info("从session读取到key:{}", alipayKeyInfo); |
| | | if (alipayKeyInfo != null) { |
| | | if (!ipInfoMap.containsKey(alipayKeyInfo.getIp())) { |
| | | try { |
| | | IPUtil.IPInfo ipInfo = IPUtil.getLocalIPInfo(alipayKeyInfo.getIp()); |
| | | ipInfoMap.put(alipayKeyInfo.getIp(), ipInfo); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | addKey(alipayKeyInfo, user.getId()); |
| | | } |
| | | response.sendRedirect(successLink); |
| | | WxUserInfo user = wxLogin(code, session); |
| | | if(alipayKeyInfo==null){ |
| | | // 普通登录 |
| | | wxLogger.info("普通登录成功"); |
| | | response.sendRedirect("/credit/index.html?state=SUCCESS"); |
| | | return; |
| | | } |
| | | } catch (Exception e) { |
| | | |
| | | wxLogger.info("从session读取到key:{}", alipayKeyInfo); |
| | | if (alipayKeyInfo != null) { |
| | | if (!ipInfoMap.containsKey(alipayKeyInfo.getIp())) { |
| | | try { |
| | | IPUtil.IPInfo ipInfo = IPUtil.getLocalIPInfo(alipayKeyInfo.getIp()); |
| | | ipInfoMap.put(alipayKeyInfo.getIp(), ipInfo); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | addKey(alipayKeyInfo, user.getId()); |
| | | } |
| | | response.sendRedirect(successLink); |
| | | return; |
| | | |
| | | } catch ( |
| | | Exception e) { |
| | | wxLogger.error("授权失败:{}", e.getMessage()); |
| | | if (!StringUtil.isNullOrEmpty(referer)) { |
| | | Map<String, String> params = HttpUtil.getPramsFromUrl(referer); |
| | |
| | | return JsonUtil.loadTrueResult(new Gson().toJson(map)); |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | |
| | | if (!StringUtil.isNullOrEmpty(search.getEnd_date())) { |
| | | query.maxCreateTime = new Date(TimeUtil.convertToTimeTemp(search.getEnd_date(), "yyyy-MM-dd") + 1000 * 60 * 60 * 24L); |
| | | } |
| | | query.sortList = Arrays.asList(new String[]{"_create_time desc"}); |
| | | query.sortList = Arrays.asList(new String[]{"create_time desc"}); |
| | | query.start = (long) (page - 1) * limit; |
| | | query.count = limit; |
| | | |
| | |
| | | int successCount = 0; |
| | | int failCount = 0; |
| | | JSONArray idsArray = JSONArray.fromObject(ids); |
| | | List<String> errorMsgList=new ArrayList<>(); |
| | | for (int i = 0; i < idsArray.size(); i++) { |
| | | long id = idsArray.optLong(i); |
| | | try { |
| | | userCreditExchangeManager.approveExchange(id); |
| | | successCount += 1; |
| | | } catch (UserCreditExchangeException e) { |
| | | errorMsgList.add(e.getMessage()); |
| | | failCount += 1; |
| | | userCreditExchangeRecordService.updateExchangeRecord(CreditExchangeRecord.builder() |
| | | .id(id) |
| | | .exchangeStatusDescription(e.getMessage()) |
| | | .updateTime(new Date()) |
| | | .build()); |
| | | } |
| | | } |
| | | return JsonUtil.loadFalseResult(String.format("成功通过 %d 条记录 通过异常 %d 条记录", successCount, failCount)); |
| | | if(idsArray.size()>1) { |
| | | return JsonUtil.loadFalseResult(String.format("成功通过 %d 条记录 通过异常 %d 条记录", successCount, failCount)); |
| | | }else{ |
| | | if(!errorMsgList.isEmpty()) { |
| | | return JsonUtil.loadFalseResult(errorMsgList.get(0)); |
| | | }else{ |
| | | return JsonUtil.loadTrueResult("通过成功"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | @ResponseBody |
| | | @RequestMapping("list") |
| | | public String listRecords(UserCreditRecordSearchVO search, int page, int limit) { |
| | | UserCreditRecordMapper.DaoQuery query = new UserCreditRecordMapper.DaoQuery(); |
| | | UserCreditRecordMapper.DaoQuery query = UserCreditRecordMapper.DaoQuery.builder().build(); |
| | | if(!StringUtil.isNullOrEmpty(search.getUid())){ |
| | | query.uid = Long.parseLong(search.getUid()); |
| | | } |
| | |
| | | if(!StringUtil.isNullOrEmpty(search.getEnd_date())){ |
| | | query.maxCreateTime = new Date(TimeUtil.convertToTimeTemp(search.getEnd_date(),"yyyy-MM-dd")+1000*60*60*24L); |
| | | } |
| | | query.sortList = Arrays.asList(new String[]{ "_create_time desc"}); |
| | | query.sortList = Arrays.asList(new String[]{ "create_time desc"}); |
| | | query.start = (long) (page - 1) * limit; |
| | | query.count = limit; |
| | | |
| | |
| | | package com.taoke.autopay.dao.credit; |
| | | |
| | | import java.util.Date; |
| | | |
| | | import lombok.Builder; |
| | | import org.apache.ibatis.annotations.Param; |
| | | import java.util.List; |
| | | import com.taoke.autopay.entity.credit.UserCreditRecord; |
| | |
| | | |
| | | long count(@Param("query") DaoQuery query); |
| | | |
| | | @Builder |
| | | public static class DaoQuery { |
| | | public Long id; |
| | | public Long uid; |
New file |
| | |
| | | package com.taoke.autopay.dto.admin; |
| | | |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | @Data |
| | | @Builder |
| | | public class CreditInfoDto { |
| | | private int balance; |
| | | private BigDecimal exchangeMoney; |
| | | private int exchangingCredits; |
| | | |
| | | } |
| | |
| | | public Long exchangeCredit(CreditExchangeRecord request) throws UserCreditExchangeException { |
| | | Long userId = request.getUid(); |
| | | CreditExchangeRecord.ExchangeType exchangeType = request.getExchangeType(); |
| | | if(exchangeType!=CreditExchangeRecord.ExchangeType.FUND_EXCHANGE){ |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_COMMON,"只支持红包兑换"); |
| | | if (exchangeType != CreditExchangeRecord.ExchangeType.FUND_EXCHANGE) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_COMMON, "只支持红包兑换"); |
| | | } |
| | | |
| | | // 检查用户积分余额是否足够 |
| | | UserCreditBalance balance = userCreditBalanceService.getCreditBalanceByUserId(userId); |
| | | if (balance == null || balance.getCreditBalance() <request.getConsumedCredits()) { |
| | | if (balance == null || balance.getCreditBalance() < request.getConsumedCredits()) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_BALANCE_NOT_ENOUGH, "用户积分不足"); |
| | | } |
| | | |
| | | |
| | | |
| | | // 如果是红包兑换,判断用户兑换频率 |
| | |
| | | |
| | | // 查询用户绑定的支付宝账户 |
| | | List<UserAlipayBinding> alipayBindings = userAlipayBindingService.getBindingsByUid(userId); |
| | | if (alipayBindings == null|| alipayBindings.isEmpty()) { |
| | | if (alipayBindings == null || alipayBindings.isEmpty()) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_NOT_BIND_ALIPAY_ACCOUNT, "用户未绑定支付宝账户"); |
| | | } |
| | | |
| | |
| | | |
| | | if (exchangeType == CreditExchangeRecord.ExchangeType.FUND_EXCHANGE) { |
| | | // 计算可兑换金额(如果是红包兑换) |
| | | BigDecimal exchangeAmount = calculateExchangeAmount(request.getUid(), request.getConsumedCredits()); |
| | | BigDecimal exchangeAmount = calculateExchangeAmount(request.getUid(), request.getConsumedCredits(), true); |
| | | exchangeRecord.setExchangeValue(exchangeAmount); |
| | | } |
| | | |
| | |
| | | exchangeRecord.setUid(userId); |
| | | exchangeRecord.setExchangeType(exchangeType); |
| | | exchangeRecord.setConsumedCredits(request.getConsumedCredits()); |
| | | exchangeRecord.setCreditBalance(balance.getCreditBalance()-request.getConsumedCredits()); |
| | | exchangeRecord.setCreditBalance(balance.getCreditBalance() - request.getConsumedCredits()); |
| | | exchangeRecord.setExchangeStatus(CreditExchangeRecord.STATUS_NOT_VERIFY); |
| | | exchangeRecord.setExchangeStatusDescription("未审核"); |
| | | exchangeRecord.setExchangeInfo1(alipayBindings.get(0).getAlipayName()); // 设置支付宝账户 |
| | |
| | | .creditAmount(request.getConsumedCredits()) |
| | | .consumptionMethod(UserCreditRecord.ConsumptionMethod.EXCHANGE_RED_PACKET) |
| | | .direction(UserCreditRecord.DIRECTION_CONSUME) |
| | | .identifierId(exchangeRecord.getId()+"") |
| | | .identifierId(exchangeRecord.getId() + "") |
| | | .uid(exchangeRecord.getUid()) |
| | | .description("红包兑换") |
| | | .build()); |
| | |
| | | * @param exchangeRecordId 兑换记录ID |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void approveExchange(Long exchangeRecordId) throws UserCreditExchangeException{ |
| | | public void approveExchange(Long exchangeRecordId) throws UserCreditExchangeException { |
| | | CreditExchangeRecord exchangeRecord = userCreditExchangeRecordService.getExchangeRecordByIdForUpdate(exchangeRecordId); |
| | | if (exchangeRecord == null) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_NOT_BIND_ALIPAY_ACCOUNT, "兑换记录不存在"); |
| | | } |
| | | |
| | | if(exchangeRecord.getExchangeStatus() != CreditExchangeRecord.STATUS_NOT_VERIFY){ |
| | | if (exchangeRecord.getExchangeStatus() != CreditExchangeRecord.STATUS_NOT_VERIFY) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_COMMON, "兑换已处理"); |
| | | } |
| | | |
| | | |
| | | // 如果是红包兑换,调用通过兑换逻辑(TODO) |
| | | if (exchangeRecord.getExchangeType() == CreditExchangeRecord.ExchangeType.FUND_EXCHANGE) { |
| | | try { |
| | | AlipayUtil.transfer("credit_exchange_"+exchangeRecordId, exchangeRecord.getExchangeInfo2(), exchangeRecord.getExchangeInfo1(), exchangeRecord.getExchangeValue(), "红包兑换", "红包兑换"); |
| | | AlipayUtil.transfer("credit_exchange_" + exchangeRecordId, exchangeRecord.getExchangeInfo2(), exchangeRecord.getExchangeInfo1(), exchangeRecord.getExchangeValue(), "红包兑换", "红包兑换"); |
| | | } catch (AlipayApiException e) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_ALIPAY_TRANSFER_FAILED, e.getErrCode()+ ":"+ e.getErrMsg()); |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_ALIPAY_TRANSFER_FAILED, e.getErrCode() + ":" + e.getErrMsg()); |
| | | } catch (AlipayUtil.AlipayTransferException e) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_ALIPAY_TRANSFER_FAILED, e.getMessage()); |
| | | } |
| | |
| | | |
| | | // 改变兑换记录状态 |
| | | userCreditExchangeRecordService.updateExchangeRecord(CreditExchangeRecord.builder() |
| | | .id(exchangeRecordId) |
| | | .exchangeStatus(CreditExchangeRecord.STATUS_PASSED) |
| | | .exchangeStatusDescription("兑换已通过") |
| | | .updateTime(new Date()) |
| | | .id(exchangeRecordId) |
| | | .exchangeStatus(CreditExchangeRecord.STATUS_PASSED) |
| | | .exchangeStatusDescription("兑换已通过") |
| | | .updateTime(new Date()) |
| | | .build()); |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param exchangeRecordId 兑换记录ID |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void rejectExchange(Long exchangeRecordId) throws UserCreditExchangeException{ |
| | | public void rejectExchange(Long exchangeRecordId) throws UserCreditExchangeException { |
| | | CreditExchangeRecord exchangeRecord = userCreditExchangeRecordService.getExchangeRecordByIdForUpdate(exchangeRecordId); |
| | | if (exchangeRecord == null) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_NOT_BIND_ALIPAY_ACCOUNT, "兑换记录不存在"); |
| | | } |
| | | |
| | | if(exchangeRecord.getExchangeStatus() != CreditExchangeRecord.STATUS_NOT_VERIFY){ |
| | | if (exchangeRecord.getExchangeStatus() != CreditExchangeRecord.STATUS_NOT_VERIFY) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_COMMON, "兑换已处理"); |
| | | } |
| | | |
| | |
| | | .identifierId(exchangeRecord.getId().toString()) |
| | | .acquisitionMethod(UserCreditRecord.AcquisitionMethod.EXCHANGE_RETURN) |
| | | .description("兑换退回") |
| | | .createTime(new Date()) |
| | | .createTime(new Date()) |
| | | .updateTime(new Date()).build()); |
| | | userCreditExchangeRecordService.updateExchangeRecord(CreditExchangeRecord.builder() |
| | | .id(exchangeRecordId) |
| | |
| | | * |
| | | * @param userId 用户ID |
| | | */ |
| | | private void checkRedPacketExchangeFrequency(Long userId) throws UserCreditExchangeException{ |
| | | private void checkRedPacketExchangeFrequency(Long userId) throws UserCreditExchangeException { |
| | | //实现红包兑换频率检查逻辑 |
| | | // 获取今日兑换的次数 |
| | | long nowTimeStamp=System.currentTimeMillis(); |
| | | long count = userCreditExchangeRecordService.countExchangeRecords(CreditExchangeRecordMapper.DaoQuery.builder() |
| | | .uid(userId) |
| | | .minCreateTime(new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(nowTimeStamp,"yyyyMMdd"),"yyyyMMdd"))) |
| | | .maxCreateTime(new Date(nowTimeStamp)) |
| | | long nowTimeStamp = System.currentTimeMillis(); |
| | | long count = userCreditExchangeRecordService.countExchangeRecords(CreditExchangeRecordMapper.DaoQuery.builder() |
| | | .uid(userId) |
| | | .minCreateTime(new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(nowTimeStamp, "yyyyMMdd"), "yyyyMMdd"))) |
| | | .maxCreateTime(new Date(nowTimeStamp)) |
| | | .build()); |
| | | CreditSetting setting = creditSettingService.getSettingCacheByType(CreditSetting.CreditSettingType.DAILY_EXCHANGE_LIMIT, new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(nowTimeStamp,"yyyyMMddHHmm"),"yyyyMMddHHmm"))); |
| | | if(setting==null){ |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_EXCHANGE_FREQUENCY_LIMIT,"兑换频率未设置"); |
| | | CreditSetting setting = creditSettingService.getSettingCacheByType(CreditSetting.CreditSettingType.DAILY_EXCHANGE_LIMIT, new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(nowTimeStamp, "yyyyMMddHHmm"), "yyyyMMddHHmm"))); |
| | | if (setting == null) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_EXCHANGE_FREQUENCY_LIMIT, "兑换频率未设置"); |
| | | } |
| | | if(count>=Integer.parseInt(setting.getValue())){ |
| | | if (count >= Integer.parseInt(setting.getValue())) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_EXCHANGE_FREQUENCY_LIMIT, String.format("每天只能兑换%s次", setting.getValue())); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 计算兑换金额 |
| | | * |
| | | * @param uid |
| | | * @param credit |
| | | * @return |
| | | */ |
| | | public BigDecimal calculateExchangeAmount(Long uid, int credit) throws UserCreditExchangeException{ |
| | | long count = userCreditExchangeRecordService.countExchangeRecords(CreditExchangeRecordMapper.DaoQuery.builder() |
| | | public BigDecimal calculateExchangeAmount(Long uid, int credit, boolean forExchange) throws UserCreditExchangeException { |
| | | long count = userCreditExchangeRecordService.countExchangeRecords(CreditExchangeRecordMapper.DaoQuery.builder() |
| | | .uid(uid).build()); |
| | | Date nowDate = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(System.currentTimeMillis(),"yyyyMMddHHmm"),"yyyyMMddHHmm")); |
| | | Date nowDate = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyyMMddHHmm"), "yyyyMMddHHmm")); |
| | | |
| | | BigDecimal money =null; |
| | | if(count<=0){ |
| | | BigDecimal money = null; |
| | | if (count <= 0) { |
| | | // 新人兑换 |
| | | List<ExchangeRate> rates = exchangeRateService.listExchangeRates(ExchangeRateMapper.DaoQuery.builder() |
| | | .exchangeType(ExchangeRate.ExchangeRateType.NEW_USER_EXCHANGE) |
| | | .maxStartTime(nowDate) |
| | | .minEndTime(nowDate) |
| | | .count(Integer.MAX_VALUE) |
| | | List<ExchangeRate> rates = exchangeRateService.listExchangeRates(ExchangeRateMapper.DaoQuery.builder() |
| | | .exchangeType(ExchangeRate.ExchangeRateType.NEW_USER_EXCHANGE) |
| | | .maxStartTime(nowDate) |
| | | .minEndTime(nowDate) |
| | | .count(Integer.MAX_VALUE) |
| | | .build()); |
| | | if(rates.isEmpty()) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_COMMON,"新人兑换汇率未设置"); |
| | | if (rates.isEmpty()) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_COMMON, "新人兑换汇率未设置"); |
| | | } |
| | | money = new BigDecimal(credit).multiply(rates.get(0).getRate()).setScale(2, RoundingMode.HALF_UP); |
| | | }else{ |
| | | } else { |
| | | // 老用户兑换 |
| | | List<ExchangeRate> rates = exchangeRateService.listExchangeRates(ExchangeRateMapper.DaoQuery.builder() |
| | | List<ExchangeRate> rates = exchangeRateService.listExchangeRates(ExchangeRateMapper.DaoQuery.builder() |
| | | .exchangeType(ExchangeRate.ExchangeRateType.GENERAL_EXCHANGE) |
| | | .maxStartTime(nowDate) |
| | | .minEndTime(nowDate) |
| | | .count(Integer.MAX_VALUE) |
| | | .build()); |
| | | if(rates.isEmpty()) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_COMMON,"老用户兑换汇率未设置"); |
| | | if (rates.isEmpty()) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_COMMON, "老用户兑换汇率未设置"); |
| | | } |
| | | money = new BigDecimal(credit).multiply(rates.get(0).getRate()).setScale(2, RoundingMode.HALF_UP); |
| | | } |
| | | |
| | | CreditSetting setting = creditSettingService.getSettingCacheByType(CreditSetting.CreditSettingType.MINIMUM_EXCHANGE_AMOUNT, nowDate); |
| | | if(setting!=null&& new BigDecimal(setting.getValue()).compareTo(money)>0){ |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_COMMON,String.format("兑换金额不能低于%s元",setting.getValue())); |
| | | if (forExchange) { |
| | | CreditSetting setting = creditSettingService.getSettingCacheByType(CreditSetting.CreditSettingType.MINIMUM_EXCHANGE_AMOUNT, nowDate); |
| | | if (setting != null && new BigDecimal(setting.getValue()).compareTo(money) > 0) { |
| | | throw new UserCreditExchangeException(UserCreditExchangeException.CODE_COMMON, String.format("兑换金额不能低于%s元", setting.getValue())); |
| | | } |
| | | } |
| | | return money; |
| | | } |
| | |
| | | import com.taoke.autopay.service.SystemConfigService; |
| | | import com.taoke.autopay.service.WxUserService; |
| | | import com.taoke.autopay.service.WxUserSettingService; |
| | | import com.taoke.autopay.service.credit.UserCreditBalanceService; |
| | | import com.taoke.autopay.utils.IPUtil; |
| | | import com.taoke.autopay.utils.StringUtil; |
| | | import com.taoke.autopay.utils.WxApiUtil; |
| | |
| | | @Resource |
| | | private SystemConfigService systemConfigService; |
| | | |
| | | @Resource |
| | | private UserCreditBalanceService userCreditBalanceService; |
| | | |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Override |
| | |
| | | user.setLoginTime(new Date()); |
| | | user.setCreateTime(new Date()); |
| | | wxUserInfoMapper.insertSelective(user); |
| | | userCreditBalanceService.initializeCreditBalance(user.getId()); |
| | | return user; |
| | | } else { |
| | | WxUserInfo update = new WxUserInfo(); |
| | |
| | | update.setLoginTime(new Date()); |
| | | update.setUpdateTime(new Date()); |
| | | wxUserInfoMapper.updateByPrimaryKeySelective(update); |
| | | userCreditBalanceService.initializeCreditBalance(update.getId()); |
| | | return list.get(0); |
| | | } |
| | | } |
| | |
| | | |
| | | @Override |
| | | public void initializeCreditBalance(Long userId) { |
| | | if(getCreditBalanceByUserId(userId)!=null){ |
| | | if (getCreditBalanceByUserId(userId) != null) { |
| | | return; |
| | | } |
| | | UserCreditBalance userCreditBalance = new UserCreditBalance(); |
| | |
| | | userCreditBalance.setCreditBalance(0); |
| | | userCreditBalance.setCreateTime(new Date()); |
| | | userCreditBalance.setUpdateTime(new Date()); |
| | | userCreditBalanceMapper.insert(userCreditBalance); |
| | | userCreditBalanceMapper.insertSelective(userCreditBalance); |
| | | } |
| | | |
| | | @Override |
| | |
| | | @Override |
| | | public void increaseCreditBalance(Long userId, int amount) { |
| | | UserCreditBalance userCreditBalance = userCreditBalanceMapper.selectByPrimaryKeyForUpdate(userId); |
| | | if (userCreditBalance == null) { |
| | | initializeCreditBalance(userId); |
| | | userCreditBalance = userCreditBalanceMapper.selectByPrimaryKeyForUpdate(userId); |
| | | } |
| | | if (userCreditBalance != null) { |
| | | userCreditBalanceMapper.updateByPrimaryKeySelective(UserCreditBalance.builder() |
| | | .id(userCreditBalance.getId()) |
| | | .creditBalance(userCreditBalance.getCreditBalance() + amount) |
| | | .updateTime(new Date()) |
| | | .id(userCreditBalance.getId()) |
| | | .creditBalance(userCreditBalance.getCreditBalance() + amount) |
| | | .updateTime(new Date()) |
| | | .build()); |
| | | } |
| | | } |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Override |
| | | public void decreaseCreditBalance(Long userId, int amount) { |
| | | UserCreditBalance userCreditBalance = userCreditBalanceMapper.selectByPrimaryKeyForUpdate(userId); |
| | | if (userCreditBalance == null) { |
| | | initializeCreditBalance(userId); |
| | | userCreditBalance = userCreditBalanceMapper.selectByPrimaryKeyForUpdate(userId); |
| | | } |
| | | |
| | | if (userCreditBalance != null) { |
| | | userCreditBalanceMapper.updateByPrimaryKeySelective(UserCreditBalance.builder() |
| | | .id(userCreditBalance.getId()) |
| | |
| | | import com.alipay.api.response.AlipayFundTransUniTransferResponse; |
| | | |
| | | import net.sf.json.JSONObject; |
| | | |
| | | import org.slf4j.Logger; |
| | | |
| | | |
| | | public class AlipayUtil { |
| | | |
| | | private final static Logger logger = org.slf4j.LoggerFactory.getLogger("debugLogger"); |
| | | |
| | | private static DefaultAlipayClient alipayClient = null; |
| | | |
| | |
| | | alipayClient = new DefaultAlipayClient(certAlipayRequest); |
| | | } catch (AlipayApiException e) { |
| | | e.printStackTrace(); |
| | | logger.error("支付宝初始化失败", e); |
| | | } |
| | | |
| | | } |
| | |
| | | spring: |
| | | profiles: |
| | | active: dev |
| | | active: pro |
| | |
| | | <include refid="Base_Column_List"/> from table_credit_exchange_record where 1=1 |
| | | <include refid="listWhereSQL"/> |
| | | <if test="query.sortList!=null"> |
| | | <foreach collection="query.sortList" item="item" open=" order by " separator=",">#{item}</foreach> |
| | | <foreach collection="query.sortList" item="item" open=" order by " separator=",">${item}</foreach> |
| | | </if>limit #{query.start},#{query.count} |
| | | </select> |
| | | <select id="count" resultType="java.lang.Long">select count(*) from table_credit_exchange_record where 1=1 |
| | |
| | | <include refid="Base_Column_List"/> from table_user_credit_record where 1=1 |
| | | <include refid="listWhereSQL"/> |
| | | <if test="query.sortList!=null"> |
| | | <foreach collection="query.sortList" item="item" open=" order by " separator=",">#{item}</foreach> |
| | | <foreach collection="query.sortList" item="item" open=" order by " separator=",">${item}</foreach> |
| | | </if>limit #{query.start},#{query.count} |
| | | </select> |
| | | <select id="count" resultType="java.lang.Long">select count(*) from table_user_credit_record where 1=1 |
| | |
| | | } |
| | | return "未知"; |
| | | }}, |
| | | {field: 'exchangeStatusDescription', title: '状态描述', width: 180}, |
| | | {field: 'createTime', title: '创建时间', width: 180}, |
| | | {field: 'updateTime', title: '更新时间', width: 180} |
| | | ] |
| | |
| | | let ids = checkStatus.data.map(item => item.id); |
| | | if (ids.length === 0) { |
| | | layer.msg("请至少选择一条记录"); |
| | | return true; |
| | | return false; |
| | | } |
| | | $.post('/admin/api/credit/exchange-record/approve', {ids: JSON.stringify(ids)}, function (response) { |
| | | if (response.code === 0) { |
| | |
| | | }, 'json').fail(function () { |
| | | layer.msg("网络请求失败"); |
| | | }); |
| | | return false; |
| | | }); |
| | | |
| | | // 批量驳回 |
| | |
| | | let ids = checkStatus.data.map(item => item.id); |
| | | if (ids.length === 0) { |
| | | layer.msg("请至少选择一条记录"); |
| | | return; |
| | | return false; |
| | | } |
| | | $.post('/admin/api/credit/exchange-record/reject', {ids: JSON.stringify(ids)}, function (response) { |
| | | if (response.code === 0) { |
| | |
| | | }, 'json').fail(function () { |
| | | layer.msg("网络请求失败"); |
| | | }); |
| | | return false; |
| | | }); |
| | | }); |
| | | </script> |
| | |
| | | </head> |
| | | |
| | | <body> |
| | | |
| | | <form class="layui-form" action="" lay-filter='search'> |
| | | <div class="layui-form-item"> |
| | | <div class="layui-inline"> |
| | | <input type="text" name="uid" id="uid" placeholder="用户ID" autocomplete="off" class="layui-input"> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <button class="layui-btn layui-btn-normal" lay-submit lay-filter="search" id="search"><i |
| | | class="layui-icon layui-icon-search"></i>搜索 |
| | | </button> |
| | | </div> |
| | | |
| | | </div> |
| | | </form> |
| | | <table id="table" lay-filter="table"></table> |
| | | |
| | | |
| | |
| | | layui.use(['table', 'layer'], function () { |
| | | var table = layui.table; |
| | | var layer = layui.layer; |
| | | var form = layui.form; |
| | | |
| | | // 渲染表格 |
| | | table.render({ |
| | |
| | | ]], |
| | | page: true |
| | | }); |
| | | // 监听搜索 |
| | | form.on('submit(search)', function (data) { |
| | | |
| | | tableIns.reload(); |
| | | return false; |
| | | }); |
| | | |
| | | |
| | | |
| | | |
| | |
| | | }, |
| | | |
| | | getConfig: function() { |
| | | http_util.post("/agentapi/admin/getConfig", {}, function(res) { |
| | | http.post("/agentapi/admin/getConfig", {}, function(res) { |
| | | if (res.code == 0) { |
| | | app.config = res.data; |
| | | } |
| | |
| | | }); |
| | | }, |
| | | requestOrders: function() { |
| | | http_util.post("/agentapi/admin/orderList", { |
| | | http.post("/agentapi/admin/orderList", { |
| | | key: $("#search_key").val(), |
| | | timeIndex: app.screen_time_index, |
| | | page: app.current_page |
| | |
| | | }); |
| | | }, |
| | | requestWithdraw: function() { |
| | | http_util.post("/agentapi/admin/withdrawList", { |
| | | http.post("/agentapi/admin/withdrawList", { |
| | | page: app.current_page |
| | | }, function(res) { |
| | | if (res.code == 0) { |
| | |
| | | app.requestWithdraw(); |
| | | }, |
| | | withdraw: function(id) { |
| | | http_util.post("/agentapi/admin/withdraw", { |
| | | http.post("/agentapi/admin/withdraw", { |
| | | id: id |
| | | }, function(res) { |
| | | if (res.code == 0) { |
| | |
| | | window.onresize(); |
| | | </script> |
| | | <link rel="stylesheet" type="text/css" href="../layui/css/layui.css" /> |
| | | <link rel="stylesheet" type="text/css" href="css/common.css" /> |
| | | <script src="../js/jquery.min.js"></script> |
| | | <script src="../js/vue.min.js"></script> |
| | | <script src="../layui/layui.js"></script> |
| | | <script src="js/http.js"></script> |
| | | |
| | | <style> |
| | | body { |
| | |
| | | height: 0.78rem; |
| | | line-height: 0.78rem; |
| | | background: #F6BDD3; |
| | | border-radius: 0.39rem; |
| | | border-radius: 0.2rem; |
| | | margin: auto 0; |
| | | border: none; |
| | | color: #FFF; |
| | |
| | | } |
| | | |
| | | .active { |
| | | background-color: #FF2B4B; |
| | | background-color: #ff5722; |
| | | } |
| | | </style> |
| | | </head> |
| | | |
| | | <body> |
| | | <div id="container" style="text-align: center;"> |
| | | <div class="top-nav"> |
| | | <div @click="goBack"></div> |
| | | <div>支付宝设置</div> |
| | | |
| | | </div> |
| | | <div style="height: 0.82rem;"></div> |
| | | |
| | | <div class="item"> |
| | |
| | | <button class="btn active" @click="save">保存并提交</button> |
| | | |
| | | </div> |
| | | <script src="../js/http.js"></script> |
| | | |
| | | <script> |
| | | $(function() { |
| | | var app = new Vue({ |
| | | el: "#container", |
| | | data: { |
| | | alipayName: "", |
| | | alipayAccount: "" |
| | | }, |
| | | methods: { |
| | | goBack: function() { |
| | | if (window.history.length > 1) { |
| | | window.history.back(); |
| | | } |
| | | }, |
| | | save: function() { |
| | | var account = $("#alipayAccount").val(); |
| | | var name = $("#alipayName").val(); |
| | |
| | | return; |
| | | } |
| | | var index = layer.load(); |
| | | http_util.post("/agentapi/admin/setAlipayAccount", { |
| | | alipayAccount: account, |
| | | alipayName: name |
| | | http.post("/credit/api/updateAlipayBinding", { |
| | | alipayName: name, |
| | | alipayAccount: account |
| | | }, function(res) { |
| | | layer.close(index); |
| | | if (res.code == 0) { |
| | | layer.msg("设置成功"); |
| | | app.goBack(); |
| | | } else { |
| | | layer.msg(res.msg); |
| | | } |
| | | }, function(res) { |
| | | },function () { |
| | | layer.close(index); |
| | | layer.msg(res); |
| | | layer.msg("网络请求失败"); |
| | | }); |
| | | }, |
| | | fetchAlipayBinding: function() { |
| | | var index = layer.load(); |
| | | http.post("/credit/api/getAlipayBinding", {}, function(res) { |
| | | layer.close(index); |
| | | if (res.code === 0) { |
| | | app.alipayName = res.data.alipayName; |
| | | app.alipayAccount = res.data.alipayAccount; |
| | | $("#alipayName").val(app.alipayName); |
| | | $("#alipayAccount").val(app.alipayAccount); |
| | | } else { |
| | | layer.msg(res.msg); |
| | | } |
| | | },function () { |
| | | layer.close(index); |
| | | layer.msg("网络请求失败"); |
| | | }); |
| | | } |
| | | }, |
| | | mounted: function() { |
| | | this.fetchAlipayBinding(); |
| | | } |
| | | }); |
| | | }); |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html> |
| | | |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <meta name="viewport" content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> |
| | | <title>积分记录</title> |
| | | <script> |
| | | window.onresize = function() { |
| | | document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px'; |
| | | }; |
| | | window.onresize(); |
| | | </script> |
| | | <link rel="stylesheet" type="text/css" href="../layui/css/layui.css" /> |
| | | <style> |
| | | body { |
| | | background-color: #E0E0E0; |
| | | } |
| | | |
| | | .record-item { |
| | | margin-bottom: 1px; |
| | | padding: 0.3rem; |
| | | background-color: #FFF; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .record-item .left { |
| | | text-align: left; |
| | | } |
| | | |
| | | .record-item .date { |
| | | font-size: 0.30rem; |
| | | color: #000000; |
| | | } |
| | | |
| | | .record-item .description { |
| | | font-size: 0.26rem; |
| | | color: #666666; |
| | | margin-top: 0.1rem; |
| | | } |
| | | |
| | | .record-item .points { |
| | | font-size: 0.30rem; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .record-item .points.increase { |
| | | color: #FF5722; |
| | | } |
| | | |
| | | .record-item .points.decrease { |
| | | color: #009688; |
| | | } |
| | | |
| | | .loading { |
| | | text-align: center; |
| | | padding: 0.3rem; |
| | | color: #999; |
| | | } |
| | | |
| | | .loading-no { |
| | | color: #ccc; |
| | | } |
| | | </style> |
| | | </head> |
| | | |
| | | <body> |
| | | <div id="container"> |
| | | |
| | | <div v-if="records.length > 0"> |
| | | <div class="record-item" v-for="(record, index) in records" :key="index"> |
| | | <div class="left"> |
| | | <div class="date">{{ record.createTime }}</div> |
| | | <div class="description">{{ record.description }}</div> |
| | | </div> |
| | | <div class="points" :class="{'increase': record.direction == 1, 'decrease':record.direction == 0}"> |
| | | <span v-if="record.direction>0">+{{record.creditAmount}}</span> |
| | | <span v-else>-{{ record.creditAmount }}</span> |
| | | |
| | | </div> |
| | | </div> |
| | | <div class="loading" @click="loadMore" :class="{'loading-no': !hasMore}"> |
| | | <span v-if="hasMore">点击加载更多</span> |
| | | <span v-else>没有更多了</span> |
| | | </div> |
| | | </div> |
| | | <div v-else class="empty"> |
| | | 暂无积分记录 |
| | | </div> |
| | | </div> |
| | | |
| | | <script src="../js/jquery.min.js"></script> |
| | | <script src="../js/vue.min.js"></script> |
| | | <script src="../layui/layui.js"></script> |
| | | <script src="../js/http.js"></script> |
| | | <script> |
| | | let app = new Vue({ |
| | | el: '#container', |
| | | data: { |
| | | records: [], |
| | | page: 1, |
| | | hasMore: true |
| | | }, |
| | | methods: { |
| | | goBack: function() { |
| | | if (window.history.length > 1) { |
| | | window.history.back(); |
| | | } |
| | | }, |
| | | loadRecords: function() { |
| | | let index = layer.load(); |
| | | http.post("/credit/api/records", { |
| | | page: this.page, |
| | | pageSize: 20 |
| | | }, function(res) { |
| | | layer.close(index); |
| | | if (res.code == 0) { |
| | | var newRecords = res.data.list.map(function(item) { |
| | | return item; |
| | | }); |
| | | app.records = app.records.concat(newRecords); |
| | | app.hasMore = newRecords.length === 20; |
| | | } else { |
| | | layer.msg(res.msg); |
| | | } |
| | | },function () { |
| | | layer.close(index); |
| | | layer.msg("网络请求失败"); |
| | | }); |
| | | }, |
| | | loadMore: function() { |
| | | if (this.hasMore) { |
| | | this.page++; |
| | | this.loadRecords(); |
| | | } |
| | | } |
| | | }, |
| | | mounted: function() { |
| | | this.loadRecords(); |
| | | } |
| | | }); |
| | | </script> |
| | | </body> |
| | | |
| | | </html> |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html> |
| | | |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <meta name="viewport" content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> |
| | | <title>积分兑换记录</title> |
| | | <script> |
| | | window.onresize = function() { |
| | | document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px'; |
| | | }; |
| | | window.onresize(); |
| | | </script> |
| | | <link rel="stylesheet" type="text/css" href="../layui/css/layui.css" /> |
| | | <style> |
| | | body { |
| | | background-color: #E0E0E0; |
| | | } |
| | | |
| | | .record-item { |
| | | margin-bottom: 1px; |
| | | padding: 0.3rem; |
| | | background-color: #FFF; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .record-item .left { |
| | | text-align: left; |
| | | } |
| | | |
| | | .record-item .value { |
| | | font-size: 0.30rem; |
| | | color: #000000; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .record-item .date { |
| | | font-size: 0.26rem; |
| | | color: #666666; |
| | | margin-top: 0.1rem; |
| | | } |
| | | |
| | | .record-item .points { |
| | | font-size: 0.26rem; |
| | | color: #999999; |
| | | margin-top: 0.1rem; |
| | | } |
| | | |
| | | .record-item .status { |
| | | font-size: 0.30rem; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .record-item .status.pending { |
| | | color: #FF5722; |
| | | } |
| | | |
| | | .record-item .status.completed { |
| | | color: #009688; |
| | | } |
| | | |
| | | .loading { |
| | | text-align: center; |
| | | padding: 0.3rem; |
| | | color: #999; |
| | | } |
| | | |
| | | .loading-no { |
| | | color: #ccc; |
| | | } |
| | | </style> |
| | | </head> |
| | | |
| | | <body> |
| | | <div id="container"> |
| | | |
| | | <div v-if="records.length > 0"> |
| | | <div class="record-item" v-for="(record, index) in records" :key="index"> |
| | | <div class="left"> |
| | | <div class="value">{{ record.exchangeValue }}元</div> |
| | | <div class="date">{{ record.exchangeTime }}</div> |
| | | <div class="points">消耗积分:{{ record.consumedCredits }}</div> |
| | | </div> |
| | | <div class="status" :class="record.status === 'pending' ? 'pending' : 'completed'"> |
| | | {{ record.statusDesc }} |
| | | </div> |
| | | </div> |
| | | <div class="loading" @click="loadMore" :class="{'loading-no': !hasMore}"> |
| | | <span v-if="hasMore">点击加载更多</span> |
| | | <span v-else>没有更多了</span> |
| | | </div> |
| | | </div> |
| | | <div v-else class="empty"> |
| | | 暂无兑换记录 |
| | | </div> |
| | | </div> |
| | | |
| | | <script src="../js/vue.min.js"></script> |
| | | <script src="../layui/layui.js"></script> |
| | | <script src="../js/http.js"></script> |
| | | <script src="../js/jquery.min.js"></script> |
| | | <script> |
| | | const app = new Vue({ |
| | | el: '#container', |
| | | data: { |
| | | records: [], |
| | | page: 1, |
| | | hasMore: true |
| | | }, |
| | | methods: { |
| | | loadRecords: function() { |
| | | var index = layer.load(); |
| | | http.post("/credit/api/exchange_records", { |
| | | page: this.page, |
| | | pageSize: 20 |
| | | }, function(res) { |
| | | layer.close(index); |
| | | if (res.code === 0) { |
| | | var newRecords = res.data.list.map(function(item) { |
| | | var fitem = { |
| | | exchangeTime: item.createTime, |
| | | consumedCredits: item.consumedCredits, |
| | | exchangeValue: item.exchangeValue, |
| | | status: item.exchangeStatus===0 ? 'pending' : 'completed', |
| | | statusDesc: item.exchangeStatusDescription |
| | | }; |
| | | switch (item.exchangeStatus) { |
| | | case 0: |
| | | fitem.statusDesc = "等待审核"; |
| | | break; |
| | | case 1: |
| | | fitem.statusDesc = "兑换成功"; |
| | | break; |
| | | case 2: |
| | | fitem.statusDesc = "兑换驳回"; |
| | | break; |
| | | default: |
| | | fitem.statusDesc = "未知"; |
| | | break; |
| | | |
| | | } |
| | | return fitem; |
| | | }); |
| | | app.records = app.records.concat(newRecords); |
| | | app.hasMore = newRecords.length === 20; |
| | | } else { |
| | | layer.msg(res.msg); |
| | | } |
| | | },function() { |
| | | layer.close(index); |
| | | layer.msg("网络请求出错"); |
| | | }); |
| | | }, |
| | | loadMore: function() { |
| | | if (this.hasMore) { |
| | | this.page++; |
| | | this.loadRecords(); |
| | | } |
| | | } |
| | | }, |
| | | mounted: function() { |
| | | this.loadRecords(); |
| | | } |
| | | }); |
| | | </script> |
| | | </body> |
| | | |
| | | </html> |
| | |
| | | |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <meta name="viewport" content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> |
| | | <meta name="viewport" |
| | | content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/> |
| | | <title>积分中心</title> |
| | | <script> |
| | | window.onresize = function() { |
| | | window.onresize = function () { |
| | | document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px'; |
| | | }; |
| | | window.onresize(); |
| | | </script> |
| | | <link rel="stylesheet" type="text/css" href="../layui/css/layui.css" /> |
| | | <link rel="stylesheet" type="text/css" href="../css/common.css" /> |
| | | <link rel="stylesheet" type="text/css" href="../layui/css/layui.css"/> |
| | | <style> |
| | | body { |
| | | background-color: #FFFFFF; |
| | |
| | | |
| | | .estimated-amount { |
| | | font-size: 0.21rem; /* 修改字体大小为原来的30% */ |
| | | color: #333; |
| | | color: #666; |
| | | margin-top: -0.5rem; |
| | | } |
| | | |
| | | .exchange-container { |
| | | text-align: center; |
| | | text-align: left; |
| | | margin: 1rem 0; |
| | | padding: 1rem; |
| | | background-color: #fff; |
| | |
| | | .links-container a:hover { |
| | | text-decoration: underline; |
| | | } |
| | | [v-cloak]{ |
| | | display: none; |
| | | } |
| | | </style> |
| | | |
| | | |
| | | <style> |
| | | /* 新增样式:底部菜单 */ |
| | | .footer-menu { |
| | | position: fixed; |
| | | bottom: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | display: flex; |
| | | justify-content: space-around; |
| | | background-color: #fff; |
| | | border-top: 1px solid #eee; |
| | | padding: 0.5rem 0; |
| | | box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .menu-item { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | text-decoration: none; |
| | | color: #666; |
| | | font-size: 0.24rem; |
| | | } |
| | | |
| | | .menu-item.active { |
| | | color: #000; |
| | | } |
| | | |
| | | .menu-icon { |
| | | width: 0.4rem; |
| | | height: 0.4rem; |
| | | margin-bottom: 0.1rem; |
| | | } |
| | | </style> |
| | | </head> |
| | | |
| | | <body> |
| | | <div id="app"> |
| | | <div class="exchange-container"> |
| | | <div class="balance"><span style=" color:black;">当前积分余额: </span>{{ creditBalance }}</div> |
| | | <div class="estimated-amount">预计可兑换红包金额: {{ estimatedRedPacketAmount }}元</div> |
| | | |
| | | <div class="balance" v-cloak><span style=" color:black;">当前积分余额: </span>{{ creditBalance }}</div> |
| | | <div class="estimated-amount" v-cloak>预计可兑换红包金额: {{ estimatedRedPacketAmount }}元</div> |
| | | <div class="balance" v-cloak><span style=" color:black;">兑换中的积分: </span>{{ exchangingCredits }}</div> |
| | | <div class="exchange-title">积分红包兑换</div> |
| | | |
| | | |
| | | <div class="exchange-input"> |
| | | <input type="number" v-model="exchangePoints" placeholder="请输入兑换积分" /> |
| | | <input type="number" v-model="exchangePoints" placeholder="请输入兑换积分"/> |
| | | <button class="btn" @click="exchangePointsToRedPacket">兑换</button> |
| | | </div> |
| | | <div class="links-container"> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- 新增底部菜单 --> |
| | | <div class="footer-menu"> |
| | | <a href="/index3.html" class="menu-item"> |
| | | <img src="../img/command.png" alt="口令" class="menu-icon"> |
| | | <span>口令</span> |
| | | </a> |
| | | <a href="/credit/index.html" class="menu-item active"> |
| | | <img src="../img/credit_fill.png" alt="积分" class="menu-icon"> |
| | | <span>积分</span> |
| | | </a> |
| | | </div> |
| | | |
| | | |
| | | <script src="../js/jquery.min.js"></script> |
| | | <script src="../js/vue.min.js"></script> |
| | | <script src="../layui/layui.js"></script> |
| | | <script src="../js/http.js"></script> |
| | | <script src="../layui/layui.js"></script> |
| | | <script> |
| | | new Vue({ |
| | | let app = new Vue({ |
| | | el: '#app', |
| | | data: { |
| | | creditBalance: 0, |
| | | estimatedRedPacketAmount: 0, |
| | | exchangingCredits: 0, |
| | | exchangePoints: '' |
| | | }, |
| | | mounted() { |
| | |
| | | }, |
| | | methods: { |
| | | loadCreditBalance() { |
| | | let index = layer.load(); |
| | | // 调用API获取积分余额 |
| | | http.get('/api/credit/balance').then(response => { |
| | | this.creditBalance = response.data.balance; |
| | | this.calculateEstimatedRedPacketAmount(); |
| | | http.post("/credit/api/info", {}, function (response) { |
| | | layer.close(index); |
| | | if (response.code === 0) { |
| | | let data = response.data; |
| | | console.log("data:",data); |
| | | app.creditBalance = data.balance; |
| | | app.estimatedRedPacketAmount = data.exchangeMoney; |
| | | } else if (response.code === 1001) { |
| | | window.location.replace(response.data.link); |
| | | } else { |
| | | layer.msg(response.msg); |
| | | } |
| | | }, 'json').fail(function (jqXHR, textStatus, errorThrown) { |
| | | layer.close(index); |
| | | layer.msg("网络请求失败"); |
| | | }); |
| | | }, |
| | | calculateEstimatedRedPacketAmount() { |
| | | // 假设每100积分可兑换1元红包 |
| | | this.estimatedRedPacketAmount = (this.creditBalance / 100).toFixed(2); |
| | | |
| | | |
| | | }, |
| | | exchangePointsToRedPacket() { |
| | | if (!this.exchangePoints || this.exchangePoints <= 0) { |
| | | alert('请输入有效的兑换积分'); |
| | | // 校验输入的积分值是否为正整数 |
| | | const points = parseInt(this.exchangePoints, 0); |
| | | if (isNaN(points) || points <= 0) { |
| | | layer.msg('请输入有效的兑换积分'); |
| | | return; |
| | | } |
| | | // 校验用户积分余额是否足够 |
| | | if (points > this.creditBalance) { |
| | | layer.msg('积分余额不足'); |
| | | return; |
| | | } |
| | | let index = layer.load(); |
| | | // 调用API进行积分兑换 |
| | | http.post('/api/credit/exchange', { points: this.exchangePoints }).then(response => { |
| | | alert('兑换成功'); |
| | | this.loadCreditBalance(); |
| | | this.exchangePoints = ''; |
| | | }).catch(error => { |
| | | alert('兑换失败: ' + error.message); |
| | | http.post('/credit/api/exchange', {"credits":points}, function(response){ |
| | | layer.close(index); |
| | | if(response.code===0){ |
| | | layer.msg("提交成功,等待审核"); |
| | | app.loadCreditBalance(); |
| | | }else{ |
| | | layer.msg(response.msg); |
| | | } |
| | | |
| | | },function (){ |
| | | layer.close(index); |
| | | layer.msg("网络请求失败"); |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | </script> |
| | | </body> |
| | | |
| | | </html> |
| | |
| | | <meta name="viewport" content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> |
| | | <title>福利发放</title> |
| | | <link rel="stylesheet" type="text/css" href="layui/css/layui.css" /> |
| | | <script> |
| | | window.onresize = function () { |
| | | document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px'; |
| | | }; |
| | | window.onresize(); |
| | | </script> |
| | | <script src="js/jquery.min.js"></script> |
| | | <script src="layui/layui.js"></script> |
| | | <style> |
| | |
| | | flex-direction: column; |
| | | } |
| | | .edit{ |
| | | border-radius: 1rem; |
| | | border-radius: 0.2rem; |
| | | width: 80%; |
| | | margin-top: 3rem; |
| | | margin-top: 0.6rem; |
| | | } |
| | | .money { |
| | | border-radius: 0.5rem; |
| | | border-radius: 0.1rem; |
| | | width: 80%; |
| | | margin-top: 2rem; |
| | | margin-top: 0.4rem; |
| | | display: none; |
| | | } |
| | | |
| | | .btn{ |
| | | background-color: #FF2B4B; |
| | | border-radius: 0.5rem; |
| | | border-radius: 0.1rem; |
| | | width: 80%; |
| | | margin-top: 2rem; |
| | | font-size: 1.2rem; |
| | | margin-top: 0.4rem; |
| | | font-size: 0.25rem; |
| | | } |
| | | |
| | | </style> |
| | |
| | | <button class="layui-btn btn" >提交</button> |
| | | |
| | | </div> |
| | | |
| | | <!-- 新增底部菜单 --> |
| | | <div class="footer-menu"> |
| | | <a href="/index3.html" class="menu-item"> |
| | | <img src="../img/command_fill.png" alt="口令" class="menu-icon"> |
| | | <span>口令</span> |
| | | </a> |
| | | <a href="/credit/index.html" class="menu-item active"> |
| | | <img src="../img/credit.png" alt="积分" class="menu-icon"> |
| | | <span>积分</span> |
| | | </a> |
| | | </div> |
| | | |
| | | <style> |
| | | /* 新增样式:底部菜单 */ |
| | | .footer-menu { |
| | | position: fixed; |
| | | bottom: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | display: flex; |
| | | justify-content: space-around; |
| | | background-color: #fff; |
| | | border-top: 1px solid #eee; |
| | | padding: 0.5rem 0; |
| | | box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .menu-item { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | text-decoration: none; |
| | | color: #666; |
| | | font-size: 0.24rem; |
| | | } |
| | | |
| | | .menu-item.active { |
| | | color: #000; |
| | | } |
| | | |
| | | .menu-icon { |
| | | width: 0.4rem; |
| | | height: 0.4rem; |
| | | margin-bottom: 0.1rem; |
| | | } |
| | | </style> |
| | | |
| | | <script> |
| | | $(function(){ |
New file |
| | |
| | | const http = { |
| | | |
| | | getQueryString: function (name) { |
| | | |
| | | }, |
| | | post: function (url, params, success_callback, fail_callback) { |
| | | $.post(url, params, function (res) { |
| | | success_callback(res) |
| | | if (res.code === 1001) { |
| | | window.location.replace(res.data.link); |
| | | } |
| | | }, 'json').fail(function (jqXHR, textStatus, errorThrown) { |
| | | layer.msg("网络请求失败"); |
| | | if (fail_callback) { |
| | | fail_callback(); |
| | | } |
| | | }); |
| | | |
| | | }, |
| | | |
| | | }; |