Browse Source

[feat]采购管理

采购订单前端列表页面新增导出供应商合同按钮和js方法,加上对主子表数据的判断
采购订单后端新增导出供应商合同接口,完成对供应商模板的数据填充
采购订单子表新增 通过供应商code查询采购订单子表集合后端接口;新增通过供应商code和采购订单code查询采购订单子表集合后端接口
[feat]公司信息
新增 查询所有公司信息后端接口
[feat]供应商
新增 根据供应商编码查询供应商信息后端接口
[feat]项目依赖
更新项目后端框架springboot升级版本由旧版本升级成2.5.15版本.解决与新导出模块框架不兼容问题
导入poi-ooxml依赖5.5.3
导入poi依赖5.5.3
导入poi-ooxml-schemas依赖4.1.2
导入poi-scratchpad依赖5.2.3
导入log4j-api依赖 2.17.1
导入poi-tl依赖1.12.0
排除原有过旧easyexcel中的poi-ooxml、poi-ooxml-schemas和poi依赖,解决依赖冲突问题
更新项目中shiro依赖
[feat]通用模块
新增 通用金钱工具类,完成数字金额转换成中文大写金额
新增 通用下载工具类,处理统一附件文件存储路径
[feat]附件
新增合同模板
[fix]配置文件
修改新版配置文件
[fix]核心配置模块
修改旧版定时任务配置类
dev
liuxiaoxu 3 months ago
parent
commit
728fadeb4f
  1. 38
      pom.xml
  2. 28
      ruoyi-admin/src/main/java/com/ruoyi/purchase/controller/PurchaseOrderController.java
  3. 13
      ruoyi-admin/src/main/java/com/ruoyi/purchase/mapper/PurchaseOrderChildMapper.java
  4. 6
      ruoyi-admin/src/main/java/com/ruoyi/purchase/service/IPurchaseOrderService.java
  5. 140
      ruoyi-admin/src/main/java/com/ruoyi/purchase/service/impl/PurchaseOrderServiceImpl.java
  6. 5
      ruoyi-admin/src/main/java/com/ruoyi/system/mapper/SysCompanyInformationMapper.java
  7. 6
      ruoyi-admin/src/main/java/com/ruoyi/system/mapper/SysSupplierMapper.java
  8. 7
      ruoyi-admin/src/main/java/com/ruoyi/system/service/ISysSupplierService.java
  9. 11
      ruoyi-admin/src/main/java/com/ruoyi/system/service/impl/SysSupplierServiceImpl.java
  10. 43
      ruoyi-admin/src/main/resources/application.yml
  11. BIN
      ruoyi-admin/src/main/resources/attachments/采购合同.docx
  12. 13
      ruoyi-admin/src/main/resources/mapper/purchase/PurchaseOrderChildMapper.xml
  13. 4
      ruoyi-admin/src/main/resources/mapper/system/SysCompanyInformationMapper.xml
  14. 6
      ruoyi-admin/src/main/resources/mapper/system/SysSupplierMapper.xml
  15. 79
      ruoyi-admin/src/main/resources/templates/purchase/purchaseOrder/purchaseOrder.html
  16. 44
      ruoyi-common/pom.xml
  17. 61
      ruoyi-common/src/main/java/com/ruoyi/common/utils/MoneyUtils.java
  18. 20
      ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileDownloadUtils.java
  19. 114
      ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java
  20. 14
      ruoyi-system/pom.xml

38
pom.xml

@ -16,8 +16,9 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<shiro.version>1.7.1</shiro.version>
<thymeleaf.extras.shiro.version>2.0.0</thymeleaf.extras.shiro.version>
<shiro.version>1.13.0</shiro.version>
<spring-framework.version>5.3.33</spring-framework.version>
<thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
<druid.version>1.2.6</druid.version>
<bitwalker.version>1.21</bitwalker.version>
<kaptcha.version>2.3.2</kaptcha.version>
@ -27,9 +28,9 @@
<fastjson.version>1.2.76</fastjson.version>
<oshi.version>5.6.0</oshi.version>
<jna.version>5.7.0</jna.version>
<commons.io.version>2.5</commons.io.version>
<commons.io.version>2.11.0</commons.io.version>
<commons.fileupload.version>1.3.3</commons.fileupload.version>
<poi.version>4.1.2</poi.version>
<!-- <poi.version>4.1.2</poi.version>-->
<velocity.version>1.7</velocity.version>
<activiti.version>6.0.0</activiti.version>
</properties>
@ -42,7 +43,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.13.RELEASE</version>
<version>2.5.15</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -82,6 +83,7 @@
<version>${shiro.version}</version>
</dependency>
<!-- thymeleaf模板引擎和shiro框架的整合 -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
@ -167,12 +169,12 @@
<version>${commons.fileupload.version}</version>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<!-- &lt;!&ndash; excel工具 &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.apache.poi</groupId>-->
<!-- <artifactId>poi-ooxml</artifactId>-->
<!-- <version>${poi.version}</version>-->
<!-- </dependency>-->
@ -182,6 +184,20 @@
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>

28
ruoyi-admin/src/main/java/com/ruoyi/purchase/controller/PurchaseOrderController.java

@ -120,19 +120,29 @@ public class PurchaseOrderController extends BaseController
/**
*
* 导出采购订单列表
* 导出采购订单合同
*/
@RequiresPermissions("purchase:purchaseOrder:export")
// @RequiresPermissions("purchase:purchaseOrder:export")
// @Log(title = "采购订单", businessType = BusinessType.EXPORT)
// @GetMapping("/export/{purchaseOrderCode}")
// public void export(@PathVariable("purchaseOrderCode") String purchaseOrderCode, HttpServletResponse response) {
// PurchaseOrder purchaseOrder = purchaseOrderService.selectPurchaseOrderByOrderCode(purchaseOrderCode);
// purchaseOrderService.exportPurchaseOrder(purchaseOrder, response);
// }
/**
*
* 导出采购订单供应商合同
*/
@RequiresPermissions("purchase:purchaseOrder:exportContract")
@Log(title = "采购订单", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(PurchaseOrder purchaseOrder)
{
List<PurchaseOrderVo> list = purchaseOrderService.selectPurchaseOrderList(purchaseOrder);
ExcelUtil<PurchaseOrderVo> util = new ExcelUtil<PurchaseOrderVo>(PurchaseOrderVo.class);
return util.exportExcel(list, "采购订单数据");
@GetMapping("/exportContract/{purchaseOrderCode}")
public void export(@PathVariable("purchaseOrderCode") String purchaseOrderCode,@RequestParam("supplierCode") String supplierCode ,HttpServletResponse response) {
PurchaseOrder purchaseOrder = purchaseOrderService.selectPurchaseOrderByOrderCode(purchaseOrderCode);
purchaseOrderService.exportPurchaseOrder(purchaseOrder,supplierCode, response);
}
/**
* 新增采购订单
*/

13
ruoyi-admin/src/main/java/com/ruoyi/purchase/mapper/PurchaseOrderChildMapper.java

@ -80,4 +80,17 @@ public interface PurchaseOrderChildMapper
List<PurchaseOrderChild> selectPurchaseOrderChildByOrderCodeTotal(String purchaseOrderCode);
List<PurchaseOrderChild> selectPurchaseOrderStorageByPurchaseOrderCode(String purchaseOrderCode);
/**
* 通过供应商code查询采购订单子表集合
* */
List<PurchaseOrderChild> selectPurchaseOrderChildBySupplierCode(String supplierCode);
/**
* 通过供应商code和采购订单code查询采购订单子表集合
* */
List<PurchaseOrderChild> selectChildListBySupplierCodeAndOrderCode(PurchaseOrderChild purchaseOrderChild);
}

6
ruoyi-admin/src/main/java/com/ruoyi/purchase/service/IPurchaseOrderService.java

@ -6,6 +6,7 @@ import com.ruoyi.warehouse.domain.WarehouseStorageOrder;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
@ -82,4 +83,9 @@ public interface IPurchaseOrderService
public ProcessInstance cancelPurchaseOrderById(Long id);
public ProcessInstance restorePurchaseOrderById(Long id);
/**
* 导出采购订单供应商合同
* */
void exportPurchaseOrder(PurchaseOrder purchaseOrder, String supplierCode ,HttpServletResponse response);
}

140
ruoyi-admin/src/main/java/com/ruoyi/purchase/service/impl/PurchaseOrderServiceImpl.java

@ -1,5 +1,10 @@
package com.ruoyi.purchase.service.impl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.github.pagehelper.Page;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
@ -8,9 +13,11 @@ import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.service.ICommonService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MoneyUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.file.FileDownloadUtils;
import com.ruoyi.erp.domain.ErpDevelopModifyorder;
import com.ruoyi.erp.mapper.ErpDevelopModifyorderMapper;
import com.ruoyi.financial.domain.FinancialAccountsPayable;
@ -25,8 +32,10 @@ import com.ruoyi.purchase.mapper.PurchaseOrderChildMapper;
import com.ruoyi.purchase.mapper.PurchaseOrderMapper;
import com.ruoyi.purchase.mapper.PurchasePlanMapper;
import com.ruoyi.purchase.service.IPurchaseOrderService;
import com.ruoyi.system.domain.SysCompanyInformation;
import com.ruoyi.system.domain.SysSupplier;
import com.ruoyi.system.domain.Vo.SysSupplierVo;
import com.ruoyi.system.mapper.SysCompanyInformationMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysAttachFileService;
import com.ruoyi.system.service.ISysAttachService;
@ -46,8 +55,16 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@ -113,6 +130,9 @@ public class PurchaseOrderServiceImpl implements IPurchaseOrderService
@Autowired
private ErpDevelopModifyorderMapper developModifyorderMapper;
@Autowired
private SysCompanyInformationMapper companyInformationMapper;
/**
* 查询采购订单
*
@ -679,6 +699,123 @@ public class PurchaseOrderServiceImpl implements IPurchaseOrderService
purchaseOrderMapper.updatePurchaseOrder(purchaseOrder);
return processInstance;
}
@Override
public void exportPurchaseOrder(PurchaseOrder purchaseOrder, String supplierCode, HttpServletResponse response) {
String fileName = "采购合同.docx";
FileDownloadUtils fileDownloadUtils = new FileDownloadUtils();
try {
String fileAbsolutePath = fileDownloadUtils.getFileAbsolutePath(fileName);
//处理供应商
SysSupplier sysSupplier = sysSupplierService.selectSysSupplierByCode(supplierCode);
String realFileName = sysSupplier.getSupplierName() +"-"+ fileName.substring(0, fileName.lastIndexOf("."))+ ".docx";
// 设置响应头,指定文件名和文件类型
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(realFileName, "UTF-8"));
response.setContentType("application/octet-stream");
String purchaseOrderCode = purchaseOrder.getPurchaseOrderCode();
//下单日期
Date applyTime = purchaseOrder.getApplyTime();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String orderDate = dateFormat.format(applyTime);
PurchaseOrderChild purchaseOrderChild = new PurchaseOrderChild();
purchaseOrderChild.setPurchaseOrderCode(purchaseOrderCode);
purchaseOrderChild.setSupplierCode(supplierCode);
List<PurchaseOrderChild> purchaseOrderChildList = purchaseOrderChildService.selectChildListBySupplierCodeAndOrderCode(purchaseOrderChild);
List<Map<String, Object>> detailList = new ArrayList<>();
// 数字合计金额
BigDecimal totalAmount = purchaseOrderChildList.stream()
.filter(item -> item.getMaterialRealRmbSum() != null) // 过滤掉值为空的字段
.map(item -> item.getMaterialRealRmbSum())
.reduce(BigDecimal.ZERO, BigDecimal::add);
//转换成中文金额 //汉字大写合计金额
String ChineseCharacterAmount = MoneyUtils.toChineseCapitalized(totalAmount);
AtomicInteger index = new AtomicInteger(1);
for (PurchaseOrderChild item : purchaseOrderChildList) {
Map<String, Object> detailMap = new HashMap<>();
detailMap.put("index", index.getAndIncrement());
detailMap.put("materialName", item.getMaterialName());
detailMap.put("materialDescribe", item.getMaterialDescribe());
detailMap.put("materialUnit", item.getMaterialUnit());
detailMap.put("materialRealNum", item.getMaterialRealNum());
detailMap.put("materialRealRmb", item.getMaterialRealRmb());
detailMap.put("materialRealRmbSum", item.getMaterialRealRmbSum());
// 使用 Optional 来安全地处理可能为 null 的值
Optional<Date> optionalDeliveryTime = Optional.ofNullable(item.getDeliveryTime());
String formattedDeliveryTime = optionalDeliveryTime.map(dateFormat::format).orElse("未提供");
detailMap.put("deliveryTime", formattedDeliveryTime);
detailList.add(detailMap);
}
//查询仓库信息
//查询万材的公司信息
List<SysCompanyInformation> companyInformations = companyInformationMapper.selectSysCompanyInformationAllList();
SysCompanyInformation sysCompanyInformation = companyInformations.get(0);
String enterpriseName = sysCompanyInformation.getEnterpriseName();
String bankAccountWC = sysCompanyInformation.getBankAccount();
String depositBankWC = sysCompanyInformation.getDepositBank();
String contacts = sysCompanyInformation.getContacts();
String taxRate = sysSupplier.getTaxRate() + "%";
// 为表格的显示绑定行循环
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
Configure configure = Configure.builder().bind("detailList", policy).build();
XWPFTemplate template = XWPFTemplate.compile(fileAbsolutePath, configure).render(
new HashMap<String, Object>() {{
put("detailList", detailList);
put("purchaseOrderCode", purchaseOrderCode);
put("supplierName", sysSupplier.getSupplierName());
put("orderDate", orderDate);
put("deliverAddress", sysSupplier.getDeliverAddress());
put("deliverPerson", sysSupplier.getDeliverPerson());
put("deliverPersonPhone", sysSupplier.getDeliverPersonPhone());
put("depositBank", sysSupplier.getDepositBank());
put("bankAccount", sysSupplier.getBankAccount());
put("exchangeSettlementAccount", sysSupplier.getExchangeSettlementAccount());
put("totalAmount", totalAmount);
put("ChineseCharacterAmount", ChineseCharacterAmount);
put("taxRate", taxRate);
put("enterpriseName", enterpriseName);
put("bankAccountWC", bankAccountWC);
put("depositBankWC", depositBankWC);
put("contacts", contacts);
put("stockAddress", purchaseOrder.getStockAddress());
put("stockPhone", purchaseOrder.getStockPhone());
put("stockContact", purchaseOrder.getStockContact());
}}
);
// table
// 序号
// 产品名称 materialName
// 规格和型号 materialDescribe
// 单位 materialUnit
// 数量 materialNum
// 单价 materialRmb
// 金额 materialRmbSum
// 交期 deliveryTime
// 合计人民币(大写): 合并序号、产品名称、规格和型号、单位、数量的单元格,展示在最后一行
//table下面的字段
try (ServletOutputStream outputStream = response.getOutputStream()) {
template.writeAndClose(outputStream);
}
} catch (IOException e) {
throw new RuntimeException("文件处理失败", e);
}
}
private ProcessInstance startProcessInstance(String applyTitle, String instanceType, PurchaseOrder purchaseOrder, SysUser user) {
Long materialId = purchaseOrder.getPurchaseOrderId();
String businessKey = materialId.toString(); // 实体类 ID,作为流程的业务 key
@ -710,4 +847,7 @@ public class PurchaseOrderServiceImpl implements IPurchaseOrderService
}
}
}

5
ruoyi-admin/src/main/java/com/ruoyi/system/mapper/SysCompanyInformationMapper.java

@ -60,4 +60,9 @@ public interface SysCompanyInformationMapper
*/
int deleteSysCompanyInformationByIds(String[] companyIds);
/**
* 查询所有公司信息
* */
List<SysCompanyInformation> selectSysCompanyInformationAllList();
}

