diff --git a/doc/report.ftl b/doc/report.ftl index ca4aa36..d1ae676 100644 --- a/doc/report.ftl +++ b/doc/report.ftl @@ -31,21 +31,21 @@
-
-
-

- 合同编号:PS- - ${contract.contractCode}   - 客户编号: - ${contract.customId}                 -

-
-
-
+<#--
--> +<#--
--> +<#--

--> +<#-- 合同编号:PS- --> +<#-- ${contract.contractCode}   --> +<#-- 客户编号: --> +<#-- ${contract.customId}                --> +<#--

--> +<#--
--> +<#--
--> +<#--
--> <#--
-->

- ${company.companyName}

+ ${main.name}

服务合同

本合同由缔约双方在自愿、平等、公平及诚实信用原则的基础上,本着共赢互利原则,根据《中华人民共和国民法典》等

@@ -69,8 +69,24 @@
+

+ ${item.businessType}-金额:${item.businessAmount}元 + <#if item.businessDesc?? && item.businessDesc != ""> + -备注:${item.businessDesc} + +

<#list item.detailBos as detail> -

${detail.businessProjectLabel}——${detail.amount}

+

${detail.businessProjectLabel} + <#if detail.extentInfo?? && detail.extentInfo != ""> + :${detail.extentInfo} + + <#if detail.amount??> + -金额:${detail.amount} + + <#if detail.amountDesc?? && detail.amountDesc != ""> + -备注:${detail.amountDesc} + +

@@ -82,9 +98,9 @@
-

公司名称:${company.companyName}

-

账号:${company.companyAccountBank}

-

开户行:${company.companyAccountBankAdress}

+

公司名称:${main.name?if_exists}

+

账号:${main.account?if_exists}

+

开户行:${main.bank?if_exists}

@@ -98,7 +114,7 @@ 合同金额:共计¥ ${contract.contractAmount} 元(大写金额: - + ${contractAmount} 元整),垫付项目中涉及银行开户、刻章等,实际价格以第三方机构及政府规定为准。除此之外,甲方无需向乙方支付其他任何费用。

@@ -119,7 +135,7 @@

<#if text2?? && text2 != ""> - ${contract.signDesc} + ${contract.signDesc?if_exists} <#else> 无 @@ -132,7 +148,11 @@

 

一、服务期限

-

本合同中的服务周期为 至 。

+ <#if contract.startServiceDate??> +

本合同中的服务周期为 + ${contract.startServiceDate?string('yyyy年MM月dd日')}至${contract.endServiceDate?string('yyyy年MM月dd日')}。 +

+

本合同中的企业托管服务,在合同到期前 30 天,乙方有义务告知甲方。如果双方在合同期满前 30 天内未提出终止或变更要

求,未办理交接手续,本合同将自行延期一年。如为其他业务,则与双方约定时间为准。

@@ -196,9 +216,9 @@

裁决是终局性的,对双方具有约束力。因争议解决产生的案件受理费、律师费、保全费、公证费、鉴定费等由败诉方承担。

(五)本合同传真及扫描件与合同原件具有同等法律效力。

 

-

甲方名称(签章): ${customer.customName}

-

甲方联系人: ${customer.customName}

-

联系方式: ${customer.customMobile}

+

甲方名称(签章): ${company.companyName?if_exists}

+

甲方联系人: ${company.legalPersonName?if_exists}

+

联系方式: ${company.legalPersonPhone?if_exists}

签约日期: ${contract.applyDate?string('yyyy年MM月dd日')} <#-- 月 @@ -206,9 +226,9 @@

 

-

乙方名称(签章): ${customer.customName}

-

乙方联系人: ${customer.customName}

-

联系方式: ${customer.customName}

+

乙方名称(签章): ${main.name?if_exists}

+

乙方联系人: ${user.nickname?if_exists}

+

联系方式: ${user.phonenumber?if_exists}

