待我审核
parent
dc0159b4eb
commit
01c2d0488d
|
@ -51,7 +51,6 @@ import cn.palmte.work.utils.InterfaceUtil;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
|
* @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
|
||||||
|
@ -189,7 +188,6 @@ public class ProcessController {
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@Transactional
|
@Transactional
|
||||||
public void post(@RequestBody @Valid SaleContractProcessForm form) {
|
public void post(@RequestBody @Valid SaleContractProcessForm form) {
|
||||||
System.out.println(form);
|
|
||||||
SaleContractProcess entity = new SaleContractProcess();
|
SaleContractProcess entity = new SaleContractProcess();
|
||||||
BeanUtils.copyProperties(form, entity, "sealTypes", "applyDate", "applyDept");
|
BeanUtils.copyProperties(form, entity, "sealTypes", "applyDate", "applyDept");
|
||||||
entity.setApplyDate(LocalDate.parse(form.getApplyDate(), formatter));
|
entity.setApplyDate(LocalDate.parse(form.getApplyDate(), formatter));
|
||||||
|
@ -223,7 +221,7 @@ public class ProcessController {
|
||||||
|
|
||||||
private String projectNo;
|
private String projectNo;
|
||||||
private String projectTitle;
|
private String projectTitle;
|
||||||
private String projectCreator;
|
private String applyPersonName;
|
||||||
|
|
||||||
private ProcessType processType;
|
private ProcessType processType;
|
||||||
private ProcessStatus processStatus;
|
private ProcessStatus processStatus;
|
||||||
|
|
|
@ -3,6 +3,7 @@ package cn.palmte.work.model.process;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
import javax.persistence.Convert;
|
import javax.persistence.Convert;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
@ -77,6 +78,14 @@ public class SaleContractProcess {
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private ProcessStatus status;
|
private ProcessStatus status;
|
||||||
|
|
||||||
|
// 当前审核人
|
||||||
|
private String currentAudit;
|
||||||
|
|
||||||
|
// 最后更新时间
|
||||||
|
private LocalDateTime lastUpdateAt;
|
||||||
|
|
||||||
|
private LocalDateTime createAt;
|
||||||
|
|
||||||
// 项目类型
|
// 项目类型
|
||||||
// @Enumerated(EnumType.STRING)
|
// @Enumerated(EnumType.STRING)
|
||||||
// private ProjectType projectType;
|
// private ProjectType projectType;
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
package cn.palmte.work.service;
|
|
||||||
|
|
||||||
import cn.palmte.work.config.UploadProperties;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import sun.misc.BASE64Decoder;
|
|
||||||
import top.jfunc.common.datetime.DatetimeUtils;
|
|
||||||
import top.jfunc.common.utils.CommonUtil;
|
|
||||||
import top.jfunc.common.utils.FileUtil;
|
|
||||||
import java.io.File;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author xiongshiyan at 2020/10/13 , contact me with email yanshixiong@126.com or phone 15208384257
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class UploadService {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(UploadService.class);
|
|
||||||
public static final String DATA_IMAGE_PNG_BASE64 = "data:image/png;base64,";
|
|
||||||
public static final String DATA_IMAGE_JPEG_BASE64 = "data:image/jpeg;base64,";
|
|
||||||
public static final String DATA_IMAGE_JPG_BASE64 = "data:image/jpg;base64,";
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UploadProperties uploadProperties;
|
|
||||||
|
|
||||||
public String upload(String base64Str){
|
|
||||||
String suffix = "png";
|
|
||||||
if (base64Str.contains(DATA_IMAGE_PNG_BASE64)) {
|
|
||||||
base64Str = base64Str.replaceAll(DATA_IMAGE_PNG_BASE64, "");
|
|
||||||
suffix = "png";
|
|
||||||
} else if (base64Str.contains(DATA_IMAGE_JPEG_BASE64)) {
|
|
||||||
base64Str = base64Str.replaceAll(DATA_IMAGE_JPEG_BASE64, "");
|
|
||||||
suffix = "jpeg";
|
|
||||||
}else if (base64Str.contains(DATA_IMAGE_JPG_BASE64)) {
|
|
||||||
base64Str = base64Str.replaceAll(DATA_IMAGE_JPG_BASE64, "");
|
|
||||||
suffix = "jpg";
|
|
||||||
}
|
|
||||||
String uploadPath = uploadProperties.getPath();
|
|
||||||
String uploadPrefix = uploadProperties.getPrefix();
|
|
||||||
String yyyyMMdd = DatetimeUtils.toStr(new Date(), "yyyyMMdd");
|
|
||||||
String saveDir = uploadPath + "/" + yyyyMMdd;
|
|
||||||
FileUtil.makeSureExistDir(saveDir);
|
|
||||||
|
|
||||||
String fileName = CommonUtil.randomString(32) + "." + suffix;
|
|
||||||
String absolutePath = saveDir + "/" + fileName;
|
|
||||||
File file = new File(absolutePath);
|
|
||||||
|
|
||||||
decodeAndWrite(base64Str , file);
|
|
||||||
|
|
||||||
return uploadPrefix + "/" + yyyyMMdd + "/" + fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void decodeAndWrite(String base64Str, File destFile) {
|
|
||||||
try {
|
|
||||||
// Base64解码
|
|
||||||
byte[] bytes = new BASE64Decoder().decodeBuffer(base64Str);
|
|
||||||
for (int i = 0; i < bytes.length; ++i) {
|
|
||||||
if (bytes[i] < 0) {
|
|
||||||
// 调整异常数据
|
|
||||||
bytes[i] += 256;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Files.write(Paths.get(destFile.getAbsolutePath()), bytes);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,305 +0,0 @@
|
||||||
package cn.palmte.work.utils.image;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import sun.misc.BASE64Decoder;
|
|
||||||
import top.jfunc.common.utils.ArrayUtil;
|
|
||||||
import top.jfunc.common.utils.RandomUtil;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.*;
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 滑动验证码相关工具方法
|
|
||||||
*/
|
|
||||||
public class VerifyImageUtil {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(VerifyImageUtil.class);
|
|
||||||
/**
|
|
||||||
* 模板图宽度
|
|
||||||
*/
|
|
||||||
private static int CUT_WIDTH = 50;
|
|
||||||
/**
|
|
||||||
* 模板图高度
|
|
||||||
*/
|
|
||||||
private static int CUT_HEIGHT = 50;
|
|
||||||
/**
|
|
||||||
* 抠图凸起圆心
|
|
||||||
*/
|
|
||||||
private static int CIRCLE_R = 5;
|
|
||||||
/**
|
|
||||||
* 抠图内部矩形填充大小
|
|
||||||
*/
|
|
||||||
private static int RECTANGLE_PADDING = 8;
|
|
||||||
/**
|
|
||||||
* 抠图的边框宽度
|
|
||||||
*/
|
|
||||||
private static int SLIDER_IMG_OUT_PADDING = 1;
|
|
||||||
|
|
||||||
private static int CENTER_INDICATOR = 1;
|
|
||||||
private static int BORDER_INDICATOR = 2;
|
|
||||||
private static int OTHER_INDICATOR = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据传入的file生成验证码图片
|
|
||||||
*/
|
|
||||||
public static VerifyImage getVerifyImage(File file) throws IOException {
|
|
||||||
BufferedImage srcImage = ImageIO.read(file);
|
|
||||||
|
|
||||||
return getVerifyImage(srcImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据转入的流生成验证码图片
|
|
||||||
*/
|
|
||||||
public static VerifyImage getVerifyImage(InputStream inputStream) throws IOException {
|
|
||||||
BufferedImage srcImage = ImageIO.read(inputStream);
|
|
||||||
|
|
||||||
return getVerifyImage(srcImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 以左上角为计数起点
|
|
||||||
*/
|
|
||||||
public static VerifyImage getVerifyImage(BufferedImage srcImage) throws IOException {
|
|
||||||
//1/4=75处,最右减1个方块儿,-5是保守的防止超界
|
|
||||||
int locationX = RandomUtil.randomInt(srcImage.getWidth()/4, srcImage.getWidth()-CUT_WIDTH-5);
|
|
||||||
//距离最下方一个方块,-5是保守的防止超界
|
|
||||||
int locationY = RandomUtil.randomInt(5, srcImage.getHeight()-CUT_HEIGHT-5);
|
|
||||||
|
|
||||||
BufferedImage markImage = new BufferedImage(CUT_WIDTH,CUT_HEIGHT,BufferedImage.TYPE_4BYTE_ABGR);
|
|
||||||
cutImgByTemplate(srcImage, markImage, getBlockData(), locationX, locationY);
|
|
||||||
return new VerifyImage(getImageBASE64(srcImage),
|
|
||||||
getImageBASE64(markImage),
|
|
||||||
locationX,
|
|
||||||
locationY,
|
|
||||||
srcImage.getWidth(),
|
|
||||||
srcImage.getHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成随机滑块形状
|
|
||||||
* <p>
|
|
||||||
* 0 透明像素
|
|
||||||
* 1 滑块像素
|
|
||||||
* 2 阴影像素
|
|
||||||
* @return int[][]
|
|
||||||
*/
|
|
||||||
private static int[][] getBlockData() {
|
|
||||||
int[][] data = new int[CUT_WIDTH][CUT_HEIGHT];
|
|
||||||
SecureRandom random = new SecureRandom();
|
|
||||||
//Random random = new Random();
|
|
||||||
//(x-a)²+(y-b)²=r²
|
|
||||||
//x中心位置左右5像素随机
|
|
||||||
double x1 = RECTANGLE_PADDING + (CUT_WIDTH - 2 * RECTANGLE_PADDING) / 2.0/* - 5 + random.nextInt(10)*/;
|
|
||||||
//y 矩形上边界半径-1像素移动
|
|
||||||
double y1_top = RECTANGLE_PADDING - random.nextInt(3);
|
|
||||||
double y1_bottom = CUT_HEIGHT - RECTANGLE_PADDING + random.nextInt(3);
|
|
||||||
double y1 = random.nextInt(2) == 1 ? y1_top : y1_bottom;
|
|
||||||
|
|
||||||
|
|
||||||
double x2_right = CUT_WIDTH - RECTANGLE_PADDING - CIRCLE_R + random.nextInt(2 * CIRCLE_R - 4);
|
|
||||||
double x2_left = RECTANGLE_PADDING + CIRCLE_R - 2 - random.nextInt(2 * CIRCLE_R - 4);
|
|
||||||
double x2 = random.nextInt(2) == 1 ? x2_right : x2_left;
|
|
||||||
double y2 = RECTANGLE_PADDING + (CUT_HEIGHT - 2 * RECTANGLE_PADDING) / 2.0 - 4 + random.nextInt(10);
|
|
||||||
|
|
||||||
double po = Math.pow(CIRCLE_R, 2);
|
|
||||||
for (int i = 0; i < CUT_WIDTH; i++) {
|
|
||||||
for (int j = 0; j < CUT_HEIGHT; j++) {
|
|
||||||
//矩形区域
|
|
||||||
boolean fill;
|
|
||||||
if ((i >= RECTANGLE_PADDING && i < CUT_WIDTH - RECTANGLE_PADDING)
|
|
||||||
&& (j >= RECTANGLE_PADDING && j < CUT_HEIGHT - RECTANGLE_PADDING)) {
|
|
||||||
data[i][j] = CENTER_INDICATOR;
|
|
||||||
fill = true;
|
|
||||||
} else {
|
|
||||||
data[i][j] = OTHER_INDICATOR;
|
|
||||||
fill = false;
|
|
||||||
}
|
|
||||||
//凸出区域
|
|
||||||
double d3 = Math.pow(i - x1, 2) + Math.pow(j - y1, 2);
|
|
||||||
if (d3 < po) {
|
|
||||||
data[i][j] = CENTER_INDICATOR;
|
|
||||||
} else {
|
|
||||||
if (!fill) {
|
|
||||||
data[i][j] = OTHER_INDICATOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//凹进区域
|
|
||||||
double d4 = Math.pow(i - x2, 2) + Math.pow(j - y2, 2);
|
|
||||||
if (d4 < po) {
|
|
||||||
data[i][j] = OTHER_INDICATOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//边界阴影
|
|
||||||
for (int i = 0; i < CUT_WIDTH; i++) {
|
|
||||||
for (int j = 0; j < CUT_HEIGHT; j++) {
|
|
||||||
//四个正方形边角处理
|
|
||||||
for (int k = 1; k <= SLIDER_IMG_OUT_PADDING; k++) {
|
|
||||||
//左上、右上
|
|
||||||
if (i >= RECTANGLE_PADDING - k && i < RECTANGLE_PADDING
|
|
||||||
&& ((j >= RECTANGLE_PADDING - k && j < RECTANGLE_PADDING)
|
|
||||||
|| (j >= CUT_HEIGHT - RECTANGLE_PADDING - k && j < CUT_HEIGHT - RECTANGLE_PADDING +1))) {
|
|
||||||
data[i][j] = BORDER_INDICATOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
//左下、右下
|
|
||||||
if (i >= CUT_WIDTH - RECTANGLE_PADDING + k - 1 && i < CUT_WIDTH - RECTANGLE_PADDING + 1) {
|
|
||||||
for (int n = 1; n <= SLIDER_IMG_OUT_PADDING; n++) {
|
|
||||||
if (((j >= RECTANGLE_PADDING - n && j < RECTANGLE_PADDING)
|
|
||||||
|| (j >= CUT_HEIGHT - RECTANGLE_PADDING - n && j <= CUT_HEIGHT - RECTANGLE_PADDING ))) {
|
|
||||||
data[i][j] = BORDER_INDICATOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data[i][j] == 1 && j - SLIDER_IMG_OUT_PADDING > 0 && data[i][j - SLIDER_IMG_OUT_PADDING] == 0) {
|
|
||||||
data[i][j - SLIDER_IMG_OUT_PADDING] = BORDER_INDICATOR;
|
|
||||||
}
|
|
||||||
if (data[i][j] == 1 && j + SLIDER_IMG_OUT_PADDING > 0 && j + SLIDER_IMG_OUT_PADDING < CUT_HEIGHT && data[i][j + SLIDER_IMG_OUT_PADDING] == 0) {
|
|
||||||
data[i][j + SLIDER_IMG_OUT_PADDING] = BORDER_INDICATOR;
|
|
||||||
}
|
|
||||||
if (data[i][j] == 1 && i - SLIDER_IMG_OUT_PADDING > 0 && data[i - SLIDER_IMG_OUT_PADDING][j] == 0) {
|
|
||||||
data[i - SLIDER_IMG_OUT_PADDING][j] = BORDER_INDICATOR;
|
|
||||||
}
|
|
||||||
if (data[i][j] == 1 && i + SLIDER_IMG_OUT_PADDING > 0 && i + SLIDER_IMG_OUT_PADDING < CUT_WIDTH && data[i + SLIDER_IMG_OUT_PADDING][j] == 0) {
|
|
||||||
data[i + SLIDER_IMG_OUT_PADDING][j] = BORDER_INDICATOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//最外边界
|
|
||||||
/*for (int i = 0; i < CUT_WIDTH; i++) {
|
|
||||||
data[0][i] = data[CUT_WIDTH-1][i] = 3;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < CUT_HEIGHT; i++) {
|
|
||||||
data[i][0] = data[i][CUT_HEIGHT-1] = 3;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 裁剪区块
|
|
||||||
* 根据生成的滑块形状,对原图和裁剪块进行变色处理
|
|
||||||
* @param oriImage 原图
|
|
||||||
* @param targetImage 裁剪图
|
|
||||||
* @param blockImage 滑块
|
|
||||||
* @param x 裁剪点x
|
|
||||||
* @param y 裁剪点y
|
|
||||||
*/
|
|
||||||
private static void cutImgByTemplate(BufferedImage oriImage, BufferedImage targetImage, int[][] blockImage, int x, int y) {
|
|
||||||
|
|
||||||
print(blockImage);
|
|
||||||
|
|
||||||
for (int i = 0; i < CUT_WIDTH; i++) {
|
|
||||||
for (int j = 0; j < CUT_HEIGHT; j++) {
|
|
||||||
int xx = x + i;
|
|
||||||
int yy = y + j;
|
|
||||||
int rgbFlg = blockImage[i][j];
|
|
||||||
int rgb_ori = oriImage.getRGB(xx, yy);
|
|
||||||
|
|
||||||
// 原图中对应位置变色处理
|
|
||||||
if (rgbFlg == CENTER_INDICATOR) {
|
|
||||||
//中心
|
|
||||||
//抠图上复制对应颜色值
|
|
||||||
targetImage.setRGB(i,j, rgb_ori);
|
|
||||||
//原图对应位置颜色变化[透明50%]
|
|
||||||
oriImage.setRGB(xx, yy, rgb_ori & 0x80ffffff);
|
|
||||||
} else if (rgbFlg == BORDER_INDICATOR) {
|
|
||||||
//边框
|
|
||||||
targetImage.setRGB(i, j, Color.WHITE.getRGB());
|
|
||||||
oriImage.setRGB(xx, yy, Color.GRAY.getRGB());
|
|
||||||
}else if(rgbFlg == OTHER_INDICATOR){
|
|
||||||
//int alpha = 0;
|
|
||||||
targetImage.setRGB(i, j, rgb_ori & 0x00ffffff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private static void print(int[][] blockData){
|
|
||||||
StringBuilder builder = new StringBuilder("\r\n");
|
|
||||||
for (int i = 0; i < blockData.length; i++) {
|
|
||||||
for (int j = 0; j < blockData[i].length; j++) {
|
|
||||||
builder.append(blockData[i][j]).append(" ");
|
|
||||||
}
|
|
||||||
builder.append("\r\n");
|
|
||||||
}
|
|
||||||
logger.debug(builder.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 随机获取一张图片文件
|
|
||||||
*/
|
|
||||||
public static File getRandomFile(File dir) throws IOException {
|
|
||||||
File[] fileList = dir.listFiles();
|
|
||||||
if(ArrayUtil.isEmpty(fileList)){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
List<String> fileNameList = new ArrayList<>(fileList.length);
|
|
||||||
for (File tempFile: fileList){
|
|
||||||
if (tempFile.isDirectory()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (tempFile.getName().endsWith(".png") || tempFile.getName().endsWith(".jpg")){
|
|
||||||
fileNameList.add(tempFile.getAbsolutePath().trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int randomIndex = new SecureRandom().nextInt(fileNameList.size());
|
|
||||||
//int randomIndex = new Random().nextInt(fileNameList.size());
|
|
||||||
return new File(fileNameList.get(randomIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将IMG输出为文件
|
|
||||||
*/
|
|
||||||
public static void writeImg(BufferedImage image, File file) throws IOException {
|
|
||||||
ByteArrayOutputStream bao=new ByteArrayOutputStream();
|
|
||||||
ImageIO.write(image,"png",bao);
|
|
||||||
try (FileOutputStream out = new FileOutputStream(file)){
|
|
||||||
out.write(bao.toByteArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将图片转换为BASE64
|
|
||||||
*/
|
|
||||||
public static String getImageBASE64(BufferedImage image) throws IOException {
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
ImageIO.write(image,"png",out);
|
|
||||||
//转成byte数组
|
|
||||||
byte[] bytes = out.toByteArray();
|
|
||||||
|
|
||||||
return Base64.getEncoder().encodeToString(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将BASE64字符串转换为图片
|
|
||||||
*/
|
|
||||||
public static BufferedImage base64String2Image(String base64String) throws IOException {
|
|
||||||
BASE64Decoder decoder=new BASE64Decoder();
|
|
||||||
byte[] bytes1 = decoder.decodeBuffer(base64String);
|
|
||||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes1);
|
|
||||||
return ImageIO.read(byteArrayInputStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*public static void main(String[] args) throws IOException {
|
|
||||||
VerifyImage verifyImage = VerifyImageUtil.getVerifyImage(new File("C:\\Users\\xiongshiyan\\Desktop\\ssss.png"));
|
|
||||||
System.out.println(verifyImage);
|
|
||||||
VerifyImageUtil.writeImg(VerifyImageUtil.base64String2Image(verifyImage.getSrcImage()), new File("C:\\Users\\xiongshiyan\\Desktop\\src.png"));
|
|
||||||
VerifyImageUtil.writeImg(VerifyImageUtil.base64String2Image(verifyImage.getCutImage()), new File("C:\\Users\\xiongshiyan\\Desktop\\cut.png"));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
# 创建 流程表
|
||||||
|
create table sale_contract_process
|
||||||
|
(
|
||||||
|
id int auto_increment primary key,
|
||||||
|
apply_date date null,
|
||||||
|
apply_dept varchar(255) null,
|
||||||
|
apply_dept_leader_name varchar(255) null,
|
||||||
|
apply_person_name varchar(255) null,
|
||||||
|
apply_person_phone varchar(255) null,
|
||||||
|
client_name varchar(255) null,
|
||||||
|
contract_name varchar(255) null,
|
||||||
|
contract_no varchar(255) null,
|
||||||
|
payment_terms varchar(255) null,
|
||||||
|
project_id int null,
|
||||||
|
project_no varchar(255) null,
|
||||||
|
project_title varchar(255) null comment '标题',
|
||||||
|
seal_types varchar(255) null comment '印章类型',
|
||||||
|
`status` varchar(255) null,
|
||||||
|
tax_rate varchar(255) null,
|
||||||
|
|
||||||
|
current_audit varchar(255) null comment '当前审核人',
|
||||||
|
|
||||||
|
create_at datetime default CURRENT_TIMESTAMP comment '创建时间',
|
||||||
|
last_update_at datetime on update CURRENT_TIMESTAMP comment '最后更新时间'
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
alter table sale_contract_process
|
||||||
|
add current_audit varchar(255) null comment '当前审核人';
|
||||||
|
|
||||||
|
alter table sale_contract_process
|
||||||
|
add create_at datetime default CURRENT_TIMESTAMP comment '创建时间';
|
||||||
|
alter table sale_contract_process
|
||||||
|
add last_update_at datetime on update CURRENT_TIMESTAMP comment '最后更新时间';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,10 @@
|
||||||
.el-table__empty-block {
|
.el-table__empty-block {
|
||||||
height: 60px !important;
|
height: 60px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-radio-button__inner, .el-radio-group {
|
||||||
|
line-height: unset;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="admin-content" id="app">
|
<div class="admin-content" id="app">
|
||||||
|
@ -42,7 +46,7 @@
|
||||||
|
|
||||||
<div class="am-g">
|
<div class="am-g">
|
||||||
<div class="am-u-sm-12 am-u-md-12">
|
<div class="am-u-sm-12 am-u-md-12">
|
||||||
<el-form :inline="true" ref="queryForm" :model="queryForm" label-position="right" label-width="100px">
|
<el-form :inline="true" ref="queryForm" :model="queryForm" label-position="right">
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<el-form-item label="标题">
|
<el-form-item label="标题">
|
||||||
|
@ -64,8 +68,8 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="项目创建者">
|
<el-form-item label="申请人">
|
||||||
<el-input placeholder="请输入项目创建者" v-model="queryForm.projectCreator"></el-input>
|
<el-input placeholder="请输入申请人" v-model="queryForm.applyPersonName"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-button type="primary" @click="queryTable">查询</el-button>
|
<el-button type="primary" @click="queryTable">查询</el-button>
|
||||||
|
@ -75,13 +79,13 @@
|
||||||
|
|
||||||
<el-table border :data="tableData">
|
<el-table border :data="tableData">
|
||||||
<el-table-column type="index" :index="1" label="序号" fixed></el-table-column>
|
<el-table-column type="index" :index="1" label="序号" fixed></el-table-column>
|
||||||
<el-table-column prop="name" label="项目编号" fixed></el-table-column>
|
<el-table-column prop="projectNo" label="项目编号" fixed></el-table-column>
|
||||||
<el-table-column prop="type" label="标题"></el-table-column>
|
<el-table-column prop="projectTitle" label="标题"></el-table-column>
|
||||||
<el-table-column prop="spec" label="流程类型"></el-table-column>
|
<el-table-column prop="processType" label="流程类型"></el-table-column>
|
||||||
<el-table-column prop="param" label="项目创建者"></el-table-column>
|
<el-table-column prop="applyPersonName" label="申请人"></el-table-column>
|
||||||
<el-table-column prop="unit" label="审核状态"></el-table-column>
|
<el-table-column prop="status" label="审核状态"></el-table-column>
|
||||||
<el-table-column prop="amount" label="当前审核人"></el-table-column>
|
<el-table-column prop="amount" label="当前审核人"></el-table-column>
|
||||||
<el-table-column prop="price" label="最后更新时间"></el-table-column>
|
<el-table-column prop="lastUpdateAt" label="最后更新时间"></el-table-column>
|
||||||
|
|
||||||
<el-table-column label="操作" fixed="right" width="180">
|
<el-table-column label="操作" fixed="right" width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
|
@ -92,21 +96,24 @@
|
||||||
|
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
|
<el-pagination style="text-align: center; margin-top: 10px"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
layout="prev, pager, next" :total="50"></el-pagination>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-dialog title="审核" :visible.sync="auditFormVisible">
|
<el-dialog title="审核" :visible.sync="auditFormVisible">
|
||||||
<el-form :model="auditForm">
|
<el-form ref="auditForm" :model="auditForm" label-width="80px">
|
||||||
|
|
||||||
<el-form-item label="审核">
|
<el-form-item prop="processStatus" label="审核" :rules="[{ required: true, message: '还没审核'}]">
|
||||||
<el-radio-group v-model="auditForm.processStatus">
|
<el-radio-group v-model="auditForm.processStatus">
|
||||||
<el-radio label="audit_passed">审核通过</el-radio>
|
<el-radio label="audit_passed">审核通过</el-radio>
|
||||||
<el-radio label="audit_not_passed">审核不通过</el-radio>
|
<el-radio label="audit_not_passed">审核不通过</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="审核意见">
|
<el-form-item prop="auditOpinion" label="审核意见" :rules="[{ required: true, message: '审核意见不能为空'}]">
|
||||||
<el-input type="textarea" :autosize="{ minRows: 3, maxRows: 10}"
|
<el-input type="textarea" :autosize="{ minRows: 4, maxRows: 10}"
|
||||||
maxlength="5000" v-model="auditForm.auditOpinion"
|
maxlength="5000" v-model="auditForm.auditOpinion"
|
||||||
placeholder="请输入审核意见" cols="90"></el-input>
|
placeholder="请输入审核意见" cols="90"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
@ -166,14 +173,48 @@
|
||||||
|
|
||||||
},
|
},
|
||||||
auditProcess(row, scope) {
|
auditProcess(row, scope) {
|
||||||
console.log(row)
|
this.auditForm = {
|
||||||
console.log(scope)
|
processId: row.id,
|
||||||
|
processStatus: null
|
||||||
|
}
|
||||||
|
this.auditFormVisible = true
|
||||||
},
|
},
|
||||||
|
|
||||||
submitAudit() {
|
submitAudit() {
|
||||||
|
this.$refs["auditForm"].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
text: '正在审核',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
|
||||||
|
const form = this.auditForm
|
||||||
|
|
||||||
|
fetch("${base}/process/audit", {
|
||||||
|
method: 'POST', // or 'PUT'
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(form),
|
||||||
|
}).then(response => {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: '审核成功',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
// 关闭对话框
|
||||||
|
this.auditFormVisible = false
|
||||||
|
}).catch(err => {
|
||||||
|
this.$message.error("审核失败");
|
||||||
|
}).finally(() => loading.close())
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
console.log("submitAudit");
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render(obj) {
|
render(obj) {
|
||||||
|
@ -200,6 +241,12 @@
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handlePageChange(val) {
|
||||||
|
console.log(`当前页:` + val)
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
|
|
Loading…
Reference in New Issue