feat(quotation): 添加部署工具类并优化折扣配置功能
- 在DateTimeUtil中新增parse方法支持自定义格式解析 - 新增DeployTest类实现SSH文件部署功能 - 将多个VO类的id字段从Integer改为Long类型 - 重构DiscountConfigController中的保存逻辑 - 在ModelConfigItemLanguageVO中添加创建时间和更新时间字段 - 修改相关Mapper XML文件以支持新增字段查询 - 优化折扣配置的数据持久化流程 - 修复折扣查询时的状态过滤条件
This commit is contained in:
parent
d1f3aa8fd2
commit
85987c0b01
|
|
@ -7,7 +7,7 @@ import lombok.experimental.Accessors;
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class DictionaryItemTranslateVO {
|
public class DictionaryItemTranslateVO {
|
||||||
|
|
||||||
private Integer id;
|
private Long id;
|
||||||
|
|
||||||
//语言代码
|
//语言代码
|
||||||
private String code;
|
private String code;
|
||||||
|
|
@ -19,7 +19,7 @@ public class DictionaryItemTranslateVO {
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
//字典值id
|
//字典值id
|
||||||
private Integer dictionaryItemId;
|
private Long dictionaryItemId;
|
||||||
|
|
||||||
//字典值编号
|
//字典值编号
|
||||||
private String dictionaryItemCode;
|
private String dictionaryItemCode;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import java.time.LocalDateTime;
|
||||||
@Data
|
@Data
|
||||||
public class DictionaryItemVO {
|
public class DictionaryItemVO {
|
||||||
|
|
||||||
private Integer id;
|
private Long id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典值名称
|
* 字典值名称
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import java.time.LocalDateTime;
|
||||||
@Data
|
@Data
|
||||||
public class ModelConfigVO {
|
public class ModelConfigVO {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模块名称
|
* 模块名称
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
package com.nflg.mobilebroken.common.pojo.vo.quotation;
|
package com.nflg.mobilebroken.common.pojo.vo.quotation;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|
@ -51,5 +54,25 @@ public class ModelConfigItemLanguageVO {
|
||||||
*/
|
*/
|
||||||
private String imageUrl;
|
private String imageUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人
|
||||||
|
*/
|
||||||
|
private String createBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人
|
||||||
|
*/
|
||||||
|
private String updateBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
private List<ModelConfigItemLanguageVO> children;
|
private List<ModelConfigItemLanguageVO> children;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,10 @@ public class DateTimeUtil {
|
||||||
return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
|
return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static LocalDateTime parse(String dateStr,String format) {
|
||||||
|
return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(format));
|
||||||
|
}
|
||||||
|
|
||||||
public static int between(LocalDate date1, LocalDate date2) {
|
public static int between(LocalDate date1, LocalDate date2) {
|
||||||
return (int) ChronoUnit.DAYS.between(date1, date2) + 1;
|
return (int) ChronoUnit.DAYS.between(date1, date2) + 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.nflg.mobilebroken.quotation.controller.admin;
|
package com.nflg.mobilebroken.quotation.controller.admin;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
@ -12,26 +13,21 @@ import com.nflg.mobilebroken.common.pojo.request.ModelConfigSearchRequest;
|
||||||
import com.nflg.mobilebroken.common.pojo.request.ModelPriceSaveRequest;
|
import com.nflg.mobilebroken.common.pojo.request.ModelPriceSaveRequest;
|
||||||
import com.nflg.mobilebroken.common.pojo.vo.DynamicHeaderVO;
|
import com.nflg.mobilebroken.common.pojo.vo.DynamicHeaderVO;
|
||||||
import com.nflg.mobilebroken.common.pojo.vo.ModelDiscountConfigVO;
|
import com.nflg.mobilebroken.common.pojo.vo.ModelDiscountConfigVO;
|
||||||
|
import com.nflg.mobilebroken.common.util.AdminUserUtil;
|
||||||
import com.nflg.mobilebroken.common.util.DateTimeUtil;
|
import com.nflg.mobilebroken.common.util.DateTimeUtil;
|
||||||
import com.nflg.mobilebroken.common.util.NumberUtil;
|
import com.nflg.mobilebroken.common.util.NumberUtil;
|
||||||
import com.nflg.mobilebroken.quotation.controller.ControllerBase;
|
import com.nflg.mobilebroken.quotation.controller.ControllerBase;
|
||||||
import com.nflg.mobilebroken.repository.entity.DictionaryItem;
|
import com.nflg.mobilebroken.repository.entity.*;
|
||||||
import com.nflg.mobilebroken.repository.entity.QuotationModelDiscountArea;
|
import com.nflg.mobilebroken.repository.service.*;
|
||||||
import com.nflg.mobilebroken.repository.entity.QuotationModelPriceItemArea;
|
|
||||||
import com.nflg.mobilebroken.repository.service.IDictionaryItemService;
|
|
||||||
import com.nflg.mobilebroken.repository.service.IQuotationModelDiscountAreaService;
|
|
||||||
import com.nflg.mobilebroken.repository.service.IQuotationModelDiscountService;
|
|
||||||
import com.nflg.mobilebroken.repository.service.IQuotationModelPriceItemAreaService;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -53,6 +49,9 @@ public class DiscountConfigController extends ControllerBase {
|
||||||
@Resource
|
@Resource
|
||||||
private IQuotationModelDiscountAreaService discountAreaService;
|
private IQuotationModelDiscountAreaService discountAreaService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IQuotationModelDiscountApplyService discountApplyService;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private IQuotationModelPriceItemAreaService priceItemAreaService;
|
private IQuotationModelPriceItemAreaService priceItemAreaService;
|
||||||
|
|
||||||
|
|
@ -103,7 +102,7 @@ public class DiscountConfigController extends ControllerBase {
|
||||||
List<QuotationModelDiscountArea> discountAreas = discountAreaService.lambdaQuery()
|
List<QuotationModelDiscountArea> discountAreas = discountAreaService.lambdaQuery()
|
||||||
.in(QuotationModelDiscountArea::getDiscountId, pdata.getRecords().stream().map(ModelDiscountConfigVO::getId).collect(Collectors.toList()))
|
.in(QuotationModelDiscountArea::getDiscountId, pdata.getRecords().stream().map(ModelDiscountConfigVO::getId).collect(Collectors.toList()))
|
||||||
.list();
|
.list();
|
||||||
return ApiResult.success(pdata,data->{
|
return ApiResult.success(pdata, data -> {
|
||||||
Map<String, Object> map = objectMapper.convertValue(data, new TypeReference<>() {
|
Map<String, Object> map = objectMapper.convertValue(data, new TypeReference<>() {
|
||||||
});
|
});
|
||||||
areas.forEach(area -> {
|
areas.forEach(area -> {
|
||||||
|
|
@ -127,12 +126,55 @@ public class DiscountConfigController extends ControllerBase {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * 保存
|
* 保存
|
||||||
// */
|
*/
|
||||||
// @Transactional
|
@Transactional
|
||||||
// @PostMapping("/save")
|
@PostMapping("/save")
|
||||||
// public ApiResult<Void> save(@Valid @RequestBody List<ModelDiscountSaveRequest> datas) {
|
public ApiResult<Void> save(@RequestBody @NotEmpty List<Map<String, Object>> datas) {
|
||||||
//
|
List<Long> modelIds = datas.stream().map(data -> (Long) data.get("modelId")).collect(Collectors.toList());
|
||||||
// }
|
List<QuotationModelDiscount> discounts = new ArrayList<>();
|
||||||
|
List<QuotationModelDiscountArea> discountAreas = new ArrayList<>();
|
||||||
|
List<QuotationModelDiscountApply> discountApplies = new ArrayList<>();
|
||||||
|
datas.forEach(data -> {
|
||||||
|
Long modelId = (Long) data.get("modelId");
|
||||||
|
QuotationModelDiscount discount = new QuotationModelDiscount()
|
||||||
|
.setId(IdUtil.getSnowflakeNextId())
|
||||||
|
.setModelId(modelId)
|
||||||
|
.setCreateById(AdminUserUtil.getUserId())
|
||||||
|
.setCreateBy(AdminUserUtil.getUserName())
|
||||||
|
.setCreateTime(LocalDateTime.now());
|
||||||
|
discounts.add(discount);
|
||||||
|
List<DictionaryItem> areas = dictionaryItemService.getListByDictionaryCode(Constant.DICTIONARY_DIRECT_SALES_CATEGORY);
|
||||||
|
for (DictionaryItem area : areas) {
|
||||||
|
if (data.containsKey(area.getCode() + "_ratio")) {
|
||||||
|
QuotationModelDiscountArea discountArea = new QuotationModelDiscountArea()
|
||||||
|
.setDiscountId(discount.getId())
|
||||||
|
.setAreaId(area.getId())
|
||||||
|
.setRatio(new BigDecimal(data.get(area.getCode() + "_ratio").toString()))
|
||||||
|
.setDiscountStartDate(DateTimeUtil.parse(data.get(area.getCode() + "_start").toString(), "yyyy-MM-dd"))
|
||||||
|
.setDiscountEndDate(DateTimeUtil.parse(data.get(area.getCode() + "_end").toString(), "yyyy-MM-dd"));
|
||||||
|
discountAreas.add(discountArea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Integer[] userIds = (Integer[]) data.get("apply");
|
||||||
|
for (Integer userId : userIds) {
|
||||||
|
discountApplies.add(new QuotationModelDiscountApply()
|
||||||
|
.setDiscountId(discount.getId())
|
||||||
|
.setSourceId(userId)
|
||||||
|
.setCreateById(AdminUserUtil.getUserId())
|
||||||
|
.setCreateBy(AdminUserUtil.getUserName())
|
||||||
|
.setCreateTime(LocalDateTime.now())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
discountService.lambdaUpdate()
|
||||||
|
.set(QuotationModelDiscount::getDiscountStatus, 2)
|
||||||
|
.in(QuotationModelDiscount::getModelId, modelIds)
|
||||||
|
.update();
|
||||||
|
discountService.saveBatch(discounts);
|
||||||
|
discountAreaService.saveBatch(discountAreas);
|
||||||
|
discountApplyService.saveBatch(discountApplies);
|
||||||
|
return ApiResult.success();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,332 @@
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.jcraft.jsch.*;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.file.DirectoryStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class DeployTest {
|
||||||
|
|
||||||
|
private static final String serviceName = "quotation";
|
||||||
|
private static final String localPath = System.getProperty("user.dir") + "//target//";
|
||||||
|
private static final String remotePath = "/mnt/mobilebroken/" + serviceName + "/";
|
||||||
|
private static final String jarName = "nflg-mobilebroken-" + serviceName + "-1.0.0-SNAPSHOT.jar";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void DeployToSit() throws Exception {
|
||||||
|
SSHUtil sshUtil = new SSHUtil();
|
||||||
|
sshUtil.connect("192.168.163.73", 22, "root", "NFcfs2025");
|
||||||
|
//处理主jar包
|
||||||
|
handleFile(sshUtil, localPath + jarName, remotePath + jarName);
|
||||||
|
//处理字体目录
|
||||||
|
// handleDir(sshUtil, localPath, remotePath, "fonts");
|
||||||
|
//处理lib目录
|
||||||
|
// handleDir(sshUtil, localPath, remotePath, "lib");
|
||||||
|
//执行脚本启动服务
|
||||||
|
sshUtil.exec("cd " + remotePath + " && ./restart.sh");
|
||||||
|
sshUtil.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleDir(SSHUtil sshUtil, String localPath, String remotePath, String dirName) throws Exception {
|
||||||
|
printInfo("处理目录:" + dirName);
|
||||||
|
List<Path> files = getFileList(localPath + dirName);
|
||||||
|
for (Path file : files) {
|
||||||
|
handleFile(sshUtil, file.toString(), remotePath +dirName+ "/" + file.getFileName().toString());
|
||||||
|
}
|
||||||
|
printInfo("处理目录完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Path> getFileList(String folderPath) throws IOException {
|
||||||
|
Path path = Paths.get(folderPath);
|
||||||
|
if (Files.exists(path) && Files.isDirectory(path)) {
|
||||||
|
List<Path> fileList = new ArrayList<>();
|
||||||
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) {
|
||||||
|
for (Path entry : stream) {
|
||||||
|
fileList.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fileList;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleFile(SSHUtil sshUtil, String localPath, String remotePath) throws Exception {
|
||||||
|
BasicFileAttributes localFileAttr = Files.readAttributes(Paths.get(localPath), BasicFileAttributes.class);
|
||||||
|
printInfo("处理文件:{},大小:{}", localPath, getSize(localFileAttr.size()));
|
||||||
|
if (sshUtil.fileExists(remotePath)) {
|
||||||
|
if (!StrUtil.equals(getRemoteFileMD5(sshUtil, remotePath), getLocalFileMD5(localPath), true)) {
|
||||||
|
printError("文件不一致,开始上传");
|
||||||
|
sshUtil.uploadFile(localPath, remotePath);
|
||||||
|
} else {
|
||||||
|
printInfo("文件一致");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printError("文件不存在,开始上传");
|
||||||
|
sshUtil.uploadFile(localPath, remotePath);
|
||||||
|
}
|
||||||
|
printInfo("处理完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRemoteFileMD5(SSHUtil sshUtil, String remotePath) throws Exception {
|
||||||
|
String md5 = StrUtil.subPre(sshUtil.execWithReturn("md5sum " + remotePath), 32);
|
||||||
|
printInfo("远程文件MD5为" + md5);
|
||||||
|
return md5;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLocalFileMD5(String localPath) throws Exception {
|
||||||
|
String md5 = DigestUtils.md5Hex(new FileInputStream(localPath));
|
||||||
|
printInfo("本地文件MD5为" + md5);
|
||||||
|
return md5;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSize(long size) {
|
||||||
|
long s = 1024;
|
||||||
|
if (size < s) {
|
||||||
|
return size + "B";
|
||||||
|
}
|
||||||
|
s = s * 1024;
|
||||||
|
if (size < s) {
|
||||||
|
return String.format("%.2f", size / 1.00 / 1024) + "KB";
|
||||||
|
}
|
||||||
|
s = s * 1024;
|
||||||
|
if (size < s) {
|
||||||
|
return String.format("%.2f", size / 1.00 / 1024 / 1024) + "MB";
|
||||||
|
}
|
||||||
|
s = s * 1024;
|
||||||
|
return String.format("%.2f", size / 1.00 / 1024 / 1024 / 1024) + "GB";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SSHUtil {
|
||||||
|
|
||||||
|
private Session session;
|
||||||
|
private ChannelSftp channelSftp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 建立SSH连接
|
||||||
|
*/
|
||||||
|
public void connect(String host, int port, String userName, String password) throws JSchException {
|
||||||
|
printInfo("开始连接服务器,ip:{},port:{},userName:{},password:{}", host, port, userName, password);
|
||||||
|
JSch jsch = new JSch();
|
||||||
|
session = jsch.getSession(userName, host, port);
|
||||||
|
session.setPassword(password);
|
||||||
|
session.setConfig("StrictHostKeyChecking", "no");
|
||||||
|
session.connect();
|
||||||
|
printInfo("连接成功");
|
||||||
|
|
||||||
|
Channel channel = session.openChannel("sftp");
|
||||||
|
channel.connect();
|
||||||
|
channelSftp = (ChannelSftp) channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行远程命令并返回输出
|
||||||
|
*/
|
||||||
|
public void exec(String command) {
|
||||||
|
printInfo("开始执行命令:{}", command);
|
||||||
|
if (session == null || !session.isConnected()) {
|
||||||
|
throw new IllegalStateException("SSH未连接");
|
||||||
|
}
|
||||||
|
ChannelExec channel = null;
|
||||||
|
SshResultCallback callback = new SshResultCallback() {
|
||||||
|
@Override
|
||||||
|
public void onOutput(String output) {
|
||||||
|
printInfo(false, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onErrorOutput(String errorOutput) {
|
||||||
|
printError(false, errorOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCompleted(int exitStatus) {
|
||||||
|
printInfo("输出完毕,退出状态:" + exitStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Exception e) {
|
||||||
|
printError(false, e.getMessage());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
// 创建执行命令的通道
|
||||||
|
channel = (ChannelExec) session.openChannel("exec");
|
||||||
|
channel.setCommand(command);
|
||||||
|
|
||||||
|
// 获取输入流以读取命令输出
|
||||||
|
InputStream in = channel.getInputStream();
|
||||||
|
InputStream err = channel.getExtInputStream();
|
||||||
|
|
||||||
|
channel.connect();
|
||||||
|
|
||||||
|
// 读取命令输出
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||||
|
BufferedReader errReader = new BufferedReader(new InputStreamReader(err));
|
||||||
|
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
callback.onOutput(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取错误输出
|
||||||
|
String errLine;
|
||||||
|
while ((errLine = errReader.readLine()) != null) {
|
||||||
|
callback.onErrorOutput(errLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取退出状态
|
||||||
|
int exitStatus = channel.getExitStatus();
|
||||||
|
callback.onCompleted(exitStatus);
|
||||||
|
} catch (JSchException | IOException e) {
|
||||||
|
callback.onError(e);
|
||||||
|
} finally {
|
||||||
|
if (channel != null) {
|
||||||
|
channel.disconnect();
|
||||||
|
}
|
||||||
|
if (session != null) {
|
||||||
|
session.disconnect();
|
||||||
|
}
|
||||||
|
printInfo("执行命令完毕");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String execWithReturn(String command) throws Exception {
|
||||||
|
printInfo("开始执行命令:{}", command);
|
||||||
|
if (session == null || !session.isConnected()) {
|
||||||
|
throw new IllegalStateException("SSH未连接");
|
||||||
|
}
|
||||||
|
ChannelExec channel = null;
|
||||||
|
BufferedReader reader = null;
|
||||||
|
try {
|
||||||
|
// 创建执行命令的通道
|
||||||
|
channel = (ChannelExec) session.openChannel("exec");
|
||||||
|
channel.setCommand(command);
|
||||||
|
// 获取输入流以读取命令输出
|
||||||
|
InputStream in = channel.getInputStream();
|
||||||
|
InputStream err = channel.getExtInputStream();
|
||||||
|
channel.connect();
|
||||||
|
reader = new BufferedReader(new InputStreamReader(in));
|
||||||
|
String data = reader.readLine();
|
||||||
|
// log.info("执行命令成功,返回数据:" + data);
|
||||||
|
BufferedReader errReader = new BufferedReader(new InputStreamReader(err));
|
||||||
|
String errData = errReader.readLine();
|
||||||
|
// log.info("执行命令失败,返回数据:" + errData);
|
||||||
|
if (StrUtil.isBlank(errData)) {
|
||||||
|
return data;
|
||||||
|
} else {
|
||||||
|
errReader.close();
|
||||||
|
throw new Exception("执行命令失败:" + errData);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (channel != null) {
|
||||||
|
channel.disconnect();
|
||||||
|
}
|
||||||
|
if (reader != null) {
|
||||||
|
try {
|
||||||
|
reader.close();
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printInfo("执行命令完毕");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查远程文件是否存在
|
||||||
|
*/
|
||||||
|
public boolean fileExists(String remotePath) throws SftpException {
|
||||||
|
try {
|
||||||
|
channelSftp.stat(remotePath);
|
||||||
|
return true;
|
||||||
|
} catch (SftpException e) {
|
||||||
|
if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
*/
|
||||||
|
public void uploadFile(String localPath, String remotePath) throws SftpException {
|
||||||
|
printInfo("开始上传本地文件{}到远程{}", localPath, remotePath);
|
||||||
|
channelSftp.put(localPath, remotePath);
|
||||||
|
printInfo("上传完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭连接
|
||||||
|
*/
|
||||||
|
public void disconnect() {
|
||||||
|
if (channelSftp != null) {
|
||||||
|
channelSftp.disconnect();
|
||||||
|
}
|
||||||
|
if (session != null) {
|
||||||
|
session.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface SshResultCallback {
|
||||||
|
void onOutput(String output);
|
||||||
|
|
||||||
|
void onErrorOutput(String errorOutput);
|
||||||
|
|
||||||
|
void onCompleted(int exitStatus);
|
||||||
|
|
||||||
|
void onError(Exception e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printError(String msg) {
|
||||||
|
if (StrUtil.isNotBlank(msg)) {
|
||||||
|
System.out.println(red + msg + reset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printError(boolean addTime, String msg) {
|
||||||
|
if (addTime) {
|
||||||
|
System.out.println(red + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + " " + msg + reset);
|
||||||
|
} else {
|
||||||
|
System.out.println(red + msg + reset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printInfo(String msg) {
|
||||||
|
printInfo(true, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printInfo(boolean addTime, String msg) {
|
||||||
|
if (addTime) {
|
||||||
|
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + " " + msg);
|
||||||
|
} else {
|
||||||
|
System.out.println(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printInfo(String format, Object... args) {
|
||||||
|
printInfo(true, format, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printInfo(boolean addTime, String format, Object... args) {
|
||||||
|
if (addTime) {
|
||||||
|
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + " " + StrUtil.format(format, args));
|
||||||
|
} else {
|
||||||
|
System.out.println(StrUtil.format(format, args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String red = "\u001B[31m";
|
||||||
|
public static final String reset = "\u001B[0m";
|
||||||
|
}
|
||||||
|
|
@ -28,8 +28,8 @@ public class QuotationModelDiscount implements Serializable {
|
||||||
/**
|
/**
|
||||||
* 流水号
|
* 流水号
|
||||||
*/
|
*/
|
||||||
@TableId(value = "id", type = IdType.AUTO)
|
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||||
private Integer id;
|
private Long id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 机型编号
|
* 机型编号
|
||||||
|
|
|
||||||
|
|
@ -28,13 +28,13 @@ public class QuotationModelDiscountApply implements Serializable {
|
||||||
/**
|
/**
|
||||||
* 主键
|
* 主键
|
||||||
*/
|
*/
|
||||||
@TableId(value = "id", type = IdType.AUTO)
|
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||||
private Integer id;
|
private Long id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 折扣ID
|
* 折扣ID
|
||||||
*/
|
*/
|
||||||
private Integer discountId;
|
private Long discountId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户类型 0 内部用户;1 代理商公司
|
* 用户类型 0 内部用户;1 代理商公司
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@
|
||||||
<mapper namespace="com.nflg.mobilebroken.repository.mapper.QuotationModelConfigItemMapper">
|
<mapper namespace="com.nflg.mobilebroken.repository.mapper.QuotationModelConfigItemMapper">
|
||||||
|
|
||||||
<select id="getVOListByConfigId" resultType="com.nflg.mobilebroken.common.pojo.vo.quotation.ModelConfigItemLanguageVO">
|
<select id="getVOListByConfigId" resultType="com.nflg.mobilebroken.common.pojo.vo.quotation.ModelConfigItemLanguageVO">
|
||||||
SELECT mcil.id,mci.parent_id as 'item_parent_id',mci.id as 'item_id',mcil.part_name,mcil.part_remark,mci.*
|
SELECT mcil.id,mci.parent_id as 'item_parent_id',mci.id as 'item_id',mcil.part_name,mcil.part_remark
|
||||||
|
,mcil.create_by,mcil.create_time,mcil.update_by,mcil.update_time,mci.*
|
||||||
FROM quotation_model_config_item mci
|
FROM quotation_model_config_item mci
|
||||||
INNER JOIN quotation_model_config_item_language mcil ON mci.id=mcil.config_item_id
|
INNER JOIN quotation_model_config_item_language mcil ON mci.id=mcil.config_item_id
|
||||||
INNER JOIN `language` l ON l.id=mcil.language_id
|
INNER JOIN `language` l ON l.id=mcil.language_id
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<mapper namespace="com.nflg.mobilebroken.repository.mapper.QuotationModelConfigMapper">
|
<mapper namespace="com.nflg.mobilebroken.repository.mapper.QuotationModelConfigMapper">
|
||||||
|
|
||||||
<select id="search" resultType="com.nflg.mobilebroken.common.pojo.vo.ModelConfigVO">
|
<select id="search" resultType="com.nflg.mobilebroken.common.pojo.vo.ModelConfigVO">
|
||||||
SELECT di.`name` as 'moduleName',ps.`name` AS 'seriesName',pt.`name` as 'typeName',pm.batch_number AS 'modelId'
|
SELECT qmc.id,di.`name` as 'moduleName',ps.`name` AS 'seriesName',pt.`name` as 'typeName',pm.batch_number AS 'modelId'
|
||||||
,pm.`no` as 'modelNo',pm.recommend,pm.image,qmc.config_version,qmc.create_by,qmc.create_time,qmc.update_by
|
,pm.`no` as 'modelNo',pm.recommend,pm.image,qmc.config_version,qmc.create_by,qmc.create_time,qmc.update_by
|
||||||
,qmc.update_time
|
,qmc.update_time
|
||||||
FROM product_model pm
|
FROM product_model pm
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
LEFT JOIN product_type pt on pm.type_number=pt.batch_number AND pt.state=1
|
LEFT JOIN product_type pt on pm.type_number=pt.batch_number AND pt.state=1
|
||||||
LEFT JOIN product_series ps ON pm.series_number=ps.batch_number AND ps.state=1
|
LEFT JOIN product_series ps ON pm.series_number=ps.batch_number AND ps.state=1
|
||||||
LEFT JOIN dictionary_item di ON di.id=pm.module_id
|
LEFT JOIN dictionary_item di ON di.id=pm.module_id
|
||||||
WHERE pm.state=1
|
WHERE pm.state=1 and qmd.discount_status=1
|
||||||
<where>
|
<where>
|
||||||
<if test="request.moduleId!=null">
|
<if test="request.moduleId!=null">
|
||||||
AND pm.module_id=#{request.moduleId}
|
AND pm.module_id=#{request.moduleId}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue