Compare commits
5 Commits
8e6131c197
...
00bb295cb0
Author | SHA1 | Date |
---|---|---|
|
00bb295cb0 | |
|
ea22f44e41 | |
|
41dc6aee69 | |
|
774dc07d1a | |
|
2ec5255615 |
|
@ -73,4 +73,12 @@ public class CabinetCellController extends BaseController {
|
|||
cabinetCellApplicationService.configureGoodsCells(cellId, goodsId);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "配置格口商品库存")
|
||||
@AccessLog(title = "格口管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping("/configureGoodsCellsStock/{cellId}/{goodsId}/{stock}")
|
||||
public ResponseDTO<Void> configureGoodsCellsStock(@PathVariable Long cellId, @PathVariable Long goodsId, @PathVariable Integer stock) {
|
||||
cabinetCellApplicationService.configureGoodsCellsStock(cellId, goodsId, stock);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
}
|
|
@ -71,6 +71,11 @@ public class SmartCabinetController extends BaseController {
|
|||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "获取所有柜机数据")
|
||||
@GetMapping("/allCabinets")
|
||||
public ResponseDTO<List<SmartCabinetEntity>> allCabinets() {
|
||||
return ResponseDTO.ok(smartCabinetApplicationService.selectAll());
|
||||
}
|
||||
|
||||
@Operation(summary = "获取所有柜机和格口数据")
|
||||
@GetMapping("/all")
|
||||
|
|
|
@ -1,18 +1,28 @@
|
|||
package com.agileboot.api.controller;
|
||||
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.agileboot.api.response.ShopGoodsResponse;
|
||||
import com.agileboot.common.constant.WeixinConstants;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.domain.shop.category.CategoryApplicationService;
|
||||
import com.agileboot.domain.shop.category.db.ShopCategoryEntity;
|
||||
import com.agileboot.domain.shop.category.dto.ShopCategoryDTO;
|
||||
import com.agileboot.domain.shop.goods.GoodsApplicationService;
|
||||
import com.agileboot.domain.shop.goods.db.SearchGoodsWithCabinetDO;
|
||||
import com.agileboot.domain.shop.goods.db.ShopGoodsEntity;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
@ -20,6 +30,7 @@ import org.springframework.web.util.UriComponentsBuilder;
|
|||
@RestController
|
||||
@RequestMapping("/api/shop")
|
||||
@CrossOrigin(origins = "*", allowedHeaders = "*")
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class ShopController {
|
||||
|
||||
|
@ -28,7 +39,7 @@ public class ShopController {
|
|||
|
||||
@GetMapping("/goods")
|
||||
public ResponseDTO<ShopGoodsResponse> getShopGoodsInfo() {
|
||||
// 获取商品列表
|
||||
/*// 获取商品列表
|
||||
List<ShopGoodsEntity> goodsList = goodsApplicationService.getGoodsAll();
|
||||
goodsList.forEach(goods -> {
|
||||
// 最多只能购买一件
|
||||
|
@ -37,25 +48,69 @@ public class ShopController {
|
|||
}
|
||||
});
|
||||
// 获取分类列表
|
||||
List<ShopCategoryDTO> categoryList = categoryApplicationService.getCategoryAll();
|
||||
List<ShopCategoryDTO> categoryList = categoryApplicationService.getCategoryAll();*/
|
||||
|
||||
// 客户端显示商品列表按柜机格口
|
||||
List<SearchGoodsWithCabinetDO> goodsWithCabinetList = goodsApplicationService.getGoodsWithCabinetList();
|
||||
goodsWithCabinetList.forEach(goodsWithCabinet -> {
|
||||
goodsWithCabinet.setCategoryId(goodsWithCabinet.getCabinetId());
|
||||
});
|
||||
|
||||
return ResponseDTO.ok(new ShopGoodsResponse(goodsList, categoryList, "0"));
|
||||
List<ShopCategoryDTO> categoryList = goodsWithCabinetList.stream().map(g -> {
|
||||
ShopCategoryDTO categoryDTO = new ShopCategoryDTO(new ShopCategoryEntity());
|
||||
categoryDTO.setCategoryId(g.getCategoryId());
|
||||
categoryDTO.setCategoryName(g.getCabinetName());
|
||||
return categoryDTO;
|
||||
}).distinct().collect(Collectors.toList());
|
||||
|
||||
return ResponseDTO.ok(new ShopGoodsResponse(goodsWithCabinetList, categoryList, "0"));
|
||||
}
|
||||
|
||||
@GetMapping("/wechatAuth")
|
||||
public RedirectView wechatAuthRedirect() {
|
||||
public RedirectView wechatAuthRedirect(HttpServletRequest request) {
|
||||
/*java.util.StringJoiner joiner = new java.util.StringJoiner("&");
|
||||
request.getParameterMap().forEach((key, values) -> {
|
||||
joiner.add(key + "=" + String.join(",", values));
|
||||
log.info("wechatAuth key: {} value: {}", key, values[0]);
|
||||
});
|
||||
log.info("wechatAuth 参数:{}", joiner.toString());*/
|
||||
|
||||
// 从请求参数中提取包含token的参数名(参数名本身可能包含"token=")
|
||||
String token = request.getParameterMap().keySet().stream()
|
||||
.filter(key -> key.contains("token="))
|
||||
.findFirst().orElse("");
|
||||
|
||||
log.info("wechatAuth token:{}", token);
|
||||
String state = "";
|
||||
if (StringUtils.isNotBlank(token)) {
|
||||
// 清洗token参数值(原参数名格式为"token=xxx")
|
||||
token = token.replace("token=", "");
|
||||
// 构造带有token标识的state参数,用于授权后回传
|
||||
state = "token_" + token;
|
||||
} else {
|
||||
// 默认state参数,保持微信要求的标准格式
|
||||
state = "state";
|
||||
}
|
||||
|
||||
// 构造微信网页授权URL
|
||||
String authUrl = "https://open.weixin.qq.com/connect/oauth2/authorize"
|
||||
+ "?appid=" + WeixinConstants.appid
|
||||
+ "&redirect_uri=http%3A%2F%2Fwxshop.ab98.cn%2Fshop"
|
||||
+ "&response_type=code"
|
||||
+ "&scope=snsapi_base"
|
||||
+ "&state=STATE#wechat_redirect";
|
||||
+ "&state=" + state
|
||||
+ "#wechat_redirect";
|
||||
return new RedirectView(authUrl);
|
||||
}
|
||||
|
||||
@GetMapping("/qy/wechatAuth")
|
||||
public RedirectView qyWechatAuthRedirect() {
|
||||
public RedirectView qyWechatAuthRedirect(HttpServletRequest request) {
|
||||
/*java.util.StringJoiner joiner = new java.util.StringJoiner("&");
|
||||
request.getParameterMap().forEach((key, values) -> {
|
||||
joiner.add(key + "=" + String.join(",", values));
|
||||
});
|
||||
log.info("/qy/wechatAuth 参数:{}", joiner.toString());*/
|
||||
|
||||
String authUrl = "https://open.weixin.qq.com/connect/oauth2/authorize"
|
||||
+ "?appid=" + WeixinConstants.corpid
|
||||
+ "&redirect_uri=http%3A%2F%2Fwxshop.ab98.cn%2Fshop-api%2Fapi%2Fshop%2FapprovalRedirect"
|
||||
|
@ -82,4 +137,9 @@ public class ShopController {
|
|||
|
||||
return new RedirectView(builder.build().encode().toUriString());
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws UnsupportedEncodingException {
|
||||
String res = URLEncoder.encode("token=12312", StandardCharsets.UTF_8.name());
|
||||
System.out.println(res);
|
||||
}
|
||||
}
|
|
@ -2,15 +2,19 @@ package com.agileboot.api.controller;
|
|||
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.domain.ab98.api.SsoLoginUserinfo;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.agileboot.domain.ab98.api.Ab98ApiUtil;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/wx/login")
|
||||
@CrossOrigin(origins = "*", allowedHeaders = "*")
|
||||
|
@ -88,7 +92,28 @@ public class WxLoginController {
|
|||
data.setTel(loginResponse.getOutputData().getTel());
|
||||
return ResponseDTO.ok(data);
|
||||
} catch (ApiException e) {
|
||||
log.error("短信验证失败: {}", e.getMessage());
|
||||
return ResponseDTO.fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/tokenLogin")
|
||||
@ApiOperation(value = "通过token登录", notes = "用于快速登录,无需验证码")
|
||||
public ResponseDTO<Ab98ApiUtil.LoginData> tokenLogin(@RequestParam String token) {
|
||||
SsoLoginUserinfo loginUserinfo = Ab98ApiUtil.getLoginUserInfoRemote("wxshop", "34164e41f0c6694be6bbbba0dc50c14a", token, "");
|
||||
|
||||
Ab98ApiUtil.LoginData data = new Ab98ApiUtil.LoginData();
|
||||
if (loginUserinfo == null) {
|
||||
return ResponseDTO.fail(new ApiException(ErrorCode.FAILED, "登录失败,请重新尝试"));
|
||||
}
|
||||
data.setFace_img(loginUserinfo.getFace());
|
||||
data.setSuccess(true);
|
||||
data.setSex(loginUserinfo.getSex());
|
||||
data.setName(loginUserinfo.getName());
|
||||
data.setUserid(String.valueOf(loginUserinfo.getId()));
|
||||
data.setRegistered(true);
|
||||
data.setTel(loginUserinfo.getPhone());
|
||||
|
||||
return ResponseDTO.ok(data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.agileboot.api.response;
|
|||
|
||||
|
||||
import com.agileboot.domain.shop.category.dto.ShopCategoryDTO;
|
||||
import com.agileboot.domain.shop.goods.db.SearchGoodsWithCabinetDO;
|
||||
import com.agileboot.domain.shop.goods.db.ShopGoodsEntity;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
@ -10,7 +11,7 @@ import lombok.Data;
|
|||
@Data
|
||||
@AllArgsConstructor
|
||||
public class ShopGoodsResponse {
|
||||
private List<ShopGoodsEntity> goodsList;
|
||||
private List<SearchGoodsWithCabinetDO> goodsList;
|
||||
private List<ShopCategoryDTO> categoryList;
|
||||
private String res;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
package com.agileboot.domain.ab98.api;
|
||||
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -22,9 +26,6 @@ public class Ab98ApiUtil {
|
|||
* 发送短信验证码(短信登录)
|
||||
* @param token 通过getToken获取的临时令牌(有效期5分钟)
|
||||
* @param tel 接收验证码的手机号码(需符合格式:11位数字)
|
||||
* @param nobind "true"表示不绑定手机号(固定值)
|
||||
* @param for_login "true"表示用于登录(固定值)
|
||||
* @param from 来源渠道(固定值"jt")
|
||||
*/
|
||||
public static SmsSendResponse sendLoginSms(String token, String tel) {
|
||||
String url = BASE_URL + "?code=doSendSms";
|
||||
|
@ -146,6 +147,38 @@ public class Ab98ApiUtil {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户信息
|
||||
* @param appname
|
||||
* @param appsecret
|
||||
* @param token
|
||||
* @param companyName
|
||||
* @return
|
||||
*/
|
||||
public static SsoLoginUserinfo getLoginUserInfoRemote(String appname,
|
||||
String appsecret,
|
||||
String token,
|
||||
String companyName) {
|
||||
String sign = DigestUtils.md5Hex(String.format("app=%s&token=%s%s", appname, token, appsecret));
|
||||
String url = String.format("https://www.ab98.cn/api/getLoginUserInfo?token=%s&app=%s&company_name=%s&sign=%s"
|
||||
,token
|
||||
,appname
|
||||
,""
|
||||
,sign);
|
||||
|
||||
String res = HttpUtil.get(url);
|
||||
try {
|
||||
JSONObject o = JSONUtil.parseObj(res);
|
||||
String state = o.getStr("state");
|
||||
if (StringUtils.equalsIgnoreCase(state, "ok")) {
|
||||
return o.get("data", SsoLoginUserinfo.class);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("获取登录用户信息失败", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 基础响应对象
|
||||
@Data
|
||||
public static class BaseResponse {
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package com.agileboot.domain.ab98.api;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class SsoLoginUserinfo {
|
||||
private Long id;
|
||||
/**
|
||||
* 缓存失效时间戳(秒)
|
||||
*/
|
||||
private Integer expire;
|
||||
/**
|
||||
* 账号状态状态:1-正常 2-冻结
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 姓名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 性别
|
||||
*/
|
||||
private String sex;
|
||||
/**
|
||||
* 手机号码
|
||||
*/
|
||||
private String phone;
|
||||
/**
|
||||
* 微信昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 微信openid
|
||||
*/
|
||||
private String openId;
|
||||
/**
|
||||
* 微信unionId
|
||||
*/
|
||||
private String unionId;
|
||||
/**
|
||||
* 微信头像
|
||||
*/
|
||||
private String headImage;
|
||||
/**
|
||||
* 人脸图像
|
||||
*/
|
||||
private String face;
|
||||
/**
|
||||
* 身份证号码
|
||||
*/
|
||||
private String idCardNo;
|
||||
/**
|
||||
* 身份证正面
|
||||
*/
|
||||
private String idCardFront;
|
||||
/**
|
||||
* 身份证背面
|
||||
*/
|
||||
private String idCardBack;
|
||||
/**
|
||||
* 身份证地址
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 原登录账号
|
||||
*/
|
||||
private String oldAccount;
|
||||
|
||||
}
|
|
@ -10,6 +10,8 @@ import com.agileboot.domain.cabinet.cell.dto.CabinetCellDTO;
|
|||
import com.agileboot.domain.cabinet.cell.model.CabinetCellModel;
|
||||
import com.agileboot.domain.cabinet.cell.model.CabinetCellModelFactory;
|
||||
import com.agileboot.domain.cabinet.cell.query.SearchCabinetCellQuery;
|
||||
import com.agileboot.domain.shop.goods.db.ShopGoodsEntity;
|
||||
import com.agileboot.domain.shop.goods.db.ShopGoodsService;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -24,11 +26,25 @@ import org.springframework.web.bind.annotation.PathVariable;
|
|||
public class CabinetCellApplicationService {
|
||||
private final CabinetCellService cabinetCellService;
|
||||
private final CabinetCellModelFactory cabinetCellModelFactory;
|
||||
private final ShopGoodsService shopGoodsService;
|
||||
|
||||
public PageDTO<CabinetCellDTO> getCabinetCellList(SearchCabinetCellQuery<CabinetCellEntity> query) {
|
||||
Page<CabinetCellEntity> page = cabinetCellService.getCellList(query);
|
||||
List<ShopGoodsEntity> goodsList = shopGoodsService.selectAll();
|
||||
List<CabinetCellDTO> dtoList = page.getRecords().stream()
|
||||
.map(CabinetCellDTO::new)
|
||||
.map(cell -> {
|
||||
CabinetCellDTO dto = new CabinetCellDTO(cell);
|
||||
ShopGoodsEntity goods = goodsList.stream()
|
||||
.filter(g -> g.getGoodsId().equals(cell.getGoodsId()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (goods != null) {
|
||||
dto.setGoodsName(goods.getGoodsName());
|
||||
dto.setPrice(goods.getPrice());
|
||||
dto.setCoverImg(goods.getCoverImg());
|
||||
}
|
||||
return dto;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
return new PageDTO<>(dtoList, page.getTotal());
|
||||
}
|
||||
|
@ -67,4 +83,12 @@ public class CabinetCellApplicationService {
|
|||
model.setUsageStatus(2);
|
||||
model.updateById();
|
||||
}
|
||||
|
||||
public void configureGoodsCellsStock(Long cellId, Long goodsId, Integer stock) {
|
||||
CabinetCellModel model = cabinetCellModelFactory.loadById(cellId);
|
||||
model.setGoodsId(goodsId);
|
||||
model.setStock(stock);
|
||||
model.setUsageStatus(2);
|
||||
model.updateById();
|
||||
}
|
||||
}
|
|
@ -43,6 +43,10 @@ public class CabinetCellEntity extends BaseEntity<CabinetCellEntity> {
|
|||
@TableField("pin_no")
|
||||
private Integer pinNo;
|
||||
|
||||
@ApiModelProperty("库存数量")
|
||||
@TableField("stock")
|
||||
private Integer stock;
|
||||
|
||||
@ApiModelProperty("格口类型(1小格 2中格 3大格 4超大格)")
|
||||
@TableField("cell_type")
|
||||
private Integer cellType;
|
||||
|
|
|
@ -8,6 +8,8 @@ import com.agileboot.domain.cabinet.cell.db.CabinetCellEntity;
|
|||
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@ExcelSheet(name = "柜机格口信息列表")
|
||||
@Data
|
||||
public class CabinetCellDTO {
|
||||
|
@ -35,6 +37,9 @@ public class CabinetCellDTO {
|
|||
@ExcelColumn(name = "针脚序号")
|
||||
private Integer pinNo;
|
||||
|
||||
@ExcelColumn(name = "库存数量")
|
||||
private Integer stock;
|
||||
|
||||
@ExcelColumn(name = "格口类型")
|
||||
private Integer cellType;
|
||||
|
||||
|
@ -47,6 +52,13 @@ public class CabinetCellDTO {
|
|||
@ExcelColumn(name = "关联商品ID")
|
||||
private Long goodsId;
|
||||
|
||||
@ExcelColumn(name = "商品名称")
|
||||
private String goodsName;
|
||||
@ExcelColumn(name = "商品价格")
|
||||
private BigDecimal price;
|
||||
@ExcelColumn(name = "封面图URL")
|
||||
private String coverImg;
|
||||
|
||||
@ExcelColumn(name = "操作人")
|
||||
private String operator;
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ public class SearchCabinetCellQuery<T> extends AbstractPageQuery<T> {
|
|||
.eq(cellType != null, "cell_type", cellType)
|
||||
.eq(usageStatus != null, "usage_status", usageStatus)
|
||||
.eq(availableStatus != null, "available_status", availableStatus)
|
||||
.eq("deleted", false)
|
||||
.between(startTime != null && endTime != null, "create_time", startTime, endTime);
|
||||
|
||||
this.timeRangeColumn = "create_time";
|
||||
|
|
|
@ -25,6 +25,7 @@ public class SearchSmartCabinetQuery<T> extends AbstractPageQuery<T> {
|
|||
.like(StrUtil.isNotEmpty(cabinetName), "cabinet_name", cabinetName)
|
||||
.eq(cabinetType != null, "cabinet_type", cabinetType)
|
||||
.eq(StrUtil.isNotEmpty(templateNo), "template_no", templateNo)
|
||||
.eq("deleted", false)
|
||||
.between(startTime != null && endTime != null, "create_time", startTime, endTime);
|
||||
|
||||
this.timeRangeColumn = "create_time";
|
||||
|
|
|
@ -13,10 +13,14 @@ import org.eclipse.paho.client.mqttv3.*;
|
|||
@RequiredArgsConstructor
|
||||
public class MqttService implements MqttCallback {
|
||||
private static final String SERVER_URL = "tcp://221.7.159.46:1883";
|
||||
private static final String USERNAME = "lock";
|
||||
private static final String PASSWORD = "lock@ys#6785$";
|
||||
private static final String TOPIC_FILTER = "lock/up/S4202414S";
|
||||
private static final String TOPIC = "lock/down/S4202414S";
|
||||
// private static final String USERNAME = "lock";
|
||||
// private static final String PASSWORD = "lock@ys#6785$";
|
||||
// private static final String TOPIC_FILTER = "lock/up/S4202414S";
|
||||
// private static final String TOPIC = "lock/down/S4202414S";
|
||||
private static final String USERNAME = "sell";
|
||||
private static final String PASSWORD = "sell@ys#6785$";
|
||||
private static final String TOPIC_FILTER = "lock/up/S5200184S";
|
||||
private static final String TOPIC = "lock/down/S5200184S";
|
||||
|
||||
private MqttClient client;
|
||||
// 设置自定义消息处理器
|
||||
|
|
|
@ -29,7 +29,7 @@ public class QywxApiUtil {
|
|||
* @return 消息发送结果
|
||||
*/
|
||||
public static NewsMessageResponse sendNewsMessage(String accessToken, Integer agentId, String toUser, String toparty, String totag, List<NewsArticle> articles) {
|
||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken + "&debug=" + 1;
|
||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken;
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("touser", toUser);
|
||||
|
|
|
@ -31,4 +31,16 @@ public interface QyUserMapper extends BaseMapper<QyUserEntity> {
|
|||
"AND deleted = 0")
|
||||
QyUserEntity selectByUserid(@Param("userid") String userid, @Param("corpid") String corpid);
|
||||
|
||||
@Select("SELECT DISTINCT qu.userid " +
|
||||
"FROM qy_user qu " +
|
||||
"LEFT JOIN sys_user_qy_user suqy ON qu.id = suqy.qy_user_id " +
|
||||
"LEFT JOIN sys_user su ON suqy.sys_user_id = su.user_id " +
|
||||
"LEFT JOIN sys_role sr ON su.role_id = sr.role_id " +
|
||||
"WHERE qu.deleted = 0 " +
|
||||
"AND suqy.deleted = 0 " +
|
||||
"AND su.deleted = 0 " +
|
||||
"AND sr.deleted = 0 " +
|
||||
"AND sr.role_key = 'admin'")
|
||||
List<String> selectAdminUserIds();
|
||||
|
||||
}
|
||||
|
|
|
@ -20,4 +20,6 @@ public interface QyUserService extends IService<QyUserEntity> {
|
|||
List<QyUserEntity> selectAll();
|
||||
|
||||
QyUserEntity getUserByUserId(String userid, String corpid);
|
||||
|
||||
List<String> selectAdminUserIds();
|
||||
}
|
||||
|
|
|
@ -38,4 +38,9 @@ public class QyUserServiceImpl extends ServiceImpl<QyUserMapper, QyUserEntity> i
|
|||
public QyUserEntity getUserByUserId(String userid, String corpid) {
|
||||
return baseMapper.selectByUserid(userid, corpid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> selectAdminUserIds() {
|
||||
return baseMapper.selectAdminUserIds();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.agileboot.domain.qywx.api.QywxApiUtil;
|
|||
import com.agileboot.domain.qywx.api.response.NewsArticle;
|
||||
import com.agileboot.domain.qywx.authCorpInfo.AuthCorpInfoApplicationService;
|
||||
import com.agileboot.domain.qywx.authCorpInfo.db.QyAuthCorpInfoEntity;
|
||||
import com.agileboot.domain.qywx.user.db.QyUserService;
|
||||
import com.agileboot.domain.shop.approval.command.AddReturnApprovalCommand;
|
||||
import com.agileboot.domain.shop.approval.command.UpdateReturnApprovalCommand;
|
||||
import com.agileboot.domain.shop.approval.db.ReturnApprovalEntity;
|
||||
|
@ -57,6 +58,7 @@ public class ReturnApprovalApplicationService {
|
|||
private final GoodsModelFactory goodsModelFactory;
|
||||
private final AuthCorpInfoApplicationService authCorpInfoApplicationService;
|
||||
private final AccessTokenApplicationService accessTokenApplicationService;
|
||||
private final QyUserService qyUserService;
|
||||
|
||||
/**
|
||||
* 获取退货审批列表
|
||||
|
@ -203,8 +205,9 @@ public class ReturnApprovalApplicationService {
|
|||
.filter(a -> "wpZ1ZrEgAA2QTxIRcB4cMtY7hQbTcPAw".equals(a.getCorpid()))
|
||||
.findFirst().orElse(null);
|
||||
QyAccessTokenEntity accessToken = accessTokenApplicationService.getByAppid(appid, authCorpInfo.getCorpid());
|
||||
// TODO 获取用户ID
|
||||
String toUser = "woZ1ZrEgAAV9AEdRt1MGQxSg-KDJrDlA|woZ1ZrEgAAoFQl9vWHMj4PkFoSc8FR8w";
|
||||
// 获取用户ID
|
||||
List<String> adminUserIds = qyUserService.selectAdminUserIds();
|
||||
String toUser = String.join("|", adminUserIds);
|
||||
String toparty = "";
|
||||
String totag = "";
|
||||
List<NewsArticle> articles = new ArrayList<>();
|
||||
|
|
|
@ -84,6 +84,21 @@ public class ReturnApprovalEntity extends BaseEntity<ReturnApprovalEntity> {
|
|||
@TableField(exist = false)
|
||||
private String coverImg;
|
||||
|
||||
@ApiModelProperty("手机号码")
|
||||
@TableField(exist = false)
|
||||
private String mobile;
|
||||
|
||||
@ApiModelProperty("企业微信用户ID或汇邦云用户ID")
|
||||
@TableField(exist = false)
|
||||
private String userid;
|
||||
|
||||
@ApiModelProperty("用户姓名")
|
||||
@TableField(exist = false)
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("是否内部用户(0否 1汇邦云用户 2企业微信用户)")
|
||||
@TableField(exist = false)
|
||||
private Integer isInternal;
|
||||
|
||||
@Override
|
||||
public Serializable pkVal() {
|
||||
|
|
|
@ -18,9 +18,11 @@ import org.apache.ibatis.annotations.Select;
|
|||
*/
|
||||
public interface ReturnApprovalMapper extends BaseMapper<ReturnApprovalEntity> {
|
||||
|
||||
@Select("SELECT ra.*, sog.goods_name AS goodsName, sog.cover_img AS coverImg " +
|
||||
@Select("SELECT ra.*, sog.goods_name AS goodsName, sog.cover_img AS coverImg, " +
|
||||
"so.mobile, so.userid, so.name, so.is_internal AS isInternal " +
|
||||
"FROM return_approval ra " +
|
||||
"LEFT JOIN shop_order_goods sog ON ra.order_goods_id = sog.order_goods_id " +
|
||||
"LEFT JOIN shop_order so ON ra.order_id = so.order_id AND so.deleted = 0 " +
|
||||
"LEFT JOIN shop_order_goods sog ON ra.order_goods_id = sog.order_goods_id AND sog.deleted = 0 " +
|
||||
"${ew.customSqlSegment}")
|
||||
Page<ReturnApprovalEntity> selectApprovalWithGoodsInfo(Page<ReturnApprovalEntity> page,
|
||||
@Param(Constants.WRAPPER) Wrapper<ReturnApprovalEntity> queryWrapper);
|
||||
|
|
|
@ -6,9 +6,11 @@ import com.agileboot.common.annotation.ExcelSheet;
|
|||
import com.agileboot.domain.shop.category.db.ShopCategoryEntity;
|
||||
import java.util.Date;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@ExcelSheet(name = "商品分类列表")
|
||||
@Data
|
||||
@EqualsAndHashCode(of = {"categoryId", "categoryName"})
|
||||
public class ShopCategoryDTO {
|
||||
|
||||
public ShopCategoryDTO(ShopCategoryEntity entity) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.agileboot.domain.common.command.BulkOperationCommand;
|
|||
import com.agileboot.domain.shop.goods.command.AddGoodsCommand;
|
||||
import com.agileboot.domain.shop.goods.command.UpdateGoodsCommand;
|
||||
import com.agileboot.domain.shop.goods.db.SearchGoodsDO;
|
||||
import com.agileboot.domain.shop.goods.db.SearchGoodsWithCabinetDO;
|
||||
import com.agileboot.domain.shop.goods.db.ShopGoodsEntity;
|
||||
import com.agileboot.domain.shop.goods.db.ShopGoodsService;
|
||||
import com.agileboot.domain.shop.goods.dto.ShopGoodsDTO;
|
||||
|
@ -59,4 +60,9 @@ public class GoodsApplicationService {
|
|||
public List<ShopGoodsEntity> getGoodsAll(){
|
||||
return shopGoodsService.selectAll();
|
||||
}
|
||||
|
||||
|
||||
public List<SearchGoodsWithCabinetDO> getGoodsWithCabinetList() {
|
||||
return shopGoodsService.getGoodsWithCabinetList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,4 +18,6 @@ public class SearchGoodsDO extends ShopGoodsEntity {
|
|||
private String cabinetName;
|
||||
@TableField("cell_no")
|
||||
private Integer cellNo;
|
||||
@TableField("total_stock")
|
||||
private Integer totalStock;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package com.agileboot.domain.shop.goods.db;
|
||||
|
||||
import com.agileboot.common.core.base.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.math.BigDecimal;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("shop_goods")
|
||||
public class SearchGoodsWithCabinetDO extends BaseEntity<SearchGoodsWithCabinetDO> {
|
||||
|
||||
private Long goodsId;
|
||||
private String goodsName;
|
||||
private Long categoryId;
|
||||
private BigDecimal price;
|
||||
private Integer stock;
|
||||
private Integer status;
|
||||
private String coverImg;
|
||||
private String goodsDetail;
|
||||
private String remark;
|
||||
|
||||
@TableField("sc.cabinet_id")
|
||||
private Long cabinetId;
|
||||
|
||||
@TableField("sc.cabinet_name")
|
||||
private String cabinetName;
|
||||
|
||||
@TableField("cc.cell_id")
|
||||
private Long cellId;
|
||||
}
|
|
@ -23,7 +23,7 @@ public interface ShopGoodsMapper extends BaseMapper<ShopGoodsEntity> {
|
|||
* @param queryWrapper 查询条件
|
||||
* @return 商品分页列表
|
||||
*/
|
||||
@Select("SELECT g.goods_id, g.goods_name, g.category_id, g.price, " +
|
||||
/* @Select("SELECT g.goods_id, g.goods_name, g.category_id, g.price, " +
|
||||
"g.stock, g.status, g.cover_img, c.category_name, " +
|
||||
"sc.cabinet_id, sc.cabinet_name, cc.cell_no " +
|
||||
"FROM shop_goods g " +
|
||||
|
@ -34,6 +34,19 @@ public interface ShopGoodsMapper extends BaseMapper<ShopGoodsEntity> {
|
|||
Page<SearchGoodsDO> getGoodsList(
|
||||
Page<SearchGoodsDO> page,
|
||||
@Param(Constants.WRAPPER) Wrapper<SearchGoodsDO> queryWrapper
|
||||
); */
|
||||
@Select("SELECT g.goods_id, g.goods_name, g.category_id, g.price, " +
|
||||
"g.stock, g.status, g.cover_img, SUM(cc.stock) AS total_stock, " +
|
||||
"GROUP_CONCAT(DISTINCT cc.cell_no) AS cell_no, " +
|
||||
"GROUP_CONCAT(DISTINCT sc.cabinet_name) AS cabinet_name " +
|
||||
"FROM shop_goods g " +
|
||||
"LEFT JOIN cabinet_cell cc ON g.goods_id = cc.goods_id AND cc.deleted = 0 " +
|
||||
"LEFT JOIN smart_cabinet sc ON cc.cabinet_id = sc.cabinet_id AND sc.deleted = 0 " +
|
||||
"${ew.customSqlSegment} " +
|
||||
"GROUP BY g.goods_id")
|
||||
Page<SearchGoodsDO> getGoodsList(
|
||||
Page<SearchGoodsDO> page,
|
||||
@Param(Constants.WRAPPER) Wrapper<SearchGoodsDO> queryWrapper
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -45,4 +58,15 @@ public interface ShopGoodsMapper extends BaseMapper<ShopGoodsEntity> {
|
|||
"WHERE deleted = 0 " +
|
||||
"ORDER BY create_time DESC")
|
||||
List<ShopGoodsEntity> selectAll();
|
||||
|
||||
/**
|
||||
* 查询商品及其关联的柜机格口信息
|
||||
* @return 商品列表
|
||||
*/
|
||||
@Select("SELECT g.*, sc.cabinet_id, sc.cabinet_name, cc.cell_id " +
|
||||
"FROM shop_goods g " +
|
||||
"LEFT JOIN cabinet_cell cc ON g.goods_id = cc.goods_id " +
|
||||
"LEFT JOIN smart_cabinet sc ON cc.cabinet_id = sc.cabinet_id " +
|
||||
"WHERE g.deleted = 0 AND sc.deleted = 0 AND cc.deleted = 0 AND cc.goods_id IS NOT NULL ")
|
||||
List<SearchGoodsWithCabinetDO> getGoodsWithCabinetList();
|
||||
}
|
||||
|
|
|
@ -17,4 +17,6 @@ public interface ShopGoodsService extends IService<ShopGoodsEntity> {
|
|||
Page<SearchGoodsDO> getGoodsList(AbstractPageQuery<SearchGoodsDO> query);
|
||||
|
||||
List<ShopGoodsEntity> selectAll();
|
||||
|
||||
List<SearchGoodsWithCabinetDO> getGoodsWithCabinetList();
|
||||
}
|
||||
|
|
|
@ -29,4 +29,9 @@ public class ShopGoodsServiceImpl extends ServiceImpl<ShopGoodsMapper, ShopGoods
|
|||
public List<ShopGoodsEntity> selectAll() {
|
||||
return baseMapper.selectAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SearchGoodsWithCabinetDO> getGoodsWithCabinetList() {
|
||||
return baseMapper.getGoodsWithCabinetList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,9 @@ public class ShopGoodsDTO {
|
|||
public ShopGoodsDTO(ShopGoodsEntity entity) {
|
||||
if (entity != null) {
|
||||
BeanUtil.copyProperties(entity, this);
|
||||
|
||||
if (this.getTotalStock() == null) {
|
||||
this.setTotalStock(0);
|
||||
}
|
||||
/* ShopCategoryEntity category = CacheCenter.categoryCache.get(entity.getCategoryId() + "");
|
||||
if (category != null) {
|
||||
this.categoryName = category.getCategoryName();
|
||||
|
@ -77,4 +79,6 @@ public class ShopGoodsDTO {
|
|||
private String cabinetName;
|
||||
@ExcelColumn(name = "格口号")
|
||||
private Integer cellNo;
|
||||
@ExcelColumn(name = "已分配库存")
|
||||
private Integer totalStock;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public class SearchShopGoodsQuery<T> extends AbstractPageQuery<T> {
|
|||
|
||||
queryWrapper
|
||||
.like(StrUtil.isNotEmpty(goodsName), "g.goods_name", goodsName)
|
||||
.eq(categoryId != null, "g.category_id", categoryId)
|
||||
.eq(categoryId != null, "cc.cabinet_id", categoryId)
|
||||
.eq(status != null, "g.status", status)
|
||||
.ge(minPrice != null, "g.price", minPrice)
|
||||
.le(maxPrice != null, "g.price", maxPrice)
|
||||
|
|
|
@ -72,34 +72,28 @@ public class OrderApplicationService {
|
|||
if (orderModel.getStatus() != 2) {
|
||||
throw new ApiException(ErrorCode.Client.COMMON_FORBIDDEN_TO_CALL, "订单状态不允许操作");
|
||||
}
|
||||
Date payTime = orderModel.getPayTime();
|
||||
if (payTime == null)
|
||||
payTime = orderModel.getCreateTime();
|
||||
// 验证payTime是否在24小时内
|
||||
if (DateUtil.offsetHour(payTime, 24).before(new Date())) {
|
||||
throw new ApiException(ErrorCode.Client.COMMON_FORBIDDEN_TO_CALL, "订单支付时间超过24小时,不允许操作");
|
||||
}
|
||||
|
||||
// 获取并验证订单商品信息
|
||||
ShopOrderGoodsEntity goodsEntity = orderGoodsService.getById(orderGoodsId);
|
||||
if (null == goodsEntity || !orderId.equals(goodsEntity.getOrderId())) {
|
||||
throw new ApiException(ErrorCode.Client.COMMON_FORBIDDEN_TO_CALL, "订单商品不存在");
|
||||
}
|
||||
if (goodsEntity.getStatus() != 1) {
|
||||
if (goodsEntity.getStatus() != 1 && goodsEntity.getStatus()!= 5) {
|
||||
throw new ApiException(ErrorCode.Client.COMMON_FORBIDDEN_TO_CALL, "订单商品状态不允许操作");
|
||||
}
|
||||
|
||||
List<CabinetCellEntity> cabinetCellEntityList = cabinetCellService.selectByGoodsId(goodsEntity.getGoodsId());
|
||||
if (null == cabinetCellEntityList || cabinetCellEntityList.isEmpty()) {
|
||||
throw new ApiException(ErrorCode.Client.COMMON_FORBIDDEN_TO_CALL, "商品未绑定柜子");
|
||||
if (goodsEntity.getCellId() == null) {
|
||||
throw new ApiException(ErrorCode.Client.COMMON_FORBIDDEN_TO_CALL, "订单商品未绑定柜子");
|
||||
}
|
||||
CabinetCellEntity cabinetCellEntity = cabinetCellEntityList.get(0);
|
||||
|
||||
// 获取柜子单元和智能柜信息
|
||||
CabinetCellEntity cabinetCellEntity = cabinetCellService.getById(goodsEntity.getCellId());
|
||||
SmartCabinetEntity smartCabinet = smartCabinetService.getById(cabinetCellEntity.getCabinetId());
|
||||
if (null == smartCabinet) {
|
||||
throw new ApiException(ErrorCode.Client.COMMON_FORBIDDEN_TO_CALL, "柜子不存在");
|
||||
}
|
||||
|
||||
// 发送指令
|
||||
// 构造MQTT开柜指令:
|
||||
// 指令格式:8A + 锁控编号(2位HEX) + 引脚号(2位HEX) + 操作码11
|
||||
String mqttDate = "8A";
|
||||
mqttDate += String.format("%02X", smartCabinet.getLockControlNo());
|
||||
mqttDate += String.format("%02X", cabinetCellEntity.getPinNo());
|
||||
|
@ -131,6 +125,7 @@ public class OrderApplicationService {
|
|||
orderModel.setMobile(command.getMobile());
|
||||
orderModel.setIsInternal(command.getIsInternal());
|
||||
orderModel.setUserid(command.getQyUserid());
|
||||
orderModel.setName(command.getName());
|
||||
orderModel.insert();
|
||||
|
||||
processOrderGoods(orderModel, goodsList);
|
||||
|
|
|
@ -31,6 +31,9 @@ public class SubmitOrderCommand {
|
|||
@ApiModelProperty("企业微信用户ID或汇邦云用户ID")
|
||||
private String qyUserid;
|
||||
|
||||
@ApiModelProperty("用户姓名")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("是否内部订单 0否 1汇邦云用户 2企业微信用户")
|
||||
private Integer isInternal;
|
||||
}
|
|
@ -53,6 +53,10 @@ public class ShopOrderEntity extends BaseEntity<ShopOrderEntity> {
|
|||
@TableField("userid")
|
||||
private String userid;
|
||||
|
||||
@ApiModelProperty("用户姓名")
|
||||
@TableField("name")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("是否内部用户(0否 1汇邦云用户 2企业微信用户)")
|
||||
@TableField("is_internal")
|
||||
private Integer isInternal;
|
||||
|
|
|
@ -40,6 +40,10 @@ public class ShopOrderGoodsEntity extends BaseEntity<ShopOrderGoodsEntity> {
|
|||
@TableField("goods_id")
|
||||
private Long goodsId;
|
||||
|
||||
@ApiModelProperty("关联格口ID")
|
||||
@TableField("cell_id")
|
||||
private Long cellId;
|
||||
|
||||
@ApiModelProperty("购买数量")
|
||||
@TableField("quantity")
|
||||
private Integer quantity;
|
||||
|
|
|
@ -25,6 +25,7 @@ CREATE TABLE `cabinet_cell` (
|
|||
`goods_id` BIGINT DEFAULT NULL COMMENT '关联商品ID',
|
||||
`cell_no` INT NOT NULL COMMENT '格口号',
|
||||
`pin_no` INT NOT NULL COMMENT '针脚序号',
|
||||
`stock` INT NOT NULL DEFAULT 0 COMMENT '库存数量',
|
||||
`cell_type` TINYINT NOT NULL DEFAULT 1 COMMENT '格口类型(1小格 2中格 3大格 4超大格)',
|
||||
`usage_status` TINYINT NOT NULL DEFAULT 1 COMMENT '使用状态(1空闲 2已占用)',
|
||||
`available_status` TINYINT NOT NULL DEFAULT 1 COMMENT '可用状态(1正常 2故障)',
|
||||
|
|
|
@ -66,3 +66,9 @@ ADD COLUMN `is_internal` TINYINT(1) DEFAULT 0 COMMENT '是否内部用户(0否
|
|||
|
||||
ALTER TABLE `shop_order`
|
||||
ADD COLUMN `userid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '企业微信用户ID或汇邦云用户ID' AFTER `mobile`;
|
||||
|
||||
ALTER TABLE `shop_order`
|
||||
ADD COLUMN `name` varchar(30) DEFAULT NULL COMMENT '成员名称' AFTER `mobile`;
|
||||
|
||||
ALTER TABLE `shop_order_goods`
|
||||
ADD COLUMN `cell_id` BIGINT NULL COMMENT '格口ID' AFTER `goods_id`;
|
Loading…
Reference in New Issue