mirror of
				https://gitee.com/lab1024/smart-admin.git
				synced 2025-11-04 10:23:43 +08:00 
			
		
		
		
	【V3.2.0】1、左侧菜单Logo和标题固定;2、Excel导出添加水印;3、长时间不在线自动返回登录页;4、移除sa-token的 token-prefix 配置;5、升级 ant deign vue到最新版4.2;6、登录页面引入登录类型图标方式;7、文件预览组件的文件下载方式为接口方式下载;
This commit is contained in:
		@@ -39,6 +39,7 @@
 | 
			
		||||
        <xerces.version>2.12.0</xerces.version>
 | 
			
		||||
        <easy-excel.version>3.3.2</easy-excel.version>
 | 
			
		||||
        <poi.version>5.2.4</poi.version>
 | 
			
		||||
        <ooxml-schemas.version>1.4</ooxml-schemas.version>
 | 
			
		||||
        <aws-java-sdk.version>1.11.842</aws-java-sdk.version>
 | 
			
		||||
        <log4j-spring-boot.version>2.17.2</log4j-spring-boot.version>
 | 
			
		||||
        <hutool.version>5.7.22</hutool.version>
 | 
			
		||||
@@ -282,19 +283,18 @@
 | 
			
		||||
                <version>${poi.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
 | 
			
		||||
            <!-- 为Excel导出添加水印-->
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>org.apache.poi</groupId>
 | 
			
		||||
                <artifactId>ooxml-schemas</artifactId>
 | 
			
		||||
                <version>1.4</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>org.apache.poi</groupId>
 | 
			
		||||
                <artifactId>poi-scratchpad</artifactId>
 | 
			
		||||
                <version>${poi.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>org.apache.poi</groupId>
 | 
			
		||||
                <artifactId>ooxml-schemas</artifactId>
 | 
			
		||||
                <version>${ooxml-schemas.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>com.fasterxml.jackson.datatype</groupId>
 | 
			
		||||
                <artifactId>jackson-datatype-jsr310</artifactId>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
package net.lab1024.sa.admin.module.business.goods.controller;
 | 
			
		||||
 | 
			
		||||
import cn.dev33.satoken.annotation.SaCheckPermission;
 | 
			
		||||
import io.swagger.v3.oas.annotations.tags.Tag;
 | 
			
		||||
import io.swagger.v3.oas.annotations.Operation;
 | 
			
		||||
import io.swagger.v3.oas.annotations.tags.Tag;
 | 
			
		||||
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
 | 
			
		||||
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsAddForm;
 | 
			
		||||
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsQueryForm;
 | 
			
		||||
@@ -10,16 +10,17 @@ import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsUpdateForm;
 | 
			
		||||
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsExcelVO;
 | 
			
		||||
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO;
 | 
			
		||||
import net.lab1024.sa.admin.module.business.goods.service.GoodsService;
 | 
			
		||||
import net.lab1024.sa.admin.util.excel.ExcelUtils;
 | 
			
		||||
import net.lab1024.sa.base.common.domain.PageResult;
 | 
			
		||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
 | 
			
		||||
import net.lab1024.sa.base.common.domain.ValidateList;
 | 
			
		||||
import net.lab1024.sa.base.common.util.SmartExcelUtil;
 | 
			
		||||
import org.springframework.web.bind.annotation.*;
 | 
			
		||||
import org.springframework.web.multipart.MultipartFile;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import javax.validation.Valid;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -85,10 +86,9 @@ public class GoodsController {
 | 
			
		||||
    @Operation(summary = "导出 @author 卓大")
 | 
			
		||||
    @GetMapping("/goods/exportGoods")
 | 
			
		||||
    @SaCheckPermission("goods:exportGoods")
 | 
			
		||||
    public void exportGoods(HttpServletResponse response)  {
 | 
			
		||||
    public void exportGoods(HttpServletResponse response) throws IOException {
 | 
			
		||||
        List<GoodsExcelVO> goodsList = goodsService.getAllGoods();
 | 
			
		||||
        ExcelUtils<GoodsExcelVO> utils = new ExcelUtils<>(GoodsExcelVO.class);
 | 
			
		||||
        utils.exportData(response,goodsList,"商品列表");
 | 
			
		||||
        SmartExcelUtil.exportExcel(response,"商品列表.xlsx","商品",GoodsExcelVO.class, goodsList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,12 +10,11 @@ import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEm
 | 
			
		||||
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO;
 | 
			
		||||
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO;
 | 
			
		||||
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO;
 | 
			
		||||
import net.lab1024.sa.admin.util.excel.ExcelUtils;
 | 
			
		||||
import net.lab1024.sa.admin.util.AdminRequestUtil;
 | 
			
		||||
import net.lab1024.sa.base.common.domain.PageResult;
 | 
			
		||||
import net.lab1024.sa.base.common.domain.RequestUser;
 | 
			
		||||
import net.lab1024.sa.base.common.domain.ResponseDTO;
 | 
			
		||||
import net.lab1024.sa.base.common.util.SmartRequestUtil;
 | 
			
		||||
import net.lab1024.sa.base.common.util.SmartResponseUtil;
 | 
			
		||||
import net.lab1024.sa.base.common.util.*;
 | 
			
		||||
import net.lab1024.sa.base.module.support.operatelog.annotation.OperateLog;
 | 
			
		||||
import org.apache.commons.collections.CollectionUtils;
 | 
			
		||||
import org.springframework.web.bind.annotation.*;
 | 
			
		||||
@@ -23,6 +22,8 @@ import org.springframework.web.bind.annotation.*;
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import javax.validation.Valid;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -52,14 +53,18 @@ public class EnterpriseController {
 | 
			
		||||
 | 
			
		||||
    @Operation(summary = "导出企业信息 @author 卓大")
 | 
			
		||||
    @PostMapping("/oa/enterprise/exportExcel")
 | 
			
		||||
    public void exportExcel(@RequestBody @Valid EnterpriseQueryForm queryForm, HttpServletResponse response) {
 | 
			
		||||
    public void exportExcel(@RequestBody @Valid EnterpriseQueryForm queryForm, HttpServletResponse response) throws IOException {
 | 
			
		||||
        List<EnterpriseExcelVO> data = enterpriseService.getExcelExportData(queryForm);
 | 
			
		||||
        if (CollectionUtils.isEmpty(data)) {
 | 
			
		||||
            SmartResponseUtil.write(response, ResponseDTO.userErrorParam("暂无数据"));
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        ExcelUtils<EnterpriseExcelVO> utils = new ExcelUtils<>(EnterpriseExcelVO.class);
 | 
			
		||||
        utils.exportData(response,data,"企业基本信息");
 | 
			
		||||
 | 
			
		||||
        String watermark = AdminRequestUtil.getRequestUser().getActualName();
 | 
			
		||||
        watermark += SmartLocalDateUtil.format(LocalDateTime.now(), SmartDateFormatterEnum.YMD_HMS);
 | 
			
		||||
 | 
			
		||||
        SmartExcelUtil.exportExcelWithWatermark(response,"企业基本信息.xlsx","企业信息",EnterpriseExcelVO.class,data,watermark);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Operation(summary = "查询企业详情 @author 开云")
 | 
			
		||||
 
 | 
			
		||||
@@ -65,7 +65,7 @@ public class InvoiceController {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Operation(summary = "删除发票信息 @author 善逸")
 | 
			
		||||
    @GetMapping("/oa/invoice/delete/{invoiceId}")
 | 
			
		||||
    @GetMapping("/invoice/delete/{invoiceId}")
 | 
			
		||||
    public ResponseDTO<String> deleteInvoice(@PathVariable Long invoiceId) {
 | 
			
		||||
        return invoiceService.deleteInvoice(invoiceId);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -208,8 +208,6 @@ public class NoticeService {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        NoticeUpdateFormVO updateFormVO = SmartBeanUtil.copy(noticeEntity, NoticeUpdateFormVO.class);
 | 
			
		||||
        NoticeTypeVO noticeType = noticeTypeService.getByNoticeTypeId(noticeEntity.getNoticeTypeId());
 | 
			
		||||
        updateFormVO.setNoticeTypeName(noticeType.getNoticeTypeName());
 | 
			
		||||
        if (!updateFormVO.getAllVisibleFlag()) {
 | 
			
		||||
            List<NoticeVisibleRangeVO> noticeVisibleRangeList = noticeDao.queryVisibleRange(noticeId);
 | 
			
		||||
            List<Long> employeeIdList = noticeVisibleRangeList.stream().filter(e -> NoticeVisibleRangeDataTypeEnum.EMPLOYEE.getValue().equals(e.getDataType()))
 | 
			
		||||
 
 | 
			
		||||
@@ -108,7 +108,7 @@ public class LoginService implements StpInterface {
 | 
			
		||||
    private ProtectLoginService protectLoginService;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private ProtectPasswordService protectPasswordService;
 | 
			
		||||
    private ProtectPasswordService profectPasswordService;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取验证码
 | 
			
		||||
@@ -148,7 +148,7 @@ public class LoginService implements StpInterface {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 解密前端加密的密码
 | 
			
		||||
        String requestPassword = protectPasswordService.decryptPassword(loginForm.getPassword());
 | 
			
		||||
        String requestPassword = profectPasswordService.decryptPassword(loginForm.getPassword());
 | 
			
		||||
 | 
			
		||||
        // 验证密码 是否为万能密码
 | 
			
		||||
        String superPassword = configService.getConfigValue(ConfigKeyEnum.SUPER_PASSWORD);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,105 +0,0 @@
 | 
			
		||||
package net.lab1024.sa.admin.util.excel;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import com.alibaba.excel.write.handler.SheetWriteHandler;
 | 
			
		||||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
 | 
			
		||||
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.apache.poi.openxml4j.opc.PackagePartName;
 | 
			
		||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
 | 
			
		||||
import org.apache.poi.openxml4j.opc.TargetMode;
 | 
			
		||||
import org.apache.poi.xssf.usermodel.XSSFPictureData;
 | 
			
		||||
import org.apache.poi.xssf.usermodel.XSSFRelation;
 | 
			
		||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
 | 
			
		||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 | 
			
		||||
 | 
			
		||||
import javax.imageio.ImageIO;
 | 
			
		||||
import java.awt.*;
 | 
			
		||||
import java.awt.geom.AffineTransform;
 | 
			
		||||
import java.awt.image.BufferedImage;
 | 
			
		||||
import java.io.ByteArrayOutputStream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author liuzhexian
 | 
			
		||||
 * @since 2024-04-16
 | 
			
		||||
 * @email 1037512352@qq.com
 | 
			
		||||
 */
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class CustomWaterMarkHandler implements SheetWriteHandler {
 | 
			
		||||
 | 
			
		||||
    private final Watermark watermark;
 | 
			
		||||
 | 
			
		||||
    public CustomWaterMarkHandler(Watermark watermark) {
 | 
			
		||||
        this.watermark = watermark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
 | 
			
		||||
        BufferedImage bufferedImage = createWatermarkImage();
 | 
			
		||||
        XSSFWorkbook workbook = (XSSFWorkbook) writeSheetHolder.getParentWriteWorkbookHolder().getWorkbook();
 | 
			
		||||
        try {
 | 
			
		||||
            // 添加水印的具体操作
 | 
			
		||||
            addWatermarkToSheet(workbook, bufferedImage);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.error("添加水印出错:", e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 创建水印图片
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    private BufferedImage createWatermarkImage() {
 | 
			
		||||
        // 获取水印相关参数
 | 
			
		||||
        Font font = watermark.getFont();
 | 
			
		||||
        int width = watermark.getWidth();
 | 
			
		||||
        int height = watermark.getHeight();
 | 
			
		||||
        Color color = watermark.getColor();
 | 
			
		||||
        String text = watermark.getContent();
 | 
			
		||||
 | 
			
		||||
        // 创建带有透明背景的 BufferedImage
 | 
			
		||||
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
 | 
			
		||||
        Graphics2D g = image.createGraphics();
 | 
			
		||||
 | 
			
		||||
        // 设置画笔字体、平滑、颜色
 | 
			
		||||
        g.setFont(font);
 | 
			
		||||
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 | 
			
		||||
        g.setColor(color);
 | 
			
		||||
 | 
			
		||||
        // 计算水印位置和角度
 | 
			
		||||
        int y = watermark.getYAxis();
 | 
			
		||||
        int x = watermark.getXAxis();
 | 
			
		||||
        AffineTransform transform = AffineTransform.getRotateInstance(Math.toRadians(-watermark.getAngle()), 0, y);
 | 
			
		||||
        g.setTransform(transform);
 | 
			
		||||
        // 绘制水印文字
 | 
			
		||||
        g.drawString(text, x, y);
 | 
			
		||||
 | 
			
		||||
        // 释放资源
 | 
			
		||||
        g.dispose();
 | 
			
		||||
 | 
			
		||||
        return image;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void addWatermarkToSheet(XSSFWorkbook workbook, BufferedImage watermarkImage) {
 | 
			
		||||
        try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
 | 
			
		||||
            ImageIO.write(watermarkImage, "png", os);
 | 
			
		||||
            int pictureIdx = workbook.addPicture(os.toByteArray(), XSSFWorkbook.PICTURE_TYPE_PNG);
 | 
			
		||||
            XSSFPictureData pictureData = workbook.getAllPictures().get(pictureIdx);
 | 
			
		||||
            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
 | 
			
		||||
                // 获取每个Sheet表
 | 
			
		||||
                XSSFSheet sheet = workbook.getSheetAt(i);
 | 
			
		||||
                PackagePartName ppn = pictureData.getPackagePart().getPartName();
 | 
			
		||||
                String relType = XSSFRelation.IMAGES.getRelation();
 | 
			
		||||
                PackageRelationship pr = sheet.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null);
 | 
			
		||||
                sheet.getCTWorksheet().addNewPicture().setId(pr.getId());
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            // 处理ImageIO.write可能抛出的异常
 | 
			
		||||
            log.error("添加水印图片时发生错误", e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1,96 +0,0 @@
 | 
			
		||||
package net.lab1024.sa.admin.util.excel;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.date.DateUtil;
 | 
			
		||||
import cn.hutool.extra.spring.SpringUtil;
 | 
			
		||||
import com.alibaba.excel.EasyExcel;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import net.lab1024.sa.admin.module.system.login.domain.LoginResultVO;
 | 
			
		||||
import net.lab1024.sa.admin.module.system.login.service.LoginService;
 | 
			
		||||
import net.lab1024.sa.admin.util.AdminRequestUtil;
 | 
			
		||||
import net.lab1024.sa.base.common.util.SmartResponseUtil;
 | 
			
		||||
import org.springframework.core.env.Environment;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author liuzhexian
 | 
			
		||||
 * @since 2024-04-16
 | 
			
		||||
 * @email 1037512352@qq.com
 | 
			
		||||
 */
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class ExcelUtils<T> implements Serializable {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 导出文件后缀
 | 
			
		||||
     */
 | 
			
		||||
    public static final String XLSX = ".xlsx";
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 实体对象
 | 
			
		||||
     */
 | 
			
		||||
    public Class<T> clazz;
 | 
			
		||||
 | 
			
		||||
    public ExcelUtils(Class<T> clazz) {
 | 
			
		||||
        this.clazz = clazz;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 通用导出方法
 | 
			
		||||
     *
 | 
			
		||||
     * @param response response
 | 
			
		||||
     * @param list     导出的列表
 | 
			
		||||
     * @param title    导出的名称
 | 
			
		||||
     */
 | 
			
		||||
    public void exportData(HttpServletResponse response, List<T> list, String title) {
 | 
			
		||||
        // 设置下载消息头
 | 
			
		||||
        SmartResponseUtil.setDownloadFileHeader(response, title + XLSX, null);
 | 
			
		||||
        // 根据配置文件中的参数判断导出是否带水印
 | 
			
		||||
        String show = SpringUtil.getBean(Environment.class).getProperty("export.show-watermark");
 | 
			
		||||
        if(Boolean.parseBoolean(show)) {
 | 
			
		||||
            exportSheetWithWatermark(response, list, title);
 | 
			
		||||
        } else {
 | 
			
		||||
            exportSheet(response, list, title);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 通用导出方法(不带水印)
 | 
			
		||||
     *
 | 
			
		||||
     * @param response response
 | 
			
		||||
     * @param list     导出的列表
 | 
			
		||||
     * @param title    导出的名称
 | 
			
		||||
     */
 | 
			
		||||
    public void exportSheet(HttpServletResponse response, List<T> list, String title) {
 | 
			
		||||
        try {
 | 
			
		||||
            EasyExcel.write(response.getOutputStream(), this.clazz).sheet(title).doWrite(list);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.error("{}导出异常", title, e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 通用导出方法(带水印)
 | 
			
		||||
     *
 | 
			
		||||
     * @param response   response
 | 
			
		||||
     * @param exportList 导出的列表
 | 
			
		||||
     * @param title      导出的名称
 | 
			
		||||
     */
 | 
			
		||||
    public void exportSheetWithWatermark(HttpServletResponse response, List<T> exportList, String title) {
 | 
			
		||||
        try {
 | 
			
		||||
            LoginResultVO loginResult = SpringUtil.getBean(LoginService.class).getLoginResult(AdminRequestUtil.getRequestUser());
 | 
			
		||||
            // 注册水印处理器  水印  员工昵称 + 日期
 | 
			
		||||
            Watermark watermark = new Watermark(String.format("%s %s",loginResult.getActualName(), DateUtil.formatDate(new Date())));
 | 
			
		||||
            // 一定要inMemory
 | 
			
		||||
            EasyExcel.write(response.getOutputStream(), this.clazz)
 | 
			
		||||
                    .inMemory(true).sheet(title).registerWriteHandler(new CustomWaterMarkHandler(watermark)).doWrite(exportList);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.error("{}导出异常", title, e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,95 +0,0 @@
 | 
			
		||||
package net.lab1024.sa.admin.util.excel;
 | 
			
		||||
 | 
			
		||||
import cn.dev33.satoken.stp.StpUtil;
 | 
			
		||||
import cn.hutool.core.date.DateUtil;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
import java.awt.*;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author liuzhexian
 | 
			
		||||
 * @since 2024-04-16
 | 
			
		||||
 * @email 1037512352@qq.com
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
public class Watermark {
 | 
			
		||||
 | 
			
		||||
    public Watermark(String content) {
 | 
			
		||||
        this.content = content;
 | 
			
		||||
        init();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Watermark(String content, Color color, Font font, double angle) {
 | 
			
		||||
        this.content = content;
 | 
			
		||||
        this.color = color;
 | 
			
		||||
        this.font = font;
 | 
			
		||||
        this.angle = angle;
 | 
			
		||||
        init();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据水印内容长度自适应水印图片大小,简单的三角函数
 | 
			
		||||
     */
 | 
			
		||||
    private void init() {
 | 
			
		||||
        FontMetrics fontMetrics = new JLabel().getFontMetrics(this.font);
 | 
			
		||||
        int stringWidth = fontMetrics.stringWidth(this.content);
 | 
			
		||||
        int charWidth = fontMetrics.charWidth('A');
 | 
			
		||||
        this.width = (int) Math.abs(stringWidth * Math.cos(Math.toRadians(this.angle))) + 2 * charWidth;
 | 
			
		||||
        this.height = (int) Math.abs(stringWidth * Math.sin(Math.toRadians(this.angle))) + 2 * charWidth;
 | 
			
		||||
        this.yAxis = this.height;
 | 
			
		||||
        this.xAxis = charWidth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 水印内容
 | 
			
		||||
     */
 | 
			
		||||
    private String content;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 画笔颜色
 | 
			
		||||
     */
 | 
			
		||||
    private Color color = new Color(239,239,239);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 字体样式
 | 
			
		||||
     */
 | 
			
		||||
    private Font font = new Font("Microsoft YaHei", Font.BOLD, 15);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 水印宽度
 | 
			
		||||
     */
 | 
			
		||||
    private int width;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 水印高度
 | 
			
		||||
     */
 | 
			
		||||
    private int height;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 倾斜角度,非弧度制
 | 
			
		||||
     */
 | 
			
		||||
    private double angle = 25;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 字体的y轴位置
 | 
			
		||||
     */
 | 
			
		||||
    private int yAxis = 50;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 字体的X轴位置
 | 
			
		||||
     */
 | 
			
		||||
    private int xAxis;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 水平倾斜度
 | 
			
		||||
     */
 | 
			
		||||
    private double shearX = 0.1;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 垂直倾斜度
 | 
			
		||||
     */
 | 
			
		||||
    private double shearY = -0.26;
 | 
			
		||||
}
 | 
			
		||||
@@ -155,24 +155,22 @@
 | 
			
		||||
        left join t_notice_type on t_notice.notice_type_id = t_notice_type.notice_type_id
 | 
			
		||||
        <where>
 | 
			
		||||
            <if test="!administratorFlag">
 | 
			
		||||
                (
 | 
			
		||||
                    t_notice.notice_id in
 | 
			
		||||
                    (select t_notice_visible_range.notice_id
 | 
			
		||||
                    from t_notice_visible_range
 | 
			
		||||
                    where
 | 
			
		||||
                    ( t_notice_visible_range.data_type = #{departmentDataType}
 | 
			
		||||
                        <if test="requestEmployeeDepartmentIdList != null and requestEmployeeDepartmentIdList.size > 0">
 | 
			
		||||
                            and
 | 
			
		||||
                            t_notice_visible_range.data_id
 | 
			
		||||
                            in
 | 
			
		||||
                            <foreach collection="requestEmployeeDepartmentIdList" open="(" close=")" separator="," item="item">
 | 
			
		||||
                                #{item}
 | 
			
		||||
                            </foreach>
 | 
			
		||||
                        </if>
 | 
			
		||||
                        )
 | 
			
		||||
                        or ( t_notice_visible_range.data_type = #{employeeDataType} and t_notice_visible_range.data_id = #{requestEmployeeId} )
 | 
			
		||||
                    )
 | 
			
		||||
                    or t_notice.all_visible_flag = true
 | 
			
		||||
                t_notice.notice_id in
 | 
			
		||||
                (select t_notice_visible_range.notice_id
 | 
			
		||||
                from t_notice_visible_range
 | 
			
		||||
                where
 | 
			
		||||
                (t_notice_visible_range.data_type = #{departmentDataType}
 | 
			
		||||
                <if test="requestEmployeeDepartmentIdList != null and requestEmployeeDepartmentIdList.size > 0">
 | 
			
		||||
                    and
 | 
			
		||||
                    t_notice_visible_range.data_id
 | 
			
		||||
                    in
 | 
			
		||||
                    <foreach collection="requestEmployeeDepartmentIdList" open="(" close=")" separator="," item="item">
 | 
			
		||||
                        #{item}
 | 
			
		||||
                    </foreach>
 | 
			
		||||
                </if>
 | 
			
		||||
                )
 | 
			
		||||
                or ( t_notice_visible_range.data_type = #{employeeDataType} and t_notice_visible_range.data_id =
 | 
			
		||||
                #{requestEmployeeId} )
 | 
			
		||||
                )
 | 
			
		||||
            </if>
 | 
			
		||||
            and t_notice.all_visible_flag = true
 | 
			
		||||
@@ -184,7 +182,7 @@
 | 
			
		||||
            <if test="query.keywords != null and query.keywords !=''">
 | 
			
		||||
                AND ( INSTR(t_notice.title,#{query.keywords})
 | 
			
		||||
                OR INSTR(t_notice.author,#{query.keywords})
 | 
			
		||||
                OR INSTR(t_notice.document_number,#{query.keywords})
 | 
			
		||||
                OR INSTR(t_notice.documentNumber,#{query.keywords})
 | 
			
		||||
                OR INSTR(t_notice.source,#{query.keywords})
 | 
			
		||||
                )
 | 
			
		||||
            </if>
 | 
			
		||||
 
 | 
			
		||||
@@ -245,12 +245,12 @@
 | 
			
		||||
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.apache.poi</groupId>
 | 
			
		||||
            <artifactId>ooxml-schemas</artifactId>
 | 
			
		||||
            <artifactId>poi-scratchpad</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.apache.poi</groupId>
 | 
			
		||||
            <artifactId>poi-scratchpad</artifactId>
 | 
			
		||||
            <artifactId>ooxml-schemas</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <dependency>
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,226 @@
 | 
			
		||||
package net.lab1024.sa.base.common.util;
 | 
			
		||||
 | 
			
		||||
import com.alibaba.excel.EasyExcel;
 | 
			
		||||
import com.alibaba.excel.write.handler.SheetWriteHandler;
 | 
			
		||||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
 | 
			
		||||
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.apache.poi.openxml4j.opc.PackagePartName;
 | 
			
		||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
 | 
			
		||||
import org.apache.poi.openxml4j.opc.TargetMode;
 | 
			
		||||
import org.apache.poi.xssf.usermodel.XSSFPictureData;
 | 
			
		||||
import org.apache.poi.xssf.usermodel.XSSFRelation;
 | 
			
		||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
 | 
			
		||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 | 
			
		||||
 | 
			
		||||
import javax.imageio.ImageIO;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
import java.awt.*;
 | 
			
		||||
import java.awt.geom.AffineTransform;
 | 
			
		||||
import java.awt.image.BufferedImage;
 | 
			
		||||
import java.io.ByteArrayOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * excel 工具类
 | 
			
		||||
 *
 | 
			
		||||
 * @Author 1024创新实验室-主任:卓大
 | 
			
		||||
 * @Date 2024/4/22 22:49:07
 | 
			
		||||
 * @Wechat zhuoda1024
 | 
			
		||||
 * @Email lab1024@163.com
 | 
			
		||||
 * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2024
 | 
			
		||||
 */
 | 
			
		||||
public final class SmartExcelUtil {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 通用单sheet导出
 | 
			
		||||
     */
 | 
			
		||||
    public static void exportExcel(HttpServletResponse response, String fileName, String sheetName, Class head,Collection<?> data) throws IOException {
 | 
			
		||||
        // 设置下载消息头
 | 
			
		||||
        SmartResponseUtil.setDownloadFileHeader(response, fileName, null);
 | 
			
		||||
        // 下载
 | 
			
		||||
        EasyExcel.write(response.getOutputStream(), head)
 | 
			
		||||
                .autoCloseStream(Boolean.FALSE)
 | 
			
		||||
                .sheet(sheetName)
 | 
			
		||||
                .doWrite(data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 通用单 sheet水印 导出
 | 
			
		||||
     */
 | 
			
		||||
    public static void exportExcelWithWatermark(HttpServletResponse response, String fileName, String sheetName, Class head,Collection<?> data, String watermarkString) throws IOException {
 | 
			
		||||
        // 设置下载消息头
 | 
			
		||||
        SmartResponseUtil.setDownloadFileHeader(response, fileName, null);
 | 
			
		||||
        // 水印
 | 
			
		||||
        Watermark watermark = new Watermark(watermarkString);
 | 
			
		||||
        // 一定要inMemory
 | 
			
		||||
        EasyExcel.write(response.getOutputStream(), head)
 | 
			
		||||
                .inMemory(true)
 | 
			
		||||
                .sheet(sheetName)
 | 
			
		||||
                .registerWriteHandler(new CustomWaterMarkHandler(watermark))
 | 
			
		||||
                .doWrite(data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Slf4j
 | 
			
		||||
    private static class CustomWaterMarkHandler implements SheetWriteHandler {
 | 
			
		||||
 | 
			
		||||
        private final Watermark watermark;
 | 
			
		||||
 | 
			
		||||
        public CustomWaterMarkHandler(Watermark watermark) {
 | 
			
		||||
            this.watermark = watermark;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
 | 
			
		||||
            BufferedImage bufferedImage = createWatermarkImage();
 | 
			
		||||
            XSSFWorkbook workbook = (XSSFWorkbook) writeSheetHolder.getParentWriteWorkbookHolder().getWorkbook();
 | 
			
		||||
            try {
 | 
			
		||||
                // 添加水印的具体操作
 | 
			
		||||
                addWatermarkToSheet(workbook, bufferedImage);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                log.error("添加水印出错:", e);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 创建水印图片
 | 
			
		||||
         *
 | 
			
		||||
         * @return
 | 
			
		||||
         */
 | 
			
		||||
        private BufferedImage createWatermarkImage() {
 | 
			
		||||
            // 获取水印相关参数
 | 
			
		||||
            Font font = watermark.getFont();
 | 
			
		||||
            int width = watermark.getWidth();
 | 
			
		||||
            int height = watermark.getHeight();
 | 
			
		||||
            Color color = watermark.getColor();
 | 
			
		||||
            String text = watermark.getContent();
 | 
			
		||||
 | 
			
		||||
            // 创建带有透明背景的 BufferedImage
 | 
			
		||||
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
 | 
			
		||||
            Graphics2D g = image.createGraphics();
 | 
			
		||||
 | 
			
		||||
            // 设置画笔字体、平滑、颜色
 | 
			
		||||
            g.setFont(font);
 | 
			
		||||
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 | 
			
		||||
            g.setColor(color);
 | 
			
		||||
 | 
			
		||||
            // 计算水印位置和角度
 | 
			
		||||
            int y = watermark.getYAxis();
 | 
			
		||||
            int x = watermark.getXAxis();
 | 
			
		||||
            AffineTransform transform = AffineTransform.getRotateInstance(Math.toRadians(-watermark.getAngle()), 0, y);
 | 
			
		||||
            g.setTransform(transform);
 | 
			
		||||
            // 绘制水印文字
 | 
			
		||||
            g.drawString(text, x, y);
 | 
			
		||||
 | 
			
		||||
            // 释放资源
 | 
			
		||||
            g.dispose();
 | 
			
		||||
 | 
			
		||||
            return image;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void addWatermarkToSheet(XSSFWorkbook workbook, BufferedImage watermarkImage) {
 | 
			
		||||
            try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
 | 
			
		||||
                ImageIO.write(watermarkImage, "png", os);
 | 
			
		||||
                int pictureIdx = workbook.addPicture(os.toByteArray(), XSSFWorkbook.PICTURE_TYPE_PNG);
 | 
			
		||||
                XSSFPictureData pictureData = workbook.getAllPictures().get(pictureIdx);
 | 
			
		||||
                for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
 | 
			
		||||
                    // 获取每个Sheet表
 | 
			
		||||
                    XSSFSheet sheet = workbook.getSheetAt(i);
 | 
			
		||||
                    PackagePartName ppn = pictureData.getPackagePart().getPartName();
 | 
			
		||||
                    String relType = XSSFRelation.IMAGES.getRelation();
 | 
			
		||||
                    PackageRelationship pr = sheet.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null);
 | 
			
		||||
                    sheet.getCTWorksheet().addNewPicture().setId(pr.getId());
 | 
			
		||||
                }
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                // 处理ImageIO.write可能抛出的异常
 | 
			
		||||
                log.error("添加水印图片时发生错误", e);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Data
 | 
			
		||||
    private static class Watermark {
 | 
			
		||||
 | 
			
		||||
        public Watermark(String content) {
 | 
			
		||||
            this.content = content;
 | 
			
		||||
            init();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Watermark(String content, Color color, Font font, double angle) {
 | 
			
		||||
            this.content = content;
 | 
			
		||||
            this.color = color;
 | 
			
		||||
            this.font = font;
 | 
			
		||||
            this.angle = angle;
 | 
			
		||||
            init();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 根据水印内容长度自适应水印图片大小,简单的三角函数
 | 
			
		||||
         */
 | 
			
		||||
        private void init() {
 | 
			
		||||
            FontMetrics fontMetrics = new JLabel().getFontMetrics(this.font);
 | 
			
		||||
            int stringWidth = fontMetrics.stringWidth(this.content);
 | 
			
		||||
            int charWidth = fontMetrics.charWidth('A');
 | 
			
		||||
            this.width = (int) Math.abs(stringWidth * Math.cos(Math.toRadians(this.angle))) + 5 * charWidth;
 | 
			
		||||
            this.height = (int) Math.abs(stringWidth * Math.sin(Math.toRadians(this.angle))) + 5 * charWidth;
 | 
			
		||||
            this.yAxis = this.height;
 | 
			
		||||
            this.xAxis = charWidth;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 水印内容
 | 
			
		||||
         */
 | 
			
		||||
        private String content;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 画笔颜色
 | 
			
		||||
         */
 | 
			
		||||
        private Color color = new Color(239,239,239);
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 字体样式
 | 
			
		||||
         */
 | 
			
		||||
        private Font font = new Font("Microsoft YaHei", Font.BOLD, 26);
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 水印宽度
 | 
			
		||||
         */
 | 
			
		||||
        private int width;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 水印高度
 | 
			
		||||
         */
 | 
			
		||||
        private int height;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 倾斜角度,非弧度制
 | 
			
		||||
         */
 | 
			
		||||
        private double angle = 25;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 字体的y轴位置
 | 
			
		||||
         */
 | 
			
		||||
        private int yAxis = 50;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 字体的X轴位置
 | 
			
		||||
         */
 | 
			
		||||
        private int xAxis;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 水平倾斜度
 | 
			
		||||
         */
 | 
			
		||||
        private double shearX = 0.1;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 垂直倾斜度
 | 
			
		||||
         */
 | 
			
		||||
        private double shearY = -0.26;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -3,7 +3,7 @@ spring:
 | 
			
		||||
  datasource:
 | 
			
		||||
    url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v3?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
 | 
			
		||||
    username: root
 | 
			
		||||
    password: 123456
 | 
			
		||||
    password: Zhuoda1024lab
 | 
			
		||||
    initial-size: 2
 | 
			
		||||
    min-idle: 2
 | 
			
		||||
    max-active: 10
 | 
			
		||||
@@ -120,8 +120,6 @@ reload:
 | 
			
		||||
sa-token:
 | 
			
		||||
  # token 名称(同时也是 cookie 名称)
 | 
			
		||||
  token-name: x-access-token
 | 
			
		||||
  # token 前缀 例如:Bear
 | 
			
		||||
  token-prefix:
 | 
			
		||||
  # token 有效期(单位:秒) 默认30天(2592000秒),-1 代表永久有效
 | 
			
		||||
  timeout: 2592000
 | 
			
		||||
  # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
 | 
			
		||||
@@ -141,7 +139,4 @@ sa-token:
 | 
			
		||||
  # 启动时的字符画打印
 | 
			
		||||
  is-print: false
 | 
			
		||||
  # 是否从cookie读取token
 | 
			
		||||
  is-read-cookie: false
 | 
			
		||||
 | 
			
		||||
export:
 | 
			
		||||
  show-watermark: true
 | 
			
		||||
  is-read-cookie: false
 | 
			
		||||
@@ -122,8 +122,6 @@ reload:
 | 
			
		||||
sa-token:
 | 
			
		||||
  # token 名称(同时也是 cookie 名称)
 | 
			
		||||
  token-name: x-access-token
 | 
			
		||||
  # token 前缀 例如:Bear
 | 
			
		||||
  token-prefix:
 | 
			
		||||
  # token 有效期(单位:秒) 默认30天(2592000秒),-1 代表永久有效
 | 
			
		||||
  timeout: 2592000
 | 
			
		||||
  # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
 | 
			
		||||
@@ -143,7 +141,4 @@ sa-token:
 | 
			
		||||
  # 启动时的字符画打印
 | 
			
		||||
  is-print: false
 | 
			
		||||
  # 是否从cookie读取token
 | 
			
		||||
  is-read-cookie: false
 | 
			
		||||
 | 
			
		||||
export:
 | 
			
		||||
  show-watermark: true
 | 
			
		||||
  is-read-cookie: false
 | 
			
		||||
@@ -122,8 +122,6 @@ reload:
 | 
			
		||||
sa-token:
 | 
			
		||||
  # token 名称(同时也是 cookie 名称)
 | 
			
		||||
  token-name: x-access-token
 | 
			
		||||
  # token 前缀 例如:Bear
 | 
			
		||||
  token-prefix:
 | 
			
		||||
  # token 有效期(单位:秒) 默认30天(2592000秒),-1 代表永久有效
 | 
			
		||||
  timeout: 2592000
 | 
			
		||||
  # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
 | 
			
		||||
@@ -143,7 +141,4 @@ sa-token:
 | 
			
		||||
  # 启动时的字符画打印
 | 
			
		||||
  is-print: false
 | 
			
		||||
  # 是否从cookie读取token
 | 
			
		||||
  is-read-cookie: false
 | 
			
		||||
 | 
			
		||||
export:
 | 
			
		||||
  show-watermark: true
 | 
			
		||||
  is-read-cookie: false
 | 
			
		||||
@@ -122,8 +122,6 @@ reload:
 | 
			
		||||
sa-token:
 | 
			
		||||
  # token 名称(同时也是 cookie 名称)
 | 
			
		||||
  token-name: x-access-token
 | 
			
		||||
  # token 前缀 例如:Bear
 | 
			
		||||
  token-prefix:
 | 
			
		||||
  # token 有效期(单位:秒) 默认30天(2592000秒),-1 代表永久有效
 | 
			
		||||
  timeout: 2592000
 | 
			
		||||
  # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
 | 
			
		||||
@@ -143,7 +141,4 @@ sa-token:
 | 
			
		||||
  # 启动时的字符画打印
 | 
			
		||||
  is-print: false
 | 
			
		||||
  # 是否从cookie读取token
 | 
			
		||||
  is-read-cookie: false
 | 
			
		||||
 | 
			
		||||
export:
 | 
			
		||||
  show-watermark: true
 | 
			
		||||
  is-read-cookie: false
 | 
			
		||||
							
								
								
									
										5882
									
								
								smart-admin-web/javascript-ant-design-vue3/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5882
									
								
								smart-admin-web/javascript-ant-design-vue3/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -19,7 +19,7 @@
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@wangeditor/editor": "5.1.14",
 | 
			
		||||
    "@wangeditor/editor-for-vue": "5.1.12",
 | 
			
		||||
    "ant-design-vue": "4.1.2",
 | 
			
		||||
    "ant-design-vue": "4.2.0",
 | 
			
		||||
    "axios": "1.6.8",
 | 
			
		||||
    "clipboard": "2.0.11",
 | 
			
		||||
    "crypto-js": "4.1.1",
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@ export const appDefaultConfig = {
 | 
			
		||||
  // 网站名称
 | 
			
		||||
  websiteName: 'SmartAdmin 3.X',
 | 
			
		||||
  // 主题颜色
 | 
			
		||||
  primaryColor: 'red',
 | 
			
		||||
  primaryColor: '#1677ff',
 | 
			
		||||
  // 紧凑
 | 
			
		||||
  compactFlag: false,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
<!--
 | 
			
		||||
  * 传统菜单
 | 
			
		||||
  * 
 | 
			
		||||
  * @Author:    1024创新实验室-主任:卓大 
 | 
			
		||||
  * @Date:      2022-09-06 20:29:12 
 | 
			
		||||
  * @Wechat:    zhuda1024 
 | 
			
		||||
  * @Email:     lab1024@163.com 
 | 
			
		||||
  * @Copyright  1024创新实验室 ( https://1024lab.net ),Since 2012 
 | 
			
		||||
  *
 | 
			
		||||
  * @Author:    1024创新实验室-主任:卓大
 | 
			
		||||
  * @Date:      2022-09-06 20:29:12
 | 
			
		||||
  * @Wechat:    zhuda1024
 | 
			
		||||
  * @Email:     lab1024@163.com
 | 
			
		||||
  * @Copyright  1024创新实验室 ( https://1024lab.net ),Since 2012
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
  <!--左侧菜单分为两部分:1、顶部logo区域,包含 logo和名称;2、下方菜单区域-->
 | 
			
		||||
@@ -21,7 +21,9 @@
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <!-- 2、下方菜单区域: 这里使用一个递归菜单解决 -->
 | 
			
		||||
  <RecursionMenu :collapsed="collapsed" ref="menuRef" />
 | 
			
		||||
  <div class="menu">
 | 
			
		||||
    <RecursionMenu :collapsed="collapsed" ref="menuRef" />
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup>
 | 
			
		||||
@@ -60,6 +62,13 @@
 | 
			
		||||
  function onGoHome() {
 | 
			
		||||
    router.push({ name: HOME_PAGE_NAME });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const color = computed(() => {
 | 
			
		||||
    let isLight = useAppConfigStore().$state.sideMenuTheme === 'light';
 | 
			
		||||
    return {
 | 
			
		||||
      background: isLight ? '#FFFFFF' : '#001529',
 | 
			
		||||
    };
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="less" scoped>
 | 
			
		||||
@@ -75,7 +84,9 @@
 | 
			
		||||
      height: @header-user-height;
 | 
			
		||||
      line-height: @header-user-height;
 | 
			
		||||
      padding: 0px 15px 0px 15px;
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      background-color: v-bind('color.background');
 | 
			
		||||
      position: fixed;
 | 
			
		||||
      width: 80px;
 | 
			
		||||
      z-index: 21;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
@@ -89,7 +100,9 @@
 | 
			
		||||
    .logo {
 | 
			
		||||
      height: @header-user-height;
 | 
			
		||||
      line-height: @header-user-height;
 | 
			
		||||
      background-color: v-bind('color.background');
 | 
			
		||||
      padding: 0px 15px 0px 15px;
 | 
			
		||||
      position: fixed;
 | 
			
		||||
      z-index: 21;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
@@ -115,6 +128,6 @@
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  .menu {
 | 
			
		||||
    padding: 16px 0;
 | 
			
		||||
    margin-top: @header-user-height;
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,12 @@ const smartAxios = axios.create({
 | 
			
		||||
  baseURL: import.meta.env.VITE_APP_API_URL,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 退出系统
 | 
			
		||||
function logout() {
 | 
			
		||||
  localClear();
 | 
			
		||||
  location.href = '/';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ================================= 请求拦截器 =================================
 | 
			
		||||
 | 
			
		||||
smartAxios.interceptors.request.use(
 | 
			
		||||
@@ -73,10 +79,7 @@ smartAxios.interceptors.response.use(
 | 
			
		||||
      if (res.code === 30007 || res.code === 30008) {
 | 
			
		||||
        message.destroy();
 | 
			
		||||
        message.error('您没有登录,请重新登录');
 | 
			
		||||
        localClear();
 | 
			
		||||
        setTimeout(() => {
 | 
			
		||||
          location.href = '/';
 | 
			
		||||
        }, 300);
 | 
			
		||||
        setTimeout(logout, 300);
 | 
			
		||||
        return Promise.reject(response);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@@ -94,15 +97,9 @@ smartAxios.interceptors.response.use(
 | 
			
		||||
        Modal.error({
 | 
			
		||||
          title: '重要提醒',
 | 
			
		||||
          content: res.msg,
 | 
			
		||||
          onOk() {
 | 
			
		||||
            return new Promise((resolve, reject) => {
 | 
			
		||||
              localClear();
 | 
			
		||||
              setTimeout(() => {
 | 
			
		||||
                location.href = '/';
 | 
			
		||||
              }, 300);
 | 
			
		||||
            }).catch(() => console.log('Oops errors!'));
 | 
			
		||||
          },
 | 
			
		||||
          onOk: logout,
 | 
			
		||||
        });
 | 
			
		||||
        setTimeout(logout, 3000);
 | 
			
		||||
        return Promise.reject(response);
 | 
			
		||||
      }
 | 
			
		||||
      message.destroy();
 | 
			
		||||
 
 | 
			
		||||
@@ -5,12 +5,13 @@ export const themeColors = [
 | 
			
		||||
    activeColor: '#0958d9',
 | 
			
		||||
    hoverColor: '#bae0ff',
 | 
			
		||||
  },
 | 
			
		||||
  // 紫色
 | 
			
		||||
  // 绿色
 | 
			
		||||
  {
 | 
			
		||||
    primaryColor: '#722ED1',
 | 
			
		||||
    activeColor: '#531dab',
 | 
			
		||||
    hoverColor: '#9254de',
 | 
			
		||||
    primaryColor: '#00b96b',
 | 
			
		||||
    activeColor: '#00945b',
 | 
			
		||||
    hoverColor: '#20c77c',
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  // 红色
 | 
			
		||||
  {
 | 
			
		||||
    primaryColor: '#F5222D',
 | 
			
		||||
@@ -29,10 +30,10 @@ export const themeColors = [
 | 
			
		||||
    activeColor: '#c41d7f',
 | 
			
		||||
    hoverColor: '#f759ab',
 | 
			
		||||
  },
 | 
			
		||||
  // 绿色
 | 
			
		||||
  // 紫色
 | 
			
		||||
  {
 | 
			
		||||
    primaryColor: '#52C41A',
 | 
			
		||||
    activeColor: '#389e0d',
 | 
			
		||||
    hoverColor: '#73d13d',
 | 
			
		||||
    primaryColor: '#722ED1',
 | 
			
		||||
    activeColor: '#531dab',
 | 
			
		||||
    hoverColor: '#9254de',
 | 
			
		||||
  },
 | 
			
		||||
];
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
<!--
 | 
			
		||||
  * 公司列表
 | 
			
		||||
  * 
 | 
			
		||||
  * @Author:    1024创新实验室-主任:卓大 
 | 
			
		||||
  *
 | 
			
		||||
  * @Author:    1024创新实验室-主任:卓大
 | 
			
		||||
  * @Date:      2022-08-15 20:15:49
 | 
			
		||||
  * @Wechat:    zhuda1024 
 | 
			
		||||
  * @Email:     lab1024@163.com 
 | 
			
		||||
  * @Copyright  1024创新实验室 ( https://1024lab.net ),Since 2012 
 | 
			
		||||
  * @Wechat:    zhuda1024
 | 
			
		||||
  * @Email:     lab1024@163.com
 | 
			
		||||
  * @Copyright  1024创新实验室 ( https://1024lab.net ),Since 2012
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
  <a-form class="smart-query-form" v-privilege="'oa:enterprise:query'">
 | 
			
		||||
@@ -50,7 +50,7 @@
 | 
			
		||||
          <template #icon>
 | 
			
		||||
            <FileExcelOutlined />
 | 
			
		||||
          </template>
 | 
			
		||||
          导出数据
 | 
			
		||||
          导出数据(带水印)
 | 
			
		||||
        </a-button>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="smart-table-setting-block">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
<!--
 | 
			
		||||
  * 登录
 | 
			
		||||
  * 
 | 
			
		||||
  * @Author:    1024创新实验室-主任:卓大 
 | 
			
		||||
  * @Date:      2022-09-12 22:34:00 
 | 
			
		||||
  * @Wechat:    zhuda1024 
 | 
			
		||||
  * @Email:     lab1024@163.com 
 | 
			
		||||
  * @Copyright  1024创新实验室 ( https://1024lab.net ),Since 2012 
 | 
			
		||||
  *
 | 
			
		||||
  * @Author:    1024创新实验室-主任:卓大
 | 
			
		||||
  * @Date:      2022-09-12 22:34:00
 | 
			
		||||
  * @Wechat:    zhuda1024
 | 
			
		||||
  * @Email:     lab1024@163.com
 | 
			
		||||
  * @Copyright  1024创新实验室 ( https://1024lab.net ),Since 2012
 | 
			
		||||
  *
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
@@ -154,7 +154,7 @@
 | 
			
		||||
    notification['success']({
 | 
			
		||||
      message: '温馨提示',
 | 
			
		||||
      description: 'SmartAdmin 提供 9种 登录背景风格哦!',
 | 
			
		||||
      duration: null,
 | 
			
		||||
      duration: 8,
 | 
			
		||||
      onClick: () => {},
 | 
			
		||||
      btn: () =>
 | 
			
		||||
        h(
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user