Merge remote-tracking branch 'origin/main'

This commit is contained in:
attiya 2025-05-27 15:41:04 +08:00
commit 3c7a39f7ba
14 changed files with 353 additions and 94 deletions

View File

@ -24,12 +24,26 @@ public class GeoCodingUtil {
private final static String LOCATION_TO_ADDRESS = "regeo";
private final static String ADDRESS_TO_LOCATION = "geo";
private final static String STATUS_KEY = "status";
private final static String LONGITUDE_KEY = "lng";
private final static String LATITUDE_KEY = "lat";
// 结果键 高德地图webservice 为geocodesregeocode腾讯地图webservice为result
private final static String ADDRESS_RESULT_KEY = "regeocode";
private final static String LOCATION_RESULT_KEY = "geocodes";
//private final static String RESULT_KEY = "geocodes";
// 成功状态码 高德地图webservice 为1腾讯地图webservice为0
private final static int CODE_STATUS_SUCCESS = 1;
// 地址键 高德地图webservice 为formatted_address腾讯地图webservice为formatted_addresses-->standard_address
//private final static String ADDRESS_KEY = "formatted_addresses";
private final static String ADDRESS_KEY = "formatted_address";
private final static String STANDARD_ADDRESS_KEY = "standard_address";
// 位置键 高德地图webservice 为location腾讯地图webservice为location
private final static String LOCATION_KEY = "location";
// 地址详情键 高德地图webservice 为addressComponent腾讯地图webservice为ad_info
private final static String ADDRESS_COMPONENT_KEY = "addressComponent";
private final static String DISTRICT_KEY = "district";
private final static String ADCODE_KEY = "adcode";
private final static String MSG_KEY = "message";
private final String url;
private final String accessKey;
@ -55,8 +69,10 @@ public class GeoCodingUtil {
* @return 地址
*/
public String getLocationToAddress(JSONObject location) {
//String locationStr = String.format("%f,%f", location.getDouble(LATITUDE_KEY), location.getDouble(LONGITUDE_KEY));
String locationStr = String.format("%f,%f", location.getDouble(LONGITUDE_KEY), location.getDouble(LATITUDE_KEY));
Request request = new Request.Builder()
.url(url + "/"+LOCATION_TO_ADDRESS + "?"+"location=" + String.format("%f,%f", location.getDouble("lng"), location.getDouble("lat")) + "&key=" + accessKey)
.url(url + "/"+LOCATION_TO_ADDRESS + "?"+"location=" + locationStr + "&key=" + accessKey)
.build();
try(Response response = client.newCall(request).execute()) {
if(response.isSuccessful()) {
@ -64,10 +80,10 @@ public class GeoCodingUtil {
String result = response.body().string();
JSONObject jsonObject = JSONObject.parseObject(result);
if (jsonObject.getInteger(STATUS_KEY) == CODE_STATUS_SUCCESS) {
//return jsonObject.getJSONObject(RESULT_KEY).getJSONObject("formatted_addresses").getString("standard_address");
return jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getString("formatted_address");
//return jsonObject.getJSONObject(RESULT_KEY).getJSONObject(ADDRESS_KEY).getString(STANDARD_ADDRESS_KEY);
return jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getString(ADDRESS_KEY);
}
logError("地址解析失败==>{}", jsonObject.getString("message"));
logError("地址解析失败==>{}", jsonObject.getString(MSG_KEY));
return null;
}
logError("地址解析失败==>{}", response.message());
@ -88,8 +104,10 @@ public class GeoCodingUtil {
* @return 地址
*/
public JSONObject getLocationToAddressDetails(JSONObject location) {
//String locationStr = String.format("%f,%f", location.getDouble(LATITUDE_KEY), location.getDouble(LONGITUDE_KEY));
String locationStr = String.format("%f,%f", location.getDouble(LONGITUDE_KEY), location.getDouble(LATITUDE_KEY));
Request request = new Request.Builder()
.url(url + "/"+LOCATION_TO_ADDRESS + "?location=" + String.format("%f,%f", location.getDouble("lng"), location.getDouble("lat")) + "&key=" + accessKey)
.url(url + "/"+LOCATION_TO_ADDRESS + "?location=" + locationStr + "&key=" + accessKey)
.build();
try(Response response = client.newCall(request).execute()) {
if(response.isSuccessful()) {
@ -98,18 +116,18 @@ public class GeoCodingUtil {
JSONObject jsonObject = JSONObject.parseObject(result);
if (jsonObject.getInteger(STATUS_KEY) == CODE_STATUS_SUCCESS) {
JSONObject address = new JSONObject();
//String detail = jsonObject.getJSONObject("result").getJSONObject("formatted_addresses").getString("standard_address");
String detail = jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getString("formatted_address");
//String detail = jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getJSONObject(ADDRESS_KEY).getString(STANDARD_ADDRESS_KEY);
String detail = jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getString(ADDRESS_KEY);
address.put("detail", detail);
//String district = jsonObject.getJSONObject("result").getJSONObject("ad_info").getString("district");
String district = jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getJSONObject("addressComponent").getString("district");
//String district = jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getJSONObject(ADDRESS_COMPONENT_KEY).getString(DISTRICT_KEY);
String district = jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getJSONObject(ADDRESS_COMPONENT_KEY).getString(DISTRICT_KEY);
address.put("district", district);
//String adcode = jsonObject.getJSONObject("result").getJSONObject("ad_info").getString("adcode");
String adcode = jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getJSONObject("addressComponent").getString("adcode");
//String adcode = jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getJSONObject(ADDRESS_COMPONENT_KEY).getString(ADCODE_KEY);
String adcode = jsonObject.getJSONObject(ADDRESS_RESULT_KEY).getJSONObject(ADDRESS_COMPONENT_KEY).getString(ADCODE_KEY);
address.put("adcode", adcode);
return address;
}
logError("地址解析失败==>{}", jsonObject.getString("message"));
logError("地址解析失败==>{}", jsonObject.getString(MSG_KEY));
return null;
}
logError("地址解析失败==>{}", response.message());
@ -139,15 +157,16 @@ public class GeoCodingUtil {
String result = response.body().string();
JSONObject jsonObject = JSONObject.parseObject(result);
if (jsonObject.getInteger(STATUS_KEY) == CODE_STATUS_SUCCESS) {
//return jsonObject.getJSONObject(LOCATION_RESULT_KEY).getJSONObject("location");
String loc = jsonObject.getJSONArray(LOCATION_RESULT_KEY).getJSONObject(0).getString("location");
// 腾讯地图webservice的位置是 JSONObject {"lat": 39.9042, "lng": 116.4074}
//return jsonObject.getJSONObject(LOCATION_RESULT_KEY).getJSONObject(LOCATION_KEY);
String loc = jsonObject.getJSONArray(LOCATION_RESULT_KEY).getJSONObject(0).getString(LOCATION_KEY);
String[] locArr = loc.split(",");
JSONObject location = new JSONObject();
location.put("lng", Double.valueOf(locArr[0]));
location.put("lat", Double.valueOf(locArr[1]));
return location;
}else{
logError("位置解析失败==>{}", jsonObject.getString("message"));
logError("位置解析失败==>{}", jsonObject.getString(MSG_KEY));
return null;
}
}else{

View File

@ -3,16 +3,21 @@ package com.cdzy.ebikeoperate.controller;
import com.cdzy.common.model.JsonResult;
import com.cdzy.ebikeoperate.mapper.EbikeEcuEnterRecordsMapper;
import com.cdzy.ebikeoperate.model.dto.request.*;
import com.cdzy.ebikeoperate.model.dto.response.ResComponentOutRecordInfoDto;
import com.cdzy.ebikeoperate.model.pojo.EbikeEcuEnterRecords;
import com.cdzy.ebikeoperate.model.pojo.EbikeEcuOutRecords;
import com.cdzy.ebikeoperate.model.pojo.EbikeHelmetEnterRecords;
import com.cdzy.ebikeoperate.service.EbikeBikeQrcodeService;
import com.cdzy.ebikeoperate.service.EbikeComponentService;
import com.mybatisflex.core.paginate.Page;
import jakarta.validation.constraints.Null;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import java.util.Objects;
/**
* 车辆部件的相关接口
@ -42,7 +47,7 @@ public class EbikeComponentController {
* @return
*/
@GetMapping("/invalidateDevicePart")
public JsonResult<?> invalidateDevicePart(@RequestParam(name="componentEnterRecordId")String componentEnterRecordId) {
public JsonResult<?> invalidateDevicePart(@RequestParam(name="componentEnterRecordId")@NotNull String componentEnterRecordId) {
return ebikeComponentService.invalidateDevicePart(componentEnterRecordId);
}
/**
@ -51,7 +56,7 @@ public class EbikeComponentController {
* @return
*/
@GetMapping("/cancelDevicePart")
public JsonResult<?> cancelDevicePart(@RequestParam(name = "componentEnterRecordId") String componentEnterRecordId) {
public JsonResult<?> cancelDevicePart(@RequestParam(name = "componentEnterRecordId")@NotNull String componentEnterRecordId) {
return ebikeComponentService.cancelDevicePart(componentEnterRecordId);
}
@ -71,7 +76,7 @@ public class EbikeComponentController {
* @return
*/
@GetMapping("/cancelOutDevicePart")
public JsonResult<?> cancelOutDevicePart(@RequestParam(name = "componentOutRecordId") String componentOutRecordId) {
public JsonResult<?> cancelOutDevicePart(@RequestParam(name = "componentOutRecordId")@NotNull String componentOutRecordId) {
return ebikeComponentService.cancelOutDevicePart(componentOutRecordId);
}
/**
@ -80,7 +85,7 @@ public class EbikeComponentController {
* @return
*/
@GetMapping("/invalidateOutDevicePart")
public JsonResult<?> invalidateOutDevicePart(@RequestParam(name="componentOutRecordId")String componentOutRecordId) {
public JsonResult<?> invalidateOutDevicePart(@RequestParam(name="componentOutRecordId")@NotNull String componentOutRecordId) {
return ebikeComponentService.invalidateOutDevicePart(componentOutRecordId);
}
@ -107,4 +112,14 @@ public class EbikeComponentController {
Page<EbikeEcuOutRecords> pageRecords = ebikeComponentService.ecuOutList(reqEbikeEcuOutRecordsDto);
return JsonResult.success(pageRecords);
}
/**
* 根据部件出库记录表主键查询部件出库记录信息以及归还部件信息
*
* @param componentOutRecordId 部件出库记录ID
* @return ResComponentOutRecordInfoDto
*/
@GetMapping("/getComponentOutRecordInfo")
public JsonResult<?> getComponentOutRecordInfo(@RequestParam(name="componentOutRecordId") @NotNull String componentOutRecordId) {
return ebikeComponentService.getComponentOutRecordInfo(componentOutRecordId);
}
}

View File

@ -164,14 +164,15 @@ public class EbikeOperateSystemInfoController {
/**
* 生成二维码 (png图像base64串)
* @param content 二维码内容
* @param text 打印文字内容
* @return
*/
@PostMapping("ebikeQrCodeGenerate")
public JsonResult<?> ebikeQrGenerate(@RequestParam(name = "content") String content) {
public JsonResult<?> ebikeQrGenerate(@RequestParam(name = "content") String content, @RequestParam(name = "text") String text) {
if (content == null || content.isEmpty()) {
return JsonResult.failed("二维码内容不能为空");
}
return JsonResult.success(QRGenUtil.generateQRCodeBase64(content));
return JsonResult.success(QRGenUtil.generateQRCodeBase64(content, text));
}
/**

View File

@ -30,6 +30,11 @@ public class ReqComponentEnterRecordDto {
*/
private String owningRegion;
/**
* 关联出库记录Id 表示归还记录
*/
private String componentOutRecordId;
/**
* 部件类型ID表示部件的类别如电池ECU等部件的编号
*/
@ -45,6 +50,10 @@ public class ReqComponentEnterRecordDto {
*/
private Integer stockInType;
/**
* 单价
*/
private Double componentPrice;
/**
* 中控信息列表包含所有ECU部件的入库记录
*/

View File

@ -24,7 +24,7 @@ public class ReqComponentOutRecordDto {
private String componentOutRecordId;
/**
* 所属区域表示设备部件库的区域
* 所属区域表示设备部件库的区域
*/
private String owningRegion;
@ -47,22 +47,22 @@ public class ReqComponentOutRecordDto {
*/
private Integer enterQuantity;
/**
* 入库类型0或空 表示暂存1 表示
* 入库类型0或空 表示暂存1 表示
*/
private Integer stockInType;
/**
* 中控信息列表包含所有ECU部件的库记录
* 中控信息列表包含所有ECU部件的库记录
*/
private List<EbikeEcuOutRecords> ebikeEcuOutRecords;
/**
* 头盔信息列表包含所有头盔部件的库记录
* 头盔信息列表包含所有头盔部件的库记录
*/
private List<EbikeHelmetOutRecords> ebikeHelmetOutRecords;
/**
* 电池信息列表包含所有电池部件的库记录
* 电池信息列表包含所有电池部件的库记录
*/
private List<EbikeBatteryOutRecords> ebikeBatteryOutRecords;
}

View File

@ -0,0 +1,74 @@
package com.cdzy.ebikeoperate.model.dto.response;
import com.cdzy.ebikeoperate.model.pojo.*;
import com.mybatisflex.annotation.Id;
import lombok.Data;
import java.util.List;
@Data
public class ResComponentOutRecordInfoDto {
/**
* ID
*/
@Id
private String componentOutRecordId;
/**
* 组织id运营商id
*/
private Long orgId;
/**
* 所属区域
*/
private String owningRegion;
/**
* 部件类型
*/
private String componentType;
/**
* 出库数量
*/
private Integer outQuantity;
/**
* 状态
*/
private String state;
/**
* 原部件处理方案
*/
private String oldComponentHandleOption;
/**
* 中控信息列表包含所有ECU部件的出库记录
*/
private List<EbikeEcuOutRecords> ebikeEcuOutRecords;
/**
* 头盔信息列表包含所有头盔部件的出库记录
*/
private List<EbikeHelmetOutRecords> ebikeHelmetOutRecords;
/**
* 电池信息列表包含所有电池部件的出库记录
*/
private List<EbikeBatteryOutRecords> ebikeBatteryOutRecords;
/**
* 中控信息列表包含所有ECU部件的归还记录
*/
private List<EbikeEcuEnterRecords> ebikeEcuEnterRecords;
/**
* 头盔信息列表包含所有头盔部件的归还记录
*/
private List<EbikeHelmetEnterRecords> ebikeHelmetEnterRecords;
/**
* 电池信息列表包含所有电池部件的归还记录
*/
private List<EbikeBatteryEnterRecords> ebikeBatteryEnterRecords;
}

View File

@ -41,6 +41,10 @@ public class EbikeComponentEnterRecords implements Serializable {
*/
private Long orgId;
/**
* 关联出库记录Id 表示归还记录
*/
private String componentOutRecordId;
/**
* 所属区域
*/

View File

@ -1,5 +1,6 @@
package com.cdzy.ebikeoperate.model.pojo;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
@ -57,7 +58,8 @@ public class EbikeComponentInventorycount implements Serializable {
/**
* 部件数量
*/
private Integer count;
@Column(onInsertValue = "0")
private long itemCount;
/**
* 单位

View File

@ -2,6 +2,7 @@ package com.cdzy.ebikeoperate.service;
import com.cdzy.common.model.JsonResult;
import com.cdzy.ebikeoperate.model.dto.request.*;
import com.cdzy.ebikeoperate.model.dto.response.ResComponentOutRecordInfoDto;
import com.cdzy.ebikeoperate.model.pojo.EbikeEcuEnterRecords;
import com.cdzy.ebikeoperate.model.pojo.EbikeEcuOutRecords;
import com.cdzy.ebikeoperate.model.pojo.EbikeHelmetEnterRecords;
@ -74,4 +75,11 @@ public interface EbikeComponentService {
*/
Page<EbikeEcuOutRecords> ecuOutList(ReqEbikeEcuOutRecordsDto reqEbikeEcuOutRecordsDto);
/**
* 根据部件出库记录表主键查询部件出库记录信息以及归还部件信息
*
* @param componentOutRecordId 部件出库记录ID
* @return ResComponentOutRecordInfoDto
*/
JsonResult<?> getComponentOutRecordInfo(String componentOutRecordId);
}

View File

@ -6,6 +6,7 @@ import com.cdzy.common.model.JsonResult;
import com.cdzy.ebikeoperate.enums.ComponentType;
import com.cdzy.ebikeoperate.mapper.*;
import com.cdzy.ebikeoperate.model.dto.request.*;
import com.cdzy.ebikeoperate.model.dto.response.ResComponentOutRecordInfoDto;
import com.cdzy.ebikeoperate.model.pojo.*;
import com.cdzy.ebikeoperate.service.EbikeComponentService;
import com.ebike.feign.clients.StaffFeignClient;
@ -13,12 +14,14 @@ import com.ebike.feign.model.rsp.StaffFeign;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import static com.cdzy.ebikeoperate.model.pojo.table.EbikeEcuEnterRecordsTableDef.EBIKE_ECU_ENTER_RECORDS;
import static com.cdzy.ebikeoperate.model.pojo.table.EbikeEcuOutRecordsTableDef.EBIKE_ECU_OUT_RECORDS;
@ -76,7 +79,6 @@ public class EbikeComponentServiceImpl implements EbikeComponentService {
String userId = getStaffId(); // 获取当前操作用户ID
Long orgId = getOrgId(); // 获取当前操作用户所在组织ID
EbikeComponentTypeInfo ebikeComponentTypeInfo = getComponentTypeInfo(params.getComponentType()); // 获取部件信息
// 获取或新增部件记录
EbikeComponentEnterRecords ebikeComponentEnterRecords = buildEnterRecord(params, ebikeComponentTypeInfo, stockInType, orgId);
saveOrUpdateEnterRecord(ebikeComponentEnterRecords, params.getComponentEnterRecordId(), userId);
@ -108,6 +110,13 @@ public class EbikeComponentServiceImpl implements EbikeComponentService {
updateInventoryCount(ebikeComponentTypeInfo, orgId, enterQuantity, 1);
}
}
String componentOutRecordId = params.getComponentOutRecordId();
if(componentOutRecordId != null && !componentOutRecordId.isEmpty()){
// 更新出库记录状态为 已归还
EbikeComponentOutRecords ebikeComponentOutRecords = ebikeComponentOutRecordsMapper.selectOneById(componentOutRecordId);
ebikeComponentOutRecords.setState("2");
ebikeComponentOutRecordsMapper.update(ebikeComponentOutRecords);
}
return JsonResult.success("", componentEnterRecordId);
}
@ -143,7 +152,9 @@ public class EbikeComponentServiceImpl implements EbikeComponentService {
ebikeComponentEnterRecords.setOrgId(orgId);
ebikeComponentEnterRecords.setComponentType(params.getComponentType());
ebikeComponentEnterRecords.setEnterQuantity(params.getEnterQuantity());
ebikeComponentEnterRecords.setComponentPrice(ebikeComponentTypeInfo.getPrice());
ebikeComponentEnterRecords.setComponentOutRecordId(params.getComponentOutRecordId());
// ebikeComponentEnterRecords.setComponentPrice(ebikeComponentTypeInfo.getPrice());
ebikeComponentEnterRecords.setComponentPrice(params.getComponentPrice());
ebikeComponentEnterRecords.setState(stockInType == 1 ? "1" : "0"); // 暂存为 0 入库为1
return ebikeComponentEnterRecords;
}
@ -232,9 +243,9 @@ public class EbikeComponentServiceImpl implements EbikeComponentService {
//入库记录更新数量 type 1 入库 2 出库
private void updateInventoryCount(EbikeComponentTypeInfo ebikeComponentTypeInfo, Long orgId, int size, Integer type) {
QueryWrapper query1 = new QueryWrapper();
query1.eq("code", ebikeComponentTypeInfo.getId());
EbikeComponentInventorycount ebikeComponentInventorycount = ebikeComponentInventorycountMapper.selectOneByQuery(query1);
QueryWrapper query = new QueryWrapper();
query.eq("code", ebikeComponentTypeInfo.getId());
EbikeComponentInventorycount ebikeComponentInventorycount = ebikeComponentInventorycountMapper.selectOneByQuery(query);
if (ebikeComponentInventorycount == null) {
ebikeComponentInventorycount = new EbikeComponentInventorycount();
ebikeComponentInventorycount.setOrgId(orgId);
@ -243,13 +254,13 @@ public class EbikeComponentServiceImpl implements EbikeComponentService {
ebikeComponentInventorycount.setBrand(ebikeComponentTypeInfo.getBrand());
ebikeComponentInventorycount.setUnit(ebikeComponentTypeInfo.getUnit());
ebikeComponentInventorycount.setPrice(ebikeComponentTypeInfo.getPrice());
ebikeComponentInventorycount.setCount(size);
ebikeComponentInventorycount.setItemCount(size);
ebikeComponentInventorycountMapper.insert(ebikeComponentInventorycount);
} else {
if (type == 1) {//入库
ebikeComponentInventorycount.setCount(ebikeComponentInventorycount.getCount() + size);
ebikeComponentInventorycount.setItemCount(ebikeComponentInventorycount.getItemCount() + size);
} else {//出库
ebikeComponentInventorycount.setCount(ebikeComponentInventorycount.getCount() - size);
ebikeComponentInventorycount.setItemCount(ebikeComponentInventorycount.getItemCount() - size);
}
ebikeComponentInventorycountMapper.update(ebikeComponentInventorycount);
}
@ -366,7 +377,7 @@ public class EbikeComponentServiceImpl implements EbikeComponentService {
query1.eq("code", componentType);
EbikeComponentInventorycount ebikeComponentInventorycount = ebikeComponentInventorycountMapper.selectOneByQuery(query1);
if (ebikeComponentInventorycount != null) {
ebikeComponentInventorycount.setCount(ebikeComponentInventorycount.getCount() - size);
ebikeComponentInventorycount.setItemCount(ebikeComponentInventorycount.getItemCount() - size);
ebikeComponentInventorycountMapper.update(ebikeComponentInventorycount);
}
}
@ -383,7 +394,7 @@ public class EbikeComponentServiceImpl implements EbikeComponentService {
query1.eq("code", componentType);
EbikeComponentInventorycount ebikeComponentInventorycount = ebikeComponentInventorycountMapper.selectOneByQuery(query1);
if (ebikeComponentInventorycount != null) {
ebikeComponentInventorycount.setCount(ebikeComponentInventorycount.getCount() + size);
ebikeComponentInventorycount.setItemCount(ebikeComponentInventorycount.getItemCount() + size);
ebikeComponentInventorycountMapper.update(ebikeComponentInventorycount);
}
}
@ -405,16 +416,20 @@ public class EbikeComponentServiceImpl implements EbikeComponentService {
/**
* 验证仓库数量是否足够
*/
Integer outQuantity = params.getOutQuantity();//选择的出库数量
//查看仓库剩余部件数量
Integer outQuantity = params.getOutQuantity(); // 选择的出库数量
// 查看仓库剩余部件数量
QueryWrapper query = new QueryWrapper();
query.eq("code", params.getComponentType());
EbikeComponentInventorycount ebikeComponentInventorycount = ebikeComponentInventorycountMapper.selectOneByQuery(query);
Integer count = ebikeComponentInventorycount.getCount();
String name = ebikeComponentInventorycount.getName();
// String brand = ebikeComponentInventorycount.getBrand();
if (count < outQuantity) {
return JsonResult.failed(String.format("%s 的库存数量不足!剩余数量:%s", name, count));
// 如果查询结果为空返回错误信息
if (ebikeComponentInventorycount == null) {
return JsonResult.failed("未找到相应的部件库存信息");
}
long count = ebikeComponentInventorycount.getItemCount(); // 获取剩余数量
String name = ebikeComponentInventorycount.getName(); // 获取部件名称
// 判断库存是否足够
if (stockInType == 1 && count < outQuantity) {
return JsonResult.failed(String.format("%s 的库存数量不足!剩余数量:%d", name, count));
}
// 获取或新增部件记录
EbikeComponentOutRecords ebikeComponentOutRecords = buildOutRecord(params, ebikeComponentTypeInfo, stockInType, orgId);
@ -422,19 +437,19 @@ public class EbikeComponentServiceImpl implements EbikeComponentService {
String componentOutRecordId = ebikeComponentOutRecords.getComponentOutRecordId();
if (params.getEbikeEcuOutRecords().size() > 0) {
if (params.getEbikeEcuOutRecords()!=null && !params.getEbikeEcuOutRecords().isEmpty()) {
// 删除原有的ECU入库记录并保存新的记录
deleteAndInsertEcuOutRecords(componentOutRecordId, params.getEbikeEcuOutRecords(), stockInType, ebikeComponentTypeInfo, userId, orgId);
if (stockInType == 1) {
updateInventoryCount(ebikeComponentTypeInfo, orgId, params.getEbikeEcuOutRecords().size(), 2);
}
} else if (params.getEbikeBatteryOutRecords().size() > 0) {
} else if (params.getEbikeBatteryOutRecords()!=null && !params.getEbikeBatteryOutRecords().isEmpty()) {
// 删除原有的电池入库记录并保存新的记录
deleteAndInsertBatteryOutRecords(componentOutRecordId, params.getEbikeBatteryOutRecords(), stockInType, ebikeComponentTypeInfo, userId, orgId);
if (stockInType == 1) {
updateInventoryCount(ebikeComponentTypeInfo, orgId, params.getEbikeBatteryOutRecords().size(), 2);
}
} else if (params.getEbikeHelmetOutRecords().size() > 0) {
} else if (params.getEbikeHelmetOutRecords()!=null && !params.getEbikeHelmetOutRecords().isEmpty()) {
// 删除原有的头盔入库记录并保存新的记录
deleteAndInsertHelmetOutRecords(componentOutRecordId, params.getEbikeHelmetOutRecords(), stockInType, ebikeComponentTypeInfo, userId, orgId);
if (stockInType == 1) {
@ -469,7 +484,7 @@ public class EbikeComponentServiceImpl implements EbikeComponentService {
ebikeComponentOutRecordsMapper.insert(ebikeComponentOutRecords);
} else { // 编辑或新增
QueryWrapper query = new QueryWrapper();
query.eq("component_enter_record_id", componentEnterRecordId);
query.eq("component_out_record_id", componentEnterRecordId);
long count = ebikeComponentOutRecordsMapper.selectCountByQuery(query);
if (count > 0) {
ebikeComponentOutRecords.setComponentOutRecordId(componentEnterRecordId);
@ -631,18 +646,6 @@ public class EbikeComponentServiceImpl implements EbikeComponentService {
int size = ebikeEcuOutRecords.size();
updateOtherOutComponentStock(componentType, size);
}
public StaffFeign getStaffFeignInfo() {
String tokenValue = StpUtil.getTokenValue();
// 调用 Feign 客户端获取用户信息
JsonResult<StaffFeign> result = staffFeignClient.getInfoByToken(tokenValue);
// 判断返回码若失败则抛出异常
if (result.getCode() != Code.SUCCESS) {
throw new RuntimeException("获取用户信息失败");
}
// 返回获取到的 StaffFeign 数据
return result.getData();
}
/**
* 分页查询Ecu入库记录
*
@ -673,6 +676,97 @@ public class EbikeComponentServiceImpl implements EbikeComponentService {
Page<EbikeEcuOutRecords> page = reqEbikeEcuOutRecordsDto.getPageParam().getPage();
return ebikeEcuOutRecordsMapper.paginate(page, query);
}
/**
* 根据部件出库记录表主键查询部件出库记录信息以及归还部件信息
*
* @param componentOutRecordId 部件出库记录ID
* @return ResComponentOutRecordInfoDto
*/
@Override
public JsonResult<?> getComponentOutRecordInfo(String componentOutRecordId) {
// 创建查询条件
QueryWrapper query = new QueryWrapper();
query.eq("component_out_record_id", componentOutRecordId);
// 获取出库记录
EbikeComponentOutRecords ebikeComponentOutRecords = ebikeComponentOutRecordsMapper.selectOneByQuery(query);
if (ebikeComponentOutRecords == null) {
return JsonResult.failed("记录未找到");
}
// 将出库记录的属性复制到返回的DTO中
ResComponentOutRecordInfoDto resComponentOutRecordInfoDto = new ResComponentOutRecordInfoDto();
BeanUtils.copyProperties(ebikeComponentOutRecords, resComponentOutRecordInfoDto);
// 根据组件类型填充对应的出库记录
ComponentType componentTypeEnum = ComponentType.fromCode(ebikeComponentOutRecords.getComponentType());
populateOutRecords(resComponentOutRecordInfoDto, query, componentTypeEnum);
// 查询是否存在归还记录如果存在则填充归还记录
EbikeComponentEnterRecords ebikeComponentEnterRecords = ebikeComponentEnterRecordsMapper.selectOneByQuery(query);
if (ebikeComponentEnterRecords != null) {
populateEnterRecords(resComponentOutRecordInfoDto, ebikeComponentEnterRecords);
}
return JsonResult.success(resComponentOutRecordInfoDto);
}
// 根据组件类型填充出库记录
private void populateOutRecords(ResComponentOutRecordInfoDto dto, QueryWrapper query, ComponentType componentTypeEnum) {
switch (componentTypeEnum) {
case BATTERY: // 电池
List<EbikeBatteryOutRecords> batteryOutRecords = ebikeBatteryOutRecordsMapper.selectListWithRelationsByQuery(query);
dto.setEbikeBatteryOutRecords(batteryOutRecords);
break;
case HELMET: // 头盔
List<EbikeHelmetOutRecords> helmetOutRecords = ebikeHelmetOutRecordsMapper.selectListWithRelationsByQuery(query);
dto.setEbikeHelmetOutRecords(helmetOutRecords);
break;
case ECU: // 中控
List<EbikeEcuOutRecords> ecuOutRecords = ebikeEcuOutRecordsMapper.selectListWithRelationsByQuery(query);
dto.setEbikeEcuOutRecords(ecuOutRecords);
break;
default:
break;
}
}
// 根据归还记录填充相应的归还记录
private void populateEnterRecords(ResComponentOutRecordInfoDto dto, EbikeComponentEnterRecords enterRecords) {
QueryWrapper query = new QueryWrapper();
query.eq("component_enter_record_id", enterRecords.getComponentEnterRecordId());
// 获取归还记录对应的组件类型
ComponentType componentTypeEnumEnter = ComponentType.fromCode(enterRecords.getComponentType());
switch (componentTypeEnumEnter) {
case BATTERY: // 电池
List<EbikeBatteryEnterRecords> batteryEnterRecords = ebikeBatteryEnterRecordsMapper.selectListWithRelationsByQuery(query);
dto.setEbikeBatteryEnterRecords(batteryEnterRecords);
break;
case HELMET: // 头盔
List<EbikeHelmetEnterRecords> helmetEnterRecords = ebikeHelmetEnterRecordsMapper.selectListWithRelationsByQuery(query);
dto.setEbikeHelmetEnterRecords(helmetEnterRecords);
break;
case ECU: // 中控
List<EbikeEcuEnterRecords> ecuEnterRecords = ebikeEcuEnterRecordsMapper.selectListWithRelationsByQuery(query);
dto.setEbikeEcuEnterRecords(ecuEnterRecords);
break;
default:
break;
}
}
public StaffFeign getStaffFeignInfo() {
String tokenValue = StpUtil.getTokenValue();
// 调用 Feign 客户端获取用户信息
JsonResult<StaffFeign> result = staffFeignClient.getInfoByToken(tokenValue);
// 判断返回码若失败则抛出异常
if (result.getCode() != Code.SUCCESS) {
throw new RuntimeException("获取用户信息失败");
}
// 返回获取到的 StaffFeign 数据
return result.getData();
}
}

View File

@ -4,6 +4,10 @@ import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import net.glxn.qrgen.core.image.ImageType;
import net.glxn.qrgen.javase.QRCode;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
@ -18,17 +22,52 @@ public class QRGenUtil {
/**
* 生成二维码并返回Base64编码
* <p>增加内容文字
*
* @param content 二维码内容
* @param text 文字内容
* @return Base64编码的二维码
*/
public static String generateQRCodeBase64(String content) {
try (ByteArrayOutputStream stream = QRCode.from(content)
.withSize(300, 300) // 尺寸
public static String generateQRCodeBase64(String content, String text) {
// 1. 生成基础二维码
try (ByteArrayOutputStream qrStream = QRCode.from(content)
.withSize(300, 300)
.withCharset("UTF-8")
.withErrorCorrection(ErrorCorrectionLevel.H) // 纠错等级H为最高
.to(ImageType.PNG) // 输出格式
.stream()) {
if(text == null || text.isEmpty()){
return Base64.getEncoder().encodeToString(qrStream.toByteArray());
}
// 2. 将二维码转换为 BufferedImage
ByteArrayInputStream inputStream = new ByteArrayInputStream(qrStream.toByteArray());
BufferedImage qrImage = ImageIO.read(inputStream);
// 3. 创建新 BufferedImage 并绘制文字
BufferedImage finalImage = new BufferedImage(
qrImage.getWidth(), qrImage.getHeight()+ 20, // 增加文字区域高度,
BufferedImage.TYPE_INT_ARGB
);
Graphics2D g2d = finalImage.createGraphics();
g2d.drawImage(qrImage, 0, 0, null);
// 设置文字样式
g2d.setFont(new Font("Arial", Font.BOLD, 20));
g2d.setColor(Color.BLACK);
// 计算文字位置底部居中
int textWidth = g2d.getFontMetrics().stringWidth(text);
int x = (qrImage.getWidth() - textWidth) / 2;
int y = qrImage.getHeight() - 2; // 底部留白
// 添加文字说明
g2d.drawString(text, x, y);
g2d.dispose();
// 使用 Java 8+ Base64 编码避免自动换行问题
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ImageIO.write(finalImage, "PNG", stream);
return Base64.getEncoder().encodeToString(stream.toByteArray());
} catch (Exception e) {
throw new RuntimeException("生成二维码失败", e);
@ -36,7 +75,7 @@ public class QRGenUtil {
}
//public static void main(String[] args) {
// String content = "B726500590095"; // 二维码内容
// String content = "B72650"; // 二维码内容
// String base64 = generateQRCodeBase64(content);
// System.out.println("Base64 二维码: " + base64);
//}

View File

@ -19,12 +19,13 @@ import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "wechat")
public class WechatConfig {
private String url;
/**
* 微信小程序 appId
*/
private String appId;
/**
* 微信小程序 appSecret
*/
private String appSecret;
@Bean
public WechatUtil wechatUtil() {
return new WechatUtil(url, appId, appSecret);
}
}

View File

@ -1,10 +1,10 @@
package com.cdzy.orders.uitls;
import com.alibaba.fastjson2.JSONObject;
import com.cdzy.orders.config.WechatConfig;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.stereotype.Service;
@ -12,9 +12,9 @@ import org.springframework.stereotype.Service;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.security.*;
import java.util.Base64;
/**
@ -27,24 +27,25 @@ import java.util.Base64;
@Slf4j
@Service
public class WechatUtil {
/**
* 微信登录API地址
*/
private static final String WECHAT_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";
private static String url;
private static String appId;
private static String appSecret;
/**
* OkHttpClient实例
*/
private static OkHttpClient client = null;
@Resource
private WechatConfig wechatConfig;
/**
* 微信工具类构造函数
*
* @param apiUrl 微信登录API地址
* @param appId 微信小程序ID
* @param appSecret 微信小程序密钥
*/
public WechatUtil(String apiUrl, String appId, String appSecret) {
this.url = apiUrl;
this.appId = appId;
this.appSecret = appSecret;
this.client = new OkHttpClient();
public WechatUtil() throws IOException {
client = new OkHttpClient();
}
/**
@ -55,7 +56,7 @@ public class WechatUtil {
*/
public JSONObject wechatAuthority(String code){
Request request = new Request.Builder()
.url(url + "?appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code")
.url(WECHAT_LOGIN_URL + "?appid=" + wechatConfig.getAppId() + "&secret=" + wechatConfig.getAppSecret() + "&js_code=" + code + "&grant_type=authorization_code")
.build();
try(Response response = client.newCall(request).execute()) {
if(response.isSuccessful()) {
@ -108,11 +109,4 @@ public class WechatUtil {
}
}
//public static void main(String[] args) {
// String encryptedData = "eXzeeTDZZVYGXr1YfFxI3Z7ntaEzuFQ5DHNSSB1OEGaN4s1gxBv8/o2YIRKnyghvaCXhs+BuRZlM1mqbw/4Q+hAA9Zb0E+hzipuTHuVNEFrq7SwUZbb7WUgmrtD+9vAf/8XdHkXzs+Krybh/a7Pa7QnKx82Z1HQvP+I4cWVIhBJrhqFQX0TP2XuJ8OTliBEE+MnxGylvpqDzXxVPRA4CAQ==";
// String sessionkey = "6bWACSG9u15Lv2YI9B5IKw==";
// String iv = "PeEtJMMfPStNH0Pd61DB0A==";
// String result = decryptData(encryptedData, sessionkey, iv);
// System.out.println(result);
//}
}

View File

@ -85,7 +85,6 @@ sa-token:
# 是否输出操作日志
is-log: true
wechat:
url: https://api.weixin.qq.com/sns/jscode2session
appid: wx327d788d7bd6eddf
app-secret: adf2539a6c26499c67b5a3829f2e05e3
minio: