This commit is contained in:
yyb
2025-05-12 17:00:06 +08:00
parent 9c5b5eba7c
commit 9c93dc1e10
855 changed files with 163903 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jxy-modules</artifactId>
<groupId>com.jxy</groupId>
<version>3.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>windminer</artifactId>
<description>
追风矿机工单系统
</description>
<name>windminer</name>
<dependencies>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<scope>provided</scope>
</dependency>
<!-- Mybatis-Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- JXY Common DataSource -->
<dependency>
<groupId>com.jxy</groupId>
<artifactId>common-datasource</artifactId>
</dependency>
<!-- JXY Common security -->
<dependency>
<groupId>com.jxy</groupId>
<artifactId>common-security</artifactId>
</dependency>
<dependency>
<groupId>com.jxy</groupId>
<artifactId>common-log</artifactId>
</dependency>
<dependency>
<groupId>com.jxy</groupId>
<artifactId>common-swagger</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,26 @@
package com.jxy.windminer;
import com.jxy.common.security.annotation.EnableCustomConfig;
import com.jxy.common.security.annotation.EnableJXYFeignClients;
import com.jxy.common.swagger.annotation.EnableCustomSwagger2;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @Description TODO
* @Date 2023/9/12 15:00
* @Author 杜懿
*/
@EnableCustomConfig
@EnableCustomSwagger2
@EnableJXYFeignClients
@SpringBootApplication
@MapperScan("com.jxy.windminer.mapper")
public class WindminerApplication {
public static void main(String[] args) {
SpringApplication.run(WindminerApplication.class,args);
System.out.println("windminer微服务启动成功");
}
}

View File

@@ -0,0 +1,139 @@
package com.jxy.windminer.controller;
import com.jxy.common.core.utils.StringUtils;
import com.jxy.common.core.web.Result.AjaxResult;
import com.jxy.windminer.dto.IdsDto;
import com.jxy.windminer.service.TicketService;
import com.jxy.windminer.vo.*;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.SQLException;
/**
* @Description 统一请求接口
* @Date 2022/5/27 9:54
* @Author 杜懿
*/
@RestController
@RequestMapping("/ticket")
public class TicketController {
@Autowired
private TicketService ticketService;
@PostMapping("/uploadFile")
@ApiOperation(value = "文件上传")
//@RequiresLogin
public AjaxResult uploadFile(@RequestParam("file") MultipartFile[] file,HttpServletRequest req){
String userName = req.getHeader("user_name");
try {
return ticketService.uploadFiles(file,userName);
} catch (SQLException e) {
e.printStackTrace();
return AjaxResult.error("服务器异常,请联系管理员");
}
}
@GetMapping("/downloadFile")
@ApiOperation(value = "文件批量下载")
//@RequiresLogin
public void download(IdsDto dto, HttpServletRequest request, HttpServletResponse response){
ticketService.downloadByIds(dto.getIds(),request,response);
}
@PostMapping("/submitTicket")
@ApiOperation(value = "提交工单")
//@RequiresLogin
public AjaxResult submitTicket(@RequestBody(required = false) TicketVo vo){
if(StringUtils.isNull(vo)){vo = new TicketVo();}
return ticketService.submitTicket(vo);
}
@PostMapping("/resubmitTicket")
@ApiOperation(value = "工单继续提交 已提交内容补充")
//@RequiresLogin
public AjaxResult resubmitTicket(@RequestBody ResubmitTicketVo vo,HttpServletRequest req){
String userName = req.getHeader("user_name");
return ticketService.resubmitTicket(vo,userName);
}
@PostMapping("/retractTicket")
@ApiOperation(value = "已提交工单撤回")
//@RequiresLogin
public AjaxResult retractTicket(@RequestBody IdVo vo,HttpServletRequest req){
String userName = req.getHeader("user_name");
return ticketService.retractTicket(vo.getId(),userName);
}
@PostMapping("/readTicket")
@ApiOperation(value = "工单状态设为已读")
//@RequiresLogin
public AjaxResult readTicket(@RequestBody IdVo vo,HttpServletRequest req){
String userName = req.getHeader("user_name");
return ticketService.readTicket(vo.getId(),userName);
}
@PostMapping("/endTicket")
@ApiOperation(value = "工单状态设为已解决")
//@RequiresLogin
public AjaxResult endTicket(@RequestBody IdVo vo,HttpServletRequest req){
String userName = req.getHeader("user_name");
return ticketService.endTicket(vo.getId(),userName);
}
@PostMapping("/getPrivateTicket")
@ApiOperation(value = "个人工单列表")
//@RequiresLogin
public AjaxResult getPrivateTicket(@RequestBody(required = false) StatusVo vo,HttpServletRequest req){
if(StringUtils.isNull(vo)){
vo = new StatusVo();
vo.setStatus(0);
}
String userName = req.getHeader("user_name");
return ticketService.getPrivateTicketByStatus(vo.getStatus(),userName);
}
@PostMapping("/getTicketDetails")
@ApiOperation(value = "工单详情")
//@RequiresLogin
public AjaxResult getTicketDetails(@RequestBody IdVo vo){
return ticketService.getTicketDetails(vo.getId());
}
@PostMapping("/getUnreadCount")
@ApiOperation(value = "个人未读工单数")
//@RequiresLogin
public AjaxResult getUnreadCount(HttpServletRequest req){
String userName = req.getHeader("user_name");
return ticketService.getUnreadCount(userName);
}
@PostMapping("/getTicketList")
@ApiOperation(value = "后台工单列表")
//@RequiresLogin
public AjaxResult getTicket(@RequestBody StatusVo vo){
return ticketService.getTicketList(vo.getStatus());
}
@PostMapping("/responTicket")
@ApiOperation(value = "回复工单")
//@RequiresLogin
public AjaxResult responTicket(@RequestBody ResponTicketVo vo,HttpServletRequest req){
String userName = req.getHeader("user_name");
return ticketService.responTicket(vo,userName);
}
}

