新增pi推送邮件
This commit is contained in:
parent
79e94961ae
commit
11c705f7e6
|
|
@ -124,7 +124,6 @@
|
|||
<groupId>org.apache.tika</groupId>
|
||||
<artifactId>tika-core</artifactId> <!-- 文件客户端:文件类型的识别 -->
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -64,6 +64,32 @@
|
|||
<version>2.1.0-jdk8-snapshot</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<!-- Thymeleaf 模板引擎 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- HTML转PDF工具(flying-saucer) -->
|
||||
<dependency>
|
||||
<groupId>org.xhtmlrenderer</groupId>
|
||||
<artifactId>flying-saucer-core</artifactId>
|
||||
<version>9.1.20</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xhtmlrenderer</groupId>
|
||||
<artifactId>flying-saucer-pdf-openpdf</artifactId>
|
||||
<version>9.1.20</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.librepdf</groupId>
|
||||
<artifactId>openpdf</artifactId>
|
||||
<version>1.3.14</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -51,7 +51,11 @@ public class AppBrandController {
|
|||
public CommonResult<List<BrandSimpleRespVO>> getSimpleBrandList() {
|
||||
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||
CustomerDO customer = customerService.getCustomerByUserId(loginUser.getId());
|
||||
List<CustomerBrandDO> listByCustomerId = customerBrandService.getListByCustomerId(customer.getId());
|
||||
Long customerId = null;
|
||||
if(customer!=null){
|
||||
customerId = customer.getId();
|
||||
}
|
||||
List<CustomerBrandDO> listByCustomerId = customerBrandService.getListByCustomerId(customerId);
|
||||
List<Long> brandIds = new ArrayList<>();
|
||||
for (CustomerBrandDO customerBrandDO : listByCustomerId) {
|
||||
brandIds.add(customerBrandDO.getBrandId());
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package cn.hangtag.module.oms.controller.admin.saleorder;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
|
@ -8,6 +10,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.validation.constraints.*;
|
||||
import javax.validation.*;
|
||||
import javax.servlet.http.*;
|
||||
|
|
@ -129,9 +132,30 @@ public class SaleOrderController {
|
|||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/rejectOrder")
|
||||
@Operation(summary = "驳回")
|
||||
@PreAuthorize("@ss.hasPermission('oms:sale-order:rejectOrder')")
|
||||
public CommonResult<Boolean> rejectOrder(@RequestBody JSONObject jobs) {
|
||||
Long[] ids = jobs.getObject("ids", new Long[0].getClass());
|
||||
String reason = jobs.getString("reason");
|
||||
return success(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 生成PDF文档并下载
|
||||
* @param response HTTP响应
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
@GetMapping("/download")
|
||||
@PermitAll
|
||||
public void downloadPdf(HttpServletResponse response) throws Exception {
|
||||
String htmlContent = saleOrderService.generateHtmlContent();
|
||||
saleOrderService.generatePdf(response, htmlContent);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -70,4 +70,8 @@ public class SaleOrderRespVO {
|
|||
@ExcelProperty("备注")
|
||||
private String remarks;
|
||||
|
||||
@Schema(description = "驳回原因")
|
||||
@ExcelProperty("驳回原因")
|
||||
private String rejectReason;
|
||||
|
||||
}
|
||||
|
|
@ -62,6 +62,9 @@ public class SaleOrderSaveReqVO {
|
|||
@Schema(description = "订单状态", example = "2")
|
||||
private Integer orderStatus;
|
||||
|
||||
@Schema(description = "驳回原因", example = "2")
|
||||
private String rejectReason;
|
||||
|
||||
@Schema(description = "销售订单明细列表")
|
||||
private List<SaleOrderEntryDO> saleOrderEntrys;
|
||||
|
||||
|
|
|
|||
|
|
@ -102,5 +102,9 @@ public class SaleOrderDO extends BaseDO {
|
|||
* 发票备注
|
||||
*/
|
||||
private String invoiceRemarks;
|
||||
/**
|
||||
* 驳回原因
|
||||
*/
|
||||
private String rejectReason;
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package cn.hangtag.module.oms.service.saleorder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.*;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.vo.*;
|
||||
import cn.hangtag.module.oms.dal.dataobject.saleorder.SaleOrderDO;
|
||||
|
|
@ -68,4 +70,8 @@ public interface SaleOrderService {
|
|||
void updateSaleOrderBillStatus(List<Long> ids, String status);
|
||||
|
||||
void generateProduceOrder(List<Long> ids);
|
||||
|
||||
String generateHtmlContent();
|
||||
|
||||
void generatePdf(HttpServletResponse response, String htmlContent) throws IOException;
|
||||
}
|
||||
|
|
@ -12,12 +12,24 @@ import cn.hangtag.module.oms.dal.mysql.saleorderentry.SaleOrderEntryMapper;
|
|||
import cn.hangtag.module.oms.enums.saleorder.SaleOrderStatusEnum;
|
||||
import cn.hangtag.module.oms.service.produceorder.ProduceOrderService;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.lowagie.text.pdf.PdfWriter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.thymeleaf.TemplateEngine;
|
||||
import org.thymeleaf.context.Context;
|
||||
import org.xhtmlrenderer.pdf.ITextFontResolver;
|
||||
import org.xhtmlrenderer.pdf.ITextRenderer;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -42,6 +54,9 @@ public class SaleOrderServiceImpl implements SaleOrderService {
|
|||
@Resource
|
||||
private ProduceOrderService produceOrderService;
|
||||
|
||||
@Resource
|
||||
private TemplateEngine templateEngine;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createSaleOrder(SaleOrderSaveReqVO createReqVO) {
|
||||
|
|
@ -148,6 +163,52 @@ public class SaleOrderServiceImpl implements SaleOrderService {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateHtmlContent() {
|
||||
Context context = new Context();
|
||||
context.setVariable("title", "PDF文档标题");
|
||||
context.setVariable("content",
|
||||
"这是PDF文档的主要内容:"
|
||||
+ "“成功并不是终点,失败也不是终结,最重要的是继续前行的勇气。在人生的旅途中,我们会遇到许多挑战与挫折,这些都是成长的必经之路。每一次跌倒都是一次学习的机会,每一次失败都为成功铺设了基础。只要我们保持信念,不断努力,最终会到达梦想的彼岸。无论前方的路有多么坎坷,只要心怀希望,我们就有无限的可能性去改变自己的命运,实现心中的理想。”"
|
||||
+ "由Thymeleaf模板引擎渲染。"
|
||||
+ "");
|
||||
return templateEngine.process("pdf_template", context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generatePdf(HttpServletResponse response, String htmlContent) throws IOException {
|
||||
// 设置响应类型
|
||||
response.setContentType("application/pdf");
|
||||
response.setHeader("Content-Disposition", "attachment; filename=generated.pdf");
|
||||
|
||||
// 创建ITextRenderer实例
|
||||
ITextRenderer renderer = new ITextRenderer();
|
||||
|
||||
// 设置字体路径,使用 classpath 加载字体
|
||||
ITextFontResolver fontResolver = renderer.getFontResolver();
|
||||
ClassPathResource fontResource = new ClassPathResource("fonts/SimSun.ttf");
|
||||
System.out.println(fontResource.getFile().getAbsolutePath());
|
||||
fontResolver.addFont(fontResource.getFile().getAbsolutePath(), "Identity-H", true);
|
||||
|
||||
renderer.setDocumentFromString(htmlContent);
|
||||
renderer.layout();
|
||||
|
||||
// 输出PDF到响应输出流
|
||||
try (OutputStream outputStream = response.getOutputStream()) {
|
||||
renderer.createPDF(outputStream);
|
||||
outputStream.flush();
|
||||
}
|
||||
|
||||
/*
|
||||
// 设置输出PDF文件
|
||||
OutputStream os = new FileOutputStream("index.pdf");
|
||||
renderer.createPDF(os);
|
||||
os.flush();
|
||||
os.close();*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void createSaleOrderEntryList(Long parentId, List<SaleOrderEntryDO> list) {
|
||||
list.forEach(o -> o.setParentId(parentId));
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title th:text="${title}">PDF文档</title>
|
||||
<style>
|
||||
/* 内联CSS样式,确保在PDF中正确渲染 */
|
||||
body {
|
||||
font-family: "SimSun", serif;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
color: #333;
|
||||
}
|
||||
p {
|
||||
font-size: 16px;
|
||||
color: #555;
|
||||
}
|
||||
.footer {
|
||||
text-align: center;
|
||||
margin-top: 50px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 th:text="${title}">PDF文档标题</h1>
|
||||
<p th:text="${content}">这是PDF文档的内容部分,由Thymeleaf模板引擎渲染。</p>
|
||||
<div class="footer">
|
||||
<p>© 2024 路条编程 - 保留所有权利。</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -40,6 +40,12 @@ spring:
|
|||
redis:
|
||||
time-to-live: 1h # 设置过期时间为 1 小时
|
||||
|
||||
thymeleaf:
|
||||
prefix: classpath:/templates/
|
||||
suffix: .html
|
||||
mode: HTML
|
||||
encoding: UTF-8
|
||||
cache: false
|
||||
--- #################### 接口文档配置 ####################
|
||||
|
||||
springdoc:
|
||||
|
|
|
|||
|
|
@ -81,4 +81,14 @@ export const SaleOrderApi = {
|
|||
})
|
||||
},
|
||||
|
||||
// 驳回
|
||||
rejectOrder: async (data) => {
|
||||
return await request.post({
|
||||
url: `/oms/sale-order/rejectOrder`,
|
||||
data: data
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@
|
|||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
@click="handleReject(selectionList.map((item) => item.id))"
|
||||
:disabled="selectionList.length === 0"
|
||||
>驳回
|
||||
</el-button>
|
||||
|
|
@ -267,17 +268,17 @@
|
|||
|
||||
|
||||
<!-- 驳回对话框 -->
|
||||
<!-- <el-dialog :title="rejectTitle" :visible.sync="rejectOpen" width="650px" append-to-body>-->
|
||||
<!-- <el-form ref="form" :model="rejectform" label-width="80px" >-->
|
||||
<!-- <el-form-item label="驳回原因" prop="rejectReason" >-->
|
||||
<!-- <el-input v-model="" placeholder="请输入单价" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-form>-->
|
||||
<!-- <div slot="footer" class="dialog-footer">-->
|
||||
<!-- <el-button type="primary" @click="submitRejectForm">确 定</el-button>-->
|
||||
<!-- <el-button @click="rejectCancel">取 消</el-button>-->
|
||||
<!-- </div>-->
|
||||
<!-- </el-dialog>-->
|
||||
<el-dialog :title="rejectTitle" v-model="rejectOpen" width="750px" style="height: 210px;" append-to-body>
|
||||
<el-form ref="form" :model="rejectform" label-width="80px" >
|
||||
<el-form-item label="驳回原因" prop="rejectReason" >
|
||||
<el-input v-model="rejectform.rejectReason" :rows="3" type="textarea" placeholder="请输入驳回原因" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="dialog-footer" style="text-align: right">
|
||||
<el-button type="primary" @click="submitRejectForm">确 定</el-button>
|
||||
<el-button @click="rejectCancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</template>
|
||||
|
||||
|
|
@ -340,7 +341,7 @@ const exportLoading = ref(false) // 导出的加载中
|
|||
|
||||
//驳回参数
|
||||
const rejectOpen = ref(false)
|
||||
const rejectTitle = ref()
|
||||
const rejectTitle = ref('')
|
||||
const rejectform = reactive({
|
||||
rejectReason: undefined
|
||||
})
|
||||
|
|
@ -400,29 +401,12 @@ const handleDelete = async (id: number) => {
|
|||
}
|
||||
|
||||
|
||||
/** 反审核按钮操作 */
|
||||
// const handleReject = async () => {
|
||||
// try {
|
||||
// let ids = selectionList;
|
||||
// /*let auditStatuss = row.ifaudit || this.auditStatuss;
|
||||
//
|
||||
// for(var vals of auditStatuss) {
|
||||
// if(vals!='0'){
|
||||
// message.error("请选择待审核数据");
|
||||
// return;
|
||||
// }
|
||||
// }*/
|
||||
//
|
||||
// rejectform = {
|
||||
// rejectReason: null
|
||||
// };
|
||||
// this.resetForm("rejectform");
|
||||
// this.rejectTitle = "是否驳回选中的数据项?";
|
||||
// this.rejectOpen = true;
|
||||
// } catch {}
|
||||
// },
|
||||
|
||||
|
||||
/** 驳回操作 */
|
||||
const handleReject = async (ids: number[]) => {
|
||||
rejectform.rejectReason = undefined
|
||||
rejectTitle.value = "是否驳回选中的数据项?"
|
||||
rejectOpen.value = true
|
||||
}
|
||||
/** 审批/反审批操作 */
|
||||
const handleUpdateBillStatus = async (ids: number[], operateKey: string) => {
|
||||
try {
|
||||
|
|
@ -494,23 +478,29 @@ const handleSelectionChange = (rows: SaleOrderVO[]) => {
|
|||
|
||||
|
||||
/** 驳回提交按钮 */
|
||||
/*const submitRejectForm = async () => {
|
||||
const ids = selectionList.map((item) => item.id
|
||||
if (this.rejectform.rejectReason != null) {
|
||||
const submitRejectForm = async () => {
|
||||
const ids = selectionList.value.map((item) => item.id)
|
||||
if(rejectform.rejectReason != null) {
|
||||
const data = {
|
||||
ids:ids,
|
||||
reason:this.rejectform.rejectReason
|
||||
reason:rejectform.rejectReason
|
||||
}
|
||||
/!* notAuditOrder(data).then(response => {
|
||||
this.msgSuccess("驳回成功");
|
||||
this.rejectOpen = false;
|
||||
this.getList();
|
||||
});*!/
|
||||
|
||||
await SaleOrderApi.rejectOrder(data).then(response => {
|
||||
message.success("驳回成功");
|
||||
rejectOpen.value = false;
|
||||
getList();
|
||||
});
|
||||
}else {
|
||||
message.error(`请选择驳回原因!`)
|
||||
message.error(`请填写驳回原因!`)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
/** 驳回取消按钮 */
|
||||
const rejectCancel = () =>{
|
||||
rejectOpen.value = false
|
||||
rejectform.rejectReason = undefined
|
||||
}
|
||||
|
||||
|
||||
/** 激活时 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue