瀏覽代碼

超级会员

huangzhiguo 2 年之前
父節點
當前提交
aedae3da73
共有 19 個文件被更改,包括 2291 次插入14 次删除
  1. 26 0
      pom.xml
  2. 152 0
      src/main/java/com/caimei365/manager/config/thinkgem/utils/Encodes.java
  3. 200 0
      src/main/java/com/caimei365/manager/config/utils/OssArchiveUtil.java
  4. 70 0
      src/main/java/com/caimei365/manager/config/utils/UploadImageUtils.java
  5. 158 0
      src/main/java/com/caimei365/manager/config/utils/UploadPicUtils.java
  6. 216 0
      src/main/java/com/caimei365/manager/config/utils/UploadUtils.java
  7. 67 6
      src/main/java/com/caimei365/manager/controller/caimei/svip/CmSvipHistoryApi.java
  8. 40 4
      src/main/java/com/caimei365/manager/dao/svip/CmSvipHistoryDao.java
  9. 176 0
      src/main/java/com/caimei365/manager/entity/caimei/svip/CmCoupon.java
  10. 61 0
      src/main/java/com/caimei365/manager/entity/caimei/svip/CmCouponAssociate.java
  11. 84 0
      src/main/java/com/caimei365/manager/entity/caimei/svip/CmCouponClub.java
  12. 2 0
      src/main/java/com/caimei365/manager/entity/caimei/svip/CmSvipProduct.java
  13. 38 0
      src/main/java/com/caimei365/manager/entity/caimei/svip/CmVipCoupon.java
  14. 284 0
      src/main/java/com/caimei365/manager/entity/caimei/svip/NewCmShop.java
  15. 30 0
      src/main/java/com/caimei365/manager/entity/caimei/svip/SplitCode.java
  16. 31 4
      src/main/java/com/caimei365/manager/service/caimei/svip/CmSvipHistoryService.java
  17. 114 0
      src/main/java/com/caimei365/manager/service/caimei/svip/impl/CmCouponService.java
  18. 237 0
      src/main/java/com/caimei365/manager/service/caimei/svip/impl/CmSvipHistoryServiceImpl.java
  19. 305 0
      src/main/resources/mapper/svip/CmSvipHistoryDao.xml

+ 26 - 0
pom.xml

@@ -98,6 +98,32 @@
             <artifactId>ckfinder</artifactId>
             <version>2.3</version>
         </dependency>
+
+        <!-- jxls end -->
+        <dependency>
+            <groupId>com.caimei</groupId>
+            <artifactId>caimei-dfs-sdk</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.jcraft</groupId>
+            <artifactId>jsch</artifactId>
+            <version>0.1.55</version>
+        </dependency>
+
+        <!--对象存储oss-->
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>3.10.2</version>
+        </dependency>
+
+        <!--  jsoup 对 HTML 文档进行解析和操作 -->
+        <dependency>
+            <groupId>org.jsoup</groupId>
+            <artifactId>jsoup</artifactId>
+            <version>1.9.2</version>
+        </dependency>
     </dependencies>
 
     <profiles>

+ 152 - 0
src/main/java/com/caimei365/manager/config/thinkgem/utils/Encodes.java

