我公司最近要我開發銷售退貨/款單,其中就有編輯退貨款時需要儲存修改資料的曆史記錄。我也是一個新入職場的小白,研究了一上午終于解決了,若有不對的地方麻煩私聊找我。要求如圖所示:
下面是我解決問題的代碼:
主要代碼
/**
* 比較修改前後銷售退款單
*
* @param oldBean 修改前資料
* @param newBean 修改後資料
* @param saleSn
* @param <T>
* @return
*/
public static <T> List<WpOrderSaleReturnRecord> updateLog(Object oldBean, Object newBean, String saleSn) {
List<WpOrderSaleReturnRecord> recordList = new ArrayList<>();
StringBuilder str = new StringBuilder();
T pojo1 = (T) oldBean;
T pojo2 = (T) newBean;
try {
// 通過反射擷取類的類類型及字段屬性
Class clazz = pojo1.getClass();
Field[] fields = clazz.getDeclaredFields();
int i = 1;
for (Field field : fields) {
// 排除序列化屬性
if ("serialVersionUID".equals(field.getName())) {
continue;
}
//1、擷取屬性上的指定類型的注解
Annotation annotation = field.getAnnotation(XmlElement.class);
//有該類型的注解存在
if (annotation != null) {
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
// 擷取對應屬性值
Method getMethod = pd.getReadMethod();
Object o1 = getMethod.invoke(pojo1);
Object o2 = getMethod.invoke(pojo2);
if (o1 == null || o2 == null) {
continue;
}
//bigDecimal 類型的資料要去掉小數點後尾部的0不一緻造成資料比對差異
String type = field.getType().getName();
if(type.equals("java.math.BigDecimal") && o1!=null && o2!=null ) {
BigDecimal val_old_big = new BigDecimal(String.valueOf(o1));
BigDecimal val_new_big = new BigDecimal(String.valueOf(o2));
if (String.valueOf(val_old_big).indexOf(".") != -1 || String.valueOf(val_new_big).indexOf(".") != -1) {//由于無法擷取精度值,隻能對所有帶小數點的資料進行處理
DecimalFormat formatter1 = new DecimalFormat("0.00");
o1 = formatter1.format(val_old_big);
o2 = formatter1.format(val_new_big);
}
}
if (!o1.toString().equals(o2.toString())) {
//強制轉化為相應的注解
XmlElement xmlElement = (XmlElement) annotation;
WpOrderSaleReturnRecord record = new WpOrderSaleReturnRecord();
record.setSaleSn(saleSn);
if (xmlElement.name().equals("商品數量")) {
for (Field field1 : fields) {
if (field1.getName().equals("goodsName")) {
PropertyDescriptor pd1 = new PropertyDescriptor(field1.getName(), clazz);
// 擷取對應屬性值
Method getMethod1 = pd1.getReadMethod();
Object goodsName = getMethod1.invoke(pojo1);
record.setAlterContent(goodsName + ",申請退貨數量");
}
}
} else {
record.setAlterContent(xmlElement.name());
}
record.setAlterBefore(o1.toString());
record.setAlterAfter(o2.toString());
SaveSaleReturnRecord updateLogUtil = new SaveSaleReturnRecord();
updateLogUtil.saveOrderSaleReturnRecord(record, 2);
str.append(i + "、字段名稱:" + xmlElement.name() + ",舊值:" + o1 + ",新值:" + o2 + ";");
i++;
}
}
}
} catch (Exception e) {
logger.error("異常:" + e.getMessage());
e.printStackTrace();
}
logger.info("修改對象内容結果:==========>" + str.toString());
return recordList;
}
其中這指定類型的注解是不可缺少的,如果不寫這注解後面編輯時的變更内容則為字段名稱
注解代碼示例:
将擷取到的資料儲存到資料庫
@Autowired
WpOrderSaleReturnRecordMapper wpOrderSaleReturnRecordMapper;
public static SaveSaleReturnRecord saveSaleReturnRecord;
@PostConstruct
public void init() {
saveSaleReturnRecord = this;
saveSaleReturnRecord.wpOrderSaleReturnRecordMapper = this.wpOrderSaleReturnRecordMapper;
}
以上此段代碼是因為我這裡擷取不到dao層,你們可忽略此段代碼
/**
* 儲存銷售退款單據記錄
*
* @param records
* @param type 1.新增,2.編輯,3.稽核通過,4.稽核不通過,5.删除
*/
@Transactional("no2TransactionManager")
public void saveOrderSaleReturnRecord(WpOrderSaleReturnRecord records, Integer type) {
//type:1.新增,2.編輯,3.稽核通過,4.稽核不通過,5.删除
switch (type) {
case 1:
records.setOperationType("新增");
records.setAlterContent("新增單據");
break;
case 2:
records.setOperationType("編輯");
break;
case 3:
records.setOperationType("稽核");
records.setAlterContent("稽核通過");
break;
case 4:
records.setOperationType("稽核");
records.setAlterContent("稽核拒絕");
break;
case 5:
records.setOperationType("删除");
records.setAlterContent("删除單據");
break;
}
records.setCreateTime(new Date().getTime()); //操作時間
records.setOperationPerson(UserUtil.getUser().getId().toString());//操作人
saveSaleReturnRecord.wpOrderSaleReturnRecordMapper.insertSelective(records);
}
因為我們的業務中銷售退貨/款一對多了退款商品表,是以我這裡特地将退款商品拆分出來重新調用updateLog 方法
/**
* 訂單退款商品
*
* @param oldGoods 舊的退款商品
* @param newGoods 新的退款商品
*/
public static void returnGoods(String oldGoods, String newGoods, String saleSn) {
Gson gson = new Gson();
//String字元串類型轉list
String refundGoodsOld = oldGoods.substring(oldGoods.indexOf("["), oldGoods.lastIndexOf("}"));
List<WpOrderGoods> oldRefundGoodsList = gson.fromJson(refundGoodsOld,
new TypeToken<List<WpOrderGoods>>() {
}.getType());
//String字元串類型轉list
String refundGoodsNew = newGoods.substring(newGoods.indexOf("["), newGoods.lastIndexOf("}"));
List<WpOrderGoods> newRefundGoodsList = gson.fromJson(refundGoodsNew,
new TypeToken<List<WpOrderGoods>>() {
}.getType());
for (WpOrderGoods newOrderGoods : newRefundGoodsList) { //新
List<Integer> oldGoodsId = new ArrayList<>();
for (WpOrderGoods oldOrderGoods : oldRefundGoodsList) { //舊
if (oldOrderGoods.getId().equals(newOrderGoods.getId())) {
updateLog(oldOrderGoods, newOrderGoods, saleSn);
}
oldGoodsId.add(oldOrderGoods.getId());
}
//判斷就退款商品id是否含于新退款商品id,
// 如不含于 此條新退款商品資料判斷為新增加的退款商品
if (oldGoodsId.contains(newOrderGoods.getId()) == false) {
WpOrderSaleReturnRecord record = new WpOrderSaleReturnRecord();
record.setAlterContent(newOrderGoods.getGoodsName() + ",新增退款商品");
record.setSaleSn(saleSn);
SaveSaleReturnRecord updateLogUtil = new SaveSaleReturnRecord();
updateLogUtil.saveOrderSaleReturnRecord(record, 2);
}
}
}
ps:對于新增,删除,稽核的單據直接儲存銷售退款單據記錄(saveOrderSaleReturnRecord)就好,無需調用updateLog(比較修改前後銷售退款單)方法
最後直接調用
儲存結果: