语言 :java11 vue3

前端 vue + element + vite + vue-router

封装

axios

import axios from 'axios'

const request = axios.create({
    baseURL: '/api',
    timeout: 5000
    })
// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(
    (config) => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8'
// config.headers['token'] = user.token;  // 设置请求头
return config
},
(error) => {
    return Promise.reject(error)
}
)
// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
    (response) => {
    let res = response.data
    // 如果是返回的文件
    // 返回0 为成功
    if (res.code == 0) {
    ElMessage({
        message: res.msg,
        type: 'success'
    })
    return res.data
    }
    ElMessage.error(res.msg)
    return Promise.reject(res)
    },
    (error) => {
    ElMessage.error('网络异常')
return Promise.reject(error)
}
)
export default request

vue-route

import Login from '@/pages/login/index.vue'
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
  history: createWebHistory(),

  routes: [
    {
      path: '/',
      redirect: '/login'
    },
    {
      path: '/home',
      redirect: '/login'
    },
    {
      path: '/doctor',
      component: () => import('@/pages/layout/doctor.vue'),
      children: [
        {
          path: '/doctor',
          name: 'doctor',
          component: () => import('../pages/doctor/index.vue')
        },
        {
          path: '/doctor/new',
          name: 'new',
          component: () => import('../pages/doctor/new.vue')
        },
        {
          path: '/doctor/me',
          name: 'me',
          component: () => import('../pages/doctor/me.vue')
        }
      ]
    },
    {
      path: '/patient',
      component: () => import('@/pages/layout/index.vue'),
      children: [
        {
          path: '/patient',
          name: 'home',
          component: () => import('@/pages/home/index.vue')
        },
        {
          path: '/patient/auth',
          name: 'auth',
          component: () => import('@/pages/home/auth.vue')
        },
        {
          path: '/patient/me',
          name: 'patient-me',
          component: () => import('@/pages/home/me.vue')
        }
      ]
    },

    {
      //每一个链接都是一个对象
      path: '/login', //链接路径
      name: 'login', //路由名称,
      component: Login //对应的组件模板
    },
    {
      path: '/register',
      name: 'register',
      component: () => import('@/pages/login/register.vue')
    }
  ]
})

export default router

启动文件

import { createApp } from 'vue'
import App from './App.vue'
import Router from './router'
import './style.css'
const app = createApp(App)
app.use(Router)
app.mount('#app')

目录

$ tree                                                                                                                     
.
├── components.d.ts
├── index.html
├── jsconfig.json
├── node_modules
│   ├── @element-plus
│   │   └── icons-vue -> ../.pnpm/@element-plus+icons-vue@2.3.1_vue@3.4.21/node_modules/@element-plus/icons-vue
│   ├── @vitejs
│   │   └── plugin-vue -> ../.pnpm/@vitejs+plugin-vue@5.0.4_vite@5.1.6_vue@3.4.21/node_modules/@vitejs/plugin-vue
│   ├── autoprefixer -> .pnpm/autoprefixer@10.4.18_postcss@8.4.37/node_modules/autoprefixer
│   ├── axios -> .pnpm/axios@1.6.8/node_modules/axios
│   ├── element-plus -> .pnpm/element-plus@2.6.1_vue@3.4.21/node_modules/element-plus
│   ├── path -> .pnpm/path@0.12.7/node_modules/path
│   ├── postcss -> .pnpm/postcss@8.4.37/node_modules/postcss
│   ├── prettier -> .pnpm/prettier@3.2.5/node_modules/prettier
│   ├── prettier-plugin-organize-imports -> .pnpm/prettier-plugin-organize-imports@3.2.4_prettier@3.2.5_typescript@5.4.2/node_modules/prettier-plugin-organize-imports
│   ├── tailwindcss -> .pnpm/tailwindcss@3.4.1/node_modules/tailwindcss
│   ├── unplugin-auto-import -> .pnpm/unplugin-auto-import@0.17.5/node_modules/unplugin-auto-import
│   ├── unplugin-vue-components -> .pnpm/unplugin-vue-components@0.26.0_vue@3.4.21/node_modules/unplugin-vue-components
│   ├── vite -> .pnpm/vite@5.1.6/node_modules/vite
│   ├── vue -> .pnpm/vue@3.4.21_typescript@5.4.2/node_modules/vue
│   └── vue-router -> .pnpm/vue-router@4.3.0_vue@3.4.21/node_modules/vue-router
├── package.json
├── pnpm-lock.yaml
├── public
│   └── vite.svg
├── src
│   ├── App.vue
│   ├── assets
│   │   └── vue.svg
│   ├── components
│   ├── main.js
│   ├── pages
│   │   ├── doctor   医生
│   │   │   ├── index.vue
│   │   │   ├── me.vue
│   │   │   └── new.vue
│   │   ├── home   患者
│   │   │   ├── auth.vue
│   │   │   ├── index.vue
│   │   │   └── me.vue
│   │   ├── layout 布局
│   │   │   ├── doctor.vue
│   │   │   └── index.vue
│   │   └── login  登录注册
│   │       ├── index.vue
│   │       └── register.vue
│   ├── router
│   │   └── index.js
│   ├── style.css
│   └── utils
│       └── request.js
└── vite.config.js

30 directories, 23 files

后端

目录(代码都有注释)

.
├── pom.xml
├── src
│   └── main
│       ├── java
│       │   └── com
│       │       └── dev
│       │           └── web
│       │               ├── WebApplication.java
│       │               ├── config
│       │               │   ├── CodeGenerator.java
│       │               │   ├── SwaggerConfig.java
│       │               │   └── WebConfig.java
│       │               ├── controller
│       │               │   ├── AuthorizeController.java
│       │               │   ├── BaseController.java
│       │               │   ├── DoctorController.java
│       │               │   ├── PatientController.java
│       │               │   └── RecordController.java
│       │               ├── dto
│       │               │   ├── AuthDto.java
│       │               │   ├── DoctorAuthDto.java
│       │               │   ├── LoginDto.java
│       │               │   ├── NewRecordDto.java
│       │               │   ├── PatientSearchDto.java
│       │               │   ├── PatientSearchResultDto.java
│       │               │   ├── RecordView.java
│       │               │   ├── SearchRecordDto.java
│       │               │   └── SearchRecordResultDto.java
│       │               ├── entity
│       │               │   ├── Authorize.java
│       │               │   ├── Doctor.java
│       │               │   ├── Patient.java
│       │               │   └── Record.java
│       │               ├── ganache
│       │               │   ├── RecordContractInteraction.java
│       │               │   └── RecordERC.java
│       │               ├── mapper
│       │               │   ├── AuthorizeMapper.java
│       │               │   ├── DoctorMapper.java
│       │               │   ├── PatientMapper.java
│       │               │   ├── RecordMapper.java
│       │               │   └── xml
│       │               │       ├── AuthorizeMapper.xml
│       │               │       ├── DoctorMapper.xml
│       │               │       ├── PatientMapper.xml
│       │               │       └── RecordMapper.xml
│       │               ├── service
│       │               │   ├── AuthorizeService.java
│       │               │   ├── DoctorService.java
│       │               │   ├── PatientService.java
│       │               │   ├── RecordService.java
│       │               │   └── impl
│       │               │       ├── AuthorizeImpl.java
│       │               │       ├── DoctorImpl.java
│       │               │       ├── PatientImpl.java
│       │               │       └── RecordImpl.java
│       │               └── util
│       │                   ├── AjaxResult.java
│       │                   └── page
│       │                       ├── PageDomain.java
│       │                       └── TableDataInfo.java
│       └── resources
│           ├── application.yml
│           ├── ganache.yaml
│           ├── mybatis
│           │   └── UserMapper.xml
│           ├── record.abi
│           ├── record.bin
│           ├── record.sol
│           ├── sql
│           │   └── myweb.sql
│           └── templates
│               └── vm
│                   ├── controller.java.vm
│                   ├── entity.java.vm
│                   └── mapper.xml.vm
└── web.iml

接口文档

http://localhost:8088/api/swagger-ui.html

智能合约

src/main/resources/record.abi

src/main/resources/record.bin

src/main/resources/record.sol

https://remix.ethereum.org/

record.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.6.12 <0.9.0;

contract record {
    // 病历记录结构
    struct Record {
        string recordId;
        string description;
        string remark;
    }

    // 存储病历记录
    Record[] public records;

    // 添加病历记录事件
    event AddRecordResult(uint256 count);

    // 获取病历记录事件
    event GetRecordResult(string recordId, string description, string remark);

    // 添加病历记录
    function addRecord(
        string memory _recordId,
        string memory _description,
        string memory _remark
    ) public returns (string memory) {
        records.push(Record(_recordId, _description, _remark));
        emit AddRecordResult(records.length);
        return "ok";
    }

    // 获取病历记录数量
    // function getRecordCount() public view returns (uint256) {
    //     return records.length;
    // }

    // 获取指定recordId的病历记录
    function getRecordById(string memory _recordId)
        public
        returns (
            string memory,
            string memory,
            string memory
        )
    {
        for (uint256 i = 0; i < records.length; i++) {
            if (
                keccak256(abi.encodePacked(records[i].recordId)) ==
                keccak256(abi.encodePacked(_recordId))
            ) {
                emit GetRecordResult(records[i].recordId, records[i].description, records[i].remark);
                return (
                    records[i].recordId,
                    records[i].description,
                    records[i].remark
                );
            }
        }
        revert("Record not found");
    }
}
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.12 <0.9.0;

contract record {
    // 病历记录结构
    struct Record {
        string recordId;
        string description;
        string remark;
    }

    // 存储病历记录
    Record[] public records;

    // 添加病历记录事件
    event AddRecordResult(uint256 count);

    // 获取病历记录事件
    event GetRecordResult(string recordId, string description, string remark);

    // 添加病历记录
    function addRecord(
        string memory _recordId,
        string memory _description,
        string memory _remark
    ) public returns (string memory) {
        records.push(Record(_recordId, _description, _remark));
        emit AddRecordResult(records.length);
        return "ok";
    }

    // 获取病历记录数量
    // function getRecordCount() public view returns (uint256) {
    //     return records.length;
    // }

    // 获取指定recordId的病历记录
    function getRecordById(string memory _recordId)
        public
        returns (
            string memory,
            string memory,
            string memory
        )
    {
        for (uint256 i = 0; i < records.length; i++) {
            if (
                keccak256(abi.encodePacked(records[i].recordId)) ==
                keccak256(abi.encodePacked(_recordId))
            ) {
                emit GetRecordResult(records[i].recordId, records[i].description, records[i].remark);
                return (
                    records[i].recordId,
                    records[i].description,
                    records[i].remark
                );
            }
        }
        revert("Record not found");
    }
}

封装

mybatis-plus 封装 (自动生成数据库接口文件)

package com.dev.web.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

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


public class CodeGenerator {
    public static void main(String[] args) throws InterruptedException {
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = "/Users/xu756/开发/java/web";
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setFileOverride(true);
        gc.setActiveRecord(true);
        // XML 二级缓存
        gc.setEnableCache(false);
        // XML ResultMap
        gc.setBaseResultMap(true);
        // XML columList
        gc.setBaseColumnList(true);
        gc.setOpen(false);
        gc.setSwagger2(true);
        gc.setAuthor("admin");

        // 自定义文件命名,注意 %s 会自动填充表实体属性!
        gc.setMapperName("%sMapper");
        gc.setXmlName("%sMapper");
        gc.setServiceName("%sService");
        gc.setServiceImplName("%sImpl");
        gc.setControllerName("%sController");

        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUrl("jdbc:mysql://localhost:3306/myweb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC");
        dsc.setUsername("myweb");
        dsc.setPassword("myweb");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.dev.web")
                .setController("controller")
                .setEntity("entity")
                .setService("service")
                .setServiceImpl("service.impl")
                .setXml("mapper.xml")
                .setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig("/templates/vm/mapper.xml.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return projectPath + "/src/main/java/com/dev/web/mapper/xml/"
                        + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        focList.add(new FileOutConfig("/templates/vm/controller.java.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return projectPath + "/src/main/java/com/dev/web/controller/"
                        + tableInfo.getEntityName() + "Controller" + StringPool.DOT_JAVA;
            }
        });
        focList.add(new FileOutConfig("/templates/vm/entity.java.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return projectPath + "/src/main/java/com/dev/web/entity/"
                        + tableInfo.getEntityName() + StringPool.DOT_JAVA;
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
        //templateConfig.setXml("\\templates\\vm\\mapper.xml");
        templateConfig.setXml(null);
        templateConfig.setController("/templates/vm/controller.java");
        templateConfig.setEntity("/templates/vm/entity.java");
        mpg.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        //此处可以修改为您的表前缀
        strategy.setTablePrefix(new String[]{""});
        // 表名生成策略
        strategy.setNaming(NamingStrategy.underline_to_camel);
        // 需要生成的表
        strategy.setInclude(new String[]{""});
        // 排除生成的表
//        strategy.setExclude(new String[]{"doctor"});
        strategy.setSuperControllerClass("com.dev.web.controller.BaseController");
        strategy.setEntityLombokModel(true);

        mpg.setStrategy(strategy);

        // 执行生成
        mpg.execute();
    }
}

依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.dev</groupId>
    <artifactId>web</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>myweb</name>
    <description>springboot-mybatis-plus project for Spring Boot</description>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.2</version>
        </dependency>

        <!-- pagehelper 分页插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>4.1.0</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.22</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- swagger2 -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.5.21</version>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>1.5.21</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!-- swagger2 end -->

        <dependency>
            <groupId>jakarta.validation</groupId>
            <artifactId>jakarta.validation-api</artifactId>
            <version>2.0.2</version>
        </dependency>

        <!--        智能合约-->
        <dependency>
            <groupId>org.web3j</groupId>
            <artifactId>core</artifactId>
            <version>3.6.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>1.5.7.RELEASE</version>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>