【VUE小型网站开发】优化通用配置 二

发布于:2024-12-06 ⋅ 阅读:(45) ⋅ 点赞:(0)

1. 引入 MyBatis Plus

1.1 添加依赖

<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- MyBatis Plus Starter -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.3</version> <!-- 请使用最新版本 -->
    </dependency>

    <!-- MySQL Connector -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.23</version> <!-- 请使用最新版本 -->
    </dependency>

    <!-- Lombok (可选,用于简化代码) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.20</version> <!-- 请使用最新版本 -->
        <scope>provided</scope>
    </dependency>
</dependencies>

1.2 配置数据库连接

在 application.yml 或 application.properties 文件中配置数据库连接信息

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/tool?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: username
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

1.3 新建实体类

这边直接修改原来的Menu实体类,添加@TableName(“menu”),对应到表么menu

package com.tool.tooladmin.admin.menu.domain;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Data
@TableName("menu")
public class Menu {
    private Long menuId;
    private Long parentId;
    private String menuName;
    private String path;
    private String icon;
    private Long sort;
    private Long isFrame;
    private String query;
    @TableField(exist = false)
    private List<Menu> children;
}

1.4 创建 Mapper 接口

创建一个 MenuMapper接口,并继承 BaseMapper。MyBatis Plus 提供了丰富的 CRUD 方法,无需手动编写 SQL 语句。

package com.tool.tooladmin.admin.menu.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tool.tooladmin.admin.menu.domain.Menu;

public interface MenuMapper extends BaseMapper<Menu> {
}

1.5 配置 MyBatis Plus

在 Spring Boot 的主配置类中,添加 @MapperScan 注解,扫描 Mapper 接口所在的包。

package com.tool.tooladmin;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.tool.tooladmin.admin.menu.mapper") // 替换为你的 Mapper 接口所在包,可以只加载到个别,也可以设置父级,这样可以扫描到下面所有的mapper
public class ToolAdminApplication {

    public static void main(String[] args) {
        SpringApplication.run(ToolAdminApplication.class, args);
    }
}

1.6 修改前端menu对应的值

前面改了menu实体类,需要修改前端对应的参数

<template>
  <div>
    <el-menu-item v-if="!item.children || item.children.length === 0" :index="item.path || item.menuId">
      <span>{{ item.menuName }}</span>
    </el-menu-item>
    <el-sub-menu v-else :index="item.path || item.menuId">
      <template #title>
        <span>{{ item.menuName }}</span>
      </template>
      <menu-item v-for="child in item.children" :key="child.menuId" :item="child" />
    </el-sub-menu>
  </div>
</template>

<script setup>
import { defineProps } from 'vue';

const props = defineProps({
  item: {
    type: Object,
    required: true
  }
});
</script>

2. 添加获取反编译代码

可以通过测试demo,直接把class反编译成代码,虽然会有一定差异,但是可以节省一部分代码
采用的是cfr方式

2.1 添加依赖

        <!-- https://mvnrepository.com/artifact/org.benf/cfr -->
        <dependency>
            <groupId>org.benf</groupId>
            <artifactId>cfr</artifactId>
            <version>0.151</version>
        </dependency>

2.2 java代码

通过编译后的资源文件地址将class文件反编译成java文件,存在outputdir里,然后再进行读取

package com.tool.tooladmin.tool;

import org.apache.commons.io.FileUtils;
import org.benf.cfr.reader.api.CfrDriver;
import org.benf.cfr.reader.util.getopt.OptionsImpl;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Component
public class DecompileTool {
    /**
     * 根据资源路径获取类反编译后的代码
     * @param resourcePath 类路径
     * @return
     */
    public static String getClassDecompileCodeByCFR(String resourcePath) {
        try {
            // 读取资源文件
            ClassPathResource resource = new ClassPathResource(resourcePath + ".class");
            File file = resource.getFile();

            // 反编译并获取结果字符串
            decompile(file.getAbsolutePath());
            // 读取反编译后的代码
            StringBuffer sb = new StringBuffer();
            File decompiledFile = new ClassPathResource("output/"+ resourcePath + ".java").getFile();
            List<String> lines = FileUtils.readLines(decompiledFile, "UTF-8");
            for (String line : lines) {
                sb.append(line).append("\n");
            }
            String decompiledCode = sb.toString();
            return decompiledCode;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void decompile(String filePath) throws IOException {
        // 配置选项
        HashMap<String, String> outputMap = new HashMap<>();
        // 反编译文件输出目录,在classpath下创建一个文件夹output,用于存放反编译后的代码
        String outputDir = new ClassPathResource("/").getFile().getAbsolutePath() + "/output";
        outputMap.put("outputdir", outputDir);

        OptionsImpl options = new OptionsImpl(outputMap);
        // 构建 CfrDriver
        CfrDriver cfrDriver = new CfrDriver.Builder()
                .withBuiltOptions(options)
                .withOutputSink(null)
                .build();
        // 反编译
        List<String> files = new ArrayList<>();
        files.add(filePath);

        cfrDriver.analyse(files);
    }
}

2.3 前端将代码传给MD组件里,进行展示

<template>
  <div>
    <el-collapse v-model="activeNames">
      <el-collapse-item name="1">
        <template #title>
          <div class="title-container">
            <span>{{ title }}</span>
            <el-tooltip content="复制" placement="top">
              <el-icon class="copy-icon" @click.stop="copyText">
                <CopyDocument/>
              </el-icon>
            </el-tooltip>
          </div>
        </template>
        <div class="content-container">
          <div ref="contentToCopy" class="content-to-copy">
            <vue3-markdown-it :source="displayContent"/>
          </div>
        </div>
      </el-collapse-item>
    </el-collapse>
  </div>
</template>

<script>
import {CopyDocument} from '@element-plus/icons-vue';

export default {
  components: {
    CopyDocument
  },
  props: {
    title: {
      type: String,
      required: true
    },
    contentToCopy: {
      type: String,
      required: true
    },
    contentType: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      activeNames: []
    };
  },
  computed: {
    displayContent() {
    //中文乱码转换
      let decodedContent = this.contentToCopy.replace(/\\u(\w{4})/g, (a, b) => String.fromCharCode(parseInt(b, 16)));
      // 在最前面添加一行代码
      return `\`\`\`${this.contentType}\n${decodedContent}`;
    }
  },
  methods: {
    async copyText() {
      try {
        await navigator.clipboard.writeText(this.contentToCopy);
        this.$message({
          message: '复制成功',
          type: 'success'
        });
      } catch (err) {
        this.$message({
          message: '复制失败,请手动复制',
          type: 'error'
        });
      }
    },
  }
};
</script>

<style scoped>
.content-container {
  position: relative;
}

.content-to-copy {
  background-color: #f0f0f0; /* 设置背景颜色为灰色 */
  padding: 10px;
  border-radius: 4px;
  margin-bottom: 10px;
}

.title-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.copy-icon {
  cursor: pointer;
  font-size: 15px;
  color: #409eff;
  margin-right: 8px;
}

.copy-icon:hover {
  color: #66b1ff;
}
</style>

网站公告

今日签到

点亮在社区的每一天
去签到

热门文章