签约日期: ${contract.applyDate?string('yyyy年MM月dd日')} <#-- 月 diff --git a/pusong-admin/src/main/java/com/pusong/web/service/SysLoginService.java b/pusong-admin/src/main/java/com/pusong/web/service/SysLoginService.java index ceeeb94..efa9e18 100644 --- a/pusong-admin/src/main/java/com/pusong/web/service/SysLoginService.java +++ b/pusong-admin/src/main/java/com/pusong/web/service/SysLoginService.java @@ -156,6 +156,7 @@ public class SysLoginService { loginUser.setUsername(user.getUserName()); loginUser.setNickname(user.getNickName()); loginUser.setUserType(user.getUserType()); + loginUser.setPhonenumber(user.getPhonenumber()); loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId())); loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId())); TenantHelper.dynamic(user.getTenantId(), () -> { diff --git a/pusong-common/pusong-common-core/src/main/java/com/pusong/common/core/domain/model/LoginUser.java b/pusong-common/pusong-common-core/src/main/java/com/pusong/common/core/domain/model/LoginUser.java index d9a98fe..cfd6c38 100644 --- a/pusong-common/pusong-common-core/src/main/java/com/pusong/common/core/domain/model/LoginUser.java +++ b/pusong-common/pusong-common-core/src/main/java/com/pusong/common/core/domain/model/LoginUser.java @@ -106,6 +106,12 @@ public class LoginUser implements Serializable { */ private String nickname; + + /** + * 手机号 + */ + private String phonenumber; + /** * 角色对象 */ diff --git a/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/NumBerTool.java b/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/NumBerTool.java new file mode 100644 index 0000000..ee834bd --- /dev/null +++ b/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/NumBerTool.java @@ -0,0 +1,118 @@ +package com.pusong.common.doc.util; + +public class NumBerTool { + private static final String[] NUMBERS = { "零", "壹", "贰", "叁", "肆", "伍", "陆", + "柒", "捌", "玖" }; + /** 整数部分的单位 */ + private static final String[] IUNIT = { "元", "拾", "佰", "仟", "万", "拾", "佰", + "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟" }; + /** 小数部分的单位 */ + private static final String[] DUNIT = { "角", "分"}; + + + /** + * 得到大写金额。 + */ + public static String digitUppercase(String str) { + str = str.replaceAll(",", "");// 去掉"," + String integerStr;// 整数部分数字 + String decimalStr;// 小数部分数字 + // 初始化:分离整数部分和小数部分 + if (str.indexOf(".") > 0) { + integerStr = str.substring(0, str.indexOf(".")); + decimalStr = str.substring(str.indexOf(".") + 1); + } else if (str.indexOf(".") == 0) { + integerStr = ""; + decimalStr = str.substring(1); + } else { + integerStr = str; + decimalStr = ""; + } + // integerStr去掉首0,不必去掉decimalStr的尾0(超出部分舍去) + if (!integerStr.equals("")) { + integerStr = Long.toString(Long.parseLong(integerStr)); + if (integerStr.equals("0")) { + integerStr = ""; + } + } + // overflow超出处理能力,直接返回 + if (integerStr.length() > IUNIT.length) { + System.out.println(str + ":超出处理能力"); + return str; + } + int[] integers = toArray(integerStr);// 整数部分数字 + boolean isMust5 = isMust5(integerStr);// 设置万单位 + int[] decimals = toArray(decimalStr);// 小数部分数字 + return getChineseInteger(integers, isMust5) + getChineseDecimal(decimals); + } + /** + * 整数部分和小数部分转换为数组,从高位至低位 + */ + private static int[] toArray(String number) { + int[] array = new int[number.length()]; + for (int i = 0; i < number.length(); i++) { + array[i] = Integer.parseInt(number.substring(i, i + 1)); + } + return array; + } + /** + * 得到中文金额的整数部分。 + */ + private static String getChineseInteger(int[] integers, boolean isMust5) { + StringBuffer chineseInteger = new StringBuffer(""); + int length = integers.length; + for (int i = 0; i < length; i++) { + // 0出现在关键位置:1234(万)5678(亿)9012(万)3456(元) + // 特殊情况:10(拾元、壹拾元、壹拾万元、拾万元) + String key = ""; + if (integers[i] == 0) { + if ((length-i) == 13)// 万(亿)(必填) + key = IUNIT[4]; + else if ((length-i) == 9)// 亿(必填) + key = IUNIT[8]; + else if ((length-i) == 5 && isMust5)// 万(不必填) + key = IUNIT[4]; + else if ((length-i) == 1)// 元(必填) + key = IUNIT[0]; + // 0遇非0时补零,不包含最后一位 + if ((length-i) > 1 && integers[i + 1] != 0) + key += NUMBERS[0]; + } + chineseInteger.append(integers[i] == 0 ? key + : (NUMBERS[integers[i]] + IUNIT[length - i - 1])); + } + return chineseInteger.toString(); + } + /** + * 得到中文金额的小数部分。 + */ + private static String getChineseDecimal(int[] decimals) { + StringBuffer chineseDecimal = new StringBuffer(""); + for (int i = 0; i < decimals.length; i++) { + // 舍去2位小数之后的 + if (i == 2) + break; + chineseDecimal.append(decimals[i] == 0 ? "" + : (NUMBERS[decimals[i]] + DUNIT[i])); + } + return chineseDecimal.toString(); + } + /** + * 判断第5位数字的单位"万"是否应加。 + */ + private static boolean isMust5(String integerStr) { + int length = integerStr.length(); + if (length > 4) { + String subInteger = ""; + if (length > 8) { + // 取得从低位数,第5到第8位的字串 + subInteger = integerStr.substring(length-8, length-4); + } else { + subInteger = integerStr.substring(0, length-4); + } + return Integer.parseInt(subInteger) > 0; + } else { + return false; + } + } +} \ No newline at end of file diff --git a/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PDFBuilder.java b/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PDFBuilder.java index 8fddb45..a95f599 100644 --- a/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PDFBuilder.java +++ b/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PDFBuilder.java @@ -3,15 +3,9 @@ package com.pusong.common.doc.util; import java.io.IOException; -import com.itextpdf.text.Document; -import com.itextpdf.text.DocumentException; -import com.itextpdf.text.Element; -import com.itextpdf.text.Font; -import com.itextpdf.text.Image; -import com.itextpdf.text.PageSize; -import com.itextpdf.text.Phrase; -import com.itextpdf.text.Rectangle; +import com.itextpdf.text.*; import com.itextpdf.text.pdf.*; +import com.pusong.common.core.utils.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,59 +20,47 @@ public class PDFBuilder extends PdfPageEventHelper { /** * 页眉 */ - public String header = ""; - + public String header ; /** - * 文档字体大小,页脚页眉最好和文本大小一致 + * 是否签章 */ - public int presentFontSize = 10; - + public Boolean isSign ; /** - * 文档页面大小,最好前面传入,否则默认为A4纸张 + * 是否签章 */ - public Rectangle pageSize = PageSize.A4; - - // 模板 - public PdfTemplate total; - - // 基础字体对象 - public BaseFont bf = null; - + public String imagepath ; // 利用基础字体生成的字体对象,一般用于生成中文文字 - public Font fontDetail = null; + public static Font fontDetail = null; + // 基础字体对象 + private static BaseFont baseFont; + // 生成下划线空白占位符 + private static String Blank; + static { + try { + // 中文字体依赖itext得itext-asian包 + baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 212; i++) { + sb.append("\u00a0"); + } + Blank = sb.toString(); + fontDetail = new Font(baseFont); + } catch (DocumentException e) { + log.error("初始化字体失败", e); + } catch (IOException e) { + log.error("初始化字体失败", e); + } + } /** * * Creates a new instance of PdfReportM1HeaderFooter 无参构造方法. * */ - public PDFBuilder() { - - } - - /** - * - * Creates a new instance of PdfReportM1HeaderFooter 构造方法. - * - * @param yeMei - * 页眉字符串 - * @param presentFontSize - * 数据体字体大小 - * @param pageSize - * 页面文档大小,A4,A5,A6横转翻转等Rectangle对象 - */ - public PDFBuilder(String yeMei, int presentFontSize, Rectangle pageSize) { - this.header = yeMei; - this.presentFontSize = presentFontSize; - this.pageSize = pageSize; - } - - public void setHeader(String header) { - this.header = header; - } - - public void setPresentFontSize(int presentFontSize) { - this.presentFontSize = presentFontSize; + public PDFBuilder(Object header,Object isSign,String imagepath) { + this.header = header == null?null:header.toString(); + this.isSign = isSign == null?null:(Boolean)isSign; + this.imagepath = imagepath; } /** @@ -88,9 +70,15 @@ public class PDFBuilder extends PdfPageEventHelper { * @see com.itextpdf.text.pdf.PdfPageEventHelper#onOpenDocument(com.itextpdf.text.pdf.PdfWriter, * com.itextpdf.text.Document) */ - /* public void onOpenDocument(PdfWriter writer, Document document) { - total = writer.getDirectContent().createTemplate(50, 50);// 共 页 的矩形的长宽高 - }*/ + public void onOpenDocument(PdfWriter writer, Document document) { + } + + @Override + + public void onStartPage(PdfWriter writer, Document document) { + super.onStartPage(writer, document); + + } /** * @@ -100,85 +88,44 @@ public class PDFBuilder extends PdfPageEventHelper { * com.itextpdf.text.Document) */ public void onEndPage(PdfWriter writer, Document document) { -// this.addPage(writer, document); - this.addWatermark(writer); + //是否添加页眉 + if(StringUtils.isNotBlank(header)){ + this.addPage(writer, document); + } + //是否签章 + if(isSign){ + this.addSign(writer); + } + } //加分页 - public void addPage(PdfWriter writer, Document document){ - try { - if (bf == null) { - bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false); - } - if (fontDetail == null) { - fontDetail = new Font(bf, presentFontSize, Font.NORMAL);// 数据体字体 - } - } catch (DocumentException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); + public void addPage(PdfWriter writer, Document document) { + //页眉没有数据的话直接return + if(StringUtils.isBlank(header)){ + return; } - + //生成下划线,使用空格占位 + ColumnText.showTextAligned(writer.getDirectContent(), + Element.ALIGN_LEFT, new Phrase(PDFBuilder.Blank, new Font(PDFBuilder.baseFont, Font.DEFAULTSIZE, Font.UNDERLINE)), + document.left(-1), document.top()+10, 0); // 1.写入页眉 ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, new Phrase(header, fontDetail), - document.right()/2, document.top() - 17, 0); - - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < 210; i++) { - sb.append("\u00a0"); - } - - ColumnText.showTextAligned(writer.getDirectContent(), - Element.ALIGN_LEFT, new Phrase(sb.toString(), fontDetail), - document.left(-1), document.top() -50, 0); - -// // 2.写入前半部分的 第 X页/共 -// int pageS = writer.getPageNumber(); -// String foot1 = "第 " + pageS + " 页 /共"; -// Phrase footer = new Phrase(foot1, fontDetail); -// -// // 3.计算前半部分的foot1的长度,后面好定位最后一部分的'Y页'这俩字的x轴坐标,字体长度也要计算进去 = len -// float len = bf.getWidthPoint(foot1, presentFontSize); -// -// // 4.拿到当前的PdfContentByte -// PdfContentByte cb = writer.getDirectContent(); -// -// // 5.写入页脚1,x轴就是(右margin+左margin + right() -left()- len)/2.0F -// // 再给偏移20F适合人类视觉感受,否则肉眼看上去就太偏左了 -// // ,y轴就是底边界-20,否则就贴边重叠到数据体里了就不是页脚了;注意Y轴是从下往上累加的,最上方的Top值是大于Bottom好几百开外的。 -// ColumnText -// .showTextAligned( -// cb, -// Element.ALIGN_CENTER, -// footer, -// (document.rightMargin() + document.right() -// + document.leftMargin() - document.left() - len) / 2.0F + 20F, -// document.bottom() - 20, 0); -// -// // 6.写入页脚2的模板(就是页脚的Y页这俩字)添加到文档中,计算模板的和Y轴,X=(右边界-左边界 - 前半部分的len值)/2.0F + -// // len , y 轴和之前的保持一致,底边界-20 -// cb.addTemplate(total, (document.rightMargin() + document.right() -// + document.leftMargin() - document.left()) / 2.0F + 20F, -// document.bottom() - 20); // 调节模版显示的位置 - + document.right()/2+20, document.top()+10 , 0); } - public static void main(String[] args) { - System.out.println(System.getProperty("user.dir")); - } - //加水印 - public void addWatermark(PdfWriter writer){ + //加半章图片 + public void addSign(PdfWriter writer){ String psth; - if(writer.getPageNumber() == 1){ - psth = System.getProperty("user.dir")+"\\doc\\image\\leftZ.png"; - }else if (writer.getPageNumber() == 2){ - psth = System.getProperty("user.dir")+"\\doc\\image\\rightZ.png"; - }else{ + if(writer.getPageNumber()%2 == 1){ + psth = imagepath+"\\doc\\image\\leftZ.png"; + }else/* if (writer.getPageNumber() == 2)*/{ + psth = imagepath+"\\doc\\image\\rightZ.png"; + }/*else{ return; - } - // 水印图片 + }*/ + // 加半章图片 Image image; try { image = Image.getInstance(psth); @@ -187,17 +134,9 @@ public class PDFBuilder extends PdfPageEventHelper { content.beginText(); image.setAbsolutePosition(450+75,400); content.addImage(image); -// // 开始写入水印 -// for(int k=0;k<5;k++){ -// for (int j = 0; j <4; j++) { -// image.setAbsolutePosition(150*j,170*k); -// content.addImage(image); -// } -// } content.endText(); } catch (IOException | DocumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.error("加半章图片异常",e); } } diff --git a/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PdfGenerator.java b/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PdfGenerator.java index 066dbae..63da866 100644 --- a/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PdfGenerator.java +++ b/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PdfGenerator.java @@ -2,6 +2,7 @@ package com.pusong.common.doc.util; import com.alibaba.fastjson.JSON; import com.itextpdf.text.Document; +import com.itextpdf.text.PageSize; import com.itextpdf.text.pdf.PdfWriter; import com.itextpdf.tool.xml.XMLWorkerHelper; import freemarker.template.Configuration; @@ -20,7 +21,10 @@ import java.util.Map; public class PdfGenerator { private static final Logger log = LoggerFactory.getLogger(PdfGenerator.class); - + //标题 + public static final String HEAD = "head"; + //是否签章 + public static final String SIGN = "isSign"; public static void main(String[] args) throws Exception { @@ -48,8 +52,11 @@ public class PdfGenerator { // String html = processTemplate(template, data); // // 生成PDF // generatePdf(html, "D:/王立帅/临时/output.pdf"); - String str = " - {\"business\":[{\"businessAmount\":500,\"businessType\":\"1\",\"contractCode\":\"\",\"detailBos\":[{\"amount\":100,\"amountDesc\":\"备注\",\"businessProject\":\"1\",\"businessProjectLabel\":\"测试1\",\"contractCode\":\"\",\"id\":0}],\"id\":0}],\"contract\":{\"applyDate\":1722355200000,\"companyId\":0,\"contractAmount\":500,\"contractCode\":\"\",\"contractMain\":\"1\",\"contractName\":\"合同名称\",\"customId\":1816388144534081538,\"customManager\":1,\"customScene\":\"\",\"isProxy\":\"\",\"params\":{},\"payModeDesc\":\"支付方式\",\"signDesc\":\"描述描述\"},\"company\":{\"companyAccountBank\":\"银行编码\",\"companyAccountBankAdress\":\"开户行地址\",\"companyAdress\":\"公司地址\",\"companyName\":\"公司名\",\"customId\":0,\"id\":0,\"legalPersonIdcard\":\"法人身份证\",\"legalPersonName\":\"法人姓名\",\"legalPersonPhone\":\"法人手机号\"},\"customer\":{\"black\":\"0\",\"createBy\":1,\"createDept\":103,\"createTime\":1721895655000,\"customLevel\":\"2\",\"customManager\":3,\"customMobile\":\"13511245332\",\"customName\":\"东洲\",\"customSource\":\"抖音\",\"customStatus\":\"1\",\"delFlag\":0,\"id\":1816388144534081538,\"params\":{},\"tenantId\":\"000000\",\"updateBy\":1,\"updateTime\":1723097358000}}"; - makePdf(JSON.parseObject(str,Map.class),"D:/王立帅/临时/output.pdf","report.ftl"); + String str = "{\"business\":[{\"businessAmount\":500,\"businessType\":\"1\",\"contractCode\":\"\",\"detailBos\":[{\"amount\":100,\"amountDesc\":\"备注\",\"businessProject\":\"1\",\"businessProjectLabel\":\"测试1\",\"contractCode\":\"\",\"id\":0}],\"id\":0}],\"contract\":{\"applyDate\":1722355200000,\"companyId\":0,\"contractAmount\":500,\"contractCode\":\"\",\"contractMain\":\"1\",\"contractName\":\"合同名称\",\"customId\":1816388144534081538,\"customManager\":1,\"customScene\":\"\",\"isProxy\":\"\",\"params\":{},\"payModeDesc\":\"支付方式\",\"signDesc\":\"描述描述\"},\"company\":{\"companyAccountBank\":\"银行编码\",\"companyAccountBankAdress\":\"开户行地址\",\"companyAdress\":\"公司地址\",\"companyName\":\"公司名\",\"customId\":0,\"id\":0,\"legalPersonIdcard\":\"法人身份证\",\"legalPersonName\":\"法人姓名\",\"legalPersonPhone\":\"法人手机号\"},\"customer\":{\"black\":\"0\",\"createBy\":1,\"createDept\":103,\"createTime\":1721895655000,\"customLevel\":\"2\",\"customManager\":3,\"customMobile\":\"13511245332\",\"customName\":\"东洲\",\"customSource\":\"抖音\",\"customStatus\":\"1\",\"delFlag\":0,\"id\":1816388144534081538,\"params\":{},\"tenantId\":\"000000\",\"updateBy\":1,\"updateTime\":1723097358000}}"; + Map map = JSON.parseObject(str, Map.class); + map.put(HEAD,"sss"); + map.put(SIGN,true); + makePdf(map,"D:/王立帅/临时/output.pdf","report.ftl"); } @@ -64,8 +71,9 @@ public class PdfGenerator { // 生成HTML String html = processTemplate(template, data); // 生成PDF -// generatePdf(html, "D:/王立帅/临时/output.pdf"); - generatePdf(html, pdfpath); + PDFBuilder builder = new PDFBuilder(data.get(HEAD),data.get(SIGN),System.getProperty("user.dir")); + generatePdf(html, pdfpath, builder); + } private static String processTemplate(Template template, Map data) throws IOException, TemplateException { StringWriter writer = new StringWriter(); @@ -73,13 +81,13 @@ public class PdfGenerator { return writer.toString(); } - private static void generatePdf(String html, String outputPath) { + private static void generatePdf(String html, String outputPath,PDFBuilder builder) { Document document = null; PdfWriter writer = null; try{ - document = new Document(); + document = new Document(PageSize.A4, 36, 36, 50, 50); writer = PdfWriter.getInstance(document, new FileOutputStream(outputPath)); - PDFBuilder builder = new PDFBuilder(); + writer.setPageEvent(builder); document.open(); XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(html.getBytes()), diff --git a/pusong-modules/pusong-business/src/main/java/com/pusong/business/service/impl/PsContractInfoServiceImpl.java b/pusong-modules/pusong-business/src/main/java/com/pusong/business/service/impl/PsContractInfoServiceImpl.java index 91643ad..64accb8 100644 --- a/pusong-modules/pusong-business/src/main/java/com/pusong/business/service/impl/PsContractInfoServiceImpl.java +++ b/pusong-modules/pusong-business/src/main/java/com/pusong/business/service/impl/PsContractInfoServiceImpl.java @@ -12,17 +12,22 @@ import com.pusong.business.service.*; import com.pusong.business.service.approver.ApproverContainer; import com.pusong.business.service.approver.ApproverService; import com.pusong.common.core.constant.UserConstants; +import com.pusong.common.core.domain.model.LoginUser; import com.pusong.common.core.exception.ServiceException; +import com.pusong.common.core.service.DictService; import com.pusong.common.core.utils.DateUtils; import com.pusong.common.core.utils.MapstructUtils; import com.pusong.common.core.utils.StringUtils; +import com.pusong.common.doc.util.NumBerTool; import com.pusong.common.doc.util.PdfGenerator; import com.pusong.common.mybatis.core.page.TableDataInfo; import com.pusong.common.mybatis.core.page.PageQuery; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.pusong.common.satoken.utils.LoginHelper; +import com.pusong.system.domain.SysDictData; import com.pusong.system.domain.vo.SysOssVo; +import com.pusong.system.service.ISysDictDataService; import com.pusong.system.service.ISysOssService; import jakarta.annotation.Resource; import jodd.util.StringUtil; @@ -34,6 +39,7 @@ import org.springframework.transaction.annotation.Transactional; import java.io.File; import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors; @@ -66,6 +72,13 @@ public class PsContractInfoServiceImpl implements IPsContractInfoService { private final ApproverContainer container; private final IPsTaskService taskMainService; + + private final ISysDictDataService dictDataService; + public static String getContractCode(){ + Random random = new Random(); + int randomNumber = random.nextInt(8999) + 1000; + return DateUtils.parseDateToStr("yyyyMMddHHmm",new Date())+randomNumber; + } /** * 生成合同 * @@ -84,8 +97,9 @@ public class PsContractInfoServiceImpl implements IPsContractInfoService { if(add == null){ add = new PsContractInfo(); MapstructUtils.convert(bo, add); - add.setContractCode(UUID.randomUUID().toString().replaceAll("-", ""));//合同编码 - add.setContractName("合同名称");//todo 合同名称 + add.setContractCode(getContractCode());//合同编码 + // 合同名称:公司名+合同编码 + add.setContractName(bo.getCompanyInfoBo().getCompanyName()+add.getContractCode()); add.setCustomManager(LoginHelper.getUserId());//所属销售经理id }else{ MapstructUtils.convert(bo, add); @@ -120,11 +134,22 @@ public class PsContractInfoServiceImpl implements IPsContractInfoService { public Long preview(PsContractInfoBo bo){ //3.如果已存在合同,则进行修改,否则新增 PsContractInfo add = new PsContractInfo(); - add.setContractCode("0000000000-1");//合同编码 - add.setContractName("合同名称");//todo 合同名称 + add.setContractCode(getContractCode());//合同编码 + // 合同名称:公司名+合同编码 + add.setContractName(bo.getCompanyInfoBo().getCompanyName()+add.getContractCode()); add.setCustomManager(LoginHelper.getUserId());//所属销售经理id add.setCompanyId(bo.getCompanyInfoBo().getId());//公司id MapstructUtils.convert(bo, add); + bo.getBusinessList().forEach(item->{ + BigDecimal mony = BigDecimal.ZERO; + if(CollectionUtils.isNotEmpty(item.getDetailBos())){ + mony = item.getDetailBos().stream().map(PsContractBusinessDetailBo::getAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); + } + //服务类别填了才会修改服务项目的金额 + if(mony.compareTo(BigDecimal.ZERO) > 0){ + item.setBusinessAmount(mony); + } + }); BigDecimal sum = bo.getBusinessList().stream().map(PsContractBusinessBo::getBusinessAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); add.setContractAmount(sum);//合同总金额 return makePdf(add,bo); @@ -309,14 +334,20 @@ public class PsContractInfoServiceImpl implements IPsContractInfoService { */ public Long makePdf(PsContractInfo add ,PsContractInfoBo bo){ Long ossId = null; + SysDictData main = dictDataService.selectDict("contract_main", add.getContractMain()); try{ //生成合同pdf PsCustomInfo customer = customInfoService.listById(add.getCustomId()); Map map = new HashMap<>(); + LoginUser user = LoginHelper.getLoginUser(); + map.put("user",user); map.put("contract",add); map.put("business",bo.getBusinessList()); + map.put("main",JSON.parseObject(main.getRemark()));// 合同主体信息 map.put("company",bo.getCompanyInfoBo()); map.put("customer",customer); + // 合同总金额大写 + map.put("contractAmount", NumBerTool.digitUppercase(add.getContractAmount().setScale(2, RoundingMode.HALF_EVEN).toString())); String head = "合同编号:PS-"+add.getContractCode()+" 客户编号:"+customer.getId(); //合同标题 map.put(PdfGenerator.HEAD,head); diff --git a/pusong-modules/pusong-system/src/main/java/com/pusong/system/service/ISysDictDataService.java b/pusong-modules/pusong-system/src/main/java/com/pusong/system/service/ISysDictDataService.java index 4f731cc..9366181 100644 --- a/pusong-modules/pusong-system/src/main/java/com/pusong/system/service/ISysDictDataService.java +++ b/pusong-modules/pusong-system/src/main/java/com/pusong/system/service/ISysDictDataService.java @@ -2,6 +2,7 @@ package com.pusong.system.service; import com.pusong.common.mybatis.core.page.PageQuery; import com.pusong.common.mybatis.core.page.TableDataInfo; +import com.pusong.system.domain.SysDictData; import com.pusong.system.domain.bo.SysDictDataBo; import com.pusong.system.domain.vo.SysDictDataVo; @@ -34,6 +35,15 @@ public interface ISysDictDataService { */ String selectDictLabel(String dictType, String dictValue); + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典对象 + */ + SysDictData selectDict(String dictType, String dictValue); + /** * 根据字典数据ID查询信息 * diff --git a/pusong-modules/pusong-system/src/main/java/com/pusong/system/service/impl/SysDictDataServiceImpl.java b/pusong-modules/pusong-system/src/main/java/com/pusong/system/service/impl/SysDictDataServiceImpl.java index 320d5b0..dd1740d 100644 --- a/pusong-modules/pusong-system/src/main/java/com/pusong/system/service/impl/SysDictDataServiceImpl.java +++ b/pusong-modules/pusong-system/src/main/java/com/pusong/system/service/impl/SysDictDataServiceImpl.java @@ -79,6 +79,20 @@ public class SysDictDataServiceImpl implements ISysDictDataService { .getDictLabel(); } + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + @Override + public SysDictData selectDict(String dictType, String dictValue) { + return baseMapper.selectOne(new LambdaQueryWrapper() + .eq(SysDictData::getDictType, dictType) + .eq(SysDictData::getDictValue, dictValue)); + } + /** * 根据字典数据ID查询信息 *