新增 订单稿件导出功能

This commit is contained in:
yf 2025-01-20 00:26:12 +08:00
parent b3d8346204
commit 7b1b5cf618
6 changed files with 159 additions and 1 deletions

View File

@ -26,5 +26,6 @@ public interface ErrorCodeConstants extends cn.hangtag.module.system.enums.Erro
ErrorCode SALE_CONTRACT_NOT_EXISTS = new ErrorCode(5000, "OMS销售合约不存在");
ErrorCode PRODUCT_PRICE_NOT_EXISTS = new ErrorCode(600, "产品单价记录不存在");
ErrorCode CUSTOMER_EMAIL_EXISTS = new ErrorCode(600, "已存在重复的客户邮箱号");
ErrorCode SALE_ORDER_NOT_FILE_EXPORT = new ErrorCode(7000, "订单中没有可导出的稿件");
}

View File

@ -208,4 +208,11 @@ public class SaleOrderController {
saleOrderService.generatePdf(response,ids);
}
@GetMapping("/exportDesignSourceFile")
@Operation(summary = "导出销售订单的稿件源文件")
@PermitAll
public void exportDesignSourceFile(@RequestParam("ids") List<Long> ids,HttpServletResponse response) throws IOException {
saleOrderService.exportDesignSourceFile(response,ids);
}
}

View File

@ -145,4 +145,12 @@ public interface SaleOrderService {
* @return {@link Long }
*/
Long queryLastOrderBrand(Long customerId);
/**
* 导出销售订单 sku 设计源文件
*
* @param response 响应
* @param ids IDs
*/
void exportDesignSourceFile(HttpServletResponse response, List<Long> ids);
}

View File