View File

@@ -0,0 +1,16 @@
package com.jxy.windminer.dto;
import lombok.Data;
/**
* @Description TODO
* @Date 2023/3/20 15:10
* @Author 杜懿
*/
@Data
public class FileDto {
private long id;
private String url;
}

View File

@@ -0,0 +1,15 @@
package com.jxy.windminer.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 返回数据实体
* @Date 2022/5/30 11:17
* @Author 杜懿
*/
@Data
public class IdsDto implements Serializable {
private String ids;
}

View File

@@ -0,0 +1,27 @@
package com.jxy.windminer.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 返回数据实体
* @Date 2022/5/30 11:17
* @Author 杜懿
*/
@Data
public class SysFileDto implements Serializable {
/** 多文件拼接 */
private String id;
/**
* 文件名称
*/
private String name;
/**
* 文件地址
*/
private String url;
}

View File

@@ -0,0 +1,21 @@
package com.jxy.windminer.dto;
import lombok.Data;
import java.util.Date;
/**
* @Description TODO
* @Date 2022/6/20 17:44
* @Author 杜懿
*/
@Data
public class TicketAuditDto {
private Date time;
private String content;
private String name;
}

View File

@@ -0,0 +1,24 @@
package com.jxy.windminer.dto;
import lombok.Data;
import java.util.Date;
/**
* @Description TODO
* @Date 2022/6/20 17:44
* @Author 杜懿
*/
@Data
public class TicketContentDto {
private Date time;
private String content;
private String name;
private String files;
}

View File

@@ -0,0 +1,32 @@
package com.jxy.windminer.dto;
import lombok.Data;
import java.util.Date;
/**
* @Description TODO
* @Date 2023/3/20 15:10
* @Author 杜懿
*/
@Data
public class TicketDailyCountDto {
private Date date;
/**今日提交工单数*/
private int submitNum;
/**已处理工单数*/
private int solvedNum;
/**未处理工单数*/
private int pendingNum;
/**待审核工单数*/
private int checkingNum;
/**已审核工单数*/
private int checkedNum;
}

View File

@@ -0,0 +1,42 @@
package com.jxy.windminer.dto;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* @Description TODO
* @Date 2022/6/20 17:44
* @Author 杜懿
*/
@Data
public class TicketDetailsDto {
private int id;
private String userName;
private String email;
private String model;
private String serialNo;
private Date buyDate;
private String trackingId;
private String fault;
private String desc;
private Date submitTime;
private String status;
private List<TicketContentDto> list;
//private TicketAuditDto audit;
}

View File

@@ -0,0 +1,37 @@
package com.jxy.windminer.dto;
import lombok.Data;
import java.util.Date;
/**
* @Description TODO
* @Date 2022/6/20 17:44
* @Author 杜懿
*/
@Data
public class TicketDto {
private int id;
private String userName;
private String email;
private String model;
private String serialNo;
private Date buyDate;
private String trackingId;
private String fault;
private String desc;
private Date submitTime;
private int status;
}

View File

@@ -0,0 +1,29 @@
package com.jxy.windminer.dto;
import lombok.Data;
import java.util.Date;
/**
* @Description TODO
* @Date 2022/6/20 17:44
* @Author 杜懿
*/
@Data
public class TicketListDto {
private int id;
private Date date;
private String model;
private String serialNo;
private String userName;
private String email;
private String status;
}

View File

@@ -0,0 +1,27 @@
package com.jxy.windminer.dto;
import lombok.Data;
import java.util.Date;
/**
* @Description TODO
* @Date 2022/6/20 17:44
* @Author 杜懿
*/
@Data
public class TicketResponDto {
/** 回复时间*/
private Date responTime;
/** 回复人*/
private String responName;
/** 回复附件*/
private String responFiles;
/** 回复内容*/
private String respon;
}

View File

@@ -0,0 +1,30 @@
package com.jxy.windminer.entity;
import lombok.Data;
import java.util.Date;
/**
* @Description ETF
* @Date 2022/5/19 15:57
* @Author 杜懿
*/
@Data
public class JXYFile {
/** id */
private Long id;
/** 时间 */
private Date createTime;
/** value */
private String fileName;
private String url;
private String userName;
}

View File

@@ -0,0 +1,48 @@
package com.jxy.windminer.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
/**
* @Description TODO
* @Date 2022/6/20 17:44
* @Author 杜懿
*/
@TableName("ticket")
@Data
public class Ticket {
@TableId(type = IdType.AUTO)
private int id;
@TableField("user_name")
private String userName;
private String email;
private String model;
@TableField("serial_no")
private String serialNo;
@TableField("buy_date")
private String buyDate;
@TableField("tracking_id")
private String trackingId;
private String fault;
private String desc;
@TableField("create_time")
private Date createTime;
private int status;
}

View File

@@ -0,0 +1,24 @@
package com.jxy.windminer.entity;
import lombok.Data;
import java.util.Date;
/**
* @Description ETF
* @Date 2022/5/19 15:57
* @Author 杜懿
*/
@Data
public class TicketSupplement {
/** 时间 */
private Date date;
/** 补充内容 */
private String content;
/** 补充内容 */
private String files;
}

View File

@@ -0,0 +1,49 @@
package com.jxy.windminer.enums;
/**
* @Description 币价查询范围条件
* @Date 2022/5/20 11:15
* @Author 杜懿
*/
public enum TicketStatusType {
//ps:4是后台人员已回复用户但用户还未读 13是用户已读
STATUS_ONE(1,"已提交"),
STATUS_TWO(2,"撤回"),
STATUS_THREE(3,"待处理"),
STATUS_FOUR(4,"已处理"),
STATUS_FIVE(5,"已回复(停用)"),
STATUS_SIX(6,"重新提交"),
STATUS_SEVEN(7,"超时未确认"),
STATUS_Twelve(12,"已关闭"),
STATUS_Thirteen(13,"已处理");
private final int code;
private final String status;
TicketStatusType(int code, String status)
{
this.code = code;
this.status = status;
}
public int getCode()
{
return code;
}
public String getStatus()
{
return status;
}
public static String getStatusByCode(int code){
for (TicketStatusType t : TicketStatusType.values()) {
if(t.getCode()==code){
return t.getStatus();
}
}
return "";
}
}

View File

@@ -0,0 +1,146 @@
package com.jxy.windminer.mapper;
import com.jxy.common.datasource.annotation.JXYHelp;
import com.jxy.common.datasource.annotation.Master;
import com.jxy.windminer.dto.TicketContentDto;
import com.jxy.windminer.dto.TicketDailyCountDto;
import com.jxy.windminer.dto.TicketDto;
import com.jxy.windminer.dto.TicketListDto;
import com.jxy.windminer.entity.JXYFile;
import com.jxy.windminer.entity.Ticket;
import com.jxy.windminer.vo.QueryVo;
import com.jxy.windminer.vo.ResponTicketVo;
import com.jxy.windminer.vo.ResubmitTicketVo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Master
public interface TicketMapper {
/**
* 修改工单状态
* @param id
* @param status
* @return
*/
public boolean changeTicketStatus(@Param("id") long id, @Param("status") int status);
public int checkTicketExist(@Param("id") long id);
/**
* 新增工单
* @param data
* @return
*/
public boolean insertTicket(@Param("data") Ticket data);
/**
* 工单补充内容提交工单信息
* @param vo
* @return
*/
public boolean insertTicketSupplement(@Param("vo") ResubmitTicketVo vo);
public Integer getTicketSupplementCountByTicketId(@Param("id") long id);
/**
* 根据工单id 获取工单补充提交内容
* @param id
* @return
*/
public List<TicketContentDto> getTicketSupplementListByTicketId(@Param("id") long id);
///**
// * 根据工单id 获取工单审核内容
// * @param id
// * @return
// */
//public TicketAuditDto getTicketAuditByTicketId(@Param("id") long id);
/**
* 根据工单id 获取工单附件
* @param id
* @return
*/
public String getFileUrlsByTicketId(@Param("id") long id);
/**
* 根据工单id 获取工单回复内容
* @param id
* @return
*/
public List<TicketContentDto> getTicketResponListByTicketId(@Param("id") long id);
/**
* 查询个人工单列表
* @return
*/
public List<TicketListDto> getPrivateTicketList(@Param("userName") String userName);
/**
* 按状态查询个人工单列表
* @return
*/
public List<TicketListDto> getPrivateTicketListByStatus(@Param("userName") String userName,@Param("status") int status);
/**
* 查看工单详情
* @param id
* @return
*/
public TicketDto getTicketById(@Param("id") long id);
/**
* 后台根据状态查询工单列表
* @param status
* @return
*/
public List<TicketListDto> getBackendTicketList(@Param("status") int status);
/**
* 根据时间和状态查询未关闭工单列表
* @param vo
* @return
*/
public List<TicketListDto> getTicketListByTime(@Param("vo") QueryVo vo);
/**
* 查询每日工单数量分布
* @param vo
* @return
*/
public List<TicketDailyCountDto> getDailyCountList(@Param("vo") QueryVo vo);
/**
* 添加工单回复
* @param vo
* @return
*/
public boolean insertRespon(@Param("vo") ResponTicketVo vo, @Param("name") String name);
///**
// * 添加工单审核内容
// * @param vo
// * @return
// */
//public boolean insertAudit(@Param("vo") AuditTicketVo vo,@Param("name") String name);
/**
* 添加上传文件的保存信息
* @param vo
* @return
*/
public boolean insertFileInfo(@Param("vo") JXYFile vo);
/**
* 根据id获取文件相关信息
* @param id
* @return
*/
public JXYFile getFileInfoById(Long id);
}

View File