6
ruoyi-admin/src/main/java/com/ruoyi/system/mapper/SysSupplierMapper.java

@ -87,4 +87,10 @@ public interface SysSupplierMapper
Integer updateSysSupplierBySupplierCodes(String delFlag,SysSupplier[] sysSupplierCodes);
SysSupplierVo cancelSysSupplierById(Long id);
/**
* 根据供应商编码查询供应商信息
* */
SysSupplier selectSysSupplierByCode(String supplierCode);
}

7
ruoyi-admin/src/main/java/com/ruoyi/system/service/ISysSupplierService.java

@ -97,4 +97,11 @@ public interface ISysSupplierService
ProcessInstance restoreSysSupplierById(Long id);
ProcessInstance submitApply(SysSupplier sysSupplier);
/**
* 根据供应商编码查询供应商信息
* */
SysSupplier selectSysSupplierByCode(String supplierCode);
}

11
ruoyi-admin/src/main/java/com/ruoyi/system/service/impl/SysSupplierServiceImpl.java

@ -79,6 +79,17 @@ public class SysSupplierServiceImpl implements ISysSupplierService{
return sysSupplierMapper.selectSysSupplierById(supplierId);
}
/**
* 根据供应商编码查询供应商信息
* */
@Override
public SysSupplier selectSysSupplierByCode(String supplierCode) {
SysSupplier sysSupplier = sysSupplierMapper.selectSysSupplierByCode(supplierCode);
return sysSupplier;
}
/**
* 查询供应商资料列表
*

43
ruoyi-admin/src/main/resources/application.yml

@ -7,10 +7,8 @@ ruoyi:
# 版权年份
copyrightYear: 2024
# 实例演示开关
demoEnabled: false
# 文件路径 示例( Windows配置c:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
# profile: /Users/xiguniang/Documents/ruoyi/uploadPath
# profile: /home/ruoyi/uploadPath
demoEnabled: true
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
profile: D:/ruoyi/uploadPath
# 获取ip地址开关
addressEnabled: false
@ -30,20 +28,12 @@ server:
# Tomcat启动初始化的线程数,默认值25
min-spare-threads: 30
# 日志配置
logging:
level:
com.ruoyi: debug
org.springframework: warn
# 用户配置
user:
password:
@ -69,11 +59,11 @@ spring:
active: druid
# 文件上传
servlet:
multipart:
# 单个文件大小
max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
multipart:
# 单个文件大小
max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
# 服务模块
devtools:
restart:
@ -87,12 +77,12 @@ spring:
# MyBatis
mybatis:
# 搜索指定包别名
typeAliasesPackage: com.ruoyi.**.domain,com.ruoyi.**.**.domain
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
# 搜索指定包别名
typeAliasesPackage: com.ruoyi.**.domain
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件
pagehelper:
@ -112,7 +102,7 @@ shiro:
indexUrl: /index
# 验证码开关
captchaEnabled: true
# 验证码类型 math 数组计算 char 字符
# 验证码类型 math 数字计算 char 字符验证
captchaType: math
cookie:
# 设置Cookie的域名 默认空,即当前访问的域名
@ -123,6 +113,8 @@ shiro:
httpOnly: true
# 设置Cookie的过期时间,天为单位
maxAge: 30
# 设置密钥,务必保持唯一性(生成方式,直接拷贝到main运行即可)Base64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) (默认启动生成随机秘钥,随机秘钥会导致之前客户端RememberMe Cookie无效,如设置固定秘钥RememberMe Cookie则有效)
cipherKey:
session:
# Session超时时间,-1代表永不过期(默认30分钟)
expireTime: 30
@ -134,6 +126,9 @@ shiro:
maxSession: -1
# 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
kickoutAfter: false
# rememberMe:
# # 是否开启记住我
# enabled: true
# 防止XSS攻击
xss:

BIN
ruoyi-admin/src/main/resources/attachments/采购合同.docx

Binary file not shown.

13
ruoyi-admin/src/main/resources/mapper/purchase/PurchaseOrderChildMapper.xml

@ -77,6 +77,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where purchase_order_child_id = #{purchaseOrderChildId}
</select>
<select id="selectPurchaseOrderChildBySupplierCode" parameterType="String" resultMap="PurchaseOrderChildResult">
<include refid="selectPurchaseOrderChildVo"/>
where supplier_code = #{supplierCode}
</select>
<select id="selectChildListBySupplierCodeAndOrderCode" parameterType="PurchaseOrderChild" resultMap="PurchaseOrderChildResult">
<include refid="selectPurchaseOrderChildVo"/>
where supplier_code = #{supplierCode}
and purchase_order_code = #{purchaseOrderCode}
</select>
<insert id="insertPurchaseOrderChild" parameterType="PurchaseOrderChild" useGeneratedKeys="true" keyProperty="purchaseOrderChildId">
insert into purchase_order_child
<trim prefix="(" suffix=")" suffixOverrides=",">
@ -248,4 +260,5 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and p.material_code = w.material_no and p.supplier_code = w.supplier_code
where p.purchase_order_code = #{purchaseOrderCode} GROUP BY supplier_code,material_code
</select>
</mapper>

4
ruoyi-admin/src/main/resources/mapper/system/SysCompanyInformationMapper.xml

@ -52,6 +52,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where company_id = #{companyId}
</select>
<select id="selectSysCompanyInformationAllList" resultMap="SysCompanyInformationResult">
<include refid="selectSysCompanyInformationVo"/>
</select>
<insert id="insertSysCompanyInformation" parameterType="SysCompanyInformation" useGeneratedKeys="true" keyProperty="companyId">
insert into sys_company_information
<trim prefix="(" suffix=")" suffixOverrides=",">

6
ruoyi-admin/src/main/resources/mapper/system/SysSupplierMapper.xml

@ -196,6 +196,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select>
<select id="selectSysSupplierByCode" parameterType="String" resultMap="SysSupplierResult">
<include refid="selectSysSupplierVo"/>
where supplier_code = #{supplierCode}
</select>
<insert id="insertSysSupplier" parameterType="SysSupplier" useGeneratedKeys="true" keyProperty="supplierId">
insert into sys_supplier
<trim prefix="(" suffix=")" suffixOverrides=",">

79
ruoyi-admin/src/main/resources/templates/purchase/purchaseOrder/purchaseOrder.html

@ -78,7 +78,7 @@
<a class="btn btn-success" onclick="importPurchaseOrder()" shiro:hasPermission="purchase:purchaseOrder:add">
<i class="fa fa-plus"></i> 导入合同
</a>
<a class="btn btn-warning" onclick="exportPurchaseOrder()" shiro:hasPermission="purchase:purchaseOrder:export">
<a class="btn btn-warning" onclick="exportContract()" shiro:hasPermission="purchase:purchaseOrder:exportContract">
<i class="fa fa-download"></i> 导出合同
</a>
<a class="btn btn-primary" onclick="reviewCloseCase()" shiro:hasPermission="purchase:purchaseOrder:close">
@ -266,7 +266,12 @@
queryParams : {
purchaseOrderCode: row.purchaseOrderCode,
},
singleSelect:true,
onCheck: function(row, $element) {
$("#"+"purchase_order_child_"+row.id).bootstrapTable('check', $element.index());
},
columns: [
{checkbox: true},
{title: '供应商ID',field: 'supplierCode',},
{title: '供应商名称',field: 'supplierName',},
{title: '物料合计',field: 'materialAmount',},
@ -285,43 +290,53 @@
};
function exportContract() {
// 获取选中的行
const selectedRows = $("#bootstrap-table").bootstrapTable('getSelections');
if (selectedRows.length !== 1) {
showWarning("请先选择一条采购订单");
return;
}
const row = selectedRows[0];
//导出
function exportPurchaseOrder() {
var rows = $.common.isEmpty(table.options.uniqueId) ? $.table.selectFirstColumns() : $.table.selectColumns(table.options.uniqueId);
var data = $("#bootstrap-table").bootstrapTable("getSelections")
// 定义状态码常量
const AUDIT_STATUS_APPROVED = "1"; // 审核通过
const USE_STATUS_DELETED = "2"; // 作废
if (rows.length !== 1) {
$.modal.alert("请选择一条记录");
// 检查是否作废
if (row.useStatus === USE_STATUS_DELETED) {
showWarning("该采购订单已作废");
return;
} else {
// rows为选中行的id
$.modal.confirm("是否确认要导出本条采购订单?", function (){
axios({
url: prefix + '/exportSelected/'+data[0].purchaseOrderId,
method: 'POST',
responseType: 'blob'
}).then(response => {
// console.log(response)
const URL = window.URL.createObjectURL(response.data)
// 创建隐藏<a>标签进行下载
const tempLink = document.createElement('a')
tempLink.style.display = 'none'
tempLink.href = URL
let time = new Date().toLocaleString()
tempLink.setAttribute('download', time + "采购订单.xlsx")
if (typeof tempLink.download === 'undefined') {
tempLink.setAttribute('target', '_blank')
}
document.body.appendChild(tempLink)
tempLink.click()
document.body.removeChild(tempLink)// 移除dom元素
window.URL.revokeObjectURL(URL)//释放内存
})
});
}
// 检查是否审核通过
if (row.auditStatus !== AUDIT_STATUS_APPROVED) {
showWarning("该采购订单未审核通过");
return;
}
// 获取子表的 ID
const childTableId = "#purchase_order_child_" + row.id;
// 获取子表中选中的行
const selectedChildRows = $(childTableId).bootstrapTable('getSelections');
if (selectedChildRows.length !== 1) {
showWarning("请先选择子表中的一行");
return;
}
const selectedChildRow = selectedChildRows[0];
var supplierCode = selectedChildRow.supplierCode;
// 如果一切正常,继续导出
var purchaseOrderCode = row.purchaseOrderCode;
window.location.href = prefix + "/exportContract/" + purchaseOrderCode + "?supplierCode=" + encodeURIComponent(supplierCode);
}
// 显示警告消息的通用函数
function showWarning(message) {
$.modal.msgWarning(message);
}

44
ruoyi-common/pom.xml

@ -111,11 +111,55 @@
</dependency>
<!-- excel工具 -->
<!-- <dependency>-->
<!-- <groupId>org.apache.poi</groupId>-->
<!-- <artifactId>poi-ooxml</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>5.2.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.1</version>
</dependency>
<!-- poi-tl -->
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.0</version>
</dependency>
<!-- yml解析器 -->
<dependency>
<groupId>org.yaml</groupId>

61
ruoyi-common/src/main/java/com/ruoyi/common/utils/MoneyUtils.java

@ -0,0 +1,61 @@
package com.ruoyi.common.utils;
import java.math.BigDecimal;
public class MoneyUtils {
private static final String[] CHINESE_DIGITS = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
private static final String[] UNITS = {"", "拾", "佰", "仟", "万", "亿"};
public static String toChineseCapitalized(BigDecimal amount) {
if (amount == null || amount.compareTo(BigDecimal.ZERO) == 0) {
return "零元整";
}
StringBuilder result = new StringBuilder();
boolean isNegative = amount.signum() == -1;
amount = amount.abs();
// 将金额转换为整数部分和小数部分
long integerPart = amount.longValue();
BigDecimal decimalPart = amount.remainder(BigDecimal.ONE).setScale(2, BigDecimal.ROUND_HALF_UP);
// 处理整数部分
int unitIndex = 0;
while (integerPart > 0) {
int digit = (int) (integerPart % 10);
if (digit != 0 || result.length() > 0) { // 避免多个"零"
result.insert(0, UNITS[unitIndex]);
}
result.insert(0, CHINESE_DIGITS[digit]);
integerPart /= 10;
unitIndex++;
if (unitIndex == 4) {
unitIndex = 0;
result.insert(0, "万");
}
}
// 添加单位“元”
result.append("元");
// 处理小数部分
if (decimalPart.compareTo(BigDecimal.ZERO) > 0) {
result.append("零").append(CHINESE_DIGITS[decimalPart.intValue()]);
result.append("角");
BigDecimal cents = decimalPart.remainder(BigDecimal.ONE).multiply(BigDecimal.TEN);
if (cents.compareTo(BigDecimal.ZERO) > 0) {
result.append("零").append(CHINESE_DIGITS[cents.intValue()]);
result.append("分");
}
} else {
result.append("整");
}
if (isNegative) {
result.insert(0, "负");
}
return result.toString();
}
}

20
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileDownloadUtils.java

@ -0,0 +1,20 @@
package com.ruoyi.common.utils.file;
import org.springframework.core.io.ClassPathResource;
import java.io.File;
import java.io.IOException;
/**
* 文件下载类
* */
public class FileDownloadUtils {
// 获取文件绝对路径
public String getFileAbsolutePath(String fileName) throws IOException {
ClassPathResource resource = new ClassPathResource("attachments/" + fileName);
File file = resource.getFile();
return file.getAbsolutePath();
}
}

