...
 
Commits (18)
......@@ -109,6 +109,24 @@
<!-- <version>${与你的agent探针版本保持一致}</version>-->
<!-- </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>
<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:
sdkAppId: appid
#地域信息默认为 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:
sdkAppId: appid
#地域信息默认为 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
package com.maintain.business.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import com.maintain.business.domain.vo.ErpMaterialPickingExportVo;
import com.maintain.common.utils.poi.SheetPO;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
......@@ -62,8 +65,9 @@ public class ErpMaterialPickingController extends BaseController {
@Log(title = "物料出库", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ErpMaterialPickingBo bo, HttpServletResponse response) {
List<ErpMaterialPickingVo> list = iErpMaterialPickingService.queryList(bo);
ExcelUtil.exportExcel(list, "物料出库", ErpMaterialPickingVo.class, response);
iErpMaterialPickingService.export(bo,response);
// List<ErpMaterialPickingVo> list = iErpMaterialPickingService.queryList(bo);
// ExcelUtil.exportExcel(list, "物料出库", ErpMaterialPickingVo.class, response);
}
/**
......
......@@ -5,6 +5,7 @@ import java.util.List;
import java.util.Arrays;
import java.util.stream.Collectors;
import com.maintain.business.domain.bo.ErpSettlementMaintainPayBo;
import com.maintain.business.domain.bo.ErpSettlementMaintainRepairFormBo;
import com.maintain.business.domain.vo.ErpSettlementMaintainRepairFormVo;
import com.maintain.business.service.IErpRepairFormService;
......@@ -137,4 +138,16 @@ public class ErpSettlementMaintainController extends BaseController {
public R<Void> receipt(@Validated(EditGroup.class) @RequestBody ErpSettlementMaintainBo 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 {
*/
private Long carTypeId;
/**
* 分公司
*/
private String branchOffice;
/**
* 车队
*/
private String motorcade;
/**
* 线路
*/
private String line;
}
......@@ -71,9 +71,13 @@ public class ErpSettlementMaintain extends BaseEntity {
*/
private Date settlementTime;
/**
* 支付方式(1支付宝 2微信
* 支付方式(1扫码支付 2手动支付
*/
private Integer paymentMethod;
/**
* 支付单号
*/
private String paymentNumber;
/**
* 付款账号
*/
......@@ -111,7 +115,7 @@ public class ErpSettlementMaintain extends BaseEntity {
*/
private String collectionAccount;
/**
* 收款流水号
* 交易流水号
*/
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 {
*/
private Date createTime;
/**
* 分公司
*/
private String branchOffice;
/**
* 车队
*/
private String motorcade;
/**
* 线路
*/
private String line;
}
......@@ -131,4 +131,14 @@ public class ErpMaterialPickingBo extends BaseEntity {
private List<ErpMaterialPickingInfoAddBo> materialList;
/**
* 导出IDs
*/
private List<Long> ids;
/**
* 单位IDS
*/
private List<Long> deptIds;
}
......@@ -90,7 +90,6 @@ public class ErpSettlementMaintainBo extends BaseEntity {
/**
* 支付方式(1支付宝 2微信)
*/
@NotNull(message = "支付方式(1支付宝 2微信)不能为空", groups = { AddGroup.class, EditGroup.class })
private Integer paymentMethod;
/**
......@@ -106,7 +105,6 @@ public class ErpSettlementMaintainBo extends BaseEntity {
/**
* 付款凭证
*/
@NotBlank(message = "付款凭证不能为空", groups = { AddGroup.class, EditGroup.class })
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 {
@ColumnWidth(20)
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;
}
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;
}
......@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.maintain.business.domain.ErpMaterialPickingInfo;
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.ErpMaterialReturnsInfoVo;
import com.maintain.common.core.mapper.BaseMapperPlus;
......@@ -35,4 +37,10 @@ public interface ErpMaterialPickingInfoMapper extends BaseMapperPlus<ErpMaterial
*/
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;
import com.maintain.common.core.page.TableDataInfo;
import com.maintain.common.core.domain.PageQuery;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.List;
......@@ -63,4 +64,9 @@ public interface IErpMaterialPickingService {
* 新增物料出库退料
*/
Boolean insertReturnByBo(ErpMaterialPickingBo bo);
/**
* 导出物料出库列表
*/
void export(ErpMaterialPickingBo bo, HttpServletResponse response);
}
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.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.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
......@@ -53,4 +53,11 @@ public interface IErpSettlementMaintainService {
* @return
*/
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);
}
package com.maintain.business.service.impl;
import java.util.Date;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.bo.ErpMaterialPickingInfoAddBo;
import com.maintain.business.domain.bo.ErpMaterialPickingInfoBo;
......@@ -22,6 +24,9 @@ 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.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.system.mapper.SysDeptMapper;
import lombok.RequiredArgsConstructor;
......@@ -30,6 +35,7 @@ import com.maintain.business.domain.bo.ErpMaterialPickingBo;
import com.maintain.business.service.IErpMaterialPickingService;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
......@@ -168,7 +174,7 @@ public class ErpMaterialPickingServiceImpl implements IErpMaterialPickingService
add.setVendorName(materialVendor.getVendorName());
BigDecimal moneyTotal = bo.getMaterialList().stream().map(ErpMaterialPickingInfoAddBo::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
add.setOutMoney(moneyTotal);
add.setCreateDeptId(LoginHelper.getUserId());
add.setCreateDeptId(LoginHelper.getDeptId());
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
......@@ -446,4 +452,58 @@ public class ErpMaterialPickingServiceImpl implements IErpMaterialPickingService
}
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);
}
}
......@@ -311,9 +311,11 @@ public class ErpRepairFormServiceImpl implements IErpRepairFormService {
.eq(ErpMaterialPickingInfo::getRepairFormId, repairForm.getId())
);
// 删除库存记录表数据
LambdaUpdateWrapper<ErpMaterialInventoryRecord> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.in(ErpMaterialInventoryRecord::getInfoId, pickingInfoIds);
materialInventoryRecordMapper.delete(lambdaUpdateWrapper);
if (!pickingInfoIds.isEmpty()) {
LambdaUpdateWrapper<ErpMaterialInventoryRecord> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.in(ErpMaterialInventoryRecord::getInfoId, pickingInfoIds);
materialInventoryRecordMapper.delete(lambdaUpdateWrapper);
}
}
return flag;
}
......
package com.maintain.business.service.impl;
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.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.maintain.business.domain.ErpRepairForm;
import com.maintain.business.domain.ErpSettlementMaintain;
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.ErpSettlementMaintainVo;
import com.maintain.business.mapper.ErpClientMapper;
import com.maintain.business.mapper.ErpRepairFormMapper;
import com.maintain.business.mapper.ErpSettlementMaintainMapper;
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.SettlementState;
import com.maintain.common.exception.ServiceException;
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.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.system.mapper.SysDeptMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
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 java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.stream.Collectors;
/**
......@@ -49,6 +57,12 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS
private final ErpSettlementMaintainRepairFormMapper settlementMaintainRepairFormMapper;
private final ErpRepairFormMapper repairFormMapper;
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
}
private LambdaQueryWrapper<ErpSettlementMaintain> buildQueryWrapper(ErpSettlementMaintainBo bo) {
List<SysDept> sysDeptList = deptMapper.selectChildrenDeptById(LoginHelper.getDeptId(), null);
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<ErpSettlementMaintain> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getSettlementNumber()), ErpSettlementMaintain::getSettlementNumber, bo.getSettlementNumber());
......@@ -88,7 +103,7 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS
lqw.eq(bo.getClientCertificateType() != null, ErpSettlementMaintain::getClientCertificateType, bo.getClientCertificateType());
lqw.eq(StringUtils.isNotBlank(bo.getClientCertificateNumber()), ErpSettlementMaintain::getClientCertificateNumber, bo.getClientCertificateNumber());
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);
return lqw;
}
......@@ -204,4 +219,65 @@ public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainS
}
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 做一些数据校验,如唯一约束
}
}
......@@ -49,5 +49,70 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
${ew.getCustomSqlSegment}
</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>
......@@ -170,8 +170,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
GROUP BY repair_form_id
) erfpd ON erf.id = erfpd.repair_form_id
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
WHERE state != 3
GROUP BY repair_form_id
) empi ON erf.id = empi.repair_form_id
</sql>
......
......@@ -85,5 +85,9 @@ public class SysDept extends TreeEntity<SysDept> {
* 类型(1总公司 2分公司 3车队 4车间 5总公司管理部门 6分公司管理部门 7维修点)
*/
private String type;
/**
* 终端号
*/
private String terminalCode;
}
......@@ -10,8 +10,8 @@ import lombok.Getter;
@Getter
public enum SettlementState {
ONE(1, "待确认"),
TWO(2, "已确认");
ONE(1, "待支付"),
TWO(2, "已支付");
private final Integer code;
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;
import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
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.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
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.maintain.common.convert.ExcelBigNumberConvert;
import com.maintain.common.excel.*;
......@@ -16,6 +21,9 @@ import com.maintain.common.utils.StringUtils;
import com.maintain.common.utils.file.FileUtils;
import lombok.AccessLevel;
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.http.HttpServletResponse;
......@@ -23,6 +31,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
......@@ -32,6 +43,7 @@ import java.util.Map;
*
* @author Lion Li
*/
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ExcelUtil {
......@@ -377,4 +389,54 @@ public class ExcelUtil {
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;
}
......@@ -51,3 +51,13 @@ export function receiptSettlementMaintain(data) {
data: data
})
}
// 结算维修单回执
export function paySettlementMaintain(data) {
return request({
url: '/business/settlementMaintain/pay',
method: 'put',
data: data,
timeout: 30000
})
}
......@@ -213,6 +213,24 @@
<el-form-item label="车型ID" prop="carTypeId">
<el-input v-model="form.carTypeId" placeholder="请输入车型ID" />
</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>
<el-row :gutter="20">
<el-col :span="8">
......@@ -507,7 +525,7 @@ export default {
handleUpdate(row) {
getCar(row.id).then(res =>{
this.form = res.data
this.form.clientType = row.clientType
this.form.clientType = row.clientType+''
this.open = true;
this.title = "修改车辆信息";
this.getCode()
......
......@@ -86,7 +86,7 @@
<el-table-column label="库存" align="center" prop="inventory" />
<el-table-column label="领料数量" align="center" prop="collectNumber" width="120px">
<template slot-scope="scope">
<el-input-number v-model="scope.row.collectNumber" @change="collectNumberChange" controls-position="right" size="mini" :min="0.01" :precision="2" :max="parseFloat(scope.row.inventory)" 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>
</el-table-column>
<!-- <el-table-column label="销售单价" align="center" prop="price" width="120px">-->
......@@ -380,16 +380,26 @@ export default {
this.$modal.msgError('出库明细列表不能为空')
return
}
let isTrue = false
let isUndefined = false
this.form.pickingInfoList.forEach(item =>{
if (!item.collectNumber) {
isTrue = true
if (item.collectNumber === undefined) {
isUndefined = true
}
})
if (isTrue) {
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 =>{
return {
recordId: item.recordId,
......
......@@ -274,7 +274,7 @@
<el-table-column label="库存" align="center" prop="inventory" />
<el-table-column label="领料数量" align="center" prop="collectNumber" width="120px">
<template slot-scope="scope">
<el-input-number v-model="scope.row.collectNumber" @change="collectNumberChange" controls-position="right" size="mini" :min="0.01" :precision="2" :max="parseFloat(scope.row.inventory)" 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>
</el-table-column>
<!-- <el-table-column label="销售单价" align="center" prop="price" width="120px">-->
......@@ -759,6 +759,26 @@ export default {
this.$modal.msgError('出库物料列表不能为空')
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 =>{
return {
recordId: item.recordId,
......
......@@ -325,7 +325,7 @@
<el-button icon="el-icon-refresh" size="mini" @click="resetMaterialQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="materialLoading" :data="materialList" ref="selectionTable" max-height="450" @selection-change="handleMaterialSelectionChange">
<el-table v-loading="materialLoading" :data="materialList" ref="selectionTable" max-height="450" row-key="id" @selection-change="handleMaterialSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<!-- <el-table-column label="分类名称" align="center" prop="materialTypeName" />-->
<!-- <el-table-column label="货位类型" align="center" prop="warehouseLocationType" />-->
......@@ -431,6 +431,7 @@ export default {
total: 0,
// 物料入库表格数据
materialPutawayList: [],
selectedMaterialMap: new Map(),
// 弹出层标题
title: "",
// 是否显示弹出层
......@@ -528,23 +529,6 @@ export default {
vendorChange(id, item) {
let vendor = this.materialVendorList.find(v => v.id === id);
item.vendorName = vendor.vendorName;
},
/**
* 物资类型弃用
*/
getTreeTree(){
typeTree().then(response => {
this.typeOptions = response.data
});
},
// 筛选节点
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
// 节点单击事件
handleNodeClick(data) {
},
/** 查询仓库列表 */
getWarehouseList() {
......@@ -561,18 +545,23 @@ export default {
/** 打开物料列表 */
openMaterialModel() {
this.open1 = true
// 打开对话框时初始化已选数据
this.initializeSelectedMaterials()
this.getMaterialList()
},
/** 搜索按钮操作 */
handleMaterialQuery() {
this.queryMaterialParams.pageNum = 1;
this.getMaterialList();
},
/** 重置按钮操作 */
resetMaterialQuery() {
this.resetForm("queryMaterialForm");
this.handleMaterialQuery();
/** 初始化已选物料数据 */
initializeSelectedMaterials() {
// 将当前入库明细列表中的物料添加到已选Map中
this.selectedMaterialMap.clear()
this.form.putawayInfoList.forEach(item => {
const materialId = item.materialId || item.id
console.log('item' , item)
if (materialId) {
this.selectedMaterialMap.set(materialId, item)
}
})
},
/** 查询物资列表 */
getMaterialList() {
this.materialLoading = true;
......@@ -580,41 +569,122 @@ export default {
this.materialList = response.rows;
this.materialTotal = response.total;
this.materialLoading = false;
}).then(() =>{
}).then(() => {
this.$nextTick(() => {
// 清空临时勾选
this.tempSelection = [];
// 手动设置勾选(匹配外部已选数据)
this.materialList.forEach(row => {
const isSelected = this.form.putawayInfoList.some(item => item.id === row.id || item.materialId === row.id);
this.$refs.selectionTable.toggleRowSelection(row, isSelected);
});
// 恢复选择状态
this.restoreMaterialSelection();
});
})
},
/** 恢复物料选择状态 */
restoreMaterialSelection() {
if (!this.$refs.selectionTable || !this.materialList.length) return;
// 先清空所有选择
this.$refs.selectionTable.clearSelection();
// 获取所有需要选择的物料ID
const selectedIds = new Set();
this.form.putawayInfoList.forEach(item => {
const materialId = item.materialId || item.id;
if (materialId) {
selectedIds.add(materialId);
}
});
// 批量设置选择状态
this.$nextTick(() => {
this.materialList.forEach(row => {
if (selectedIds.has(row.id)) {
this.$refs.selectionTable.toggleRowSelection(row, true);
}
});
});
},
// 多选框选中数据
handleMaterialSelectionChange(selection) {
this.tempSelection = selection
this.tempSelection = selection;
// 更新已选数据的Map
const currentPageIds = new Set(this.materialList.map(row => row.id));
// 移除当前页中取消选择的行
console.log('currentPageIds--------->',currentPageIds);
console.log('this.selectedMaterialMap--------->',this.selectedMaterialMap);
console.log('selection--------->',selection);
for (let id of this.selectedMaterialMap.keys()) {
if (currentPageIds.has(id) && !selection.some(row => row.id === id)) {
console.log('delete-------->', id)
this.selectedMaterialMap.delete(id);
}
}
// 添加当前页中新选择的行
selection.forEach(row => {
// 如果物料已经在入库明细中,保留原有数据
if (this.selectedMaterialMap.has(row.id)) {
const existingItem = this.selectedMaterialMap.get(row.id);
// 保留入库数量、单价等编辑过的数据
this.selectedMaterialMap.set(row.id, {
...row,
putawayNumber: existingItem.putawayNumber || 0.01,
putawayPrice: existingItem.putawayPrice || 0.01,
putawayMoney: existingItem.putawayMoney || 0.01,
vendorId: existingItem.vendorId,
vendorName: existingItem.vendorName
});
} else {
// 新选择的物料,设置默认值
this.selectedMaterialMap.set(row.id, {
...row,
materialId: row.id,
putawayNumber: 0.01,
putawayPrice: 0.01,
putawayMoney: 0.01,
vendorId: row.vendorId,
vendorName: row.vendorName
});
}
});
},
// 将选中物料添加至入库明细列表
confirmSelection() {
// 删除 a 中多余数据 用 filter() + some() 保留 a 中与 b 的 id 匹配的项。
// 添加 b 中新增数据 用 filter() 找出 b 中 id 不在 a 中的项。
// 合并结果使用展开运算符 ... 合并两个数组。
this.form.putawayInfoList = [
...this.form.putawayInfoList.filter(itemA => this.tempSelection.some(itemB => itemB.id === itemA.id || itemA.materialId === itemB.id)),
...this.tempSelection.filter(itemB => !this.form.putawayInfoList.some(itemA => itemA.id === itemB.id || itemA.materialId === itemB.id))
]
this.open1 = false
// 使用Map中的数据更新入库明细列表
this.form.putawayInfoList = Array.from(this.selectedMaterialMap.values());
this.open1 = false;
this.resetMaterialQuery()
// 重新计算总金额
this.putawayChange();
},
/** 搜索按钮操作 */
handleMaterialQuery() {
this.queryMaterialParams.pageNum = 1;
this.getMaterialList();
},
/** 重置按钮操作 */
resetMaterialQuery() {
this.resetForm("queryMaterialForm");
this.handleMaterialQuery();
},
// 入库明细删除
handleRowDelete(row) {
this.form.putawayInfoList = this.form.putawayInfoList.filter(item => item.id !== row.id);
this.putawayChange()
const materialId = row.materialId || row.id;
// 从Map中移除
this.selectedMaterialMap.delete(materialId);
// 更新入库明细列表
this.form.putawayInfoList = this.form.putawayInfoList.filter(item => {
const itemMaterialId = item.materialId || item.id;
return itemMaterialId !== materialId;
});
this.putawayChange();
},
// 取消按钮
// 取消物料选择
cancelMaterial() {
this.open1 = false;
// 可选:清空临时选择,但保留已确认的选择
this.tempSelection = [];
this.resetMaterialQuery()
},
// 入库数量变动
putawayChange() {
......@@ -652,6 +722,7 @@ export default {
createTime: formatDate(new Date().getTime()),
putawayInfoList: []
};
this.selectedMaterialMap.clear();
this.resetForm("form");
},
/** 搜索按钮操作 */
......@@ -677,6 +748,9 @@ export default {
this.title = "添加物料入库";
this.getWarehouseList()
this.getVendorList()
console.log('this.selectedMaterialMap', this.selectedMaterialMap)
console.log('this.form.putawayInfoList', this.form.putawayInfoList)
console.log('this.this.tempSelection', this.tempSelection)
},
/** 详情按钮操作 */
handleDetail(row) {
......@@ -699,6 +773,8 @@ export default {
this.title = "修改物料入库";
this.getWarehouseList()
this.getVendorList()
// 初始化已选物料数据
this.initializeSelectedMaterials();
});
},
/** 提交按钮 */
......@@ -780,7 +856,6 @@ export default {
},
/** 导出按钮操作 */
handleExport() {
console.log('this.queryParams', this.queryParams);
this.download('business/materialPutawayInfo/export', {
...this.queryParams
}, `入库单明细_${new Date().getTime()}.xlsx`)
......
......@@ -513,12 +513,12 @@ export default {
this.form.returnsInfoBoList = this.materialList
let isTrue = false;
this.form.returnsInfoBoList.forEach(item => {
if (item.returnsNumber < 0.1) {
if (item.returnsNumber < 0.01) {
isTrue = true;
}
})
if (isTrue) {
this.$modal.msgError('退货数量不能小于0.1')
this.$modal.msgError('退货数量不能小于0.01')
this.buttonLoading = false;
return
}
......
......@@ -752,7 +752,7 @@ export default {
});
},
getCarList() {
listCar({ pageNum: 1, pageSize: 99 }).then(res=>{
listCar({ pageNum: 1, pageSize: 9999 }).then(res=>{
this.carList = res.rows
})
},
......
......@@ -404,7 +404,7 @@ export default {
/** 查询维修项目列表 */
getMaintainList() {
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.total = response.total;
this.loading = false;
......@@ -417,7 +417,7 @@ export default {
},
/** 查询人员-人员列表 */
getMaintainUserList() {
listUser({ type: 1, pageNum: 1, pageSize: 1000 }).then(response => {
listUser({ pageNum: 1, pageSize: 1000 }).then(response => {
this.maintainUserList = response.rows;
});
},
......
<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 @@
<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="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">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.settlementTime, '{y}-{m}-{d}') }}</span>
......@@ -269,6 +271,7 @@
<el-form-item label="收款时间" prop="collectionTime">
<el-date-picker clearable
v-model="form.collectionTime"
:disabled="isQrPay"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择收款时间">
......@@ -277,12 +280,12 @@
</el-col>
<el-col :span="6">
<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-col>
<el-col :span="6">
<el-form-item label="收款流水号" prop="collectionSerialNumber">
<el-input v-model="form.collectionSerialNumber" placeholder="请输入收款流水号" />
<el-form-item label="交易流水号" prop="collectionSerialNumber">
<el-input v-model="form.collectionSerialNumber" :disabled="isQrPay" placeholder="请输入交易流水号" />
</el-form-item>
</el-col>
</el-row>
......@@ -303,11 +306,25 @@
</el-form>
</el-scrollbar>
<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 @click="cancel"> </el-button>
</div>
</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-scrollbar style="height: 75vh;">
......@@ -392,7 +409,7 @@
import {
delSettlementMaintain,
getSettlementMaintain,
listSettlementMaintain,
listSettlementMaintain, paySettlementMaintain,
receiptSettlementMaintain
} from '@/api/business/settlementMaintain'
......@@ -403,6 +420,7 @@ export default {
return {
// 按钮loading
buttonLoading: false,
payButtonLoading: false,
// 遮罩层
loading: true,
// 选中数组
......@@ -422,6 +440,8 @@ export default {
// 是否显示弹出层
open: false,
open1: false,
open2: false,
isQrPay: false,
// 查询参数
queryParams: {
pageNum: 1,
......@@ -433,6 +453,10 @@ export default {
},
// 表单参数
form: {},
payForm: {
id: undefined,
paymentAccount: undefined,
},
// 表单校验
rules: {
collectionTime: [
......@@ -444,8 +468,13 @@ export default {
collectionSerialNumber: [
{ required: true, message: "收款流水号不能为空", trigger: "blur" }
],
collectionVoucher: [
{ required: true, message: "收款回执不能为空", trigger: "change" }
// collectionVoucher: [
// { required: true, message: "收款回执不能为空", trigger: "change" }
// ],
},
payRules: {
paymentAccount: [
{ required: true, message: "支付码不能为空", trigger: "blur" }
],
}
};
......@@ -526,6 +555,40 @@ export default {
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() {
this.reset();
......
......@@ -119,13 +119,13 @@
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<el-form-item label="支付方式" prop="paymentMethod">
<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-select>
</el-form-item>
</el-col>
<!-- <el-col :span="6">-->
<!-- <el-form-item label="支付方式" prop="paymentMethod">-->
<!-- <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-select>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="6">
<el-form-item label="结算时间" prop="settlementTime">
<el-date-picker clearable
......@@ -280,9 +280,9 @@ export default {
paymentAccountName: [
{ required: true, message: "账号名称不能为空", trigger: "blur" }
],
paymentVoucher: [
{ required: true, message: "付款凭证不能为空", trigger: "blur" }
],
// paymentVoucher: [
// { required: true, message: "付款凭证不能为空", trigger: "blur" }
// ],
},
};
},
......@@ -378,7 +378,7 @@ export default {
this.buttonLoading = false;
}).finally(() => {
this.buttonLoading = false;
this.$tab.closeOpenPage({path: '/settlement/settlementMaintain?clientType=1'})
this.$tab.closeOpenPage({path: '/settlement/settlementMaintain?clientType=2'})
});
}
});
......
......@@ -43,6 +43,15 @@
v-hasPermi="['business:settlementMaterial:add']"
>结算</el-button>
</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>
</el-row>
......@@ -447,6 +456,7 @@ export default {
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
// 如果没有选中任何项,直接禁用按钮
if (selection.length === 0) {
this.multiple = true; // 禁用按钮
......@@ -593,8 +603,9 @@ export default {
/** 导出按钮操作 */
handleExport() {
this.download('business/materialPicking/export', {
...this.queryParams
}, `materialPicking_${new Date().getTime()}.xlsx`)
...this.queryParams,
ids: this.ids
}, `供应商铺货结算.xlsx`)
}
}
};
......
......@@ -19,6 +19,7 @@
auto-complete="off"
placeholder="密码"
@keyup.enter.native="handleLogin"
@input="checkPasswordStrength"
>
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input>
......@@ -120,6 +121,26 @@ export default {
this.getCookie();
},
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() {
getCodeImg().then(res => {
this.captchaEnabled = res.data.captchaEnabled === undefined ? true : res.data.captchaEnabled;
......@@ -142,6 +163,11 @@ export default {
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
// 再次确认密码强度
if (!this.isPasswordStrong) {
this.$message.error("密码强度不足,请确保包含大小写字母、数字和特殊字符");
return;
}
this.loading = true;
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 });
......
......@@ -172,6 +172,11 @@
</el-select>
</el-form-item>
</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-form>
<div slot="footer" class="dialog-footer">
......@@ -284,7 +289,8 @@ export default {
phone: undefined,
email: undefined,
status: "0",
type: undefined
type: undefined,
terminalCode: undefined,
};
this.resetForm("form");
},
......
......@@ -260,7 +260,7 @@
</el-col>
<el-col :span="12">
<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-col>
</el-row>
......@@ -385,7 +385,30 @@ export default {
dicts: ['sys_normal_disable', 'sys_user_sex'],
components: { Treeselect },
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 {
strengthClass: 'weak',
strengthText: '',
isPasswordStrong: false,
// 遮罩层
loading: true,
// 选中数组
......@@ -468,7 +491,8 @@ export default {
],
password: [
{ 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: [
{
......@@ -501,6 +525,40 @@ export default {
});
},
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() {
this.loading = true;
......@@ -625,13 +683,13 @@ export default {
confirmButtonText: "确定",
cancelButtonText: "取消",
closeOnClickModal: false,
inputPattern: /^.{5,20}$/,
inputErrorMessage: "用户密码长度必须介于 5 和 20 之间"
inputPattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,20}$/,
inputErrorMessage: "密码必须为8-20个字符,且包含大写字母、小写字母、数字和特殊字符(@$!%*?&)"
}).then(({ value }) => {
resetUserPwd(row.userId, value).then(response => {
this.$modal.msgSuccess("修改成功,新密码是:" + value);
});
}).catch(() => {});
resetUserPwd(row.userId, value).then(response => {
this.$modal.msgSuccess("修改成功,新密码是:" + value);
});
}).catch(() => {});
},
/** 分配角色操作 */
handleAuthRole: function(row) {
......