@@ -0,0 +1,127 @@
package com.jxy.windminer.service;
import com.jxy.common.core.web.Result.AjaxResult;
import com.jxy.windminer.vo.QueryVo;
import com.jxy.windminer.vo.ResponTicketVo;
import com.jxy.windminer.vo.ResubmitTicketVo;
import com.jxy.windminer.vo.TicketVo;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.SQLException;
/**
* @Description 追风工单系统服务类
* @Date 2022/5/19 17:40
* @Author 杜懿
*/
public interface TicketService {
//
///**
// * 获取问题类型下拉列表
// * @return
// */
//public AjaxResult getTypeList();
/**
* 根据文件id下载文件 多个
* @return
*/
public void downloadByIds(String ids, HttpServletRequest request, HttpServletResponse response);
/**
* 单文件上传
* @return
*/
public AjaxResult uploadFile(MultipartFile file,String userName) throws SQLException;
/**
* 多文件上传
* @return
*/
public AjaxResult uploadFiles(MultipartFile[] file,String userName) throws SQLException;
/**
* 提交工单
* @param vo
* @return
*/
public AjaxResult submitTicket(TicketVo vo);
/**
* 工单内容补充提交
* @param vo
* @return
*/
public AjaxResult resubmitTicket(ResubmitTicketVo vo,String userName);
/**
* 已回复工单设为已读
* @param id
* @return
*/
public AjaxResult readTicket(long id,String userName);
/**
* 结束工单
* @param id
* @return
*/
public AjaxResult endTicket(long id,String userName);
/**
* 修改工单状态为撤回
* @param id
* @return
*/
public AjaxResult retractTicket(long id,String userName);
/**
* 查看工单详情
* @param id
* @return
*/
public AjaxResult getTicketDetails(long id);
/**
* 根据status获取个人工单列表
* @param status
* @return
*/
public AjaxResult getPrivateTicketByStatus(int status,String userName);
/**
* 获取当前用户未读工单数
* @return
*/
public AjaxResult getUnreadCount(String userName);
/**
* 根据status获取工单列表
* @param status
* @return
*/
public AjaxResult getTicketList(int status);
/**
* 每日工单数详情
* @param vo
* @return
*/
public AjaxResult getDailyCount(QueryVo vo);
/**
* 回复工单
* @param vo
* @return
*/
public AjaxResult responTicket(ResponTicketVo vo,String userName);
}

View File

