天天看點

儲存修改前後的資料曆史記錄

我公司最近要我開發銷售退貨/款單,其中就有編輯退貨款時需要儲存修改資料的曆史記錄。我也是一個新入職場的小白,研究了一上午終于解決了,若有不對的地方麻煩私聊找我。要求如圖所示:

儲存修改前後的資料曆史記錄

下面是我解決問題的代碼:

主要代碼

/**
     * 比較修改前後銷售退款單
     *
     * @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(比較修改前後銷售退款單)方法

最後直接調用

儲存修改前後的資料曆史記錄

儲存結果:

儲存修改前後的資料曆史記錄