增加导入附件的查看记录
This commit is contained in:
+2
-2
@@ -165,8 +165,8 @@ public class TabOrderMonitorController extends BaseController
|
||||
int fail = data.get("fail") instanceof Number ? ((Number) data.get("fail")).intValue() : 0;
|
||||
String action = rows.size() == 1 ? "ONE" : "SELECTED";
|
||||
String bizId = firstOrderBizId(rows, action);
|
||||
String status = fail > 0 && ok == 0 ? "FAIL" : "SUCCESS";
|
||||
String err = fail > 0 ? ("fail=" + fail) : null;
|
||||
String status = fail > 0 ? "FAIL" : "SUCCESS";
|
||||
String err = fail > 0 ? ("fail=" + fail + ", ok=" + ok) : null;
|
||||
TabOrderSyncEsLog.save(billSearchStore, bizId, action, rows, data, status, err);
|
||||
return success(data);
|
||||
}
|
||||
|
||||
+49
-1
@@ -1,5 +1,6 @@
|
||||
package com.bms.web.controller.price;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -25,8 +26,11 @@ import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.DateUtils;
|
||||
import com.bms.common.utils.MessageUtils;
|
||||
import com.bms.common.utils.SecurityUtils;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.system.domain.BmsBizAttachment;
|
||||
import com.bms.system.service.IBmsBizAttachmentService;
|
||||
import com.bms.price.domain.BatchAddIncomeBillFeeTask;
|
||||
import com.bms.price.domain.ChargeWeightImportTask;
|
||||
import com.bms.price.domain.PrcBillingTask;
|
||||
@@ -66,6 +70,9 @@ public class BillingController extends BaseController
|
||||
@Autowired
|
||||
private IPrcBillingTaskService prcBillingTaskService;
|
||||
|
||||
@Autowired
|
||||
private IBmsBizAttachmentService bizAttachmentService;
|
||||
|
||||
/**
|
||||
* Historical quote list.
|
||||
*/
|
||||
@@ -360,13 +367,37 @@ public class BillingController extends BaseController
|
||||
@PostMapping("/bill/chargeWeight/importData")
|
||||
public AjaxResult importChargeWeight(MultipartFile file) throws Exception
|
||||
{
|
||||
if (file == null || file.isEmpty())
|
||||
{
|
||||
return error("file required");
|
||||
}
|
||||
byte[] bytes = file.getBytes();
|
||||
String originalName = file.getOriginalFilename();
|
||||
ExcelUtil<ChargeWeightImportRow> util = new ExcelUtil<ChargeWeightImportRow>(ChargeWeightImportRow.class);
|
||||
List<ChargeWeightImportRow> rows = util.importExcel(file.getInputStream());
|
||||
List<ChargeWeightImportRow> rows = util.importExcel(new ByteArrayInputStream(bytes));
|
||||
String taskId = prcOrderBillService.submitImportChargeWeight(rows);
|
||||
try
|
||||
{
|
||||
BmsBizAttachment att = bizAttachmentService.saveUpload(
|
||||
BmsBizAttachment.BIZ_CHARGE_WEIGHT_IMPORT, taskId, bytes, originalName,
|
||||
SecurityUtils.getUsername(), null);
|
||||
Map<String, Object> payload = new HashMap<String, Object>();
|
||||
payload.put("taskId", taskId);
|
||||
if (att != null)
|
||||
{
|
||||
payload.put("attachmentId", att.getAttachmentId());
|
||||
}
|
||||
return success(payload);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Import task already queued; attachment failure should not block rebill
|
||||
Map<String, Object> payload = new HashMap<String, Object>();
|
||||
payload.put("taskId", taskId);
|
||||
payload.put("attachmentWarn", e.getMessage());
|
||||
return success(payload);
|
||||
}
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:chargeWeightEdit')")
|
||||
@GetMapping("/bill/chargeWeight/import/task/{taskId}")
|
||||
@@ -379,4 +410,21 @@ public class BillingController extends BaseController
|
||||
}
|
||||
return success(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* List charge-weight import Excel attachment records.
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:chargeWeightEdit')")
|
||||
@GetMapping("/bill/chargeWeight/import/attachments")
|
||||
public TableDataInfo listChargeWeightImportAttachments(BmsBizAttachment query)
|
||||
{
|
||||
if (query == null)
|
||||
{
|
||||
query = new BmsBizAttachment();
|
||||
}
|
||||
query.setBizType(BmsBizAttachment.BIZ_CHARGE_WEIGHT_IMPORT);
|
||||
startPage();
|
||||
List<BmsBizAttachment> list = bizAttachmentService.selectBmsBizAttachmentList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,4 +42,32 @@ public final class TabOrderSyncEsLog
|
||||
String st = StringUtils.isEmpty(status) ? EsBizLogSupport.STATUS_SUCCESS : status;
|
||||
store.save(EsLogType.ORDER_SOURCE_SYNC, bizId, reqJson, respJson, st, errorMessage);
|
||||
}
|
||||
|
||||
/** Persist one failed sync order so it appears in order-source operation log. */
|
||||
public static void saveOneFail(IBillSearchStore store, Object row, Object response, String errorMessage)
|
||||
{
|
||||
String orderId = null;
|
||||
if (row instanceof com.bms.price.domain.vo.TabOrderMonitorVo)
|
||||
{
|
||||
orderId = ((com.bms.price.domain.vo.TabOrderMonitorVo) row).getOrderId();
|
||||
}
|
||||
else if (row instanceof Map)
|
||||
{
|
||||
Object v = ((Map<?, ?>) row).get("orderId");
|
||||
if (v != null)
|
||||
{
|
||||
orderId = String.valueOf(v);
|
||||
}
|
||||
}
|
||||
String bizId;
|
||||
if (StringUtils.isEmpty(orderId))
|
||||
{
|
||||
bizId = "ONE_FAIL_" + System.currentTimeMillis();
|
||||
}
|
||||
else
|
||||
{
|
||||
bizId = "ONE_" + orderId.trim();
|
||||
}
|
||||
save(store, bizId, "ONE_FAIL", row, response, EsBizLogSupport.STATUS_FAIL, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,8 @@ public class TabOrderSyncAsyncRunner
|
||||
AtomicInteger processed = new AtomicInteger(0);
|
||||
AtomicInteger ok = new AtomicInteger(0);
|
||||
AtomicInteger fail = new AtomicInteger(0);
|
||||
List<Map<String, Object>> failDetails = java.util.Collections.synchronizedList(
|
||||
new ArrayList<Map<String, Object>>());
|
||||
int pageNum = 1;
|
||||
while (true)
|
||||
{
|
||||
@@ -102,7 +104,7 @@ public class TabOrderSyncAsyncRunner
|
||||
{
|
||||
final TabOrderMonitorVo one = row;
|
||||
jobs.add(() -> {
|
||||
boolean success = syncOne(one);
|
||||
boolean success = syncOne(one, failDetails);
|
||||
if (success)
|
||||
{
|
||||
ok.incrementAndGet();
|
||||
@@ -137,7 +139,10 @@ public class TabOrderSyncAsyncRunner
|
||||
resp.put("ok", Integer.valueOf(ok.get()));
|
||||
resp.put("fail", Integer.valueOf(fail.get()));
|
||||
resp.put("threads", Integer.valueOf(threads));
|
||||
TabOrderSyncEsLog.save(billSearchStore, asyncTaskId, "FILTER_DONE", query, resp, "SUCCESS", null);
|
||||
resp.put("failDetails", truncateFailDetails(failDetails));
|
||||
String doneStatus = fail.get() > 0 ? "FAIL" : "SUCCESS";
|
||||
String doneErr = fail.get() > 0 ? ("fail=" + fail.get() + ", ok=" + ok.get()) : null;
|
||||
TabOrderSyncEsLog.save(billSearchStore, asyncTaskId, "FILTER_DONE", query, resp, doneStatus, doneErr);
|
||||
log.info("orderSource sync done asyncTaskId={} total={} ok={} fail={} threads={}",
|
||||
asyncTaskId, total, ok.get(), fail.get(), threads);
|
||||
}
|
||||
@@ -253,12 +258,18 @@ public class TabOrderSyncAsyncRunner
|
||||
return data;
|
||||
}
|
||||
|
||||
private boolean syncOne(TabOrderMonitorVo row)
|
||||
private boolean syncOne(TabOrderMonitorVo row, List<Map<String, Object>> failDetails)
|
||||
{
|
||||
try
|
||||
{
|
||||
PrcBillingTask task = billingTaskService.submitAndProcess(toSubmit(row));
|
||||
return task != null && BillTaskSuccessStatus.SUCCESS.getCode().equals(task.getSuccessStatus());
|
||||
boolean success = task != null
|
||||
&& BillTaskSuccessStatus.SUCCESS.getCode().equals(task.getSuccessStatus());
|
||||
if (!success)
|
||||
{
|
||||
collectFailDetail(failDetails, row, task, null);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
@@ -266,10 +277,62 @@ public class TabOrderSyncAsyncRunner
|
||||
row == null ? null : row.getOrderId(),
|
||||
row == null ? null : row.getTransferOrderId(),
|
||||
e.getMessage());
|
||||
collectFailDetail(failDetails, row, null, e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final int FAIL_DETAIL_MAX = 200;
|
||||
|
||||
private static void collectFailDetail(List<Map<String, Object>> failDetails, TabOrderMonitorVo row,
|
||||
PrcBillingTask task, String exceptionMessage)
|
||||
{
|
||||
if (failDetails == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Map<String, Object> item = new LinkedHashMap<String, Object>();
|
||||
item.put("orderId", row == null ? null : row.getOrderId());
|
||||
item.put("transferOrderId", row == null ? null : row.getTransferOrderId());
|
||||
String err = exceptionMessage;
|
||||
if (task != null)
|
||||
{
|
||||
item.put("successStatus", task.getSuccessStatus());
|
||||
item.put("billType", task.getBillType());
|
||||
item.put("taskId", task.getTaskId());
|
||||
if (StringUtils.isEmpty(err))
|
||||
{
|
||||
err = task.getErrorMessage();
|
||||
}
|
||||
}
|
||||
if (StringUtils.isEmpty(err))
|
||||
{
|
||||
err = "sync failed";
|
||||
}
|
||||
item.put("errorMessage", err);
|
||||
synchronized (failDetails)
|
||||
{
|
||||
if (failDetails.size() >= FAIL_DETAIL_MAX)
|
||||
{
|
||||
return;
|
||||
}
|
||||
failDetails.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Map<String, Object>> truncateFailDetails(List<Map<String, Object>> failDetails)
|
||||
{
|
||||
if (failDetails == null || failDetails.isEmpty())
|
||||
{
|
||||
return java.util.Collections.emptyList();
|
||||
}
|
||||
if (failDetails.size() <= FAIL_DETAIL_MAX)
|
||||
{
|
||||
return new ArrayList<Map<String, Object>>(failDetails);
|
||||
}
|
||||
return new ArrayList<Map<String, Object>>(failDetails.subList(0, FAIL_DETAIL_MAX));
|
||||
}
|
||||
|
||||
private static void invokeAllQuiet(ExecutorService pool, List<Callable<Boolean>> jobs) throws InterruptedException
|
||||
{
|
||||
List<Future<Boolean>> futures = pool.invokeAll(jobs);
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.bms.system.domain;
|
||||
|
||||
import com.bms.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 公共业务附件 bms_biz_attachment
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class BmsBizAttachment extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 批量修改计费重导入 */
|
||||
public static final String BIZ_CHARGE_WEIGHT_IMPORT = "CHARGE_WEIGHT_IMPORT";
|
||||
|
||||
private Long attachmentId;
|
||||
/** 业务类型 */
|
||||
private String bizType;
|
||||
/** 业务关联ID */
|
||||
private String bizId;
|
||||
private String fileName;
|
||||
private String filePath;
|
||||
private Long fileSize;
|
||||
private String contentType;
|
||||
private String fileExtension;
|
||||
private String delFlag;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.bms.system.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.bms.system.domain.BmsBizAttachment;
|
||||
|
||||
/** Common biz attachment mapper */
|
||||
public interface BmsBizAttachmentMapper
|
||||
{
|
||||
BmsBizAttachment selectBmsBizAttachmentById(Long attachmentId);
|
||||
|
||||
List<BmsBizAttachment> selectBmsBizAttachmentList(BmsBizAttachment query);
|
||||
|
||||
int insertBmsBizAttachment(BmsBizAttachment row);
|
||||
|
||||
int updateBmsBizAttachment(BmsBizAttachment row);
|
||||
|
||||
int deleteBmsBizAttachmentByIds(Long[] attachmentIds);
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.bms.system.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.bms.system.domain.BmsBizAttachment;
|
||||
|
||||
/** 公共业务附件 */
|
||||
public interface IBmsBizAttachmentService
|
||||
{
|
||||
BmsBizAttachment selectBmsBizAttachmentById(Long attachmentId);
|
||||
|
||||
List<BmsBizAttachment> selectBmsBizAttachmentList(BmsBizAttachment query);
|
||||
|
||||
/**
|
||||
* 落盘保存上传文件并写附件记录
|
||||
*/
|
||||
BmsBizAttachment saveUpload(String bizType, String bizId, byte[] bytes, String filename,
|
||||
String operName, String remark) throws Exception;
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package com.bms.system.service.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.bms.common.config.BmsConfig;
|
||||
import com.bms.common.exception.ServiceException;
|
||||
import com.bms.common.utils.DateUtils;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.common.utils.file.FileUploadUtils;
|
||||
import com.bms.common.utils.uuid.IdUtils;
|
||||
import com.bms.system.domain.BmsBizAttachment;
|
||||
import com.bms.system.mapper.BmsBizAttachmentMapper;
|
||||
import com.bms.system.service.IBmsBizAttachmentService;
|
||||
|
||||
@Service
|
||||
public class BmsBizAttachmentServiceImpl implements IBmsBizAttachmentService
|
||||
{
|
||||
private static final String SUB_DIR = "biz/attachment";
|
||||
|
||||
@Autowired
|
||||
private BmsBizAttachmentMapper attachmentMapper;
|
||||
|
||||
@Override
|
||||
public BmsBizAttachment selectBmsBizAttachmentById(Long attachmentId)
|
||||
{
|
||||
return attachmentMapper.selectBmsBizAttachmentById(attachmentId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BmsBizAttachment> selectBmsBizAttachmentList(BmsBizAttachment query)
|
||||
{
|
||||
List<BmsBizAttachment> list = attachmentMapper.selectBmsBizAttachmentList(query);
|
||||
return list == null ? Collections.emptyList() : list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BmsBizAttachment saveUpload(String bizType, String bizId, byte[] bytes, String filename,
|
||||
String operName, String remark) throws Exception
|
||||
{
|
||||
if (StringUtils.isEmpty(bizType))
|
||||
{
|
||||
throw new ServiceException("bizType required");
|
||||
}
|
||||
if (bytes == null || bytes.length == 0)
|
||||
{
|
||||
throw new ServiceException("file empty");
|
||||
}
|
||||
String originalName = StringUtils.isNotEmpty(filename) ? filename : "upload.bin";
|
||||
String ext = FilenameUtils.getExtension(originalName);
|
||||
if (StringUtils.isEmpty(ext))
|
||||
{
|
||||
ext = "bin";
|
||||
}
|
||||
ext = ext.toLowerCase(Locale.ROOT);
|
||||
|
||||
String uploadDir = BmsConfig.getUploadPath() + File.separator + SUB_DIR;
|
||||
String pathName = DateUtils.datePath() + "/" + IdUtils.fastSimpleUUID() + "." + ext;
|
||||
File dest = FileUploadUtils.getAbsoluteFile(uploadDir, pathName);
|
||||
FileOutputStream fos = null;
|
||||
try
|
||||
{
|
||||
fos = new FileOutputStream(dest);
|
||||
fos.write(bytes);
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtils.close(fos);
|
||||
}
|
||||
String storedPath = FileUploadUtils.getPathFileName(uploadDir, pathName);
|
||||
|
||||
BmsBizAttachment row = new BmsBizAttachment();
|
||||
row.setBizType(bizType.trim());
|
||||
row.setBizId(bizId);
|
||||
row.setFileName(originalName);
|
||||
row.setFilePath(storedPath);
|
||||
row.setFileSize(Long.valueOf(bytes.length));
|
||||
row.setContentType(resolveContentType(ext));
|
||||
row.setFileExtension(ext);
|
||||
row.setRemark(remark);
|
||||
row.setCreateBy(operName);
|
||||
attachmentMapper.insertBmsBizAttachment(row);
|
||||
return row;
|
||||
}
|
||||
|
||||
private static String resolveContentType(String ext)
|
||||
{
|
||||
if ("xls".equals(ext))
|
||||
{
|
||||
return "application/vnd.ms-excel";
|
||||
}
|
||||
if ("xlsx".equals(ext))
|
||||
{
|
||||
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.bms.system.mapper.BmsBizAttachmentMapper">
|
||||
|
||||
<resultMap type="BmsBizAttachment" id="BmsBizAttachmentResult">
|
||||
<id property="attachmentId" column="attachment_id" />
|
||||
<result property="bizType" column="biz_type" />
|
||||
<result property="bizId" column="biz_id" />
|
||||
<result property="fileName" column="file_name" />
|
||||
<result property="filePath" column="file_path" />
|
||||
<result property="fileSize" column="file_size" />
|
||||
<result property="contentType" column="content_type" />
|
||||
<result property="fileExtension" column="file_extension" />
|
||||
<result property="remark" column="remark" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectBmsBizAttachmentVo">
|
||||
select attachment_id, biz_type, biz_id, file_name, file_path, file_size, content_type,
|
||||
file_extension, remark, create_by, create_time, update_by, update_time, del_flag
|
||||
from bms_biz_attachment
|
||||
</sql>
|
||||
|
||||
<select id="selectBmsBizAttachmentById" parameterType="Long" resultMap="BmsBizAttachmentResult">
|
||||
<include refid="selectBmsBizAttachmentVo"/>
|
||||
where attachment_id = #{attachmentId} and del_flag = '0'
|
||||
</select>
|
||||
|
||||
<select id="selectBmsBizAttachmentList" parameterType="BmsBizAttachment" resultMap="BmsBizAttachmentResult">
|
||||
<include refid="selectBmsBizAttachmentVo"/>
|
||||
<where>
|
||||
del_flag = '0'
|
||||
<if test="bizType != null and bizType != ''">
|
||||
AND biz_type = #{bizType}
|
||||
</if>
|
||||
<if test="bizId != null and bizId != ''">
|
||||
AND biz_id = #{bizId}
|
||||
</if>
|
||||
<if test="fileName != null and fileName != ''">
|
||||
AND file_name like concat('%', #{fileName}, '%')
|
||||
</if>
|
||||
<if test="createBy != null and createBy != ''">
|
||||
AND create_by like concat('%', #{createBy}, '%')
|
||||
</if>
|
||||
<if test="params != null and params.beginTime != null and params.beginTime != ''">
|
||||
AND create_time >= #{params.beginTime}
|
||||
</if>
|
||||
<if test="params != null and params.endTime != null and params.endTime != ''">
|
||||
AND create_time <= #{params.endTime}
|
||||
</if>
|
||||
</where>
|
||||
order by attachment_id desc
|
||||
</select>
|
||||
|
||||
<insert id="insertBmsBizAttachment" parameterType="BmsBizAttachment" useGeneratedKeys="true" keyProperty="attachmentId">
|
||||
insert into bms_biz_attachment (
|
||||
<if test="bizType != null and bizType != ''">biz_type,</if>
|
||||
<if test="bizId != null">biz_id,</if>
|
||||
<if test="fileName != null and fileName != ''">file_name,</if>
|
||||
<if test="filePath != null and filePath != ''">file_path,</if>
|
||||
<if test="fileSize != null">file_size,</if>
|
||||
<if test="contentType != null">content_type,</if>
|
||||
<if test="fileExtension != null">file_extension,</if>
|
||||
<if test="remark != null">remark,</if>
|
||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||
create_time,
|
||||
del_flag
|
||||
) values (
|
||||
<if test="bizType != null and bizType != ''">#{bizType},</if>
|
||||
<if test="bizId != null">#{bizId},</if>
|
||||
<if test="fileName != null and fileName != ''">#{fileName},</if>
|
||||
<if test="filePath != null and filePath != ''">#{filePath},</if>
|
||||
<if test="fileSize != null">#{fileSize},</if>
|
||||
<if test="contentType != null">#{contentType},</if>
|
||||
<if test="fileExtension != null">#{fileExtension},</if>
|
||||
<if test="remark != null">#{remark},</if>
|
||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||
sysdate(),
|
||||
'0'
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="updateBmsBizAttachment" parameterType="BmsBizAttachment">
|
||||
update bms_biz_attachment
|
||||
<set>
|
||||
<if test="bizId != null">biz_id = #{bizId},</if>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||
update_time = sysdate()
|
||||
</set>
|
||||
where attachment_id = #{attachmentId}
|
||||
</update>
|
||||
|
||||
<update id="deleteBmsBizAttachmentByIds" parameterType="Long">
|
||||
update bms_biz_attachment set del_flag = '2' where attachment_id in
|
||||
<foreach collection="array" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</update>
|
||||
</mapper>
|
||||
@@ -0,0 +1,22 @@
|
||||
-- 公共业务附件表(可复用:批量修改计费重导入等)
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bms_biz_attachment (
|
||||
attachment_id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '附件ID',
|
||||
biz_type varchar(64) NOT NULL COMMENT '业务类型(如 CHARGE_WEIGHT_IMPORT)',
|
||||
biz_id varchar(64) DEFAULT NULL COMMENT '业务关联ID(如导入任务taskId)',
|
||||
file_name varchar(255) NOT NULL COMMENT '文件原始名称',
|
||||
file_path varchar(500) NOT NULL COMMENT '存储路径(相对路径)',
|
||||
file_size bigint(20) DEFAULT 0 COMMENT '文件大小(字节)',
|
||||
content_type varchar(100) DEFAULT '' COMMENT 'MIME类型',
|
||||
file_extension varchar(20) DEFAULT '' COMMENT '扩展名',
|
||||
remark varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
create_by varchar(64) DEFAULT '' COMMENT '创建人',
|
||||
create_time datetime DEFAULT NULL COMMENT '创建时间',
|
||||
update_by varchar(64) DEFAULT '' COMMENT '更新人',
|
||||
update_time datetime DEFAULT NULL COMMENT '更新时间',
|
||||
del_flag char(1) DEFAULT '0' COMMENT '删除标志(0存在 2删除)',
|
||||
PRIMARY KEY (attachment_id),
|
||||
KEY idx_biz_attach_type_time (biz_type, create_time),
|
||||
KEY idx_biz_attach_biz_id (biz_type, biz_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='公共业务附件';
|
||||
@@ -277,3 +277,12 @@ export async function downloadChargeWeightTemplate(data, filename) {
|
||||
loading.close()
|
||||
}
|
||||
}
|
||||
|
||||
/** 批量修改计费重导入附件记录 */
|
||||
export function listChargeWeightImportAttachments(query) {
|
||||
return request({
|
||||
url: '/price/billing/bill/chargeWeight/import/attachments',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
@@ -35,6 +35,14 @@
|
||||
<span class="err-text">{{ detail.errorMessage }}</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div v-if="failRows.length" class="json-panel">
|
||||
<div class="json-panel__head"><span>失败明细(共 {{ failRows.length }} 单)</span></div>
|
||||
<el-table :data="failRows" border size="small" max-height="280" class="fail-table">
|
||||
<el-table-column label="订单号" prop="orderId" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column label="转单号" prop="transferOrderId" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column label="错误信息" prop="errorMessage" min-width="220" show-overflow-tooltip />
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="json-panel">
|
||||
<div class="json-panel__head"><span>请求报文</span></div>
|
||||
<pre class="code-pre">{{ formatJson(detail.requestJson) }}</pre>
|
||||
@@ -74,7 +82,7 @@ const searchColumns = [
|
||||
]
|
||||
|
||||
const columns = [
|
||||
{ label: '操作', prop: 'actionName', width: 120, slot: 'actionName' },
|
||||
{ label: '操作', prop: 'actionName', width: 150, slot: 'actionName' },
|
||||
{ label: '业务ID', prop: 'bizId', minWidth: 180, showOverflowTooltip: true },
|
||||
{ label: '状态', prop: 'status', align: 'center', width: 90, slot: 'status' },
|
||||
{ label: '写入时间', prop: 'updateTime', align: 'center', width: 170 },
|
||||
@@ -93,12 +101,41 @@ function parseReq(row) {
|
||||
function actionLabel(row) {
|
||||
const action = parseReq(row).action
|
||||
if (action === 'FILTER') return '筛选同步'
|
||||
if (action === 'FILTER_DONE') return '筛选完成'
|
||||
if (action === 'SELECTED') return '同步选中'
|
||||
if (action === 'FILTER_DONE') {
|
||||
return row.status === 'FAIL' ? '筛选完成(有失败)' : '筛选完成'
|
||||
}
|
||||
if (action === 'SELECTED') {
|
||||
return row.status === 'FAIL' ? '同步选中(有失败)' : '同步选中'
|
||||
}
|
||||
if (action === 'ONE') return '单条同步'
|
||||
if (action === 'ONE_FAIL') return '同步失败'
|
||||
return action || '-'
|
||||
}
|
||||
|
||||
const failRows = computed(() => {
|
||||
if (!detail.value) return []
|
||||
const resp = parseResp(detail.value)
|
||||
if (Array.isArray(resp.failDetails) && resp.failDetails.length) {
|
||||
return resp.failDetails
|
||||
}
|
||||
if (Array.isArray(resp.details) && resp.details.length) {
|
||||
return resp.details.filter(d => {
|
||||
const st = d && d.successStatus
|
||||
return st && String(st).toUpperCase() !== 'SUCCESS'
|
||||
})
|
||||
}
|
||||
return []
|
||||
})
|
||||
|
||||
function parseResp(row) {
|
||||
if (!row || !row.responseJson) return {}
|
||||
try {
|
||||
return typeof row.responseJson === 'object' ? row.responseJson : JSON.parse(row.responseJson)
|
||||
} catch (e) {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
function queryList(params) {
|
||||
return listOrderSourceSyncLog(params)
|
||||
}
|
||||
@@ -143,6 +180,9 @@ defineExpose({ open })
|
||||
margin-bottom: 6px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.fail-table {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.code-pre {
|
||||
margin: 0;
|
||||
padding: 10px 12px;
|
||||
|
||||
@@ -95,6 +95,15 @@
|
||||
@click="openChargeWeightImport"
|
||||
>批量修改计费重</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="info"
|
||||
plain
|
||||
icon="Document"
|
||||
v-hasPermi="['price:billing:chargeWeightEdit']"
|
||||
@click="openChargeWeightImportAttach"
|
||||
>导入记录</el-button>
|
||||
</el-col>
|
||||
</template>
|
||||
<template #col-action="{ row }">
|
||||
<el-button link type="primary" icon="View" @click="handleView(row)">查看</el-button>
|
||||
@@ -151,6 +160,7 @@
|
||||
<div class="cw-fill-hint">勾选后下载模板会写入筛选结果的订单号、客户代码;人工修改计费重列留空待填</div>
|
||||
</template>
|
||||
</excel-import-dialog>
|
||||
<charge-weight-import-attach-drawer ref="cwImportAttachRef" />
|
||||
<el-dialog
|
||||
v-model="cwImportProgressVisible"
|
||||
title="正在导入修改计费重"
|
||||
@@ -181,6 +191,7 @@ import BillDetail from './components/BillDetail.vue'
|
||||
import BatchAddIncomeFeeDialog from './components/BatchAddIncomeFeeDialog.vue'
|
||||
import EditChargeWeightDialog from './components/EditChargeWeightDialog.vue'
|
||||
import ExcelImportDialog from '@/components/ExcelImportDialog'
|
||||
import ChargeWeightImportAttachDrawer from './components/ChargeWeightImportAttachDrawer.vue'
|
||||
|
||||
// 订单号下拉远程搜索:返回匹配的订单号列表(最多 20 条)
|
||||
function searchOrderNoOptions(keyword) {
|
||||
@@ -218,6 +229,7 @@ const refundingKey = ref(null)
|
||||
const editCwOpen = ref(false)
|
||||
const editCwRow = ref(null)
|
||||
const chargeWeightImportRef = ref()
|
||||
const cwImportAttachRef = ref()
|
||||
const chargeWeightImportDesc = [
|
||||
'模板列:订单号、客户、人工修改计费重(kg)',
|
||||
'客户可填名称或代码,须与订单客户一致',
|
||||
@@ -440,6 +452,10 @@ async function downloadChargeWeightImportTemplate() {
|
||||
await downloadChargeWeightTemplate(payload)
|
||||
}
|
||||
|
||||
function openChargeWeightImportAttach() {
|
||||
cwImportAttachRef.value?.open?.()
|
||||
}
|
||||
|
||||
function openChargeWeightImport() {
|
||||
cwFillByFilter.value = false
|
||||
chargeWeightImportRef.value?.open?.()
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<el-drawer v-model="visible" size="860px" :title="drawerTitle" append-to-body destroy-on-close>
|
||||
<basic-table
|
||||
v-if="visible"
|
||||
:columns="columns"
|
||||
:search-columns="searchColumns"
|
||||
:query="queryList"
|
||||
row-key="attachmentId"
|
||||
:page-size="10"
|
||||
:selection="false"
|
||||
:show-add="false"
|
||||
>
|
||||
<template #col-fileSize="{ row }">
|
||||
{{ formatSize(row.fileSize) }}
|
||||
</template>
|
||||
<template #col-action="{ row }">
|
||||
<el-button link type="primary" :disabled="!row.filePath" @click="handleDownload(row)">下载</el-button>
|
||||
</template>
|
||||
</basic-table>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { listChargeWeightImportAttachments } from '@/api/price/billing'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const visible = ref(false)
|
||||
const drawerTitle = '批量修改计费重导入记录'
|
||||
|
||||
const searchColumns = [
|
||||
{ label: '文件名', prop: 'fileName', component: 'input', placeholder: '文件名', width: '200px' },
|
||||
{ label: '上传人', prop: 'createBy', component: 'input', placeholder: '上传人', width: '140px' }
|
||||
]
|
||||
|
||||
const columns = [
|
||||
{ label: '文件名称', prop: 'fileName', minWidth: 220, showOverflowTooltip: true },
|
||||
{ label: '任务ID', prop: 'bizId', minWidth: 180, showOverflowTooltip: true },
|
||||
{ label: '大小', prop: 'fileSize', width: 100, align: 'right', slot: 'fileSize' },
|
||||
{ label: '上传人', prop: 'createBy', width: 110, align: 'center', showOverflowTooltip: true },
|
||||
{ label: '上传时间', prop: 'createTime', width: 170, align: 'center' },
|
||||
{ label: '操作', prop: 'action', width: 90, align: 'center', fixed: 'right', slot: 'action', showInToolbar: false }
|
||||
]
|
||||
|
||||
function queryList(params) {
|
||||
return listChargeWeightImportAttachments(params)
|
||||
}
|
||||
|
||||
function formatSize(bytes) {
|
||||
const n = Number(bytes)
|
||||
if (!n || n < 0) return '-'
|
||||
if (n < 1024) return n + ' B'
|
||||
if (n < 1024 * 1024) return (n / 1024).toFixed(1) + ' KB'
|
||||
return (n / (1024 * 1024)).toFixed(2) + ' MB'
|
||||
}
|
||||
|
||||
function handleDownload(row) {
|
||||
if (!row || !row.filePath) {
|
||||
proxy.$modal.msgWarning('文件路径不存在')
|
||||
return
|
||||
}
|
||||
proxy.$download.resource(row.filePath)
|
||||
}
|
||||
|
||||
function open() {
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
Reference in New Issue
Block a user