@@ -0,0 +1,572 @@
package com.jxy.windminer.service.impl;
import com.jxy.common.core.Result.R;
import com.jxy.common.core.text.Convert;
import com.jxy.common.core.utils.DateUtils;
import com.jxy.common.core.utils.StringUtils;
import com.jxy.common.core.web.Result.AjaxResult;
import com.jxy.common.datasource.annotation.JXYHelp;
import com.jxy.system.api.RemoteFileService;
import com.jxy.system.api.entity.SysFile;
import com.jxy.windminer.dto.*;
import com.jxy.windminer.entity.JXYFile;
import com.jxy.windminer.entity.Ticket;
import com.jxy.windminer.enums.TicketStatusType;
import com.jxy.windminer.mapper.TicketMapper;
import com.jxy.windminer.service.TicketService;
import com.jxy.windminer.vo.QueryVo;
import com.jxy.windminer.vo.ResponTicketVo;
import com.jxy.windminer.vo.ResubmitTicketVo;
import com.jxy.windminer.vo.TicketVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* @Description ETF查询业务处理
* @Date 2022/5/19 17:51
* @Author 杜懿
*/
@Service
public class TicketServiceImpl implements TicketService {
private static final Logger log = LoggerFactory.getLogger(TicketServiceImpl.class);
@Autowired
private TicketMapper ticketMapper;
@Autowired
private RemoteFileService remoteFileService;
public static final String FILE_PATH = "D:/windminer/ticket";
//@Override
//public AjaxResult getTypeList() {
//
// List<SelectDto> list = ticketMapper.getTypeSelect();
//
// return AjaxResult.success(list);
//}
@Transactional(rollbackFor = Exception.class)
@Override
@JXYHelp
public AjaxResult uploadFile(MultipartFile file,String userName) throws SQLException {
R<SysFile> upload = remoteFileService.upload(file);
if (StringUtils.isNull(upload) || StringUtils.isNull(upload.getData()))
{
return AjaxResult.error("文件服务异常,文件上传失败,请联系管理员");
}
SysFile sysFile = upload.getData();
JXYFile jxyFile = new JXYFile();
BeanUtils.copyProperties(sysFile,jxyFile);
jxyFile.setUserName(userName);
jxyFile.setFileName(sysFile.getName());
//将文件信息存入数据库:(url、name、userName、createTime)
boolean b = ticketMapper.insertFileInfo(jxyFile);
sysFile.setId(jxyFile.getId());
if(!b){
throw new SQLException("发生异常了..");
}
return AjaxResult.success(sysFile);
}
@Transactional(rollbackFor = Exception.class)
@Override
@JXYHelp
public AjaxResult uploadFiles(MultipartFile[] file,String userName) throws SQLException {
SysFileDto dto = new SysFileDto();
for (MultipartFile f: file) {
R<SysFile> upload = remoteFileService.windMinerUploadFile(f);
if (StringUtils.isNull(upload) || StringUtils.isNull(upload.getData()))
{
System.out.println("gg");
System.out.println(upload.getMsg());
return AjaxResult.error("文件服务异常,文件上传失败");
}
SysFile sysFile = upload.getData();
JXYFile jxyFile = new JXYFile();
BeanUtils.copyProperties(sysFile,jxyFile);
jxyFile.setUserName(userName);
jxyFile.setFileName(sysFile.getName());
//将文件信息存入数据库:(url、name、userName、createTime)
if(!ticketMapper.insertFileInfo(jxyFile)){
throw new SQLException("后台异常..");
}
if(StringUtils.isNull(dto.getId())){
dto.setId(Convert.toStr(jxyFile.getId()));
dto.setUrl(jxyFile.getUrl());
dto.setName(jxyFile.getFileName());
}else {
dto.setId(dto.getId()+","+jxyFile.getId());
dto.setUrl(dto.getUrl()+","+jxyFile.getUrl());
dto.setName(dto.getName()+","+jxyFile.getFileName());
}
}
return AjaxResult.success(dto);
}
@Override
public void downloadByIds(String ids, HttpServletRequest request, HttpServletResponse response){
List<JXYFile> fileInfos = getFileInfos(ids);
//设置响应头信息
response.reset();
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
//设置压缩包的名字date为时间戳
String date = DateUtils.dateTimeNow();
String downloadName = "file" + date + ".zip";
String agent = request.getHeader("USER-AGENT");
try {
//针对IE或者以IE为内核的浏览器
if (agent.contains("MSIE") || agent.contains("Trident")) {
downloadName = URLEncoder.encode(downloadName, "UTF-8");
} else {
//非IE浏览器的处理
downloadName = new String(downloadName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
}
} catch (Exception e) {
log.error("系统异常", e);
}
response.setHeader("Content-Disposition", "attachment;fileName=" + downloadName );
//设置压缩流直接写入response实现边压缩边下载
ZipOutputStream zipOs = null;
//循环将文件写入压缩流
DataOutputStream os = null;
//文件
File file;
try {
zipOs = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
//设置压缩方法
zipOs.setMethod(ZipOutputStream.DEFLATED);
//遍历文件信息(主要获取文件名/文件路径等)
for (JXYFile fileInfo : fileInfos) {
//文件名(包含后缀名,如:测试.pdf
String name = fileInfo.getFileName();
//本地文件路径(绝对路径,包含后缀名)
String path = FILE_PATH + StringUtils.substringAfter(fileInfo.getUrl(), "statics");
file = new File(path);
if (!file.exists()) {
throw new RuntimeException("文件不存在");
}
//添加ZipEntry并将ZipEntry写入文件流
zipOs.putNextEntry(new ZipEntry(name));
os = new DataOutputStream(zipOs);
FileInputStream fs = new FileInputStream(file);
byte[] b = new byte[100];
int length;
//读入需要下载的文件的内容打包到zip文件
while ((length = fs.read(b)) != -1) {
os.write(b, 0, length);
}
//关闭流
fs.close();
zipOs.closeEntry();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭流
try {
if (os != null) {
os.flush();
os.close();
}
if (zipOs != null) {
zipOs.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public AjaxResult submitTicket(TicketVo vo) {
Ticket ticket = new Ticket();
BeanUtils.copyProperties(vo,ticket);
ticket.setStatus(TicketStatusType.STATUS_ONE.getCode());
System.out.println(vo);
System.out.println(ticket);
if(ticketMapper.insertTicket(ticket)){
//工单提交成功 把工单信息内容存入工单信息表
ResubmitTicketVo reVo = new ResubmitTicketVo();
//把工单问题内容和附件路径赋值到reVo
BeanUtils.copyProperties(vo,reVo);
//把工单id赋值到reVo
reVo.setId(ticket.getId());
reVo.setDesc(StringUtils.clean(reVo.getDesc()));
return checkResult(ticketMapper.insertTicketSupplement(reVo));
}else {
return AjaxResult.error(509,"服务器网络异常,提交失败");
}
}
@Override
public AjaxResult resubmitTicket(ResubmitTicketVo vo,String userName) {
System.out.println(vo);
System.out.println(userName);
if(!checkUserPermissions(userName,vo.getId())){
return AjaxResult.error(601,"参数异常");
}
// 判断是否超过10条补充内容
Integer num = ticketMapper.getTicketSupplementCountByTicketId(vo.getId());
if(ticketMapper.checkTicketExist(vo.getId()) < 1){
return AjaxResult.error(601,"参数错误");
}
if( Convert.toInt(num,0) >= 11){
return AjaxResult.error("工单提交内容已达上限10");
}
//判断工单当前状态
AjaxResult result = checkStatusById(vo.getId());
if(StringUtils.isNotNull(result)){
return result;
}
if(StringUtils.isNull(vo)){
return AjaxResult.error(601,"参数错误");
}
vo.setDesc(StringUtils.clean(vo.getDesc()));
if(ticketMapper.insertTicketSupplement(vo)){
//提交成功 更改状态为用户重新提交
ticketMapper.changeTicketStatus(vo.getId(),TicketStatusType.STATUS_SIX.getCode());
return AjaxResult.success("提交成功");
}else {
return AjaxResult.error("服务器网络异常,提交失败");
}
}
@Override
public AjaxResult readTicket(long id,String userName) {
if(!checkUserPermissions(userName,id)){
return AjaxResult.error(601,"参数异常");
}
//更改状态为已读
if(ticketMapper.checkTicketExist(id) < 1){
return AjaxResult.error(601,"参数错误");
}
//判断工单是否是可修改的状态
AjaxResult result = checkStatusById(id);
if(StringUtils.isNotNull(result)){
return result;
}
return checkResult(ticketMapper.changeTicketStatus(id,TicketStatusType.STATUS_Thirteen.getCode()));
}
@Override
public AjaxResult endTicket(long id,String userName) {
if(!checkUserPermissions(userName,id)){
return AjaxResult.error(601,"参数异常");
}
if(ticketMapper.checkTicketExist(id) < 1){
return AjaxResult.error(601,"参数错误");
}
//更改状态为已关闭 12
return checkResult(ticketMapper.changeTicketStatus(id,TicketStatusType.STATUS_Twelve.getCode()));
}
@Override
public AjaxResult retractTicket(long id,String userName) {
if(!checkUserPermissions(userName,id)){
return AjaxResult.error(601,"参数异常");
}
if(ticketMapper.checkTicketExist(id) < 1){
return AjaxResult.error(601,"参数错误");
}
//更改状态为撤回 2
return checkResult(ticketMapper.changeTicketStatus(id,TicketStatusType.STATUS_TWO.getCode()));
}
@Override
public AjaxResult getTicketDetails(long id) {
TicketDto ticket = ticketMapper.getTicketById(id);
if (StringUtils.isNull(ticket)){
return AjaxResult.error(509,"后台异常(后台网络异常/后台传参异常),信息获取失败");
}
TicketDetailsDto details = new TicketDetailsDto();
BeanUtils.copyProperties(ticket,details);
details.setStatus(getStatus(ticket.getStatus()));
//获取工单内容list
List<TicketContentDto> supplementList = ticketMapper.getTicketSupplementListByTicketId(id);
//获取工单回复list
List<TicketContentDto> responList = ticketMapper.getTicketResponListByTicketId(id);
//合并回复和内容list并重新排序
supplementList.addAll(responList);
List<TicketContentDto> list = supplementList.stream().sorted(Comparator.comparing(TicketContentDto::getTime)).collect(Collectors.toList());
details.setList(list);
//判断工单是否是可修改的状态
AjaxResult result = checkStatusById(id);
if(StringUtils.isNotNull(result)){
int code = Convert.toInt(result.get("code"));
if( code== 601){
return result;
}
//工单状态为撤回2、已关闭12的直接原样输出状态
return AjaxResult.success(details);
}
List<Long> roles = new ArrayList<>();
//管理员
//roles.add(1L);
////支持人员
//roles.add(5L);
//if(roles.contains(SecurityUtils.getLoginUser().getSysUser().getRoleId())){
// //后台操作则修改为待处理
// //已提交1、超时未确认7则修改此时订单状态为待处理
// //已处理仅回复但用户还未读4、已处理(且用户已读)13、用户重新提交则不改变状态
// int status = ticket.getStatus();
// if(status == TicketStatusType.STATUS_ONE.getCode() || status == TicketStatusType.STATUS_SEVEN.getCode()){
// ticketMapper.changeTicketStatus(id,TicketStatusType.STATUS_THREE.getCode());
// details.setStatus(TicketStatusType.STATUS_THREE.getStatus());
// }
//}
return AjaxResult.success(details);
}
@Override
public AjaxResult getPrivateTicketByStatus(int status,String userName) {
List<TicketListDto> list = new ArrayList<>();
if (status == 0){
list = ticketMapper.getPrivateTicketList(userName);
}else if (status == 4){
//已处理工单 查询状态为已处理/回复 4和 已处理 13
list = ticketMapper.getPrivateTicketListByStatus(userName, status);
list.addAll(ticketMapper.getPrivateTicketListByStatus(userName,TicketStatusType.STATUS_Thirteen.getCode()));
}else if (status == 5){
//已回复未读工单(即已处理工单) 查询状态为已处理 4和 已处理 13
list = ticketMapper.getPrivateTicketListByStatus(userName, status);
}else{
return AjaxResult.success(list);
}
list.stream().forEach(e ->{
e.setStatus(getStatus(Convert.toInt(e.getStatus())));
});
return AjaxResult.success(list);
}
@Override
public AjaxResult getUnreadCount(String userName) {
List<TicketListDto> list = ticketMapper.getPrivateTicketListByStatus(userName, TicketStatusType.STATUS_FIVE.getCode());
int num = list.size();
Map<String,Integer> map = new HashMap<>();
map.put("count",num);
return AjaxResult.success(map);
}
@Override
public AjaxResult getTicketList(int status) {
List<TicketListDto> list = ticketMapper.getBackendTicketList(status);
//特殊处理1待处理工单应该包含status为待处理、已提交和用户重新提交
if(status == TicketStatusType.STATUS_THREE.getCode()){
list.addAll(ticketMapper.getBackendTicketList(TicketStatusType.STATUS_SIX.getCode()));
list.addAll(ticketMapper.getBackendTicketList(TicketStatusType.STATUS_ONE.getCode()));
}
//特殊处理2已处理需要把用户已读 13也得包含进去
if(status == TicketStatusType.STATUS_FOUR.getCode()){
list.addAll(ticketMapper.getBackendTicketList(TicketStatusType.STATUS_Thirteen.getCode()));
}
list.stream().forEach(e ->{
e.setStatus(getStatus(Convert.toInt(e.getStatus())));
});
return AjaxResult.success(list);
}
@Override
public AjaxResult getDailyCount(QueryVo vo) {
List<TicketDailyCountDto> list = ticketMapper.getDailyCountList(vo);
list.stream().forEach(t -> {t.setPendingNum(t.getSubmitNum() - t.getSolvedNum());});
return CheckData(list);
}
@Override
public AjaxResult responTicket(ResponTicketVo vo,String userName) {
if(!checkUserPermissions(userName, vo.getId())){
return AjaxResult.error(601,"参数异常");
}
if(ticketMapper.checkTicketExist(vo.getId()) < 1){
return AjaxResult.error(601,"参数错误,工单不存在");
}
AjaxResult result = checkStatusById(vo.getId());
if(StringUtils.isNotNull(result)){
return result;
}
vo.setFiles(StringUtils.clean(vo.getFiles()));
vo.setRespon(StringUtils.clean(vo.getRespon()));
if(ticketMapper.insertRespon(vo,userName)){
//回复信息入库成功 修改工单状态为已处理 4 (原来的5已回复 合并)
return checkResult(ticketMapper.changeTicketStatus(vo.getId(), TicketStatusType.STATUS_FOUR.getCode()));
}else {
return AjaxResult.error("服务器网络异常,提交失败");
}
}
public AjaxResult checkResult(boolean b){
if(!b){
return AjaxResult.error("服务器网络异常,提交失败");
}
return AjaxResult.success();
}
/**
* 验证list是否为空
* @param list
* @return
*/
public AjaxResult CheckData(List list) {
if(list.size() < 1){
return AjaxResult.error(508,"后台数据获取失败,请稍后再试");
}
return AjaxResult.success(list);
}
public List<JXYFile> getFileInfos(String files){
List<JXYFile> list = new ArrayList<>();
if(StringUtils.isNull(files)){
return list;
}
if(StringUtils.isEmpty(files)){
return list;
}
Long[] ids = Convert.toLongArray(files);
for (long id: ids) {
JXYFile file = ticketMapper.getFileInfoById(id);
if(StringUtils.isNotNull(file)){
list.add(file);
}
}
return list;
}
public String getStatus(int status) {
return TicketStatusType.getStatusByCode(status);
}
public AjaxResult checkStatusById(long id){
TicketDto ticket = ticketMapper.getTicketById(id);
if(StringUtils.isNull(ticket)){
return AjaxResult.error(601,"工单id参数错误");
}else {
String result = checkStatusByStatusCode(ticket.getStatus());
if(StringUtils.isNotNull(result)){
return AjaxResult.error(result);
}else {
return null;
}
}
}
public String checkStatusByStatusCode(int status) {
if(status == TicketStatusType.STATUS_Twelve.getCode()){
return "工单已关闭,不能再操作";
}else if(status == TicketStatusType.STATUS_TWO.getCode()) {
return "已撤回工单不能再操作";
}
return null;
}
public boolean checkUserPermissions(String userName,long ticketId) {
if(StringUtils.isNull(userName)){
return false;
}
if (ticketId < 1){
return false;
}
TicketDto ticket = ticketMapper.getTicketById(ticketId);
System.out.println("根据工单id"+ticketId+"获取到数据"+ticket);
System.out.println("根据用户名:"+userName);
if(StringUtils.isNull(ticket)){
return false;
}
if(!ticket.getUserName().equals(userName))
{
return false;
}
return true;
}
}

View File

@@ -0,0 +1,15 @@
package com.jxy.windminer.vo;
import lombok.Data;
/**
* @Description TODO
* @Date 2022/8/1 18:44
* @Author 杜懿
*/
@Data
public class IdVo {
private long id;
}

View File

@@ -0,0 +1,20 @@
package com.jxy.windminer.vo;
import lombok.Data;
/**
* @Description 接口请求基础信息
* @Date 2022/5/27 10:52
* @Author 杜懿
*/
@Data
public class QueryVo {
/** 起始时间 */
private String start;
/** 截止时间 */
private String end;
private int sma=0;
}

View File

@@ -0,0 +1,21 @@
package com.jxy.windminer.vo;
import lombok.Data;
/**
* @Description 指标查询条件
* @Date 2022/5/19 17:17
* @Author 杜懿
*/
@Data
public class ResponTicketVo {
/** 工单id */
private long id;
/** 回复内容 */
private String respon;
/** 附件编号 逗号分隔*/
private String files;
}

View File

@@ -0,0 +1,21 @@
package com.jxy.windminer.vo;
import lombok.Data;
/**
* @Description 指标查询条件
* @Date 2022/5/19 17:17
* @Author 杜懿
*/
@Data
public class ResubmitTicketVo {
/** 工单id */
private long id;
/** 补充内容 */
private String desc;
private String files;
}

View File

@@ -0,0 +1,15 @@
package com.jxy.windminer.vo;
import lombok.Data;
/**
* @Description TODO
* @Date 2022/8/1 18:44
* @Author 杜懿
*/
@Data
public class StatusVo {
private int status;
}

View File

@@ -0,0 +1,38 @@
package com.jxy.windminer.vo;
import lombok.Data;
/**
* @Description 指标查询条件
* @Date 2022/5/19 17:17
* @Author 杜懿
*/
@Data
public class TicketVo {
private String userName;
private String email;
/** 机器型号 */
private String model;
/** 序列号 */
private String serialNo;
private String buyDate;
/** 快递单号 */
private String trackingId;
/** 故障现象 */
private String fault;
/** 故障描述 */
private String desc;
/** 附件标号 逗号分隔*/
private String files;
}

View File

@@ -0,0 +1,33 @@
# Tomcat
server:
port: 9808
compression:
enabled: true
mime-types: application/json
# Spring
spring:
application:
# 应用名称
name: windminer
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址 172.16.2.5
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
servlet:
multipart:
max-file-size: 2MB
max-request-size: 8MB

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/windminer" />
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.jxy" level="info" />
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<root level="info">
<appender-ref ref="console" />
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
</configuration>

View File

@@ -0,0 +1,214 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jxy.windminer.mapper.TicketMapper">
<select id="getPrivateTicketList" resultType="com.jxy.windminer.dto.TicketListDto">
select
id,model,create_time `date`,serial_no serialNo,user_name userName,email,status
from
ticket
<where>
<if test="userName != null and userName != ''">
user_name = #{userName}
</if>
</where>
</select>
<select id="getPrivateTicketListByStatus" resultType="com.jxy.windminer.dto.TicketListDto">
select
id,
model,
create_time `date`,
serial_no serialNo,
user_name userName,
email,
status
from
ticket
<where>
<if test="userName != null and userName != ''">
and user_name = #{userName}
</if>
<if test="status != null and status != 0">
and status = #{status}
</if>
</where>
</select>
<select id="getTicketById" resultType="com.jxy.windminer.dto.TicketDto">
select
id,
user_name userName,
email,
model,
serial_no serialNo,
buy_date buyDate,
tracking_id trackingId,
fault,
`desc`,
create_time submitTime,
status
from
ticket
where
id = #{id}
ORDER BY create_time
</select>
<select id="getBackendTicketList" resultType="com.jxy.windminer.dto.TicketListDto">
select
id,
model,
create_time `date`,
serial_no serialNo,
user_name userName,
email,
status
from
ticket
<where>
<if test="status != null and status != 0">
and t.status = #{status}
</if>
</where>
order by t.create_time,t.user_name
</select>
<select id="getDailyCountList" resultType="com.jxy.windminer.dto.TicketDailyCountDto">
select
DATE_FORMAT(create_time,'%Y-%m-%d') as date,
sum(case when 1 then 1 else 0 end) submitNum,
sum(case when status = 4 then 1 else 0 end) solvdNum,
sum(case when status = 8 then 1 else 0 end) checkingNum,
sum(case when status = 11 then 1 else 0 end) checkedNum
FROM
ticket
GROUP BY date
</select>
<select id="getTicketResponListByTicketId" resultType="com.jxy.windminer.dto.TicketContentDto">
select
create_time `time`,
respon content,
responer name,
files
from
respon
<where>
<if test="id != null and id != 0">
ticket_id = #{id}
</if>
</where>
order BY create_time
</select>
<select id="getFileUrlsByTicketId" resultType="java.lang.String">
SELECT url FROM file where id =#{id};
</select>
<select id="getTicketSupplementCountByTicketId" resultType="java.lang.Integer">
select count(*) from ticket_supplement where ticket_id = #{id};
</select>
<select id="getTicketSupplementListByTicketId" resultType="com.jxy.windminer.dto.TicketContentDto">
select
s.create_time `time`,
s.content content,
s.files files,
t.user_name name
from
ticket_supplement s left join ticket t on s.ticket_id = t.id
<where>
<if test="id != null and id != 0">
s.ticket_id = #{id}
</if>
</where>
order by s.create_time,s.id
</select>
<select id="checkTicketExist" resultType="java.lang.Integer">
select count(1) from ticket where id = #{id} limit 1
</select>
<select id="getTicketAuditByTicketId" resultType="com.jxy.windminer.dto.TicketAuditDto">
select create_time `time`,user_name name,content
from audit
<where>
<if test="id != null and id != 0">
and ticket_id = #{id}
</if>
</where>
limit 1
</select>
<select id="getTicketListByTime" resultType="com.jxy.windminer.dto.TicketListDto">
select
id,create_time `date`,user_name userName,status
from
ticket
<where>
<if test="vo.start != null and vo.start != ''">
and create_time &gt;= #{vo.start}
</if>
<if test="vo.end != null and vo.end != ''">
and create_time &lt;= #{vo.end}
</if>
</where>
order by t.user_name,t.create_time
</select>
<select id="getFileInfoById" resultType="com.jxy.windminer.entity.JXYFile">
select id,file_name fileName,url,user_name userName,create_time createTime from file where id = #{id}
</select>
<update id="changeTicketStatus">
UPDATE ticket SET status=#{status} WHERE id = #{id}
</update>
<insert id="insertTicket" useGeneratedKeys="true" keyProperty="id">
insert into ticket(
<if test="data.userName != null and data.userName != ''">user_name,</if>
<if test="data.email != null and data.email !=''">email,</if>
<if test="data.model != null and data.model !=''">model,</if>
<if test="data.serialNo != null and data.serialNo != ''">serial_no,</if>
<if test="data.buyDate != null and data.buyDate != ''">buy_date,</if>
<if test="data.trackingId != null and data.trackingId != ''">tracking_id,</if>
<if test="data.fault != null and data.fault != ''">fault,</if>
<if test="data.desc != null and data.desc != ''">`desc`,</if>
<if test="data.status != null and data.status != 0">status,</if>
create_time
)values(
<if test="data.userName != null and data.userName != ''">#{data.userName},</if>
<if test="data.email != null and data.email != ''">#{data.email},</if>
<if test="data.model != null and data.model != ''">#{data.model},</if>
<if test="data.serialNo != null and data.serialNo != ''">#{data.serialNo},</if>
<if test="data.buyDate != null and data.buyDate != ''">#{data.buyDate},</if>
<if test="data.trackingId != null and data.trackingId != ''">#{data.trackingId},</if>
<if test="data.fault != null and data.fault != ''">#{data.fault},</if>
<if test="data.desc != null and data.desc != ''">#{data.desc},</if>
<if test="data.status != null and data.status != 0">1,</if>
sysdate()
)
</insert>
<insert id="insertTicketSupplement">
insert into ticket_supplement(ticket_id,content,files,create_time) values (
#{vo.id},#{vo.desc},#{vo.files},sysdate()
)
</insert>
<insert id="insertRespon">
insert into respon(ticket_id,respon,responer,files,create_time) values(
#{vo.id},#{vo.respon},#{name},#{vo.files},sysdate()
)
</insert>
<insert id="insertFileInfo" useGeneratedKeys="true" keyProperty="id">
insert into `file`(url,file_name,user_name,create_time) values(
#{vo.url},#{vo.fileName},#{vo.userName},sysdate()
)
</insert>
</mapper>