@@ -0,0 +1,152 @@
+/**
+ * Copyright (c) 2005-2012 springside.org.cn
+ */
+package com.caimei365.manager.config.thinkgem.utils;
+
+import com.caimei.utils.Exceptions;
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.lang3.StringEscapeUtils;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+
+/**
+ * 封装各种格式的编码解码工具类.
+ * 1.Commons-Codec的 hex/base64 编码
+ * 2.自制的base62 编码
+ * 3.Commons-Lang的xml/html escape
+ * 4.JDK提供的URLEncoder
+ * @author calvin
+ * @version 2013-01-15
+ */
+public class Encodes {
+
+	private static final String DEFAULT_URL_ENCODING = "UTF-8";
+	private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
+
+	/**
+	 * Hex编码.
+	 */
+	public static String encodeHex(byte[] input) {
+		return new String(Hex.encodeHex(input));
+	}
+
+	/**
+	 * Hex解码.
+	 */
+	public static byte[] decodeHex(String input) {
+		try {
+			return Hex.decodeHex(input.toCharArray());
+		} catch (DecoderException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * Base64编码.
+	 */
+	public static String encodeBase64(byte[] input) {
+		return new String(Base64.encodeBase64(input));
+	}
+
+	/**
+	 * Base64编码.
+	 */
+	public static String encodeBase64(String input) {
+		try {
+			return new String(Base64.encodeBase64(input.getBytes(DEFAULT_URL_ENCODING)));
+		} catch (UnsupportedEncodingException e) {
+			return "";
+		}
+	}
+
+//	/**
+//	 * Base64编码, URL安全(将Base64中的URL非法字符'+'和'/'转为'-'和'_', 见RFC3548).
+//	 */
+//	public static String encodeUrlSafeBase64(byte[] input) {
+//		return Base64.encodeBase64URLSafe(input);
+//	}
+
+	/**
+	 * Base64解码.
+	 */
+	public static byte[] decodeBase64(String input) {
+		return Base64.decodeBase64(input.getBytes());
+	}
+
+	/**
+	 * Base64解码.
+	 */
+	public static String decodeBase64String(String input) {
+		try {
+			return new String(Base64.decodeBase64(input.getBytes()), DEFAULT_URL_ENCODING);
+		} catch (UnsupportedEncodingException e) {
+			return "";
+		}
+	}
+
+	/**
+	 * Base62编码。
+	 */
+	public static String encodeBase62(byte[] input) {
+		char[] chars = new char[input.length];
+		for (int i = 0; i < input.length; i++) {
+			chars[i] = BASE62[((input[i] & 0xFF) % BASE62.length)];
+		}
+		return new String(chars);
+	}
+
+	/**
+	 * Html 转码.
+	 */
+	public static String escapeHtml(String html) {
+		return StringEscapeUtils.escapeHtml4(html);
+	}
+
+	/**
+	 * Html 解码.
+	 */
+	public static String unescapeHtml(String htmlEscaped) {
+		return StringEscapeUtils.unescapeHtml4(htmlEscaped);
+	}
+
+	/**
+	 * Xml 转码.
+	 */
+	public static String escapeXml(String xml) {
+		return StringEscapeUtils.escapeXml10(xml);
+	}
+
+	/**
+	 * Xml 解码.
+	 */
+	public static String unescapeXml(String xmlEscaped) {
+		return StringEscapeUtils.unescapeXml(xmlEscaped);
+	}
+
+	/**
+	 * URL 编码, Encode默认为UTF-8.
+	 */
+	public static String urlEncode(String part) {
+		try {
+			return URLEncoder.encode(part, DEFAULT_URL_ENCODING);
+		} catch (UnsupportedEncodingException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+
+	/**
+	 * URL 解码, Encode默认为UTF-8.
+	 */
+	public static String urlDecode(String part) {
+
+		try {
+			return URLDecoder.decode(part, DEFAULT_URL_ENCODING);
+		} catch (UnsupportedEncodingException e) {
+			throw Exceptions.unchecked(e);
+		}
+	}
+}

+ 200 - 0
src/main/java/com/caimei365/manager/config/utils/OssArchiveUtil.java

@@ -0,0 +1,200 @@
+package com.caimei365.manager.config.utils;
+
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.model.CannedAccessControlList;
+import com.aliyun.oss.model.GetObjectRequest;
+import com.aliyun.oss.model.ObjectMetadata;
+import com.aliyun.oss.model.UploadFileRequest;
+import com.caimei.utils.StringUtils;
+import com.caimei365.manager.config.thinkgem.Global;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+import java.util.UUID;
+
+public class OssArchiveUtil {
+    private static String endpoint = Global.getConfig("aliyun.endpoint");
+    private static String accessKeyId = Global.getConfig("aliyun.accessKeyId");
+    private static String accessKeySecret = Global.getConfig("aliyun.accessKeySecret");
+    private static String privateBucket = Global.getConfig("aliyun.bucketName");
+    private static String config = Global.getConfig("cm.config");
+
+    public static String ossUpload(String fileName, String path, File file, String contentType, String contentDisposition) {
+        String url = null;
+        try {
+            if ("product".equals(config)) {
+                fileName = "prod/" + path + fileName;
+            } else {
+                fileName = config + "/" + path + fileName;
+            }
+            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+            ObjectMetadata meta = new ObjectMetadata();
+            meta.setContentType(contentType);
+            meta.setObjectAcl(CannedAccessControlList.PublicRead);
+            meta.setContentDisposition(StringUtils.isEmpty(contentDisposition) ? "inline" : contentDisposition);
+            UploadFileRequest uploadFileRequest = new UploadFileRequest(privateBucket, fileName);
+            // 指定上传的本地文件。
+            uploadFileRequest.setUploadFile(file.toString());
+            // 指定上传并发线程数,默认为1。
+            uploadFileRequest.setTaskNum(10);
+            // 指定上传的分片大小,范围为100KB~5GB,默认为文件大小/10000。
+            uploadFileRequest.setPartSize(1024 * 1024);
+            // 开启断点续传,默认关闭。
+            uploadFileRequest.setEnableCheckpoint(true);
+            uploadFileRequest.setCheckpointFile(file.getAbsolutePath() + "uploadFile.ucp");
+            // 文件的元数据。
+            uploadFileRequest.setObjectMetadata(meta);
+            // 设置上传成功回调,参数为Callback类型。
+            //uploadFileRequest.setCallback("<yourCallbackEvent>");
+            // 断点续传上传。
+            ossClient.uploadFile(uploadFileRequest);
+            // 有效期100年
+            Date expiration = new Date(System.currentTimeMillis() + 60L * 60 * 24 * 365 * 100 * 1000);
+            url = ossClient.generatePresignedUrl(privateBucket, fileName, expiration).toString();
+            // 关闭OSSClient。
+            ossClient.shutdown();
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+        return url;
+    }
+
+
+    /**
+     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
+     */
+    public static String getContentType(String fileName) {
+        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
+        if (".bmp".equalsIgnoreCase(fileExtension)) {
+            return "image/bmp";
+        }
+        if (".gif".equalsIgnoreCase(fileExtension)) {
+            return "image/gif";
+        }
+        if (".jpeg".equalsIgnoreCase(fileExtension)) {
+            return "image/jpeg";
+        }
+        if (".jpg".equalsIgnoreCase(fileExtension)) {
+            return "image/jpg";
+        }
+        if (".png".equalsIgnoreCase(fileExtension)) {
+            return "image/png";
+        }
+        if (".html".equalsIgnoreCase(fileExtension)) {
+            return "text/html";
+        }
+        if (".txt".equalsIgnoreCase(fileExtension)) {
+            return "text/plain";
+        }
+        if (".vsd".equalsIgnoreCase(fileExtension)) {
+            return "application/vnd.visio";
+        }
+        if (".ppt".equalsIgnoreCase(fileExtension)  ) {
+            return "application/vnd.ms-powerpoint";
+        }
+        if (".pptx".equalsIgnoreCase(fileExtension)) {
+            return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
+        }
+        if (".doc".equalsIgnoreCase(fileExtension) ) {
+            return "application/msword";
+        }
+        if ("docx".equalsIgnoreCase(fileExtension)) {
+            return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
+        }
+        if (".xml".equalsIgnoreCase(fileExtension)) {
+            return "text/xml";
+        }
+        if (".mp4".equalsIgnoreCase(fileExtension)) {
+            return "video/mp4";
+        }
+        if (".mp3".equalsIgnoreCase(fileExtension)) {
+            return "audio/mp3";
+        }
+        if (".pdf".equalsIgnoreCase(fileExtension)) {
+            return "application/pdf";
+        }
+        return "text/html";
+    }
+
+    public static void deleteFile(File... files) {
+        for (File file : files) {
+            //logger.info("File:[{}]",file.getAbsolutePath());
+            if (file.exists()) {
+                file.delete();
+            }
+        }
+    }
+
+    public static File ossUpload(MultipartFile file) throws IOException {
+        // 获取文件名
+        String fileName = file.getOriginalFilename();
+        // 获取文件后缀
+        String prefix = fileName.substring(fileName.lastIndexOf("."));
+        // 用uuid作为文件名,防止生成的临时文件重复
+        File excelFile = File.createTempFile(UUID.randomUUID().toString(), prefix);
+        // MultipartFile to File
+        file.transferTo(excelFile);
+        //程序结束时,删除临时文件
+        return excelFile;
+    }
+
+    /**
+     * 授权生成签名URL临时访问
+     *
+     * @param fileName 文件名称
+     */
+    public static String getOssUrl(String path, String fileName) {
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        // 设置URL过期时间为1个小时
+        Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000);
+        if ("product".equals(config)) {
+            fileName = "prod/" + path + fileName;
+        } else {
+            fileName = config + "/" + path + fileName;
+        }
+        String url = ossClient.generatePresignedUrl(privateBucket, fileName, expiration).toString();
+        // 关闭OSSClient。
+        ossClient.shutdown();
+        return url;
+    }
+
+    /**
+     * oss单个文件删除
+     *
+     * @param fileName 文件名称或文件夹名称
+     */
+    public static void deleteSingleFile(String path, String fileName) {
+        // 创建OSSClient实例。
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        // 删除文件。如需删除文件夹,请将ObjectName设置为对应的文件夹名称。
+        // 如果文件夹非空,则需要将文件夹下的所有object删除后才能删除该文件夹。
+        if ("product".equals(config)) {
+            fileName = "prod/" + path + fileName;
+        } else {
+            fileName = config + "/" + path + fileName;
+        }
+        ossClient.deleteObject(privateBucket, fileName);
+        // 关闭OSSClient。
+        ossClient.shutdown();
+    }
+
+    /**
+     * oss单个文件下载
+     */
+    public static void downFile(String path, String ossName, String fileName) {
+        // 创建OSSClient实例。
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。
+        if ("product".equals(config)) {
+            ossName = "prod/" + path + ossName;
+        } else {
+            ossName = config + "/" + path + ossName;
+        }
+        ossClient.getObject(new GetObjectRequest(privateBucket, ossName), new File("./" + fileName));
+        // 关闭OSSClient。
+        ossClient.shutdown();
+    }
+}

+ 70 - 0
src/main/java/com/caimei365/manager/config/utils/UploadImageUtils.java

@@ -0,0 +1,70 @@
+package com.caimei365.manager.config.utils;
+
+import com.caimei.utils.StringUtils;
+import com.caimei365.manager.config.thinkgem.Global;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * 上传图片公用方法
+ * 弃用request.getSession().getServletContext().getRealPath(image)
+ * @author Lijun
+ * @version 2019-06-28
+ **/
+public class UploadImageUtils {
+
+    static Logger logger = LoggerFactory.getLogger(UploadImageUtils.class);
+    static String basedir = Global.getConfig("userfiles.basedir");
+
+
+    /**
+     * 获取上传图片的绝对路径
+     *
+     * @param imagePath 图片路径
+     */
+    public static String getAbsolutePath(String imagePath) {
+        if(StringUtils.isNotEmpty(imagePath)){
+            String absolutePath = basedir + imagePath;
+            logger.info("----------上传绝对路径为:"+ absolutePath);
+            return absolutePath;
+        }else{
+            return "";
+        }
+    }
+
+
+    public static Map<String, Object> uploadOss(MultipartFile multipartFile, String dirName) {
+        Map<String, Object> map = new HashMap<>();
+        String fileAllName = multipartFile.getOriginalFilename();
+        String fileType = fileAllName.substring(fileAllName.lastIndexOf(".") + 1);
+        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
+        String filePath = uuid + "." + fileType;
+        String contentType = OssArchiveUtil.getContentType(fileAllName);
+        try {
+            //保存本地
+            File file = OssArchiveUtil.ossUpload(multipartFile);
+            logger.info("默认路径>>>" + file.getAbsolutePath());
+            //上传oss
+            String url = OssArchiveUtil.ossUpload(filePath, dirName, file, contentType, null);
+            //删除本地文件
+            OssArchiveUtil.deleteFile(file);
+            map.put("success", true);
+            map.put("msg", "操作成功");
+            map.put("ossName", filePath);
+            map.put("url", url);
+        } catch (Exception e) {
+            e.printStackTrace();
+            map.put("success", false);
+            map.put("msg", "操作失败");
+            logger.info("上传异常!!!");
+        }
+        return map;
+    }
+
+}

+ 158 - 0
src/main/java/com/caimei365/manager/config/utils/UploadPicUtils.java

@@ -0,0 +1,158 @@
+package com.caimei365.manager.config.utils;
+
+import com.caimei.dfs.DfsFileManager;
+import com.caimei.dfs.beens.BufferDfsFile;
+import com.caimei.dfs.image.beens.ImageUploadInfo;
+import com.caimei.utils.StringUtils;
+import com.caimei365.manager.config.thinkgem.Global;
+import com.caimei365.manager.config.thinkgem.utils.Encodes;
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.Session;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Properties;
+
+public class UploadPicUtils {
+
+    public static String saveImageToServer(String imgUrl) {
+        String photoServer = Global.getConfig("photoServer");//获取文件服务器地址
+        ImageUploadInfo saveImageSerivce = new ImageUploadInfo();
+        String newImage = imgUrl;
+        if (StringUtils.isNotBlank(newImage) && !newImage.startsWith("http:") && !newImage.startsWith("https:")) {
+            newImage = Encodes.urlDecode(newImage);
+            String realPath = UploadImageUtils.getAbsolutePath(newImage);
+            int pointerIndex = realPath.lastIndexOf(".");
+            try {
+                saveImageSerivce = UploadUtils.saveImageSerivce(realPath, pointerIndex, realPath);
+                newImage = photoServer + saveImageSerivce.getSource();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return newImage;
+    }
+
+    public static String saveImageToDfsServer(String imgUrl) throws IOException {
+        String source = "";
+        try {
+            String photoServer = Global.getConfig("photoServer");//获取文件服务器地址
+            InputStream input = UploadPicUtils.getInputStream(imgUrl);
+            ByteArrayOutputStream output = new ByteArrayOutputStream();
+            byte[] buffer = new byte[1024];
+            int len;
+            while ((len = input.read(buffer)) > -1) {
+                output.write(buffer, 0, len);
+            }
+            output.flush();
+//            InputStream cloneInput = new ByteArrayInputStream(output.toByteArray());
+            BufferDfsFile bufferDfsFile = new BufferDfsFile();
+
+            int pointerIndex = imgUrl.lastIndexOf("=");
+            if (pointerIndex == -1) {
+                bufferDfsFile.setFileExtName("jpeg");
+            } else {
+                // dfs 上传原图
+                bufferDfsFile.setFileExtName(imgUrl.substring(pointerIndex + 1));
+            }
+            bufferDfsFile.setBufferFile(output.toByteArray());
+            source = photoServer + DfsFileManager.upload1(bufferDfsFile);
+            System.out.println("==================>新图片路径:" + source);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return source;
+    }
+
+
+    public static void uploadPicToServer(String picUrl, String picName) {
+        try {
+            String host = "120.78.158.98";
+            int port = 22;
+            String username = "root";
+            String password = "qy19970328.";
+            String directory = "/home/pic/";
+            //String downloadFile = "upload.txt";
+            //String saveFile = "D:\\tmp\\save.txt";
+            //String deleteFile = "delete.txt";
+            ChannelSftp sftp = connect(host, port, username, password);
+            upload(directory, picUrl, picName, sftp);
+            //sf.download(directory, downloadFile, saveFile, sftp);
+            //sf.delete(directory, deleteFile, sftp);
+            System.out.println("成功");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /*
+	host 主机
+	port 端口
+	username 用户名
+	password 密码
+	*/
+    public static ChannelSftp connect(String host, int port, String username,
+                                      String password) {
+        ChannelSftp sftp = null;
+        try {
+            JSch jsch = new JSch();
+            jsch.getSession(username, host, port);
+            Session sshSession = jsch.getSession(username, host, port);
+            //SSH实现免密连接
+            sshSession.setPassword(password);
+            Properties sshConfig = new Properties();
+            sshConfig.put("StrictHostKeyChecking", "no");
+            sshSession.setConfig(sshConfig);
+            sshSession.connect();
+            Channel channel = sshSession.openChannel("sftp");
+            channel.connect();
+            sftp = (ChannelSftp) channel;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return sftp;
+    }
+
+    /*directory 上传的目录
+    uploadFile 要上传的文件*/
+    public static void upload(String directory, String picUrl, String picName, ChannelSftp sftp) {
+        try {
+            sftp.cd(directory);
+            sftp.put(getInputStream(picUrl), picName);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static InputStream getInputStream(String picUrl) {
+        InputStream is = null;
+        try {
+            if (picUrl == null || picUrl == "") {
+                return is;
+            }
+            URL urlGet = new URL(picUrl);
+            HttpURLConnection http = (HttpURLConnection) urlGet
+                    .openConnection();
+            http.setRequestMethod("GET"); // 必须是get方式请求
+            http.setRequestProperty("Content-Type",
+                    "application/x-www-form-urlencoded");
+            http.setDoOutput(true);
+            http.setDoInput(true);
+            System.setProperty("sun.net.client.defaultConnectTimeout", "300000");// 连接超时300秒
+            System.setProperty("sun.net.client.defaultReadTimeout", "300000"); // 读取超时300秒
+            http.connect();
+            // 获取文件转化为byte流
+            is = http.getInputStream();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return is;
+
+    }
+}

+ 216 - 0
src/main/java/com/caimei365/manager/config/utils/UploadUtils.java

@@ -0,0 +1,216 @@
+package com.caimei365.manager.config.utils;
+
+import com.caimei.dfs.image.ImageUpload;
+import com.caimei.dfs.image.beens.ImageSize;
+import com.caimei.dfs.image.beens.ImageUploadInfo;
+import com.caimei.utils.Encodes;
+import com.caimei.utils.StringUtils;
+import com.caimei365.manager.config.thinkgem.Global;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.imageio.ImageIO;
+import javax.servlet.http.HttpServletRequest;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class UploadUtils {
+
+	private  final static Logger logger = LoggerFactory.getLogger(UploadUtils.class);
+
+	 /**
+     * @param args
+     */
+    public static void main(String[] args) {
+        String srcImgPath = "E:/work/文档/hehe/bg3282.jpg";
+        String iconPath = "E:/work/文档/hehe/1.png";
+        String targerPath = "E:/work/文档/hehe/test.jpg" ;
+         // 给图片添加水印
+        markImageByIcon(iconPath, srcImgPath, targerPath);
+    }
+
+    /**
+     * 给图片添加水印
+     * @param iconPath 水印图片路径
+     * @param srcImgPath 源图片路径
+     * @param targerPath 目标图片路径
+     */
+    public static void markImageByIcon(String iconPath, String srcImgPath,
+            String targerPath) {
+        markImageByIcon(iconPath, srcImgPath, targerPath, null) ;
+    }
+
+    /**
+     * 给图片添加水印、可设置水印图片旋转角度
+     * @param iconPath 水印图片路径
+     * @param srcImgPath 源图片路径
+     * @param targerPath 目标图片路径
+     * @param degree 水印图片旋转角度
+     */
+    public static void markImageByIcon(String iconPath, String srcImgPath,
+            String targerPath, Integer degree) {
+        OutputStream os = null;
+        try {
+            Image srcImg = ImageIO.read(new File(srcImgPath));
+            BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
+                    srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
+            // 得到画笔对象
+            // Graphics g= buffImg.getGraphics();
+            Graphics2D g = buffImg.createGraphics();
+
+            // 设置对线段的锯齿状边缘处理
+            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+
+            g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg
+                    .getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);
+
+            if (null != degree) {
+                // 设置水印旋转
+                g.rotate(Math.toRadians(degree),
+                        (double) buffImg.getWidth() / 2, (double) buffImg
+                                .getHeight() / 2);
+            }
+            // 水印图象的路径 水印一般为gif或者png的,这样可设置透明度
+            ImageIcon imgIcon = new ImageIcon(iconPath);
+            // 得到Image对象。
+            Image img = imgIcon.getImage();
+            float alpha = 0.5f; // 透明度
+            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
+                    alpha));
+            // 表示水印图片的位置
+            g.drawImage(img, 0, 0, null);
+            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
+            g.dispose();
+            os = new FileOutputStream(targerPath);
+            // 生成图片
+            ImageIO.write(buffImg, "JPG", os);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (null != os)
+                    os.close();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+	 * 得到图片地址
+	 * @param request
+	 * @param maskTemplates
+	 * @param iamgeArray
+	 * @param imagesList
+	 * @param largeImageList
+	 * @throws UnsupportedEncodingException
+	 */
+	public static void getImagesPath(HttpServletRequest request, String maskTemplates, String[] iamgeArray,
+			List<String> imagesList, List<String> largeImageList){
+		for (String iamge : iamgeArray) {
+			iamge=Encodes.urlDecode(iamge);
+			if(!iamge.contains("http:") && !iamge.contains("https:")){
+//			String realPath = request.getSession().getServletContext().getRealPath(iamge);
+                String realPath = UploadImageUtils.getAbsolutePath(iamge);
+//			realPath=Encodes.urlDecode(realPath);
+			int pointerIndex = realPath.lastIndexOf(".");
+			String targetPath = realPath.substring(0, pointerIndex)+"_watermask"+realPath.substring(pointerIndex);
+			// 打水印
+			markImageByIcon(maskTemplates, realPath, targetPath);
+
+			// 保存到图片服务器
+			ImageUploadInfo imageUploadInfo = saveImageSerivce(realPath, pointerIndex, targetPath);
+			Map<String, String> slaveMap = imageUploadInfo.getSlaveMap();
+			if(slaveMap == null) {
+				logger.error("[LG]source ===> " + imageUploadInfo.getSource());
+				logger.error("[LG]slaveMap ===> " + imageUploadInfo.getSlaveMap());
+				imageUploadInfo = saveImageSerivce(realPath, pointerIndex, targetPath);
+				slaveMap = imageUploadInfo.getSlaveMap();
+			}
+			String photoServer = Global.getConfig("photoServer");
+			largeImageList.add(photoServer+imageUploadInfo.getSource()) ;
+
+			imagesList.add(photoServer+slaveMap.get("500x500"));
+
+			}else{
+				String[] s = iamge.split("_500x500");
+				largeImageList.add(s[0]+s[1]);
+				imagesList.add((iamge));
+			}
+		}
+	}
+
+	/**
+	 * 保存到图片服务器
+	 * @param realPath
+	 * @param pointerIndex
+	 * @param targetPath
+	 */
+	public static ImageUploadInfo saveImageSerivce(String realPath, int pointerIndex, String targetPath) {
+		ImageUploadInfo imageUploadInfo =new ImageUploadInfo();
+		try {
+			InputStream inStream = new FileInputStream(targetPath);
+			List<ImageSize> sizeList = new ArrayList<>();
+			ImageSize imageSize = new ImageSize(500);
+			sizeList.add(imageSize);
+			 imageUploadInfo = ImageUpload.resizeMaxSizeUpload(inStream, realPath.substring(pointerIndex+1), sizeList, null);
+//			System.out.println("source ===> " + imageUploadInfo.getSource());
+//			for(Map.Entry<String, String> entry : imageUploadInfo.getSlaveMap().entrySet()) {
+//				System.out.println("key ===> " + entry.getKey() + "," + "value ===> " + entry.getValue());
+//			}
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return imageUploadInfo;
+	}
+
+	/**
+     * 富文本内容处理
+     * @author LG
+     * @date  2016年8月31日
+     * @version 1.0
+     * @param text
+     * @return
+     */
+    public static String textHandle(String text, String photoServer,HttpServletRequest request){
+    	 text=Encodes.unescapeHtml(text);
+		text = StringUtils.replace(text, "<body", "<div");
+		text = StringUtils.replace(text, "</body>", "</div>");
+		//infoContent=Encodes.urlDecode(infoContent);
+		Document doc = Jsoup.parse(text);
+		Elements links = doc.getElementsByTag("img");
+		for (Element link : links) {
+			  String linkSrc = link.attr("src");
+              String linkSrcOld = link.attr("src");
+			  if(StringUtils.isNotBlank(linkSrc) && !linkSrc.startsWith("http:") && !linkSrc.startsWith("https:") && !linkSrc.contains("uploadFile/ueditor") ){//不包含http开头的
+//				  String realPath = Encodes.urlDecode(request.getSession().getServletContext().getRealPath(linkSrc));
+                  linkSrc= Encodes.urlDecode(linkSrc);
+                  String realPath = UploadImageUtils.getAbsolutePath(linkSrc);
+				  int pointerIndex = realPath.lastIndexOf(".");
+					ImageUploadInfo saveImageSerivce=new ImageUploadInfo();
+					try {
+						saveImageSerivce = UploadUtils.saveImageSerivce(realPath, pointerIndex,realPath);
+						String src=photoServer+saveImageSerivce.getSource();
+						text = StringUtils.replace(text, linkSrcOld, src);
+					} catch (Exception e) {
+						logger.error("图片上传错误:"+e.toString(),e);
+					}
+
+			  }
+		}
+		return text;
+    }
+
+}

+ 67 - 6
src/main/java/com/caimei365/manager/controller/caimei/svip/CmSvipHistoryApi.java

@@ -4,14 +4,9 @@ import com.caimei.utils.StringUtils;
 import com.caimei365.manager.entity.PaginationVo;
 import com.caimei365.manager.entity.ResponseJson;
 import com.caimei365.manager.entity.caimei.CmUser;
-import com.caimei365.manager.entity.caimei.svip.CmSvipGive;
-import com.caimei365.manager.entity.caimei.svip.CmSvipHistory;
-import com.caimei365.manager.entity.caimei.svip.CmSvipPackage;
-import com.caimei365.manager.entity.caimei.svip.CmSvipProduct;
+import com.caimei365.manager.entity.caimei.svip.*;
 import com.caimei365.manager.service.caimei.svip.CmSvipHistoryService;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.*;
 
 /**
@@ -58,6 +53,12 @@ public class CmSvipHistoryApi {
         return historyService.findClubList(clubId, name, shortName, pageNum, pageSize);
     }
 
+    /**
+     * 赠送超级会员
+     * @param cmSvipGive
+     * @return
+     * @throws Exception
+     */
     @PostMapping("/saveSvip")
     public ResponseJson save(CmSvipGive cmSvipGive) throws Exception {
         if (StringUtils.isBlank(cmSvipGive.getUserId()) || null == cmSvipGive.getMonth() || null == cmSvipGive.getClubId()) {
@@ -66,6 +67,13 @@ public class CmSvipHistoryApi {
         return historyService.saveGive(cmSvipGive);
     }
 
+    /**
+     * 机构购买记录
+     * @param cmSvipHistory
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
     @GetMapping("/findHistory")
     public ResponseJson<PaginationVo<CmSvipHistory>> findHistory(CmSvipHistory cmSvipHistory,
                                                                  @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
@@ -75,6 +83,59 @@ public class CmSvipHistoryApi {
         }
         return historyService.findHistory(cmSvipHistory, pageNum, pageSize);
     }
+
+    /**
+     * 超级会员专属优惠券
+     * @param cmVipCoupon
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/couponList")
+    public ResponseJson<PaginationVo<CmVipCoupon>> couponList(CmVipCoupon cmVipCoupon,
+                                                              @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                              @RequestParam(value = "pageSize", defaultValue = "20") int pageSize) {
+        return historyService.couponList(cmVipCoupon, pageNum, pageSize);
+    }
+
+    /**
+     * 关闭超级会员专属优惠券
+     * @param id
+     * @return
+     */
+    @GetMapping("/closeCoupon")
+    public ResponseJson closeCoupon(Integer id) {
+        if (null == id) {
+            return ResponseJson.error(-1,"参数为空", null);
+        }
+        return historyService.closeCoupon(id);
+    }
+
+    /**
+     * 开启超级会员专属优惠券
+     * @param id
+     * @return
+     */
+    @GetMapping("/openCoupon")
+    public ResponseJson openCoupon(Integer id) {
+        if (null == id) {
+            return ResponseJson.error(-1,"参数为空", null);
+        }
+        return historyService.openCoupon(id);
+    }
+
+    /**
+     * 删除超级会员专属优惠券
+     * @param id
+     * @return
+     */
+    @GetMapping("/deleteCoupon")
+    public ResponseJson deleteCoupon(Integer id) {
+        if (null == id) {
+            return ResponseJson.error(-1,"参数为空", null);
+        }
+        return historyService.deleteCoupon(id);
+    }
     /**
      * 超级会员商品列表
      * @param cmSvipProduct

+ 40 - 4
src/main/java/com/caimei365/manager/dao/svip/CmSvipHistoryDao.java

@@ -2,10 +2,7 @@ package com.caimei365.manager.dao.svip;
 
 import com.caimei365.manager.entity.caimei.CmUser;
 import com.caimei365.manager.entity.caimei.MessageCenter;
-import com.caimei365.manager.entity.caimei.svip.CmSku;
-import com.caimei365.manager.entity.caimei.svip.CmSvipHistory;
-import com.caimei365.manager.entity.caimei.svip.CmSvipPackage;
-import com.caimei365.manager.entity.caimei.svip.CmSvipProduct;
+import com.caimei365.manager.entity.caimei.svip.*;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
@@ -83,6 +80,45 @@ public interface CmSvipHistoryDao {
      */
     String findMonth(String id);
 
+    CmVipCoupon vipCouponGet(String id);
+
+    CmCoupon CmCouponGet(String id);
+
+    NewCmShop newCmShopGet(String id);
+
+    Integer findRedemptionCodeNum(String couponId);
+
+    void updateByDelFlag(String couponId);
+
+    void updateAssociateByDelFlag(String couponId);
+
+    void updateVipCouponMonth(CmVipCoupon cmVipCoupon);
+
+    void deleteByMonthId(String montId);
+
+    List<Integer> findByCouponId(String couponId);
+
+    void insertCouponAssociate(CmCouponAssociate associate);
+
+    void updateCouponAssociate(CmCouponAssociate a);
+
+    void logicDeleteCouponAssociate(Integer id);
+
+    void insertCoupon(CmCoupon cmCoupon);
+
+    void updateCoupon(CmCoupon cmCoupon);
+
+    /**
+     * 超级会员专属优惠券
+     * @param cmVipCoupon
+     * @return
+     */
+    List<CmVipCoupon> findCouponList(CmVipCoupon cmVipCoupon);
+
+    List<String> getBindCoupons(String montId);
+
+    List<CmCoupon> getCouponListByIds(@Param("bindCoupons") List<String> bindCoupons,@Param("couponType") String couponType,@Param("status") String status);
+
     /**
      * 超级会员优惠商品
      * @param svipProduct

+ 176 - 0
src/main/java/com/caimei365/manager/entity/caimei/svip/CmCoupon.java

@@ -0,0 +1,176 @@
+package com.caimei365.manager.entity.caimei.svip;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/4/11
+ */
+@Data
+public class CmCoupon {
+
+    private String id;
+    /**
+     * 活动主题
+     */
+    private String name;
+    /**
+     * 优惠券金额(面值)
+     */
+    private BigDecimal couponAmount;
+    /**
+     * 优惠满减条件金额
+     */
+    private BigDecimal touchPrice;
+    /**
+     * 使用开始时间(有效期)
+     */
+    private Date startDate;
+    /**
+     * 使用结束时间(有效期)
+     */
+    private Date endDate;
+    /**
+     * 领取期限(天)
+     */
+    private Integer receivePeriod;
+    /**
+     * 领取期限同开始-结束时间
+     */
+    private Integer receiveFlag;
+    /**
+     * 使用期限(天)
+     */
+    private Integer usePeriod;
+    /**
+     * 状态 0未生效 1已生效 2已关闭 3已失效
+     */
+    private String status;
+    /**
+     * 劵类型 0活动券 1品类券 2用户专享券 3店铺券 4新用户券
+     */
+    private Integer couponType;
+    /**
+     * 超级会员专享优惠券标志:0否,1是
+     */
+    private Integer vipFlag;
+    /**
+     * 机构用户id(用户专享券有效)
+     */
+    private Integer userId;
+    /**
+     * 供应商id(店铺券有效)
+     */
+    private Integer shopId;
+    /**
+     * 优惠商品:1全商城商品 2指定商品(活动券有效)
+     */
+    private String productType;
+    /**
+     * 网站活动页banner
+     */
+    private String pcBanner;
+    /**
+     * 小程序活动页banner
+     */
+    private String appletsBanner;
+    /**
+     * 优惠品类:1 产品 2 仪器(品类券有效)
+     */
+    private String categoryType;
+    /**
+     * 领券方式:0正常 1使用兑换码
+     */
+    private String couponsMode;
+    /**
+     * 商品json数据
+     */
+    private String productInfo;
+    /**
+     * 机构名称
+     */
+    private String clubName;
+    /**
+     * 领取状态:1未领取 2已领取
+     */
+    private String claimStatus;
+    /**
+     * 使用状态 1未使用 2已使用
+     */
+    private String useStatus;
+    /**
+     * 领取渠道:1 小程序 2 网站 3 订单退回
+     */
+    private String source;
+    /**
+     * 供应商名称
+     */
+    private String shopName;
+    /**
+     * 兑换码数量
+     */
+    private Integer codeNum;
+    /**
+     * 机构领券id
+     */
+    private Integer clubCouponId;
+    /**
+     * 优惠券名称
+     */
+    private String couponName;
+    /**
+     * 描述
+     */
+    private String couponDesc;
+    /**
+     * 兑换码
+     */
+    private String redemptionCode;
+    private CmCouponClub couponClub;
+    /**
+     * 价值优惠券属性 1,意向券,2,定向券
+     */
+    private Integer moneyCouponType;
+    /**
+     * 是否是价值优惠券,1是,2不是
+     */
+    private Integer moneyCouponFlag;
+    /**
+     * 价值优惠券购买金额
+     */
+    private Double moneyCouponPrice;
+    private NewCmShop shop;
+    private List<Integer> productIdList;
+    /**
+     * 购买方式 1.直接购买 2.采美豆抵扣
+     */
+    private Integer couponPayWay;
+    /**
+     * 使用期限同上下架时间
+     */
+    private Integer useTimeFlag;
+    /**
+     * 领取时间
+     */
+    private Date receiveDate;
+    /**
+     * 使用截止时间
+     */
+    private Date useEndDate;
+    /**
+     * 专属优惠券配置  1是、0否
+     */
+    private Integer configure;
+
+    private Date createDate;
+    /**
+     * 删除标记
+     */
+    private String delFlag;
+}

+ 61 - 0
src/main/java/com/caimei365/manager/entity/caimei/svip/CmCouponAssociate.java

@@ -0,0 +1,61 @@
+package com.caimei365.manager.entity.caimei.svip;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/4/11
+ */
+@Data
+public class CmCouponAssociate {
+
+    private Integer id;
+    /**
+     * 优惠券id
+     */
+    private Integer couponId;
+    /**
+     * 商品id(对应活动券)
+     */
+    private Integer productId;
+    /**
+     * pc状态 0停用 1启用
+     */
+    private String pcStatus;
+    /**
+     * 小程序状态 0停用 1启用
+     */
+    private String appletsStatus;
+    /**
+     * 供应商id(对应店铺券)
+     */
+    private Integer shopId;
+    /**
+     * 排序值
+     */
+    private Integer sort;
+    /**
+     * 添加时间
+     */
+    private Date addTime;
+    /**
+     * 删除标记 0否 其余是
+     */
+    private String delFlag;
+    /**
+     * 商品名称
+     */
+    private String productName;
+    /**
+     * 商品图片
+     */
+    private String image;
+    /**
+     * 供应商名称
+     */
+    private String shopName;
+}

+ 84 - 0
src/main/java/com/caimei365/manager/entity/caimei/svip/CmCouponClub.java

@@ -0,0 +1,84 @@
+package com.caimei365.manager.entity.caimei.svip;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/4/11
+ */
+@Data
+public class CmCouponClub {
+    /**
+     * 机构用户Id
+     */
+    private Integer userId;
+    /**
+     * 优惠券id
+     */
+    private Integer couponId;
+    /**
+     * 订单id
+     */
+    private Integer orderId;
+    /**
+     * 退款id,订单退回时有效
+     */
+    private Integer returnedId;
+    /**
+     * 领取渠道:1小程序 2网站 3订单退回
+     */
+    private String source;
+    /**
+     * 使用状态 1未使用 2已使用
+     */
+    private String status;
+    /**
+     * 使用时间
+     */
+    private Date useDate;
+    /**
+     * 机构名称
+     */
+    private String clubName;
+    /**
+     * 劵类型 0活动券 1品类券 2用户专享券 3店铺券 4新用户券
+     */
+    private Integer couponType;
+    /**
+     * 可用券的数量
+     */
+    private Integer num;
+    /**
+     * 优惠券金额(面值)
+     */
+    private BigDecimal couponAmount;
+    /**
+     * 优惠满减条件金额
+     */
+    private BigDecimal touchPrice;
+    /**
+     * 状态 0未生效 1已生效 2已关闭 3已失效
+     */
+    private String couponStatus;
+    /**
+     * 普通/价值优惠券标记1是2不是
+     */
+    private Integer moneyCouponFlag;
+    /**
+     * 使用开始时间(有效期)
+     */
+    private Date startDate;
+    /**
+     * 使用结束时间(有效期)
+     */
+    private Date endDate;
+    /**
+     * 订单编号
+     */
+    private String orderNo;
+}

+ 2 - 0
src/main/java/com/caimei365/manager/entity/caimei/svip/CmSvipProduct.java

@@ -1,5 +1,6 @@
 package com.caimei365.manager.entity.caimei.svip;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 
 import java.math.BigDecimal;
@@ -38,6 +39,7 @@ public class CmSvipProduct {
     /**
      * 添加时间
      */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date addTime;
     /**
      * 商品图片

+ 38 - 0
src/main/java/com/caimei365/manager/entity/caimei/svip/CmVipCoupon.java

@@ -0,0 +1,38 @@
+package com.caimei365.manager.entity.caimei.svip;
+
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/4/11
+ */
+@Data
+public class CmVipCoupon {
+    private String id;
+    /** 生效月份 */
+    private String useTime;
+    private String endTime;
+    /**
+     * 0未生效 1已生效 2已关闭 3已失效
+     */
+    private String status;
+    /** 一组优惠券id的String字符串,逗号隔开 */
+    private String bindCoupon;
+    private Date updateTime;
+    private String delFlag;
+    /**
+     * 4张优惠券详情
+     */
+    List<CmCoupon> couponList;
+    /** 开始时间 */
+    private String startDate;
+    /** 结束时间 */
+    private String endDate;
+    /** 优惠券类型 */
+    private String couponType;
+}

+ 284 - 0
src/main/java/com/caimei365/manager/entity/caimei/svip/NewCmShop.java

@@ -0,0 +1,284 @@
+package com.caimei365.manager.entity.caimei.svip;
+
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/4/11
+ */
+@Data
+public class NewCmShop {
+
+    /**
+     * 审核人
+     */
+    private String checkMan;
+    /**
+     * shopID
+     */
+    private Integer shopID;
+    /**
+     * 对应的userId
+     */
+    private Integer userID;
+    /**
+     * 名称
+     */
+    private String name;
+    /**
+     * 供应商公司简称
+     */
+    private String sname;
+    /**
+     * 公司LOGO
+     */
+    private String logo;
+    /**
+     * 法人
+     */
+    private String legalPerson;
+    /**
+     *  businessLicense
+     */
+    private String businessLicense;
+    /**
+     * 营业执照
+     */
+    private String businessLicenseImage;
+    /**
+     * taxCertificate
+     */
+    private String taxCertificate;
+    /**
+     * 税务登记证
+     */
+    private String taxCertificateImage;
+    /**
+     * 所在县区Id
+     */
+    private Integer townId;
+    private Integer provinceId;
+    private Integer cityId;
+    /**
+     * 地址
+     */
+    private String address;
+    /**
+     * 注册资本
+     */
+    private String registeredCapital;
+    /**
+     * 公司性质
+     */
+    private String nature;
+    /**
+     * 年营业额
+     */
+    private String turnover;
+    /**
+     * 联系人
+     */
+    private String linkMan;
+    /**
+     * 固定电话
+     */
+    private String contractPhone;
+    /**
+     * 手机号
+     */
+    private String contractMobile;
+    private String contractEmail;
+    /**
+     * 传真
+     */
+    private String fax;
+    /**
+     * 邮编
+     */
+    private String zipCode;
+    /**
+     * 介绍
+     */
+    private String info;
+    /**
+     * 主打产品说明
+     */
+    private String productDesc;
+    /**
+     * 网址
+     */
+    private String website;
+    /**
+     * 微信公众号
+     */
+    private String wxOfficialAccount;
+    /**
+     * 微信小程序
+     */
+    private String wxApplets;
+    /**
+     * 添加时间
+     */
+    private String addTime;
+    /**
+     * 审核状态
+     */
+    private String auditStatus;
+    /**
+     * 审核时间
+     */
+    private String auditTime;
+    /**
+     * 审核信息
+     */
+    private String auditNote;
+    /**
+     * 是否可用,1可用
+     */
+    private String validFlag;
+    /**
+     * note
+     */
+    private String note;
+    /**
+     * 供应商状态,见表c_shopstatus或枚举ShopStatus
+     */
+    private Integer status;
+    /**
+     * 经营范围
+     */
+    private String businessScope;
+    private String firstShopType;
+    private String secondShopType;
+    private String medicalPracticeLicenseImg1;
+    private String medicalPracticeLicenseImg2;
+    private String medicalPracticeLicenseImg3;
+    private String mainpro;
+    /**
+     * 供应商欠款金额
+     */
+    private Double rebateAmount;
+    /**
+     * 银行账号
+     */
+    private String bankAccount;
+    /**
+     * 付款账号的户名
+     */
+    private String bankAccountName;
+    /**
+     * 付款账号的开户行
+     */
+    private String bankName;
+    /**
+     * 可用余额
+     */
+    private Double ableRebateAmount;
+    /**
+     * 邮箱
+     */
+    private String email;
+    private String maintenanceDate;
+    private String maintenanceFee;
+    /**
+     * 荣誉证书1
+     */
+    private String honorCertificate1;
+    /**
+     * 荣誉证书2
+     */
+    private String honorCertificate2;
+    /**
+     * 荣誉证书3
+     */
+    private String honorCertificate3;
+    /**
+     * 荣誉证书4
+     */
+    private String honorCertificate4;
+    /**
+     * 荣誉证书5
+     */
+    private String honorCertificate5;
+    /**
+     * 产品证书
+     */
+    private String productCertificate;
+    /**
+     * 生产许可
+     */
+    private String productionLicense;
+    /**
+     * 卫生许可
+     */
+    private String sanitationPermit;
+    /**
+     * 税务许可
+     */
+    private String taxPermit;
+    /**
+     * 分账方,子商户商编
+     */
+    private List<SplitCode> splitCodes;
+    /**
+     * 列表页回显
+     */
+    private String splitCode;
+    /**
+     * 统一社会信用代码
+     */
+    private String socialCreditCode;
+    /**
+     * 供应商类别 0未审核的二手供应商,普通1,新品供应商2,二手供应商3
+     */
+    private Integer shopType;
+    /**
+     * 收款卡号
+     */
+    private String cardNumber;
+    /**
+     * 线上支付手续费:默认1采美承担,2供应商承担
+     */
+    private Integer chargeSupport;
+    /**
+     * 企业用户账号
+     **/
+    private String account;
+    /**
+     * 注册时间
+     */
+    private Date registerTime;
+    /**
+     * 区
+     */
+    private String town;
+    /**
+     * 市
+     */
+    private String city;
+    /**
+     * 省
+     */
+    private String province;
+    /**
+     * 注册时间开始 查询条件
+     */
+    private String startTime;
+    /**
+     * 注册时间结束  查询条件
+     */
+    private String endTime;
+    /**
+     * 1 编辑,2 审核
+     */
+    private String editStatus;
+    /**
+     * 注册来源: 0 网站 1 小程序
+     */
+    private String source;
+}

+ 30 - 0
src/main/java/com/caimei365/manager/entity/caimei/svip/SplitCode.java

@@ -0,0 +1,30 @@
+package com.caimei365.manager.entity.caimei.svip;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/4/11
+ */
+@Data
+public class SplitCode {
+    /**
+     * 分账商户号
+     */
+    private String splitCode;
+    /**
+     * 账户备注
+     */
+    private String codeRemark;
+    /**
+     * 供应商ID
+     */
+    private Integer shopId;
+    private String email;
+    /**
+     * 微信开户意愿确认 1开通 2未开通
+     */
+    private Integer weChatFlag;
+}

+ 31 - 4
src/main/java/com/caimei365/manager/service/caimei/svip/CmSvipHistoryService.java

@@ -3,10 +3,7 @@ package com.caimei365.manager.service.caimei.svip;
 import com.caimei365.manager.entity.PaginationVo;
 import com.caimei365.manager.entity.ResponseJson;
 import com.caimei365.manager.entity.caimei.CmUser;
-import com.caimei365.manager.entity.caimei.svip.CmSvipGive;
-import com.caimei365.manager.entity.caimei.svip.CmSvipHistory;
-import com.caimei365.manager.entity.caimei.svip.CmSvipPackage;
-import com.caimei365.manager.entity.caimei.svip.CmSvipProduct;
+import com.caimei365.manager.entity.caimei.svip.*;
 
 /**
  * Description
@@ -50,6 +47,36 @@ public interface CmSvipHistoryService {
      */
     ResponseJson<PaginationVo<CmSvipHistory>> findHistory(CmSvipHistory cmSvipHistory, int pageNum, int pageSize);
 
+    /**
+     * 超级会员专属优惠券
+     * @param cmVipCoupon
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmVipCoupon>> couponList(CmVipCoupon cmVipCoupon, int pageNum, int pageSize);
+
+    /**
+     * 关闭超级会员专属优惠券
+     * @param id
+     * @return
+     */
+    ResponseJson closeCoupon(Integer id);
+
+    /**
+     * 开启超级会员专属优惠券
+     * @param id
+     * @return
+     */
+    ResponseJson openCoupon(Integer id);
+
+    /**
+     * 删除超级会员专属优惠券
+     * @param id
+     * @return
+     */
+    ResponseJson deleteCoupon(Integer id);
+
     /**
      *超级会员优惠商品
      * @param svipProduct

+ 114 - 0
src/main/java/com/caimei365/manager/service/caimei/svip/impl/CmCouponService.java

@@ -0,0 +1,114 @@
+package com.caimei365.manager.service.caimei.svip.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.caimei365.manager.config.utils.UploadPicUtils;
+import com.caimei365.manager.dao.svip.CmSvipHistoryDao;
+import com.caimei365.manager.entity.caimei.svip.CmCoupon;
+import com.caimei365.manager.entity.caimei.svip.CmCouponAssociate;
+import com.caimei365.manager.entity.caimei.svip.NewCmShop;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/4/11
+ */
+@Service
+public class CmCouponService {
+
+    @Autowired
+    private CmSvipHistoryDao historyDao;
+
+    public CmCoupon cmCouponget(String id) {
+        CmCoupon coupon = historyDao.CmCouponGet(id);
+        setCouponStatus(coupon, new Date());
+        if (coupon.getCouponType() == 3 && coupon.getShopId() != null) {
+            //店铺券
+            NewCmShop shop = historyDao.newCmShopGet(coupon.getShopId().toString());
+            coupon.setShop(shop);
+        }
+        if ("1".equals(coupon.getCouponsMode())) {
+            Integer codeNum = historyDao.findRedemptionCodeNum(coupon.getId());
+            coupon.setCodeNum(codeNum);
+        }
+        return coupon;
+    }
+
+    public void save(CmCoupon cmCoupon) {
+        if (StringUtils.isNotBlank(cmCoupon.getPcBanner())) {
+            String image = UploadPicUtils.saveImageToServer(cmCoupon.getPcBanner());
+            cmCoupon.setPcBanner(image);
+        }
+        if (StringUtils.isNotBlank(cmCoupon.getAppletsBanner())) {
+            String image = UploadPicUtils.saveImageToServer(cmCoupon.getAppletsBanner());
+            cmCoupon.setAppletsBanner(image);
+        }
+        Date date = new Date();
+        cmCoupon.setCreateDate(date);
+        setCouponStatus(cmCoupon, date);
+        if (StringUtils.isBlank(cmCoupon.getCouponsMode())) {
+            cmCoupon.setCouponsMode("0");
+        }
+        if (null == cmCoupon.getVipFlag()){
+            cmCoupon.setVipFlag(0);
+        }
+        if(null==cmCoupon.getMoneyCouponFlag()){
+            cmCoupon.setMoneyCouponFlag(2);
+        }
+        if (null == cmCoupon.getId()) {
+            historyDao.insertCoupon(cmCoupon);
+        } else {
+            historyDao.updateCoupon(cmCoupon);
+        }
+        List<Integer> associateIds = historyDao.findByCouponId(cmCoupon.getId());
+        if (0 == cmCoupon.getCouponType()) {
+            //活动券
+            if (StringUtils.isNotBlank(cmCoupon.getProductInfo())) {
+                List<CmCouponAssociate> associateList = JSON.parseArray(cmCoupon.getProductInfo(), CmCouponAssociate.class);
+                associateList.forEach(a -> {
+                    if (a.getId() == null) {
+                        a.setDelFlag("0");
+                        a.setCouponId(Integer.valueOf(cmCoupon.getId()));
+                        a.setAddTime(date);
+                        historyDao.insertCouponAssociate(a);
+                    } else {
+                        associateIds.removeIf(id -> id.equals(a.getId()));
+                        historyDao.updateCouponAssociate(a);
+                    }
+                });
+            }
+        }
+        if (associateIds != null && associateIds.size() > 0) {
+            associateIds.forEach(id -> {
+                historyDao.logicDeleteCouponAssociate(id);
+            });
+        }
+    }
+
+    public void delete(CmCoupon cmCoupon) {
+        historyDao.updateByDelFlag(cmCoupon.getId());
+        historyDao.updateAssociateByDelFlag(cmCoupon.getId());
+    }
+
+    public void setCouponStatus(CmCoupon cmCoupon, Date date) {
+        if (cmCoupon != null) {
+            if (!cmCoupon.getStatus().contains("2")) {
+                if (date.compareTo(cmCoupon.getStartDate()) < 0) {
+                    cmCoupon.setStatus("0");
+                } else if (date.compareTo(cmCoupon.getEndDate()) > 0) {
+                    cmCoupon.setStatus("3");
+                } else {
+                    cmCoupon.setStatus("1");
+                }
+            } else {
+                cmCoupon.setStatus("2");
+            }
+        }
+    }
+}

+ 237 - 0
src/main/java/com/caimei365/manager/service/caimei/svip/impl/CmSvipHistoryServiceImpl.java

@@ -2,6 +2,7 @@ package com.caimei365.manager.service.caimei.svip.impl;
 
 import com.caimei.utils.AppUtils;
 import com.caimei.utils.StringUtil;
+import com.caimei.utils.StringUtils;
 import com.caimei365.manager.dao.svip.CmSvipHistoryDao;
 import com.caimei365.manager.entity.PaginationVo;
 import com.caimei365.manager.entity.ResponseJson;
@@ -17,6 +18,7 @@ import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
 
@@ -32,6 +34,40 @@ public class CmSvipHistoryServiceImpl implements CmSvipHistoryService {
 
     @Autowired private CmSvipHistoryDao historyDao;
     @Resource private SendSmsService sendSmsService;
+    @Resource private CmCouponService cmCouponService;
+
+    private CmVipCoupon get(String id) {
+
+        CmVipCoupon vipCoupon = historyDao.vipCouponGet(id);
+        if (null != vipCoupon) {
+            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
+            try {
+                Date parse = simpleDateFormat.parse(vipCoupon.getUseTime());
+                Calendar calendar = Calendar.getInstance();
+                calendar.setTime(parse);
+                calendar.add(Calendar.MONTH,2);
+                Date time = calendar.getTime();
+                vipCoupon.setEndTime(simpleDateFormat.format(time));
+                Date newParse = simpleDateFormat.parse("2023-02");
+                if (parse.before(newParse)) {
+                    vipCoupon.setEndTime(vipCoupon.getUseTime());
+                }
+            } catch (ParseException e) {
+                e.printStackTrace();
+            }
+            setVipCouponStatus(vipCoupon);
+            List<CmCoupon> couponList = new ArrayList<>();
+            List<String> bindCoupons = historyDao.getBindCoupons(id);
+            for (String s : bindCoupons) {
+                CmCoupon cmCoupon = cmCouponService.cmCouponget(s);
+                couponList.add(cmCoupon);
+            }
+            vipCoupon.setCouponList(couponList);
+        }
+        return vipCoupon;
+    }
+
+
 
     @Override
     public ResponseJson<PaginationVo<CmSvipHistory>> memberList(CmSvipHistory vip, Integer pageNum, Integer pageSize) {
@@ -170,6 +206,101 @@ public class CmSvipHistoryServiceImpl implements CmSvipHistoryService {
         return ResponseJson.success(page);
     }
 
+    /**
+     * 超级会员专属优惠券
+     *
+     * @param cmVipCoupon
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmVipCoupon>> couponList(CmVipCoupon cmVipCoupon, int pageNum, int pageSize) {
+        CmVipCoupon couponEnt = quarter(cmVipCoupon);
+        List<CmVipCoupon> cmVipCouponList = historyDao.findCouponList(couponEnt);
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
+        cmVipCouponList.forEach(vipCoupon -> {
+            try {
+                Date parse = simpleDateFormat.parse(vipCoupon.getUseTime());
+                Calendar calendar = Calendar.getInstance();
+                calendar.setTime(parse);
+                calendar.add(Calendar.MONTH,2);
+                Date time = calendar.getTime();
+                vipCoupon.setEndTime(simpleDateFormat.format(time));
+                Date newParse = simpleDateFormat.parse("2023-02");
+                if (parse.before(newParse)) {
+                    vipCoupon.setEndTime(vipCoupon.getUseTime());
+                }
+            } catch (ParseException e) {
+                e.printStackTrace();
+            }
+            setVipCouponStatus(vipCoupon);
+            List<String> bindCoupons = historyDao.getBindCoupons(vipCoupon.getId());
+            List<CmCoupon> couponList = historyDao.getCouponListByIds(bindCoupons, cmVipCoupon.getCouponType(), cmVipCoupon.getStatus());
+            Date date = new Date();
+            couponList.forEach(coupon -> {
+                setCouponStatus(coupon, date);
+            });
+            vipCoupon.setCouponList(couponList);
+        });
+        PaginationVo<CmVipCoupon> page = new PaginationVo<>(cmVipCouponList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 关闭超级会员专属优惠券
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public ResponseJson closeCoupon(Integer id) {
+        CmVipCoupon cmVipCoupon = get(id.toString());
+        cmVipCoupon.setStatus("2");
+        List<CmCoupon> couponList = cmVipCoupon.getCouponList();
+        for (CmCoupon coupon : couponList) {
+            coupon.setStatus("2");
+            cmCouponService.save(coupon);
+        }
+        historyDao.updateVipCouponMonth(cmVipCoupon);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 开启超级会员专属优惠券
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public ResponseJson openCoupon(Integer id) {
+        CmVipCoupon cmVipCoupon = get(id.toString());
+        cmVipCoupon.setStatus("1");
+        List<CmCoupon> couponList = cmVipCoupon.getCouponList();
+        for (CmCoupon coupon : couponList) {
+            coupon.setStatus("1");
+            cmCouponService.save(coupon);
+        }
+        historyDao.updateVipCouponMonth(cmVipCoupon);
+        return ResponseJson.success();
+    }
+
+    @Override
+    public ResponseJson deleteCoupon(Integer id) {
+        CmVipCoupon cmVipCoupon = get(id.toString());
+        cmVipCoupon.setDelFlag("1");
+        List<CmCoupon> couponList = cmVipCoupon.getCouponList();
+        for (CmCoupon coupon : couponList) {
+            coupon.setDelFlag("1");
+            // 逻辑删除
+            cmCouponService.delete(coupon);
+        }
+        historyDao.updateVipCouponMonth(cmVipCoupon);
+        // 逻辑删除关系表
+        historyDao.deleteByMonthId(cmVipCoupon.getId());
+        return ResponseJson.success();
+    }
+
     /**
      * 超级会员优惠商品
      *
@@ -256,4 +387,110 @@ public class CmSvipHistoryServiceImpl implements CmSvipHistoryService {
         }
         return str;
     }
+
+    public void setCouponStatus(CmCoupon cmCoupon, Date date) {
+        if (cmCoupon != null) {
+            if (!cmCoupon.getStatus().contains("2")) {
+                if (date.compareTo(cmCoupon.getStartDate()) < 0) {
+                    cmCoupon.setStatus("0");
+                } else if (date.compareTo(cmCoupon.getEndDate()) > 0) {
+                    cmCoupon.setStatus("3");
+                } else {
+                    cmCoupon.setStatus("1");
+                }
+            } else {
+                cmCoupon.setStatus("2");
+            }
+        }
+    }
+    /**
+     * 设置会员优惠生效状态
+     */
+    private void setVipCouponStatus(CmVipCoupon vipCoupon) {
+        if (!"2".equals(vipCoupon.getStatus())) {
+            try {
+                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM");
+                String current = df.format(new Date());
+                String useTime = vipCoupon.getUseTime();
+                try {
+                    Date parse = df.parse(vipCoupon.getUseTime());
+                    Calendar calendar = Calendar.getInstance();
+                    calendar.setTime(parse);
+                    calendar.add(Calendar.MONTH,2);
+                    Date time = calendar.getTime();
+                    vipCoupon.setEndTime(df.format(time));
+
+                    Date newParse = df.parse("2023-02");
+                    if (parse.before(newParse)) {
+                        vipCoupon.setEndTime(vipCoupon.getUseTime());
+                    }
+//                    current = vipCoupon.getEndTime();
+                } catch (ParseException e) {
+                    e.printStackTrace();
+                }
+                String endTime = vipCoupon.getEndTime();
+                // 0未生效 1已生效 2已关闭 3已失效
+                if (df.parse(useTime).after(df.parse(current))) {
+                    // 未生效
+                    vipCoupon.setStatus("0");
+                } else if (df.parse(endTime).before(df.parse(current))) {
+                    // 已失效
+                    vipCoupon.setStatus("3");
+                } else {
+                    // 生效
+                    vipCoupon.setStatus("1");
+                }
+            } catch (ParseException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+    /**
+     * 查询条件 优惠月份季度调整
+     * @param cmVipCoupon
+     * @return
+     */
+    public CmVipCoupon quarter(CmVipCoupon cmVipCoupon) {
+        String startDate  = "";
+        String endDate  = "";
+        String year = "";
+        String month = "";
+        if (StringUtils.isNotEmpty(cmVipCoupon.getStartDate())) {
+            year = cmVipCoupon.getStartDate().substring(0,cmVipCoupon.getStartDate().length() - 2);
+            month = cmVipCoupon.getStartDate().substring(cmVipCoupon.getStartDate().length() - 2);
+            if (month.equals("02") || month.equals("03") || month.equals("04")) {
+                month = "02";
+            }
+            if (month.equals("05") || month.equals("06") || month.equals("07")) {
+                month = "05";
+            }
+            if (month.equals("08") || month.equals("09") || month.equals("10")) {
+                month = "08";
+            }
+            if (month.equals("11") || month.equals("12") || month.equals("1")) {
+                month = "11";
+            }
+            startDate = year + month;
+        }
+        if (StringUtils.isNotEmpty(cmVipCoupon.getEndDate())) {
+            year = cmVipCoupon.getEndDate().substring(0,cmVipCoupon.getEndDate().length() - 2);
+            month = cmVipCoupon.getEndDate().substring(cmVipCoupon.getEndDate().length() - 2);
+            if (month.equals("02") || month.equals("03") || month.equals("04")) {
+                month = "02";
+            }
+            if (month.equals("05") || month.equals("06") || month.equals("07")) {
+                month = "05";
+            }
+            if (month.equals("08") || month.equals("09") || month.equals("10")) {
+                month = "08";
+            }
+            if (month.equals("11") || month.equals("12") || month.equals("1")) {
+                month = "11";
+            }
+            endDate = year + month;
+        }
+        cmVipCoupon.setStartDate(startDate);
+        cmVipCoupon.setEndDate(endDate);
+        return cmVipCoupon;
+    }
 }

+ 305 - 0
src/main/resources/mapper/svip/CmSvipHistoryDao.xml

@@ -1,6 +1,94 @@
 <?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.caimei365.manager.dao.svip.CmSvipHistoryDao">
+    <sql id="cmCouponColumns">
+        a.id AS "id",
+		a.name AS "name",
+		a.couponAmount AS "couponAmount",
+		a.touchPrice AS "touchPrice",
+		a.startDate AS "startDate",
+		a.endDate AS "endDate",
+		a.status AS "status",
+		a.couponType AS "couponType",
+        a.vipFlag AS "vipFlag",
+		a.userId AS "userId",
+		a.shopId AS "shopId",
+		a.productType AS "productType",
+		a.pcBanner AS "pcBanner",
+		a.appletsBanner AS "appletsBanner",
+		a.categoryType AS "categoryType",
+		a.couponsMode AS "couponsMode",
+		a.createDate AS "createDate",
+		a.delFlag AS "delFlag"
+    </sql>
+    <sql id="newCmShopColumns">
+        a.shopID AS "shopID",
+		a.checkMan as "checkMan",
+		a.userID AS "userID",
+		a.name AS "name",
+		u.userName AS "sname",
+		a.logo AS "logo",
+		a.legalPerson AS "legalPerson",
+		a.businessLicense AS "businessLicense",
+		a.businessLicenseImage AS "businessLicenseImage",
+		a.taxCertificate AS "taxCertificate",
+		a.taxCertificateImage AS "taxCertificateImage",
+		a.townID AS "townID",
+		d.provinceID AS "provinceID",
+		c.cityID AS "cityID",
+		a.address AS "address",
+		a.registeredCapital AS "registeredCapital",
+		a.nature AS "nature",
+		a.turnover AS "turnover",
+		a.linkMan AS "linkMan",
+		a.contractPhone AS "contractPhone",
+		ifnull(u.bindMobile,a.contractMobile) AS "contractMobile",
+		a.contractEmail AS "contractEmail",
+		a.fax AS "fax",
+		a.zipCode AS "zipCode",
+		a.info AS "info",
+		a.productDesc AS "productDesc",
+		a.website,
+		a.wxOfficialAccount,
+		a.wxApplets,
+		a.addTime AS "addTime",
+		a.auditStatus AS "auditStatus",
+		a.auditTime AS "auditTime",
+		a.auditNote AS "auditNote",
+		a.validFlag AS "validFlag",
+		a.status AS "status",
+		a.maintenanceFee AS "maintenanceFee",
+		a.maintenanceDate AS "maintenanceDate",
+		a.businessScope AS "businessScope",
+		u.account AS "account",
+		u.registerTime AS "registerTime",
+		a.firstShopType AS "firstShopType",
+		a.secondShopType AS "secondShopType",
+		a.medicalPracticeLicenseImg1 AS "medicalPracticeLicenseImg1",
+		a.medicalPracticeLicenseImg2 AS "medicalPracticeLicenseImg2",
+		a.medicalPracticeLicenseImg3 AS "medicalPracticeLicenseImg3",
+		a.mainpro AS "mainpro",
+		a.bankAccount AS "bankAccount",
+		a.ableRebateAmount AS "ableRebateAmount",
+		a.rebateAmount AS "rebateAmount",
+		a.bankAccountName AS "bankAccountName",
+		a.bankName AS "bankName",
+		a.socialCreditCode AS "socialCreditCode",
+		u.email,
+		u.source AS "source",
+		a.shopType AS "shopType",
+		a.cardNumber AS "cardNumber",
+		a.chargeSupport AS "chargeSupport",
+		d.name AS "province",c.name AS "city",b.name AS "town"
+    </sql>
+
+    <sql id="newCmShopJoins">
+        LEFT JOIN user u ON u.userID = a.userID
+		LEFT JOIN town b ON b.townID=a.townID
+		LEFT JOIN city c ON c.cityID=b.cityID
+		LEFT JOIN province d ON d.provinceID=c.provinceID
+    </sql>
+
     <select id="superFind" resultType="com.caimei365.manager.entity.caimei.svip.CmSvipHistory">
         SELECT u.name as clubName, u.username as linkMan, u.bindMobile as mobile,
         cs.userId,cs.beginTime,cs.endTime,cs.packageId
@@ -154,6 +242,223 @@
         SELECT TIMESTAMPDIFF(MONTH, cs.beginTime, cs.endTime) FROM cm_svip_history cs
         where id = #{id}
     </select>
+    <select id="vipCouponGet" resultType="com.caimei365.manager.entity.caimei.svip.CmVipCoupon">
+        SELECT DISTINCT id, useTime, status, updateTime, delFlag
+        FROM cm_svip_coupon_month
+        WHERE id = #{id}
+        LIMIT 1
+    </select>
+    <select id="CmCouponGet" resultType="com.caimei365.manager.entity.caimei.svip.CmCoupon">
+        SELECT
+        <include refid="cmCouponColumns"/>
+        FROM cm_coupon a
+        WHERE a.id = #{id}
+    </select>
+    <select id="newCmShopGet" resultType="com.caimei365.manager.entity.caimei.svip.NewCmShop">
+        SELECT
+        <include refid="newCmShopColumns"/>
+        FROM shop a
+        <include refid="newCmShopJoins"/>
+        WHERE a.shopID = #{id}
+    </select>
+    <select id="findRedemptionCodeNum" resultType="java.lang.Integer">
+        SELECT COUNT(id) FROM cm_coupon_redemption_code WHERE couponId = #{couponId}
+    </select>
+    <update id="updateByDelFlag">
+        UPDATE cm_coupon SET delFlag = 1 WHERE id = #{couponId}
+    </update>
+    <update id="updateAssociateByDelFlag">
+        UPDATE cm_coupon_product SET delFlag = 1 WHERE couponId = #{couponId}
+    </update>
+    <update id="updateVipCouponMonth" parameterType="com.caimei365.manager.entity.caimei.svip.CmVipCoupon">
+        UPDATE cm_svip_coupon_month SET useTime=#{useTime}, updateTime=#{updateTime}, status=#{status}, delFlag=#{delFlag}
+        WHERE id=#{id}
+    </update>
+    <delete id="deleteByMonthId">
+        UPDATE cm_svip_coupon SET delFlag=1 WHERE montId = #{montId}
+    </delete>
+    <select id="findByCouponId" resultType="java.lang.Integer">
+        SELECT id FROM cm_coupon_product WHERE couponId = #{couponId} AND delFlag = 0
+    </select>
+    <insert id="insertCouponAssociate">
+        INSERT INTO `cm_coupon_product` (
+            `couponId`, `productId`, `pcStatus`,
+            `appletsStatus`,
+            `sort`, `addTime`, `delFlag`
+        )
+        VALUES
+            (
+                #{couponId}, #{productId}, #{pcStatus},
+                #{appletsStatus},
+                #{sort}, #{addTime}, #{delFlag}
+            )
+    </insert>
+
+    <update id="updateCouponAssociate">
+        UPDATE
+        `cm_coupon_product`
+        <set>
+            <if test="pcStatus != null and pcStatus != ''">
+                `pcStatus` = #{pcStatus},
+            </if>
+            <if test="appletsStatus != null and appletsStatus != ''">
+                `appletsStatus` = #{appletsStatus},
+            </if>
+            <if test="sort != null">
+                `sort` = #{sort},
+            </if>
+        </set>
+        WHERE
+        `id` = #{id}
+    </update>
+    <update id="logicDeleteCouponAssociate">
+        UPDATE cm_coupon_product SET delFlag = 1 WHERE id = #{id}
+    </update>
+
+    <insert id="insertCoupon" parameterType="com.caimei365.manager.entity.caimei.svip.CmCoupon"  keyProperty="id" useGeneratedKeys="true">
+        INSERT INTO cm_coupon(
+            name,
+            couponPayWay,
+            couponAmount,
+            touchPrice,
+            startDate,
+            endDate,
+            receivePeriod,
+            receiveFlag,
+            useTimeFlag,
+            usePeriod,
+            status,
+            couponType,
+            vipFlag,
+            userId,
+            shopId,
+            productType,
+            pcBanner,
+            appletsBanner,
+            categoryType,
+            couponsMode,
+            createDate,
+            moneyCouponPrice,
+            moneyCouponFlag,
+            moneyCouponType,
+            delFlag,
+            configure
+        ) VALUES (
+                     #{name},
+                     #{couponPayWay},
+                     #{couponAmount},
+                     #{touchPrice},
+                     #{startDate},
+                     #{endDate},
+                     #{receivePeriod},
+                     #{receiveFlag},
+                     #{useTimeFlag},
+                     #{usePeriod},
+                     #{status},
+                     #{couponType},
+                     #{vipFlag},
+                     #{userId},
+                     #{shopId},
+                     #{productType},
+                     #{pcBanner},
+                     #{appletsBanner},
+                     #{categoryType},
+                     #{couponsMode},
+                     #{createDate},
+                     #{moneyCouponPrice},
+                     #{moneyCouponFlag},
+                     #{moneyCouponType},
+                     #{delFlag},
+                     #{configure}
+                 )
+    </insert>
+    <update id="updateCoupon">
+        UPDATE cm_coupon SET
+                 name = #{name},
+                 couponPayWay = #{couponPayWay},
+                 couponAmount = #{couponAmount},
+                 touchPrice = #{touchPrice},
+                 startDate = #{startDate},
+                 endDate = #{endDate},
+                 receivePeriod = #{receivePeriod},
+                 receiveFlag = #{receiveFlag},
+                 useTimeFlag = #{useTimeFlag},
+                 usePeriod = #{usePeriod},
+                 status = #{status},
+                 couponType = #{couponType},
+                 vipFlag = #{vipFlag},
+                 userId = #{userId},
+                 shopId = #{shopId},
+                 productType = #{productType},
+                 pcBanner = #{pcBanner},
+                 appletsBanner = #{appletsBanner},
+                 categoryType = #{categoryType},
+                 couponsMode = #{couponsMode},
+                 moneyCouponPrice = #{moneyCouponPrice},
+                 moneyCouponType = #{moneyCouponType},
+                 configure = #{configure}
+        WHERE id = #{id}
+    </update>
+
+    <select id="findCouponList" resultType="com.caimei365.manager.entity.caimei.svip.CmVipCoupon">
+        SELECT cs.id, cs.useTime, cs.status, cs.updateTime, cs.delFlag
+        FROM cm_svip_coupon_month cs
+        <where>
+            AND cs.delFlag = 0
+            <if test="startDate!=null and startDate!=''">
+                AND cs.useTime <![CDATA[  >=  ]]> #{startDate}
+            </if>
+            <if test="endDate!=null and endDate!=''">
+                AND cs.useTime <![CDATA[   <=  ]]> #{endDate}
+            </if>
+            <!-- 0未生效 1已生效 2已关闭 3已失效 -->
+            <if test="status!=null and status!=''">
+                <if test='status == "0"'>
+                    AND cs.status != '2'
+                    AND cs.useTime <![CDATA[ > ]]> DATE_FORMAT(NOW(), '%Y-%m')
+                </if>
+                <if test='status == "1"'>
+                    AND cs.status != '2'
+                    AND cs.useTime <![CDATA[ = ]]> DATE_FORMAT(NOW(), '%Y-%m')
+                </if>
+                <if test='status == "2"'>
+                    AND cs.status = '2'
+                </if>
+                <if test='status == "3"'>
+                    AND cs.status != '2'
+                    AND cs.useTime <![CDATA[ < ]]> DATE_FORMAT(NOW(), '%Y-%m')
+                </if>
+            </if>
+        </where>
+        ORDER BY cs.useTime DESC
+    </select>
+    <select id="getBindCoupons" resultType="java.lang.String">
+        SELECT couponId from cm_svip_coupon  WHERE montId = #{montId} AND delFlag=0
+    </select>
+    <select id="getCouponListByIds" resultType="com.caimei365.manager.entity.caimei.svip.CmCoupon">
+        SELECT
+        <include refid="cmCouponColumns"/>,
+        u.name AS "clubName",
+        s.name AS "shopName"
+        FROM cm_coupon a
+        LEFT JOIN cm_coupon_club ccc ON ccc.couponId = a.id
+        LEFT JOIN USER u ON u.userID = a.userId
+        LEFT JOIN shop s ON s.shopID = a.shopId
+        <where>
+            AND a.delFlag = 0
+            <if test="couponType!=null and couponType!=''">
+                AND a.couponType = #{couponType}
+            </if>
+            <if test="bindCoupons!=null and bindCoupons.size()!=0">
+                AND a.id IN
+                <foreach collection="bindCoupons" open="(" separator="," close=")" item="couponId">
+                    #{couponId}
+                </foreach>
+            </if>
+        </where>
+        GROUP BY a.id
+        ORDER BY a.createDate DESC
+    </select>
     <select id="findProductList" resultType="com.caimei365.manager.entity.caimei.svip.CmSvipProduct">
         SELECT
         a.id AS "id",