@ -35,6 +35,7 @@ import cn.hangtag.module.oms.dal.dataobject.saleorder.SaleOrderDO;
import cn.hangtag.module.oms.dal.dataobject.saleorderentry.SaleOrderEntryDO;
import cn.hangtag.module.oms.dal.dataobject.saleordersku.SaleOrderSkuDO;
import cn.hangtag.module.oms.dal.mysql.customer.CustomerMapper;
import cn.hangtag.module.oms.dal.mysql.productinfo.ProductInfoMapper;
import cn.hangtag.module.oms.dal.mysql.salecontract.SaleContractMapper;
import cn.hangtag.module.oms.dal.mysql.saleorder.SaleOrderMapper;
import cn.hangtag.module.oms.dal.mysql.saleorderentry.SaleOrderEntryMapper;
@ -71,6 +72,7 @@ import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
@ -129,6 +131,9 @@ public class SaleOrderServiceImpl implements SaleOrderService {
private CustomerMapper customerMapper;
@Resource
private UserBrandMapper userBrandMapper;
@Resource
private ProductInfoMapper productInfoMapper;
@Resource
private ProductPriceService productPriceService;
@ -1174,6 +1179,107 @@ public class SaleOrderServiceImpl implements SaleOrderService {
return null;
}
@SneakyThrows
@Override
public void exportDesignSourceFile(HttpServletResponse response, List<Long> ids) {
// 获取 分录
LambdaQueryWrapper<SaleOrderEntryDO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(SaleOrderEntryDO::getParentId, ids);
queryWrapper.eq(SaleOrderEntryDO::getDeleted, false);
List<SaleOrderEntryDO> entryDOS = saleOrderEntryMapper.selectList(queryWrapper);
if(FuncUtil.isEmpty(entryDOS)){
throw exception(ErrorCodeConstants.SALE_ORDER_NOT_FILE_EXPORT);
}
List<Long> id = new ArrayList<>();
Map<Long,String> codeMap = new HashMap<>();
for (SaleOrderEntryDO entryDO : entryDOS) {
Long materialId = entryDO.getMaterialId();
ProductInfoDO infoDO = productInfoMapper.selectById(materialId);
if(FuncUtil.isNotEmpty(infoDO)){
String templateType = infoDO.getTemplateType();
if("1".equals(templateType)){
// 有模板物料
id.add(entryDO.getId());
String code = infoDO.getCode();
codeMap.put(entryDO.getId(), code);
}
}
}
if(FuncUtil.isEmpty(id)){
throw exception(ErrorCodeConstants.SALE_ORDER_NOT_FILE_EXPORT);
}
// 获取 sku
LambdaQueryWrapper<SaleOrderSkuDO> skuWrapper = new LambdaQueryWrapper<>();
skuWrapper.in(SaleOrderSkuDO::getEntryId, id);
skuWrapper.eq(SaleOrderSkuDO::getDeleted, false);
List<SaleOrderSkuDO> skuDOS = skuOrderSkuMapper.selectList(skuWrapper);
if(FuncUtil.isEmpty(skuDOS)){
throw exception(ErrorCodeConstants.SALE_ORDER_NOT_FILE_EXPORT);
}
String pathUrl = System.getProperty("user.dir") + "/dsf";
File file1 = new File(pathUrl);
if (!file1.exists()) {
file1.mkdirs();
}
List<File> files = new ArrayList<>();
List<String> delFiles = new ArrayList<>();
for (SaleOrderSkuDO skuDO : skuDOS) {
String sourceFile = skuDO.getSourceFile();
if(FuncUtil.isNotEmpty(sourceFile)){
// 生成文件
Long entryId = skuDO.getEntryId();
String s = codeMap.get(entryId);
Integer orderQty = skuDO.getOrderQty();
//主宿机生成路径
String name = DateUtil.format(LocalDateTime.now(), "yyyyMMdd")
+"-"+IdUtil.simpleUUID().substring(0, 4);
String ouput = StrUtil.format(pathUrl + "/{}_{}.pdf",
s+"_"+orderQty,name);
//请求wkapp
JSONObject params = new JSONObject();
params.put("input_html_path", sourceFile);
params.put("output_pdf_path", ouput);
log.info("稿件导出 请求wkapp接口url" + wkappUrl + "/exehtmltopdf");
String result = HttpUtil.post(wkappUrl + "/exehtmltopdf", params, 5 * 60 * 1000);
log.info("稿件导出 请求wkapp接口返回结果" + result);
//WKHtmlToPdfUtil.convert(templatePath, pdfPath);
File file = FileUtil.file(ouput);
files.add(file);
delFiles.add(ouput);
}
}
if(FuncUtil.isEmpty(files)){
throw exception(ErrorCodeConstants.SALE_ORDER_NOT_FILE_EXPORT);
}
String zipFileName = StrUtil.format(pathUrl + "/订单稿件_{}", new Date().getTime());
// 压缩到的位置
File zipFile = new File(zipFileName + ".zip");
ZipUtil.zip(zipFile, false, files.toArray(new File[files.size()]));
// 设置响应类型
//response.setContentType("application/pdf");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFile.getName(), "UTF-8"));
// 输出PDF到响应输出流
// 将文件内容写入响应流
try (InputStream inputStream = new FileInputStream(zipFile)) {
IoUtil.copy(inputStream, response.getOutputStream());
} catch (IOException e) {
// 异常处理
log.info("导出销售合约写入流失败,{}", e.getMessage());
}
// 导出完删除
delFiles.add(zipFileName);
for (String delFile : delFiles) {
FileUtil.del(delFile);
}
}
/**
* 下载ZIP压缩包(会对下载后的压缩包进行删除)
*

View File

@ -115,5 +115,13 @@ export const SaleOrderApi = {
ids: ids.join(',')
}
return await request.download({ url: `/oms/sale-order/exportSalePIPDF`, params})
} ,
// 导出稿件
exportDesignSourceFile: async (ids: number[]) => {
const params = {
ids: ids.join(',')
}
return await request.download({ url: `/oms/sale-order/exportDesignSourceFile`, params})
}
}

View File

@ -170,6 +170,15 @@
>
导出PI
</el-button>
<el-button
type="primary"
plain
:loading="exportLoading3"
@click="exportDesignFile"
:disabled="selectionList.length === 0"
>
导出订单稿件
</el-button>
<el-button
type="success"
plain
@ -303,7 +312,7 @@
<script setup lang="ts">
import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import {dateFormatter, dateFormatter2} from '@/utils/formatTime'
import {dateFormatter, dateFormatter2, formatDate} from '@/utils/formatTime'
import download from '@/utils/download'
import { SaleOrderApi, SaleOrderVO } from '@/api/oms/saleorder'
import SaleOrderForm from './SaleOrderForm.vue'
@ -361,6 +370,7 @@ const queryParams = reactive({
const queryFormRef = ref() //
const exportLoading = ref(false) //
const exportLoading2 = ref(false) //
const exportLoading3 = ref(false) //
//
@ -611,6 +621,24 @@ const openDetail = (id: number) => {
push({ name: 'SaleOrderDetail', params: { id } })
}
/** 导出稿件元文件 */
const exportDesignFile = async () => {
try {
const ids = selectionList.value.map((item) => item.id)
//
await message.exportConfirm("是否确认导出订单稿件?")
//
exportLoading3.value = true
//
const data = await SaleOrderApi.exportDesignSourceFile(ids)
message.notifySuccess(`导出成功`);
download.zip(data, `订单稿件_${formatDate(new Date(), 'YYYYmmdd_HHMM')}.zip`)
selectionList.value = selectionList.value.filter((item) => !ids.includes(item.id))
} catch {
} finally {
exportLoading3.value = false
}
}
const tableRowClassName = ({
row,
rowIndex,