114
ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java

@ -1,57 +1,57 @@
package com.ruoyi.quartz.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import javax.sql.DataSource;
import java.util.Properties;
/**
* 定时任务配置
*
* @author ruoyi
*/
@Configuration
public class ScheduleConfig
{
@Bean
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource)
{
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setDataSource(dataSource);
// quartz参数
Properties prop = new Properties();
prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler");
prop.put("org.quartz.scheduler.instanceId", "AUTO");
// 线程池配置
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
prop.put("org.quartz.threadPool.threadCount", "20");
prop.put("org.quartz.threadPool.threadPriority", "5");
// JobStore配置
prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
// 集群配置
prop.put("org.quartz.jobStore.isClustered", "true");
prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
// sqlserver 启用
// prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
prop.put("org.quartz.jobStore.misfireThreshold", "12000");
prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
factory.setQuartzProperties(prop);
factory.setSchedulerName("RuoyiScheduler");
// 延时启动
factory.setStartupDelay(1);
factory.setApplicationContextSchedulerContextKey("applicationContextKey");
// 可选,QuartzScheduler
// 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
factory.setOverwriteExistingJobs(true);
// 设置自动启动,默认为true
factory.setAutoStartup(true);
return factory;
}
}
//package com.ruoyi.quartz.config;
//
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.scheduling.quartz.SchedulerFactoryBean;
//import javax.sql.DataSource;
//import java.util.Properties;
//
///**
// * 定时任务配置
// *
// * @author ruoyi
// */
//@Configuration
//public class ScheduleConfig
//{
// @Bean
// public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource)
// {
// SchedulerFactoryBean factory = new SchedulerFactoryBean();
// factory.setDataSource(dataSource);
//
// // quartz参数
// Properties prop = new Properties();
// prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler");
// prop.put("org.quartz.scheduler.instanceId", "AUTO");
// // 线程池配置
// prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
// prop.put("org.quartz.threadPool.threadCount", "20");
// prop.put("org.quartz.threadPool.threadPriority", "5");
// // JobStore配置
// prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
// // 集群配置
// prop.put("org.quartz.jobStore.isClustered", "true");
// prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
// prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
//
// // sqlserver 启用
// // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
// prop.put("org.quartz.jobStore.misfireThreshold", "12000");
// prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
// factory.setQuartzProperties(prop);
//
// factory.setSchedulerName("RuoyiScheduler");
// // 延时启动
// factory.setStartupDelay(1);
// factory.setApplicationContextSchedulerContextKey("applicationContextKey");
// // 可选,QuartzScheduler
// // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
// factory.setOverwriteExistingJobs(true);
// // 设置自动启动,默认为true
// factory.setAutoStartup(true);
//
// return factory;
// }
//}

14
ruoyi-system/pom.xml

@ -28,6 +28,20 @@
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>

Loading…
Cancel
Save