...
 
Commits (29)
...@@ -109,6 +109,24 @@ ...@@ -109,6 +109,24 @@
<!-- <version>${与你的agent探针版本保持一致}</version>--> <!-- <version>${与你的agent探针版本保持一致}</version>-->
<!-- </dependency>--> <!-- </dependency>-->
<!--数据库说明书-->
<!-- https://mvnrepository.com/artifact/cn.smallbun.screw/screw-core -->
<dependency>
<groupId>cn.smallbun.screw</groupId>
<artifactId>screw-core</artifactId>
<version>1.0.5</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/screw-core-1.0.5.jar</systemPath>
</dependency>
<!-- https://mvnrepository.com/artifact/com.zaxxer/HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.5</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
package com.maintain.web.controller.business;
import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.engine.EngineFileType;
import cn.smallbun.screw.core.engine.EngineTemplateType;
import cn.smallbun.screw.core.execute.DocumentationExecute;
import cn.smallbun.screw.core.process.ProcessConfig;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.util.ArrayList;
/**
* 数据库说明书
*/
public class ExportMysql {
public static void main(String[] args) {
//数据源
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
hikariConfig.setJdbcUrl("jdbc:mysql://rm-hp3340490n5mw72tcto.mysql.huhehaote.rds.aliyuncs.com:3306/tianmaiweixiu_db?currentSchema=single");
hikariConfig.setUsername("tianmaiweixiu");
hikariConfig.setPassword("7HTx9s@2wcbTQ@r1");
//设置可以获取tables remarks信息
hikariConfig.setMinimumIdle(2);
hikariConfig.setMaximumPoolSize(5);
HikariDataSource dataSource = new HikariDataSource(hikariConfig);
//生成配置
EngineConfig engineConfig = EngineConfig.builder()
//生成文件路径
.fileOutputDir("C:\\Users\\admin\\Desktop")
//打开目录
.openOutputDir(true)
//文件类型
.fileType(EngineFileType.WORD)
//生成模板实现
.produceType(EngineTemplateType.freemarker)
//自定义文件名称
.fileName("维修管理系统数据库说明书").build();
//忽略表
ArrayList<String> ignoreTableName = new ArrayList<>();
// ignoreTableName.add("sys_config");
// ignoreTableName.add("sys_user");
//忽略表前缀
ArrayList<String> ignorePrefix = new ArrayList<>();
// ignorePrefix.add("test_");
//忽略表后缀
ArrayList<String> ignoreSuffix = new ArrayList<>();
// ignoreSuffix.add("_test");
ProcessConfig processConfig = ProcessConfig.builder()
//指定生成逻辑、当存在指定表、指定表前缀、指定表后缀时,将生成指定表,其余表不生成、并跳过忽略表配置
//根据名称指定表生成
.designatedTableName(new ArrayList<>())
//根据表前缀生成
.designatedTablePrefix(new ArrayList<>())
//根据表后缀生成
.designatedTableSuffix(new ArrayList<>())
//忽略表名
.ignoreTableName(ignoreTableName)
//忽略表前缀
.ignoreTablePrefix(ignorePrefix)
//忽略表后缀
.ignoreTableSuffix(ignoreSuffix).build();
//配置
Configuration config = Configuration.builder()
//版本
.version("1.0.0")
//描述
.description("数据库设计文档生成")
//数据源
.dataSource(dataSource)
//生成配置
.engineConfig(engineConfig)
//生成配置
.produceConfig(processConfig)
.build();
//执行生成
new DocumentationExecute(config).execute();
}
}
...@@ -180,3 +180,11 @@ sms: ...@@ -180,3 +180,11 @@ sms:
sdkAppId: appid sdkAppId: appid
#地域信息默认为 ap-guangzhou 如无特殊改变可不用设置 #地域信息默认为 ap-guangzhou 如无特殊改变可不用设置
territory: ap-guangzhou territory: ap-guangzhou
pay:
appid: 10037e6f72b586db0172b6ea24ec0000
appkey: 6f7a00170935445fbe25e67a5ce1be48
url: https://test-api-open.chinaums.com/v6/poslink/transaction/pay
merchantCode: 123456789111115
terminalCode: gxrb0001
deviceType: 11
payMode: CODE_SCAN
...@@ -183,3 +183,10 @@ sms: ...@@ -183,3 +183,10 @@ sms:
sdkAppId: appid sdkAppId: appid
#地域信息默认为 ap-guangzhou 如无特殊改变可不用设置 #地域信息默认为 ap-guangzhou 如无特殊改变可不用设置
territory: ap-guangzhou territory: ap-guangzhou
pay:
appid: 8a81c1bd96cf23aa0199cc0a8dcb187c
appkey: 02c4bc73faaf46c89e0c620345a11aec
url: https://api-mop.chinaums.com/v6/poslink/transaction/pay
merchantCode: 898440300005398
deviceType: 11
payMode: CODE_SCAN
...@@ -102,7 +102,7 @@ sa-token: ...@@ -102,7 +102,7 @@ sa-token:
timeout: 86400 timeout: 86400
# 多端不同 token 有效期 可查看 LoginHelper.loginByDevice 方法自定义 # 多端不同 token 有效期 可查看 LoginHelper.loginByDevice 方法自定义
# token最低活跃时间 (指定时间无操作就过期) 单位: 秒 # token最低活跃时间 (指定时间无操作就过期) 单位: 秒
active-timeout: 1800 active-timeout: 43200
# 允许动态设置 token 有效期 # 允许动态设置 token 有效期
dynamic-active-timeout: true dynamic-active-timeout: true
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
...@@ -139,9 +139,10 @@ security: ...@@ -139,9 +139,10 @@ security:
# actuator 监控配置 # actuator 监控配置
- /actuator - /actuator
- /actuator/** - /actuator/**
# - /jmreport/** # 积木报表配置
# - /drag/** - /jmreport/**
# - /jimubi/** - /drag/**
- /jimubi/**
# MyBatisPlus配置 # MyBatisPlus配置
# https://baomidou.com/config/ # https://baomidou.com/config/
...@@ -312,82 +313,15 @@ spring: ...@@ -312,82 +313,15 @@ spring:
jeecg: jeecg:
jmreport: jmreport:
#多租户模式,默认值为空(created:按照创建人隔离、tenant:按照租户隔离) (v1.6.2+ 新增) #多租户模式,默认值为空(created:按照创建人隔离、tenant:按照租户隔离) (v1.6.2+ 新增)
saasMode: saasMode: createDeptId
# 平台上线安全配置(v1.6.2+ 新增) # 平台上线安全配置(v1.6.2+ 新增)
firewall: firewall:
# 数据源安全 (开启后,不允许使用平台数据源、SQL解析加签并且不允许查询数据库) # 数据源安全 (开启后,不允许使用平台数据源、SQL解析不允许select * 查询、禁止测试数据源连接是否正确)
dataSourceSafe: false # 数据源安全下,预留角色有权限使用 select * 和测试数据源链接
# 低代码开发模式(dev:开发模式, prod:发布模式关闭报表设计,admin或预留角色可设计, prodsf:发布安全模式 彻底关闭报表设计) dataSourceSafe: true
# 低代码开发模式(dev:开发模式,prod:发布模式关闭报表设计,预留角色admin、lowdeveloper可设计, prodsf:发布安全模式 彻底关闭报表设计)
lowCodeMode: dev lowCodeMode: dev
#是否 禁用导出PDF和图片的按钮 默认为false # api数据集内网ip白名单,在发布模式下只只能向设置了白名单的内网服务器发送请求。
exportDisabled: false apiDsIpWhite:
# 导出是否开启另存为弹窗 默认为false (v1.7.4+) # sql注入检查级别(strict:严格, basic:简单校验, none:不校验)
enableSaveAsOpen: false sqlInjectionLevel: strict
#是否自动保存
autoSave: true
#自动保存间隔时间毫秒
interval: 20000
# 行数(设计页面展示多少行)
row: 100
# 列数(设计页面展示多少列)
col: 100
#自定义项目前缀
customPrePath:
# 自定义API接口的前缀 #{api_base_path}和#{domainURL}的值
apiBasePath: http://localhost:8080/jeecg-boot
#数据源标识(作废参数)
datasource: master
#预览分页自定义
pageSize:
- 10
- 20
- 30
- 40
#打印纸张自定义
printPaper:
- title: A5纸
size:
- 148
- 210
- title: B4纸
size:
- 250
- 353
#接口超时设置(毫秒)
connect-timeout: 300000
#导出超时时间(毫秒,默认600000)
export-timeout: 600000
#Excel导出模式(fast/快、primary/精致模式,默认fast)
export-excel-pattern: fast
#Excel导出数据每个sheet的行数,每个sheet最大1048576行
page-size-number: 10000
#设计页面表格的线是否显示 默认true
line: true
#只看自己创建数据 (v1.6.2+删除)
saas: false
#是否开启租户模式 (v1.6.2+删除)
openTenant: false
#sql数据源不写字典下拉框显示条数 (v1.4.2+删除)
select-show-total: 10
#是否启用签名校验,默认不开启,对执行sql的接口参数校验(v1.6.2+删除)
safeMode: true
# 自动导出 ( v1.7.5+ )
automate:
# python文件目录,绝对路径
py-path: "/usr/bin/python3"
export:
# 非必须,下载的报表的存放目录(服务器上的绝对路径)
download-path: "/home/jimureport-auto-export/downloads/"
# 非必须,积木报表view页面地址
jimu-view-path: "http://???/jmreport/shareView/"
# 使用插件导出必须,插件访问域名 比如: http://127.0.0.1:16065
plugin-domain: "http://127.0.0.1:16065"
# 文件过期时间,单位天,默认:30
expired: 30
# 导出任务使用插件,默认false
job-use-plugin: false
# 开启自动导出( v1.9.6+ ),默认false
enable-auto-export: false
#国际化(v1.9.5+新增)
i18n:
enable: false
package com.maintain.business.controller; package com.maintain.business.controller;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Arrays; import java.util.Arrays;
import com.maintain.business.domain.vo.ErpMaterialPickingExportVo;
import com.maintain.common.utils.poi.SheetPO;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*; import javax.validation.constraints.*;
...@@ -62,8 +65,9 @@ public class ErpMaterialPickingController extends BaseController { ...@@ -62,8 +65,9 @@ public class ErpMaterialPickingController extends BaseController {
@Log(title = "物料出库", businessType = BusinessType.EXPORT) @Log(title = "物料出库", businessType = BusinessType.EXPORT)
@PostMapping("/export") @PostMapping("/export")
public void export(ErpMaterialPickingBo bo, HttpServletResponse response) { public void export(ErpMaterialPickingBo bo, HttpServletResponse response) {
List<ErpMaterialPickingVo> list = iErpMaterialPickingService.queryList(bo); iErpMaterialPickingService.export(bo,response);
ExcelUtil.exportExcel(list, "物料出库", ErpMaterialPickingVo.class, response); // List<ErpMaterialPickingVo> list = iErpMaterialPickingService.queryList(bo);
// ExcelUtil.exportExcel(list, "物料出库", ErpMaterialPickingVo.class, response);
} }
/** /**
......
...@@ -103,6 +103,17 @@ public class ErpRepairFormProjectDispatchController extends BaseController { ...@@ -103,6 +103,17 @@ public class ErpRepairFormProjectDispatchController extends BaseController {
return toAjax(iErpRepairFormProjectDispatchService.updateByBo(bo)); return toAjax(iErpRepairFormProjectDispatchService.updateByBo(bo));
} }
/**
* 修改报修单-报修项目-派工
*/
@SaCheckPermission("business:repairFormProjectDispatch:edit")
@Log(title = "报修单-报修项目-派工", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/batch")
public R<Void> edit(@Validated(EditGroup.class) @RequestBody List<ErpRepairFormProjectDispatchBo> bo) {
return toAjax(iErpRepairFormProjectDispatchService.updateBatchByBo(bo));
}
/** /**
* 删除报修单-报修项目-派工 * 删除报修单-报修项目-派工
* *
......
...@@ -5,6 +5,7 @@ import java.util.List; ...@@ -5,6 +5,7 @@ import java.util.List;
import java.util.Arrays; import java.util.Arrays;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.maintain.business.domain.bo.ErpSettlementMaintainPayBo;
import com.maintain.business.domain.bo.ErpSettlementMaintainRepairFormBo; import com.maintain.business.domain.bo.ErpSettlementMaintainRepairFormBo;
import com.maintain.business.domain.vo.ErpSettlementMaintainRepairFormVo; import com.maintain.business.domain.vo.ErpSettlementMaintainRepairFormVo;
import com.maintain.business.service.IErpRepairFormService; import com.maintain.business.service.IErpRepairFormService;
...@@ -137,4 +138,16 @@ public class ErpSettlementMaintainController extends BaseController { ...@@ -137,4 +138,16 @@ public class ErpSettlementMaintainController extends BaseController {
public R<Void> receipt(@Validated(EditGroup.class) @RequestBody ErpSettlementMaintainBo bo) { public R<Void> receipt(@Validated(EditGroup.class) @RequestBody ErpSettlementMaintainBo bo) {
return toAjax(iErpSettlementMaintainService.receiptByBo(bo)); return toAjax(iErpSettlementMaintainService.receiptByBo(bo));
} }
/**
* 结算维修单回执
*
* @param bo
*/
@Log(title = "结算维修单支付", businessType = BusinessType.UPDATE)
@PutMapping("/pay")
public R<Void> pay(@Validated(EditGroup.class) @RequestBody ErpSettlementMaintainPayBo bo) {
return toAjax(iErpSettlementMaintainService.pay(bo));
}
} }
...@@ -62,4 +62,19 @@ public class ErpCar extends BaseEntity { ...@@ -62,4 +62,19 @@ public class ErpCar extends BaseEntity {
*/ */
private Long carTypeId; private Long carTypeId;
/**
* 分公司
*/
private String branchOffice;
/**
* 车队
*/
private String motorcade;
/**
* 线路
*/
private String line;
} }
...@@ -92,6 +92,10 @@ public class ErpMaterial extends BaseEntity { ...@@ -92,6 +92,10 @@ public class ErpMaterial extends BaseEntity {
* 物资品牌 * 物资品牌
*/ */
private String materialBrand; private String materialBrand;
/**
* 生产厂家
*/
private String manufacturer;
/** /**
* 采购标的 * 采购标的
*/ */
......
...@@ -110,7 +110,7 @@ public class ErpMaterialPickingInfo extends BaseEntity { ...@@ -110,7 +110,7 @@ public class ErpMaterialPickingInfo extends BaseEntity {
*/ */
private BigDecimal putawayMoney; private BigDecimal putawayMoney;
/** /**
* 状态(1已领料 2已退料) * 状态(1登记中 2已完成 3已退料)
*/ */
private Integer state; private Integer state;
......
...@@ -71,9 +71,13 @@ public class ErpSettlementMaintain extends BaseEntity { ...@@ -71,9 +71,13 @@ public class ErpSettlementMaintain extends BaseEntity {
*/ */
private Date settlementTime; private Date settlementTime;
/** /**
* 支付方式(1支付宝 2微信 * 支付方式(1扫码支付 2手动支付
*/ */
private Integer paymentMethod; private Integer paymentMethod;
/**
* 支付单号
*/
private String paymentNumber;
/** /**
* 付款账号 * 付款账号
*/ */
...@@ -111,7 +115,7 @@ public class ErpSettlementMaintain extends BaseEntity { ...@@ -111,7 +115,7 @@ public class ErpSettlementMaintain extends BaseEntity {
*/ */
private String collectionAccount; private String collectionAccount;
/** /**
* 收款流水号 * 交易流水号
*/ */
private String collectionSerialNumber; private String collectionSerialNumber;
/** /**
......
package com.maintain.business.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.maintain.common.core.domain.BaseEntity;
/**
* 银联支付日志记录对象 sys_pay_log
*
* @author liushuai
* @date 2025-11-10
*/
@Data
@TableName("sys_pay_log")
public class SysPayLog implements Serializable {
private static final long serialVersionUID=1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 结算维修单ID
*/
private Long settlementMaintainId;
/**
* 认证报文
*/
private String authorization;
/**
* 请求参数
*/
private String operParam;
/**
* 返回参数
*/
private String jsonResult;
/**
* 操作状态(0正常 1异常)
*/
private String status;
/**
* 操作时间
*/
private Date operTime;
/**
* 操作用户
*/
private Long operUser;
}
...@@ -82,5 +82,19 @@ public class ErpCarBo extends BaseEntity { ...@@ -82,5 +82,19 @@ public class ErpCarBo extends BaseEntity {
*/ */
private Date createTime; private Date createTime;
/**
* 分公司
*/
private String branchOffice;
/**
* 车队
*/
private String motorcade;
/**
* 线路
*/
private String line;
} }
...@@ -114,6 +114,10 @@ public class ErpMaterialBo extends BaseEntity { ...@@ -114,6 +114,10 @@ public class ErpMaterialBo extends BaseEntity {
* 物资品牌 * 物资品牌
*/ */
private String materialBrand; private String materialBrand;
/**
* 生产厂家
*/
private String manufacturer;
/** /**
* 采购标的 * 采购标的
*/ */
......
...@@ -131,4 +131,14 @@ public class ErpMaterialPickingBo extends BaseEntity { ...@@ -131,4 +131,14 @@ public class ErpMaterialPickingBo extends BaseEntity {
private List<ErpMaterialPickingInfoAddBo> materialList; private List<ErpMaterialPickingInfoAddBo> materialList;
/**
* 导出IDs
*/
private List<Long> ids;
/**
* 单位IDS
*/
private List<Long> deptIds;
} }
...@@ -90,7 +90,6 @@ public class ErpSettlementMaintainBo extends BaseEntity { ...@@ -90,7 +90,6 @@ public class ErpSettlementMaintainBo extends BaseEntity {
/** /**
* 支付方式(1支付宝 2微信) * 支付方式(1支付宝 2微信)
*/ */
@NotNull(message = "支付方式(1支付宝 2微信)不能为空", groups = { AddGroup.class, EditGroup.class })
private Integer paymentMethod; private Integer paymentMethod;
/** /**
...@@ -106,7 +105,6 @@ public class ErpSettlementMaintainBo extends BaseEntity { ...@@ -106,7 +105,6 @@ public class ErpSettlementMaintainBo extends BaseEntity {
/** /**
* 付款凭证 * 付款凭证
*/ */
@NotBlank(message = "付款凭证不能为空", groups = { AddGroup.class, EditGroup.class })
private String paymentVoucher; private String paymentVoucher;
/** /**
......
package com.maintain.business.domain.bo;
import com.maintain.common.core.domain.BaseEntity;
import com.maintain.common.core.validate.AddGroup;
import com.maintain.common.core.validate.EditGroup;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 结算维修单业务对象 erp_settlement_maintain
*
* @author liushuai
* @date 2025-04-03
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class ErpSettlementMaintainPayBo extends BaseEntity {
/**
* 结算单ID
*/
@NotNull(message = "结算单ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long id;
/**
* 付款码
*/
@NotBlank(message = "付款码不能为空", groups = { AddGroup.class, EditGroup.class })
private String paymentAccount;
}
package com.maintain.business.domain.bo;
import com.maintain.common.core.validate.AddGroup;
import com.maintain.common.core.validate.EditGroup;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.maintain.common.core.domain.BaseEntity;
/**
* 银联支付日志记录业务对象 sys_pay_log
*
* @author liushuai
* @date 2025-11-10
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class SysPayLogBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = { EditGroup.class })
private Long id;
/**
* 结算维修单ID
*/
@NotNull(message = "结算维修单ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long settlementMaintainId;
/**
* 认证报文
*/
@NotBlank(message = "认证报文不能为空", groups = { AddGroup.class, EditGroup.class })
private String authorization;
/**
* 请求参数
*/
@NotBlank(message = "请求参数不能为空", groups = { AddGroup.class, EditGroup.class })
private String operParam;
/**
* 返回参数
*/
@NotBlank(message = "返回参数不能为空", groups = { AddGroup.class, EditGroup.class })
private String jsonResult;
/**
* 操作状态(0正常 1异常)
*/
@NotNull(message = "操作状态(0正常 1异常)不能为空", groups = { AddGroup.class, EditGroup.class })
private Long status;
/**
* 操作时间
*/
@NotNull(message = "操作时间不能为空", groups = { AddGroup.class, EditGroup.class })
private Date operTime;
}
...@@ -110,4 +110,22 @@ public class ErpCarVo implements Serializable { ...@@ -110,4 +110,22 @@ public class ErpCarVo implements Serializable {
@ColumnWidth(20) @ColumnWidth(20)
private Date createTime; private Date createTime;
/**
* 分公司
*/
@ExcelProperty(value = "分公司")
private String branchOffice;
/**
* 车队
*/
@ExcelProperty(value = "车队")
private String motorcade;
/**
* 线路
*/
@ExcelProperty(value = "线路")
private String line;
} }
package com.maintain.business.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadFontStyle;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.alibaba.excel.annotation.write.style.HeadStyle;
import com.alibaba.excel.enums.poi.BorderStyleEnum;
import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import com.alibaba.excel.enums.poi.VerticalAlignmentEnum;
import com.maintain.common.annotation.ExcelDictFormat;
import com.maintain.common.convert.ExcelDictConvert;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* @Author haoxuyang
* @Date 2026/4/2 9:24
*/
@Data
@HeadRowHeight(value = 35)
@ContentRowHeight(value = 22)
/** 金黄表头、黑字、细边框(与 IndexedColors 调色板接近 #FFC107/#FFB800 效果) */
@HeadStyle(
fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 51,
horizontalAlignment = HorizontalAlignmentEnum.CENTER,
verticalAlignment = VerticalAlignmentEnum.CENTER,
borderLeft = BorderStyleEnum.THIN,
borderRight = BorderStyleEnum.THIN,
borderTop = BorderStyleEnum.THIN,
borderBottom = BorderStyleEnum.THIN,
leftBorderColor = 8,
rightBorderColor = 8,
topBorderColor = 8,
bottomBorderColor = 8
)
@HeadFontStyle(color = 8)
public class ErpMaterialPickingExportVo {
/**
* 序号
*/
@ColumnWidth(20)
@ExcelProperty(index = 0, value = {"title", "序号"})
private String index;
/**
* 分公司
*/
@ColumnWidth(20)
@ExcelProperty(index = 1, value = {"title", "分公司"})
private String branchOffice;
/**
* 车间
*/
@ColumnWidth(20)
@ExcelProperty(index = 2, value = {"title", "车间"})
private String workshopName;
/**
* 仓库
*/
@ColumnWidth(20)
@ExcelProperty(index = 3, value = {"title", "仓库"})
private String warehouseName;
/**
* 到货单号
*/
@ColumnWidth(20)
@ExcelProperty(index = 4, value = {"title", "到货单号"})
private String arrivalNumber;
/**
* 领料人
*/
@ColumnWidth(20)
@ExcelProperty(index = 5, value = {"title", "领料人"})
private String receiveUserName;
/**
* 领料时间
*/
@ColumnWidth(25)
@ExcelProperty(index = 6, value = {"title", "领料时间"})
private Date receiveTime;
/**
* 材料编码
*/
@ColumnWidth(20)
@ExcelProperty(index = 7, value = {"title", "材料编码"})
private String materialCode;
/**
* 物资名称
*/
@ColumnWidth(20)
@ExcelProperty(index = 8, value = {"title", "物资名称"})
private String materialName;
/**
* 规格
*/
@ColumnWidth(20)
@ExcelProperty(index = 9, value = {"title", "规格"})
private String materialSpecifications;
/**
* 单位
*/
@ColumnWidth(20)
@ExcelProperty(index = 10, value = {"title", "单位"}, converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "material_unit")
private String materialUnit;
/**
* 入库价格
*/
@ColumnWidth(20)
@ExcelProperty(index = 11, value = {"title", "入库价格"})
private BigDecimal putawayPrice;
/**
* 数量
*/
@ColumnWidth(20)
@ExcelProperty(index = 12, value = {"title", "数量"})
private BigDecimal collectNumber;
/**
* 合计(元)
*/
@ColumnWidth(20)
@ExcelProperty(index = 13, value = {"title", "合计(元)"})
private BigDecimal money;
/**
* 供应商名称
*/
@ColumnWidth(30)
@ExcelProperty(index = 14, value = {"title", "供应商名称"})
private String vendorName;
}
...@@ -122,6 +122,11 @@ public class ErpMaterialVo implements Serializable { ...@@ -122,6 +122,11 @@ public class ErpMaterialVo implements Serializable {
*/ */
@ExcelProperty(value = "物资品牌") @ExcelProperty(value = "物资品牌")
private String materialBrand; private String materialBrand;
/**
* 生产厂家
*/
@ExcelProperty(value = "生产厂家")
private String manufacturer;
/** /**
* 采购标的 * 采购标的
*/ */
......
package com.maintain.business.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.maintain.common.annotation.ExcelDictFormat;
import com.maintain.common.convert.ExcelDictConvert;
import lombok.Data;
import java.util.Date;
import java.io.Serializable;
/**
* 银联支付日志记录视图对象 sys_pay_log
*
* @author liushuai
* @date 2025-11-10
*/
@Data
@ExcelIgnoreUnannotated
public class SysPayLogVo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 结算维修单ID
*/
@ExcelProperty(value = "结算维修单ID")
private Long settlementMaintainId;
/**
* 认证报文
*/
@ExcelProperty(value = "认证报文")
private String authorization;
/**
* 请求参数
*/
@ExcelProperty(value = "请求参数")
private String operParam;
/**
* 返回参数
*/
@ExcelProperty(value = "返回参数")
private String jsonResult;
/**
* 操作状态(0正常 1异常)
*/
@ExcelProperty(value = "操作状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "0=正常,1=异常")
private Long status;
/**
* 操作时间
*/
@ExcelProperty(value = "操作时间")
private Date operTime;
}
...@@ -84,21 +84,21 @@ public class ErpMaterialImportListener extends AnalysisEventListener<ErpMaterial ...@@ -84,21 +84,21 @@ public class ErpMaterialImportListener extends AnalysisEventListener<ErpMaterial
} }
} }
/** /**
* 物资类型 * 物资类型(弃用)
*/ */
if (StringUtils.isNotEmpty(material.getMaterialTypeName())) { // if (StringUtils.isNotEmpty(material.getMaterialTypeName())) {
List<ErpMaterialType> materialTypes = materialTypeMapper.selectList(new LambdaQueryWrapper<ErpMaterialType>().eq(ErpMaterialType::getTypeName, material.getMaterialTypeName())); // List<ErpMaterialType> materialTypes = materialTypeMapper.selectList(new LambdaQueryWrapper<ErpMaterialType>().eq(ErpMaterialType::getTypeName, material.getMaterialTypeName()));
if (materialTypes.isEmpty()) { // if (materialTypes.isEmpty()) {
ErpMaterialType materialType = new ErpMaterialType(); // ErpMaterialType materialType = new ErpMaterialType();
materialType.setTypeName(material.getMaterialTypeName()); // materialType.setTypeName(material.getMaterialTypeName());
materialType.setParentId(1L); // materialType.setParentId(1L);
materialType.setAncestors("0,1"); // materialType.setAncestors("0,1");
materialTypeMapper.insert(materialType); // materialTypeMapper.insert(materialType);
material.setMaterialTypeId(materialType.getTypeId()); // material.setMaterialTypeId(materialType.getTypeId());
}else { // }else {
material.setMaterialTypeId(materialTypes.get(0).getTypeId()); // material.setMaterialTypeId(materialTypes.get(0).getTypeId());
} // }
} // }
/** /**
* 供应商 * 供应商
*/ */
...@@ -114,22 +114,22 @@ public class ErpMaterialImportListener extends AnalysisEventListener<ErpMaterial ...@@ -114,22 +114,22 @@ public class ErpMaterialImportListener extends AnalysisEventListener<ErpMaterial
} }
} }
/** /**
* 仓库货位 * 仓库货位(弃用)
*/ */
if (StringUtils.isNotEmpty(material.getWarehouseLocationType())) { // if (StringUtils.isNotEmpty(material.getWarehouseLocationType())) {
ErpWarehouseLocation warehouseLocation = warehouseLocationMapper.selectOne(new LambdaQueryWrapper<ErpWarehouseLocation>().eq(ErpWarehouseLocation::getLocationType, material.getWarehouseLocationType())); // ErpWarehouseLocation warehouseLocation = warehouseLocationMapper.selectOne(new LambdaQueryWrapper<ErpWarehouseLocation>().eq(ErpWarehouseLocation::getLocationType, material.getWarehouseLocationType()));
if (ObjectUtil.isNull(warehouseLocation)) { // if (ObjectUtil.isNull(warehouseLocation)) {
ErpWarehouseLocation location = new ErpWarehouseLocation(); // ErpWarehouseLocation location = new ErpWarehouseLocation();
location.setLocationCode(material.getWarehouseLocationType()); // location.setLocationCode(material.getWarehouseLocationType());
location.setLocationType(material.getWarehouseLocationType()); // location.setLocationType(material.getWarehouseLocationType());
warehouseLocationMapper.insert(location); // warehouseLocationMapper.insert(location);
material.setWarehouseLocationCode(location.getLocationCode()); // material.setWarehouseLocationCode(location.getLocationCode());
material.setWarehouseLocationId(location.getId()); // material.setWarehouseLocationId(location.getId());
} else { // } else {
material.setWarehouseLocationCode(warehouseLocation.getLocationCode()); // material.setWarehouseLocationCode(warehouseLocation.getLocationCode());
material.setWarehouseLocationId(warehouseLocation.getId()); // material.setWarehouseLocationId(warehouseLocation.getId());
} // }
} // }
materialMapper.insert(material); materialMapper.insert(material);
successNum++; successNum++;
successMsg.append("<br/>").append(successNum).append("、物料 【").append(material.getMaterialName()).append("】 导入成功"); successMsg.append("<br/>").append(successNum).append("、物料 【").append(material.getMaterialName()).append("】 导入成功");
...@@ -141,19 +141,19 @@ public class ErpMaterialImportListener extends AnalysisEventListener<ErpMaterial ...@@ -141,19 +141,19 @@ public class ErpMaterialImportListener extends AnalysisEventListener<ErpMaterial
/** /**
* 物资类型 * 物资类型
*/ */
if (StringUtils.isNotEmpty(material.getMaterialTypeName())) { // if (StringUtils.isNotEmpty(material.getMaterialTypeName())) {
List<ErpMaterialType> materialTypes = materialTypeMapper.selectList(new LambdaQueryWrapper<ErpMaterialType>().eq(ErpMaterialType::getTypeName, material.getMaterialTypeName())); // List<ErpMaterialType> materialTypes = materialTypeMapper.selectList(new LambdaQueryWrapper<ErpMaterialType>().eq(ErpMaterialType::getTypeName, material.getMaterialTypeName()));
if (materialTypes.isEmpty()) { // if (materialTypes.isEmpty()) {
ErpMaterialType materialType = new ErpMaterialType(); // ErpMaterialType materialType = new ErpMaterialType();
materialType.setTypeName(material.getMaterialTypeName()); // materialType.setTypeName(material.getMaterialTypeName());
materialType.setParentId(1L); // materialType.setParentId(1L);
materialType.setAncestors("0,1"); // materialType.setAncestors("0,1");
materialTypeMapper.insert(materialType); // materialTypeMapper.insert(materialType);
material.setMaterialTypeId(materialType.getTypeId()); // material.setMaterialTypeId(materialType.getTypeId());
}else { // }else {
material.setMaterialTypeId(materialTypes.get(0).getTypeId()); // material.setMaterialTypeId(materialTypes.get(0).getTypeId());
} // }
} // }
/** /**
* 物资仓库 * 物资仓库
*/ */
...@@ -186,18 +186,18 @@ public class ErpMaterialImportListener extends AnalysisEventListener<ErpMaterial ...@@ -186,18 +186,18 @@ public class ErpMaterialImportListener extends AnalysisEventListener<ErpMaterial
/** /**
* 仓库货位 * 仓库货位
*/ */
if (StringUtils.isNotEmpty(material.getWarehouseLocationType())) { // if (StringUtils.isNotEmpty(material.getWarehouseLocationType())) {
ErpWarehouseLocation warehouseLocation = warehouseLocationMapper.selectOne(new LambdaQueryWrapper<ErpWarehouseLocation>().eq(ErpWarehouseLocation::getLocationType, material.getWarehouseLocationType())); // ErpWarehouseLocation warehouseLocation = warehouseLocationMapper.selectOne(new LambdaQueryWrapper<ErpWarehouseLocation>().eq(ErpWarehouseLocation::getLocationType, material.getWarehouseLocationType()));
if (ObjectUtil.isNull(warehouseLocation)) { // if (ObjectUtil.isNull(warehouseLocation)) {
ErpWarehouseLocation location = new ErpWarehouseLocation(); // ErpWarehouseLocation location = new ErpWarehouseLocation();
location.setLocationCode(material.getWarehouseLocationType()); // location.setLocationCode(material.getWarehouseLocationType());
location.setLocationType(material.getWarehouseLocationType()); // location.setLocationType(material.getWarehouseLocationType());
warehouseLocationMapper.insert(location); // warehouseLocationMapper.insert(location);
material.setWarehouseLocationId(location.getId()); // material.setWarehouseLocationId(location.getId());
} else { // } else {
material.setWarehouseLocationId(warehouseLocation.getId()); // material.setWarehouseLocationId(warehouseLocation.getId());
} // }
} // }
materialMapper.updateById(material); materialMapper.updateById(material);
successNum++; successNum++;
successMsg.append("<br/>").append(successNum).append("、物料 ").append(material.getMaterialName()).append(" 更新成功"); successMsg.append("<br/>").append(successNum).append("、物料 ").append(material.getMaterialName()).append(" 更新成功");
......
...@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.toolkit.Constants; ...@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.maintain.business.domain.ErpMaterialPickingInfo; import com.maintain.business.domain.ErpMaterialPickingInfo;
import com.maintain.business.domain.ErpMaterialReturnsInfo; import com.maintain.business.domain.ErpMaterialReturnsInfo;
import com.maintain.business.domain.bo.ErpMaterialPickingBo;
import com.maintain.business.domain.vo.ErpMaterialPickingExportVo;
import com.maintain.business.domain.vo.ErpMaterialPickingInfoVo; import com.maintain.business.domain.vo.ErpMaterialPickingInfoVo;
import com.maintain.business.domain.vo.ErpMaterialReturnsInfoVo; import com.maintain.business.domain.vo.ErpMaterialReturnsInfoVo;
import com.maintain.common.core.mapper.BaseMapperPlus; import com.maintain.common.core.mapper.BaseMapperPlus;
...@@ -35,4 +37,10 @@ public interface ErpMaterialPickingInfoMapper extends BaseMapperPlus<ErpMaterial ...@@ -35,4 +37,10 @@ public interface ErpMaterialPickingInfoMapper extends BaseMapperPlus<ErpMaterial
*/ */
List<ErpMaterialPickingInfoVo> customQueryList(@Param(Constants.WRAPPER) Wrapper<ErpMaterialPickingInfo> queryWrapper); List<ErpMaterialPickingInfoVo> customQueryList(@Param(Constants.WRAPPER) Wrapper<ErpMaterialPickingInfo> queryWrapper);
/**
* 获取导出列表
* @param bo 参数
* @return 结果
*/
List<ErpMaterialPickingExportVo> getExportList(ErpMaterialPickingBo bo);
} }
package com.maintain.business.mapper;
import com.maintain.business.domain.SysPayLog;
import com.maintain.business.domain.vo.SysPayLogVo;
import com.maintain.common.core.mapper.BaseMapperPlus;
/**
* 银联支付日志记录Mapper接口
*
* @author liushuai
* @date 2025-11-10
*/
public interface SysPayLogMapper extends BaseMapperPlus<SysPayLogMapper, SysPayLog, SysPayLogVo> {
}
...@@ -6,6 +6,7 @@ import com.maintain.business.domain.bo.ErpMaterialPickingBo; ...@@ -6,6 +6,7 @@ import com.maintain.business.domain.bo.ErpMaterialPickingBo;
import com.maintain.common.core.page.TableDataInfo; import com.maintain.common.core.page.TableDataInfo;
import com.maintain.common.core.domain.PageQuery; import com.maintain.common.core.domain.PageQuery;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
...@@ -63,4 +64,9 @@ public interface IErpMaterialPickingService { ...@@ -63,4 +64,9 @@ public interface IErpMaterialPickingService {
* 新增物料出库退料 * 新增物料出库退料
*/ */
Boolean insertReturnByBo(ErpMaterialPickingBo bo); Boolean insertReturnByBo(ErpMaterialPickingBo bo);
/**
* 导出物料出库列表
*/
void export(ErpMaterialPickingBo bo, HttpServletResponse response);
} }
...@@ -47,6 +47,11 @@ public interface IErpRepairFormProjectDispatchService { ...@@ -47,6 +47,11 @@ public interface IErpRepairFormProjectDispatchService {
*/ */
Boolean updateByBo(ErpRepairFormProjectDispatchBo bo); Boolean updateByBo(ErpRepairFormProjectDispatchBo bo);
/**
* 修改报修单-报修项目-派工
*/
Boolean updateBatchByBo(List<ErpRepairFormProjectDispatchBo> boList);
/** /**
* 校验并批量删除报修单-报修项目-派工信息 * 校验并批量删除报修单-报修项目-派工信息
*/ */
......
package com.maintain.business.service; package com.maintain.business.service;
import com.maintain.business.domain.ErpSettlementMaintain;
import com.maintain.business.domain.vo.ErpSettlementMaintainVo;
import com.maintain.business.domain.bo.ErpSettlementMaintainBo; import com.maintain.business.domain.bo.ErpSettlementMaintainBo;
import com.maintain.common.core.page.TableDataInfo; import com.maintain.business.domain.bo.ErpSettlementMaintainPayBo;
import com.maintain.business.domain.vo.ErpSettlementMaintainVo;
import com.maintain.common.core.domain.PageQuery; import com.maintain.common.core.domain.PageQuery;
import com.maintain.common.core.page.TableDataInfo;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
...@@ -53,4 +53,11 @@ public interface IErpSettlementMaintainService { ...@@ -53,4 +53,11 @@ public interface IErpSettlementMaintainService {
* @return * @return
*/ */
Boolean receiptByBo(ErpSettlementMaintainBo bo); Boolean receiptByBo(ErpSettlementMaintainBo bo);
/**
* 结算维修单支付
* @param bo
* @return
*/
Boolean pay(ErpSettlementMaintainPayBo bo);
} }
package com.maintain.business.service;
import com.maintain.business.domain.bo.SysPayLogBo;
import com.maintain.business.domain.vo.SysPayLogVo;
import com.maintain.common.core.domain.PageQuery;
import com.maintain.common.core.page.TableDataInfo;
import com.maintain.common.pay.PayResult;
import java.util.List;
/**
* 银联支付日志记录Service接口
*
* @author liushuai
* @date 2025-11-10
*/
public interface ISysPayLogService {
/**
* 查询银联支付日志记录
*/
SysPayLogVo queryById(Long id);
/**
* 查询银联支付日志记录列表
*/
TableDataInfo<SysPayLogVo> queryPageList(SysPayLogBo bo, PageQuery pageQuery);
/**
* 查询银联支付日志记录列表
*/
List<SysPayLogVo> queryList(SysPayLogBo bo);
/**
* 新增银联支付日志记录
*/
PayResult insertByBo(Long id, PayResult payResult);
}
...@@ -2,14 +2,12 @@ package com.maintain.business.service.impl; ...@@ -2,14 +2,12 @@ package com.maintain.business.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.extra.pinyin.PinyinUtil; import cn.hutool.extra.pinyin.PinyinUtil;
import com.maintain.business.domain.ErpMaintainMalfunction; import com.maintain.business.domain.*;
import com.maintain.business.domain.ErpMalfunctionProject;
import com.maintain.business.domain.ErpProjectType;
import com.maintain.business.domain.bo.ErpMalfunctionProjectBo; import com.maintain.business.domain.bo.ErpMalfunctionProjectBo;
import com.maintain.business.domain.vo.ErpMalfunctionProjectVo; import com.maintain.business.domain.vo.ErpMalfunctionProjectVo;
import com.maintain.business.mapper.ErpMaintainMalfunctionMapper; import com.maintain.business.domain.vo.ErpRepairFormProjectVo;
import com.maintain.business.mapper.ErpMalfunctionProjectMapper; import com.maintain.business.mapper.*;
import com.maintain.business.mapper.ErpProjectTypeMapper; import com.maintain.common.exception.ServiceException;
import com.maintain.common.pinyin.PinyinUtils; import com.maintain.common.pinyin.PinyinUtils;
import com.maintain.common.utils.StringUtils; import com.maintain.common.utils.StringUtils;
import com.maintain.common.core.page.TableDataInfo; import com.maintain.common.core.page.TableDataInfo;
...@@ -21,14 +19,13 @@ import lombok.RequiredArgsConstructor; ...@@ -21,14 +19,13 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.maintain.business.domain.bo.ErpMaintainProjectBo; import com.maintain.business.domain.bo.ErpMaintainProjectBo;
import com.maintain.business.domain.vo.ErpMaintainProjectVo; import com.maintain.business.domain.vo.ErpMaintainProjectVo;
import com.maintain.business.domain.ErpMaintainProject;
import com.maintain.business.mapper.ErpMaintainProjectMapper;
import com.maintain.business.service.IErpMaintainProjectService; import com.maintain.business.service.IErpMaintainProjectService;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Collection; import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -45,6 +42,7 @@ public class ErpMaintainProjectServiceImpl implements IErpMaintainProjectService ...@@ -45,6 +42,7 @@ public class ErpMaintainProjectServiceImpl implements IErpMaintainProjectService
private final ErpProjectTypeMapper projectTypeMapper; private final ErpProjectTypeMapper projectTypeMapper;
private final ErpMalfunctionProjectMapper malfunctionProjectMapper; private final ErpMalfunctionProjectMapper malfunctionProjectMapper;
private final ErpMaintainMalfunctionMapper maintainMalfunctionMapper; private final ErpMaintainMalfunctionMapper maintainMalfunctionMapper;
private final ErpRepairFormProjectMapper repairFormProjectMapper;
/** /**
...@@ -176,11 +174,18 @@ public class ErpMaintainProjectServiceImpl implements IErpMaintainProjectService ...@@ -176,11 +174,18 @@ public class ErpMaintainProjectServiceImpl implements IErpMaintainProjectService
/** /**
* 批量删除维修项目 * 批量删除维修项目
*/ */
@Transactional
@Override @Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){ if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验 //TODO 做一些业务上的校验,判断是否需要校验
List<ErpRepairFormProjectVo> projectVos = repairFormProjectMapper.selectVoList(new LambdaQueryWrapper<ErpRepairFormProject>().in(ErpRepairFormProject::getMaintainId, ids));
if (!projectVos.isEmpty()) {
Set<String> collect = projectVos.stream().map(ErpRepairFormProjectVo::getProjectName).collect(Collectors.toSet());
throw new ServiceException("删除失败,维修项目 "+collect+" 已被使用!");
}
} }
maintainMalfunctionMapper.delete(new LambdaQueryWrapper<ErpMaintainMalfunction>().in(ErpMaintainMalfunction::getMaintainId, ids));
return baseMapper.deleteBatchIds(ids) > 0; return baseMapper.deleteBatchIds(ids) > 0;
} }
} }
...@@ -87,9 +87,9 @@ public class ErpMaterialInventoryRecordServiceImpl implements IErpMaterialInvent ...@@ -87,9 +87,9 @@ public class ErpMaterialInventoryRecordServiceImpl implements IErpMaterialInvent
.eq("t.type", 1) .eq("t.type", 1)
.like(StringUtils.isNotBlank(bo.getMaterialName()),"t.material_name", bo.getMaterialName()) .like(StringUtils.isNotBlank(bo.getMaterialName()),"t.material_name", bo.getMaterialName())
.like(StringUtils.isNotBlank(bo.getMaterialCode()),"t.material_code", bo.getMaterialCode()) .like(StringUtils.isNotBlank(bo.getMaterialCode()),"t.material_code", bo.getMaterialCode())
.like(null != bo.getVendorId(),"t.vendor_id", bo.getVendorId()) .eq(null != bo.getVendorId(),"t.vendor_id", bo.getVendorId())
.like(null != bo.getWarehouseId(), "t.warehouse_id", bo.getWarehouseId()) .like(null != bo.getWarehouseId(), "t.warehouse_id", bo.getWarehouseId())
.in(!bo.getWarehouseIdList().isEmpty(), "t.warehouse_id", bo.getWarehouseIdList()) .in(null != bo.getWarehouseIdList(), "t.warehouse_id", bo.getWarehouseIdList())
.ge(null != bo.getInventory(), "t.inventory", bo.getInventory()) .ge(null != bo.getInventory(), "t.inventory", bo.getInventory())
.orderByDesc("t.create_time"); .orderByDesc("t.create_time");
Page<ErpMaterialInventoryRecordVo> queryPageList = baseMapper.customQueryPageInventoryList(pageQuery.build(), query); Page<ErpMaterialInventoryRecordVo> queryPageList = baseMapper.customQueryPageInventoryList(pageQuery.build(), query);
......
package com.maintain.business.service.impl; package com.maintain.business.service.impl;
import java.util.Date;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.maintain.business.domain.*; import com.maintain.business.domain.*;
import com.maintain.business.domain.bo.ErpMaterialPickingInfoAddBo; import com.maintain.business.domain.bo.ErpMaterialPickingInfoAddBo;
import com.maintain.business.domain.bo.ErpMaterialPickingInfoBo; import com.maintain.business.domain.bo.ErpMaterialPickingInfoBo;
...@@ -22,6 +24,9 @@ import com.maintain.common.core.domain.PageQuery; ...@@ -22,6 +24,9 @@ import com.maintain.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.maintain.common.utils.poi.ExcelUtil;
import com.maintain.common.utils.poi.MergeCellModel;
import com.maintain.common.utils.poi.SheetPO;
import com.maintain.common.utils.redis.RedisUtils; import com.maintain.common.utils.redis.RedisUtils;
import com.maintain.system.mapper.SysDeptMapper; import com.maintain.system.mapper.SysDeptMapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
...@@ -30,6 +35,7 @@ import com.maintain.business.domain.bo.ErpMaterialPickingBo; ...@@ -30,6 +35,7 @@ import com.maintain.business.domain.bo.ErpMaterialPickingBo;
import com.maintain.business.service.IErpMaterialPickingService; import com.maintain.business.service.IErpMaterialPickingService;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -142,7 +148,7 @@ public class ErpMaterialPickingServiceImpl implements IErpMaterialPickingService ...@@ -142,7 +148,7 @@ public class ErpMaterialPickingServiceImpl implements IErpMaterialPickingService
lqw.eq(bo.getReceiveTime() != null, ErpMaterialPicking::getReceiveTime, bo.getReceiveTime()); lqw.eq(bo.getReceiveTime() != null, ErpMaterialPicking::getReceiveTime, bo.getReceiveTime());
lqw.eq(bo.getState() != null, ErpMaterialPicking::getState, bo.getState()); lqw.eq(bo.getState() != null, ErpMaterialPicking::getState, bo.getState());
lqw.in(bo.getStateList() != null, ErpMaterialPicking::getState, bo.getStateList()); lqw.in(bo.getStateList() != null, ErpMaterialPicking::getState, bo.getStateList());
lqw.in(!sysDeptList.isEmpty(), ErpMaterialPicking::getCreateDeptId, sysDeptList.stream().map(SysDept::getDeptId).collect(Collectors.toList())); lqw.in(bo.getRepairFormId() == null && !sysDeptList.isEmpty(), ErpMaterialPicking::getCreateDeptId, sysDeptList.stream().map(SysDept::getDeptId).collect(Collectors.toList()));
lqw.orderByDesc(BaseEntity::getCreateTime); lqw.orderByDesc(BaseEntity::getCreateTime);
return lqw; return lqw;
} }
...@@ -168,7 +174,7 @@ public class ErpMaterialPickingServiceImpl implements IErpMaterialPickingService ...@@ -168,7 +174,7 @@ public class ErpMaterialPickingServiceImpl implements IErpMaterialPickingService
add.setVendorName(materialVendor.getVendorName()); add.setVendorName(materialVendor.getVendorName());
BigDecimal moneyTotal = bo.getMaterialList().stream().map(ErpMaterialPickingInfoAddBo::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal moneyTotal = bo.getMaterialList().stream().map(ErpMaterialPickingInfoAddBo::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
add.setOutMoney(moneyTotal); add.setOutMoney(moneyTotal);
add.setCreateDeptId(LoginHelper.getUserId()); add.setCreateDeptId(LoginHelper.getDeptId());
validEntityBeforeSave(add); validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0; boolean flag = baseMapper.insert(add) > 0;
if (flag) { if (flag) {
...@@ -446,4 +452,58 @@ public class ErpMaterialPickingServiceImpl implements IErpMaterialPickingService ...@@ -446,4 +452,58 @@ public class ErpMaterialPickingServiceImpl implements IErpMaterialPickingService
} }
return flag; return flag;
} }
@Override
public void export(ErpMaterialPickingBo bo, HttpServletResponse response) {
String sheetName ="供应商材料消耗明细表";
String title ="供应商铺货结算表";
List<SysDept> sysDeptList = deptMapper.selectChildrenDeptById(LoginHelper.getDeptId(), null);
if (!sysDeptList.isEmpty()){
bo.setDeptIds(sysDeptList.stream().map(SysDept::getDeptId).collect(Collectors.toList()));
}
List<ErpMaterialPickingExportVo> list = pickingInfoMapper.getExportList(bo);
//生成合并单元格信息
List<MergeCellModel> mergeCellList = new ArrayList<>();
Integer centerMergedAnchorExcelRowIndex = null;
if (CollectionUtils.isNotEmpty(list)){
list.forEach(item -> {
item.setIndex(String.valueOf(list.indexOf(item) + 1));
});
//合计统计
ErpMaterialPickingExportVo erpMaterialPickingExportVo1 = new ErpMaterialPickingExportVo();
// 合计文案须落在合并区域左上角列:index=0 为序号(Integer),合并 0~10 时左上角为空会“吃掉”7、8 列的合计文字
erpMaterialPickingExportVo1.setIndex("合计");
list.add(erpMaterialPickingExportVo1);
// 双行表头:第 0 行为大标题,第 1 行为列名;合计行 Excel 行号 = list.size() + 1
int totalExcelRowIndex = list.size() + 1;
centerMergedAnchorExcelRowIndex = totalExcelRowIndex;
mergeCellList.add(MergeCellModel.createMergeCellModel(sheetName, totalExcelRowIndex, totalExcelRowIndex, 0, 11));
//计算数量总和
BigDecimal collectNumber = list.stream().map(ErpMaterialPickingExportVo::getCollectNumber).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
erpMaterialPickingExportVo1.setCollectNumber(collectNumber);
//计算价格总和
BigDecimal money = list.stream().map(ErpMaterialPickingExportVo::getMoney).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
erpMaterialPickingExportVo1.setMoney(money);
//签名地方
ErpMaterialPickingExportVo erpMaterialPickingExportVo2 = new ErpMaterialPickingExportVo();
erpMaterialPickingExportVo2.setWorkshopName("车间仓库员签名:");
erpMaterialPickingExportVo2.setMaterialSpecifications("车间负责人签名:");
list.add(erpMaterialPickingExportVo2);
}
List<SheetPO> sheetPOList = new ArrayList<>();
SheetPO<ErpMaterialPickingExportVo> sheetPO = new SheetPO<>();
sheetPOList.add(sheetPO);
Map<String, String> titleMap = new HashMap<>();
titleMap.put("title", title);
sheetPO.setData(list);
sheetPO.setTitleMap(titleMap);
sheetPO.setClazz(ErpMaterialPickingExportVo.class);
sheetPO.setSheetNo(1);
sheetPO.setMergeCellList(mergeCellList);
sheetPO.setSheetName(sheetName);
sheetPO.setWhiteFirstHeadRow(true);
sheetPO.setCenterMergedAnchorExcelRowIndex(centerMergedAnchorExcelRowIndex);
ExcelUtil.exportSheetSetTitle(response, title, sheetPOList);
}
} }
...@@ -247,6 +247,7 @@ public class ErpMaterialPutawayServiceImpl implements IErpMaterialPutawayService ...@@ -247,6 +247,7 @@ public class ErpMaterialPutawayServiceImpl implements IErpMaterialPutawayService
List<ErpMaterialInventoryRecord> inventoryRecordList = collect.stream().map(item -> { List<ErpMaterialInventoryRecord> inventoryRecordList = collect.stream().map(item -> {
ErpMaterialInventoryRecord record = new ErpMaterialInventoryRecord(); ErpMaterialInventoryRecord record = new ErpMaterialInventoryRecord();
record.setInfoId(item.getId()); record.setInfoId(item.getId());
record.setVendorId(item.getVendorId());
record.setMaterialId(item.getMaterialId()); record.setMaterialId(item.getMaterialId());
record.setWarehouseId(warehouseVo.getId()); record.setWarehouseId(warehouseVo.getId());
record.setDeptId(warehouseVo.getDeptId()); record.setDeptId(warehouseVo.getDeptId());
......
...@@ -3,12 +3,16 @@ package com.maintain.business.service.impl; ...@@ -3,12 +3,16 @@ package com.maintain.business.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.maintain.business.domain.*; import com.maintain.business.domain.*;
import com.maintain.business.domain.vo.ErpMaterialInventoryRecordVo;
import com.maintain.business.domain.vo.ErpUserVo; import com.maintain.business.domain.vo.ErpUserVo;
import com.maintain.business.domain.vo.ErpWarehouseVo;
import com.maintain.business.mapper.*; import com.maintain.business.mapper.*;
import com.maintain.business.service.IErpMaterialService; import com.maintain.business.service.IErpMaterialService;
import com.maintain.common.enums.InventoryType;
import com.maintain.common.enums.IsEnableStatus; import com.maintain.common.enums.IsEnableStatus;
import com.maintain.common.enums.PickingState; import com.maintain.common.enums.PickingState;
import com.maintain.common.enums.RepairFormState; import com.maintain.common.enums.RepairFormState;
import com.maintain.common.exception.ServiceException;
import com.maintain.common.utils.StringUtils; import com.maintain.common.utils.StringUtils;
import com.maintain.common.core.page.TableDataInfo; import com.maintain.common.core.page.TableDataInfo;
import com.maintain.common.core.domain.PageQuery; import com.maintain.common.core.domain.PageQuery;
...@@ -44,6 +48,9 @@ public class ErpRepairFormDeliveryServiceImpl implements IErpRepairFormDeliveryS ...@@ -44,6 +48,9 @@ public class ErpRepairFormDeliveryServiceImpl implements IErpRepairFormDeliveryS
private final ErpMaterialPickingMapper pickingMapper; private final ErpMaterialPickingMapper pickingMapper;
private final ErpMaterialPickingInfoMapper pickingInfoMapper; private final ErpMaterialPickingInfoMapper pickingInfoMapper;
private final IErpMaterialService materialService; private final IErpMaterialService materialService;
private final ErpMaterialInventoryRecordMapper materialInventoryRecordMapper;
private final ErpMaterialPutawayInfoMapper putawayInfoMapper;
private final ErpWarehouseMapper warehouseMapper;
/** /**
* 查询报修单-交车信息 * 查询报修单-交车信息
...@@ -116,15 +123,37 @@ public class ErpRepairFormDeliveryServiceImpl implements IErpRepairFormDeliveryS ...@@ -116,15 +123,37 @@ public class ErpRepairFormDeliveryServiceImpl implements IErpRepairFormDeliveryS
pickingInfoLambdaQueryWrapper.eq(ErpMaterialPickingInfo::getRepairFormId, add.getRepairFormId()).eq(ErpMaterialPickingInfo::getState, PickingState.ONE.getCode()); pickingInfoLambdaQueryWrapper.eq(ErpMaterialPickingInfo::getRepairFormId, add.getRepairFormId()).eq(ErpMaterialPickingInfo::getState, PickingState.ONE.getCode());
List<ErpMaterialPickingInfo> pickingInfoList = pickingInfoMapper.selectList(pickingInfoLambdaQueryWrapper); List<ErpMaterialPickingInfo> pickingInfoList = pickingInfoMapper.selectList(pickingInfoLambdaQueryWrapper);
if (!pickingInfoList.isEmpty()) { if (!pickingInfoList.isEmpty()) {
for (ErpMaterialPickingInfo pickingInfo : pickingInfoList) { List<ErpMaterialInventoryRecord> inventoryRecordList = pickingInfoList.stream().map(item -> {
materialService.modifyMaterialInventory(pickingInfo.getMaterialId(), pickingInfo.getCollectNumber(), false); ErpMaterialInventoryRecordVo recordVo = materialInventoryRecordMapper.customQueryInventoryById(item.getRecordId());
} if (null == recordVo) {
pickingInfoMapper.updateBatchById(pickingInfoList.stream().map(item -> { throw new ServiceException("仓库["+item.getWarehouseName()+"]中物料["+item.getMaterialName()+"]库存异常,请联系管理员!");
ErpMaterialPickingInfo pickingInfo = new ErpMaterialPickingInfo(); }
pickingInfo.setId(item.getId()); if (item.getCollectNumber().compareTo(recordVo.getInventory()) > 0) {
pickingInfo.setState(PickingState.TWO.getCode()); throw new ServiceException("仓库["+item.getWarehouseName()+"]中物料["+item.getMaterialName()+"]库存不足,请调整后重试!");
return pickingInfo; }
}).collect(Collectors.toList())); /* 记录已出数量 */
ErpMaterialInventoryRecord inventoryRecord = materialInventoryRecordMapper.selectById(item.getRecordId());
if (null == inventoryRecord) {
throw new ServiceException("库存存在异常,请联系管理员!!!");
}
ErpMaterialPutawayInfo putawayInfo = putawayInfoMapper.selectById(inventoryRecord.getInfoId());
putawayInfo.setIssuedNumber(putawayInfo.getIssuedNumber().add(item.getCollectNumber()));
putawayInfoMapper.updateById(putawayInfo);
/* 创建库存记录 */
ErpMaterialInventoryRecord record = new ErpMaterialInventoryRecord();
record.setInfoId(item.getId());
record.setMaterialId(item.getMaterialId());
ErpWarehouseVo warehouseVo = warehouseMapper.selectVoById(item.getWarehouseId());
record.setWarehouseId(warehouseVo.getId());
record.setDeptId(warehouseVo.getDeptId());
record.setVendorId(item.getVendorId());
record.setNumber(item.getCollectNumber());
record.setPrice(item.getPrice());
record.setMoney(item.getMoney());
record.setType(InventoryType.picking.getCode());
return record;
}).collect(Collectors.toList());
materialInventoryRecordMapper.insertBatch(inventoryRecordList);
} }
} }
return flag; return flag;
......
package com.maintain.business.service.impl; package com.maintain.business.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.maintain.business.domain.ErpRepairFormProject; import com.maintain.business.domain.ErpRepairFormProject;
import com.maintain.business.domain.bo.ErpRepairFormProjectDispatchBatchBo; import com.maintain.business.domain.bo.ErpRepairFormProjectDispatchBatchBo;
import com.maintain.business.domain.vo.ErpUserVo; import com.maintain.business.domain.vo.ErpUserVo;
...@@ -23,6 +24,8 @@ import com.maintain.business.service.IErpRepairFormProjectDispatchService; ...@@ -23,6 +24,8 @@ import com.maintain.business.service.IErpRepairFormProjectDispatchService;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Collection; import java.util.Collection;
...@@ -112,10 +115,22 @@ public class ErpRepairFormProjectDispatchServiceImpl implements IErpRepairFormPr ...@@ -112,10 +115,22 @@ public class ErpRepairFormProjectDispatchServiceImpl implements IErpRepairFormPr
@Override @Override
public Boolean insertBatchByBo(ErpRepairFormProjectDispatchBatchBo bo) { public Boolean insertBatchByBo(ErpRepairFormProjectDispatchBatchBo bo) {
ErpRepairFormProject formProject = projectMapper.selectById(bo.getProjectId()); ErpRepairFormProject formProject = projectMapper.selectById(bo.getProjectId());
// 删除原有绑定 // 删除原有绑定
LambdaQueryWrapper<ErpRepairFormProjectDispatch> lqw = Wrappers.lambdaQuery(); LambdaQueryWrapper<ErpRepairFormProjectDispatch> lqw = Wrappers.lambdaQuery();
lqw.eq(ErpRepairFormProjectDispatch::getRepairFormProjectId, bo.getProjectId()); lqw.eq(ErpRepairFormProjectDispatch::getRepairFormProjectId, bo.getProjectId());
BigDecimal totalActualManHour = baseMapper.selectList(lqw)
.stream()
.map(ErpRepairFormProjectDispatch::getActualManHour).reduce(BigDecimal.ZERO, BigDecimal::add);
baseMapper.delete(lqw); baseMapper.delete(lqw);
// 汇总原总工时
//总工时均分
BigDecimal hour = formProject.getStandardManHour().divide(
BigDecimal.valueOf(bo.getDispatchIdList().size()), 1, RoundingMode.HALF_DOWN
);
BigDecimal totalHour = hour.multiply(BigDecimal.valueOf(bo.getDispatchIdList().size()));
BigDecimal lostHour = formProject.getStandardManHour().subtract(totalHour);
// 批量新增派工人员列表 // 批量新增派工人员列表
List<ErpRepairFormProjectDispatch> collect = bo.getDispatchIdList().stream().map(item -> { List<ErpRepairFormProjectDispatch> collect = bo.getDispatchIdList().stream().map(item -> {
ErpRepairFormProjectDispatch projectDispatch = new ErpRepairFormProjectDispatch(); ErpRepairFormProjectDispatch projectDispatch = new ErpRepairFormProjectDispatch();
...@@ -132,15 +147,20 @@ public class ErpRepairFormProjectDispatchServiceImpl implements IErpRepairFormPr ...@@ -132,15 +147,20 @@ public class ErpRepairFormProjectDispatchServiceImpl implements IErpRepairFormPr
projectDispatch.setMaintainUserName(userVo.getName()); projectDispatch.setMaintainUserName(userVo.getName());
projectDispatch.setMaintainJobNumber(userVo.getJobNumber()); projectDispatch.setMaintainJobNumber(userVo.getJobNumber());
projectDispatch.setMaintainUserState(userVo.getState()); projectDispatch.setMaintainUserState(userVo.getState());
BigDecimal hour = formProject.getStandardManHour().divide(BigDecimal.valueOf(bo.getDispatchIdList().size()));
projectDispatch.setDispatchManHour(hour); projectDispatch.setDispatchManHour(hour);
projectDispatch.setActualManHour(hour); projectDispatch.setActualManHour(hour);
// projectDispatch.setDeductManHour(hour); // projectDispatch.setDeductManHour(hour);
// 汇总实际总工时
formProject.setActualTime(formProject.getActualTime().add(hour));
return projectDispatch; return projectDispatch;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
//处理最后一个
if (bo.getDispatchIdList().size() > 1) {
ErpRepairFormProjectDispatch projectDispatch = collect.get(collect.size() - 1);
projectDispatch.setDispatchManHour(projectDispatch.getDispatchManHour().add(lostHour));
projectDispatch.setActualManHour(hour);
}
formProject.setIsDispatch(IsEnableStatus.YES.getCode()); formProject.setIsDispatch(IsEnableStatus.YES.getCode());
formProject.setActualTime(formProject.getStandardManHour());
projectMapper.updateById(formProject); projectMapper.updateById(formProject);
return baseMapper.insertBatch(collect); return baseMapper.insertBatch(collect);
} }
...@@ -149,11 +169,43 @@ public class ErpRepairFormProjectDispatchServiceImpl implements IErpRepairFormPr ...@@ -149,11 +169,43 @@ public class ErpRepairFormProjectDispatchServiceImpl implements IErpRepairFormPr
* 修改报修单-报修项目-派工 * 修改报修单-报修项目-派工
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class)
public Boolean updateByBo(ErpRepairFormProjectDispatchBo bo) { public Boolean updateByBo(ErpRepairFormProjectDispatchBo bo) {
ErpRepairFormProjectDispatch projectDispatch = baseMapper.selectById(bo.getId()); ErpRepairFormProjectDispatch projectDispatch = baseMapper.selectById(bo.getId());
projectDispatch.setDispatchManHour(bo.getDispatchManHour());
projectDispatch.setActualManHour(bo.getDispatchManHour().subtract(bo.getDeductManHour())); projectDispatch.setActualManHour(bo.getDispatchManHour().subtract(bo.getDeductManHour()));
projectDispatch.setDeductManHour(bo.getDeductManHour()); projectDispatch.setDeductManHour(bo.getDeductManHour());
return baseMapper.updateById(projectDispatch) > 0; boolean flag = baseMapper.updateById(projectDispatch) > 0;
updateFormProject(projectDispatch.getRepairFormProjectId());
return flag;
}
@Override
public Boolean updateBatchByBo(List<ErpRepairFormProjectDispatchBo> boList) {
if (CollUtil.isEmpty(boList)){
return false;
}
List<ErpRepairFormProjectDispatch> dispatchList = boList.stream().map(bo -> {
ErpRepairFormProjectDispatch projectDispatch = new ErpRepairFormProjectDispatch();
projectDispatch.setId(bo.getId());
projectDispatch.setDispatchManHour(bo.getDispatchManHour());
projectDispatch.setActualManHour(bo.getDispatchManHour().subtract(bo.getDeductManHour()));
projectDispatch.setDeductManHour(bo.getDeductManHour());
return projectDispatch;
}).collect(Collectors.toList());
baseMapper.updateBatchById(dispatchList);
//计算总工时
BigDecimal reduce = dispatchList.stream().map(ErpRepairFormProjectDispatch::getActualManHour).reduce(BigDecimal.ZERO, BigDecimal::add);
ErpRepairFormProject project = new ErpRepairFormProject();
project.setId(boList.get(0).getRepairFormProjectId());
project.setActualTime(reduce);
projectMapper.updateById(project);
return true;
} }
/** /**
...@@ -167,10 +219,34 @@ public class ErpRepairFormProjectDispatchServiceImpl implements IErpRepairFormPr ...@@ -167,10 +219,34 @@ public class ErpRepairFormProjectDispatchServiceImpl implements IErpRepairFormPr
* 批量删除报修单-报修项目-派工 * 批量删除报修单-报修项目-派工
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){ if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验 //TODO 做一些业务上的校验,判断是否需要校验
} }
return baseMapper.deleteBatchIds(ids) > 0; Iterator<Long> iterator = ids.iterator();
Long id = iterator.hasNext() ? iterator.next() : null;
ErpRepairFormProjectDispatch projectDispatch = baseMapper.selectById(id);
boolean flag = baseMapper.deleteBatchIds(ids) > 0;
updateFormProject(projectDispatch.getRepairFormProjectId());
return flag;
}
/**
* 更新报修单-报修项目实际时间
* @param projectId
*/
private void updateFormProject(Long projectId){
List<ErpRepairFormProjectDispatch> formProjectDispatches = baseMapper.selectList(Wrappers.<ErpRepairFormProjectDispatch>lambdaQuery()
.eq(ErpRepairFormProjectDispatch::getRepairFormProjectId, projectId));
//计算总工时
BigDecimal reduce = formProjectDispatches.stream().map(ErpRepairFormProjectDispatch::getActualManHour).reduce(BigDecimal.ZERO, BigDecimal::add);
ErpRepairFormProject project = new ErpRepairFormProject();
project.setId(projectId);
project.setActualTime(reduce);
projectMapper.updateById(project);
} }
} }
package com.maintain.business.service.impl; package com.maintain.business.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.maintain.business.domain.*; import com.maintain.business.domain.*;
import com.maintain.business.domain.bo.ErpRepairFormBo;
import com.maintain.business.domain.vo.ErpGroupVo; import com.maintain.business.domain.vo.ErpGroupVo;
import com.maintain.business.domain.vo.ErpMaterialInventoryRecordVo;
import com.maintain.business.domain.vo.ErpRepairFormDeliveryVo; import com.maintain.business.domain.vo.ErpRepairFormDeliveryVo;
import com.maintain.business.domain.vo.ErpRepairFormVo;
import com.maintain.business.mapper.*; import com.maintain.business.mapper.*;
import com.maintain.business.service.IErpMaterialService; import com.maintain.business.service.IErpMaterialService;
import com.maintain.business.service.IErpRepairFormService;
import com.maintain.common.core.domain.PageQuery;
import com.maintain.common.core.domain.entity.SysDept; import com.maintain.common.core.domain.entity.SysDept;
import com.maintain.common.core.page.TableDataInfo;
import com.maintain.common.enums.PickingState; import com.maintain.common.enums.PickingState;
import com.maintain.common.enums.RepairFormState; import com.maintain.common.enums.RepairFormState;
import com.maintain.common.helper.LoginHelper; import com.maintain.common.helper.LoginHelper;
import com.maintain.common.utils.StringUtils; import com.maintain.common.utils.StringUtils;
import com.maintain.common.core.page.TableDataInfo;
import com.maintain.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.maintain.common.utils.redis.RedisUtils; import com.maintain.common.utils.redis.RedisUtils;
import com.maintain.system.mapper.SysDeptMapper; import com.maintain.system.mapper.SysDeptMapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.maintain.business.domain.bo.ErpRepairFormBo;
import com.maintain.business.domain.vo.ErpRepairFormVo;
import com.maintain.business.service.IErpRepairFormService;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Collection;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -55,6 +56,9 @@ public class ErpRepairFormServiceImpl implements IErpRepairFormService { ...@@ -55,6 +56,9 @@ public class ErpRepairFormServiceImpl implements IErpRepairFormService {
private final ErpMaterialPickingInfoMapper pickingInfoMapper; private final ErpMaterialPickingInfoMapper pickingInfoMapper;
private final ErpMaterialPickingMapper pickingMapper; private final ErpMaterialPickingMapper pickingMapper;
private final IErpMaterialService materialService; private final IErpMaterialService materialService;
private final ErpMaterialInventoryRecordMapper materialInventoryRecordMapper;
private final ErpMaterialPutawayInfoMapper putawayInfoMapper;
private final ErpWarehouseMapper warehouseMapper;
/** /**
* 查询报修单 * 查询报修单
...@@ -289,18 +293,29 @@ public class ErpRepairFormServiceImpl implements IErpRepairFormService { ...@@ -289,18 +293,29 @@ public class ErpRepairFormServiceImpl implements IErpRepairFormService {
LambdaQueryWrapper<ErpMaterialPickingInfo> pickingInfoLambdaQueryWrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<ErpMaterialPickingInfo> pickingInfoLambdaQueryWrapper = Wrappers.lambdaQuery();
pickingInfoLambdaQueryWrapper.eq(ErpMaterialPickingInfo::getRepairFormId, repairForm.getId()).eq(ErpMaterialPickingInfo::getState, PickingState.TWO.getCode()); pickingInfoLambdaQueryWrapper.eq(ErpMaterialPickingInfo::getRepairFormId, repairForm.getId()).eq(ErpMaterialPickingInfo::getState, PickingState.TWO.getCode());
List<ErpMaterialPickingInfo> pickingInfoList = pickingInfoMapper.selectList(pickingInfoLambdaQueryWrapper); List<ErpMaterialPickingInfo> pickingInfoList = pickingInfoMapper.selectList(pickingInfoLambdaQueryWrapper);
for (ErpMaterialPickingInfo pickingInfo : pickingInfoList) { List<Long> pickingInfoIds = pickingInfoList.stream().map(item -> {
materialService.modifyMaterialInventory(pickingInfo.getMaterialId(), pickingInfo.getCollectNumber(), true); /* 回退入库明细中已出数量 */
} ErpMaterialInventoryRecordVo recordVo = materialInventoryRecordMapper.customQueryInventoryById(item.getRecordId());
ErpMaterialPutawayInfo putawayInfo = putawayInfoMapper.selectById(recordVo.getInfoId());
putawayInfo.setIssuedNumber(putawayInfo.getIssuedNumber().subtract(item.getCollectNumber()));
putawayInfoMapper.updateById(putawayInfo);
return item.getId();
}).collect(Collectors.toList());
// 将出库单以及出库明细所有状态全部更新为已退料 // 将出库单以及出库明细所有状态全部更新为已退料
LambdaUpdateWrapper<ErpMaterialPicking> pickingLambdaUpdateWrapper = Wrappers.lambdaUpdate(); pickingMapper.delete(
pickingLambdaUpdateWrapper.eq(ErpMaterialPicking::getRepairFormId, repairForm.getId()); new LambdaUpdateWrapper<ErpMaterialPicking>()
pickingLambdaUpdateWrapper.set(ErpMaterialPicking::getState, PickingState.THREE.getCode()); .eq(ErpMaterialPicking::getRepairFormId, repairForm.getId())
pickingMapper.update(pickingLambdaUpdateWrapper); );
LambdaUpdateWrapper<ErpMaterialPickingInfo> pickingInfoLambdaUpdateWrapper = Wrappers.lambdaUpdate(); pickingInfoMapper.delete(
pickingInfoLambdaUpdateWrapper.eq(ErpMaterialPickingInfo::getRepairFormId, repairForm.getId()); new LambdaUpdateWrapper<ErpMaterialPickingInfo>()
pickingInfoLambdaUpdateWrapper.set(ErpMaterialPickingInfo::getState, PickingState.THREE.getCode()); .eq(ErpMaterialPickingInfo::getRepairFormId, repairForm.getId())
pickingInfoMapper.update(pickingInfoLambdaUpdateWrapper); );
// 删除库存记录表数据
if (!pickingInfoIds.isEmpty()) {
LambdaUpdateWrapper<ErpMaterialInventoryRecord> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.in(ErpMaterialInventoryRecord::getInfoId, pickingInfoIds);
materialInventoryRecordMapper.delete(lambdaUpdateWrapper);
}
} }
return flag; return flag;
} }
......
package com.maintain.business.service.impl; package com.maintain.business.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.maintain.business.domain.ErpRepairForm; import com.maintain.business.domain.ErpRepairForm;
import com.maintain.business.domain.ErpSettlementMaintain;
import com.maintain.business.domain.ErpSettlementMaintainRepairForm; import com.maintain.business.domain.ErpSettlementMaintainRepairForm;
import com.maintain.business.domain.bo.ErpSettlementMaintainRepairFormBo; import com.maintain.business.domain.bo.ErpSettlementMaintainBo;
import com.maintain.business.domain.bo.ErpSettlementMaintainPayBo;
import com.maintain.business.domain.vo.ErpClientVo; import com.maintain.business.domain.vo.ErpClientVo;
import com.maintain.business.domain.vo.ErpSettlementMaintainVo;
import com.maintain.business.mapper.ErpClientMapper; import com.maintain.business.mapper.ErpClientMapper;
import com.maintain.business.mapper.ErpRepairFormMapper; import com.maintain.business.mapper.ErpRepairFormMapper;
import com.maintain.business.mapper.ErpSettlementMaintainMapper;
import com.maintain.business.mapper.ErpSettlementMaintainRepairFormMapper; import com.maintain.business.mapper.ErpSettlementMaintainRepairFormMapper;
import com.maintain.business.service.IErpSettlementMaintainService;
import com.maintain.business.service.ISysPayLogService;
import com.maintain.common.core.domain.PageQuery;
import com.maintain.common.core.domain.entity.SysDept;
import com.maintain.common.core.page.TableDataInfo;
import com.maintain.common.enums.RepairFormSettlementState; import com.maintain.common.enums.RepairFormSettlementState;
import com.maintain.common.enums.SettlementState; import com.maintain.common.enums.SettlementState;
import com.maintain.common.exception.ServiceException;
import com.maintain.common.helper.LoginHelper; import com.maintain.common.helper.LoginHelper;
import com.maintain.common.pay.PayResponse;
import com.maintain.common.pay.PayResult;
import com.maintain.common.pay.YinLianPayApi;
import com.maintain.common.utils.StringUtils; import com.maintain.common.utils.StringUtils;
import com.maintain.common.core.page.TableDataInfo;
import com.maintain.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.maintain.common.utils.redis.RedisUtils; import com.maintain.common.utils.redis.RedisUtils;
import com.maintain.system.mapper.SysDeptMapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.maintain.business.domain.bo.ErpSettlementMaintainBo;
import com.maintain.business.domain.vo.ErpSettlementMaintainVo;
import com.maintain.business.domain.ErpSettlementMaintain;
import com.maintain.business.mapper.ErpSettlementMaintainMapper;
import com.maintain.business.service.IErpSettlementMaintainService;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Collection;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -49,6 +57,12 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS ...@@ -49,6 +57,12 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS
private final ErpSettlementMaintainRepairFormMapper settlementMaintainRepairFormMapper; private final ErpSettlementMaintainRepairFormMapper settlementMaintainRepairFormMapper;
private final ErpRepairFormMapper repairFormMapper; private final ErpRepairFormMapper repairFormMapper;
private final ErpClientMapper clientMapper; private final ErpClientMapper clientMapper;
private final YinLianPayApi yinLianPayApi;
private final SysDeptMapper sysDeptMapper;
private final ISysPayLogService sysPayLogService;
private final SysDeptMapper deptMapper;
@Value("${pay.merchantCode}")
private String merchantCode;
/** /**
* 查询结算维修单 * 查询结算维修单
...@@ -78,6 +92,7 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS ...@@ -78,6 +92,7 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS
} }
private LambdaQueryWrapper<ErpSettlementMaintain> buildQueryWrapper(ErpSettlementMaintainBo bo) { private LambdaQueryWrapper<ErpSettlementMaintain> buildQueryWrapper(ErpSettlementMaintainBo bo) {
List<SysDept> sysDeptList = deptMapper.selectChildrenDeptById(LoginHelper.getDeptId(), null);
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<ErpSettlementMaintain> lqw = Wrappers.lambdaQuery(); LambdaQueryWrapper<ErpSettlementMaintain> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getSettlementNumber()), ErpSettlementMaintain::getSettlementNumber, bo.getSettlementNumber()); lqw.like(StringUtils.isNotBlank(bo.getSettlementNumber()), ErpSettlementMaintain::getSettlementNumber, bo.getSettlementNumber());
...@@ -88,7 +103,7 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS ...@@ -88,7 +103,7 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS
lqw.eq(bo.getClientCertificateType() != null, ErpSettlementMaintain::getClientCertificateType, bo.getClientCertificateType()); lqw.eq(bo.getClientCertificateType() != null, ErpSettlementMaintain::getClientCertificateType, bo.getClientCertificateType());
lqw.eq(StringUtils.isNotBlank(bo.getClientCertificateNumber()), ErpSettlementMaintain::getClientCertificateNumber, bo.getClientCertificateNumber()); lqw.eq(StringUtils.isNotBlank(bo.getClientCertificateNumber()), ErpSettlementMaintain::getClientCertificateNumber, bo.getClientCertificateNumber());
lqw.eq(bo.getState() != null, ErpSettlementMaintain::getState, bo.getState()); lqw.eq(bo.getState() != null, ErpSettlementMaintain::getState, bo.getState());
lqw.eq(bo.getCreateDeptId() != null, ErpSettlementMaintain::getCreateDeptId, bo.getCreateDeptId()); lqw.in(ErpSettlementMaintain::getCreateDeptId, sysDeptList.stream().map(SysDept::getDeptId).collect(Collectors.toList()));
lqw.orderByDesc(ErpSettlementMaintain::getCreateTime); lqw.orderByDesc(ErpSettlementMaintain::getCreateTime);
return lqw; return lqw;
} }
...@@ -204,4 +219,65 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS ...@@ -204,4 +219,65 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS
} }
return flag; return flag;
} }
/**
* 结算维修单支付
*
* @param bo
* @return
*/
@Transactional(rollbackFor = Exception.class)
@Override
public Boolean pay(ErpSettlementMaintainPayBo bo) {
ErpSettlementMaintain maintain = baseMapper.selectById(bo.getId());
List<ErpSettlementMaintainRepairForm> maintainRepairForms = settlementMaintainRepairFormMapper.selectList(
new LambdaQueryWrapper<ErpSettlementMaintainRepairForm>()
.eq(ErpSettlementMaintainRepairForm::getSettlementMaintainId, maintain.getId())
);
if (ObjectUtil.isEmpty(maintainRepairForms)) {
throw new ServiceException("当前结算单未绑定维修单,请检查后重试!");
}
ErpSettlementMaintainRepairForm settlementMaintainRepairForm = maintainRepairForms.get(0);
ErpRepairForm repairForm = repairFormMapper.selectById(settlementMaintainRepairForm.getRepairFormId());
if (ObjectUtil.isEmpty(repairForm)) {
throw new ServiceException("报修单不存在,请联系管理员!");
}
SysDept sysDept = sysDeptMapper.selectById(repairForm.getRepairerDeptId());
if (ObjectUtil.isEmpty(sysDept)) {
throw new ServiceException("维修车间不存在,请联系管理员!");
}
if (ObjectUtil.isEmpty(sysDept.getTerminalCode())) {
throw new ServiceException("当前车间未填写终端号,请联系管理员添加!");
}
if (ObjectUtil.isEmpty(maintain)) {
throw new ServiceException("当前支付订单不存在,请刷新后重试!");
}
if (maintain.getState().equals(SettlementState.TWO.getCode())) {
throw new ServiceException("当前结算单已支付,不能重复支付!");
}
// 生成一个时间戳单号
String orderNo = String.valueOf(System.currentTimeMillis());
int money = maintain.getPracticalMoney().movePointRight(2).intValue();
if (money == 0) {
throw new ServiceException("结算单金额为0,无需支付!");
}
// 调用支付API
PayResult payResult = yinLianPayApi.pay(orderNo, money, bo.getPaymentAccount(), sysDept.getTerminalCode());
/* 保存支付调用记录 */
sysPayLogService.insertByBo(maintain.getId(), payResult);
PayResponse payResponse = payResult.getPayResponse();
/* 判断是否支付成功 */
if (!payResponse.getErrCode().equals("00")) {
throw new ServiceException("结算单支付失败:"+ payResponse.getErrInfo());
}
maintain.setCollectionAccount(merchantCode);
maintain.setCollectionSerialNumber(payResponse.getOrderId());
maintain.setCollectionTime(new Date());
maintain.setState(SettlementState.TWO.getCode());
maintain.setPaymentMethod(1);
maintain.setPaymentAccount(bo.getPaymentAccount());
maintain.setPaymentNumber(orderNo);
baseMapper.updateById(maintain);
return true;
}
} }
package com.maintain.business.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.maintain.business.domain.SysPayLog;
import com.maintain.business.domain.bo.SysPayLogBo;
import com.maintain.business.domain.vo.SysPayLogVo;
import com.maintain.business.mapper.SysPayLogMapper;
import com.maintain.business.service.ISysPayLogService;
import com.maintain.common.core.domain.PageQuery;
import com.maintain.common.core.page.TableDataInfo;
import com.maintain.common.helper.LoginHelper;
import com.maintain.common.pay.PayResult;
import com.maintain.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 银联支付日志记录Service业务层处理
*
* @author liushuai
* @date 2025-11-10
*/
@RequiredArgsConstructor
@Service
public class SysPayLogServiceImpl implements ISysPayLogService {
private final SysPayLogMapper baseMapper;
/**
* 查询银联支付日志记录
*/
@Override
public SysPayLogVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 查询银联支付日志记录列表
*/
@Override
public TableDataInfo<SysPayLogVo> queryPageList(SysPayLogBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SysPayLog> lqw = buildQueryWrapper(bo);
Page<SysPayLogVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询银联支付日志记录列表
*/
@Override
public List<SysPayLogVo> queryList(SysPayLogBo bo) {
LambdaQueryWrapper<SysPayLog> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<SysPayLog> buildQueryWrapper(SysPayLogBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SysPayLog> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getSettlementMaintainId() != null, SysPayLog::getSettlementMaintainId, bo.getSettlementMaintainId());
lqw.eq(StringUtils.isNotBlank(bo.getAuthorization()), SysPayLog::getAuthorization, bo.getAuthorization());
lqw.eq(StringUtils.isNotBlank(bo.getOperParam()), SysPayLog::getOperParam, bo.getOperParam());
lqw.eq(StringUtils.isNotBlank(bo.getJsonResult()), SysPayLog::getJsonResult, bo.getJsonResult());
lqw.eq(bo.getStatus() != null, SysPayLog::getStatus, bo.getStatus());
lqw.eq(bo.getOperTime() != null, SysPayLog::getOperTime, bo.getOperTime());
return lqw;
}
/**
* 新增银联支付日志记录
*/
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class, timeout = 30)
public PayResult insertByBo(Long id, PayResult payResult) {
// 保存支付日志
SysPayLog sysPayLog = new SysPayLog();
sysPayLog.setSettlementMaintainId(id);
sysPayLog.setAuthorization(payResult.getAuthorization());
sysPayLog.setOperParam(payResult.getRequestParams());
sysPayLog.setJsonResult(payResult.getResponse());
sysPayLog.setStatus(payResult.getPayResponse().getErrCode());
sysPayLog.setOperTime(new Date());
sysPayLog.setOperUser(LoginHelper.getUserId());
baseMapper.insert(sysPayLog);
return payResult;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(SysPayLog entity){
//TODO 做一些数据校验,如唯一约束
}
}
...@@ -83,58 +83,39 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ...@@ -83,58 +83,39 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
) t ) t
</sql> </sql>
<sql id="list"> <sql id="list">
SELECT t.* FROM (SELECT SELECT
r.id as recordId, t.*
r.info_id, FROM
r.material_id, (
r.warehouse_id, SELECT
r.vendor_id, r.id AS recordId,
r.price, r.info_id,
r.type, r.material_id,
r.create_time, r.warehouse_id,
IFNULL(put.put_number, 0) - IFNULL(ret.ret_number, 0) - IFNULL(pic.out_number, 0) + IFNULL(back.back_number, 0) AS inventory, r.vendor_id,
m.material_code, r.price,
m.material_name, r.type,
m.material_specifications, r.create_time,
m.material_unit, IFNULL( put.putaway_number, 0 ) - IFNULL( put.issued_number, 0 ) - IFNULL( put.returned_number, 0 ) AS inventory,m.material_code,
m.material_brand, m.material_name,
m.procurement_subject, m.material_specifications,
m.compatible_with, m.material_unit,
m.material_warranty_period, m.material_brand,
m.reference_price, m.procurement_subject,
m.selling_price, m.compatible_with,
m.material_url, m.material_warranty_period,
v.vendor_name, m.reference_price,
w.name as warehouseName m.selling_price,
FROM erp_material_inventory_record r m.material_url,
LEFT JOIN erp_material m ON r.material_id = m.id v.vendor_name,
LEFT JOIN erp_warehouse w ON r.warehouse_id = w.id w.NAME AS warehouseName
LEFT JOIN erp_material_vendor v ON r.vendor_id = v.id FROM
LEFT JOIN ( erp_material_inventory_record r
SELECT material_id, warehouse_id, vendor_id, SUM(number) AS put_number LEFT JOIN erp_material m ON r.material_id = m.id
FROM erp_material_inventory_record LEFT JOIN erp_warehouse w ON r.warehouse_id = w.id
WHERE type = '1' LEFT JOIN erp_material_vendor v ON r.vendor_id = v.id
GROUP BY material_id, warehouse_id, vendor_id LEFT JOIN erp_material_putaway_info put ON r.info_id = put.id
) put ON r.material_id = put.material_id AND r.warehouse_id = put.warehouse_id AND r.vendor_id = put.vendor_id ) t
LEFT JOIN (
SELECT material_id, warehouse_id, vendor_id, SUM(number) AS ret_number
FROM erp_material_inventory_record
WHERE type = '2'
GROUP BY material_id, warehouse_id, vendor_id
) ret ON r.material_id = ret.material_id AND r.warehouse_id = ret.warehouse_id AND r.vendor_id = ret.vendor_id
LEFT JOIN (
SELECT material_id, warehouse_id, vendor_id, SUM(number) AS out_number
FROM erp_material_inventory_record
WHERE type = '3'
GROUP BY material_id, warehouse_id, vendor_id
) pic ON r.material_id = pic.material_id AND r.warehouse_id = pic.warehouse_id AND r.vendor_id = pic.vendor_id
LEFT JOIN (
SELECT material_id, warehouse_id, vendor_id, SUM(number) AS back_number
FROM erp_material_inventory_record
WHERE type = '4'
GROUP BY material_id, warehouse_id, vendor_id
) back ON r.material_id = back.material_id AND r.warehouse_id = back.warehouse_id AND r.vendor_id = back.vendor_id
) t
</sql> </sql>
<select id="customQueryPageInventoryList" resultType="com.maintain.business.domain.vo.ErpMaterialInventoryRecordVo"> <select id="customQueryPageInventoryList" resultType="com.maintain.business.domain.vo.ErpMaterialInventoryRecordVo">
<include refid="list"/> <include refid="list"/>
......
...@@ -49,5 +49,70 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ...@@ -49,5 +49,70 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
${ew.getCustomSqlSegment} ${ew.getCustomSqlSegment}
</select> </select>
<select id="getExportList" resultType="com.maintain.business.domain.vo.ErpMaterialPickingExportVo">
SELECT
ec.branch_office AS branchOffice,
empi.warehouse_name AS warehouseName,
su.nick_name AS receiveUserName,
emp.receive_time AS receiveTime,
empi.material_code AS materialCode,
empi.material_name AS materialName,
empi.material_specifications AS materialSpecifications,
empi.material_unit AS materialUnit,
empi.putaway_price AS putawayPrice,
empi.collect_number AS collectNumber,
empi.`money` AS money,
erf.repairer_dept_name as workshopName,
empi.vendor_name as vendorName,
empp.arrival_number as arrivalNumber
FROM
erp_material_picking_info empi
LEFT JOIN erp_material_picking emp ON empi.picking_id = emp.id
LEFT JOIN erp_car ec ON ec.id = emp.car_id
left join erp_repair_form erf ON erf.id = empi.repair_form_id
left join sys_user su on su.user_name = emp.receive_user_name
left join erp_material_inventory_record emir ON empi.record_id = emir.id
left join erp_material_putaway_info empii ON empii.id = emir.info_id
left join erp_material_putaway empp ON empii.putaway_id = empp.id
<where>
<if test="repairNumber != null">
and emp.repair_number like CONCAT('%',#{repairNumber},'%')
</if>
<if test="outNumber != null">
and emp.out_number like CONCAT('%',#{outNumber},'%')
</if>
<if test="plateNumber != null">
and emp.plate_number like CONCAT('%',#{plateNumber},'%')
</if>
<if test="settlementState != null">
and emp.settlement_state = #{settlementState}
</if>
<if test="type != null">
and emp.type = #{type}
</if>
<if test="plateNumber != null">
and emp.plate_number like CONCAT('%',#{plateNumber},'%')
</if>
<if test="ids != null and ids.size()>0">
AND emp.id in
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
#{id}
</foreach>
</if>
<if test="stateList != null and stateList.size()>0">
AND emp.state in
<foreach item="state" collection="stateList" separator="," open="(" close=")" index="">
#{state}
</foreach>
</if>
<if test="deptIds != null and deptIds.size()>0">
AND emp.create_dept_id in
<foreach item="deptId" collection="deptIds" separator="," open="(" close=")" index="">
#{deptId}
</foreach>
</if>
</where>
GROUP BY empi.id
ORDER BY emp.receive_time DESC
</select>
</mapper> </mapper>
...@@ -170,8 +170,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ...@@ -170,8 +170,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
GROUP BY repair_form_id GROUP BY repair_form_id
) erfpd ON erf.id = erfpd.repair_form_id ) erfpd ON erf.id = erfpd.repair_form_id
LEFT JOIN ( LEFT JOIN (
SELECT repair_form_id, SUM(selling_price * collect_number) AS totalMaterialMoney SELECT repair_form_id, SUM(money) AS totalMaterialMoney
FROM erp_material_picking_info FROM erp_material_picking_info
WHERE state != 3
GROUP BY repair_form_id GROUP BY repair_form_id
) empi ON erf.id = empi.repair_form_id ) empi ON erf.id = empi.repair_form_id
</sql> </sql>
......
...@@ -85,5 +85,9 @@ public class SysDept extends TreeEntity<SysDept> { ...@@ -85,5 +85,9 @@ public class SysDept extends TreeEntity<SysDept> {
* 类型(1总公司 2分公司 3车队 4车间 5总公司管理部门 6分公司管理部门 7维修点) * 类型(1总公司 2分公司 3车队 4车间 5总公司管理部门 6分公司管理部门 7维修点)
*/ */
private String type; private String type;
/**
* 终端号
*/
private String terminalCode;
} }
...@@ -10,8 +10,8 @@ import lombok.Getter; ...@@ -10,8 +10,8 @@ import lombok.Getter;
@Getter @Getter
public enum SettlementState { public enum SettlementState {
ONE(1, "待确认"), ONE(1, "待支付"),
TWO(2, "已确认"); TWO(2, "已支付");
private final Integer code; private final Integer code;
private final String info; private final String info;
......
package com.maintain.common.pay;
/**
* PayResponse
*
* @author Liu Shuai
* @date 2025/10/28 14:30
*/
public class PayResponse {
/**
* errCode : 00
* errInfo : 10000成功响应码
* transactionTime : 140747
* transactionDate : 1028
* settlementDate : 1028
* transactionDateWithYear : 20251028
* settlementDateWithYear : 20251028
* retrievalRefNum : 01479200019N
* transactionAmount : 1
* actualTransactionAmount : 1
* amount : 1
* orderId : 20251028140747440012928716
* thirdPartyDiscountInstrution : 微信钱包支付0.01元
* thirdPartyDiscountInstruction : 微信钱包支付0.01元
* thirdPartyName : 微信钱包
* userId : oUpF8uMv_IaPg4f03FtZSQ7TiAiM
* thirdPartyBuyerId : oUpF8uMv_IaPg4f03FtZSQ7TiAiM
* thirdPartyOrderId : 4200002861202510289915715464
* thirdPartyPayInformation : 现金:1
* cardAttr : 91
* mchntName : 测试商户
* chnlType : WXPay
* promotionAmt : 0
* systemTraceNum : 002841
*/
private String errCode;
private String errInfo;
private String transactionTime;
private String transactionDate;
private String settlementDate;
private String transactionDateWithYear;
private String settlementDateWithYear;
private String retrievalRefNum;
private int transactionAmount;
private int actualTransactionAmount;
private int amount;
private String orderId;
private String thirdPartyDiscountInstrution;
private String thirdPartyDiscountInstruction;
private String thirdPartyName;
private String userId;
private String thirdPartyBuyerId;
private String thirdPartyOrderId;
private String thirdPartyPayInformation;
private String cardAttr;
private String mchntName;
private String chnlType;
private String promotionAmt;
private String systemTraceNum;
public String getErrCode() {
return errCode;
}
public void setErrCode(String errCode) {
this.errCode = errCode;
}
public String getErrInfo() {
return errInfo;
}
public void setErrInfo(String errInfo) {
this.errInfo = errInfo;
}
public String getTransactionTime() {
return transactionTime;
}
public void setTransactionTime(String transactionTime) {
this.transactionTime = transactionTime;
}
public String getTransactionDate() {
return transactionDate;
}
public void setTransactionDate(String transactionDate) {
this.transactionDate = transactionDate;
}
public String getSettlementDate() {
return settlementDate;
}
public void setSettlementDate(String settlementDate) {
this.settlementDate = settlementDate;
}
public String getTransactionDateWithYear() {
return transactionDateWithYear;
}
public void setTransactionDateWithYear(String transactionDateWithYear) {
this.transactionDateWithYear = transactionDateWithYear;
}
public String getSettlementDateWithYear() {
return settlementDateWithYear;
}
public void setSettlementDateWithYear(String settlementDateWithYear) {
this.settlementDateWithYear = settlementDateWithYear;
}
public String getRetrievalRefNum() {
return retrievalRefNum;
}
public void setRetrievalRefNum(String retrievalRefNum) {
this.retrievalRefNum = retrievalRefNum;
}
public int getTransactionAmount() {
return transactionAmount;
}
public void setTransactionAmount(int transactionAmount) {
this.transactionAmount = transactionAmount;
}
public int getActualTransactionAmount() {
return actualTransactionAmount;
}
public void setActualTransactionAmount(int actualTransactionAmount) {
this.actualTransactionAmount = actualTransactionAmount;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getThirdPartyDiscountInstrution() {
return thirdPartyDiscountInstrution;
}
public void setThirdPartyDiscountInstrution(String thirdPartyDiscountInstrution) {
this.thirdPartyDiscountInstrution = thirdPartyDiscountInstrution;
}
public String getThirdPartyDiscountInstruction() {
return thirdPartyDiscountInstruction;
}
public void setThirdPartyDiscountInstruction(String thirdPartyDiscountInstruction) {
this.thirdPartyDiscountInstruction = thirdPartyDiscountInstruction;
}
public String getThirdPartyName() {
return thirdPartyName;
}
public void setThirdPartyName(String thirdPartyName) {
this.thirdPartyName = thirdPartyName;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getThirdPartyBuyerId() {
return thirdPartyBuyerId;
}
public void setThirdPartyBuyerId(String thirdPartyBuyerId) {
this.thirdPartyBuyerId = thirdPartyBuyerId;
}
public String getThirdPartyOrderId() {
return thirdPartyOrderId;
}
public void setThirdPartyOrderId(String thirdPartyOrderId) {
this.thirdPartyOrderId = thirdPartyOrderId;
}
public String getThirdPartyPayInformation() {
return thirdPartyPayInformation;
}
public void setThirdPartyPayInformation(String thirdPartyPayInformation) {
this.thirdPartyPayInformation = thirdPartyPayInformation;
}
public String getCardAttr() {
return cardAttr;
}
public void setCardAttr(String cardAttr) {
this.cardAttr = cardAttr;
}
public String getMchntName() {
return mchntName;
}
public void setMchntName(String mchntName) {
this.mchntName = mchntName;
}
public String getChnlType() {
return chnlType;
}
public void setChnlType(String chnlType) {
this.chnlType = chnlType;
}
public String getPromotionAmt() {
return promotionAmt;
}
public void setPromotionAmt(String promotionAmt) {
this.promotionAmt = promotionAmt;
}
public String getSystemTraceNum() {
return systemTraceNum;
}
public void setSystemTraceNum(String systemTraceNum) {
this.systemTraceNum = systemTraceNum;
}
}
package com.maintain.common.pay;
import lombok.Data;
/**
* PayResult
*
* @author Liu Shuai
* @date 2025/11/10 14:44
*/
@Data
public class PayResult {
// 请求参数
private String requestParams;
// 认证报文
private String authorization;
// 响应结果
private String response;
// 解析后的响应对象
private PayResponse payResponse;
}
package com.maintain.common.utils.poi;
import org.apache.commons.lang3.StringUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
/**
* 注解工具类
*/
public class AnnotationUtils {
/**
* 变更注解的属性值再处理业务,处理完业务之后恢复类的属性
*
* @param clazz 注解所在的实体类
* @param tClass 注解类
* @param attrName 要修改的注解属性名
* @param attrTypeEnum 要修改的注解属性的类型
* @param valueMap 要设置的属性值
*/
public static <A extends Annotation> void changeAnnotationValueToDealProcess(
Class<?> clazz,
Class<A> tClass,
String attrName,
AttrTypeEnum attrTypeEnum,
Map<String, String> valueMap,
DealProcess dealProcess) {
try {
Map<String, Object> fieldAnnotationValueMap = new HashMap<>();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
A annotation = field.getAnnotation(tClass);
if (annotation == null) continue;
Object value = setAnnotationValue(annotation, attrName, attrTypeEnum, valueMap);
String fieldName = field.getName();
fieldAnnotationValueMap.put(fieldName, value);
}
// 处理业务逻辑
dealProcess.deal();
// 恢复
for (Field field : fields) {
A annotation = field.getAnnotation(tClass);
String fieldName = field.getName();
if (annotation == null) continue;
Object value = fieldAnnotationValueMap.get(fieldName);
InvocationHandler handler = Proxy.getInvocationHandler(annotation);
Field memberValuesField = handler.getClass().getDeclaredField("memberValues");
memberValuesField.setAccessible(true);
@SuppressWarnings("all")
Map<String, Object> memberValues = (Map) memberValuesField.get(handler);
memberValues.put(attrName, value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置注解中的字段值
*
* @param annotation 要修改的注解实例
* @param attrName 要修改的注解属性名
* @param attrTypeEnum 要修改的注解属性的类型
* @param valueMap 替换属性集的map
*/
@SuppressWarnings("all")
private static Object setAnnotationValue(Annotation annotation, String attrName,
AttrTypeEnum attrTypeEnum, Map<String, String> valueMap) throws NoSuchFieldException, IllegalAccessException {
InvocationHandler handler = Proxy.getInvocationHandler(annotation);
Field field = handler.getClass().getDeclaredField("memberValues");
field.setAccessible(true);
Map memberValues = (Map) field.get(handler);
Object value = memberValues.get(attrName);
switch (attrTypeEnum) {
case STRING: {
String oldValue = (String) value;
String newValue = valueMap.get(oldValue);
if (StringUtils.isNotBlank(newValue)) {
memberValues.put(attrName, newValue);
}
}
break;
case STRING_ARR: {
String[] oldValue = (String[]) value;
String[] newValue = new String[oldValue.length];
for (int i = 0; i < oldValue.length; i++) {
String replace = valueMap.get(oldValue[i]);
newValue[i] = replace != null ? replace : oldValue[i];
}
memberValues.put(attrName, newValue);
}
break;
}
return value;
}
public enum AttrTypeEnum {
STRING,
STRING_ARR
}
public interface DealProcess {
void deal() throws Exception;
}
}
package com.maintain.common.utils.poi;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import java.util.List;
import java.util.stream.Collectors;
/**
* 自定义合并单元格处理器
* 每次合并需要sheet页名称、指定开始行号、开始列号、结束行号、结束列号
* 支持批量合并单元格
*
* @author weibaoting
*/
public class CustomMergeCellHandler implements SheetWriteHandler {
/**
* 合并单元格信息
*/
private List<MergeCellModel> mergeCellList;
/**
* sheet页名称列表
*/
private List<String> sheetNameList;
public CustomMergeCellHandler(List<MergeCellModel> mergeCellList) {
if (CollUtil.isEmpty(mergeCellList)) {
return;
}
this.mergeCellList = mergeCellList.stream().filter(x ->
StrUtil.isNotBlank(x.getSheetName()) && x.getStartRowIndex() >= 0 && x.getEndRowIndex() >= 0
&& x.getStartColumnIndex() >= 0 && x.getEndColumnIndex() >= 0).collect(Collectors.toList());
List<String> sheetNameList = this.mergeCellList.stream().map(x -> x.getSheetName()).distinct().collect(Collectors.toList());
if (CollUtil.isEmpty(sheetNameList)) {
return;
}
this.sheetNameList = sheetNameList;
}
@Override
public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
}
/**
* sheet页创建之后调用
*
* @param writeWorkbookHolder
* @param writeSheetHolder
*/
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
Sheet sheet = writeSheetHolder.getSheet();
//不需要合并单元格信息,或者当前sheet页不需要合并单元格信息
if (CollUtil.isEmpty(mergeCellList) || sheetNameList.contains(sheet.getSheetName()) == false) {
return;
}
List<MergeCellModel> sheetMergeCellList = mergeCellList.stream().filter(x ->
StrUtil.equals(x.getSheetName(), sheet.getSheetName())).collect(Collectors.toList());
for (MergeCellModel mergeCellModel : sheetMergeCellList) {
//开始行号
int startRowIndex = mergeCellModel.getStartRowIndex();
//结束行号
int endRowIndex = mergeCellModel.getEndRowIndex();
//开始列号
int startColumnIndex = mergeCellModel.getStartColumnIndex();
//结束列号
int endColumnIndex = mergeCellModel.getEndColumnIndex();
//行号和列号非法(<0)
if (startColumnIndex < 0 || endColumnIndex < 0 || startRowIndex < 0 || endRowIndex < 0) {
continue;
}
//合并单元格区域只有一个单元格时,不合并
if (endRowIndex == startRowIndex && endColumnIndex == startColumnIndex) {
continue;
}
//开始行号大于结束行号,或者开始列号大于结束列号
if (startColumnIndex > endColumnIndex || startRowIndex > endRowIndex) {
continue;
}
//添加合并单元格区域
CellRangeAddress cellRangeAddress = new CellRangeAddress(startRowIndex, endRowIndex, startColumnIndex, endColumnIndex);
sheet.addMergedRegionUnsafe(cellRangeAddress);
}
//删除合并单元格信息
mergeCellList.removeAll(sheetMergeCellList);
sheetNameList = mergeCellList.stream().map(x -> x.getSheetName()).distinct().collect(Collectors.toList());
}
}
...@@ -5,10 +5,15 @@ import cn.hutool.core.io.resource.ClassPathResource; ...@@ -5,10 +5,15 @@ import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder; import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig; import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper; import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.maintain.common.convert.ExcelBigNumberConvert; import com.maintain.common.convert.ExcelBigNumberConvert;
import com.maintain.common.excel.*; import com.maintain.common.excel.*;
...@@ -16,6 +21,9 @@ import com.maintain.common.utils.StringUtils; ...@@ -16,6 +21,9 @@ import com.maintain.common.utils.StringUtils;
import com.maintain.common.utils.file.FileUtils; import com.maintain.common.utils.file.FileUtils;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.springframework.http.HttpHeaders;
import javax.servlet.ServletOutputStream; import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
...@@ -23,6 +31,9 @@ import java.io.IOException; ...@@ -23,6 +31,9 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -32,6 +43,7 @@ import java.util.Map; ...@@ -32,6 +43,7 @@ import java.util.Map;
* *
* @author Lion Li * @author Lion Li
*/ */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ExcelUtil { public class ExcelUtil {
...@@ -377,4 +389,54 @@ public class ExcelUtil { ...@@ -377,4 +389,54 @@ public class ExcelUtil {
return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx"; return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx";
} }
/**
* 载Excel格式的数据-带自定义标题
*
* @param response
* @param fileName
* @param sheetPOList
* @param <T>
*/
public static <T> void exportSheetSetTitle(HttpServletResponse response, String fileName, List<SheetPO> sheetPOList) {
//导出
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
try {
// 这里URLEncoder.encode可以防止中文乱码
String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");
//新建ExcelWriter
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
for (SheetPO sheetPO : sheetPOList) {
AnnotationUtils.changeAnnotationValueToDealProcess(
sheetPO.getClazz(), ExcelProperty.class, "value", AnnotationUtils.AttrTypeEnum.STRING_ARR, sheetPO.getTitleMap(), new AnnotationUtils.DealProcess() {
@Override
public void deal() {
ExcelWriterSheetBuilder sheetBuilder = EasyExcel.writerSheet(sheetPO.getSheetNo(), sheetPO.getSheetName())
.head(sheetPO.getClazz())
.registerWriteHandler(new CustomMergeCellHandler(sheetPO.getMergeCellList()));
if (Boolean.TRUE.equals(sheetPO.getWhiteFirstHeadRow())) {
sheetBuilder.registerWriteHandler(new HeadTitleRowWhiteStyleHandler());
}
if (sheetPO.getCenterMergedAnchorExcelRowIndex() != null) {
sheetBuilder.registerWriteHandler(
new MergedAnchorCellCenterStyleHandler(sheetPO.getCenterMergedAnchorExcelRowIndex(), 0));
}
WriteSheet mainSheet = sheetBuilder.build();
excelWriter.write(sheetPO.getData(), mainSheet);
}
}
);
}
excelWriter.finish();
log.info("数据导出完成");
} catch (Exception e) {
// 重置response
log.error("文件下载失败" + e.getMessage());
throw new RuntimeException("下载文件失败", e);
}
}
} }
package com.maintain.common.utils.poi;
import com.alibaba.excel.constant.OrderConstant;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Workbook;
/**
* 多行表头时,仅将第一行(大标题行,relativeRowIndex=0)设为白底,其余表头行保持实体类上的 {@code @HeadStyle}。
*/
public class HeadTitleRowWhiteStyleHandler implements CellWriteHandler {
private CellStyle whiteTitleRowStyle;
/**
* 在注解 {@code @HeadStyle} 等样式写入之后再执行(EasyExcel:order 越小越早)。
*/
@Override
public int order() {
return OrderConstant.FILL_STYLE + 10000;
}
@Override
public void afterCellDispose(CellWriteHandlerContext context) {
if (!Boolean.TRUE.equals(context.getHead())) {
return;
}
Integer relativeRowIndex = context.getRelativeRowIndex();
if (relativeRowIndex == null || relativeRowIndex != 0) {
return;
}
Cell cell = context.getCell();
if (cell == null) {
return;
}
Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();
if (whiteTitleRowStyle == null) {
whiteTitleRowStyle = workbook.createCellStyle();
whiteTitleRowStyle.cloneStyleFrom(cell.getCellStyle());
whiteTitleRowStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
whiteTitleRowStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
}
cell.setCellStyle(whiteTitleRowStyle);
}
}
package com.maintain.common.utils.poi;
import lombok.Getter;
/**
* @Author weibaoting
* @Date 2023/2/2 0002 15:53
* @Description
*/
@Getter
public class MergeCellModel {
/**
* sheet名称
*/
private String sheetName;
/**
* 开始行号
*/
private int startRowIndex;
/**
* 开始列号
*/
private int startColumnIndex;
/**
* 结束行号
*/
private int endRowIndex;
/**
* 结束列号
*/
private int endColumnIndex;
private void setSheetName(String sheetName) {
this.sheetName = sheetName;
}
private void setStartRowIndex(int startRowIndex) {
this.startRowIndex = startRowIndex;
}
private void setStartColumnIndex(int startColumnIndex) {
this.startColumnIndex = startColumnIndex;
}
private void setEndRowIndex(int endRowIndex) {
this.endRowIndex = endRowIndex;
}
private void setEndColumnIndex(int endColumnIndex) {
this.endColumnIndex = endColumnIndex;
}
public MergeCellModel() {
}
/**
* 生成合并列单元格信息
*
* @param sheetName sheet页名称
* @param rowIndex 行号
* @param startColumnIndex 开始列号
* @param endColumnIndex 结束列号
* @return
*/
public static MergeCellModel createMergeColumnCellModel(String sheetName, int rowIndex, int startColumnIndex
, int endColumnIndex) {
return createMergeCellModel(sheetName, rowIndex, rowIndex, startColumnIndex, endColumnIndex);
}
/**
* 生成合并单元格信息
*
* @param sheetName sheet页名称
* @param startRowIndex 开始行号
* @param endRowIndex 结束行号
* @param columnIndex 列号
* @return
*/
public static MergeCellModel createMergeRowCellModel(String sheetName, int startRowIndex, int endRowIndex, int columnIndex) {
return createMergeCellModel(sheetName, startRowIndex, endRowIndex, columnIndex, columnIndex);
}
/**
* 生成合并单元格信息
*
* @param sheetName sheet页名称
* @param startRowIndex 开始行号
* @param endRowIndex 结束行号
* @param startColumnIndex 开始列号
* @param endColumnIndex 结束列号
* @return
*/
public static MergeCellModel createMergeCellModel(String sheetName, int startRowIndex, int endRowIndex, int startColumnIndex
, int endColumnIndex) {
MergeCellModel mergeCellModel = new MergeCellModel();
//sheet页名称
mergeCellModel.setSheetName(sheetName);
//开始行号
mergeCellModel.setStartRowIndex(startRowIndex);
//结束行号
mergeCellModel.setEndRowIndex(endRowIndex);
//开始列号
mergeCellModel.setStartColumnIndex(startColumnIndex);
//结束列号
mergeCellModel.setEndColumnIndex(endColumnIndex);
return mergeCellModel;
}
}
package com.maintain.common.utils.poi;
import com.alibaba.excel.constant.OrderConstant;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
/**
* 将指定数据行、指定列(一般为合并区域左上角)的单元格设为水平、垂直居中,用于合并后「合计」等文案居中显示。
*/
public class MergedAnchorCellCenterStyleHandler implements CellWriteHandler {
private final int excelRowIndex;
private final int columnIndex;
public MergedAnchorCellCenterStyleHandler(int excelRowIndex, int columnIndex) {
this.excelRowIndex = excelRowIndex;
this.columnIndex = columnIndex;
}
@Override
public int order() {
return OrderConstant.FILL_STYLE + 15000;
}
@Override
public void afterCellDispose(CellWriteHandlerContext context) {
if (Boolean.TRUE.equals(context.getHead())) {
return;
}
Cell cell = context.getCell();
if (cell == null) {
return;
}
if (cell.getRowIndex() != excelRowIndex || cell.getColumnIndex() != columnIndex) {
return;
}
Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();
CellStyle style = workbook.createCellStyle();
style.cloneStyleFrom(cell.getCellStyle());
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
cell.setCellStyle(style);
}
}
package com.maintain.common.utils.poi;
import lombok.Data;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author weibaoting
* @Date 2023/2/2 0002 17:00
* @Description
*/
@Data
public class SheetPO<T> {
/**
* sheetNo
*/
private Integer sheetNo;
/**
* sheet名称
*/
private String sheetName;
/**
* 标题替换
*/
private Map<String, String> titleMap = new HashMap<>();
/**
* 数据
*/
private List<T> data;
/**
* 表头
*/
private Class<T> clazz;
/**
* 需要合并的数据
*/
private List<MergeCellModel> mergeCellList;
/**
* 多行表头时是否将第一行(大标题行)设为白底;第二行仍用实体类上的表头样式。默认 false。
*/
private Boolean whiteFirstHeadRow;
/**
* 若设置:对该 Excel 行号(0-based)、第 0 列锚点单元格水平垂直居中(用于合并单元格内文字居中,如合计行)。
*/
private Integer centerMergedAnchorExcelRowIndex;
}
...@@ -44,6 +44,16 @@ export function updateRepairFormProjectDispatch(data) { ...@@ -44,6 +44,16 @@ export function updateRepairFormProjectDispatch(data) {
}) })
} }
// 批量修改报修单-报修项目-派工
export function updateRepairFormProjectDispatchBatch(data) {
return request({
url: '/business/repairFormProjectDispatch/batch',
method: 'put',
data: data
})
}
// 删除报修单-报修项目-派工 // 删除报修单-报修项目-派工
export function delRepairFormProjectDispatch(id) { export function delRepairFormProjectDispatch(id) {
return request({ return request({
......
...@@ -51,3 +51,13 @@ export function receiptSettlementMaintain(data) { ...@@ -51,3 +51,13 @@ export function receiptSettlementMaintain(data) {
data: data data: data
}) })
} }
// 结算维修单回执
export function paySettlementMaintain(data) {
return request({
url: '/business/settlementMaintain/pay',
method: 'put',
data: data,
timeout: 30000
})
}
...@@ -213,6 +213,24 @@ ...@@ -213,6 +213,24 @@
<el-form-item label="车型ID" prop="carTypeId"> <el-form-item label="车型ID" prop="carTypeId">
<el-input v-model="form.carTypeId" placeholder="请输入车型ID" /> <el-input v-model="form.carTypeId" placeholder="请输入车型ID" />
</el-form-item> --> </el-form-item> -->
<div class="app-title">车队信息</div>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="分公司" prop="branchOffice">
<el-input v-model="form.branchOffice" placeholder="请输入分公司" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="车队" prop="motorcade">
<el-input v-model="form.motorcade" placeholder="请输入车队" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="线路" prop="line">
<el-input v-model="form.line" placeholder="请输入线路" />
</el-form-item>
</el-col>
</el-row>
<div class="app-title">关联车型信息</div> <div class="app-title">关联车型信息</div>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
...@@ -507,7 +525,7 @@ export default { ...@@ -507,7 +525,7 @@ export default {
handleUpdate(row) { handleUpdate(row) {
getCar(row.id).then(res =>{ getCar(row.id).then(res =>{
this.form = res.data this.form = res.data
this.form.clientType = row.clientType this.form.clientType = row.clientType+''
this.open = true; this.open = true;
this.title = "修改车辆信息"; this.title = "修改车辆信息";
this.getCode() this.getCode()
......
...@@ -38,6 +38,17 @@ ...@@ -38,6 +38,17 @@
v-hasPermi="['business:maintainProject:add']" v-hasPermi="['business:maintainProject:add']"
>新增</el-button> >新增</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['business:maintainProject:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
type="warning" type="warning"
...@@ -62,7 +73,7 @@ ...@@ -62,7 +73,7 @@
</el-row> </el-row>
<el-table v-loading="loading" :data="maintainProjectList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="maintainProjectList" @selection-change="handleSelectionChange">
<!-- <el-table-column type="selection" width="55" align="center" />--> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" align="center" type="index" /> <el-table-column label="序号" align="center" type="index" />
<el-table-column label="维修项目类别" align="center" prop="typeName" /> <el-table-column label="维修项目类别" align="center" prop="typeName" />
<el-table-column label="维修项目编号" align="center" prop="projectCode" /> <el-table-column label="维修项目编号" align="center" prop="projectCode" />
...@@ -471,7 +482,7 @@ export default { ...@@ -471,7 +482,7 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const ids = row.id || this.ids; const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除维修项目编号为"' + row.projectCode + '"的数据项?').then(() => { this.$modal.confirm('是否确认删除维修项目,删除后无法恢复!').then(() => {
this.loading = true; this.loading = true;
return delMaintainProject(ids); return delMaintainProject(ids);
}).then(() => { }).then(() => {
......
...@@ -34,6 +34,17 @@ ...@@ -34,6 +34,17 @@
v-hasPermi="['business:malfunctionProject:add']" v-hasPermi="['business:malfunctionProject:add']"
>新增</el-button> >新增</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['business:malfunctionProject:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
type="warning" type="warning"
...@@ -76,7 +87,7 @@ ...@@ -76,7 +87,7 @@
</el-row> </el-row>
<el-table v-loading="loading" :data="malfunctionProjectList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="malfunctionProjectList" @selection-change="handleSelectionChange">
<!-- <el-table-column type="selection" width="55" align="center" />--> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" align="center" type="index"/> <el-table-column label="序号" align="center" type="index"/>
<el-table-column label="故障类型名称" align="center" prop="typeName" /> <el-table-column label="故障类型名称" align="center" prop="typeName" />
<el-table-column label="故障项目编号" align="center" prop="malfunctionCode" /> <el-table-column label="故障项目编号" align="center" prop="malfunctionCode" />
...@@ -431,7 +442,7 @@ export default { ...@@ -431,7 +442,7 @@ export default {
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const ids = row.id || this.ids; const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除故障项目编号为"' + row.malfunctionCode + '"的数据项?').then(() => { this.$modal.confirm('是否确认删除维修项目,删除后无法恢复!').then(() => {
this.loading = true; this.loading = true;
return delMalfunctionProject(ids); return delMalfunctionProject(ids);
}).then(() => { }).then(() => {
......
...@@ -138,27 +138,28 @@ ...@@ -138,27 +138,28 @@
<el-table-column label="物资编码" align="center" fixed="left" prop="materialCode" /> <el-table-column label="物资编码" align="center" fixed="left" prop="materialCode" />
<el-table-column label="物资名称" align="center" fixed="left" prop="materialName" /> <el-table-column label="物资名称" align="center" fixed="left" prop="materialName" />
<el-table-column label="物资规格" align="center" fixed="left" prop="materialSpecifications" /> <el-table-column label="物资规格" align="center" fixed="left" prop="materialSpecifications" />
<el-table-column label="供应商" align="center" fixed="left" prop="vendorName" show-overflow-tooltip />
<el-table-column label="物资品牌" align="center" fixed="left" prop="materialBrand" /> <el-table-column label="物资品牌" align="center" fixed="left" prop="materialBrand" />
<el-table-column label="物资单位" align="center" fixed="left" prop="materialUnit"> <el-table-column label="生产厂家" align="center" fixed="left" prop="manufacturer" />
<el-table-column label="采购标的" align="center" prop="procurementSubject" />
<el-table-column label="物资单位" align="center" prop="materialUnit" width="50">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.material_unit" :value="scope.row.materialUnit" /> <dict-tag :options="dict.type.material_unit" :value="scope.row.materialUnit" />
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column label="所在仓库" align="center" prop="warehouseName" />--> <!-- <el-table-column label="所在仓库" align="center" prop="warehouseName" />-->
<!-- <el-table-column label="分类名称" align="center" prop="materialTypeName" />--> <!-- <el-table-column label="分类名称" align="center" prop="materialTypeName" />-->
<el-table-column label="供应商" align="center" prop="vendorName" show-overflow-tooltip /> <el-table-column label="适用车型" align="center" prop="compatibleWith" show-overflow-tooltip/>
<el-table-column label="采购标的" align="center" prop="procurementSubject" />
<el-table-column label="适用车型" align="center" prop="compatibleWith" />
<el-table-column label="物资图片" align="center" prop="materialUrl"> <el-table-column label="物资图片" align="center" prop="materialUrl">
<template slot-scope="scope"> <template slot-scope="scope">
<image-preview :src="scope.row.materialUrl" style="width: 50px; height: 50px" /> <image-preview :src="scope.row.materialUrl" style="width: 50px; height: 50px" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="质保期(月)" align="center" prop="materialWarrantyPeriod" /> <el-table-column label="质保期(月)" align="center" prop="materialWarrantyPeriod" width="60" />
<el-table-column label="参考价" align="center" prop="referencePrice" /> <el-table-column label="参考价" align="center" prop="referencePrice" width="80" />
<el-table-column label="销售价" align="center" prop="sellingPrice" /> <el-table-column label="销售价" align="center" prop="sellingPrice" width="80" />
<!-- <el-table-column label="库存" align="center" prop="inventory" />--> <!-- <el-table-column label="库存" align="center" prop="inventory" />-->
<el-table-column label="是否启用" align="center" prop="isEnable"> <el-table-column label="是否启用" align="center" prop="isEnable" width="50">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.sys_is_enable" :value="scope.row.isEnable"/> <dict-tag :options="dict.type.sys_is_enable" :value="scope.row.isEnable"/>
</template> </template>
...@@ -168,7 +169,7 @@ ...@@ -168,7 +169,7 @@
<!-- <dict-tag :options="dict.type.sys_is_enable" :value="String(scope.row.isCheck)"/>--> <!-- <dict-tag :options="dict.type.sys_is_enable" :value="String(scope.row.isCheck)"/>-->
<!-- </template>--> <!-- </template>-->
<!-- </el-table-column>--> <!-- </el-table-column>-->
<el-table-column label="是否通用" align="center" prop="isUniversal"> <el-table-column label="是否通用" align="center" prop="isUniversal" width="50">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.sys_is_enable" :value="scope.row.isUniversal"/> <dict-tag :options="dict.type.sys_is_enable" :value="scope.row.isUniversal"/>
</template> </template>
...@@ -202,7 +203,7 @@ ...@@ -202,7 +203,7 @@
/> />
<!-- 添加或修改物资对话框 --> <!-- 添加或修改物资对话框 -->
<el-dialog :title="title" :visible.sync="open" width="900px" append-to-body> <el-dialog :title="title" :visible.sync="open" width="60%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px"> <el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
...@@ -236,14 +237,14 @@ ...@@ -236,14 +237,14 @@
<!-- </el-col>--> <!-- </el-col>-->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="供应商" prop="vendorId"> <el-form-item label="供应商" prop="vendorId">
<el-select v-model="form.vendorId" placeHolder="请选择供应商"> <el-select v-model="form.vendorId" placeHolder="请选择供应商" style="width: 100%" >
<el-option v-for="item in materialVendorList" :key="item.id" :value="item.id" :label="item.vendorName" /> <el-option v-for="item in materialVendorList" :key="item.id" :value="item.id" :label="item.vendorName" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="物资单位" prop="materialUnit"> <el-form-item label="物资单位" prop="materialUnit">
<el-select v-model="form.materialUnit" placeHolder="请选择物资单位"> <el-select v-model="form.materialUnit" placeHolder="请选择物资单位" style="width: 100%" >
<el-option v-for="dict in dict.type.material_unit" :key="dict.value" :label="dict.label" :value="dict.value" /> <el-option v-for="dict in dict.type.material_unit" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
...@@ -281,10 +282,8 @@ ...@@ -281,10 +282,8 @@
<!-- </el-form-item>--> <!-- </el-form-item>-->
<!-- </el-col>--> <!-- </el-col>-->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="是否启用" prop="isEnable"> <el-form-item label="生产厂家" prop="manufacturer">
<el-select v-model="form.isEnable" style="width: 100%" placeholder="请选择是否启用"> <el-input v-model="form.manufacturer" placeholder="请输入生产厂家" />
<el-option v-for="dict in dict.type.sys_is_enable" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
...@@ -304,6 +303,13 @@ ...@@ -304,6 +303,13 @@
<!-- <el-input-number v-model="form.inventory" :min="0" style="width: 100%" :disabled="form.id != null" placeholder="请输入库存数量" />--> <!-- <el-input-number v-model="form.inventory" :min="0" style="width: 100%" :disabled="form.id != null" placeholder="请输入库存数量" />-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
<!-- </el-col>--> <!-- </el-col>-->
<el-col :span="8">
<el-form-item label="是否启用" prop="isEnable">
<el-select v-model="form.isEnable" style="width: 100%" placeholder="请选择是否启用">
<el-option v-for="dict in dict.type.sys_is_enable" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="是否通用" prop="isUniversal"> <el-form-item label="是否通用" prop="isUniversal">
<el-select v-model="form.isUniversal" style="width: 100%" placeholder="请选择是否通用"> <el-select v-model="form.isUniversal" style="width: 100%" placeholder="请选择是否通用">
...@@ -414,8 +420,7 @@ export default { ...@@ -414,8 +420,7 @@ export default {
materialSpecifications: undefined, materialSpecifications: undefined,
materialUnit: undefined, materialUnit: undefined,
materialWarrantyPeriod: undefined, materialWarrantyPeriod: undefined,
referencePrice: undefined, manufacturer: undefined,
sellingPrice: undefined,
inventory: undefined, inventory: undefined,
isEnable: undefined, isEnable: undefined,
isUniversal: undefined, isUniversal: undefined,
...@@ -545,6 +550,7 @@ export default { ...@@ -545,6 +550,7 @@ export default {
materialSpecifications: undefined, materialSpecifications: undefined,
materialUnit: undefined, materialUnit: undefined,
materialBrand: undefined, materialBrand: undefined,
manufacturer: undefined,
procurementSubject: undefined, procurementSubject: undefined,
compatibleWith: undefined, compatibleWith: undefined,
materialUrl: undefined, materialUrl: undefined,
......
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
<el-table-column label="库存" align="center" prop="inventory" /> <el-table-column label="库存" align="center" prop="inventory" />
<el-table-column label="领料数量" align="center" prop="collectNumber" width="120px"> <el-table-column label="领料数量" align="center" prop="collectNumber" width="120px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input-number v-model="scope.row.collectNumber" @change="collectNumberChange" controls-position="right" size="mini" :min="1" :precision="0" style="width: 100%" placeholder="数量"/> <el-input-number v-model="scope.row.collectNumber" @change="collectNumberChange" controls-position="right" size="mini" :min="0.00" :precision="2" :max="parseFloat(scope.row.inventory)" style="width: 100%" placeholder="数量"/>
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column label="销售单价" align="center" prop="price" width="120px">--> <!-- <el-table-column label="销售单价" align="center" prop="price" width="120px">-->
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
<!-- </el-table-column>--> <!-- </el-table-column>-->
<el-table-column label="领料金额" align="center" prop="money" width="120px"> <el-table-column label="领料金额" align="center" prop="money" width="120px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input-number v-model="scope.row.money" disabled controls-position="right" size="mini" :min="0" style="width: 100%" placeholder="金额"/> <el-input-number v-model="scope.row.money" disabled controls-position="right" size="mini" :precision="2" style="width: 100%" placeholder="金额"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
...@@ -260,7 +260,7 @@ export default { ...@@ -260,7 +260,7 @@ export default {
}; };
}, },
created() { created() {
this.form = {...this.$route.query} this.form = {...this.$route.query, outMoney: undefined}
this.getWarehouseList(this.form.repairerDeptId) this.getWarehouseList(this.form.repairerDeptId)
this.getVendorList() this.getVendorList()
}, },
...@@ -289,7 +289,9 @@ export default { ...@@ -289,7 +289,9 @@ export default {
}, },
/** 供应商改变 */ /** 供应商改变 */
vendorIdChange(vendorId) { vendorIdChange(vendorId) {
this.queryMaterialParams.vendorId = vendorId; if (vendorId) {
this.queryMaterialParams.vendorId = vendorId;
}
this.form.pickingInfoList = [] this.form.pickingInfoList = []
}, },
/** 打开物料列表 */ /** 打开物料列表 */
...@@ -329,7 +331,7 @@ export default { ...@@ -329,7 +331,7 @@ export default {
this.tempSelection = []; this.tempSelection = [];
// 手动设置勾选(匹配外部已选数据) // 手动设置勾选(匹配外部已选数据)
this.materialList.forEach(row => { this.materialList.forEach(row => {
const isSelected = this.form.pickingInfoList.some(item => item.warehouseId === row.warehouseId && item.materialId === row.materialId); const isSelected = this.form.pickingInfoList.some(item => item.recordId === row.recordId);
this.$refs.selectionTable.toggleRowSelection(row, isSelected); this.$refs.selectionTable.toggleRowSelection(row, isSelected);
}); });
}); });
...@@ -348,6 +350,7 @@ export default { ...@@ -348,6 +350,7 @@ export default {
item.money = item.collectNumber * item.sellingPrice item.money = item.collectNumber * item.sellingPrice
return sum + (item.collectNumber * item.sellingPrice); return sum + (item.collectNumber * item.sellingPrice);
}, 0) }, 0)
console.log('outMoney', this.form.outMoney)
}, },
// 多选框选中数据 // 多选框选中数据
handleMaterialSelectionChange(selection) { handleMaterialSelectionChange(selection) {
...@@ -377,16 +380,26 @@ export default { ...@@ -377,16 +380,26 @@ export default {
this.$modal.msgError('出库明细列表不能为空') this.$modal.msgError('出库明细列表不能为空')
return return
} }
let isTrue = false let isUndefined = false
this.form.pickingInfoList.forEach(item =>{ this.form.pickingInfoList.forEach(item =>{
if (!item.collectNumber) { if (item.collectNumber === undefined) {
isTrue = true isUndefined = true
} }
}) })
if (isTrue) { if (isUndefined) {
this.$modal.msgError('领料数量不能为空') this.$modal.msgError('领料数量不能为空')
return return
} }
let isValidNumber = false
this.form.pickingInfoList.forEach(item => {
if (item.collectNumber < 0.01) {
isValidNumber = true
}
})
if (isValidNumber) {
this.$modal.msgError('出库物料数量不能为[0.00]')
return
}
this.form.materialList = this.form.pickingInfoList.map(item =>{ this.form.materialList = this.form.pickingInfoList.map(item =>{
return { return {
recordId: item.recordId, recordId: item.recordId,
......
...@@ -274,7 +274,7 @@ ...@@ -274,7 +274,7 @@
<el-table-column label="库存" align="center" prop="inventory" /> <el-table-column label="库存" align="center" prop="inventory" />
<el-table-column label="领料数量" align="center" prop="collectNumber" width="120px"> <el-table-column label="领料数量" align="center" prop="collectNumber" width="120px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input-number v-model="scope.row.collectNumber" @change="collectNumberChange" controls-position="right" size="mini" :min="1" :max="parseInt(scope.row.inventory)" :precision="0" style="width: 100%" placeholder="数量"/> <el-input-number v-model="scope.row.collectNumber" @change="collectNumberChange" controls-position="right" size="mini" :min="0.00" :precision="2" :max="parseFloat(scope.row.inventory)" style="width: 100%" placeholder="数量"/>
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column label="销售单价" align="center" prop="price" width="120px">--> <!-- <el-table-column label="销售单价" align="center" prop="price" width="120px">-->
...@@ -284,7 +284,7 @@ ...@@ -284,7 +284,7 @@
<!-- </el-table-column>--> <!-- </el-table-column>-->
<el-table-column label="领料金额" align="center" prop="money" width="120px"> <el-table-column label="领料金额" align="center" prop="money" width="120px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input-number v-model="scope.row.money" disabled controls-position="right" size="mini" :min="0" style="width: 100%" placeholder="金额"/> <el-input-number v-model="scope.row.money" disabled controls-position="right" size="mini" :precision="2" style="width: 100%" placeholder="金额"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
...@@ -343,7 +343,7 @@ ...@@ -343,7 +343,7 @@
<el-table-column label="物资编码" align="center" prop="materialCode" /> <el-table-column label="物资编码" align="center" prop="materialCode" />
<el-table-column label="物资名称" align="center" prop="materialName" /> <el-table-column label="物资名称" align="center" prop="materialName" />
<el-table-column label="物资规格" align="center" prop="materialSpecifications" /> <el-table-column label="物资规格" align="center" prop="materialSpecifications" />
<el-table-column label="物资单位" align="center" prop="materialUnit" width="80"> <el-table-column label="物资单位" align="center" prop="materialUnit" width="50">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.material_unit" :value="scope.row.materialUnit" /> <dict-tag :options="dict.type.material_unit" :value="scope.row.materialUnit" />
</template> </template>
...@@ -351,7 +351,8 @@ ...@@ -351,7 +351,8 @@
<!-- <el-table-column label="质保期" align="center" prop="materialWarrantyPeriod" />--> <!-- <el-table-column label="质保期" align="center" prop="materialWarrantyPeriod" />-->
<el-table-column label="参考价" align="center" prop="referencePrice" width="100" /> <el-table-column label="参考价" align="center" prop="referencePrice" width="100" />
<el-table-column label="销售价" align="center" prop="sellingPrice" width="100" /> <el-table-column label="销售价" align="center" prop="sellingPrice" width="100" />
<el-table-column label="库存" align="center" prop="inventory" width="100" /> <el-table-column label="库存" align="center" prop="inventory" width="80" />
<el-table-column label="入库时间" align="center" prop="createTime" width="160" />
</el-table> </el-table>
<pagination v-show="materialTotal>0" :total="materialTotal" :page.sync="queryMaterialParams.pageNum" :limit.sync="queryMaterialParams.pageSize" @pagination="getMaterialList"/> <pagination v-show="materialTotal>0" :total="materialTotal" :page.sync="queryMaterialParams.pageNum" :limit.sync="queryMaterialParams.pageSize" @pagination="getMaterialList"/>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
...@@ -486,6 +487,7 @@ export default { ...@@ -486,6 +487,7 @@ export default {
queryMaterialParams: { queryMaterialParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
vendorId: undefined,
vendorName: undefined, vendorName: undefined,
warehouseId: undefined, warehouseId: undefined,
warehouseIdList: [], warehouseIdList: [],
...@@ -567,11 +569,11 @@ export default { ...@@ -567,11 +569,11 @@ export default {
return return
} }
this.open1 = true this.open1 = true
this.queryMaterialParams.vendorId = this.form.vendorId;
this.getMaterialList() this.getMaterialList()
}, },
/** 供应商改变 */ /** 供应商改变 */
vendorIdChange(vendorId) { vendorIdChange(vendorId) {
this.queryMaterialParams.vendorId = vendorId;
this.form.pickingInfoList = [] this.form.pickingInfoList = []
}, },
/** 搜索按钮操作 */ /** 搜索按钮操作 */
...@@ -581,7 +583,10 @@ export default { ...@@ -581,7 +583,10 @@ export default {
}, },
/** 重置按钮操作 */ /** 重置按钮操作 */
resetMaterialQuery() { resetMaterialQuery() {
this.resetForm("queryMaterialForm"); this.queryMaterialParams.materialCode = undefined;
this.queryMaterialParams.materialName = undefined;
this.queryMaterialParams.pageNum = 1
this.queryMaterialParams.pageSize = 10
this.handleMaterialQuery(); this.handleMaterialQuery();
}, },
/** 查询物资列表 */ /** 查询物资列表 */
...@@ -597,7 +602,7 @@ export default { ...@@ -597,7 +602,7 @@ export default {
this.tempSelection = []; this.tempSelection = [];
// 手动设置勾选(匹配外部已选数据) // 手动设置勾选(匹配外部已选数据)
this.materialList.forEach(row => { this.materialList.forEach(row => {
const isSelected = this.form.pickingInfoList.some(item => item.warehouseId === row.warehouseId && item.materialId === row.materialId); const isSelected = this.form.pickingInfoList.some(item => item.recordId === row.recordId);
this.$refs.selectionTable.toggleRowSelection(row, isSelected); this.$refs.selectionTable.toggleRowSelection(row, isSelected);
}); });
}); });
...@@ -612,8 +617,8 @@ export default { ...@@ -612,8 +617,8 @@ export default {
// 入库数量变动 // 入库数量变动
collectNumberChange() { collectNumberChange() {
this.form.outMoney = this.form.pickingInfoList.reduce((sum, item) => { this.form.outMoney = this.form.pickingInfoList.reduce((sum, item) => {
item.money = item.collectNumber * item.price item.money = item.collectNumber * item.sellingPrice
return sum + (item.collectNumber * item.price); return sum + (item.collectNumber * item.sellingPrice);
}, 0) }, 0)
}, },
// 多选框选中数据 // 多选框选中数据
...@@ -754,6 +759,26 @@ export default { ...@@ -754,6 +759,26 @@ export default {
this.$modal.msgError('出库物料列表不能为空') this.$modal.msgError('出库物料列表不能为空')
return return
} }
let isUndefined = false
this.form.pickingInfoList.forEach(item =>{
if (item.collectNumber === undefined) {
isUndefined = true
}
})
if (isUndefined) {
this.$modal.msgError('领料数量不能为空')
return
}
let isValidNumber = false
this.form.pickingInfoList.forEach(item => {
if (item.collectNumber < 0.01) {
isValidNumber = true
}
})
if (isValidNumber) {
this.$modal.msgError('出库物料数量不能为[0.00]')
return
}
this.form.materialList = this.form.pickingInfoList.map(item =>{ this.form.materialList = this.form.pickingInfoList.map(item =>{
return { return {
recordId: item.recordId, recordId: item.recordId,
......
...@@ -119,7 +119,7 @@ ...@@ -119,7 +119,7 @@
<el-row> <el-row>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="供应商" prop="vendorId"> <el-form-item label="供应商" prop="vendorId">
<el-select v-model="form.vendorId" placeHolder="请选择供应商" filterable @change="vendorIdChange" style="width: 100%"> <el-select v-model="form.vendorId" placeHolder="请选择供应商" filterable style="width: 100%">
<el-option v-for="item in materialVendorOpt" :key="item.id" :value="item.id" :label="item.vendorName" /> <el-option v-for="item in materialVendorOpt" :key="item.id" :value="item.id" :label="item.vendorName" />
</el-select> </el-select>
</el-form-item> </el-form-item>
......
...@@ -242,17 +242,17 @@ ...@@ -242,17 +242,17 @@
</el-table-column> </el-table-column>
<el-table-column label="退货数量" align="center" prop="returnsNumber" width="120px"> <el-table-column label="退货数量" align="center" prop="returnsNumber" width="120px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input-number v-model="scope.row.returnsNumber" @change="returnsNumberChange" controls-position="right" size="mini" :min="0" :max="scope.row.putawayNumber - scope.row.returnedNumber - scope.row.issuedNumber" :precision="0" style="width: 100%" placeholder="数量"/> <el-input-number v-model="scope.row.returnsNumber" @change="returnsNumberChange" controls-position="right" size="mini" :min="0" :precision="2" :max="parseFloat(scope.row.putawayNumber) - parseFloat(scope.row.returnedNumber) - parseFloat(scope.row.issuedNumber)" style="width: 100%" placeholder="数量"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="退货单价" align="center" prop="returnsPrice" width="120px"> <el-table-column label="退货单价" align="center" prop="returnsPrice" width="160px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input-number v-model="scope.row.returnsPrice" disabled controls-position="right" size="mini" :min="1" :precision="2" style="width: 100%" placeholder="单价"/> <el-input-number v-model="scope.row.returnsPrice" disabled controls-position="right" size="mini" :precision="2" style="width: 100%" placeholder="单价"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="退货金额" align="center" prop="returnsMoney" width="120px"> <el-table-column label="退货金额" align="center" prop="returnsMoney" width="160px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input-number v-model="scope.row.returnsMoney" disabled controls-position="right" size="mini" :min="1" style="width: 100%" placeholder="金额"/> <el-input-number v-model="scope.row.returnsMoney" disabled controls-position="right" size="mini" :precision="2" style="width: 100%" placeholder="金额"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
...@@ -400,15 +400,15 @@ export default { ...@@ -400,15 +400,15 @@ export default {
// 退货数量更改 // 退货数量更改
returnsNumberChange() { returnsNumberChange() {
this.form.returnsMoney = this.materialList.reduce((sum, item) => { this.form.returnsMoney = this.materialList.reduce((sum, item) => {
item.returnsMoney = item.returnsNumber * item.returnsPrice item.returnsMoney = parseFloat(item.returnsNumber) * parseFloat(item.returnsPrice)
return sum + (item.returnsNumber * item.returnsPrice); return sum + (parseFloat(item.returnsNumber) * parseFloat(item.returnsPrice));
}, 0) }, 0)
}, },
// 入库明细删除 // 入库明细删除
handleRowDelete(row) { handleRowDelete(row) {
this.materialList = this.materialList.filter(item => item.id !== row.id); this.materialList = this.materialList.filter(item => item.id !== row.id);
this.form.returnsMoney = this.materialList.reduce((sum, item) => { this.form.returnsMoney = this.materialList.reduce((sum, item) => {
return sum + (item.returnsNumber * item.returnsPrice); return sum + (parseFloat(item.returnsNumber) * parseFloat(item.returnsPrice));
}, 0) }, 0)
}, },
// 取消按钮 // 取消按钮
...@@ -513,12 +513,12 @@ export default { ...@@ -513,12 +513,12 @@ export default {
this.form.returnsInfoBoList = this.materialList this.form.returnsInfoBoList = this.materialList
let isTrue = false; let isTrue = false;
this.form.returnsInfoBoList.forEach(item => { this.form.returnsInfoBoList.forEach(item => {
if (item.returnsNumber < 1) { if (item.returnsNumber < 0.01) {
isTrue = true; isTrue = true;
} }
}) })
if (isTrue) { if (isTrue) {
this.$modal.msgError('退货数量不能小于1') this.$modal.msgError('退货数量不能小于0.01')
this.buttonLoading = false; this.buttonLoading = false;
return return
} }
......
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column label="采购标的" align="center" prop="procurementSubject" />--> <!-- <el-table-column label="采购标的" align="center" prop="procurementSubject" />-->
<el-table-column label="适用车型" align="center" prop="compatibleWith" /> <el-table-column label="适用车型" align="center" prop="compatibleWith" show-overflow-tooltip/>
<el-table-column label="物资图片" align="center" prop="materialUrl"> <el-table-column label="物资图片" align="center" prop="materialUrl">
<template slot-scope="scope"> <template slot-scope="scope">
<image-preview :src="scope.row.materialUrl" style="width: 50px; height: 50px" /> <image-preview :src="scope.row.materialUrl" style="width: 50px; height: 50px" />
......
...@@ -752,7 +752,7 @@ export default { ...@@ -752,7 +752,7 @@ export default {
}); });
}, },
getCarList() { getCarList() {
listCar({ pageNum: 1, pageSize: 99 }).then(res=>{ listCar({ pageNum: 1, pageSize: 9999 }).then(res=>{
this.carList = res.rows this.carList = res.rows
}) })
}, },
......
...@@ -404,7 +404,7 @@ export default { ...@@ -404,7 +404,7 @@ export default {
/** 查询维修项目列表 */ /** 查询维修项目列表 */
getMaintainList() { getMaintainList() {
this.loading = true; this.loading = true;
listMaintainProject({ ...this.queryMaintainParams, notInIdList: this.repairFormProjectList.map(item => item.maintainId) }).then(response => { listMaintainProject({ ...this.queryMaintainParams }).then(response => {
this.maintainProjectList = response.rows; this.maintainProjectList = response.rows;
this.total = response.total; this.total = response.total;
this.loading = false; this.loading = false;
...@@ -417,7 +417,7 @@ export default { ...@@ -417,7 +417,7 @@ export default {
}, },
/** 查询人员-人员列表 */ /** 查询人员-人员列表 */
getMaintainUserList() { getMaintainUserList() {
listUser({ type: 1, pageNum: 1, pageSize: 1000 }).then(response => { listUser({ pageNum: 1, pageSize: 1000 }).then(response => {
this.maintainUserList = response.rows; this.maintainUserList = response.rows;
}); });
}, },
......
...@@ -20,7 +20,20 @@ ...@@ -20,7 +20,20 @@
<el-table-column label="人员名称" align="center" prop="maintainUserName" /> <el-table-column label="人员名称" align="center" prop="maintainUserName" />
<el-table-column label="岗位名称" align="center" prop="postName" /> <el-table-column label="岗位名称" align="center" prop="postName" />
<!-- <el-table-column label="在岗状态" align="center" prop="state" />--> <!-- <el-table-column label="在岗状态" align="center" prop="state" />-->
<el-table-column label="分配工时" align="center" prop="dispatchManHour" /> <el-table-column label="分配工时" align="center" prop="dispatchManHour">
<template slot-scope="scope">
<el-input-number
v-model="scope.row.dispatchManHour"
@change="handleDispatchManHourChange(scope.row)"
controls-position="right"
size="mini"
:class="{ 'input-error': !isDispatchValid(scope.row) }"
:min="0"
:max="Number(scope.row.standardManHour)"
:precision="1"
style="width: 100%" />
</template>
</el-table-column>
<el-table-column label="扣罚工时" align="center" prop="deductManHour"> <el-table-column label="扣罚工时" align="center" prop="deductManHour">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input-number v-model="scope.row.deductManHour" @change="submitForm(scope.row)" controls-position="right" size="mini" :min="0" :max="Number(scope.row.dispatchManHour)" :precision="1" style="width: 100%" /> <el-input-number v-model="scope.row.deductManHour" @change="submitForm(scope.row)" controls-position="right" size="mini" :min="0" :max="Number(scope.row.dispatchManHour)" :precision="1" style="width: 100%" />
...@@ -28,7 +41,7 @@ ...@@ -28,7 +41,7 @@
</el-table-column> </el-table-column>
<el-table-column label="实际工时" align="center" prop="actualManHour"> <el-table-column label="实际工时" align="center" prop="actualManHour">
<template slot-scope="scope"> <template slot-scope="scope">
{{scope.row.actualManHour = Number(scope.row.dispatchManHour) - Number(scope.row.deductManHour).toFixed(1)}} {{ (Number(scope.row.dispatchManHour) - Number(scope.row.deductManHour)).toFixed(1) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
...@@ -77,7 +90,8 @@ import { ...@@ -77,7 +90,8 @@ import {
delRepairFormProjectDispatch, delRepairFormProjectDispatch,
addRepairFormProjectDispatch, addRepairFormProjectDispatch,
updateRepairFormProjectDispatch, updateRepairFormProjectDispatch,
addRepairFormProjectDispatchP addRepairFormProjectDispatchP,
updateRepairFormProjectDispatchBatch
} from '@/api/business/repairFormProjectDispatch' } from '@/api/business/repairFormProjectDispatch'
import user from "../user/index" import user from "../user/index"
...@@ -185,6 +199,16 @@ export default { ...@@ -185,6 +199,16 @@ export default {
} }
}; };
}, },
computed: {
// 检查总分配工时是否超过标准工时
isTotalExceedStandard() {
if (!this.data.standardManHour) return false;
const totalDispatchManHour = this.repairFormProjectDispatchList.reduce((total, item) => {
return total + (Number(item.dispatchManHour) || 0);
}, 0);
return totalDispatchManHour.toFixed(1) !== Number(this.data.standardManHour).toFixed(1);
}
},
created() { created() {
this.getList(); this.getList();
}, },
...@@ -262,13 +286,50 @@ export default { ...@@ -262,13 +286,50 @@ export default {
this.title = "修改报修单-报修项目-派工"; this.title = "修改报修单-报修项目-派工";
}); });
}, },
/** 提交按钮 */ // 检查分配工时是否有效
isDispatchValid(row) {
if (!this.data.standardManHour) return true;
const totalDispatchManHour = this.repairFormProjectDispatchList.reduce((total, item) => {
return total + (Number(item.dispatchManHour) || 0);
}, 0);
return totalDispatchManHour.toFixed(1) === Number(this.data.standardManHour).toFixed(1);
},
/** 分配工时变化处理 */
handleDispatchManHourChange(row) {
// 检查总分配工时是否等于标准工时
const totalDispatchManHour = this.repairFormProjectDispatchList.reduce((total, item) => {
return total + (Number(item.dispatchManHour) || 0);
}, 0);
// 如果总分配工时不等于标准工时,显示提示
if (this.data.standardManHour && totalDispatchManHour.toFixed(1) !== Number(this.data.standardManHour).toFixed(1)) {
this.$message.warning(`总分配工时(${totalDispatchManHour.toFixed(1)})不等于项目标准工时(${Number(this.data.standardManHour).toFixed(1)})`);
return false;
}
// 更新实际工时
row.actualManHour = (Number(row.dispatchManHour) - Number(row.deductManHour)).toFixed(1);
// 提交更新所有数据
this.submitAllForm();
},
/** 扣罚工时变化处理 */
submitForm(row) { submitForm(row) {
// 更新实际工时
row.actualManHour = (Number(row.dispatchManHour) - Number(row.deductManHour)).toFixed(1);
// 提交更新所有数据
this.submitAllForm();
},
/** 提交所有数据 */
submitAllForm() {
this.buttonLoading = true; this.buttonLoading = true;
updateRepairFormProjectDispatch(row).then(response => { // 使用批量更新接口提交所有行数据
updateRepairFormProjectDispatchBatch(this.repairFormProjectDispatchList).then(response => {
this.$modal.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList(); this.getList();
}).catch(error => {
console.error(error);
this.$modal.msgError("修改失败");
}).finally(() => { }).finally(() => {
this.buttonLoading = false; this.buttonLoading = false;
}); });
...@@ -312,3 +373,9 @@ export default { ...@@ -312,3 +373,9 @@ export default {
} }
}; };
</script> </script>
<style scoped>
.input-error ::v-deep .el-input__inner {
border-color: #f56c6c !important;
}
</style>
\ No newline at end of file
<template>
<i-frame :src="url"/>
</template>
<script>
import { getToken } from '@/utils/auth'
import { getBiUrl } from '@/api/tool/jimu'
import iFrame from '@/components/iFrame/index.vue'
import {getCurrentDeptTree} from "@/api/business/unit";
export default {
name: "orderInfo",
components: {
iFrame
},
data() {
return {
url: ''
}
},
created() {
this.init()
},
methods: {
init() {
getCurrentDeptTree().then(response => {
let deptIds = response.data.map((item) => {
return item.deptId
})
console.log('deptIds',deptIds.join(','))
this.url = `http://${window.location.hostname}:8099/jmreport/view/1174907222744879104?token=Bearer `+ getToken()
console.log('url', this.url)
});
},
}
}
</script>
<template>
<i-frame :src="url"/>
</template>
<script>
import {getToken} from '@/utils/auth'
import iFrame from '@/components/iFrame/index.vue'
import {getCurrentDeptTree} from "@/api/business/unit";
export default {
name: "orderInfo",
components: {
iFrame
},
data() {
return {
url: ''
}
},
created() {
this.init()
},
methods: {
init() {
getCurrentDeptTree().then(response => {
let deptIds = response.data.map((item) => {
return item.deptId
})
console.log('deptIds',deptIds.join(','))
this.url = `http://${window.location.hostname}:8099/jmreport/view/1174586035611238400?deptId=${this.$store.state.user.userInfo.deptId}&deptIds=${deptIds.join(',')}&token=Bearer `+ getToken()
console.log('url', this.url)
});
},
}
}
</script>
...@@ -58,6 +58,8 @@ ...@@ -58,6 +58,8 @@
<el-table-column label="证件号" align="center" prop="clientCertificateNumber" width="100px" show-overflow-tooltip/> <el-table-column label="证件号" align="center" prop="clientCertificateNumber" width="100px" show-overflow-tooltip/>
<el-table-column label="工时费优惠" align="center" prop="manHourDiscountMoney" /> <el-table-column label="工时费优惠" align="center" prop="manHourDiscountMoney" />
<el-table-column label="原料费优惠" align="center" prop="materialDiscountMoney" /> <el-table-column label="原料费优惠" align="center" prop="materialDiscountMoney" />
<el-table-column label="应收金额" align="center" prop="receivableMoney" />
<el-table-column label="结算金额" align="center" prop="practicalMoney" />
<el-table-column label="结算时间" align="center" prop="settlementTime" width="120"> <el-table-column label="结算时间" align="center" prop="settlementTime" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.settlementTime, '{y}-{m}-{d}') }}</span> <span>{{ parseTime(scope.row.settlementTime, '{y}-{m}-{d}') }}</span>
...@@ -269,6 +271,7 @@ ...@@ -269,6 +271,7 @@
<el-form-item label="收款时间" prop="collectionTime"> <el-form-item label="收款时间" prop="collectionTime">
<el-date-picker clearable <el-date-picker clearable
v-model="form.collectionTime" v-model="form.collectionTime"
:disabled="isQrPay"
type="datetime" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择收款时间"> placeholder="请选择收款时间">
...@@ -277,12 +280,12 @@ ...@@ -277,12 +280,12 @@
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="收款账号" prop="collectionAccount"> <el-form-item label="收款账号" prop="collectionAccount">
<el-input v-model="form.collectionAccount" placeholder="请输入收款账号" /> <el-input v-model="form.collectionAccount" :disabled="isQrPay" placeholder="请输入收款账号" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="收款流水号" prop="collectionSerialNumber"> <el-form-item label="交易流水号" prop="collectionSerialNumber">
<el-input v-model="form.collectionSerialNumber" placeholder="请输入收款流水号" /> <el-input v-model="form.collectionSerialNumber" :disabled="isQrPay" placeholder="请输入交易流水号" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
...@@ -303,11 +306,25 @@ ...@@ -303,11 +306,25 @@
</el-form> </el-form>
</el-scrollbar> </el-scrollbar>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="qrOpen">扫码支付</el-button>
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button> <el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button> <el-button @click="cancel"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
<!-- 扫码支付对话框 -->
<el-dialog :title="title" :visible.sync="open2" width="500px" append-to-body>
<el-form ref="payForm" :model="payForm" :rules="payRules" label-width="80px">
<el-form-item label="支付码" prop="paymentAccount">
<el-input ref="payCodeInput" v-model="payForm.paymentAccount" @keydown.enter.native.prevent placeholder="使用设备扫描条形码" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="payButtonLoading" type="primary" @click="paySubmitForm">确认支付</el-button>
<el-button :loading="payButtonLoading" @click="open2 = false"> </el-button>
</div>
</el-dialog>
<!-- 详情对话框 --> <!-- 详情对话框 -->
<el-dialog :title="title" :visible.sync="open1" width="80%" append-to-body> <el-dialog :title="title" :visible.sync="open1" width="80%" append-to-body>
<el-scrollbar style="height: 75vh;"> <el-scrollbar style="height: 75vh;">
...@@ -392,7 +409,7 @@ ...@@ -392,7 +409,7 @@
import { import {
delSettlementMaintain, delSettlementMaintain,
getSettlementMaintain, getSettlementMaintain,
listSettlementMaintain, listSettlementMaintain, paySettlementMaintain,
receiptSettlementMaintain receiptSettlementMaintain
} from '@/api/business/settlementMaintain' } from '@/api/business/settlementMaintain'
...@@ -403,6 +420,7 @@ export default { ...@@ -403,6 +420,7 @@ export default {
return { return {
// 按钮loading // 按钮loading
buttonLoading: false, buttonLoading: false,
payButtonLoading: false,
// 遮罩层 // 遮罩层
loading: true, loading: true,
// 选中数组 // 选中数组
...@@ -422,6 +440,8 @@ export default { ...@@ -422,6 +440,8 @@ export default {
// 是否显示弹出层 // 是否显示弹出层
open: false, open: false,
open1: false, open1: false,
open2: false,
isQrPay: false,
// 查询参数 // 查询参数
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
...@@ -433,6 +453,10 @@ export default { ...@@ -433,6 +453,10 @@ export default {
}, },
// 表单参数 // 表单参数
form: {}, form: {},
payForm: {
id: undefined,
paymentAccount: undefined,
},
// 表单校验 // 表单校验
rules: { rules: {
collectionTime: [ collectionTime: [
...@@ -444,8 +468,13 @@ export default { ...@@ -444,8 +468,13 @@ export default {
collectionSerialNumber: [ collectionSerialNumber: [
{ required: true, message: "收款流水号不能为空", trigger: "blur" } { required: true, message: "收款流水号不能为空", trigger: "blur" }
], ],
collectionVoucher: [ // collectionVoucher: [
{ required: true, message: "收款回执不能为空", trigger: "change" } // { required: true, message: "收款回执不能为空", trigger: "change" }
// ],
},
payRules: {
paymentAccount: [
{ required: true, message: "支付码不能为空", trigger: "blur" }
], ],
} }
}; };
...@@ -526,6 +555,40 @@ export default { ...@@ -526,6 +555,40 @@ export default {
this.title = "结算维修单详情"; this.title = "结算维修单详情";
}); });
}, },
/** 扫码支付按钮操作 */
qrOpen() {
this.payForm = {
id: this.form.id,
paymentAccount: undefined,
}
this.open2 = true;
this.isQrPay = false;
this.title = "扫码支付";
this.$nextTick(() => {
// 确保输入框存在并获取焦点
if (this.$refs.payCodeInput && this.$refs.payCodeInput.focus) {
this.$refs.payCodeInput.focus()
}
})
},
/** 确认支付按钮操作 */
paySubmitForm() {
this.$refs["payForm"].validate(valid => {
if (valid) {
this.payButtonLoading = true;
paySettlementMaintain(this.payForm).then(response => {
this.$modal.msgSuccess("支付成功");
this.open2 = false;
this.isQrPay = true;
getSettlementMaintain(this.form.id).then(response => {
this.form = response.data;
});
}).finally(() => {
this.payButtonLoading = false;
});
}
});
},
/** 新增按钮操作 */ /** 新增按钮操作 */
handleAdd() { handleAdd() {
this.reset(); this.reset();
......
...@@ -119,13 +119,13 @@ ...@@ -119,13 +119,13 @@
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="6"> <!-- <el-col :span="6">-->
<el-form-item label="支付方式" prop="paymentMethod"> <!-- <el-form-item label="支付方式" prop="paymentMethod">-->
<el-select v-model="form.paymentMethod" placeholder="请选择支付方式" style="width: 100%"> <!-- <el-select v-model="form.paymentMethod" placeholder="请选择支付方式" style="width: 100%">-->
<el-option v-for="item in dict.type.settlement_payment_method" :key="item.value" :value="parseInt(item.value)" :label="item.label" /> <!-- <el-option v-for="item in dict.type.settlement_payment_method" :key="item.value" :value="parseInt(item.value)" :label="item.label" />-->
</el-select> <!-- </el-select>-->
</el-form-item> <!-- </el-form-item>-->
</el-col> <!-- </el-col>-->
<el-col :span="6"> <el-col :span="6">
<el-form-item label="结算时间" prop="settlementTime"> <el-form-item label="结算时间" prop="settlementTime">
<el-date-picker clearable <el-date-picker clearable
...@@ -280,9 +280,9 @@ export default { ...@@ -280,9 +280,9 @@ export default {
paymentAccountName: [ paymentAccountName: [
{ required: true, message: "账号名称不能为空", trigger: "blur" } { required: true, message: "账号名称不能为空", trigger: "blur" }
], ],
paymentVoucher: [ // paymentVoucher: [
{ required: true, message: "付款凭证不能为空", trigger: "blur" } // { required: true, message: "付款凭证不能为空", trigger: "blur" }
], // ],
}, },
}; };
}, },
...@@ -378,7 +378,7 @@ export default { ...@@ -378,7 +378,7 @@ export default {
this.buttonLoading = false; this.buttonLoading = false;
}).finally(() => { }).finally(() => {
this.buttonLoading = false; this.buttonLoading = false;
this.$tab.closeOpenPage({path: '/settlement/settlementMaintain?clientType=1'}) this.$tab.closeOpenPage({path: '/settlement/settlementMaintain?clientType=2'})
}); });
} }
}); });
......
...@@ -43,6 +43,15 @@ ...@@ -43,6 +43,15 @@
v-hasPermi="['business:settlementMaterial:add']" v-hasPermi="['business:settlementMaterial:add']"
>结算</el-button> >结算</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
...@@ -447,6 +456,7 @@ export default { ...@@ -447,6 +456,7 @@ export default {
}, },
// 多选框选中数据 // 多选框选中数据
handleSelectionChange(selection) { handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
// 如果没有选中任何项,直接禁用按钮 // 如果没有选中任何项,直接禁用按钮
if (selection.length === 0) { if (selection.length === 0) {
this.multiple = true; // 禁用按钮 this.multiple = true; // 禁用按钮
...@@ -593,8 +603,9 @@ export default { ...@@ -593,8 +603,9 @@ export default {
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.download('business/materialPicking/export', { this.download('business/materialPicking/export', {
...this.queryParams ...this.queryParams,
}, `materialPicking_${new Date().getTime()}.xlsx`) ids: this.ids
}, `供应商铺货结算.xlsx`)
} }
} }
}; };
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
auto-complete="off" auto-complete="off"
placeholder="密码" placeholder="密码"
@keyup.enter.native="handleLogin" @keyup.enter.native="handleLogin"
@input="checkPasswordStrength"
> >
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input> </el-input>
...@@ -120,6 +121,26 @@ export default { ...@@ -120,6 +121,26 @@ export default {
this.getCookie(); this.getCookie();
}, },
methods: { methods: {
// 检查密码强度
checkPasswordStrength() {
if (!this.loginForm.password) {
this.isPasswordStrong = false;
return;
}
let strength = 0;
// 长度检查
if (this.loginForm.password.length >= 8) strength++;
// 包含小写字母
if (/[a-z]/.test(this.loginForm.password)) strength++;
// 包含大写字母
if (/[A-Z]/.test(this.loginForm.password)) strength++;
// 包含数字
if (/[0-9]/.test(this.loginForm.password)) strength++;
// 包含特殊字符
if (/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(this.loginForm.password)) strength++;
// 设置强度等级
this.isPasswordStrong = strength > 4;
},
getCode() { getCode() {
getCodeImg().then(res => { getCodeImg().then(res => {
this.captchaEnabled = res.data.captchaEnabled === undefined ? true : res.data.captchaEnabled; this.captchaEnabled = res.data.captchaEnabled === undefined ? true : res.data.captchaEnabled;
...@@ -142,6 +163,11 @@ export default { ...@@ -142,6 +163,11 @@ export default {
handleLogin() { handleLogin() {
this.$refs.loginForm.validate(valid => { this.$refs.loginForm.validate(valid => {
if (valid) { if (valid) {
// 再次确认密码强度
if (!this.isPasswordStrong) {
this.$message.error("密码强度不足,请确保包含大小写字母、数字和特殊字符");
return;
}
this.loading = true; this.loading = true;
if (this.loginForm.rememberMe) { if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 }); Cookies.set("username", this.loginForm.username, { expires: 30 });
......
...@@ -172,6 +172,11 @@ ...@@ -172,6 +172,11 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" v-if="form.type == 4">
<el-form-item label="终端号" prop="terminalCode">
<el-input v-model="form.terminalCode" placeholder="请输入终端号" />
</el-form-item>
</el-col>
</el-row> </el-row>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
...@@ -284,7 +289,8 @@ export default { ...@@ -284,7 +289,8 @@ export default {
phone: undefined, phone: undefined,
email: undefined, email: undefined,
status: "0", status: "0",
type: undefined type: undefined,
terminalCode: undefined,
}; };
this.resetForm("form"); this.resetForm("form");
}, },
......
...@@ -260,7 +260,7 @@ ...@@ -260,7 +260,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item v-if="form.userId == undefined" label="用户密码" prop="password"> <el-form-item v-if="form.userId == undefined" label="用户密码" prop="password">
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password/> <el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password @input="checkPasswordStrength"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
...@@ -385,7 +385,30 @@ export default { ...@@ -385,7 +385,30 @@ export default {
dicts: ['sys_normal_disable', 'sys_user_sex'], dicts: ['sys_normal_disable', 'sys_user_sex'],
components: { Treeselect }, components: { Treeselect },
data() { data() {
// 验证密码复杂度
const validatePasswordComplexity = (rule, value, callback) => {
if (!value) {
callback(new Error("新密码不能为空"));
return;
}
// 检查密码复杂度
const hasLowerCase = /[a-z]/.test(value);
const hasUpperCase = /[A-Z]/.test(value);
const hasNumber = /[0-9]/.test(value);
const hasSpecialChar = /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(value);
if (!hasLowerCase || !hasUpperCase || !hasNumber || !hasSpecialChar) {
callback(new Error("密码必须包含大小写字母、数字和特殊字符"));
return;
}
callback();
};
return { return {
strengthClass: 'weak',
strengthText: '',
isPasswordStrong: false,
// 遮罩层 // 遮罩层
loading: true, loading: true,
// 选中数组 // 选中数组
...@@ -468,7 +491,8 @@ export default { ...@@ -468,7 +491,8 @@ export default {
], ],
password: [ password: [
{ required: true, message: "用户密码不能为空", trigger: "blur" }, { required: true, message: "用户密码不能为空", trigger: "blur" },
{ min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' } { min: 8, message: "密码至少为8个字符,须包含大写字母、小写字母、数字和特殊字符", trigger: "blur" },
{ validator: validatePasswordComplexity, trigger: "blur" }
], ],
email: [ email: [
{ {
...@@ -501,6 +525,40 @@ export default { ...@@ -501,6 +525,40 @@ export default {
}); });
}, },
methods: { methods: {
// 检查密码强度
checkPasswordStrength() {
if (!this.form.password) {
this.strengthClass = 'weak';
this.strengthText = '';
this.isPasswordStrong = false;
return;
}
let strength = 0;
// 长度检查
if (this.form.password.length >= 8) strength++;
// 包含小写字母
if (/[a-z]/.test(this.form.password)) strength++;
// 包含大写字母
if (/[A-Z]/.test(this.form.password)) strength++;
// 包含数字
if (/[0-9]/.test(this.form.password)) strength++;
// 包含特殊字符
if (/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(this.form.password)) strength++;
// 设置强度等级
if (strength <= 2) {
this.strengthClass = 'weak';
this.strengthText = '';
this.isPasswordStrong = false;
} else if (strength <= 4) {
this.strengthClass = 'medium';
this.strengthText = '';
this.isPasswordStrong = false;
} else {
this.strengthClass = 'strong';
this.strengthText = '';
this.isPasswordStrong = true;
}
},
/** 查询用户列表 */ /** 查询用户列表 */
getList() { getList() {
this.loading = true; this.loading = true;
...@@ -625,13 +683,13 @@ export default { ...@@ -625,13 +683,13 @@ export default {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
closeOnClickModal: false, closeOnClickModal: false,
inputPattern: /^.{5,20}$/, inputPattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,20}$/,
inputErrorMessage: "用户密码长度必须介于 5 和 20 之间" inputErrorMessage: "密码必须为8-20个字符,且包含大写字母、小写字母、数字和特殊字符(@$!%*?&)"
}).then(({ value }) => { }).then(({ value }) => {
resetUserPwd(row.userId, value).then(response => { resetUserPwd(row.userId, value).then(response => {
this.$modal.msgSuccess("修改成功,新密码是:" + value); this.$modal.msgSuccess("修改成功,新密码是:" + value);
}); });
}).catch(() => {}); }).catch(() => {});
}, },
/** 分配角色操作 */ /** 分配角色操作 */
handleAuthRole: function(row) { handleAuthRole: function(row) {
......