| | |
| | | package com.ruoyi.account.controller; |
| | | |
| | | |
| | | import cn.hutool.http.HttpResponse; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | |
| | | import com.ruoyi.account.mapper.AppUserMapper; |
| | | import com.ruoyi.account.service.*; |
| | | import com.ruoyi.account.util.ObsUploadUtil; |
| | | import com.ruoyi.account.util.UUIDUtil; |
| | | import com.ruoyi.account.util.weChat.EnvVersion; |
| | | import com.ruoyi.account.util.weChat.WeChatUtil; |
| | | import com.ruoyi.account.vo.*; |
| | | import com.ruoyi.common.core.constant.CacheConstants; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.utils.poi.ExcelUtil; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.core.web.page.PageInfo; |
| | | import com.ruoyi.common.redis.service.RedisService; |
| | |
| | | import com.ruoyi.order.feignClient.RemoteOrderGoodsClient; |
| | | import com.ruoyi.order.model.Order; |
| | | import com.ruoyi.other.api.domain.Shop; |
| | | import com.ruoyi.other.api.domain.ShopBalanceStatement; |
| | | import com.ruoyi.other.api.domain.ShopWithdraw; |
| | | import com.ruoyi.other.api.feignClient.ShopClient; |
| | | import com.ruoyi.system.api.domain.SysConfig; |
| | | import com.ruoyi.system.api.domain.SysUser; |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.ibatis.annotations.Param; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.net.URLDecoder; |
| | | import java.net.URLEncoder; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.temporal.ChronoUnit; |
| | | import java.util.*; |
| | |
| | | private TokenService tokenService; |
| | | @Resource |
| | | private AppUserService appUserService; |
| | | @Resource |
| | | private IUserWithdrawService userWithdrawService; |
| | | @Resource |
| | | private UserPointService userPointService; |
| | | @Resource |
| | | private AppUserBankService appUserBankService; |
| | | @Resource |
| | | private AppUserMapper appUserMapper; |
| | | @Resource |
| | |
| | | @Value("${file.upload.location}") |
| | | private String filePath; |
| | | |
| | | @PostMapping("/verifyBankInfo") |
| | | @ApiOperation(value = "用户提现前校验银行卡信息") |
| | | public R<Boolean> mobileLogin() { |
| | | LoginUser loginUserApplet = tokenService.getLoginUserApplet(); |
| | | AppUser appUser = appUserService.getById(loginUserApplet.getUserid()); |
| | | AppUserBank bank = appUserBankService.lambdaQuery().eq(AppUserBank::getAppUserId, appUser.getId()).last("limit 1") |
| | | .one(); |
| | | if (bank == null){ |
| | | return R.ok(false); |
| | | }else{ |
| | | return R.ok(true); |
| | | } |
| | | } |
| | | @ApiOperation(value = "提现申请") |
| | | @GetMapping("/withdrawalApplication") |
| | | @ResponseBody |
| | | public R withdrawalApplication(@ApiParam("提现金额") @RequestParam BigDecimal money) { |
| | | LoginUser loginUser = tokenService.getLoginUserApplet(); |
| | | SysConfig data = sysConfigClient.getInfo(8L).getData(); |
| | | AppUser appUser = appUserService.getById(loginUser.getUserid()); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); |
| | | String code = sdf.format(new Date()) + UUIDUtil.getNumberRandom(5); |
| | | money=money.setScale(2, BigDecimal.ROUND_HALF_DOWN); |
| | | if (money.compareTo(BigDecimal.ZERO)==0){ |
| | | throw new ServiceException("提现金额必须大于零"); |
| | | } |
| | | Integer rate = Integer.valueOf(data.getConfigValue()); |
| | | BigDecimal availablePoint = new BigDecimal(appUser.getAvailablePoint()); |
| | | BigDecimal unMoney = availablePoint.divide(BigDecimal.valueOf(rate), 2, RoundingMode.HALF_DOWN); |
| | | if (unMoney.compareTo( money)<0){ |
| | | throw new ServiceException("提现金额不能大于可提现金额,当前可提现金额为:"+unMoney); |
| | | } |
| | | AppUserBank bank = appUserBankService.lambdaQuery().eq(AppUserBank::getAppUserId, appUser.getId()).last("limit 1") |
| | | .one(); |
| | | if(bank==null){ |
| | | throw new ServiceException("请完善账户信息后再申请提现!"); |
| | | } |
| | | if(!org.springframework.util.StringUtils.hasLength(bank.getBankNumber())){ |
| | | throw new ServiceException("请完善银行卡后再申请提现!"); |
| | | } |
| | | // 增加用户提现积分变动记录 |
| | | UserPoint one = userPointService.lambdaQuery().eq(UserPoint::getAppUserId, appUser.getId()) |
| | | .orderByDesc(UserPoint::getCreateTime).last("limit 1").one(); |
| | | UserWithdraw userWithdraw = new UserWithdraw(); |
| | | userWithdraw.setAppUserId(appUser.getId()); |
| | | userWithdraw.setMoney(money); |
| | | BigDecimal multiply = money.multiply(BigDecimal.valueOf(rate)); |
| | | appUser.setAvailablePoint(appUser.getAvailablePoint()-multiply.setScale(0, RoundingMode.HALF_UP).intValue()); |
| | | if (multiply.compareTo(new BigDecimal(appUser.getAvailablePoint()))>0){ |
| | | throw new ServiceException("积分不足!"); |
| | | } |
| | | userWithdraw.setIntegral(Integer.valueOf(multiply.setScale(0, RoundingMode.HALF_UP).toString())); |
| | | userWithdraw.setAuditStatus(0); |
| | | userWithdraw.setStatus(1); |
| | | userWithdraw.setCode(code); |
| | | userWithdraw.setCreateTime(LocalDateTime.now()); |
| | | if (one.getBalance() - Integer.valueOf(multiply.setScale(0, RoundingMode.HALF_UP).toString())<0){ |
| | | throw new ServiceException("积分不足!"); |
| | | } |
| | | userWithdraw.setReceiverAccountNoEnc(bank.getBankNumber()); |
| | | userWithdraw.setReceiverNameEnc(bank.getUserName()); |
| | | userWithdraw.setReceiverBankChannelNo(bank.getReceiverBankChannelNo()); |
| | | userWithdraw.setReceiverAccountType(201); |
| | | userWithdrawService.save(userWithdraw); |
| | | UserPoint userPoint = new UserPoint(); |
| | | userPoint.setType(18); |
| | | userPoint.setVariablePoint(Integer.valueOf(multiply.setScale(0, RoundingMode.HALF_UP).toString())); |
| | | userPoint.setHistoricalPoint(one.getBalance()); |
| | | userPoint.setBalance(one.getBalance() - Integer.valueOf(multiply.setScale(0, RoundingMode.HALF_UP).toString())); |
| | | userPoint.setCreateTime(LocalDateTime.now()); |
| | | userPoint.setAppUserId(appUser.getId()); |
| | | userPoint.setObjectId(userWithdraw.getId()); |
| | | userPointService.save(userPoint); |
| | | appUserService.updateById(appUser); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/mobileLogin") |
| | |
| | | return appUserService.mobileLogin(mobileLogin); |
| | | } |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/registerAccount") |
| | | @ApiOperation(value = "注册新账号") |
| | | public R<LoginVo> registerAccount(@RequestBody RegisterAccount registerAccount) { |
| | | return appUserService.registerAccount(registerAccount); |
| | | } |
| | | |
| | | @GetMapping("/logout") |
| | | @ApiOperation(value = "登出") |
| | |
| | | public AppUser getAppUserById(@RequestParam("id") Long id) { |
| | | System.out.println("根据id获取用户:"+id); |
| | | return appUserService.getById(id); |
| | | } |
| | | // 获取所有用户 |
| | | @PostMapping("/getAppUserAll") |
| | | public List<AppUser> getAppUserAll() { |
| | | return appUserService.list(); |
| | | } |
| | | |
| | | @PostMapping("/getBaseUserById") |
| | |
| | | |
| | | |
| | | |
| | | /* |
| | | |
| | | @GetMapping("/detail") |
| | | @ApiOperation(value = "用户列表-详情", tags = {"管理后台"}) |
| | | public R<AppUser> detail(Long id, Integer shopId) { |
| | | Long userid = tokenService.getLoginUser().getUserid(); |
| | | SysUser sysUser = sysUserClient.getSysUser(userid).getData(); |
| | | public R<AppUser> detail(Long id) { |
| | | AppUser byId = appUserService.getById(id); |
| | | Shop shop1 = shopClient.getServiceProvider(byId.getId()).getData(); |
| | | if(null != shop1){ |
| | | byId.setShopName(shop1.getName()); |
| | | byId.setShopId(shop1.getId()); |
| | | //获取店铺名称 |
| | | List<String> shopNames=shopClient.getServiceProvider(byId.getId()).getData(); |
| | | if(null != shopNames){ |
| | | byId.setShopNames(shopNames); |
| | | } |
| | | R<List<Shop>> shopByUserId = shopClient.getShopByUserId(id); |
| | | if (shopByUserId.getData() != null) { |
| | | List<String> shopName = new ArrayList<>(); |
| | | for (Shop datum : shopByUserId.getData()) { |
| | | shopName.add(datum.getName()); |
| | | } |
| | | byId.setShopNames(shopName); |
| | | } |
| | | |
| | | //最后下单时间 |
| | | R<Order> lastOrder = remoteOrderGoodsClient.getLastOrder(id); |
| | | if (lastOrder.getData() != null) { |
| | | byId.setLastOrderTime(lastOrder.getData().getCreateTime()); |
| | | } |
| | | |
| | | //消费总金额 |
| | | if(null == shopId || 1 == sysUser.getRoleType()){ |
| | | shopId = -1; |
| | | } |
| | | if(null == shopId && 2 == sysUser.getRoleType()){ |
| | | shopId = sysUser.getObjectId(); |
| | | } |
| | | R<List<Order>> orderR = remoteOrderGoodsClient.byUserId(id, shopId); |
| | | List<Order> orderList = orderR.getData(); |
| | | if (!CollectionUtils.isEmpty(orderList)){ |
| | | BigDecimal paymentAmount = orderList.stream().map(Order::getPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | byId.setShopAmount(paymentAmount); |
| | | }else { |
| | | byId.setShopAmount(BigDecimal.ZERO); |
| | | } |
| | | Integer customPoint =(byId.getExchangePoint()==null?0:byId.getExchangePoint())+ |
| | | (byId.getTransferableOutPoint()==null?0:byId.getTransferableOutPoint())- |
| | | (byId.getCancelPoint()==null?0:byId.getCancelPoint()); |
| | | byId.setCustomPoint(customPoint); |
| | | |
| | | return R.ok(byId); |
| | | } |
| | | */ |
| | | |
| | | |
| | | |
| | |
| | | /** |
| | | * 工作台-顶部 |
| | | */ |
| | | @GetMapping("/homeStatistics/statistics") |
| | | @GetMapping("/statistics") |
| | | @ApiOperation(value = "统计", tags = {"后台-工作台-顶部"}) |
| | | public R<UserStatistics> statistics() { |
| | | QueryWrapper<AppUser> queryWrapper = new QueryWrapper<>(); |
| | |
| | | userStatistics.setTotalUser(appUserList.size());//总用户数 |
| | | userStatistics.setConsumerUser((int) consumerUser);//消费过的用户 |
| | | |
| | | //用户类型统计门店 |
| | | long shopUserCount = appUserList.stream() |
| | | .filter(appUser -> appUser.getUserType() == 2) |
| | | .count(); |
| | | userStatistics.setShopUser((int) shopUserCount); |
| | | //拥有店铺用户数 |
| | | Integer shopUserCount = appUserShopService.getHaveShopUserNum(); |
| | | |
| | | userStatistics.setShopUser(shopUserCount); |
| | | |
| | | //门店总数 |
| | | long shopNum = shopClient.getAllShop().getData().size(); |
| | |
| | | queryWrapper.eq("del_flag", 0);//未删除的 |
| | | queryWrapper.ne("status", 3);//未注销的 |
| | | if (userId != null) { |
| | | queryWrapper.eq("user_id", userId); |
| | | queryWrapper.eq("id", userId); |
| | | } |
| | | //统计充值积分 |
| | | Map<String, Object> result = appUserService.getMap(queryWrapper); |
| | | if (result == null || result.get("total_points") == null) { |
| | | userStatistics.setTotalScore(0L); |
| | | }else { |
| | | userStatistics.setTotalScore((Long) result.get("total_points")); |
| | | userStatistics.setTotalScore(Long.valueOf(result.get("total_points").toString())); |
| | | } |
| | | |
| | | //统计消费积分和现金支付数 |
| | | Map<String, Object> data = orderClient.getConsumeScoreAndPayAmount(userId).getData(); |
| | | |
| | | //条件构造 消费积分现金支付金额 |
| | | queryWrapper.clear(); |
| | | QueryWrapper<AppUser> queryWrapper1 = new QueryWrapper<>(); |
| | | queryWrapper1.select("sum(exchange_point + transferable_out_point - cancel_point) as total_points"); |
| | | queryWrapper1.select("sum(shop_amount) as payment_amounts "); |
| | | queryWrapper1.eq("del_flag", 0);//未删除的 |
| | | queryWrapper1.ne("status", 3);//未注销的 |
| | | if (userId != null) { |
| | | queryWrapper1.eq("id", userId); |
| | | } |
| | | Map<String, Object> data = appUserShopService.getPointAndPayAmount(userId); |
| | | if (data == null || data.get("total_points") == null) { |
| | | userStatistics.setConsumeScore(0L); |
| | | }else { |
| | |
| | | }else { |
| | | userStatistics.setShopAmount(new BigDecimal(data.get("payment_amounts").toString())); |
| | | } |
| | | |
| | | |
| | | return R.ok(userStatistics); |
| | | } |
| | |
| | | * @param file |
| | | * @return |
| | | */ |
| | | @PostMapping("/upload") |
| | | /* @PostMapping("/upload") |
| | | public R upload(MultipartFile file){ |
| | | String s = null; |
| | | try { |
| | |
| | | throw new RuntimeException(e); |
| | | } |
| | | return R.ok(s); |
| | | }*/ |
| | | |
| | | private static final String FILE_DIRECTORY = "/dev/xvdb/project/upload_files"; // Linux路径 |
| | | // private static final String FILE_DIRECTORY = "E://ldf_files"; // Linux路径 |
| | | |
| | | @PostMapping("/upload") |
| | | public R handleFileUpload(@RequestParam("file") MultipartFile file) { |
| | | if (file.isEmpty()) { |
| | | return R.fail("请选择一个文件上传"); |
| | | } |
| | | try { |
| | | // 1. 构建日期目录路径(格式:/年/月/日) |
| | | LocalDate today = LocalDate.now(); |
| | | String datePath = String.format("/%d/%02d/%02d", |
| | | today.getYear(), today.getMonthValue(), today.getDayOfMonth()); |
| | | |
| | | // 2. 完整目标目录路径 |
| | | String fullDirPath = FILE_DIRECTORY + datePath; |
| | | File targetDir = new File(fullDirPath); |
| | | |
| | | // 3. 自动创建目录(如果不存在) |
| | | if (!targetDir.exists()) { |
| | | targetDir.mkdirs(); // 递归创建所有父目录 |
| | | } |
| | | String UUID= java.util.UUID.randomUUID().toString(); |
| | | // 4. 保存文件 |
| | | String filePath = fullDirPath + "/" +UUID+ file.getOriginalFilename(); |
| | | File targetFile = new File(filePath); |
| | | file.transferTo(targetFile); |
| | | // 5. 返回可访问的URL(修正路径分隔符为Web格式) |
| | | return R.ok("https://zjrqxny.com/images" + datePath + "/" + UUID+file.getOriginalFilename()); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | return R.fail("上传文件失败"); |
| | | } |
| | | } |
| | | |
| | | |
| | | @GetMapping("/download/{year}/{month}/{day}/{fileName:.+}") |
| | | @ResponseBody |
| | | public ResponseEntity<org.springframework.core.io.Resource> downloadFile( @PathVariable String year, |
| | | @PathVariable String month, |
| | | @PathVariable String day, |
| | | @PathVariable String fileName) { |
| | | System.out.println("下载文件名:"+fileName); |
| | | try { |
| | | // 1. 解码文件名 |
| | | String decodedFileName = URLDecoder.decode(fileName, "UTF-8"); |
| | | |
| | | |
| | | java.nio.file.Path filePath = java.nio.file.Paths.get(FILE_DIRECTORY, year, month, day, decodedFileName).normalize(); |
| | | org.springframework.core.io.Resource resource = new org.springframework.core.io.UrlResource(filePath.toUri()); |
| | | if (resource.exists() || resource.isReadable()) { |
| | | // 5. 设置下载头(兼容所有浏览器) |
| | | String contentDisposition = "attachment; filename=\"" + decodedFileName + "\"; " + |
| | | "filename*=UTF-8''" + URLEncoder.encode(decodedFileName, "UTF-8").replace("+", "%20"); |
| | | |
| | | return ResponseEntity.ok() |
| | | .contentType(MediaType.APPLICATION_OCTET_STREAM) |
| | | .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition) |
| | | .body(resource); |
| | | |
| | | } else { |
| | | return ResponseEntity.notFound().build(); |
| | | } |
| | | } catch (IOException ex) { |
| | | ex.printStackTrace(); |
| | | return ResponseEntity.status(500).build(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 清空绑定门店的用户门店数据 |
| | |
| | | return R.ok(pageInfo); |
| | | } |
| | | |
| | | /** |
| | | * 导出用户积分列表 |
| | | */ |
| | | @ResponseBody |
| | | @GetMapping("/exportUserPoint") |
| | | @ApiOperation(value = "导出用户积分列表", tags = "后台-财务统计-用户积分统计") |
| | | public void exportUserPoint(HttpServletResponse response, @RequestParam(value = "name",required = false) String name) { |
| | | |
| | | List<UserPointStatisticsVO> exportList=appUserMapper.exportUserPoint(name); |
| | | ExcelUtil<UserPointStatisticsVO> util = new ExcelUtil<UserPointStatisticsVO>(UserPointStatisticsVO.class); |
| | | util.exportExcel(response, exportList, "用户积分汇总"); |
| | | } |
| | | |
| | | |
| | | @PostMapping("/saveOrUpdateAppUser") |
| | | Long saveOrUpdateAppUser(@RequestBody AppUser appuser){ |
| | | if (appuser.getId() == null) { |
| | |
| | | |
| | | } |
| | | |
| | | @GetMapping("/getAllUser") |
| | | @ApiOperation(value = "获取所有用户") |
| | | public R<List<AppUser>> getAllUser() { |
| | | LambdaQueryWrapper<AppUser> queryWrapper=new LambdaQueryWrapper<>(); |
| | | queryWrapper.select(AppUser::getId,AppUser::getName); |
| | | queryWrapper.eq(AppUser::getDelFlag,0);//未删除的 |
| | | queryWrapper.ne(AppUser::getStatus, 3);//未注销的 |
| | | List<AppUser> list = appUserService.list(queryWrapper); |
| | | return R.ok(list); |
| | | } |
| | | |
| | | } |
| | | |