diff --git a/ccic-entity/src/main/java/com/ccic/safeliab/entity/ExCustomerRetention.java b/ccic-entity/src/main/java/com/ccic/safeliab/entity/ExCustomerRetention.java new file mode 100644 index 0000000..c655317 --- /dev/null +++ b/ccic-entity/src/main/java/com/ccic/safeliab/entity/ExCustomerRetention.java @@ -0,0 +1,63 @@ +package com.ccic.safeliab.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * 客户留存实体类 + * + * @author edwong + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("ex_customer_retention") +public class ExCustomerRetention extends BaseEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.ID_WORKER) + @JsonFormat(shape = JsonFormat.Shape.STRING) + private Long id; + + /** + * 客户ID + */ + @JsonFormat(shape = JsonFormat.Shape.STRING) + private Long customerId; + + /** + * 说明描述 + */ + private String description; + + /** + * 上传时间 + */ + @DateTimeFormat( + pattern = "yyyy-MM-dd HH:mm:ss" + ) + @JsonFormat( + pattern = "yyyy-MM-dd HH:mm:ss" + ) + private Date uploadTime; + + /** + * 附件ID + */ + @JsonFormat(shape = JsonFormat.Shape.STRING) + private Long fileId; + + /** + * 附件名称 + */ + private String fileName; + +} diff --git a/ccic-entity/src/main/java/com/ccic/safeliab/entity/ExFile.java b/ccic-entity/src/main/java/com/ccic/safeliab/entity/ExFile.java new file mode 100644 index 0000000..5f9cf3e --- /dev/null +++ b/ccic-entity/src/main/java/com/ccic/safeliab/entity/ExFile.java @@ -0,0 +1,33 @@ +package com.ccic.safeliab.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 附件实体类 + * + * @author edwong + * @since 2025-2-26 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("ex_file") +public class ExFile extends BaseEntity { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.ID_WORKER) + @JsonFormat(shape = JsonFormat.Shape.STRING) + private Long id; + private String fileName; + private String originalName; + private String fileSuffix; + private String filePath; + private String businessType; +} diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/dao/CustomerRetMapper.java b/ccic-exam/src/main/java/com/ccic/safeliab/dao/CustomerRetMapper.java new file mode 100644 index 0000000..ccf9462 --- /dev/null +++ b/ccic-exam/src/main/java/com/ccic/safeliab/dao/CustomerRetMapper.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.ccic.safeliab.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ccic.safeliab.entity.ExCustomerRetention; +import com.ccic.safeliab.vo.CustomerRetentionVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * Mapper 接口 + * + * @author edwong + */ +@Mapper +public interface CustomerRetMapper extends BaseMapper { + + List selectCustomerRetPage(IPage page, @Param("customerRet") CustomerRetentionVO customerRetentionVO); +} diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/dao/FileMapper.java b/ccic-exam/src/main/java/com/ccic/safeliab/dao/FileMapper.java new file mode 100644 index 0000000..9a1f563 --- /dev/null +++ b/ccic-exam/src/main/java/com/ccic/safeliab/dao/FileMapper.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.ccic.safeliab.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ccic.safeliab.entity.ExFile; +import org.apache.ibatis.annotations.Mapper; + +/** + * Mapper 接口 + * + * @author edwong + */ +@Mapper +public interface FileMapper extends BaseMapper { + +} diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/service/CustomerRetService.java b/ccic-exam/src/main/java/com/ccic/safeliab/service/CustomerRetService.java new file mode 100644 index 0000000..0eed553 --- /dev/null +++ b/ccic-exam/src/main/java/com/ccic/safeliab/service/CustomerRetService.java @@ -0,0 +1,16 @@ +package com.ccic.safeliab.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ccic.safeliab.entity.ExCustomerRetention; +import com.ccic.safeliab.support.BaseService; +import com.ccic.safeliab.vo.CustomerRetentionVO; + +/** + * 服务类 + * + * @author edwong + */ +public interface CustomerRetService extends BaseService { + + IPage findPage(CustomerRetentionVO cusRet, int page, int num); +} diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/service/CustomerRetServiceImpl.java b/ccic-exam/src/main/java/com/ccic/safeliab/service/CustomerRetServiceImpl.java new file mode 100644 index 0000000..b0a811d --- /dev/null +++ b/ccic-exam/src/main/java/com/ccic/safeliab/service/CustomerRetServiceImpl.java @@ -0,0 +1,27 @@ +package com.ccic.safeliab.service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ccic.safeliab.dao.CustomerRetMapper; +import com.ccic.safeliab.entity.ExCustomerRetention; +import com.ccic.safeliab.support.BaseServiceImpl; +import com.ccic.safeliab.support.Condition; +import com.ccic.safeliab.vo.CustomerRetentionVO; +import org.springframework.stereotype.Service; + +/** + * 服务实现类 + * + * @author edwong + */ +@Service +public class CustomerRetServiceImpl extends BaseServiceImpl implements CustomerRetService { + + @Override + public IPage findPage(CustomerRetentionVO cusRet, int page, int num) { + IPage iPage = new Page<>(page, num); + iPage.setRecords(baseMapper.selectCustomerRetPage(iPage, cusRet)); + return iPage; + } +} diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/service/FileService.java b/ccic-exam/src/main/java/com/ccic/safeliab/service/FileService.java new file mode 100644 index 0000000..d233d45 --- /dev/null +++ b/ccic-exam/src/main/java/com/ccic/safeliab/service/FileService.java @@ -0,0 +1,21 @@ +package com.ccic.safeliab.service; + +import com.alibaba.nacos.shaded.com.google.protobuf.ServiceException; +import com.ccic.safeliab.entity.ExFile; +import com.ccic.safeliab.support.BaseService; + +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + +/** + * 服务类 + * + * @author edwong + */ +public interface FileService extends BaseService { + + Map saveFileInfo(String fileType, String filePath, String fileName, String fileSuffix, String oldFileName); + + void downloadFile(String fileName, HttpServletResponse response); + +} diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/service/FileServiceImpl.java b/ccic-exam/src/main/java/com/ccic/safeliab/service/FileServiceImpl.java new file mode 100644 index 0000000..3fe13b6 --- /dev/null +++ b/ccic-exam/src/main/java/com/ccic/safeliab/service/FileServiceImpl.java @@ -0,0 +1,94 @@ +package com.ccic.safeliab.service; + +import com.alibaba.nacos.shaded.com.google.protobuf.ServiceException; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.ccic.safeliab.dao.FileMapper; +import com.ccic.safeliab.entity.ExFile; +import com.ccic.safeliab.support.BaseServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.FileInputStream; +import java.util.HashMap; +import java.util.Map; + +/** + * 服务实现类 + * + * @author edwong + */ +@Slf4j +@Service +public class FileServiceImpl extends BaseServiceImpl implements FileService { + + @Override + public Map saveFileInfo(String fileType, String filePath, String fileName, String fileSuffix, String oldFileName) { + ExFile file = new ExFile(); + file.setFileName(fileName); + file.setOriginalName(oldFileName); + file.setFileSuffix(fileSuffix); + file.setFilePath(filePath); + file.setBusinessType(fileType); + boolean saveFlag = super.save(file); + Map map = new HashMap<>(); + if (saveFlag) { + map.put("id", file.getId().toString()); + map.put("url", "./ex/file/download?fileName=" + fileName); + map.put("fileName", fileName); + map.put("name", oldFileName); + return map; + } + return null; + } + + @Override + public void downloadFile(String fileName, HttpServletResponse response) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.lambda().eq(ExFile::getFileName, fileName); + ExFile info = super.getOne(wrapper, false); + + if (info == null) { + log.error("下载文件出错,文件名: {}", fileName); + return; + } + + String path = "." + info.getFilePath() + info.getFileName() + info.getFileSuffix(); + String osName = System.getProperties().getProperty("os.name"); + + if (osName.contains("Windows")) { + path = "C:/" + path; + } + + File file = new File(path); + if (!file.exists()) { + log.error("下载文件出错,文件路径: {}", path); + return; + } + + try { + String realName = info.getOriginalName(); + // 3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码 + response.setHeader("Content-Disposition", "attachment; filename=\"" + new String(realName.getBytes(), "ISO8859-1") + "\""); + response.setCharacterEncoding("UTF-8"); + // 4. 获取下载文件的输入流 + FileInputStream in = new FileInputStream(path); + // 5. 创建缓冲区 + int len = 0; + byte[] buffer = new byte[1024]; + // 6. 获取OutputStream对象 + ServletOutputStream out = response.getOutputStream(); + // 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端! + while ((len = in.read(buffer)) > 0) { + out.write(buffer, 0, len); + } + in.close(); + out.close(); + } catch (Exception e) { + log.error("下载文件出错,原因: {}", e.getMessage()); + } + + } +} diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/service/StatisticsService.java b/ccic-exam/src/main/java/com/ccic/safeliab/service/StatisticsService.java index 1fc65e8..4c3d413 100644 --- a/ccic-exam/src/main/java/com/ccic/safeliab/service/StatisticsService.java +++ b/ccic-exam/src/main/java/com/ccic/safeliab/service/StatisticsService.java @@ -29,5 +29,5 @@ import java.util.Map; */ public interface StatisticsService { - Page findPage(CustomerVO customer); + Page findPage(CustomerVO customer, int page, int num); } diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/service/StatisticsServiceImpl.java b/ccic-exam/src/main/java/com/ccic/safeliab/service/StatisticsServiceImpl.java index 90e45a7..954c5c5 100644 --- a/ccic-exam/src/main/java/com/ccic/safeliab/service/StatisticsServiceImpl.java +++ b/ccic-exam/src/main/java/com/ccic/safeliab/service/StatisticsServiceImpl.java @@ -42,8 +42,8 @@ public class StatisticsServiceImpl implements StatisticsService { private ICustomerService customerService; @Override - public Page findPage(CustomerVO customer) { - Page page = new Page(customer.getPage(), customer.getNum()); + public Page findPage(CustomerVO customer, int page, int num) { + Page iPage = new Page(customer.getPage(), customer.getNum()); QueryWrapper wrapper = Condition.getQueryWrapper(customer); if (!StringUtils.isEmpty(customer.getKeyword())) { // 客户名称与编号过滤 @@ -60,8 +60,9 @@ public class StatisticsServiceImpl implements StatisticsService { wrapper.lambda().eq(Customer::getTypePid, customer.getTypePid()); } wrapper.orderByDesc("changed_at"); - customerService.page(page,wrapper); + wrapper.orderByDesc("customer_id"); + customerService.page(iPage,wrapper); - return page; + return iPage; } } diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/util/DateTimeUtils.java b/ccic-exam/src/main/java/com/ccic/safeliab/util/DateTimeUtils.java new file mode 100644 index 0000000..275d29c --- /dev/null +++ b/ccic-exam/src/main/java/com/ccic/safeliab/util/DateTimeUtils.java @@ -0,0 +1,440 @@ +package com.ccic.safeliab.util; + + +import com.baomidou.mybatisplus.core.toolkit.StringUtils; + +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * 日期处理工具类 + */ +public class DateTimeUtils { + + public static final String FULL_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + public static final String FULL_DATE_FORMAT_CN = "yyyy年MM月dd日 HH时mm分ss秒"; + public static final String PART_DATE_FORMAT = "yyyy-MM-dd"; + public static final String PART_DATE_FORMAT_CN = "yyyy年MM月dd日"; + public static final String YEAR_DATE_FORMAT = "yyyy"; + public static final String MONTH_DATE_FORMAT = "MM"; + public static final String DAY_DATE_FORMAT = "dd"; + public static final String WEEK_DATE_FORMAT = "week"; + public static final String YEAR_MONTH_DATE_FORMAT = "yyyyMMdd"; + + + /** + * 将日期类型转换为字符串 + * + * @param date 日期 + * @param xFormat 格式 + * @return + */ + public static String getFormatDate(Date date, String xFormat) { + date = date == null ? new Date() : date; + xFormat = StringUtils.isNotEmpty(xFormat) ? xFormat : FULL_DATE_FORMAT; + SimpleDateFormat sdf = new SimpleDateFormat(xFormat); + return sdf.format(date); + } + + + /** + * 比较日期大小 + * + * @param dateX + * @param dateY + * @return x < y return [-1]; + * x = y return [0] ; + * x > y return [1] ; + */ + public static int compareDate(Date dateX, Date dateY) { + return dateX.compareTo(dateY); + } + + + /** + * 将日期字符串转换为日期格式类型 + * + * @param xDate + * @param xFormat 为NULL则转换如:2012-06-25 + * @return + */ + public static Date parseString2Date(String xDate, String xFormat) { + while (!isNotDate(xDate)) { + xFormat = StringUtils.isNotEmpty(xFormat) == true ? xFormat : PART_DATE_FORMAT; + SimpleDateFormat sdf = new SimpleDateFormat(xFormat); + Date date = null; + try { + date = sdf.parse(xDate); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + return date; + } + return null; + } + + + /** + * 判断需要转换类型的日期字符串是否符合格式要求 + * + * @param xDate + * @return + */ + public static boolean isNotDate(String xDate) { + SimpleDateFormat sdf = new SimpleDateFormat(PART_DATE_FORMAT); + try { + if (StringUtils.isEmpty(xDate)) { + return true; + } + sdf.parse(xDate); + return false; + } catch (ParseException e) { + e.printStackTrace(); + return true; + } + } + + public static boolean isDate(String xDate) { + return !isDate(xDate); + } + + + /** + * 获取俩个日期之间相差天数 + * + * @param dateX + * @param dateY + * @return + */ + public static int getDiffDays(Date dateX, Date dateY) { + if ((dateX == null) || (dateY == null)) { + return 0; + } + + int dayX = (int) (dateX.getTime() / (60 * 60 * 1000 * 24)); + int dayY = (int) (dateY.getTime() / (60 * 60 * 1000 * 24)); + + return dayX > dayY ? dayX - dayY : dayY - dayX; + } + + /** + * 获取俩个日期之间相差天数(日期) + * + * @param dateX + * @param dateY + * @return + */ + public static int getDiffDaysNoABS(Date dateX, Date dateY) { + if ((dateX == null) || (dateY == null)) { + return 0; + } + + int dayX = (int) (dateX.getTime() / (60 * 60 * 1000 * 24)); + int dayY = (int) (dateY.getTime() / (60 * 60 * 1000 * 24)); + + return dayX - dayY; + } + + + /** + * 获取传值日期之后几天的日期并转换为字符串类型 + * + * @param date 需要转换的日期 date 可以为NULL 此条件下则获取当前日期 + * @param after 天数 + * @param xFormat 转换字符串类型 (可以为NULL) + * @return + */ + public static String getAfterCountDate(Date date, int after, String xFormat) { + date = date == null ? new Date() : date; + xFormat = StringUtils.isNotEmpty(xFormat) == true ? xFormat : PART_DATE_FORMAT; + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.DAY_OF_MONTH, after); + return getFormatDate(calendar.getTime(), xFormat); + } + + /** + * 获取传值日期之前几天的日期并转换为字符串类型 + * + * @param date 需要转换的日期 date 可以为NULL 此条件下则获取当前日期 + * @param before 天数 + * @param xFormat 转换字符串类型 (可以为NULL) + * @return + */ + public static String getBeforeCountDate(Date date, int before, String xFormat) { + date = date == null ? new Date() : date; + xFormat = StringUtils.isNotEmpty(xFormat) == true ? xFormat : PART_DATE_FORMAT; + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.DAY_OF_MONTH, -before); + return getFormatDate(calendar.getTime(), xFormat); + } + + + /** + * 获取日期的参数 如:年 , 月 , 日 , 星期几 + * + * @param xDate 日期 可以为日期格式,可以是字符串格式; 为NULL或者其他格式时都判定为当前日期 + * @param xFormat 年 yyyy 月 MM 日 dd 星期 week ;其他条件下都返回0 + */ + public static int getDateTimeParam(Object xDate, String xFormat) { + xDate = xDate == null ? new Date() : xDate; + Date date = null; + if (xDate instanceof String) { + date = parseString2Date(xDate.toString(), null); + } else if (xDate instanceof Date) { + date = (Date) xDate; + } else { + date = new Date(); + } + date = date == null ? new Date() : date; + if (StringUtils.isNotEmpty(xFormat) + && (xFormat.equals(YEAR_DATE_FORMAT) + || xFormat.equals(MONTH_DATE_FORMAT) + || xFormat.equals(DAY_DATE_FORMAT))) { + return Integer.parseInt(getFormatDate(date, xFormat)); + } else if (StringUtils.isNotEmpty(xFormat) + && (WEEK_DATE_FORMAT.equals(xFormat))) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int week = cal.get(Calendar.DAY_OF_WEEK) - 1 == 0 ? + 7 : cal.get(Calendar.DAY_OF_WEEK) - 1; + return week; + } else { + return 0; + } + } + + + /** + * 日期格式转换为时间戳 + * + * @param time + * @param format + * @return + */ + public static Long getLongTime(String time, String format) { + SimpleDateFormat sdf = new SimpleDateFormat(format); + Date date = null; + try { + date = sdf.parse(time); + return (date.getTime() / 1000); + } catch (ParseException e) { + e.printStackTrace(); + } + return null; + } + + + /** + * 获取星期字符串 + * + * @param xDate + * @return + */ + public static String getWeekString(Object xDate) { + int week = getDateTimeParam(xDate, WEEK_DATE_FORMAT); + switch (week) { + case 1: + return "星期一"; + case 2: + return "星期二"; + case 3: + return "星期三"; + case 4: + return "星期四"; + case 5: + return "星期五"; + case 6: + return "星期六"; + case 7: + return "星期日"; + default: + return ""; + } + } + + /** + * 获得十位时间 + */ + public static Long getTenBitTimestamp() { + return System.currentTimeMillis() / 1000; + } + + /** + * 获得某天的结束时间 + */ + public static Date getDateEnd(Date date) { + return new Date(date.getTime() + (86400 - 1) * 1000); + } + + /** + * 日期格式转换为毫秒 + * + * @param time + * @param format + * @return + */ + public static Long getLongDateTime(String time, String format) { + SimpleDateFormat sdf = new SimpleDateFormat(format); + Date date = null; + try { + date = sdf.parse(time); + return date.getTime(); + } catch (ParseException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 获取某天开始时间戳_10位 + */ + public static Long getStartTimestamp(Date date) { + + Calendar calendar = Calendar.getInstance(); + date = date == null ? new Date() : date; + calendar.setTime(date); + + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + + return calendar.getTime().getTime() / 1000; + } + + /** + * 获取某天结束时间戳_10位 + */ + public static Long getEndTimestamp(Date date) { + + Calendar calendar = Calendar.getInstance(); + date = date == null ? new Date() : date; + calendar.setTime(date); + + calendar.set(Calendar.HOUR_OF_DAY, 23); + calendar.set(Calendar.MINUTE, 59); + calendar.set(Calendar.SECOND, 59); + calendar.set(Calendar.MILLISECOND, 999); + + return calendar.getTime().getTime() / 1000; + } + + /** + * 获取昨天日期 + * + * @param date + * @return + */ + public static Date getYesterday(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.DAY_OF_MONTH, -1); + + calendar.set(Calendar.HOUR_OF_DAY, 9); + calendar.set(Calendar.MINUTE, 59); + calendar.set(Calendar.SECOND, 59); + calendar.set(Calendar.MILLISECOND, 999); + date = calendar.getTime(); + return date; + } + + /** + * 获取明天时间(参数时间+1天) + * + * @param date + * @return + */ + public static Date getTomorrowday(Date date) { + Calendar c = Calendar.getInstance(); + c.setTime(date); + c.add(Calendar.DAY_OF_YEAR, +1); + return c.getTime(); + } + + /* 10位int型的时间戳转换为String(yyyy-MM-dd HH:mm:ss) + * + * @param time + * @return + */ + public static String timestampToString(Integer time, String format) { + // int转long时,先进行转型再进行计算,否则会是计算结束后在转型 + long temp = (long) time * 1000; + Timestamp ts = new Timestamp(temp); + String tsStr = ""; + DateFormat dateFormat = new SimpleDateFormat(format); + try { + // 方法一 + tsStr = dateFormat.format(ts); + } catch (Exception e) { + e.printStackTrace(); + } + return tsStr; + } + + /** + * 获取某天开始时间 + */ + public static Date getStartTime(Date date) { + + Calendar calendar = Calendar.getInstance(); + date = date == null ? new Date() : date; + calendar.setTime(date); + + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + + return calendar.getTime(); + } + + /** + * 获取某天结束时间 + */ + public static Date getEndTime(Date date) { + + Calendar calendar = Calendar.getInstance(); + date = date == null ? new Date() : date; + calendar.setTime(date); + + calendar.set(Calendar.HOUR_OF_DAY, 23); + calendar.set(Calendar.MINUTE, 59); + calendar.set(Calendar.SECOND, 59); + calendar.set(Calendar.MILLISECOND, 999); + + return calendar.getTime(); + } + + /** + * Date类型转换为10位时间戳 + * + * @param time + * @return + */ + public static Integer DateToTimestamp(Date time) { + Timestamp ts = new Timestamp(time.getTime()); + + return (int) ((ts.getTime()) / 1000); + } + + /** + * 获取当前时间之前或之后几分钟 + * + * @param minute + * @return + */ + public static String getTimeByMinute(int minute, Date time) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(time); + calendar.add(Calendar.MINUTE, minute); + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()); + + } +} diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/vo/CustomerRetentionVO.java b/ccic-exam/src/main/java/com/ccic/safeliab/vo/CustomerRetentionVO.java new file mode 100644 index 0000000..367be37 --- /dev/null +++ b/ccic-exam/src/main/java/com/ccic/safeliab/vo/CustomerRetentionVO.java @@ -0,0 +1,18 @@ +package com.ccic.safeliab.vo; + +import com.ccic.safeliab.entity.ExCustomerRetention; +import lombok.Data; + +/** + *

+ * 客户留存表 + *

+ * + * @author edwong + */ +@Data +public class CustomerRetentionVO extends ExCustomerRetention { + + private String fileUid; + +} diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/web/FileController.java b/ccic-exam/src/main/java/com/ccic/safeliab/web/FileController.java new file mode 100644 index 0000000..0214700 --- /dev/null +++ b/ccic-exam/src/main/java/com/ccic/safeliab/web/FileController.java @@ -0,0 +1,84 @@ +package com.ccic.safeliab.web; +import com.ccic.safeliab.service.FileService; +import com.ccic.safeliab.util.DateTimeUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import com.ccic.safeliab.util.R; + +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * Created by edwong on 2025/2/28. + * 文件控制器 + */ +@RestController +@RequestMapping("/ex/file") +@Slf4j +public class FileController { + + @Value("${file.upload_path}") + private String uploadPath; + + @Autowired + private FileService fileService; + + + /** + * 附件上载 + */ + @PostMapping(value = "/upload") + public R upload(@RequestPart("file") MultipartFile picture, @RequestParam("fileType") String fileType) { + Map resultMap = new HashMap<>(); + try { + if (null != picture) { + String sUniqueNewImageName = UUID.randomUUID().toString(); + String sOriginalFilename = picture.getOriginalFilename(); + int suffixIndex = sOriginalFilename.lastIndexOf("."); + String suffix = ""; + if (suffixIndex > 0) { + suffix = sOriginalFilename.substring(suffixIndex); + } + String fileSavePath = uploadPath; + + if (StringUtils.isEmpty(fileType)) { + fileType = "default"; + } + + fileSavePath = fileSavePath + fileType + "/" + DateTimeUtils.getFormatDate(new Date(), DateTimeUtils.YEAR_MONTH_DATE_FORMAT) + "/"; + + String filePath = "/data/actual/" + fileType + "/" + DateTimeUtils.getFormatDate(new Date(), DateTimeUtils.YEAR_MONTH_DATE_FORMAT) + "/"; + if (!new File(fileSavePath).exists()) { + new File(fileSavePath).mkdirs(); + } + picture.transferTo(new File(fileSavePath + sUniqueNewImageName + suffix)); + + resultMap = fileService.saveFileInfo(fileType, filePath, sUniqueNewImageName, suffix, sOriginalFilename); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return R.error().data(e.getMessage()); + } + return R.ok().data(resultMap); + } + + /** + * 附件上载 + */ + @GetMapping(value = "/download") + @ResponseBody + public void download(@RequestParam("fileName") String fileName, HttpServletResponse response) { + fileService.downloadFile(fileName, response); + } + +} + + diff --git a/ccic-exam/src/main/java/com/ccic/safeliab/web/StatisticsController.java b/ccic-exam/src/main/java/com/ccic/safeliab/web/StatisticsController.java index af5e8a2..b6f8f09 100644 --- a/ccic-exam/src/main/java/com/ccic/safeliab/web/StatisticsController.java +++ b/ccic-exam/src/main/java/com/ccic/safeliab/web/StatisticsController.java @@ -1,22 +1,59 @@ package com.ccic.safeliab.web; +import com.ccic.safeliab.entity.ExCustomerRetention; +import com.ccic.safeliab.service.CustomerRetService; import com.ccic.safeliab.service.StatisticsService; import com.ccic.safeliab.util.R; +import com.ccic.safeliab.vo.CustomerRetentionVO; import com.ccic.safeliab.vo.CustomerVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import java.util.Date; +/** + * 客户统计控制器 + * + * @author edwong + */ @RestController @RequestMapping("/ex/statistics") public class StatisticsController { @Autowired private StatisticsService statisticsService; + @Autowired + private CustomerRetService customerRetService; + /** + * 分页 客户列表(统计动态看板) + * @param customer + * @return + */ @PostMapping("/page") - public R page(@RequestBody CustomerVO customer) { - return R.ok().dataPage(statisticsService.findPage(customer)); + public R page(@RequestBody CustomerVO customer, + @RequestParam int page,@RequestParam int num) { + return R.ok().dataPage(statisticsService.findPage(customer, page, num)); + } + + /** + * 分页 客户留存 + * @param customerRetention + * @return + */ + @PostMapping("/customerRetPage") + public R customerRetPage(@RequestBody CustomerRetentionVO customerRetention, + @RequestParam int page,@RequestParam int num) { + return R.ok().data(customerRetService.findPage(customerRetention, page, num)); + } + + /** + * 新增或修改 客户留存 + */ + @PostMapping("/submitCustomerRet") + public R submitCustomerRet(@RequestBody ExCustomerRetention customerRetention) { + customerRetention.setUploadTime(new Date()); + return R.ok().data(customerRetService.save(customerRetention)); } diff --git a/ccic-exam/src/main/resources/mappers/CustomerRetMapper.xml b/ccic-exam/src/main/resources/mappers/CustomerRetMapper.xml new file mode 100644 index 0000000..3ff9747 --- /dev/null +++ b/ccic-exam/src/main/resources/mappers/CustomerRetMapper.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + +