Commit 24a7e812 authored by 谢希宇's avatar 谢希宇

create by Strive

create date 2021/01/27
1、检测券管理,赠券信息,检测结果建模
2、二维码生成工具;
3、检测券表单;
4、聊天记录模块;
parent 0126d2cf
<?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/maven-v4_0_0.xsd">
<parent>
<artifactId>aidea-modules</artifactId>
<groupId>com.cftech</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<name>checkcoupon-module-web</name>
<groupId>com.cftech</groupId>
<artifactId>checkcoupon-module-web</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<finalName>checkcoupon-module-web</finalName>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.cftech</groupId>
<artifactId>checkcoupon-module</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<?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>aidea-modules</artifactId>
<groupId>com.cftech</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>checkcoupon-module</artifactId>
</project>
\ No newline at end of file
package com.cftech.checkcoupon.dao;
import com.cftech.checkcoupon.model.Checkcoupon;
import com.cftech.core.generic.GenericDao;
/**
* 检测券管理Mapper
*
* @author Strive
* @date: 2021-01-25 14:42
*/
public interface CheckcouponMapper extends GenericDao<Checkcoupon> {
}
\ No newline at end of file
<?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.cftech.checkcoupon.dao.CheckcouponMapper">
<resultMap id="resultMap" type="com.cftech.checkcoupon.model.Checkcoupon">
<id column="id" property="id"/>
<result column="take_effect_month" property="takeEffectMonth"/>
<result column="take_effect_year" property="takeEffectYear"/>
<result column="expire_month" property="expireMonth"/>
<result column="type" property="type"/>
<result column="name" property="name"/>
<result column="remarks" property="remarks"/>
<result column="instructions" property="instructions"/>
<result column="accounts_id" property="accountsId"/>
<result column="del_flag" property="delFlag"/>
<result column="status" property="status"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="description" property="description"/>
<result column="create_by" property="createBy"/>
<result column="update_by" property="updateBy"/>
</resultMap>
<sql id="sqlWhere">
<if test="conds!=null">
<trim prefix="WHERE" prefixOverrides="AND|OR">
<foreach collection="conds.conds" index="index" item="cond">
${cond.linkType}
<if test="cond.condType == 'EQUAL'">${cond.param} = #{cond.value}</if>
<if test="cond.condType == 'NOTEQUAL'">${cond.param} &lt;&gt; #{cond.value}</if>
<if test="cond.condType == 'GREATEQUAL'">${cond.param} &gt;= #{cond.value}</if>
<if test="cond.condType == 'GREATTHAN'">${cond.param} &gt; #{cond.value}</if>
<if test="cond.condType == 'LESSEQUAL'">${cond.param} &lt;= #{cond.value}</if>
<if test="cond.condType == 'LESSTHAN'">${cond.param} &lt; #{cond.value}</if>
<if test="cond.condType == 'BETWEEN'">${cond.param} BETWEEN #{cond.startValue} AND
#{cond.endValue}
</if>
<if test="cond.condType == 'ISNULL'">${cond.param} IS NULL</if>
<if test="cond.condType == 'NOTNULL'">${cond.param} IS NOT NULL</if>
<if test="cond.condType == 'LIKE'">${cond.param} LIKE #{cond.value}</if>
<if test="cond.condType == 'IN'">${cond.param} IN
<foreach item="item" index="index" collection="cond.value" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</foreach>
</trim>
</if>
</sql>
<sql id="sqlColumns">
id
,
take_effect_month,
take_effect_year,
expire_month,
type,
name,
remarks,
instructions,
accounts_id,
del_flag,
status,
create_time,
update_time,
description,
create_by,
update_by
</sql>
<insert id="save" parameterType="com.cftech.checkcoupon.model.Checkcoupon" useGeneratedKeys="true"
keyProperty="id">
insert into t_aidea_check_coupon
(
<include refid="sqlColumns"/>
)
values
(
#{id, jdbcType=BIGINT},
#{takeEffectMonth, jdbcType=VARCHAR},
#{takeEffectYear, jdbcType=VARCHAR},
#{expireMonth, jdbcType=VARCHAR},
#{type, jdbcType=VARCHAR},
#{name, jdbcType=VARCHAR},
#{remarks, jdbcType=VARCHAR},
#{instructions, jdbcType=VARCHAR},
#{accountsId, jdbcType=BIGINT},
#{delFlag, jdbcType=TINYINT},
#{status, jdbcType=VARCHAR},
now(),
now(),
#{description, jdbcType=VARCHAR},
#{createBy, jdbcType=BIGINT},
#{updateBy, jdbcType=BIGINT}
)
</insert>
<select id="fetchById" parameterType="java.lang.Long" resultMap="resultMap">
SELECT
<include refid="sqlColumns"/>
FROM t_aidea_check_coupon t
WHERE t.id=#{id}
</select>
<select id="count" parameterType="java.util.Map" resultType="java.lang.Integer">
SELECT COUNT(1) FROM t_aidea_check_coupon
<include refid="sqlWhere"/>
</select>
<select id="fetchSearchByPage" parameterType="java.util.Map" resultMap="resultMap">
SELECT
<include refid="sqlColumns"/>
FROM t_aidea_check_coupon
<include refid="sqlWhere"/>
<if test="sort!=null">ORDER BY ${sort.param} ${sort.type}</if>
<if test="limit>0">limit #{offset},#{limit}</if>
</select>
<update id="update" parameterType="com.cftech.checkcoupon.model.Checkcoupon">
update t_aidea_check_coupon
<set>
<if test="id != null">
id = #{id, jdbcType=BIGINT},
</if>
<if test="takeEffectMonth != null">
take_effect_month = #{takeEffectMonth, jdbcType=VARCHAR},
</if>
<if test="takeEffectYear != null">
take_effect_year = #{takeEffectYear, jdbcType=VARCHAR},
</if>
<if test="expireMonth != null">
expire_month = #{expireMonth, jdbcType=VARCHAR},
</if>
<if test="type != null">
type = #{type, jdbcType=VARCHAR},
</if>
<if test="name != null">
name = #{name, jdbcType=VARCHAR},
</if>
<if test="remarks != null">
remarks = #{remarks, jdbcType=VARCHAR},
</if>
<if test="instructions != null">
instructions = #{instructions, jdbcType=VARCHAR},
</if>
<if test="accountsId != null">
accounts_id = #{accountsId, jdbcType=BIGINT},
</if>
<if test="delFlag != null">
del_flag = #{delFlag, jdbcType=TINYINT},
</if>
<if test="status != null">
status = #{status, jdbcType=VARCHAR},
</if>
<if test="createTime != null">
create_time = #{createTime, jdbcType=TIMESTAMP},
</if>
<if test="description != null">
description = #{description, jdbcType=VARCHAR},
</if>
<if test="createBy != null">
create_by = #{createBy, jdbcType=BIGINT},
</if>
<if test="updateBy != null">
update_by = #{updateBy, jdbcType=BIGINT},
</if>
</set>
where id=#{id,jdbcType=BIGINT}
</update>
<update id="delete" parameterType="java.lang.Long">
update t_aidea_check_coupon
set del_flag=1
where id = #{id,jdbcType=BIGINT}
</update>
</mapper>
\ No newline at end of file
package com.cftech.checkcoupon.model;
import com.cftech.core.poi.ExportConfig;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 检测券管理
*
* @author Strive
* @date: 2021-01-25 14:42
*/
@Data
public class Checkcoupon implements Serializable {
/* 主键id */
private Long id;
/* 有效期年 */
@ExportConfig(value = "有效期年", width = 100, showLevel = 1)
private String takeEffectYear;
/* 生效月 */
@ExportConfig(value = "生效月", width = 100, showLevel = 1)
private String takeEffectMonth;
/* 过期月份 */
@ExportConfig(value = "过期月份", width = 100, showLevel = 1)
private String expireMonth;
/* 检测券类型 */
@ExportConfig(value = "检测券类型", width = 100, showLevel = 1)
private String type;
/* 检测券名称 */
@ExportConfig(value = "检测券名称", width = 100, showLevel = 1)
private String name;
/* 描述 */
@ExportConfig(value = "描述", width = 100, showLevel = 1)
private String remarks;
/* 使用说明 */
@ExportConfig(value = "使用说明", width = 100, showLevel = 1)
private String instructions;
/* 所属的账号 */
private Long accountsId;
/* 删除标识 */
private boolean delFlag;
/* 状态 */
private String status;
/* 创建时间 */
private Date createTime;
/* 更新时间 */
private Date updateTime;
/* 备注 */
private String description;
/* 创建人 */
private Long createBy;
/* 更新人 */
private Long updateBy;
public Checkcoupon() {
this.delFlag = false;
this.status = "0";
}
}
\ No newline at end of file
package com.cftech.checkcoupon.service;
import com.cftech.checkcoupon.model.Checkcoupon;
import com.cftech.core.generic.GenericService;
/**
* 检测券管理Service
*
* @author Strive
* @date: 2021-01-25 14:42
*/
public interface CheckcouponService extends GenericService<Checkcoupon> {
}
package com.cftech.checkcoupon.service.impl;
import com.cftech.checkcoupon.model.Checkcoupon;
import com.cftech.checkcoupon.dao.CheckcouponMapper;
import com.cftech.checkcoupon.service.CheckcouponService;
import com.cftech.core.generic.GenericDao;
import com.cftech.core.generic.GenericServiceImpl;
import com.cftech.core.sql.Conds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
/**
* 检测券管理ServiceImpl
*
* @author Strive
* @date: 2021-01-25 14:42
*/
@Service("checkcouponService")
public class CheckcouponServiceImpl extends GenericServiceImpl<Checkcoupon> implements CheckcouponService {
@Autowired
@Qualifier("checkcouponMapper")
private CheckcouponMapper checkcouponMapper;
@Override
public GenericDao<Checkcoupon> getGenericMapper() {
return checkcouponMapper;
}
}
\ No newline at end of file
package com.cftech.checkcoupon.utils;
import lombok.extern.slf4j.Slf4j;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
* @CreateBy Strive
* @CreateDate 2021-01-26
*/
@Slf4j
public class LogoConfig {
/**
* 设置 logo
* @param matrixImage 源二维码图片
* @return 返回带有logo的二维码图片
* @throws IOException
* @author Administrator sangwenhao
*/
public BufferedImage LogoMatrix(BufferedImage matrixImage) throws IOException {
/**
* 读取二维码图片,并构建绘图对象
*/
Graphics2D g2 = matrixImage.createGraphics();
int matrixWidth = matrixImage.getWidth();
int matrixHeigh = matrixImage.getHeight();
/**
* 读取Logo图片
*/
BufferedImage logo = ImageIO.read(new File("E:\\logo.png"));
//开始绘制图片
g2.drawImage(logo,matrixWidth/5*2,matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5, null);//绘制
BasicStroke stroke = new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g2.setStroke(stroke);// 设置笔画对象
//指定弧度的圆角矩形
RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth/5*2, matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5,20,20);
g2.setColor(Color.white);
g2.draw(round);// 绘制圆弧矩形
//设置logo 有一道灰色边框
BasicStroke stroke2 = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g2.setStroke(stroke2);// 设置笔画对象
RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth/5*2+2, matrixHeigh/5*2+2, matrixWidth/5-4, matrixHeigh/5-4,20,20);
g2.setColor(new Color(128,128,128));
g2.draw(round2);// 绘制圆弧矩形
g2.dispose();
matrixImage.flush() ;
return matrixImage ;
}
}
package com.cftech.checkcoupon.utils;
import com.google.zxing.common.BitMatrix;
import lombok.extern.slf4j.Slf4j;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
/**
* @CreateBy Strive
* @CreateDate 2021-01-26
*/
@Slf4j
public class MatrixToImageWriter {
private static final int BLACK = 0xFF000000;//用于设置图案的颜色
private static final int WHITE = 0xFFFFFFFF; //用于背景色
private MatrixToImageWriter() {
}
public static BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, (matrix.get(x, y) ? BLACK : WHITE));
// image.setRGB(x, y, (matrix.get(x, y) ? Color.YELLOW.getRGB() : Color.CYAN.getRGB()));
}
}
return image;
}
public static boolean writeToFile(BitMatrix matrix, String format, File file, boolean isLogo) throws IOException {
BufferedImage image = toBufferedImage(matrix);
//设置logo图标
if (isLogo) {
LogoConfig logoConfig = new LogoConfig();
image = logoConfig.LogoMatrix(image);
}
if (!ImageIO.write(image, format, file)) {
throw new IOException("Could not write an image of format " + format + " to " + file);
}else{
log.info("图片生成成功!");
return true;
}
}
public static void writeToStream(BitMatrix matrix, String format, OutputStream stream) throws IOException {
BufferedImage image = toBufferedImage(matrix);
//设置logo图标
LogoConfig logoConfig = new LogoConfig();
image = logoConfig.LogoMatrix(image);
if (!ImageIO.write(image, format, stream)) {
throw new IOException("Could not write an image of format " + format);
}
}
}
package com.cftech.checkcoupon.utils;
import com.cftech.core.util.DateFormatUtils;
import com.cftech.core.util.SystemConfig;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Hashtable;
/**
* @CreateBy Strive
* @CreateDate 2021-01-26
*/
@Slf4j
public class QrcodeUtil {
private static int QRCODE_WIDTH = 430;
private static int QRCODE_HEIGHT = 430;
private static String LOGO_FORMAT = "png";
private static String QRCODE_DIR = SystemConfig.p.getProperty("userfiles.qrcodedir");
/**
* 对应卡券编码
* @param contents
* @return
* @throws WriterException
* @throws IOException
*/
public static String generateQrcode(String contents) throws WriterException, IOException {
Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MARGIN, 1);//设置二维码边的空度,非负数
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,//要编码的内容
//编码类型,目前zxing支持:Aztec 2D,CODABAR 1D format,Code 39 1D,Code 93 1D ,Code 128 1D,
//Data Matrix 2D , EAN-8 1D,EAN-13 1D,ITF (Interleaved Two of Five) 1D,
//MaxiCode 2D barcode,PDF417,QR Code 2D,RSS 14,RSS EXPANDED,UPC-A 1D,UPC-E 1D,UPC/EAN extension,UPC_EAN_EXTENSION
BarcodeFormat.QR_CODE,
QRCODE_WIDTH, //条形码的宽度
QRCODE_HEIGHT, //条形码的高度
hints);//生成条形码时的一些配置,此项可选
//文件夹
String path = QRCODE_DIR + File.separator + DateFormatUtils.getDateFormat(new Date(), "yyyyMMdd");
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
String mediaPath = path + File.separator + contents + "." + LOGO_FORMAT;
//生成对应文件
File outputFile = new File(path + File.separator + contents + "." + LOGO_FORMAT);
if (MatrixToImageWriter.writeToFile(bitMatrix, LOGO_FORMAT, outputFile, true)) {
return mediaPath;
}
return null;
}
public static void main(String[] args) throws IOException, WriterException {
generateQrcode("CS202011100002");
}
}
package com.cftech.checkcoupon.web;
import com.alibaba.fastjson.JSONObject;
import com.cftech.checkcoupon.model.Checkcoupon;
import com.cftech.checkcoupon.service.CheckcouponService;
import com.cftech.core.poi.ExcelKit;
import com.cftech.core.scope.OrderType;
import com.cftech.core.sql.Conds;
import com.cftech.core.sql.Sort;
import com.cftech.core.util.Constants;
import com.cftech.core.util.StringUtils;
import com.cftech.sys.security.PermissionSign;
import com.cftech.sys.security.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* 检测券管理Controller
* <p>
* 权限字符串说明:
* 查看:public static final String CHECKCOUPON_VIEW = "qy:checkcoupon:view"
* 查看:public static final String CHECKCOUPON_EDIT = "qy:checkcoupon:edit"
*
* @author Strive
* @date: 2021-01-25 14:42
*/
@Slf4j
@Controller
@RequestMapping("/a/checkcoupon")
public class CheckcouponController {
public static final String CHECKCOUPON_VIEW = "qy:checkcoupon:view";
public static final String CHECKCOUPON_EDIT = "qy:checkcoupon:edit";
@Autowired
private CheckcouponService checkcouponService;
//列表页面
@RequiresPermissions(value = CHECKCOUPON_VIEW)
@RequestMapping("/list")
public String list(HttpServletRequest request, Model model) {
Long accountId = UserUtils.getmpaccounts(request);
model.addAttribute("accountId", accountId);
return "checkcoupon/checkcouponlist";
}
//编辑页面(新增、修改)
@RequiresPermissions(value = CHECKCOUPON_VIEW)
@RequestMapping("/form")
public String form(HttpServletRequest request, String id, Model model, String pageType) {
if (!StringUtils.isEmpty(id)) {
Checkcoupon checkcoupon = checkcouponService.fetchById(id);
model.addAttribute("data", checkcoupon);
}
model.addAttribute("pageType", pageType);
return "checkcoupon/checkcouponform";
}
//提交数据(新增、修改)
@RequiresPermissions(value = CHECKCOUPON_EDIT)
@RequestMapping("/formData")
@ResponseBody
public JSONObject formData(Checkcoupon checkcoupon, Model model, HttpServletRequest request) {
Long accountsId = UserUtils.getmpaccounts(request);
JSONObject rtnJson = new JSONObject();
try {
if (checkcoupon != null && checkcoupon.getId() != null) {
checkcoupon.setUpdateBy(UserUtils.getUser().getId());
checkcouponService.update(checkcoupon);
rtnJson.put("errorNo", 0);
} else {
if (Integer.parseInt(checkcoupon.getTakeEffectMonth()) + Integer.parseInt(checkcoupon.getExpireMonth()) > 12) {
rtnJson.put("errorNo", 3);
rtnJson.put("errorMsg", "生效月和过期月不能超过12个月!");
return rtnJson;
}
checkcoupon.setAccountsId(accountsId);
checkcoupon.setDelFlag(false);
checkcoupon.setAccountsId(UserUtils.getmpaccounts(request));
checkcoupon.setCreateBy(UserUtils.getUser().getId());
checkcoupon.setUpdateBy(UserUtils.getUser().getId());
checkcouponService.save(checkcoupon);
rtnJson.put("errorNo", 2);
}
} catch (Exception e) {
rtnJson.put("errorNo", 1);
}
return rtnJson;
}
//获取列表数据
@RequiresPermissions(value = CHECKCOUPON_VIEW)
@RequestMapping(value = "/listData")
@ResponseBody
public JSONObject listData(int iDisplayStart, int iDisplayLength, Checkcoupon checkcoupon, HttpServletRequest request) {
Long accountsId = UserUtils.getmpaccounts(request);
Conds conds = new Conds();
conds.equal("del_flag", Constants.DEL_FLAG_0);
conds.equal("accounts_id", accountsId);
if (StringUtils.isNoneBlank(checkcoupon.getName())) {
conds.like("name", checkcoupon.getName());
}
Sort sort = new Sort("create_time", OrderType.DESC);
List<Checkcoupon> list = checkcouponService.fetchSearchByPage(conds, sort, iDisplayStart, iDisplayLength);
Integer counts = checkcouponService.count(conds);
JSONObject rtnJson = new JSONObject();
rtnJson.put("iTotalRecords", counts);
rtnJson.put("iTotalDisplayRecords", counts);
rtnJson.put("aaData", list);
return rtnJson;
}
//删除数据
@RequiresPermissions(value = CHECKCOUPON_EDIT)
@RequestMapping("/delete")
@ResponseBody
public JSONObject delete(String id) {
JSONObject rtnJosn = new JSONObject();
try {
checkcouponService.delete(id);
rtnJosn.put("errorNo", 0);
} catch (Exception e) {
rtnJosn.put("errorNo", 1);
}
return rtnJosn;
}
@RequestMapping("/exportExcel")
@RequiresPermissions(value = CHECKCOUPON_VIEW)
public void exportExcel(HttpServletRequest request, HttpServletResponse response) {
Long accountId = UserUtils.getmpaccounts(request);
Sort sort = new Sort("create_time", OrderType.ASC);
Conds conds = new Conds();
conds.equal("del_flag", 0);
conds.equal("accounts_id", accountId);
List<Checkcoupon> list = checkcouponService.fetchSearchByPage(conds, sort, 0, 0);
ExcelKit.$Export(Checkcoupon.class, response).toExcel(list, "检测券管理信息");
}
@RequestMapping("/templateExcel")
@RequiresPermissions(value = CHECKCOUPON_VIEW)
public void templateExcel(HttpServletRequest request, HttpServletResponse response) {
ExcelKit.$Export(Checkcoupon.class, response).toExcel(null, "检测券管理信息");
}
@RequestMapping("/importExcel")
@RequiresPermissions(value = CHECKCOUPON_EDIT)
public String importExcel(HttpServletRequest request, MultipartFile file, Model model) {
Long accountId = UserUtils.getmpaccounts(request);
if (file == null) {
return list(request, model);
}
// 构造临时路径来存储上传的文件
String uploadPath = System.getProperty("java.io.tmpdir");
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
String fileName = file.getOriginalFilename();
String filePath = uploadPath + File.separator + fileName;
File storeFile = new File(filePath);
try {
file.transferTo(storeFile);
ExcelKit.$Import().setEmptyCellValue("").readExcel(storeFile, rowData -> {
if (!StringUtils.isEmpty(rowData.get(0))) {
Checkcoupon checkcoupon = new Checkcoupon();
checkcoupon.setAccountsId(accountId);
checkcouponService.save(checkcoupon);
}
});
} catch (IOException e) {
log.error(e.getMessage());
}
return list(request, model);
}
}
<?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/maven-v4_0_0.xsd">
<parent>
<artifactId>aidea-modules</artifactId>
<groupId>com.cftech</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<name>checkresult-module-web</name>
<groupId>com.cftech</groupId>
<artifactId>checkresult-module-web</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<finalName>checkresult-module-web</finalName>
</build>
<dependencies>
<dependency>
<groupId>com.cftech</groupId>
<artifactId>checkresult-module</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<!DOCTYPE html>
<!--[if IE 8]>
<html lang="en" class="ie8 no-js"> <![endif]-->
<!--[if IE 9]>
<html lang="en" class="ie9 no-js"> <![endif]-->
<!--[if !IE]><!-->
<html>
<!--<![endif]-->
<!-- BEGIN HEAD -->
<head>
<base href="#springUrl('/assets/adminlte/')"/>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>工作台</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.5 -->
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="plugins/font-awesome/css/font-awesome.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="plugins/ionicons/css/ionicons.min.css">
<!-- DataTables -->
<link rel="stylesheet" href="plugins/datatables/dataTables.bootstrap.css">
<!-- Theme style -->
<link rel="stylesheet" href="dist/css/AdminLTE.min.css">
<!-- AdminLTE Skins. Choose a skin from the css/skins
folder instead of downloading all of them to reduce the load. -->
<link rel="stylesheet" href="dist/css/skins/_all-skins.min.css">
<!-- iCheck -->
<link rel="stylesheet" href="plugins/iCheck/flat/blue.css">
<!-- Date Picker -->
<link rel="stylesheet" href="plugins/datepicker/datepicker3.css">
<!-- Daterange picker -->
<link rel="stylesheet" href="plugins/daterangepicker/daterangepicker-bs3.css">
<!-- bootstrap wysihtml5 - text editor -->
<link rel="stylesheet" href="plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<!--validate css-->
<link rel="stylesheet" href="plugins/jquery-validation/css/validate.css">
<!--fileinput css-->
<link rel="stylesheet" href="plugins/bootstrap-fileinput/bootstrap-fileinput.css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<!-- END HEAD -->
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<div class="content-wrapper" style="margin-left:0;">
<section class="content-header">
<h1>
检测结果管理管理
<small>检测结果管理</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i>首页</a></li>
<li><a class="active">检测结果管理</a></li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<div class="row">
<div class="col-xs-12">
<!-- general form elements disabled -->
<div class="box box-primary">
<form role="form" id="myForm">
<input name="id" value="$!{data.id}" hidden="true"/>
<div class="box-body">
</div>
<div class="box-footer">
#if($shiro.hasPermission("qy:checkresult:edit"))
<input class="btn btn-primary" id="save" value="保存" type="submit">
#end
<a href="#springUrl('/a/checkresult/list')" class="btn btn-default">取消</a>
</div>
</form>
<!-- /.box-body -->
</div><!-- /.box -->
</div><!-- /.col -->
</div><!-- /.row -->
</section><!-- /.content -->
</div><!-- /.content-wrapper -->
<!-- Add the sidebar's background. This div must be placed
immediately after the control sidebar -->
<div class="control-sidebar-bg"></div>
</div><!-- ./wrapper -->
<script src="plugins/jQuery/jQuery-2.1.4.min.js"></script>
<!-- Bootstrap 3.3.5 -->
<script src="bootstrap/js/bootstrap.min.js"></script>
<!-- DataTables -->
<script src="plugins/datatables/jquery.dataTables.min.js"></script>
<script src="plugins/datatables/extensions/i18n/lanauage_ch.js"></script>
<script src="plugins/datatables/dataTables.bootstrap.min.js"></script>
<!-- SlimScroll -->
<script src="plugins/slimScroll/jquery.slimscroll.min.js"></script>
<!-- FastClick -->
<script src="plugins/fastclick/fastclick.min.js"></script>
<!--fileinput js-->
<script src="plugins/bootstrap-fileinput/bootstrap-fileinput.js"></script>
<!-- AdminLTE App -->
<script src="dist/js/app.min.js"></script>
<script src="plugins/bootstrap-maxlength/bootstrap-maxlength.min.js" type="text/javascript"></script>
<script src="plugins/security/sha256.js" type="text/javascript"></script>
<script src="plugins/jquery-validation/js/jquery.validate.min.js"></script>
<script src="js/jquery.form.min.js"></script>
<script type="text/javascript" charset="utf-8" src="plugins/ueditor-min-1.4.3/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="plugins/ueditor-min-1.4.3/ueditor.all.js"></script>
<script type="text/javascript" charset="utf-8" src="plugins/ueditor-min-1.4.3/lang/zh-cn/zh-cn.js"></script>
<script src="common/js/cfapp.js"></script>
<!-- END PAGE LEVEL PLUGINS -->
<script>
$().ready(function () {
Cfapp.init();
recdTypeAdd.init();
});
var recdTypeAdd = function () {
var initForm = function () {
var initFormCtrl = function () {
bindEvent();
};
var bindEvent = function () {
$("#myForm").validate({
rules: {},
messages: {},
submitHandler: function (form) {
$("#save").attr("disabled", true);
$.getJSON("#springUrl('/a/checkresult/formData')", $("#myForm").serialize(), function (returnobj) {
$("#save").attr("disabled", false);
if (returnobj.errorNo == 2) { //保存成功
Cfapp.confirm({
message: "添加成功",
btnoktext: "继续添加",
btncanceltext: "关闭",
success: function () {
location.href = "#springUrl('/a/checkresult/form')";
},
cancel: function () {
location.href = "#springUrl('/a/checkresult/list')";
}
});
} else if (returnobj.errorNo == 0) { //修改成功
Cfapp.alert({
message: "更新成功",
btntext: "确定",
success: function () {
location.href = "#springUrl('/a/checkresult/list')";
}
});
} else {
Cfapp.alert({
message: "创建失败",
btntext: "确定",
success: function () {
location.href = "#springUrl('/a/checkresult/list')";
}
});
}
});
}
})
}
initFormCtrl();
}
return {
//main function to initiate the module
init: function () {
initForm();
}
};
}();
</script>
</body>
<!-- END BODY -->
</html>
\ No newline at end of file
<!DOCTYPE html>
<!--[if IE 8]>
<html lang="en" class="ie8 no-js"> <![endif]-->
<!--[if IE 9]>
<html lang="en" class="ie9 no-js"> <![endif]-->
<!--[if !IE]><!-->
<html>
<!--<![endif]-->
<!-- BEGIN HEAD -->
<head>
<base href="#springUrl('/assets/adminlte/')"/>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>工作台</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.5 -->
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="plugins/font-awesome/css/font-awesome.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="plugins/ionicons/css/ionicons.min.css">
<!-- DataTables -->
<link rel="stylesheet" href="plugins/datatables/dataTables.bootstrap.css">
<!-- Theme style -->
<link rel="stylesheet" href="dist/css/AdminLTE.min.css">
<!-- AdminLTE Skins. Choose a skin from the css/skins
folder instead of downloading all of them to reduce the load. -->
<link rel="stylesheet" href="dist/css/skins/_all-skins.min.css">
<!-- iCheck -->
<link rel="stylesheet" href="plugins/iCheck/flat/blue.css">
<!-- Morris chart -->
<link rel="stylesheet" href="plugins/morris/morris.css">
<!-- jvectormap -->
<link rel="stylesheet" href="plugins/jvectormap/jquery-jvectormap-1.2.2.css">
<!-- Date Picker -->
<link rel="stylesheet" href="plugins/datepicker/datepicker3.css">
<!-- Daterange picker -->
<link rel="stylesheet" href="plugins/daterangepicker/daterangepicker-bs3.css">
<link rel="stylesheet"
href="plugins\bootstrap-fileinput\fileinput.min.css">
<!-- bootstrap wysihtml5 - text editor -->
<link rel="stylesheet" href="plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<div class="content-wrapper" style="margin-left:0;">
<div id="importExcelDiv"></div>
<section class="content-header">
<h1>
检测结果管理管理
<small>检测结果管理</small>
</h1>
<ol class="breadcrumb">
<li><a><i class="fa fa-dashboard"></i>首页</a></li>
<li><a class="active">检测结果管理管理列表</a></li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<div class="row">
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<form id="seachTableForm" action="#springUrl('/a/checkresult/list')" method="get">
<div class="col-xs-5">
<button type="button" class="search btn btn-primary">搜索</button>
#if($shiro.hasPermission("qy:checkresult:edit"))
<a href="#springUrl('/a/checkresult/form')" class="btn btn-primary">新增</a>
<a href="#springUrl('/a/checkresult/exportExcel')" class="btn btn-primary">导出</a>
<a onclick="importExcel();" class="btn btn-primary">导入</a>
#end
</div>
</form>
</div><!-- /.box-header -->
<div class="box-body">
<table id="table" class="table table-bordered table-striped">
<thead>
<tr>
<td hidden="true">Id</td><th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="tablebody">
</tbody>
</table>
</div><!-- /.box-body -->
</div><!-- /.box -->
</div><!-- /.col -->
</div><!-- /.row -->
</section><!-- /.content -->
</div><!-- /.content-wrapper -->
<!-- Add the sidebar's background. This div must be placed
immediately after the control sidebar -->
<div class="control-sidebar-bg"></div>
</div><!-- ./wrapper -->
<!-- jQuery 2.1.4 -->
<script src="plugins/jQuery/jQuery-2.1.4.min.js"></script>
<!-- Bootstrap 3.3.5 -->
<script src="bootstrap/js/bootstrap.min.js"></script>
<!-- DataTables -->
<script src="plugins/datatables/jquery.dataTables.min.js"></script>
<script src="plugins/datatables/extensions/i18n/lanauage_ch.js"></script>
<script src="plugins/datatables/dataTables.bootstrap.min.js"></script>
<!-- SlimScroll -->
<script src="plugins/slimScroll/jquery.slimscroll.min.js"></script>
<script src="plugins/datepicker/bootstrap-datepicker.js"></script>
<script src="plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script>
<!-- FastClick -->
<script src="plugins/fastclick/fastclick.min.js"></script>
<!--fileinput js-->
<script src="plugins\bootstrap-fileinput\fileinput.js"></script>
<script src="plugins/bootstrap-fileinput/zh.js"></script>
<script src="plugins/bootstrap-fileinput/zh2.js"></script>
<!-- AdminLTE App -->
<script src="dist/js/app.min.js"></script>
<script type="text/javascript"
src="plugins/jquery-validation/js/jquery.validate.min.js"></script>
<!-- AdminLTE for demo purposes -->
<script src="common/js/cfapp.js"></script>
<script>
function formatDates(now) {
var now = new Date(now);
var year = now.getFullYear();
var month = now.getMonth() + 1;
var date = now.getDate();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
return year + "-" + month + "-" + date + " " + hour + ":"
+ minute + ":" + second;
}
function seachTable() {
var sSource = "#springUrl('/a/checkresult/listData')";
var aoData = {
iDisplayStart: 1,
iDosplayLength: 10
}
var retrieveData = function (sSource, aoData, fnCallback) {
$("#seachTableForm input").each(function () {
var params = {
name: $(this).attr("name"),
value: $(this).val()
};
aoData.push(params);
})
$.ajax({
"type": "GET",
"url": sSource,
"dataType": "json",
"data": aoData, //以json格式传递
"success": fnCallback
});
};
$('#table').DataTable({
"lengthChange": false,
"searching": false,
"ordering": false,
"bFiltered": false,
"bStateSave": true, // save datatable state(pagination, sort, etc) in cookie.
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": sSource,
"fnServerData": retrieveData,
"pagingType": "full_numbers",
"aoColumns": [
{
"mData": "id"
},
{
"mData": "createTime"
},
{
"mData": "id"
}],
"aoColumnDefs": [
{ // set default column settings
'visible': false,
'targets': [0]
},
{
"aTargets": [1],
"mData": "createTime",
"mRender": function (a, b, c, d) {
return '<a href="#springUrl("/a/checkresult/form?id=' + c.id + '")" data-id="' + c.id + '" data-action="view">' + formatDates(a, "yyyy-MM-dd HH:mm:ss");
+'</a>';
}
},
]
});
}
jQuery(document).ready(function () {
seachTable();
$('.datepicker').datepicker({
show: true,
format: 'yyyy-mm-dd',
autoclose: true,
language: 'zh-CN',
todayBtn: 'linked',
clearBtn: 'linked'
});
$('.search').click(function () {
$("#table").dataTable().fnClearTable();
});
});
Cfapp.init();
function removeData(data) {
Cfapp.confirm({
message: "确定要删除吗",
btnoktext: "确定",
btncanceltext: "取消",
success: function () {
$.ajax({
type: "POST",
url: "#springUrl('/a/checkresult/delete')",
data: {id: data},
dataType: "json",
success: function (data) {
if (data.errorNo == 0) {
Cfapp.alert({
message: "删除成功",
btntext: "确定",
success: function () {
location.href = "#springUrl('/a/checkresult/list')";
}
});
}
},
error: function () {
}
})
},
cancel: function () {
$(".modal-backdrop").fadeOut();
}
});
}
function importExcel() {
var templateExcelUrl = "#springUrl('/a/checkresult/templateExcel')";
var importExcelUrl = "#springUrl('/a/checkresult/importExcel')";
Cfapp.importExcel({
title: '检测结果管理导入',
importurl: importExcelUrl,
templateurl: templateExcelUrl,
cancel: function () {
},
success: function () {
}
});
}
</script>
</body>
</html>
<?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>aidea-modules</artifactId>
<groupId>com.cftech</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>checkresult-module</artifactId>
</project>
\ No newline at end of file
package com.cftech.checkresult.dao;
import com.cftech.checkresult.model.Checkresult;
import com.cftech.core.generic.GenericDao;
/**
* 检测结果管理Mapper
*
* @author Strive
* @date: 2021-01-27 17:19
*/
public interface CheckresultMapper extends GenericDao<Checkresult> {
}
\ No newline at end of file
<?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.cftech.checkresult.dao.CheckresultMapper">
<resultMap id="resultMap" type="com.cftech.checkresult.model.Checkresult">
<id column="id" property="id"/>
<result column="send_check_no" property="sendCheckNo"/>
<result column="check_date" property="checkDate"/>
<result column="reagent_batch_no" property="reagentBatchNo"/>
<result column="reagent_verif_date" property="reagentVerifDate"/>
<result column="number" property="number"/>
<result column="check_project" property="checkProject"/>
<result column="openid" property="openid"/>
<result column="result" property="result"/>
<result column="lower_limit" property="lowerLimit"/>
<result column="brand" property="brand"/>
<result column="check_method" property="checkMethod"/>
<result column="unit" property="unit"/>
<result column="instrument" property="instrument"/>
<result column="auditor" property="auditor"/>
<result column="audit_date" property="auditDate"/>
<result column="checked_by" property="checkedBy"/>
<result column="accounts_id" property="accountsId"/>
<result column="del_flag" property="delFlag"/>
<result column="status" property="status"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="description" property="description"/>
<result column="create_by" property="createBy"/>
<result column="update_by" property="updateBy"/>
</resultMap>
<sql id="sqlWhere">
<if test="conds!=null">
<trim prefix="WHERE" prefixOverrides="AND|OR">
<foreach collection="conds.conds" index="index" item="cond">
${cond.linkType}
<if test="cond.condType == 'EQUAL'">${cond.param} = #{cond.value}</if>
<if test="cond.condType == 'NOTEQUAL'">${cond.param} &lt;&gt; #{cond.value}</if>
<if test="cond.condType == 'GREATEQUAL'">${cond.param} &gt;= #{cond.value}</if>
<if test="cond.condType == 'GREATTHAN'">${cond.param} &gt; #{cond.value}</if>
<if test="cond.condType == 'LESSEQUAL'">${cond.param} &lt;= #{cond.value}</if>
<if test="cond.condType == 'LESSTHAN'">${cond.param} &lt; #{cond.value}</if>
<if test="cond.condType == 'BETWEEN'">${cond.param} BETWEEN #{cond.startValue} AND
#{cond.endValue}
</if>
<if test="cond.condType == 'ISNULL'">${cond.param} IS NULL</if>
<if test="cond.condType == 'NOTNULL'">${cond.param} IS NOT NULL</if>
<if test="cond.condType == 'LIKE'">${cond.param} LIKE #{cond.value}</if>
<if test="cond.condType == 'IN'">${cond.param} IN
<foreach item="item" index="index" collection="cond.value" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</foreach>
</trim>
</if>
</sql>
<sql id="sqlColumns">
id,
send_check_no,
check_date,
reagent_batch_no,
reagent_verif_date,
number,
check_project,
openid,
result,
lower_limit,
brand,
check_method,
unit,
instrument,
auditor,
audit_date,
checked_by,
accounts_id,
del_flag,
status,
create_time,
update_time,
description,
create_by,
update_by
</sql>
<insert id="save" parameterType="com.cftech.checkresult.model.Checkresult" useGeneratedKeys="true"
keyProperty="id">
insert into t_aidea_check_result
(
<include refid="sqlColumns"/>
)
values
(
#{id, jdbcType=BIGINT},
#{sendCheckNo, jdbcType=VARCHAR},
now(),
#{reagentBatchNo, jdbcType=VARCHAR},
now(),
#{number, jdbcType=VARCHAR},
#{checkProject, jdbcType=VARCHAR},
#{openid, jdbcType=VARCHAR},
#{result, jdbcType=VARCHAR},
#{lowerLimit, jdbcType=VARCHAR},
#{brand, jdbcType=VARCHAR},
#{checkMethod, jdbcType=VARCHAR},
#{unit, jdbcType=VARCHAR},
#{instrument, jdbcType=VARCHAR},
#{auditor, jdbcType=VARCHAR},
now(),
#{checkedBy, jdbcType=VARCHAR},
#{accountsId, jdbcType=BIGINT},
#{delFlag, jdbcType=TINYINT},
#{status, jdbcType=VARCHAR},
now(),
now(),
#{description, jdbcType=VARCHAR},
#{createBy, jdbcType=BIGINT},
#{updateBy, jdbcType=BIGINT}
)
</insert>
<select id="fetchById" parameterType="java.lang.Long" resultMap="resultMap">
SELECT
<include refid="sqlColumns"/>
FROM t_aidea_check_result t
WHERE t.id=#{id}
</select>
<select id="count" parameterType="java.util.Map" resultType="java.lang.Integer">
SELECT COUNT(1) FROM t_aidea_check_result
<include refid="sqlWhere"/>
</select>
<select id="fetchSearchByPage" parameterType="java.util.Map" resultMap="resultMap">
SELECT
<include refid="sqlColumns"/>
FROM t_aidea_check_result
<include refid="sqlWhere"/>
<if test="sort!=null">ORDER BY ${sort.param} ${sort.type}</if>
<if test="limit>0">limit #{offset},#{limit}</if>
</select>
<update id="update" parameterType="com.cftech.checkresult.model.Checkresult">
update t_aidea_check_result
<set>
<if test="id != null">
id = #{id, jdbcType=BIGINT},
</if>
<if test="sendCheckNo != null">
send_check_no = #{sendCheckNo, jdbcType=VARCHAR},
</if>
<if test="checkDate != null">
check_date = #{checkDate, jdbcType=TIMESTAMP},
</if>
<if test="reagentBatchNo != null">
reagent_batch_no = #{reagentBatchNo, jdbcType=VARCHAR},
</if>
<if test="reagentVerifDate != null">
reagent_verif_date = #{reagentVerifDate, jdbcType=TIMESTAMP},
</if>
<if test="number != null">
number = #{number, jdbcType=VARCHAR},
</if>
<if test="checkProject != null">
check_project = #{checkProject, jdbcType=VARCHAR},
</if>
<if test="openid != null">
openid = #{openid, jdbcType=VARCHAR},
</if>
<if test="result != null">
result = #{result, jdbcType=VARCHAR},
</if>
<if test="lowerLimit != null">
lower_limit = #{lowerLimit, jdbcType=VARCHAR},
</if>
<if test="brand != null">
brand = #{brand, jdbcType=VARCHAR},
</if>
<if test="checkMethod != null">
check_method = #{checkMethod, jdbcType=VARCHAR},
</if>
<if test="unit != null">
unit = #{unit, jdbcType=VARCHAR},
</if>
<if test="instrument != null">
instrument = #{instrument, jdbcType=VARCHAR},
</if>
<if test="auditor != null">
auditor = #{auditor, jdbcType=VARCHAR},
</if>
<if test="auditDate != null">
audit_date = #{auditDate, jdbcType=TIMESTAMP},
</if>
<if test="checkedBy != null">
checked_by = #{checkedBy, jdbcType=VARCHAR},
</if>
<if test="accountsId != null">
accounts_id = #{accountsId, jdbcType=BIGINT},
</if>
<if test="delFlag != null">
del_flag = #{delFlag, jdbcType=TINYINT},
</if>
<if test="status != null">
status = #{status, jdbcType=VARCHAR},
</if>
<if test="createTime != null">
create_time = #{createTime, jdbcType=TIMESTAMP},
</if>
<if test="description != null">
description = #{description, jdbcType=VARCHAR},
</if>
<if test="createBy != null">
create_by = #{createBy, jdbcType=BIGINT},
</if>
<if test="updateBy != null">
update_by = #{updateBy, jdbcType=BIGINT},
</if>
</set>
where id=#{id,jdbcType=BIGINT}
</update>
<update id="delete" parameterType="java.lang.Long">
update t_aidea_check_result set del_flag=1 where id=#{id,jdbcType=BIGINT}
</update>
</mapper>
\ No newline at end of file
package com.cftech.checkresult.model;
import com.cftech.core.poi.ExportConfig;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 检测结果管理
*
* @author Strive
* @date: 2021-01-27 17:19
*/
@Data
public class Checkresult implements Serializable {
/* 主键id */
private Long id;
/* 送检编号 */
@ExportConfig(value = "送检编号", width = 100, showLevel = 1)
private String sendCheckNo;
/* 送检时间 */
@ExportConfig(value = "送检时间", width = 100, showLevel = 1)
private Date checkDate;
/* 检测试剂编号 */
@ExportConfig(value = "检测试剂编号", width = 100, showLevel = 1)
private String reagentBatchNo;
/* 检测试剂有效期 */
@ExportConfig(value = "检测试剂有效期", width = 100, showLevel = 1)
private Date reagentVerifDate;
/* 检测编号 */
@ExportConfig(value = "检测编号", width = 100, showLevel = 1)
private String number;
/* 检测项目 */
@ExportConfig(value = "检测项目", width = 100, showLevel = 1)
private String checkProject;
/* 粉丝id */
@ExportConfig(value = "粉丝id", width = 100, showLevel = 1)
private String openid;
/* 检测结果 */
@ExportConfig(value = "检测结果", width = 100, showLevel = 1)
private String result;
/* 试剂盒检测下限 */
@ExportConfig(value = "试剂盒检测下限", width = 100, showLevel = 1)
private String lowerLimit;
/* 试剂品牌 */
@ExportConfig(value = "试剂品牌", width = 100, showLevel = 1)
private String brand;
/* 检测方法 */
@ExportConfig(value = "检测方法", width = 100, showLevel = 1)
private String checkMethod;
/* 单位 */
@ExportConfig(value = "单位", width = 100, showLevel = 1)
private String unit;
/* 仪器名称 */
@ExportConfig(value = "仪器名称", width = 100, showLevel = 1)
private String instrument;
/* 审核人 */
@ExportConfig(value = "审核人", width = 100, showLevel = 1)
private String auditor;
/* 审核时间 */
@ExportConfig(value = "审核时间", width = 100, showLevel = 1)
private Date auditDate;
/* 检测人 */
@ExportConfig(value = "检测人", width = 100, showLevel = 1)
private String checkedBy;
/* 所属的账号 */
private Long accountsId;
/* 删除标识 */
private boolean delFlag;
/* 状态 */
private String status;
/* 创建时间 */
private Date createTime;
/* 更新时间 */
private Date updateTime;
/* 备注 */
private String description;
/* 创建人 */
private Long createBy;
/* 更新人 */
private Long updateBy;
public Checkresult() {
this.delFlag = false;
this.status = "0";
}
}
\ No newline at end of file
package com.cftech.checkresult.service;
import com.cftech.checkresult.model.Checkresult;
import com.cftech.core.generic.GenericService;
/**
* 检测结果管理Service
*
* @author Strive
* @date: 2021-01-27 17:19
*/
public interface CheckresultService extends GenericService<Checkresult> {
}
package com.cftech.checkresult.service.impl;
import com.cftech.checkresult.model.Checkresult;
import com.cftech.checkresult.dao.CheckresultMapper;
import com.cftech.checkresult.service.CheckresultService;
import com.cftech.core.generic.GenericDao;
import com.cftech.core.generic.GenericServiceImpl;
import com.cftech.core.sql.Conds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
/**
* 检测结果管理ServiceImpl
*
* @author Strive
* @date: 2021-01-27 17:19
*/
@Service("checkresultService")
public class CheckresultServiceImpl extends GenericServiceImpl<Checkresult> implements CheckresultService {
@Autowired
@Qualifier("checkresultMapper")
private CheckresultMapper checkresultMapper;
@Override
public GenericDao<Checkresult> getGenericMapper() {
return checkresultMapper;
}
}
\ No newline at end of file
package com.cftech.checkresult.web;
import com.alibaba.fastjson.JSONObject;
import com.cftech.checkresult.model.Checkresult;
import com.cftech.checkresult.service.CheckresultService;
import com.cftech.core.poi.ExcelKit;
import com.cftech.core.scope.OrderType;
import com.cftech.core.sql.Conds;
import com.cftech.core.sql.Sort;
import com.cftech.core.util.Constants;
import com.cftech.sys.security.PermissionSign;
import com.cftech.sys.security.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* 检测结果管理Controller
*
* 权限字符串说明:
* 查看:public static final String CHECKRESULT_VIEW = "qy:checkresult:view"
* 查看:public static final String CHECKRESULT_EDIT = "qy:checkresult:edit"
*
* @author Strive
* @date: 2021-01-27 17:19
*/
@Slf4j
@Controller
@RequestMapping("/a/checkresult")
public class CheckresultController {
public static final String CHECKRESULT_VIEW = "qy:checkresult:view";
public static final String CHECKRESULT_EDIT = "qy:checkresult:edit";
@Autowired
private CheckresultService checkresultService;
//列表页面
@RequiresPermissions(value = CHECKRESULT_VIEW)
@RequestMapping("/list")
public String list(HttpServletRequest request, Model model) {
Long accountId = UserUtils.getmpaccounts(request);
model.addAttribute("accountId", accountId);
return "checkresult/checkresultlist";
}
//编辑页面(新增、修改)
@RequiresPermissions(value = CHECKRESULT_VIEW)
@RequestMapping("/form")
public String form(HttpServletRequest request, String id, Model model) {
if (!StringUtils.isEmpty(id)) {
Checkresult checkresult = checkresultService.fetchById(id);
model.addAttribute("data", checkresult);
}
return "checkresult/checkresultform";
}
//提交数据(新增、修改)
@RequiresPermissions(value = CHECKRESULT_EDIT)
@RequestMapping("/formData")
@ResponseBody
public JSONObject formData(Checkresult checkresult, Model model, HttpServletRequest request) {
Long accountsId = UserUtils.getmpaccounts(request);
JSONObject rtnJson = new JSONObject();
try {
if (checkresult != null && checkresult.getId() != null) {
checkresult.setUpdateBy(UserUtils.getUser().getId());
checkresultService.update(checkresult);
rtnJson.put("errorNo", 0);
} else {
checkresult.setAccountsId(accountsId);
checkresult.setDelFlag(false);
checkresult.setAccountsId(UserUtils.getmpaccounts(request));
checkresult.setCreateBy(UserUtils.getUser().getId());
checkresult.setUpdateBy(UserUtils.getUser().getId());
checkresultService.save(checkresult);
rtnJson.put("errorNo", 2);
}
} catch (Exception e) {
rtnJson.put("errorNo", 1);
}
return rtnJson;
}
//获取列表数据
@RequiresPermissions(value = CHECKRESULT_VIEW)
@RequestMapping(value = "/listData")
@ResponseBody
public JSONObject listData(int iDisplayStart, int iDisplayLength, Checkresult checkresult, HttpServletRequest request) {
Long accountsId = UserUtils.getmpaccounts(request);
Conds conds = new Conds();
conds.equal("del_flag", Constants.DEL_FLAG_0);
conds.equal("accounts_id", accountsId);
Sort sort = new Sort("create_time", OrderType.DESC);
List<Checkresult> list = checkresultService.fetchSearchByPage(conds, sort, iDisplayStart, iDisplayLength);
Integer counts = checkresultService.count(conds);
JSONObject rtnJson = new JSONObject();
rtnJson.put("iTotalRecords", counts);
rtnJson.put("iTotalDisplayRecords", counts);
rtnJson.put("aaData", list);
return rtnJson;
}
//删除数据
@RequiresPermissions(value = CHECKRESULT_EDIT)
@RequestMapping("/delete")
@ResponseBody
public JSONObject delete(String id) {
JSONObject rtnJosn = new JSONObject();
try {
checkresultService.delete(id);
rtnJosn.put("errorNo", 0);
} catch (Exception e) {
rtnJosn.put("errorNo", 1);
}
return rtnJosn;
}
@RequestMapping("/exportExcel")
@RequiresPermissions(value = CHECKRESULT_VIEW)
public void exportExcel(HttpServletRequest request, HttpServletResponse response) {
Long accountId = UserUtils.getmpaccounts(request);
Sort sort = new Sort("create_time", OrderType.ASC);
Conds conds = new Conds();
conds.equal("del_flag", 0);
conds.equal("accounts_id", accountId);
List<Checkresult> list = checkresultService.fetchSearchByPage(conds, sort, 0, 0);
ExcelKit.$Export(Checkresult.class, response).toExcel(list, "检测结果管理信息");
}
@RequestMapping("/templateExcel")
@RequiresPermissions(value = CHECKRESULT_VIEW)
public void templateExcel(HttpServletRequest request, HttpServletResponse response) {
ExcelKit.$Export(Checkresult.class, response).toExcel(null, "检测结果管理信息");
}
@RequestMapping("/importExcel")
@RequiresPermissions(value = CHECKRESULT_EDIT)
public String importExcel(HttpServletRequest request, MultipartFile file, Model model) {
Long accountId = UserUtils.getmpaccounts(request);
if (file == null) {
return list(request, model);
}
// 构造临时路径来存储上传的文件
String uploadPath = System.getProperty("java.io.tmpdir");
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
String fileName = file.getOriginalFilename();
String filePath = uploadPath + File.separator + fileName;
File storeFile = new File(filePath);
try {
file.transferTo(storeFile);
ExcelKit.$Import().setEmptyCellValue("").readExcel(storeFile, rowData -> {
if (!StringUtils.isEmpty(rowData.get(0))) {
Checkresult checkresult = new Checkresult();
checkresult.setAccountsId(accountId);
checkresultService.save(checkresult);
}
});
} catch (IOException e) {
log.error(e.getMessage());
}
return list(request, model);
}
}
<?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/maven-v4_0_0.xsd">
<parent>
<artifactId>aidea-modules</artifactId>
<groupId>com.cftech</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<name>couponrecord-module-web</name>
<groupId>com.cftech</groupId>
<artifactId>couponrecord-module-web</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.cftech</groupId>
<artifactId>couponrecord-module</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<finalName>couponrecord-module-web</finalName>
</build>
</project>
<!DOCTYPE html>
<!--[if IE 8]>
<html lang="en" class="ie8 no-js"> <![endif]-->
<!--[if IE 9]>
<html lang="en" class="ie9 no-js"> <![endif]-->
<!--[if !IE]><!-->
<html>
<!--<![endif]-->
<!-- BEGIN HEAD -->
<head>
<base href="#springUrl('/assets/adminlte/')"/>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>工作台</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.5 -->
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="plugins/font-awesome/css/font-awesome.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="plugins/ionicons/css/ionicons.min.css">
<!-- DataTables -->
<link rel="stylesheet" href="plugins/datatables/dataTables.bootstrap.css">
<!-- Theme style -->
<link rel="stylesheet" href="dist/css/AdminLTE.min.css">
<!-- AdminLTE Skins. Choose a skin from the css/skins
folder instead of downloading all of them to reduce the load. -->
<link rel="stylesheet" href="dist/css/skins/_all-skins.min.css">
<!-- iCheck -->
<link rel="stylesheet" href="plugins/iCheck/flat/blue.css">
<!-- Date Picker -->
<link rel="stylesheet" href="plugins/datepicker/datepicker3.css">
<!-- Daterange picker -->
<link rel="stylesheet" href="plugins/daterangepicker/daterangepicker-bs3.css">
<!-- bootstrap wysihtml5 - text editor -->
<link rel="stylesheet" href="plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<!--validate css-->
<link rel="stylesheet" href="plugins/jquery-validation/css/validate.css">
<!--fileinput css-->
<link rel="stylesheet" href="plugins/bootstrap-fileinput/bootstrap-fileinput.css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<!-- END HEAD -->
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<div class="content-wrapper" style="margin-left:0;">
<section class="content-header">
<h1>
发券信息管理管理
<small>发券信息管理</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i>首页</a></li>
<li><a class="active">发券信息管理</a></li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<div class="row">
<div class="col-xs-12">
<!-- general form elements disabled -->
<div class="box box-primary">
<form role="form" id="myForm">
<input name="id" value="$!{data.id}" hidden="true"/>
<div class="box-body">
</div>
<div class="box-footer">
#if($shiro.hasPermission("qy:couponrecord:edit"))
<input class="btn btn-primary" id="save" value="保存" type="submit">
#end
<a href="#springUrl('/a/couponrecord/list')" class="btn btn-default">取消</a>
</div>
</form>
<!-- /.box-body -->
</div><!-- /.box -->
</div><!-- /.col -->
</div><!-- /.row -->
</section><!-- /.content -->
</div><!-- /.content-wrapper -->
<!-- Add the sidebar's background. This div must be placed
immediately after the control sidebar -->
<div class="control-sidebar-bg"></div>
</div><!-- ./wrapper -->
<script src="plugins/jQuery/jQuery-2.1.4.min.js"></script>
<!-- Bootstrap 3.3.5 -->
<script src="bootstrap/js/bootstrap.min.js"></script>
<!-- DataTables -->
<script src="plugins/datatables/jquery.dataTables.min.js"></script>
<script src="plugins/datatables/extensions/i18n/lanauage_ch.js"></script>
<script src="plugins/datatables/dataTables.bootstrap.min.js"></script>
<!-- SlimScroll -->
<script src="plugins/slimScroll/jquery.slimscroll.min.js"></script>
<!-- FastClick -->
<script src="plugins/fastclick/fastclick.min.js"></script>
<!--fileinput js-->
<script src="plugins/bootstrap-fileinput/bootstrap-fileinput.js"></script>
<!-- AdminLTE App -->
<script src="dist/js/app.min.js"></script>
<script src="plugins/bootstrap-maxlength/bootstrap-maxlength.min.js" type="text/javascript"></script>
<script src="plugins/security/sha256.js" type="text/javascript"></script>
<script src="plugins/jquery-validation/js/jquery.validate.min.js"></script>
<script src="js/jquery.form.min.js"></script>
<script type="text/javascript" charset="utf-8" src="plugins/ueditor-min-1.4.3/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="plugins/ueditor-min-1.4.3/ueditor.all.js"></script>
<script type="text/javascript" charset="utf-8" src="plugins/ueditor-min-1.4.3/lang/zh-cn/zh-cn.js"></script>
<script src="common/js/cfapp.js"></script>
<!-- END PAGE LEVEL PLUGINS -->
<script>
$().ready(function () {
Cfapp.init();
recdTypeAdd.init();
});
var recdTypeAdd = function () {
var initForm = function () {
var initFormCtrl = function () {
bindEvent();
};
var bindEvent = function () {
$("#myForm").validate({
rules: {},
messages: {},
submitHandler: function (form) {
$("#save").attr("disabled", true);
$.getJSON("#springUrl('/a/couponrecord/formData')", $("#myForm").serialize(), function (returnobj) {
$("#save").attr("disabled", false);
if (returnobj.errorNo == 2) { //保存成功
Cfapp.confirm({
message: "添加成功",
btnoktext: "继续添加",
btncanceltext: "关闭",
success: function () {
location.href = "#springUrl('/a/couponrecord/form')";
},
cancel: function () {
location.href = "#springUrl('/a/couponrecord/list')";
}
});
} else if (returnobj.errorNo == 0) { //修改成功
Cfapp.alert({
message: "更新成功",
btntext: "确定",
success: function () {
location.href = "#springUrl('/a/couponrecord/list')";
}
});
} else {
Cfapp.alert({
message: "创建失败",
btntext: "确定",
success: function () {
location.href = "#springUrl('/a/couponrecord/list')";
}
});
}
});
}
})
}
initFormCtrl();
}
return {
//main function to initiate the module
init: function () {
initForm();
}
};
}();
</script>
</body>
<!-- END BODY -->
</html>
\ No newline at end of file
<!DOCTYPE html>
<!--[if IE 8]>
<html lang="en" class="ie8 no-js"> <![endif]-->
<!--[if IE 9]>
<html lang="en" class="ie9 no-js"> <![endif]-->
<!--[if !IE]><!-->
<html>
<!--<![endif]-->
<!-- BEGIN HEAD -->
<head>
<base href="#springUrl('/assets/adminlte/')"/>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>工作台</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.5 -->
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="plugins/font-awesome/css/font-awesome.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="plugins/ionicons/css/ionicons.min.css">
<!-- DataTables -->
<link rel="stylesheet" href="plugins/datatables/dataTables.bootstrap.css">
<!-- Theme style -->
<link rel="stylesheet" href="dist/css/AdminLTE.min.css">
<!-- AdminLTE Skins. Choose a skin from the css/skins
folder instead of downloading all of them to reduce the load. -->
<link rel="stylesheet" href="dist/css/skins/_all-skins.min.css">
<!-- iCheck -->
<link rel="stylesheet" href="plugins/iCheck/flat/blue.css">
<!-- Morris chart -->
<link rel="stylesheet" href="plugins/morris/morris.css">
<!-- jvectormap -->
<link rel="stylesheet" href="plugins/jvectormap/jquery-jvectormap-1.2.2.css">
<!-- Date Picker -->
<link rel="stylesheet" href="plugins/datepicker/datepicker3.css">
<!-- Daterange picker -->
<link rel="stylesheet" href="plugins/daterangepicker/daterangepicker-bs3.css">
<link rel="stylesheet"
href="plugins\bootstrap-fileinput\fileinput.min.css">
<!-- bootstrap wysihtml5 - text editor -->
<link rel="stylesheet" href="plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<div class="content-wrapper" style="margin-left:0;">
<div id="importExcelDiv"></div>
<section class="content-header">
<h1>
发券信息管理管理
<small>发券信息管理</small>
</h1>
<ol class="breadcrumb">
<li><a><i class="fa fa-dashboard"></i>首页</a></li>
<li><a class="active">发券信息管理管理列表</a></li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<div class="row">
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<form id="seachTableForm" action="#springUrl('/a/couponrecord/list')" method="get">
<div class="col-xs-5">
<button type="button" class="search btn btn-primary">搜索</button>
#if($shiro.hasPermission("qy:couponrecord:edit"))
<a href="#springUrl('/a/couponrecord/form')" class="btn btn-primary">新增</a>
<a href="#springUrl('/a/couponrecord/exportExcel')" class="btn btn-primary">导出</a>
<a onclick="importExcel();" class="btn btn-primary">导入</a>
#end
</div>
</form>
</div><!-- /.box-header -->
<div class="box-body">
<table id="table" class="table table-bordered table-striped">
<thead>
<tr>
<td hidden="true">Id</td><th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="tablebody">
</tbody>
</table>
</div><!-- /.box-body -->
</div><!-- /.box -->
</div><!-- /.col -->
</div><!-- /.row -->
</section><!-- /.content -->
</div><!-- /.content-wrapper -->
<!-- Add the sidebar's background. This div must be placed
immediately after the control sidebar -->
<div class="control-sidebar-bg"></div>
</div><!-- ./wrapper -->
<!-- jQuery 2.1.4 -->
<script src="plugins/jQuery/jQuery-2.1.4.min.js"></script>
<!-- Bootstrap 3.3.5 -->
<script src="bootstrap/js/bootstrap.min.js"></script>
<!-- DataTables -->
<script src="plugins/datatables/jquery.dataTables.min.js"></script>
<script src="plugins/datatables/extensions/i18n/lanauage_ch.js"></script>
<script src="plugins/datatables/dataTables.bootstrap.min.js"></script>
<!-- SlimScroll -->
<script src="plugins/slimScroll/jquery.slimscroll.min.js"></script>
<script src="plugins/datepicker/bootstrap-datepicker.js"></script>
<script src="plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script>
<!-- FastClick -->
<script src="plugins/fastclick/fastclick.min.js"></script>
<!--fileinput js-->
<script src="plugins\bootstrap-fileinput\fileinput.js"></script>
<script src="plugins/bootstrap-fileinput/zh.js"></script>
<script src="plugins/bootstrap-fileinput/zh2.js"></script>
<!-- AdminLTE App -->
<script src="dist/js/app.min.js"></script>
<script type="text/javascript"
src="plugins/jquery-validation/js/jquery.validate.min.js"></script>
<!-- AdminLTE for demo purposes -->
<script src="common/js/cfapp.js"></script>
<script>
function formatDates(now) {
var now = new Date(now);
var year = now.getFullYear();
var month = now.getMonth() + 1;
var date = now.getDate();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
return year + "-" + month + "-" + date + " " + hour + ":"
+ minute + ":" + second;
}
function seachTable() {
var sSource = "#springUrl('/a/couponrecord/listData')";
var aoData = {
iDisplayStart: 1,
iDosplayLength: 10
}
var retrieveData = function (sSource, aoData, fnCallback) {
$("#seachTableForm input").each(function () {
var params = {
name: $(this).attr("name"),
value: $(this).val()
};
aoData.push(params);
})
$.ajax({
"type": "GET",
"url": sSource,
"dataType": "json",
"data": aoData, //以json格式传递
"success": fnCallback
});
};
$('#table').DataTable({
"lengthChange": false,
"searching": false,
"ordering": false,
"bFiltered": false,
"bStateSave": true, // save datatable state(pagination, sort, etc) in cookie.
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": sSource,
"fnServerData": retrieveData,
"pagingType": "full_numbers",
"aoColumns": [
{
"mData": "id"
},
{
"mData": "createTime"
},
{
"mData": "id"
}],
"aoColumnDefs": [
{ // set default column settings
'visible': false,
'targets': [0]
},
{
"aTargets": [1],
"mData": "createTime",
"mRender": function (a, b, c, d) {
return '<a href="#springUrl("/a/couponrecord/form?id=' + c.id + '")" data-id="' + c.id + '" data-action="view">' + formatDates(a, "yyyy-MM-dd HH:mm:ss");
+'</a>';
}
},
]
});
}
jQuery(document).ready(function () {
seachTable();
$('.datepicker').datepicker({
show: true,
format: 'yyyy-mm-dd',
autoclose: true,
language: 'zh-CN',
todayBtn: 'linked',
clearBtn: 'linked'
});
$('.search').click(function () {
$("#table").dataTable().fnClearTable();
});
});
Cfapp.init();
function removeData(data) {
Cfapp.confirm({
message: "确定要删除吗",
btnoktext: "确定",
btncanceltext: "取消",
success: function () {
$.ajax({
type: "POST",
url: "#springUrl('/a/couponrecord/delete')",
data: {id: data},
dataType: "json",
success: function (data) {
if (data.errorNo == 0) {
Cfapp.alert({
message: "删除成功",
btntext: "确定",
success: function () {
location.href = "#springUrl('/a/couponrecord/list')";
}
});
}
},
error: function () {
}
})
},
cancel: function () {
$(".modal-backdrop").fadeOut();
}
});
}
function importExcel() {
var templateExcelUrl = "#springUrl('/a/couponrecord/templateExcel')";
var importExcelUrl = "#springUrl('/a/couponrecord/importExcel')";
Cfapp.importExcel({
title: '发券信息管理导入',
importurl: importExcelUrl,
templateurl: templateExcelUrl,
cancel: function () {
},
success: function () {
}
});
}
</script>
</body>
</html>
<?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>aidea-modules</artifactId>
<groupId>com.cftech</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>couponrecord-module</artifactId>
</project>
\ No newline at end of file
package com.cftech.couponrecord.dao;
import com.cftech.couponrecord.model.Couponrecord;
import com.cftech.core.generic.GenericDao;
/**
* 发券信息管理Mapper
*
* @author Strive
* @date: 2021-01-27 15:54
*/
public interface CouponrecordMapper extends GenericDao<Couponrecord> {
}
\ No newline at end of file
<?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.cftech.couponrecord.dao.CouponrecordMapper">
<resultMap id="resultMap" type="com.cftech.couponrecord.model.Couponrecord">
<id column="id" property="id"/>
<result column="take_effect_year" property="takeEffectYear"/>
<result column="take_effect_month" property="takeEffectMonth"/>
<result column="expire_month" property="expireMonth"/>
<result column="type" property="type"/>
<result column="number" property="number"/>
<result column="openid" property="openid"/>
<result column="qrcode" property="qrcode"/>
<result column="invalid_date" property="invalidDate"/>
<result column="verif_date" property="verifDate"/>
<result column="facility_no" property="facilityNo"/>
<result column="accounts_id" property="accountsId"/>
<result column="del_flag" property="delFlag"/>
<result column="status" property="status"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="description" property="description"/>
<result column="create_by" property="createBy"/>
<result column="update_by" property="updateBy"/>
</resultMap>
<sql id="sqlWhere">
<if test="conds!=null">
<trim prefix="WHERE" prefixOverrides="AND|OR">
<foreach collection="conds.conds" index="index" item="cond">
${cond.linkType}
<if test="cond.condType == 'EQUAL'">${cond.param} = #{cond.value}</if>
<if test="cond.condType == 'NOTEQUAL'">${cond.param} &lt;&gt; #{cond.value}</if>
<if test="cond.condType == 'GREATEQUAL'">${cond.param} &gt;= #{cond.value}</if>
<if test="cond.condType == 'GREATTHAN'">${cond.param} &gt; #{cond.value}</if>
<if test="cond.condType == 'LESSEQUAL'">${cond.param} &lt;= #{cond.value}</if>
<if test="cond.condType == 'LESSTHAN'">${cond.param} &lt; #{cond.value}</if>
<if test="cond.condType == 'BETWEEN'">${cond.param} BETWEEN #{cond.startValue} AND
#{cond.endValue}
</if>
<if test="cond.condType == 'ISNULL'">${cond.param} IS NULL</if>
<if test="cond.condType == 'NOTNULL'">${cond.param} IS NOT NULL</if>
<if test="cond.condType == 'LIKE'">${cond.param} LIKE #{cond.value}</if>
<if test="cond.condType == 'IN'">${cond.param} IN
<foreach item="item" index="index" collection="cond.value" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</foreach>
</trim>
</if>
</sql>
<sql id="sqlColumns">
id
,
take_effect_year,
take_effect_month,
expire_month,
type,
number,
openid,
qrcode,
invalid_date,
verif_date,
facility_no,
accounts_id,
del_flag,
status,
create_time,
update_time,
description,
create_by,
update_by
</sql>
<insert id="save" parameterType="com.cftech.couponrecord.model.Couponrecord" useGeneratedKeys="true"
keyProperty="id">
insert into t_aidea_coupon_record
(
<include refid="sqlColumns"/>
)
values
(
#{id, jdbcType=BIGINT},
#{takeEffectYear, jdbcType=VARCHAR},
#{takeEffectMonth, jdbcType=VARCHAR},
#{expireMonth, jdbcType=VARCHAR},
#{type, jdbcType=VARCHAR},
#{number, jdbcType=VARCHAR},
#{openid, jdbcType=VARCHAR},
#{qrcode, jdbcType=VARCHAR},
now(),
now(),
now(),
#{accountsId, jdbcType=BIGINT},
#{delFlag, jdbcType=TINYINT},
#{status, jdbcType=VARCHAR},
now(),
now(),
#{description, jdbcType=VARCHAR},
#{createBy, jdbcType=BIGINT},
#{updateBy, jdbcType=BIGINT}
)
</insert>
<select id="fetchById" parameterType="java.lang.Long" resultMap="resultMap">
SELECT
<include refid="sqlColumns"/>
FROM t_aidea_coupon_record t
WHERE t.id=#{id}
</select>
<select id="count" parameterType="java.util.Map" resultType="java.lang.Integer">
SELECT COUNT(1) FROM t_aidea_coupon_record
<include refid="sqlWhere"/>
</select>
<select id="fetchSearchByPage" parameterType="java.util.Map" resultMap="resultMap">
SELECT
<include refid="sqlColumns"/>
FROM t_aidea_coupon_record
<include refid="sqlWhere"/>
<if test="sort!=null">ORDER BY ${sort.param} ${sort.type}</if>
<if test="limit>0">limit #{offset},#{limit}</if>
</select>
<update id="update" parameterType="com.cftech.couponrecord.model.Couponrecord">
update t_aidea_coupon_record
<set>
<if test="id != null">
id = #{id, jdbcType=BIGINT},
</if>
<if test="takeEffectYear != null">
take_effect_year = #{takeEffectYear, jdbcType=VARCHAR},
</if>
<if test="takeEffectMonth != null">
take_effect_month = #{takeEffectMonth, jdbcType=VARCHAR},
</if>
<if test="expireMonth != null">
expire_month = #{expireMonth, jdbcType=VARCHAR},
</if>
<if test="type != null">
type = #{type, jdbcType=VARCHAR},
</if>
<if test="number != null">
number = #{number, jdbcType=VARCHAR},
</if>
<if test="openid != null">
openid = #{openid, jdbcType=VARCHAR},
</if>
<if test="qrcode != null">
qrcode = #{qrcode, jdbcType=VARCHAR},
</if>
<if test="invalidDate != null">
invalid_date = #{invalidDate, jdbcType=TIMESTAMP},
</if>
<if test="verifDate != null">
verif_date = #{verifDate, jdbcType=TIMESTAMP},
</if>
<if test="facilityNo != null">
facility_no = #{facilityNo, jdbcType=TIMESTAMP},
</if>
<if test="accountsId != null">
accounts_id = #{accountsId, jdbcType=BIGINT},
</if>
<if test="delFlag != null">
del_flag = #{delFlag, jdbcType=TINYINT},
</if>
<if test="status != null">
status = #{status, jdbcType=VARCHAR},
</if>
<if test="createTime != null">
create_time = #{createTime, jdbcType=TIMESTAMP},
</if>
<if test="description != null">
description = #{description, jdbcType=VARCHAR},
</if>
<if test="createBy != null">
create_by = #{createBy, jdbcType=BIGINT},
</if>
<if test="updateBy != null">
update_by = #{updateBy, jdbcType=BIGINT},
</if>
</set>
where id=#{id,jdbcType=BIGINT}
</update>
<update id="delete" parameterType="java.lang.Long">
update t_aidea_coupon_record
set del_flag=1
where id = #{id,jdbcType=BIGINT}
</update>
</mapper>
\ No newline at end of file
package com.cftech.couponrecord.model;
import com.cftech.core.poi.ExportConfig;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 发券信息管理
*
* @author Strive
* @date: 2021-01-27 15:54
*/
@Data
public class Couponrecord implements Serializable {
/* 主键id */
private Long id;
/* 有效期年 */
@ExportConfig(value = "有效期年", width = 100, showLevel = 1)
private String takeEffectYear;
/* 生效月 */
@ExportConfig(value = "生效月", width = 100, showLevel = 1)
private String takeEffectMonth;
/* 过期月份 */
@ExportConfig(value = "过期月份", width = 100, showLevel = 1)
private String expireMonth;
/* 检测券类型 */
@ExportConfig(value = "检测券类型", width = 100, showLevel = 1)
private String type;
/* 检测券编码 */
@ExportConfig(value = "检测券编码", width = 100, showLevel = 1)
private String number;
/* 粉丝id */
@ExportConfig(value = "粉丝id", width = 100, showLevel = 1)
private String openid;
/* 二维码链接 */
@ExportConfig(value = "二维码链接", width = 100, showLevel = 1)
private String qrcode;
/* 失效时间 */
@ExportConfig(value = "失效时间", width = 100, showLevel = 1)
private Date invalidDate;
/* 核销时间 */
@ExportConfig(value = "核销时间", width = 100, showLevel = 1)
private Date verifDate;
/* 设备号 */
@ExportConfig(value = "设备号", width = 100, showLevel = 1)
private Date facilityNo;
/* 所属的账号 */
private Long accountsId;
/* 删除标识 */
private boolean delFlag;
/* 状态 */
private String status;
/* 创建时间 */
private Date createTime;
/* 更新时间 */
private Date updateTime;
/* 备注 */
private String description;
/* 创建人 */
private Long createBy;
/* 更新人 */
private Long updateBy;
public Couponrecord() {
this.delFlag = false;
this.status = "0";
}
}
\ No newline at end of file
package com.cftech.couponrecord.service;
import com.cftech.couponrecord.model.Couponrecord;
import com.cftech.core.generic.GenericService;
/**
* 发券信息管理Service
*
* @author Strive
* @date: 2021-01-27 15:54
*/
public interface CouponrecordService extends GenericService<Couponrecord> {
}
package com.cftech.couponrecord.service.impl;
import com.cftech.couponrecord.model.Couponrecord;
import com.cftech.couponrecord.dao.CouponrecordMapper;
import com.cftech.couponrecord.service.CouponrecordService;
import com.cftech.core.generic.GenericDao;
import com.cftech.core.generic.GenericServiceImpl;
import com.cftech.core.sql.Conds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
/**
* 发券信息管理ServiceImpl
*
* @author Strive
* @date: 2021-01-27 15:54
*/
@Service("couponrecordService")
public class CouponrecordServiceImpl extends GenericServiceImpl<Couponrecord> implements CouponrecordService {
@Autowired
@Qualifier("couponrecordMapper")
private CouponrecordMapper couponrecordMapper;
@Override
public GenericDao<Couponrecord> getGenericMapper() {
return couponrecordMapper;
}
}
\ No newline at end of file
package com.cftech.couponrecord.web;
import com.alibaba.fastjson.JSONObject;
import com.cftech.couponrecord.model.Couponrecord;
import com.cftech.couponrecord.service.CouponrecordService;
import com.cftech.core.poi.ExcelKit;
import com.cftech.core.scope.OrderType;
import com.cftech.core.sql.Conds;
import com.cftech.core.sql.Sort;
import com.cftech.core.util.Constants;
import com.cftech.sys.security.PermissionSign;
import com.cftech.sys.security.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* 发券信息管理Controller
* <p>
* 权限字符串说明:
* 查看:public static final String COUPONRECORD_VIEW = "qy:couponrecord:view"
* 查看:public static final String COUPONRECORD_EDIT = "qy:couponrecord:edit"
*
* @author Strive
* @date: 2021-01-27 15:54
*/
@Slf4j
@Controller
@RequestMapping("/a/couponrecord")
public class CouponrecordController {
public static final String COUPONRECORD_VIEW = "qy:couponrecord:view";
public static final String COUPONRECORD_EDIT = "qy:couponrecord:edit";
@Autowired
private CouponrecordService couponrecordService;
//列表页面
@RequiresPermissions(value = COUPONRECORD_VIEW)
@RequestMapping("/list")
public String list(HttpServletRequest request, Model model) {
Long accountId = UserUtils.getmpaccounts(request);
model.addAttribute("accountId", accountId);
return "couponrecord/couponrecordlist";
}
//编辑页面(新增、修改)
@RequiresPermissions(value = COUPONRECORD_VIEW)
@RequestMapping("/form")
public String form(HttpServletRequest request, String id, Model model) {
if (!StringUtils.isEmpty(id)) {
Couponrecord couponrecord = couponrecordService.fetchById(id);
model.addAttribute("data", couponrecord);
}
return "couponrecord/couponrecordform";
}
//提交数据(新增、修改)
@RequiresPermissions(value = COUPONRECORD_EDIT)
@RequestMapping("/formData")
@ResponseBody
public JSONObject formData(Couponrecord couponrecord, Model model, HttpServletRequest request) {
Long accountsId = UserUtils.getmpaccounts(request);
JSONObject rtnJson = new JSONObject();
try {
if (couponrecord != null && couponrecord.getId() != null) {
couponrecord.setUpdateBy(UserUtils.getUser().getId());
couponrecordService.update(couponrecord);
rtnJson.put("errorNo", 0);
} else {
couponrecord.setAccountsId(accountsId);
couponrecord.setDelFlag(false);
couponrecord.setAccountsId(UserUtils.getmpaccounts(request));
couponrecord.setCreateBy(UserUtils.getUser().getId());
couponrecord.setUpdateBy(UserUtils.getUser().getId());
couponrecordService.save(couponrecord);
rtnJson.put("errorNo", 2);
}
} catch (Exception e) {
rtnJson.put("errorNo", 1);
}
return rtnJson;
}
//获取列表数据
@RequiresPermissions(value = COUPONRECORD_VIEW)
@RequestMapping(value = "/listData")
@ResponseBody
public JSONObject listData(int iDisplayStart, int iDisplayLength, Couponrecord couponrecord, HttpServletRequest request) {
Long accountsId = UserUtils.getmpaccounts(request);
Conds conds = new Conds();
conds.equal("del_flag", Constants.DEL_FLAG_0);
conds.equal("accounts_id", accountsId);
Sort sort = new Sort("create_time", OrderType.DESC);
List<Couponrecord> list = couponrecordService.fetchSearchByPage(conds, sort, iDisplayStart, iDisplayLength);
Integer counts = couponrecordService.count(conds);
JSONObject rtnJson = new JSONObject();
rtnJson.put("iTotalRecords", counts);
rtnJson.put("iTotalDisplayRecords", counts);
rtnJson.put("aaData", list);
return rtnJson;
}
//删除数据
@RequiresPermissions(value = COUPONRECORD_EDIT)
@RequestMapping("/delete")
@ResponseBody
public JSONObject delete(String id) {
JSONObject rtnJosn = new JSONObject();
try {
couponrecordService.delete(id);
rtnJosn.put("errorNo", 0);
} catch (Exception e) {
rtnJosn.put("errorNo", 1);
}
return rtnJosn;
}
@RequestMapping("/exportExcel")
@RequiresPermissions(value = COUPONRECORD_VIEW)
public void exportExcel(HttpServletRequest request, HttpServletResponse response) {
Long accountId = UserUtils.getmpaccounts(request);
Sort sort = new Sort("create_time", OrderType.ASC);
Conds conds = new Conds();
conds.equal("del_flag", 0);
conds.equal("accounts_id", accountId);
List<Couponrecord> list = couponrecordService.fetchSearchByPage(conds, sort, 0, 0);
ExcelKit.$Export(Couponrecord.class, response).toExcel(list, "发券信息管理信息");
}
@RequestMapping("/templateExcel")
@RequiresPermissions(value = COUPONRECORD_VIEW)
public void templateExcel(HttpServletRequest request, HttpServletResponse response) {
ExcelKit.$Export(Couponrecord.class, response).toExcel(null, "发券信息管理信息");
}
@RequestMapping("/importExcel")
@RequiresPermissions(value = COUPONRECORD_EDIT)
public String importExcel(HttpServletRequest request, MultipartFile file, Model model) {
Long accountId = UserUtils.getmpaccounts(request);
if (file == null) {
return list(request, model);
}
// 构造临时路径来存储上传的文件
String uploadPath = System.getProperty("java.io.tmpdir");
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
String fileName = file.getOriginalFilename();
String filePath = uploadPath + File.separator + fileName;
File storeFile = new File(filePath);
try {
file.transferTo(storeFile);
ExcelKit.$Import().setEmptyCellValue("").readExcel(storeFile, rowData -> {
if (!StringUtils.isEmpty(rowData.get(0))) {
Couponrecord couponrecord = new Couponrecord();
couponrecord.setAccountsId(accountId);
couponrecordService.save(couponrecord);
}
});
} catch (IOException e) {
log.error(e.getMessage());
}
return list(request, model);
}
}
<?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/maven-v4_0_0.xsd">
<parent>
<artifactId>aidea-modules</artifactId>
<groupId>com.cftech</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<name>msgrecord-module-web</name>
<artifactId>msgrecord-module-web</artifactId>
<dependencies>
<dependency>
<groupId>com.cftech</groupId>
<artifactId>msgrecord-module</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<finalName>msgrecord-module-web</finalName>
</build>
</project>
<!DOCTYPE html>
<!--[if IE 8]>
<html lang="en" class="ie8 no-js"> <![endif]-->
<!--[if IE 9]>
<html lang="en" class="ie9 no-js"> <![endif]-->
<!--[if !IE]><!-->
<html>
<!--<![endif]-->
<!-- BEGIN HEAD -->
<head>
<base href="#springUrl('/assets/adminlte/')"/>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>工作台</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.5 -->
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="plugins/font-awesome/css/font-awesome.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="plugins/ionicons/css/ionicons.min.css">
<!-- DataTables -->
<link rel="stylesheet" href="plugins/datatables/dataTables.bootstrap.css">
<!-- Theme style -->
<link rel="stylesheet" href="dist/css/AdminLTE.min.css">
<!-- AdminLTE Skins. Choose a skin from the css/skins
folder instead of downloading all of them to reduce the load. -->
<link rel="stylesheet" href="dist/css/skins/_all-skins.min.css">
<!-- iCheck -->
<link rel="stylesheet" href="plugins/iCheck/flat/blue.css">
<!-- Date Picker -->
<link rel="stylesheet" href="plugins/datepicker/datepicker3.css">
<!-- Daterange picker -->
<link rel="stylesheet" href="plugins/daterangepicker/daterangepicker-bs3.css">
<!-- bootstrap wysihtml5 - text editor -->
<link rel="stylesheet" href="plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<!--validate css-->
<link rel="stylesheet" href="plugins/jquery-validation/css/validate.css">
<!--fileinput css-->
<link rel="stylesheet" href="plugins/bootstrap-fileinput/bootstrap-fileinput.css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<!-- END HEAD -->
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<div class="content-wrapper" style="margin-left:0;">
<section class="content-header">
<h1>
聊天记录管理
<small>聊天记录</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i>首页</a></li>
<li><a class="active">聊天记录</a></li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<div class="row">
<div class="col-xs-12">
<!-- general form elements disabled -->
<div class="box box-primary">
<form role="form" id="myForm">
<input name="id" value="$!{data.id}" hidden="true"/>
<div class="box-body">
</div>
<div class="box-footer">
#if($shiro.hasPermission("qy:msgrecord:edit"))
<input class="btn btn-primary" id="save" value="保存" type="submit">
#end
<a href="#springUrl('/a/msgrecord/list')" class="btn btn-default">取消</a>
</div>
</form>
<!-- /.box-body -->
</div><!-- /.box -->
</div><!-- /.col -->
</div><!-- /.row -->
</section><!-- /.content -->
</div><!-- /.content-wrapper -->
<!-- Add the sidebar's background. This div must be placed
immediately after the control sidebar -->
<div class="control-sidebar-bg"></div>
</div><!-- ./wrapper -->
<script src="plugins/jQuery/jQuery-2.1.4.min.js"></script>
<!-- Bootstrap 3.3.5 -->
<script src="bootstrap/js/bootstrap.min.js"></script>
<!-- DataTables -->
<script src="plugins/datatables/jquery.dataTables.min.js"></script>
<script src="plugins/datatables/extensions/i18n/lanauage_ch.js"></script>
<script src="plugins/datatables/dataTables.bootstrap.min.js"></script>
<!-- SlimScroll -->
<script src="plugins/slimScroll/jquery.slimscroll.min.js"></script>
<!-- FastClick -->
<script src="plugins/fastclick/fastclick.min.js"></script>
<!--fileinput js-->
<script src="plugins/bootstrap-fileinput/bootstrap-fileinput.js"></script>
<!-- AdminLTE App -->
<script src="dist/js/app.min.js"></script>
<script src="plugins/bootstrap-maxlength/bootstrap-maxlength.min.js" type="text/javascript"></script>
<script src="plugins/security/sha256.js" type="text/javascript"></script>
<script src="plugins/jquery-validation/js/jquery.validate.min.js"></script>
<script src="js/jquery.form.min.js"></script>
<script type="text/javascript" charset="utf-8" src="plugins/ueditor-min-1.4.3/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="plugins/ueditor-min-1.4.3/ueditor.all.js"></script>
<script type="text/javascript" charset="utf-8" src="plugins/ueditor-min-1.4.3/lang/zh-cn/zh-cn.js"></script>
<script src="common/js/cfapp.js"></script>
<!-- END PAGE LEVEL PLUGINS -->
<script>
$().ready(function () {
Cfapp.init();
recdTypeAdd.init();
});
var recdTypeAdd = function () {
var initForm = function () {
var initFormCtrl = function () {
bindEvent();
};
var bindEvent = function () {
$("#myForm").validate({
rules: {},
messages: {},
submitHandler: function (form) {
$("#save").attr("disabled", true);
$.getJSON("#springUrl('/a/msgrecord/formData')", $("#myForm").serialize(), function (returnobj) {
$("#save").attr("disabled", false);
if (returnobj.errorNo == 2) { //保存成功
Cfapp.confirm({
message: "添加成功",
btnoktext: "继续添加",
btncanceltext: "关闭",
success: function () {
location.href = "#springUrl('/a/msgrecord/form')";
},
cancel: function () {
location.href = "#springUrl('/a/msgrecord/list')";
}
});
} else if (returnobj.errorNo == 0) { //修改成功
Cfapp.alert({
message: "更新成功",
btntext: "确定",
success: function () {
location.href = "#springUrl('/a/msgrecord/list')";
}
});
} else {
Cfapp.alert({
message: "创建失败",
btntext: "确定",
success: function () {
location.href = "#springUrl('/a/msgrecord/list')";
}
});
}
});
}
})
}
initFormCtrl();
}
return {
//main function to initiate the module
init: function () {
initForm();
}
};
}();
</script>
</body>
<!-- END BODY -->
</html>
\ No newline at end of file
<!DOCTYPE html>
<!--[if IE 8]>
<html lang="en" class="ie8 no-js"> <![endif]-->
<!--[if IE 9]>
<html lang="en" class="ie9 no-js"> <![endif]-->
<!--[if !IE]><!-->
<html>
<!--<![endif]-->
<!-- BEGIN HEAD -->
<head>
<base href="#springUrl('/assets/adminlte/')"/>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>工作台</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.5 -->
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="plugins/font-awesome/css/font-awesome.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="plugins/ionicons/css/ionicons.min.css">
<!-- DataTables -->
<link rel="stylesheet" href="plugins/datatables/dataTables.bootstrap.css">
<!-- Theme style -->
<link rel="stylesheet" href="dist/css/AdminLTE.min.css">
<!-- AdminLTE Skins. Choose a skin from the css/skins
folder instead of downloading all of them to reduce the load. -->
<link rel="stylesheet" href="dist/css/skins/_all-skins.min.css">
<!-- iCheck -->
<link rel="stylesheet" href="plugins/iCheck/flat/blue.css">
<!-- Morris chart -->
<link rel="stylesheet" href="plugins/morris/morris.css">
<!-- jvectormap -->
<link rel="stylesheet" href="plugins/jvectormap/jquery-jvectormap-1.2.2.css">
<!-- Date Picker -->
<link rel="stylesheet" href="plugins/datepicker/datepicker3.css">
<!-- Daterange picker -->
<link rel="stylesheet" href="plugins/daterangepicker/daterangepicker-bs3.css">
<link rel="stylesheet"
href="plugins\bootstrap-fileinput\fileinput.min.css">
<!-- bootstrap wysihtml5 - text editor -->
<link rel="stylesheet" href="plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<div class="content-wrapper" style="margin-left:0;">
<div id="importExcelDiv"></div>
<section class="content-header">
<h1>
聊天记录管理
<small>聊天记录</small>
</h1>
<ol class="breadcrumb">
<li><a><i class="fa fa-dashboard"></i>首页</a></li>
<li><a class="active">聊天记录管理列表</a></li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<div class="row">
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<form id="seachTableForm" action="#springUrl('/a/msgrecord/list')" method="get">
<div class="col-xs-5">
<button type="button" class="search btn btn-primary">搜索</button>
#if($shiro.hasPermission("qy:msgrecord:edit"))
<a href="#springUrl('/a/msgrecord/form')" class="btn btn-primary">新增</a>
<a href="#springUrl('/a/msgrecord/exportExcel')" class="btn btn-primary">导出</a>
<a onclick="importExcel();" class="btn btn-primary">导入</a>
#end
</div>
</form>
</div><!-- /.box-header -->
<div class="box-body">
<table id="table" class="table table-bordered table-striped">
<thead>
<tr>
<td hidden="true">Id</td>
<th width="15%">发送人</th>
<th width="15%">消息类型</th>
<th width="40%">消息内容</th>
<th width="15%">发送时间</th>
<th width="15%">创建时间</th>
<!--<th>操作</th>-->
</tr>
</thead>
<tbody id="tablebody">
</tbody>
</table>
</div><!-- /.box-body -->
</div><!-- /.box -->
</div><!-- /.col -->
</div><!-- /.row -->
</section><!-- /.content -->
</div><!-- /.content-wrapper -->
<!-- Add the sidebar's background. This div must be placed
immediately after the control sidebar -->
<div class="control-sidebar-bg"></div>
</div><!-- ./wrapper -->
<!-- jQuery 2.1.4 -->
<script src="plugins/jQuery/jQuery-2.1.4.min.js"></script>
<!-- Bootstrap 3.3.5 -->
<script src="bootstrap/js/bootstrap.min.js"></script>
<!-- DataTables -->
<script src="plugins/datatables/jquery.dataTables.min.js"></script>
<script src="plugins/datatables/extensions/i18n/lanauage_ch.js"></script>
<script src="plugins/datatables/dataTables.bootstrap.min.js"></script>
<!-- SlimScroll -->
<script src="plugins/slimScroll/jquery.slimscroll.min.js"></script>
<script src="plugins/datepicker/bootstrap-datepicker.js"></script>
<script src="plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script>
<!-- FastClick -->
<script src="plugins/fastclick/fastclick.min.js"></script>
<!--fileinput js-->
<script src="plugins\bootstrap-fileinput\fileinput.js"></script>
<script src="plugins/bootstrap-fileinput/zh.js"></script>
<script src="plugins/bootstrap-fileinput/zh2.js"></script>
<!-- AdminLTE App -->
<script src="dist/js/app.min.js"></script>
<script type="text/javascript"
src="plugins/jquery-validation/js/jquery.validate.min.js"></script>
<!-- AdminLTE for demo purposes -->
<script src="common/js/cfapp.js"></script>
<script>
function formatDates(now) {
var now = new Date(now);
var year = now.getFullYear();
var month = now.getMonth() + 1;
var date = now.getDate();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
return year + "-" + month + "-" + date + " " + hour + ":"
+ minute + ":" + second;
}
function seachTable() {
var sSource = "#springUrl('/a/msgrecord/listData')";
var aoData = {
iDisplayStart: 1,
iDosplayLength: 10
}
var retrieveData = function (sSource, aoData, fnCallback) {
$("#seachTableForm input").each(function () {
var params = {
name: $(this).attr("name"),
value: $(this).val()
};
aoData.push(params);
})
$.ajax({
"type": "GET",
"url": sSource,
"dataType": "json",
"data": aoData, //以json格式传递
"success": fnCallback
});
};
$('#table').DataTable({
"lengthChange": false,
"searching": false,
"ordering": false,
"bFiltered": false,
"bStateSave": true, // save datatable state(pagination, sort, etc) in cookie.
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": sSource,
"fnServerData": retrieveData,
"pagingType": "full_numbers",
"aoColumns": [
{
"mData": "id"
},
{
"mData": "tofromName"
},
{
"mData": "msgType"
},
{
"mData": "content"
},
{
"mData": "msgtime"
},
{
"mData": "createTime"
}],
"aoColumnDefs": [
{ // set default column settings
'visible': false,
'targets': [0]
},
{
"aTargets": [2],
"mData": "createTime",
"mRender": function (a, b, c, d) {
if (a == 'text') {
return '文本';
} else if (a == 'weapp') {
return '程序消息'
} else if (a == 'image') {
return '图片消息'
} else if (a == 'disagree') {
return '拒绝会话';
} else if (a == 'agree') {
return '同意会话';
} else {
return '';
}
}
},
{
"aTargets": [3],
"mData": "content",
"mRender": function (a, b, c, d) {
if (c.msgType == 'text') {
let obj = JSON.parse(a);
return obj.content;
} else if (c.msgType == 'weapp') {
let obj = JSON.parse(a);
return '标题:' + obj.displayname + '\n' + '提醒:' + obj.title + '\n' + '内容:' + obj.description;
} else if (c.msgType == 'image') {
return "<img src='"+c.mediaPath+"' style='width: 80px;height: 80px;'>";
} else {
return '';
}
}
},
{
"aTargets": [4],
"mData": "msgtime",
"mRender": function (a, b, c, d) {
return formatDates(a, "yyyy-MM-dd HH:mm:ss");
}
},
{
"aTargets": [5],
"mData": "createTime",
"mRender": function (a, b, c, d) {
return formatDates(a, "yyyy-MM-dd HH:mm:ss");
}
},
]
});
}
jQuery(document).ready(function () {
seachTable();
$('.datepicker').datepicker({
show: true,
format: 'yyyy-mm-dd',
autoclose: true,
language: 'zh-CN',
todayBtn: 'linked',
clearBtn: 'linked'
});
$('.search').click(function () {
$("#table").dataTable().fnClearTable();
});
});
Cfapp.init();
function removeData(data) {
Cfapp.confirm({
message: "确定要删除吗",
btnoktext: "确定",
btncanceltext: "取消",
success: function () {
$.ajax({
type: "POST",
url: "#springUrl('/a/msgrecord/delete')",
data: {id: data},
dataType: "json",
success: function (data) {
if (data.errorNo == 0) {
Cfapp.alert({
message: "删除成功",
btntext: "确定",
success: function () {
location.href = "#springUrl('/a/msgrecord/list')";
}
});
}
},
error: function () {
}
})
},
cancel: function () {
$(".modal-backdrop").fadeOut();
}
});
}
function importExcel() {
var templateExcelUrl = "#springUrl('/a/msgrecord/templateExcel')";
var importExcelUrl = "#springUrl('/a/msgrecord/importExcel')";
Cfapp.importExcel({
title: '聊天记录导入',
importurl: importExcelUrl,
templateurl: templateExcelUrl,
cancel: function () {
},
success: function () {
}
});
}
</script>
</body>
</html>
<?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>aidea-modules</artifactId>
<groupId>com.cftech</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>msgrecord-module</artifactId>
</project>
\ No newline at end of file
package com.cftech.msgrecord.dao;
import com.cftech.msgrecord.model.Msgrecord;
import com.cftech.core.generic.GenericDao;
/**
* 聊天记录Mapper
*
* @author Strive
* @date: 2021-01-05 15:28
*/
public interface MsgrecordMapper extends GenericDao<Msgrecord> {
}
\ No newline at end of file
<?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.cftech.msgrecord.dao.MsgrecordMapper">
<resultMap id="resultMap" type="com.cftech.msgrecord.model.Msgrecord">
<id column="id" property="id"/>
<result column="msg_id" property="msgId"/>
<result column="varsion" property="varsion"/>
<result column="action" property="action"/>
<result column="tofrom" property="tofrom"/>
<result column="tolist" property="tolist"/>
<result column="roomid" property="roomid"/>
<result column="msgtime" property="msgtime"/>
<result column="msg_type" property="msgType"/>
<result column="content" property="content"/>
<result column="media_path" property="mediaPath"/>
<result column="accounts_id" property="accountsId"/>
<result column="del_flag" property="delFlag"/>
<result column="status" property="status"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="description" property="description"/>
<result column="create_by" property="createBy"/>
<result column="update_by" property="updateBy"/>
<result column="tofromName" property="tofromName"/>
</resultMap>
<sql id="sqlWhere">
<if test="conds!=null">
<trim prefix="WHERE" prefixOverrides="AND|OR">
<foreach collection="conds.conds" index="index" item="cond">
${cond.linkType}
<if test="cond.condType == 'EQUAL'">${cond.param} = #{cond.value}</if>
<if test="cond.condType == 'NOTEQUAL'">${cond.param} &lt;&gt; #{cond.value}</if>
<if test="cond.condType == 'GREATEQUAL'">${cond.param} &gt;= #{cond.value}</if>
<if test="cond.condType == 'GREATTHAN'">${cond.param} &gt; #{cond.value}</if>
<if test="cond.condType == 'LESSEQUAL'">${cond.param} &lt;= #{cond.value}</if>
<if test="cond.condType == 'LESSTHAN'">${cond.param} &lt; #{cond.value}</if>
<if test="cond.condType == 'BETWEEN'">${cond.param} BETWEEN #{cond.startValue} AND
#{cond.endValue}
</if>
<if test="cond.condType == 'ISNULL'">${cond.param} IS NULL</if>
<if test="cond.condType == 'NOTNULL'">${cond.param} IS NOT NULL</if>
<if test="cond.condType == 'LIKE'">${cond.param} LIKE #{cond.value}</if>
<if test="cond.condType == 'IN'">${cond.param} IN
<foreach item="item" index="index" collection="cond.value" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</foreach>
</trim>
</if>
</sql>
<sql id="sqlColumns">
id,
msg_id,
varsion,
action,
tofrom,
tolist,
roomid,
msgtime,
msg_type,
content,
media_path,
accounts_id,
del_flag,
status,
create_time,
update_time,
description,
create_by,
update_by
</sql>
<insert id="save" parameterType="com.cftech.msgrecord.model.Msgrecord" useGeneratedKeys="true"
keyProperty="id">
insert into t_aidea_msg_record
(
<include refid="sqlColumns"/>
)
values
(
#{id, jdbcType=BIGINT},
#{msgId, jdbcType=VARCHAR},
#{varsion, jdbcType=VARCHAR},
#{action, jdbcType=VARCHAR},
#{tofrom, jdbcType=VARCHAR},
#{tolist, jdbcType=VARCHAR},
#{roomid, jdbcType=VARCHAR},
#{msgtime, jdbcType=DATETIME},
#{msgType, jdbcType=VARCHAR},
#{content, jdbcType=VARCHAR},
#{mediaPath, jdbcType=VARCHAR},
#{accountsId, jdbcType=BIGINT},
#{delFlag, jdbcType=TINYINT},
#{status, jdbcType=VARCHAR},
now(),
now(),
#{description, jdbcType=VARCHAR},
#{createBy, jdbcType=BIGINT},
#{updateBy, jdbcType=BIGINT}
)
</insert>
<select id="fetchById" parameterType="java.lang.Long" resultMap="resultMap">
SELECT
<include refid="sqlColumns"/>
FROM t_aidea_msg_record t
WHERE t.id=#{id}
</select>
<select id="count" parameterType="java.util.Map" resultType="java.lang.Integer">
SELECT COUNT(1) FROM t_aidea_msg_record t
LEFT JOIN wx_mp_fanss f ON t.tofrom = f.openid AND f.delflag = 0
LEFT JOIN t_qyuser q ON t.tofrom = q.wxuser_id AND q.del_flag = 0
<include refid="sqlWhere"/>
</select>
<select id="fetchSearchByPage" parameterType="java.util.Map" resultType="com.cftech.msgrecord.model.Msgrecord">
SELECT
t.id,
t.msg_id,
t.varsion,
t.action,
t.tofrom,
t.tolist,
t.roomid,
t.msgtime,
t.msg_type,
t.content,
t.media_path,
t.accounts_id,
t.del_flag,
t.status,
t.create_time,
t.update_time,
t.description,
t.create_by,
t.update_by,
CASE WHEN CONVERT(AES_DECRYPT(f.nickname,'aideakey') USING UTF8) IS NOT NULL THEN CONVERT(AES_DECRYPT(f.nickname,'aideakey') USING UTF8)
WHEN q.name IS NOT NULL THEN q.name
ELSE t.tofrom END tofromName
FROM t_aidea_msg_record t
LEFT JOIN wx_mp_fanss f ON t.tofrom = f.openid AND f.delflag = 0
LEFT JOIN t_qyuser q ON t.tofrom = q.wxuser_id AND q.del_flag = 0
<include refid="sqlWhere"/>
<if test="sort!=null">ORDER BY ${sort.param} ${sort.type}</if>
<if test="limit>0">limit #{offset},#{limit}</if>
</select>
<update id="update" parameterType="com.cftech.msgrecord.model.Msgrecord">
update t_aidea_msg_record
<set>
<if test="id != null">
id = #{id, jdbcType=BIGINT},
</if>
<if test="msgId != null">
msg_id = #{msgId, jdbcType=VARCHAR},
</if>
<if test="varsion != null">
varsion = #{varsion, jdbcType=VARCHAR},
</if>
<if test="action != null">
action = #{action, jdbcType=VARCHAR},
</if>
<if test="tofrom != null">
tofrom = #{tofrom, jdbcType=VARCHAR},
</if>
<if test="tolist != null">
tolist = #{tolist, jdbcType=VARCHAR},
</if>
<if test="roomid != null">
roomid = #{roomid, jdbcType=VARCHAR},
</if>
<if test="msgtime != null">
msgtime = #{msgtime, jdbcType=TIMESTAMP},
</if>
<if test="msgType != null">
msg_type = #{msgType, jdbcType=VARCHAR},
</if>
<if test="content != null">
content = #{content, jdbcType=VARCHAR},
</if>
<if test="mediaPath != null">
media_path = #{mediaPath, jdbcType=VARCHAR},
</if>
<if test="accountsId != null">
accounts_id = #{accountsId, jdbcType=BIGINT},
</if>
<if test="delFlag != null">
del_flag = #{delFlag, jdbcType=TINYINT},
</if>
<if test="status != null">
status = #{status, jdbcType=VARCHAR},
</if>
<if test="createTime != null">
create_time = #{createTime, jdbcType=TIMESTAMP},
</if>
<if test="description != null">
description = #{description, jdbcType=VARCHAR},
</if>
<if test="createBy != null">
create_by = #{createBy, jdbcType=BIGINT},
</if>
<if test="updateBy != null">
update_by = #{updateBy, jdbcType=BIGINT},
</if>
</set>
where id=#{id,jdbcType=BIGINT}
</update>
<update id="delete" parameterType="java.lang.Long">
update t_aidea_msg_record set del_flag=1 where id=#{id,jdbcType=BIGINT}
</update>
</mapper>
\ No newline at end of file
package com.cftech.msgrecord.job;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cftech.accounts.model.MpAccountsEntity;
import com.cftech.accounts.model.SysJob;
import com.cftech.accounts.service.JobService;
import com.cftech.accounts.service.MpAccountsService;
import com.cftech.core.sql.Conds;
import com.cftech.core.util.Constants;
import com.cftech.core.util.SpringContextHolder;
import com.cftech.core.util.SystemConfig;
import com.cftech.msgrecord.model.Msgrecord;
import com.cftech.msgrecord.service.MsgrecordService;
import com.tencent.wework.Finance;
import com.tencent.wework.FinanceConstants;
import com.tencent.wework.FinanceUtils;
import com.tencent.wework.RSAUtils;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.UUID;
/**
* Created by 16444 on 2021/1/7.
*/
@Slf4j
public class SynWechatMsg implements Job {
private static MsgrecordService msgrecordService = SpringContextHolder.getBean(MsgrecordService.class);
private static String IMAGEURL = SystemConfig.p.getProperty("IMAGEURL");
private static String IMAGEPATH = SystemConfig.p.getProperty("userfiles.imgdir");
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
JobService jobService = SpringContextHolder.getBean(JobService.class);
boolean isCluster = Boolean.valueOf(SystemConfig.p.getProperty("quartz.isCluster"));
if (!isCluster) {
return;
}
//获得明细数据
JobDataMap jobInfo = context.getJobDetail().getJobDataMap();
String id = jobInfo.get("uid") == null ? "" : jobInfo.getString("uid");//这个也是ID主键
log.info("任务ID:" + id);
Long accounts = Long.parseLong(SystemConfig.p.getProperty("QY_CHAT_WORK"));
MpAccountsService mpAccountsService= SpringContextHolder.getBean(MpAccountsService.class);
MpAccountsEntity accountsEntity = mpAccountsService.getDetail(accounts);
executeSynWework(accountsEntity.getAppid(), accountsEntity.getSecret());
//执行更新操作
if (context.getNextFireTime() != null) {
log.info("同步微信聊天数据任务:下次执行时间=====" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(context.getNextFireTime()) + "==============");
} else {
SysJob sysJob = new SysJob();
sysJob.setJobuid(id);
sysJob.setStatus("0");
jobService.updateStatus(sysJob);
log.info("同步微信聊天数据任务,已执行完成!");
}
}
public void executeSynWework(String corpId, String secret) {
long sdk = 0;
try {
//初始化sdk
sdk = Finance.NewSdk();
int ret = Finance.Init(sdk, corpId, secret);
if (ret != 0) {
Finance.DestroySdk(sdk);
log.error("初始化微信会话内容存档SDK失败, ret = {}, sdk = {}", ret, sdk);
} else {
findWeworkMsgData(sdk);
}
} catch (Exception e) {
log.error("初始化微信会话内容存档SDK失败, sdk = {}", sdk);
e.printStackTrace();
} finally {
log.error("初始化微信会话内容存档SDK结束, sdk = {}", sdk);
Finance.DestroySdk(sdk);
}
}
private void findWeworkMsgData(long sdk) {
long req = 0;//起始条数
long limit = 5;//每次拉取数据
for(;;) {
long slice = Finance.NewSlice();
int ret = Finance.GetChatData(sdk, req, limit, "", "", 5, slice);
if (ret != 0) {
Finance.FreeSlice(slice);
log.error("获取微信会话内容存档聊天数据失败, sdk = {}, req = {}, limit = {}, ret = {}", sdk, req, limit, ret);
return;
}
String contentFromSlice = Finance.GetContentFromSlice(slice);
JSONObject result = JSONObject.parseObject(contentFromSlice);
JSONArray chatDatas = result.getJSONArray("chatdata");
Finance.FreeSlice(slice);
if (result.containsKey("errcode") && result.getIntValue("errcode") == 0) {
req = decryptWeworkMsgData(sdk, chatDatas);
if (chatDatas.size() < limit) {
log.error("获取微信会话内容存档聊天数据 结束, sdk = {}, req = {}, limit = {}, ret = {}", sdk, req, limit, ret);
return;
}
} else {
log.error("获取微信会话内容存档聊天数据 结束, sdk = {}, req = {}, limit = {}, ret = {}", sdk, req, limit, ret);
return;
}
}
}
private long decryptWeworkMsgData(long sdk, JSONArray chatDatas) {
long req = 0;
for (int i=0, y=chatDatas.size(); i<y; i++) {
JSONObject chatObj = chatDatas.getJSONObject(i);
long sep = chatObj.getLongValue("seq");
String msgid = chatObj.getString("msgid");
String version = chatObj.getString("publickey_ver");
String encryptRandomKey = chatObj.getString("encrypt_random_key");
String encryptChatMsg = chatObj.getString("encrypt_chat_msg");
String decryptByPrivateKey = RSAUtils.decryptByPriKey(encryptRandomKey, FinanceConstants.PRIKEY_PKCS8);
req = sep;
long msg = Finance.NewSlice();
int ret = Finance.DecryptData(sdk, decryptByPrivateKey, encryptChatMsg, msg);
if (ret != 0) {
Finance.FreeSlice(msg);
log.error("解密微信会话内容存档聊天数据失败, sdk = {}, req = {}, ret = {}", sdk, req, ret);
return req;
}
String message = Finance.GetContentFromSlice(msg);
Finance.FreeSlice(msg);
log.info("获取到解密消息, msg = {}", message);
JSONObject chatVo = JSONObject.parseObject(message);
//过滤企业号转换消息
if (chatVo.getString("action").equals("switch")) {
continue;
}
//过滤已存在消息
Conds conds = new Conds();
conds.equal("del_flag", Constants.DEL_FLAG_0);
conds.equal("msg_id", msgid);
Msgrecord msgrecord = msgrecordService.fetchSearchByConds(conds);
if (msgrecord != null) {
continue;
}
switch (chatVo.getString("msgtype")) {
case "image":
imageMsgRecode(sdk, sep, msgid, version, chatVo);
break;
default:
textMsgRecode(sep, msgid, version, chatVo);
}
}
return req;
}
private void textMsgRecode(long req, String msgid, String version, JSONObject chatVo) {
Msgrecord msgrecord = new Msgrecord();
msgrecord.setAccountsId(348L);
msgrecord.setStatus(String.valueOf(req));
msgrecord.setMsgId(msgid);
msgrecord.setVarsion(version);
msgrecord.setAction(chatVo.getString("action"));
msgrecord.setTofrom(chatVo.getString("from"));
msgrecord.setTolist(chatVo.getJSONArray("tolist").toString());
msgrecord.setRoomid(chatVo.getString("roomid"));
msgrecord.setMsgtime(FinanceUtils.utcTransDate(chatVo.getLongValue("msgtime")));
msgrecord.setMsgType(chatVo.getString("msgtype"));
msgrecord.setContent(chatVo.getString(chatVo.getString("msgtype")));
msgrecordService.save(msgrecord);
}
private void imageMsgRecode(long sdk, long req, String msgid, String version, JSONObject chatVo) {
log.error("处理图片");
Msgrecord msgrecord = new Msgrecord();
msgrecord.setAccountsId(348L);
msgrecord.setStatus(String.valueOf(req));
msgrecord.setMsgId(msgid);
msgrecord.setVarsion(version);
msgrecord.setAction(chatVo.getString("action"));
msgrecord.setTofrom(chatVo.getString("from"));
msgrecord.setTolist(chatVo.getJSONArray("tolist").toString());
msgrecord.setRoomid(chatVo.getString("roomid"));
msgrecord.setMsgtime(FinanceUtils.utcTransDate(chatVo.getLongValue("msgtime")));
msgrecord.setMsgType(chatVo.getString("msgtype"));
msgrecord.setContent(chatVo.getString(chatVo.getString("msgtype")));
JSONObject media = chatVo.getJSONObject(chatVo.getString("msgtype"));
String indexbuf = "";//下次拉取需要使用的indexbuf
String fileName = UUID.randomUUID().toString() + ".jpg";
String finalFileName = IMAGEPATH + File.separator + fileName;
while (true) {
//每次使用GetMediaData拉取存档前需要调用NewMediaData获取一个media_data,在使用完media_data中数据后,还需要调用FreeMediaData释放。
long media_data = Finance.NewMediaData();
int ret = Finance.GetMediaData(sdk, indexbuf, media.getString("sdkfileid"), "", "", 5, media_data);
if (ret!=0) {
System.out.println("getmediadata ret:" + ret);
Finance.FreeMediaData(media_data);
return;
}
System.out.printf("getmediadata outindex len:%d, data_len:%d, is_finis:%d\n",Finance.GetIndexLen(media_data),Finance.GetDataLen(media_data), Finance.IsMediaDataFinish(media_data));
try {
//大于512k的文件会分片拉取,此处需要使用追加写,避免后面的分片覆盖之前的数据。
File file = new File(finalFileName);
FileOutputStream outputStream = new FileOutputStream(file, true);
outputStream.write(Finance.GetData(media_data));
outputStream.close();
} catch (Exception e) {
Finance.FreeMediaData(media_data);
e.printStackTrace();
}
if (Finance.IsMediaDataFinish(media_data) == 1) {
log.error("文件存储路径 {}", finalFileName);
//已经拉取完成最后一个分片
Finance.FreeMediaData(media_data);
//保存
msgrecord.setMediaPath(IMAGEURL.replace("{PICFILENAME}", fileName));
msgrecordService.save(msgrecord);
return;
}
else {
//获取下次拉取需要使用的indexbuf
indexbuf = Finance.GetOutIndexBuf(media_data);
Finance.FreeMediaData(media_data);
}
}
}
}
package com.cftech.msgrecord.model;
import com.cftech.core.poi.ExportConfig;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 聊天记录
*
* @author Strive
* @date: 2021-01-05 15:28
*/
@Data
public class Msgrecord implements Serializable {
/* 主键id */
private Long id;
/* 聊天id */
@ExportConfig(value = "聊天id", width = 100, showLevel = 1)
private String msgId;
/* 版本号 */
@ExportConfig(value = "版本号", width = 100, showLevel = 1)
private String varsion;
/* 消息动作 */
@ExportConfig(value = "消息动作", width = 100, showLevel = 1)
private String action;
/* 消息发送方id */
@ExportConfig(value = "消息发送方id", width = 100, showLevel = 1)
private String tofrom;
/* 消息接收方 */
@ExportConfig(value = "消息接收方", width = 100, showLevel = 1)
private String tolist;
/* 群聊消息 */
@ExportConfig(value = "群聊消息", width = 100, showLevel = 1)
private String roomid;
/* 消息发送时间戳 */
@ExportConfig(value = "消息发送时间戳", width = 100, showLevel = 1)
private Date msgtime;
/* 消息类型 */
@ExportConfig(value = "消息类型", width = 100, showLevel = 1)
private String msgType;
/* 消息内容 */
@ExportConfig(value = "消息内容", width = 100, showLevel = 1)
private String content;
/* 快件产品类型 */
@ExportConfig(value = "快件产品类型", width = 100, showLevel = 1)
private String mediaPath;
/* 所属的账号 */
private Long accountsId;
/* 删除标识 */
private boolean delFlag;
/* 状态 */
private String status;
/* 创建时间 */
private Date createTime;
/* 更新时间 */
private Date updateTime;
/* 备注 */
private String description;
/* 创建人 */
private Long createBy;
/* 更新人 */
private Long updateBy;
private String tofromName;
public Msgrecord() {
this.delFlag = false;
this.status = "0";
}
}
\ No newline at end of file
package com.cftech.msgrecord.service;
import com.cftech.msgrecord.model.Msgrecord;
import com.cftech.core.generic.GenericService;
/**
* 聊天记录Service
*
* @author Strive
* @date: 2021-01-05 15:28
*/
public interface MsgrecordService extends GenericService<Msgrecord> {
}
package com.cftech.msgrecord.service.impl;
import com.cftech.msgrecord.model.Msgrecord;
import com.cftech.msgrecord.dao.MsgrecordMapper;
import com.cftech.msgrecord.service.MsgrecordService;
import com.cftech.core.generic.GenericDao;
import com.cftech.core.generic.GenericServiceImpl;
import com.cftech.core.sql.Conds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
/**
* 聊天记录ServiceImpl
*
* @author Strive
* @date: 2021-01-05 15:28
*/
@Service("msgrecordService")
public class MsgrecordServiceImpl extends GenericServiceImpl<Msgrecord> implements MsgrecordService {
@Autowired
@Qualifier("msgrecordMapper")
private MsgrecordMapper msgrecordMapper;
@Override
public GenericDao<Msgrecord> getGenericMapper() {
return msgrecordMapper;
}
}
\ No newline at end of file
package com.cftech.msgrecord.web;
import com.alibaba.fastjson.JSONObject;
import com.cftech.accounts.model.SysJob;
import com.cftech.accounts.service.JobService;
import com.cftech.msgrecord.model.Msgrecord;
import com.cftech.msgrecord.service.MsgrecordService;
import com.cftech.core.poi.ExcelKit;
import com.cftech.core.scope.OrderType;
import com.cftech.core.sql.Conds;
import com.cftech.core.sql.Sort;
import com.cftech.core.util.Constants;
import com.cftech.sys.security.PermissionSign;
import com.cftech.sys.security.UserUtils;
import com.tencent.wework.SynMsg;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.List;
/**
* 聊天记录Controller
* <p>
* 权限字符串说明:
* 查看:public static final String MSGRECORD_VIEW = "qy:msgrecord:view"
* 查看:public static final String MSGRECORD_EDIT = "qy:msgrecord:edit"
*
* @author Strive
* @date: 2021-01-05 15:28
*/
@Slf4j
@Controller
@RequestMapping("/a/msgrecord")
public class MsgrecordController {
public static final String MSGRECORD_VIEW = "qy:msgrecord:view";
public static final String MSGRECORD_EDIT = "qy:msgrecord:edit";
@Autowired
private MsgrecordService msgrecordService;
@Autowired
private JobService jobService;
//列表页面
@RequiresPermissions(value = MSGRECORD_VIEW)
@RequestMapping("/list")
public String list(HttpServletRequest request, Model model) {
Long accountId = UserUtils.getmpaccounts(request);
model.addAttribute("accountId", accountId);
return "msgrecord/msgrecordlist";
}
//编辑页面(新增、修改)
@RequiresPermissions(value = MSGRECORD_VIEW)
@RequestMapping("/form")
public String form(HttpServletRequest request, String id, Model model) {
if (!StringUtils.isEmpty(id)) {
Msgrecord msgrecord = msgrecordService.fetchById(id);
model.addAttribute("data", msgrecord);
}
return "msgrecord/msgrecordform";
}
//提交数据(新增、修改)
@RequiresPermissions(value = MSGRECORD_EDIT)
@RequestMapping("/formData")
@ResponseBody
public JSONObject formData(Msgrecord msgrecord, Model model, HttpServletRequest request) {
Long accountsId = UserUtils.getmpaccounts(request);
JSONObject rtnJson = new JSONObject();
try {
if (msgrecord != null && msgrecord.getId() != null) {
msgrecord.setUpdateBy(UserUtils.getUser().getId());
msgrecordService.update(msgrecord);
rtnJson.put("errorNo", 0);
} else {
msgrecord.setAccountsId(accountsId);
msgrecord.setDelFlag(false);
msgrecord.setAccountsId(UserUtils.getmpaccounts(request));
msgrecord.setCreateBy(UserUtils.getUser().getId());
msgrecord.setUpdateBy(UserUtils.getUser().getId());
msgrecordService.save(msgrecord);
rtnJson.put("errorNo", 2);
}
} catch (Exception e) {
rtnJson.put("errorNo", 1);
}
return rtnJson;
}
//获取列表数据
@RequiresPermissions(value = MSGRECORD_VIEW)
@RequestMapping(value = "/listData")
@ResponseBody
public JSONObject listData(int iDisplayStart, int iDisplayLength, Msgrecord msgrecord, HttpServletRequest request) {
Long accountsId = UserUtils.getmpaccounts(request);
Conds conds = new Conds();
conds.equal("t.del_flag", Constants.DEL_FLAG_0);
conds.equal("t.accounts_id", accountsId);
Sort sort = new Sort("t.create_time", OrderType.DESC);
List<Msgrecord> list = msgrecordService.fetchSearchByPage(conds, sort, iDisplayStart, iDisplayLength);
Integer counts = msgrecordService.count(conds);
JSONObject rtnJson = new JSONObject();
rtnJson.put("iTotalRecords", counts);
rtnJson.put("iTotalDisplayRecords", counts);
rtnJson.put("aaData", list);
return rtnJson;
}
//删除数据
@RequiresPermissions(value = MSGRECORD_EDIT)
@RequestMapping("/delete")
@ResponseBody
public JSONObject delete(String id) {
JSONObject rtnJosn = new JSONObject();
try {
msgrecordService.delete(id);
rtnJosn.put("errorNo", 0);
} catch (Exception e) {
rtnJosn.put("errorNo", 1);
}
return rtnJosn;
}
@RequestMapping("/exportExcel")
@RequiresPermissions(value = MSGRECORD_VIEW)
public void exportExcel(HttpServletRequest request, HttpServletResponse response) {
Long accountId = UserUtils.getmpaccounts(request);
Sort sort = new Sort("create_time", OrderType.ASC);
Conds conds = new Conds();
conds.equal("del_flag", 0);
conds.equal("accounts_id", accountId);
List<Msgrecord> list = msgrecordService.fetchSearchByPage(conds, sort, 0, 0);
ExcelKit.$Export(Msgrecord.class, response).toExcel(list, "聊天记录信息");
}
@RequestMapping("/templateExcel")
@RequiresPermissions(value = MSGRECORD_VIEW)
public void templateExcel(HttpServletRequest request, HttpServletResponse response) {
ExcelKit.$Export(Msgrecord.class, response).toExcel(null, "聊天记录信息");
}
@RequestMapping("/importExcel")
@RequiresPermissions(value = MSGRECORD_EDIT)
public String importExcel(HttpServletRequest request, MultipartFile file, Model model) {
Long accountId = UserUtils.getmpaccounts(request);
if (file == null) {
return list(request, model);
}
// 构造临时路径来存储上传的文件
String uploadPath = System.getProperty("java.io.tmpdir");
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
String fileName = file.getOriginalFilename();
String filePath = uploadPath + File.separator + fileName;
File storeFile = new File(filePath);
try {
file.transferTo(storeFile);
ExcelKit.$Import().setEmptyCellValue("").readExcel(storeFile, rowData -> {
if (!StringUtils.isEmpty(rowData.get(0))) {
Msgrecord msgrecord = new Msgrecord();
msgrecord.setAccountsId(accountId);
msgrecordService.save(msgrecord);
}
});
} catch (IOException e) {
log.error(e.getMessage());
}
return list(request, model);
}
}
package com.tencent.wework;
import com.cftech.core.util.SystemConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.util.FileCopyUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
/* sdk返回数据
typedef struct Slice_t {
char* buf;
int len;
} Slice_t;
typedef struct MediaData {
char* outindexbuf;
int out_len;
char* data;
int data_len;
int is_finish;
} MediaData_t;
*/
@Slf4j
public class Finance {
public native static long NewSdk();
/**
* 初始化函数
* Return值=0表示该API调用成功
*
* @param [in] sdk NewSdk返回的sdk指针
* @param [in] corpid 调用企业的企业id,例如:wwd08c8exxxx5ab44d,可以在企业微信管理端--我的企业--企业信息查看
* @param [in] secret 聊天内容存档的Secret,可以在企业微信管理端--管理工具--聊天内容存档查看
*
*
* @return 返回是否初始化成功
* 0 - 成功
* !=0 - 失败
*/
public native static int Init(long sdk, String corpid, String secret);
/**
* 拉取聊天记录函数
* Return值=0表示该API调用成功
*
*
* @param [in] sdk NewSdk返回的sdk指针
* @param [in] seq 从指定的seq开始拉取消息,注意的是返回的消息从seq+1开始返回,seq为之前接口返回的最大seq值。首次使用请使用seq:0
* @param [in] limit 一次拉取的消息条数,最大值1000条,超过1000条会返回错误
* @param [in] proxy 使用代理的请求,需要传入代理的链接。如:socks5://10.0.0.1:8081 或者 http://10.0.0.1:8081
* @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123
* @param [out] chatDatas 返回本次拉取消息的数据,slice结构体.内容包括errcode/errmsg,以及每条消息内容。
*
* @return 返回是否调用成功
* 0 - 成功
* !=0 - 失败
*/
public native static int GetChatData(long sdk, long seq, long limit, String proxy, String passwd, long timeout, long chatData);
/**
* 拉取媒体消息函数
* Return值=0表示该API调用成功
*
*
* @param [in] sdk NewSdk返回的sdk指针
* @param [in] sdkFileid 从GetChatData返回的聊天消息中,媒体消息包括的sdkfileid
* @param [in] proxy 使用代理的请求,需要传入代理的链接。如:socks5://10.0.0.1:8081 或者 http://10.0.0.1:8081
* @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123
* @param [in] indexbuf 媒体消息分片拉取,需要填入每次拉取的索引信息。首次不需要填写,默认拉取512k,后续每次调用只需要将上次调用返回的outindexbuf填入即可。
* @param [out] media_data 返回本次拉取的媒体数据.MediaData结构体.内容包括data(数据内容)/outindexbuf(下次索引)/is_finish(拉取完成标记)
*
* @return 返回是否调用成功
* 0 - 成功
* !=0 - 失败
*/
public native static int GetMediaData(long sdk, String indexbuf, String sdkField, String proxy, String passwd, long timeout, long mediaData);
/**
* @brief 解析密文
* @param [in] encrypt_key, getchatdata返回的encrypt_key
* @param [in] encrypt_msg, getchatdata返回的content
* @param [out] msg, 解密的消息明文
* @return 返回是否调用成功
* 0 - 成功
* !=0 - 失败
*/
public native static int DecryptData(long sdk, String encrypt_key, String encrypt_msg, long msg);
public native static void DestroySdk(long sdk);
public native static long NewSlice();
/**
* @brief 释放slice,和NewSlice成对使用
* @return
*/
public native static void FreeSlice(long slice);
/**
* @brief 获取slice内容
* @return 内容
*/
public native static String GetContentFromSlice(long slice);
/**
* @brief 获取slice内容长度
* @return 内容
*/
public native static int GetSliceLen(long slice);
public native static long NewMediaData();
public native static void FreeMediaData(long mediaData);
/**
* @brief 获取mediadata outindex
* @return outindex
*/
public native static String GetOutIndexBuf(long mediaData);
/**
* @brief 获取mediadata data数据
* @return data
*/
public native static byte[] GetData(long mediaData);
public native static int GetIndexLen(long mediaData);
public native static int GetDataLen(long mediaData);
/**
* @brief 判断mediadata是否结束
* @return 1完成、0未完成
*/
public native static int IsMediaDataFinish(long mediaData);
static {
//System.loadLibrary("WeWorkFinanceSdk_Java");
log.error(System.getProperty("java.io.tmpdir").toString());
loadLib("jniLibs/libWeWorkFinanceSdk_Java.so");
}
public static void loadLib(String libName) {
String resourcePath = "/" + libName;
String folderName = SystemConfig.p.getProperty("userfiles.msgdir");
File folder = new File(folderName);
folder.mkdirs();
File libFile = new File(folder, libName);
System.load(libFile.getAbsolutePath());
}
}
package com.tencent.wework;
import com.cftech.core.util.SystemConfig;
/**
* Created by 16444 on 2021/1/7.
*/
public class FinanceConstants {
/**
* RSA密钥
*/
public static final String PRIKEY_PKCS8 =
"MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJn88Y5HZfOIyE+A" +
"zkTEPl5/gaNRdLhguGJM5WzZng2KoXnsd1PXHUpcKxbcLcgCnERTIBYHCvhVcnW1" +
"monsA2voeJhG6Cpt64pvhvNdZX1i9x1OtnWpkLHnhxIUVxVgw4Vjhd5g2VSg/c7u" +
"D9TNxzCGwen9urslIMZpnNsef6jBAgMBAAECgYALC9VTKMWEPQ9rfpitX6t+sWRe" +
"EBmQoWWQraX2kzzOiV+QhLlBoyiHfUmdA/Hny2Ik15axZdNwYYbKsVqS4sKS9leU" +
"wiGnqS1OUh6jzxwRHMe9ylTNZiNrUaREg6cpw93wr1rUNWHm6NXlp23WZvu/zwEz" +
"BL7wXECYZ37vR+b4HQJBAMYFEtuiDX17PPUnl8ytO4H4sEfibiQ2XLsFL6jpMOzy" +
"YUchCQ3UyChJMlHjVh++IAldBUbmYh2cQDjaL/rMRTUCQQDHE2Q3zmv15kNMmzu5" +
"PXBSkJbQ3BNzEPxsvomKxXHTcJ6FKW9AzAmGXssfdj9xFHhcH15W23m0aQe7Cl5s" +
"V4LdAkB9Xvb6kZZC7QTCHmgwkTlM57wMNyMO0FBTpEvxgHqWejr2wsatuBtlzjoK" +
"uIltnX1BEGDn67MRFj1fAV1BR5VFAkEAmKI9jKwwCnFp2CqNOBHrNOK3P5v9LZQw" +
"dhAA1O1dwIfwgpiqPDw0cVns00qOidzwC3HhmybbwX9l9fqVOuw94QJBALMmZygw" +
"yT93g9R9P+Jm0lTtvju4dHx2KpVNHP97sWshJ9DXbNAXJb4TpPfu6z3RDQ+hjCL2" +
"ccDHlz+3JYJbaNk=";
/**
* 图片文件存储目录
*/
public static final String USER_IMAGES_DIR = SystemConfig.p.getProperty("userfiles.imagedir");
}
package com.tencent.wework;
import java.util.Calendar;
import java.util.Date;
/**
* Created by 16444 on 2021/1/5.
*/
public class FinanceUtils {
public static long sdk = 0;
public static Date utcTransDate(long number) {
Date date = new Date();
date.setTime(number);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 8);
return calendar.getTime();
}
}
package com.tencent.wework;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class RSAUtils {
/**
* 数字签名,密钥算法
*/
private static final String RSA_KEY_ALGORITHM = "RSA";
/**
* 数字签名签名/验证算法
*/
private static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* RSA密钥长度,RSA算法的默认密钥长度是1024密钥长度必须是64的倍数,在512到65536位之间
*/
private static final int KEY_SIZE = 1024;
/**
* 生成密钥对
*/
private static Map<String, String> initKey() throws Exception {
KeyPairGenerator keygen = KeyPairGenerator.getInstance(RSA_KEY_ALGORITHM);
SecureRandom secrand = new SecureRandom();
/**
* 初始化随机产生器
*/
secrand.setSeed("initSeed".getBytes());
/**
* 初始化密钥生成器
*/
keygen.initialize(KEY_SIZE, secrand);
KeyPair keys = keygen.genKeyPair();
byte[] pub_key = keys.getPublic().getEncoded();
String publicKeyString = org.apache.commons.codec.binary.Base64.encodeBase64String(pub_key);
byte[] pri_key = keys.getPrivate().getEncoded();
String privateKeyString = org.apache.commons.codec.binary.Base64.encodeBase64String(pri_key);
Map<String, String> keyPairMap = new HashMap<>();
keyPairMap.put("publicKeyString", publicKeyString);
keyPairMap.put("privateKeyString", privateKeyString);
return keyPairMap;
}
/**
* 密钥转成字符串
*
* @param key
* @return
*/
public static String encodeBase64String(byte[] key) {
return org.apache.commons.codec.binary.Base64.encodeBase64String(key);
}
/**
* 密钥转成byte[]
*
* @param key
* @return
*/
public static byte[] decodeBase64(String key) {
return Base64.decodeBase64(key);
}
/**
* 公钥加密
*
* @param data 加密前的字符串
* @param publicKey 公钥
* @return 加密后的字符串
* @throws Exception
*/
public static String encryptByPubKey(String data, String publicKey) throws Exception {
byte[] pubKey = RSAUtils.decodeBase64(publicKey);
byte[] enSign = encryptByPubKey(data.getBytes(), pubKey);
return org.apache.commons.codec.binary.Base64.encodeBase64String(enSign);
}
/**
* 公钥加密
*
* @param data 待加密数据
* @param pubKey 公钥
* @return
* @throws Exception
*/
public static byte[] encryptByPubKey(byte[] data, byte[] pubKey) throws Exception {
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 私钥加密
*
* @param data 加密前的字符串
* @param privateKey 私钥
* @return 加密后的字符串
* @throws Exception
*/
public static String encryptByPriKey(String data, String privateKey) throws Exception {
byte[] priKey = RSAUtils.decodeBase64(privateKey);
byte[] enSign = encryptByPriKey(data.getBytes(), priKey);
return org.apache.commons.codec.binary.Base64.encodeBase64String(enSign);
}
/**
* 私钥加密
*
* @param data 待加密的数据
* @param priKey 私钥
* @return 加密后的数据
* @throws Exception
*/
public static byte[] encryptByPriKey(byte[] data, byte[] priKey) throws Exception {
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 公钥解密
*
* @param data 待解密的数据
* @param pubKey 公钥
* @return 解密后的数据
* @throws Exception
*/
public static byte[] decryptByPubKey(byte[] data, byte[] pubKey) throws Exception {
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 公钥解密
*
* @param data 解密前的字符串
* @param publicKey 公钥
* @return 解密后的字符串
* @throws Exception
*/
public static String decryptByPubKey(String data, String publicKey) throws Exception {
byte[] pubKey = RSAUtils.decodeBase64(publicKey);
byte[] design = decryptByPubKey(org.apache.commons.codec.binary.Base64.decodeBase64(data), pubKey);
return new String(design);
}
/**
* 私钥解密
*
* @param data 待解密的数据
* @param priKey 私钥
* @return
* @throws Exception
*/
@SneakyThrows
public static byte[] decryptByPriKey(byte[] data, byte[] priKey) {
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return getMaxResultDecrypt(data, cipher);
}
/**
* 私钥解密
*
* @param data 解密前的字符串
* @param privateKey 私钥
* @return 解密后的字符串
* @throws Exception
*/
@SneakyThrows
public static String decryptByPriKey(String data, String privateKey) {
byte[] priKey = RSAUtils.decodeBase64(privateKey);
byte[] design = decryptByPriKey(Base64.decodeBase64(data.getBytes("UTF-8")), priKey);
return new String(design);
}
/**
* RSA签名
*
* @param data 待签名数据
* @param priKey 私钥
* @return 签名
* @throws Exception
*/
public static String sign(byte[] data, byte[] priKey) throws Exception {
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
// 生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 实例化Signature
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
// 初始化Signature
signature.initSign(privateKey);
// 更新
signature.update(data);
return Base64.encodeBase64String(signature.sign());
}
/**
* RSA校验数字签名
*
* @param data 待校验数据
* @param sign 数字签名
* @param pubKey 公钥
* @return boolean 校验成功返回true,失败返回false
*/
public boolean verify(byte[] data, byte[] sign, byte[] pubKey) throws Exception {
// 实例化密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
// 初始化公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
// 产生公钥
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
// 实例化Signature
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
// 初始化Signature
signature.initVerify(publicKey);
// 更新
signature.update(data);
// 验证
return signature.verify(sign);
}
private static byte[] getMaxResultDecrypt(byte[] inputArray, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
int inputLength = inputArray.length;
// 最大解密字节数,超出最大字节数需要分组加密
int MAX_ENCRYPT_BLOCK = 128;
// 标识
int offSet = 0;
byte[] resultBytes = {};
byte[] cache = {};
while (inputLength - offSet > 0) {
if (inputLength - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(inputArray, offSet, MAX_ENCRYPT_BLOCK);
offSet += MAX_ENCRYPT_BLOCK;
} else {
cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
offSet = inputLength;
}
resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
}
return resultBytes;
}
}
\ No newline at end of file
package com.tencent.wework;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cftech.core.util.SystemConfig;
import com.cftech.msgrecord.model.Msgrecord;
import com.cftech.msgrecord.service.MsgrecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import javax.crypto.Cipher;
import java.io.File;
import java.io.FileOutputStream;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Created by 16444 on 2021/1/5.
*/
@Slf4j
public class SynMsg {
@Autowired
private MsgrecordService msgrecordService;
private static String PRIKEY_PKCS8 =
"MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJn88Y5HZfOIyE+A" +
"zkTEPl5/gaNRdLhguGJM5WzZng2KoXnsd1PXHUpcKxbcLcgCnERTIBYHCvhVcnW1" +
"monsA2voeJhG6Cpt64pvhvNdZX1i9x1OtnWpkLHnhxIUVxVgw4Vjhd5g2VSg/c7u" +
"D9TNxzCGwen9urslIMZpnNsef6jBAgMBAAECgYALC9VTKMWEPQ9rfpitX6t+sWRe" +
"EBmQoWWQraX2kzzOiV+QhLlBoyiHfUmdA/Hny2Ik15axZdNwYYbKsVqS4sKS9leU" +
"wiGnqS1OUh6jzxwRHMe9ylTNZiNrUaREg6cpw93wr1rUNWHm6NXlp23WZvu/zwEz" +
"BL7wXECYZ37vR+b4HQJBAMYFEtuiDX17PPUnl8ytO4H4sEfibiQ2XLsFL6jpMOzy" +
"YUchCQ3UyChJMlHjVh++IAldBUbmYh2cQDjaL/rMRTUCQQDHE2Q3zmv15kNMmzu5" +
"PXBSkJbQ3BNzEPxsvomKxXHTcJ6FKW9AzAmGXssfdj9xFHhcH15W23m0aQe7Cl5s" +
"V4LdAkB9Xvb6kZZC7QTCHmgwkTlM57wMNyMO0FBTpEvxgHqWejr2wsatuBtlzjoK" +
"uIltnX1BEGDn67MRFj1fAV1BR5VFAkEAmKI9jKwwCnFp2CqNOBHrNOK3P5v9LZQw" +
"dhAA1O1dwIfwgpiqPDw0cVns00qOidzwC3HhmybbwX9l9fqVOuw94QJBALMmZygw" +
"yT93g9R9P+Jm0lTtvju4dHx2KpVNHP97sWshJ9DXbNAXJb4TpPfu6z3RDQ+hjCL2" +
"ccDHlz+3JYJbaNk=";
private static String secret = "tJSU7EFY3cVrG0HiFoMTRe_b3qFGIZU5h3p16FcUkEY";
private static String corpId = "ww097b4f3fff919139";
private static Long accountId = 348L;
// 本地图片目录
public static final String USER_IMAGES_DIR = SystemConfig.p.getProperty("userfiles.imagedir");
// public static void executeSynWework(String corpId, String secret) {
// long sdk = 0;
// try {
// //初始化sdk
// sdk = Finance.NewSdk();
// int ret = Finance.Init(sdk, corpId, secret);
// if (ret != 0) {
// Finance.DestroySdk(sdk);
// log.error("初始化微信会话内容存档SDK失败, ret = {}, sdk = {}", ret, sdk);
// } else {
// findWeworkMsgData(sdk);
// }
// } catch (Exception e) {
// log.error("初始化微信会话内容存档SDK失败, sdk = {}", sdk);
// e.printStackTrace();
// } finally {
// log.error("初始化微信会话内容存档SDK结束, sdk = {}", sdk);
// Finance.DestroySdk(sdk);
// }
// }
//
// private static void findWeworkMsgData(long sdk) {
// long req = 0;//起始条数
// long limit = 5;//每次拉取数据
// for(;;) {
// long slice = Finance.NewSlice();
// int ret = Finance.GetChatData(sdk, req, limit, "", "", 5, slice);
// if (ret != 0) {
// Finance.FreeSlice(slice);
// log.error("获取微信会话内容存档聊天数据失败, sdk = {}, req = {}, limit = {}, ret = {}", sdk, req, limit, ret);
// return;
// }
//
// String contentFromSlice = Finance.GetContentFromSlice(slice);
// JSONObject result = JSONObject.parseObject(contentFromSlice);
// JSONArray chatDatas = result.getJSONArray("chatdata");
// Finance.FreeSlice(slice);
//
// if (result.containsKey("errcode") && result.getIntValue("errcode") == 0) {
// req = decryptWeworkMsgData(sdk, chatDatas);
// if (chatDatas.size() < limit) {
// log.error("获取微信会话内容存档聊天数据 结束, sdk = {}, req = {}, limit = {}, ret = {}", sdk, req, limit, ret);
// return;
// }
// } else {
// log.error("获取微信会话内容存档聊天数据 结束, sdk = {}, req = {}, limit = {}, ret = {}", sdk, req, limit, ret);
// return;
// }
// }
// }
//
// private static long decryptWeworkMsgData(long sdk, JSONArray chatDatas) {
// long req = 0;
// for (int i=0, y=chatDatas.size(); i<y; i++) {
// JSONObject chatObj = chatDatas.getJSONObject(i);
//
// long sep = chatObj.getLongValue("seq");
// String msgid = chatObj.getString("msgid");
// String version = chatObj.getString("publickey_ver");
// String encryptRandomKey = chatObj.getString("encrypt_random_key");
// String encryptChatMsg = chatObj.getString("encrypt_chat_msg");
// String decryptByPrivateKey = RSAUtils.decryptByPriKey(encryptRandomKey, FinanceConstants.PRIKEY_PKCS8);
// req = sep;
//
// long msg = Finance.NewSlice();
// int ret = Finance.DecryptData(sdk, decryptByPrivateKey, encryptChatMsg, msg);
// if (ret != 0) {
// Finance.FreeSlice(msg);
// log.error("解密微信会话内容存档聊天数据失败, sdk = {}, req = {}, ret = {}", sdk, req, ret);
// return req;
// }
//
// String message = Finance.GetContentFromSlice(msg);
// Finance.FreeSlice(msg);
//
//
//
// log.info("获取到解密消息, msg = {}", message);
// JSONObject chatVo = JSONObject.parseObject(message);
//
// if (chatVo.getString("action").equals("switch")) {
// continue;
// }
//
// switch (chatVo.getString("msgtype")) {
// case "text":
// textMsgRecode(sep, msgid, version, chatVo);
// break;
// case "image":
// imageMsgRecode(sdk, sep, msgid, version, chatVo);
// break;
// default:
// otherMsgRecode(sep, msgid, version, chatVo);
// }
// }
// return req;
// }
//
// private static void textMsgRecode(long req, String msgid, String version, JSONObject chatVo) {
//// Msgrecord msgrecord = new Msgrecord();
//// msgrecord.setAccountsId(348L);
//// msgrecord.setStatus(String.valueOf(req));
//// msgrecord.setMsgId(msgid);
//// msgrecord.setVarsion(version);
//// msgrecord.setAction(chatVo.getString("action"));
//// msgrecord.setFrom(chatVo.getString("from"));
//// msgrecord.setTolist(chatVo.getJSONArray("tolist").toString());
//// msgrecord.setRoomid(chatVo.getString("roomid"));
//// msgrecord.setMsgtime(FinanceUtils.utcTransDate(chatVo.getLongValue("msgtime")));
//// msgrecord.setMsgType(chatVo.getString("msgtype"));
//// msgrecord.setContent(chatVo.getString(chatVo.getString("msgtype")));
// //msgrecordService.save(msgrecord);
// }
//
//
// private static void imageMsgRecode(long sdk, long req, String msgid, String version, JSONObject chatVo) {
// log.error("处理图片");
// Msgrecord msgrecord = new Msgrecord();
// msgrecord.setAccountsId(348L);
// msgrecord.setStatus(String.valueOf(req));
// msgrecord.setMsgId(msgid);
// msgrecord.setVarsion(version);
// msgrecord.setAction(chatVo.getString("action"));
// msgrecord.setFrom(chatVo.getString("from"));
// msgrecord.setTolist(chatVo.getJSONArray("tolist").toString());
// msgrecord.setRoomid(chatVo.getString("roomid"));
// msgrecord.setMsgtime(FinanceUtils.utcTransDate(chatVo.getLongValue("msgtime")));
// msgrecord.setMsgType(chatVo.getString("msgtype"));
//
// JSONObject media = chatVo.getJSONObject(chatVo.getString("msgtype"));
//
// String indexbuf = "";//下次拉取需要使用的indexbuf
//
// String dir = SystemConfig.p.getProperty("userfiles.imagedir") + "";
// String fileName = UUID.randomUUID().toString() + ".jpg";
// String finalFileName = dir + File.separator + fileName;
//
// while (true) {
// //每次使用GetMediaData拉取存档前需要调用NewMediaData获取一个media_data,在使用完media_data中数据后,还需要调用FreeMediaData释放。
// long media_data = Finance.NewMediaData();
// int ret = Finance.GetMediaData(sdk, indexbuf, media.getString("sdkfileid"), "", "", 5, media_data);
// if (ret!=0) {
// System.out.println("getmediadata ret:" + ret);
// Finance.FreeMediaData(media_data);
// return;
// }
//
// System.out.printf("getmediadata outindex len:%d, data_len:%d, is_finis:%d\n",Finance.GetIndexLen(media_data),Finance.GetDataLen(media_data), Finance.IsMediaDataFinish(media_data));
//
// try {
// //大于512k的文件会分片拉取,此处需要使用追加写,避免后面的分片覆盖之前的数据。
// File file = new File(finalFileName);
//
// FileOutputStream outputStream = new FileOutputStream(file, true);
// outputStream.write(Finance.GetData(media_data));
// outputStream.close();
// } catch (Exception e) {
// Finance.FreeMediaData(media_data);
// e.printStackTrace();
// }
//
// if (Finance.IsMediaDataFinish(media_data) == 1) {
// log.error("文件存储路径 {}", finalFileName);
// //已经拉取完成最后一个分片
// Finance.FreeMediaData(media_data);
// return;
// }
// else {
// //获取下次拉取需要使用的indexbuf
// indexbuf = Finance.GetOutIndexBuf(media_data);
// Finance.FreeMediaData(media_data);
// }
// }
//
// //Finance.FreeMediaData(media_data);
// }
//
// private static void otherMsgRecode(long req, String msgid, String version, JSONObject chatVo) {
//// Msgrecord msgrecord = new Msgrecord();
//// msgrecord.setAccountsId(348L);
//// msgrecord.setStatus(String.valueOf(req));
//// msgrecord.setMsgId(msgid);
//// msgrecord.setVarsion(version);
//// msgrecord.setAction(chatVo.getString("action"));
//// msgrecord.setFrom(chatVo.getString("from"));
//// msgrecord.setTolist(chatVo.getJSONArray("tolist").toString());
//// msgrecord.setRoomid(chatVo.getString("roomid"));
//// msgrecord.setMsgtime(FinanceUtils.utcTransDate(chatVo.getLongValue("msgtime")));
//// msgrecord.setMsgType(chatVo.getString("msgtype"));
//// msgrecord.setContent(chatVo.getString(chatVo.getString("msgtype")));
// }
}
......@@ -40,6 +40,10 @@
<module>msgrecord-module-web</module>
<module>checkcoupon-module</module>
<module>checkcoupon-module-web</module>
<module>couponrecord-module</module>
<module>couponrecord-module-web</module>
<module>checkresult-module</module>
<module>checkresult-module-web</module>
</modules>
<dependencies>
......
......@@ -25,6 +25,8 @@ MOBILE_MP_DOMAIN_NAME=https://pd.shxrtech.com/aideas
QY_DOMAIN=https://pd.shxrtech.com
#\u4F01\u4E1A\u53F7\u63A8\u9001\u9ED8\u8BA4\u5E94\u7528id
QY_SEND_APPID=350
#\u4F01\u4E1A\u53F7\u4F1A\u8BDD\u5185\u5BB9\u5B58\u6863
QY_CHAT_WORK=351
#\u63A8\u9001\u5BA2\u670D\u6D88\u606F\u6DFB\u52A0\u7528\u6237
QY_SEND_CUSTOMERSERVICE_MSG=\u60A8\u6536\u5230\u4E00\u5F20\u54A8\u8BE2\u5355\uFF0C\u54A8\u8BE2\u5355\u7F16\u7801\uFF1A
#\u63A8\u9001\u836F\u5E08\u6D88\u606F\u5BA1\u6279\u54A8\u8BE2\u5355
......@@ -35,12 +37,17 @@ QY_SEND_ORDERCLERK_MSG=\u60A8\u6536\u5230\u4E00\u5F20\u5F85\u53D1\u8D27\u8BA2\u5
QY_SEND_SERVICE_FOLLOWUP_MSG=\u60A8\u6536\u5230\u4E00\u5F20\u8BA2\u5355\u8DDF\u8FDB\u63D0\u9192\uFF0C\u8BA2\u5355\u7F16\u7801\uFF1A
#\u54A8\u8BE2\u5355\u5BA1\u6838\u5931\u8D25\u63A8\u9001\u6D88\u606F
QY_SEND_SERVICE_AUDIT_FAIL_MAG=\u60A8\u6536\u5230\u4E00\u5F20\u5BA1\u6838\u672A\u901A\u8FC7\u7684\u54A8\u8BE2\u5355\uFF0C\u54A8\u8BE2\u5355\u7F16\u7801\uFF1A
#\u8BA2\u5355\u5F85\u66F4\u8FDB\u63D0\u9192
QY_SEND_SERVICE_ORDER_FOLLOW_REMIND=\u60A8\u6709\u4E00\u5F20\u5F85\u8DDF\u8FDB\u8BA2\u5355\uFF0C\u8BA2\u5355\u7F16\u7801\uFF1A
#\u56FE\u7247\u4E0A\u4F20\u5730\u5740
#userfiles.imgdir=/mydata/fileResource
userfiles.imgdir=/mydata/fileResource
#\u4F1A\u8BDD\u5185\u5BB9\u5B58\u6863\u5730\u5740
userfiles.msgdir=/mydata/wechatSdk/
userfiles.imagedir=/mydata/wechatImage
#\u75C5\u8F7D\u6838\u9500\u4E8C\u7EF4\u7801
userfiles.qrcodedir=/mydata/fileQrcode
#\u56FE\u7247\u8BBF\u95EE\u5730\u5740
IMAGEURL=/aidea/mobile/qybase/showPic?picFileName={PICFILENAME}
......
......@@ -328,6 +328,18 @@
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
<dependency>
<groupId>com.cftech</groupId>
<artifactId>couponrecord-module-web</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
<dependency>
<groupId>com.cftech</groupId>
<artifactId>checkresult-module-web</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
</dependencies>
<build>
<finalName>portal-web</finalName>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment