准备

1.已买阿里云服务器或其他云服务器,此处以阿里云服务器为例子
2.服务器连接工具Xshell
3.使用xshll连接云服务器

安装软件

1.安装jdk

安装jdk步骤参考阿里云esc服务器部署javaj web环境中的安装jdk步骤
在这里插入图片描述
具体安装步骤如下
1.查看yum源中JDK版本

yum list java*

2.使用yum安装JDK1.8.0

yum -y install java-1.8.0-openjdk*

3.检查是否安装成功

java -version

出现以下内容,说明安装成功

[root@iZuspq7vnxm**** ~]# java -version
openjdk version "1.8.0_342"
OpenJDK Runtime Environment (build 1.8.0_342-b07)
OpenJDK 64-Bit Server VM (build 25.342-b07, mixed mode)

4.配置环境变量
a.查看JDK安装的路径

find /usr/lib/jvm -name 'java-1.8.0-openjdk-1.8.0*'

回显信息如下

[root@test000****~]# find /usr/lib/jvm -name 'java-1.8.0-openjdk-1.8.0*'
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.342.b07-1.el7_9.x86_64

b.打开配置文件

vim /etc/profile

c.在配置文件末尾,按i进入编辑模式
d. 添加以下信息。

     说明:JAVA_HOME值为当前JDK安装的路径。

java_home的值与安装的jdk路径保持一致。

JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.342.b07-1.el7_9.x86_64
PATH=$PATH:$JAVA_HOME/bin
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export JAVA_HOME CLASSPATH PATH

e. 按下Esc键,输入:wq并回车以保存并关闭文件。

 f. 运行以下命令,立即生效环境变量。
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

2.安装tomcat

安装tomcat步骤参考阿里云esc服务器部署javaj web环境中的tomcat安装步骤
在这里插入图片描述

1.下载tomcat安装包

wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.88/bin/apache-tomcat-8.5.88.tar.gz  --no-check-certificate 
tar -zxvf apache-tomcat-8.5.88.tar.gz

2.当前目录会有一个tomcat压缩包
在这里插入图片描述
3.解压

tar -zxvf apache-tomcat-8.5.88.tar.gz

4.移动tomcat目录并改名为tomcat

sudo mv apache-tomcat-8.5.88 /usr/local/tomcat

5.新建普通用户。
原因:为保证系统安全性,建议创建一般用户来运行Tomcat。
例如,本示例中创建一般用户www

useradd www

6.将文件的所属用户设置为www

chown -R www.www /usr/local/tomcat/

在/usr/local/tomcat/目录下:

   · bin:存放Tomcat的一些脚本文件,包含启动和关闭Tomcat服务脚本。

   · conf:存放Tomcat服务器的各种全局配置文件,其中最重要的是server.xml和web.xml。

   · webapps:Tomcat的主要Web发布目录,默认情况下把Web应用文件放于此目录。

   · logs:存放Tomcat执行时的日志文件。

7.配置server.xml文件。
a,切换到/usr/local/tomcat/conf/目录

cd /usr/local/tomcat/conf/

b.重命名server.xml文件

mv server.xml server.xml_bk
mv server.xml server.xml_bk

c.新建一个server.xml文件
1)创建并打开server.xml文件

vi server.xml

2)按下i键,添加以下内容

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8006" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
<Listener className="org.apache.catalina.core.AprLifecycleListener"/>
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
 type="org.apache.catalina.UserDatabase"
 description="User database that can be updated and saved"
 factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
 pathname="conf/tomcat-users.xml"/>
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="8080"
 protocol="HTTP/1.1"
 connectionTimeout="20000"
 redirectPort="8443"
 maxThreads="1000"
 minSpareThreads="20"
 acceptCount="1000"
 maxHttpHeaderSize="65536"
 debug="0"
 disableUploadTimeout="true"
 useBodyEncodingForURI="true"
 enableLookups="false"
 URIEncoding="UTF-8"/>
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
  resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="/data/wwwroot/default" unpackWARs="true" autoDeploy="true">
<Context path="" docBase="/data/wwwroot/default" debug="0" reloadable="false" crossContext="true"/>
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>
</Engine>
</Service>
</Server>

3)按Esc键,输入:wq并回车以保存并关闭文件
8.设置JVM内存参数
a.创建并打开/usr/local/tomcat/bin/setenv.sh文件

vi /usr/local/tomcat/bin/setenv.sh

b. 按下i键,添加以下内容。

       指定JAVA_OPTS参数,用于设置JVM的内存信息以及编码格式。
JAVA_OPTS='-Djava.security.egd=file:/dev/./urandom -server -Xms256m -Xmx496m -Dfile.encoding=UTF-8'

c. 按下Esc键,输入:wq并回车以保存并关闭文件
9.设置Tomcat自启动脚本。
a. 运行以下命令,下载Tomcat自启动脚本。

        说明:该脚本来源于社区,仅供参考。阿里云对其可靠性以及操作可能带来的潜在影响,不做任何暗示或其他形式的承诺。如果您运行wget命令下载失败,您可以通过浏览器访问https://raw.githubusercontent.com/oneinstack/oneinstack/master/init.d/Tomcat-init直接获取脚本内容。
wget https://raw.githubusercontent.com/oneinstack/oneinstack/master/init.d/Tomcat-init

b.移动并重命名Tomcat-init

mv Tomcat-init /etc/init.d/tomcat

c.为/etc/init.d/tomcat添加可执行权限

chmod +x /etc/init.d/tomcat

d. 运行以下命令,设置启动脚本JAVA_HOME。

      重要:脚本中JDK的版本信息必须与您安装的JDK版本信息一致,否则Tomcat会启动失败。
sed -i 's@^export JAVA_HOME=.*@export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.342.b07-1.el7_9.x86_64@' /etc/init.d/tomcat                  

10.依次运行以下命令,设置Tomcat开机自启动。

chkconfig --add tomcat
chkconfig tomcat on

11.启动Tomcat

service tomcat start             

回显信息类似如下所示,表示启动Tomcat成功

[root@test000**** conf]# service tomcat start
Starting tomcat
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.342.b07-1.el7_9.x86_64
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.
Tomcat is running with pid: 11837            

3.安装mysql

参考阿里云esc服务搭建教程中的LAMP环境中的第3步
在这里插入图片描述
具体步骤如下:
1.下载安装mysql

wget http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm &&
yum -y install mysql57-community-release-el7-10.noarch.rpm &&
yum install -y mysql-community-server --nogpgcheck

2.启动mysql数据库

systemctl start mysqld.service

3.查看MySQL数据库初始密码

grep "password" /var/log/mysqld.log

4.登录数据库

mysql -uroot -p

5.修改MySQL默认密码

set global validate_password_policy=0;  #修改密码安全策略为低(只校验密码长度,至少8位)。
ALTER USER 'root'@'localhost' IDENTIFIED BY '12345678';

6.授予root用户远程管理权限


GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '12345678';

7.输入exit退出数据库

后端应用功能编写及部署

编写一个简单的用户增删改查功能

1.pom文件

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>user-service</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.3.5.RELEASE</version>
    </parent>

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>

        <!--swagger-->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>2.0.2</version>
        </dependency>

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

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.5.RELEASE</version>
            </plugin>
        </plugins>
    </build>
</project>

2.配置文件
注意:log配置是为了测试阶段有问题可以查看控制台打印的sql语句,正式发布可以去掉。

server:
  port: 12001
spring:
  application:
    name: test-user
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://120.78.64.120:3306/test?timeZone=Asia/Shanghai&characterEncoding=utf-8
    username: root
    password: Qfp11111(此处写自己的数据库密码)

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

3.启动类

@SpringBootApplication
@EnableSwagger2
public class UserService {
    public static void main(String[] args) {
        SpringApplication.run(UserService.class,args);
    }
}

4.实体类

package com.test.user.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 java.util.Date;

/**
 * @author清梦
 * @site www.xiaomage.com
 * @company xxx公司
 * @create 2023-12-27 21:03
 */
@Data
@TableName("tb_user")
public class User {

    /**
     * 'id'
     */
    @TableId(type = IdType.AUTO)
    private Integer id;

    /**
     * ''用户名''
     */
    private String username;

    /**
     * '真实姓名'
     */
    private String realName;

    /**
     * '密码'
     */
    private String password;

    /**
     * '性别:0-男,1-女'
     */
    private String sex;

    /**
     * '生日'
     */
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
    private Date birthday;

    /**
     * '身份证号'
     */
    private String cardId;

    /**
     * '手机号'
     */
    private String phone;

}

5.分页插件(没有这个配置不分页)

package com.test.user.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 1
 */
@Configuration
public class MybatisConfig {

    /**
     * 添加分页插件
     * @return
     */
    @Bean
    public MybatisPlusInterceptor interceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

分页信息vo

package com.test.user.vo;

import lombok.Data;

import java.util.List;

/**
 * @author清梦
 * @site www.xiaomage.com
 * @company xxx公司
 * @create 2024-01-09 22:13
 */
@Data
public class PageResult<T> {
    /**
     * 总条数
     */
    private Long total;
    /**
     * 总页数
     */
    private Long totalPage;
    /**
     * 当前页数据
     */
    private List<T> items;

    public PageResult() {
    }

    public PageResult(Long total, List<T> items) {
        this.total = total;
        this.items = items;
    }

    public PageResult(Long total, Long totalPage, List<T> items) {
        this.total = total;
        this.totalPage = totalPage;
        this.items = items;
    }
}

6.接口

package com.test.user.controller;

import com.test.user.entity.User;
import com.test.user.service.UserService;
import com.test.user.vo.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

/**
 * @author清梦
 * @site www.xiaomage.com
 * @company xxx公司
 * @create 2023-12-27 21:11
 */
@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("page")
    public ResponseEntity<PageResult<User>> page(
            @RequestParam(value = "pageIndex",defaultValue = "1")Integer pageIndex,
            @RequestParam(value = "pageSize",defaultValue = "5")Integer pageSize,
            @RequestParam(value = "username",required = false)String username
    ){
        PageResult<User> result = userService.selectPage(pageIndex, pageSize,username);
        return ResponseEntity.ok(result);
    }

    @GetMapping("getUserById")
    public User getUserById(Integer id){
        return userService.getById(id);
    }
    @PostMapping("save")
    public ResponseEntity save(@RequestBody User user){
        userService.saveOrUpdate(user);
        return ResponseEntity.ok("操作成功");
    }

    @DeleteMapping("delete")
    public ResponseEntity delete(Integer id){
        userService.removeById(id);
        return ResponseEntity.ok("操作成功");
    }
}


7.实现类

public interface UserService extends IService<User> {
    PageResult<User> selectPage(Integer pageIndex, Integer pageSize, String username);
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public PageResult<User> selectPage(Integer pageIndex, Integer pageSize,String username) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(username),User::getUsername,username);
        Page<User> userPage = userMapper.selectPage(new Page<>(pageIndex, pageSize), queryWrapper);
        return new PageResult<>(userPage.getTotal(),userPage.getPages(),userPage.getRecords());
    }
}

8.本地测试
启动程序,浏览器输入localhost:12001/doc.html,选择接口进行增删改查
在这里插入图片描述

9.功能测试无误,可以准备发布到云服务器。

发布流程

1.将项目打包获取jar包
idea右侧栏找到maven—>user-service—>package,左键双击,开始打包
在这里插入图片描述
控制台输出build success,说明打包成功,按照红色框的路径找到打包好的jar包
在这里插入图片描述
未指定打包路径时,会默认打包在该项目的target目录下
在这里插入图片描述
2.准备项目启动脚本
新建一个txt文件,后缀名改为.sh
添加内容如下

nohup java -jar user-service-1.0-SNAPSHOT.jar &

注意:可以现在txt文件中添加内容,再修改后缀。如果先修改后缀,则需要以记事本方式打开进行编辑。

3.上传文件到服务器
在服务器的输入rz,弹出文件选择框,将文件上传到云服务器
在这里插入图片描述
如果提示命令不存在
则需要输入命令

yum -y install lrzsz

上传成功后输入

ll

显示如下
在这里插入图片描述
4.运行应用
运行启动脚本
启动命令参考博客
Linux 下通过 java 命令启动 jar 包的几种常见方式

sh start.sh

在这里插入图片描述
因为我们没有指定日志文件,所以会默认将日志输入到nohup.out文件中
启动成功后可以查看是否成功

ps -ef |grep user-service

在这里插入图片描述
第一条记录说明启动成功
也可以查看日志
在这里插入图片描述

然后在浏览器输入云服务器公网地址+端口+doc.html
在这里插入图片描述
后端部署成功

前端功能应用及部署

搭建前端框架

准备:已安装npm

准备1:安装node.js
下载链接node.js
推荐下载LST版本
在这里插入图片描述
下载后自行安装
安装成功后,win+r,输入cmd,进入控制台查看版本

node -v

在这里插入图片描述
安装完成Node应该自带了NPM了,在控制台输入npm -v查看:在这里插入图片描述
npm默认的仓库地址是在国外网站,速度较慢,建议大家设置到淘宝镜像。但是切换镜像是比较麻烦的。推荐一款切换镜像的工具:nrm

我们首先安装nrm,这里-g代表全局安装

npm install nrm -g

在这里插入图片描述
然后通过nrm ls命令查看npm的仓库列表,带*的就是当前选中的镜像仓库:
在这里插入图片描述
通过nrm use taobao来指定要使用的镜像源:在这里插入图片描述
然后通过nrm test npm 来测试速度:
在这里插入图片描述
注意:

  • 安装完成请一定要重启下电脑!!!
  • 安装完成请一定要重启下电脑!!!
  • 安装完成请一定要重启下电脑!!!

1.新建一个空项目
在这里插入图片描述
2.空项目中新建模板
idea2020.1新建java web项目选择javaScript,给项目命令后完成
在这里插入图片描述
3.打开命令窗口
在这里插入图片描述
4.安装vue-cli

npm install -g vue-cli

a.用vue-cli命令,快速搭建一个webpack的项目:

vue init webpack

在这里插入图片描述
在这里插入图片描述
前面几项都走默认或yes

下面这些我们选no
在这里插入图片描述

最后,再选yes,使用 npm安装
在这里插入图片描述
在这里插入图片描述
安装好的项目结构:
在这里插入图片描述
5.本地测试运行
在命令窗口运行命令npm run dev 或者 npm start 都可以启动项目

npm run dev

运行完成
在这里插入图片描述
如果运行后提示如下,说明未安装依赖,运行npm 安装后再运行
在这里插入图片描述

点击链接后页面如下
在这里插入图片描述
ui页面参考网址
本博客使用vuetify地址:vuetify
vue2.0参考
vue2.0
注意:使用前先安装
在这里插入图片描述

vue3.0参考:
elementUI

页面

user.vue

<template>
  <v-card>
    <v-card-title>
      <v-btn @click="addUser" color="primary">新增用户</v-btn>
      <v-spacer/>
      <v-text-field
        append-icon="search"
        label="输入用户名搜索"
        single-line
        hide-details
        v-model="search"
      />
    </v-card-title>
    <v-divider/>
    <v-data-table
      :headers="headers"
      :items="userList"
      :pagination.sync="pagination"
      :total-items="totalUsers"
      :loading="loading"
      class="elevation-1"
    >
      <template slot="items" slot-scope="props">
        <td class="text-xs-center">{{ props.item.id }}</td>
        <td class="text-xs-center">{{ props.item.username }}</td>
        <td class="text-xs-center">{{ props.item.realName }}</td>
        <td class="text-xs-center">{{ props.item.birthday }}</td>
        <td class="text-xs-center">{{ props.item.sex===0 ? '男':'女' }}</td>
        <td class="text-xs-center">{{ props.item.cardId }}</td>
        <td class="text-xs-center">{{ props.item.phone }}</td>
        <td class="justify-center layout px-0">
          <v-btn icon @click="editUser(props.item)">
            <i class="el-icon-edit"/>
          </v-btn>
          <v-btn icon @click="deleteUser(props.item)">
            <i class="el-icon-delete"/>
          </v-btn>
        </td>
      </template>
      <template slot="expand" slot-scope="props">
        <v-card flat>
          <v-card-text>Peek-a-boo!</v-card-text>
        </v-card>
      </template>
      <template slot="no-data">
        <v-alert :value="true" color="info" icon="info">
          无数据
        </v-alert>
      </template>
      <template slot="pageText" slot-scope="props">{{props.itemsLength}},当前:{{ props.pageStart }} - {{ props.pageStop }}
      </template>
    </v-data-table>

    <v-dialog v-model="show" max-width="600" scrollable v-if="show">
      <v-card>
        <v-toolbar dark dense color="primary">
          <v-toolbar-title>{{isEdit ? '修改用户' : '新增用户'}}</v-toolbar-title>
          <v-spacer/>
          <v-btn icon @click="show = false">
            <v-icon>close</v-icon>
          </v-btn>
        </v-toolbar>
        <v-card-text class="px-5 py-2">
          <!-- 表单 -->
          <user-form :oldUser="oldUser" :isEdit="isEdit" @close="show = false" :reload="getDataFromApi"/>
        </v-card-text>
      </v-card>
    </v-dialog>
  </v-card>

</template>

<script>
  import UserForm from './UserForm'

  export default {
    name: "user",
    components: {
      UserForm
    },
    data() {
      return {
        search: '',// 过滤字段
        totalUsers: 0, // 总条数
        userList: [], // 当前页用户数据
        loading: true,
        pagination: {},// 分页信息
        headers: [// 表头
          {text: 'id', align: 'center', value: 'id'},
          {text: '用户名称', align: 'center', sortable: false, value: 'username'},
          {text: '真实姓名', align: 'center', sortable: false, value: 'realName'},
          {text: '生日', align: 'center', sortable: false, value: 'birthday'},
          {text: '性别', align: 'center', value: 'sex', sortable: false,},
          {text: '身份证号', align: 'center', value: 'cardId', sortable: false,},
          {text: '手机号', align: 'center', value: 'phone', sortable: false,},
          {text: '操作', align: 'center', value: 'id', sortable: false}
        ],
        show: false,// 是否弹出窗口
        oldUser: {}, // 用户信息
        isEdit: false // 判断是编辑还是新增
      }
    },
    watch: {
      pagination: {
        handler() {
          this.getDataFromApi();
        },
        deep: true
      },
      search: {
        handler() {
          this.getDataFromApi();
        }
      },
      show(val, oldVal) {
        // 表单关闭后重新加载数据
        if (oldVal) {
          this.getDataFromApi();
        }
      }
    },
    mounted() {
      this.getDataFromApi();
    },
    methods: {
      addUser() {
        this.user = {};
        this.isEdit = false;
        this.show = true;
      },
      editUser(item) {
        this.oldUser = item;
        this.isEdit = true;
        this.show = true;
      },
      deleteUser(item) {
        this.$message.confirm('此操作将永久删除该用户, 是否继续?').then(() => {
          // 发起删除请求
          this.$http.delete("/user/delete?id=" + item.id,)
            .then(() => {
              // 删除成功,重新加载数据
              this.$message.success("删除成功!");
              this.getDataFromApi();
            })
        }).catch(() => {
          this.$message.info("删除已取消!");
        });

      },
      getDataFromApi() {
        this.$http.get("/user/page", {
          params: {
            username: this.search, // 搜索条件
            pageIndex: this.pagination.page,// 当前页
            pageSize: this.pagination.rowsPerPage,// 每页大小
          }
        }).then(resp => { // 这里使用箭头函数
          this.userList = resp.data.items;
          this.totalUsers = resp.data.total;
          // 完成赋值后,把加载状态赋值为false
          this.loading = false;
        })
      }
    }
  }
</script>

<style scoped>

</style>

userForm.vue

<template>
  <v-form v-model="valid" ref="UserForm">
    <v-text-field
      label="用户名称"
      v-model="user.username"
      :rules="[v => !!v || '用户名称不能为空']"
      :counter="30"
      required
    />
    <v-text-field
      label="真实姓名"
      v-model="user.realName"
      :rules="[v => !!v || '真实姓名不能为空']"
      required
    />
    <v-text-field
      label="密码"
      v-model="user.password"
      :rules="[v => !!v || '密码不能为空']"
      required
    />
    <v-text-field
      label="生日"
      v-model="user.birthday"
      :rules="[v => !!v || '生日不能为空']"
      required
      type="date"
    />
    <v-text-field
      label="身份证号"
      v-model="user.cardId"
      :rules="[v => !!v || '身份证号不能为空']"
      required
    />
    <v-text-field
      label="手机号"
      v-model="user.phone"
      :rules="[v => !!v || '手机号不能为空']"
      required
    />
    <v-container fluid>
      <p>性别:</p>
      <v-radio-group v-model="user.sex" inline>
        <v-radio label="男" value=0></v-radio>
        <v-radio label="女" value=1></v-radio>
      </v-radio-group>
    </v-container>
    <v-layout class="my-4">
      <v-btn @click="submit" color="primary">提交</v-btn>
      <v-btn @click="clear" color="warning">重置</v-btn>
    </v-layout>
  </v-form>
</template>

<script>
  import config from '@/config';
  export default {
    name: "user-form",
    props: {
      oldUser: Object,
      isEdit: {
        type: Boolean,
        default: false
      },
      show: {
        type: Boolean,
        default: true
      }
    },
    data() {
      return {
        baseUrl: config.api,
        valid:false,
        user: {
          username: "",
          realName: "",
          password: "",
          sex: 0,
          birthday: "",
          cardId: "",
          phone: "",
        },
      }
    },
    watch: {
      oldUser:{
        deep:true,
        immediate:true,
        handler(val){
         this.user = Object.deepCopy(val,this.user)
        }
      }
    },
    methods: {
      submit() {
        // 表单校验
        if (this.$refs.UserForm.validate()) {
          this.$http({
            method: 'post',
            url: '/user/save',
            data: this.user
          }).then(() => {
            // 关闭窗口
            this.$message.success("保存成功!");
            this.closeWindow();
          }).catch(() => {
            this.$message.error("保存失败!");
          });
        }
      },
      clear() {
        // 重置表单
        this.$refs.userForm.reset();
      },
      closeWindow(){
        this.$emit("close");
      }
    }
  }
</script>
<style scoped>

</style>

前端项目源码地址:博客web源码

跨域问题

页面请求接口报错
在这里插入图片描述
后端项目添加一个配置类

package com.test.user.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * @author清梦
 * @site www.xiaomage.com
 * @company xxx公司
 * @create 2024-01-10 20:24
 */
@Configuration
public class GlobalCorsConfig {

    @Bean
    public CorsFilter corsFilter(){
        //1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        //1) 允许的域,不要写*,否则cookie就无法使用了--目前没有登录校验功能,不需要cookie,允许所有请求
        config.addAllowedOrigin("*");
        //2) 是否发送Cookie信息
        config.setAllowCredentials(true);
        //3) 允许的请求方式
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        // 4)允许的头信息
        config.addAllowedHeader("*");

        //2.添加映射路径,我们拦截一切请求
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);

        //3.返回新的CorsFilter.
        return new CorsFilter(configSource);
    }
}

6.打包到服务器
先打包

npm run build

打包后的文件在dist目录下
在这里插入图片描述
注意打包时将config.js文件中的访问IP改为公网IP
在这里插入图片描述
改为公网IP
在这里插入图片描述

把整个dist文件夹压缩成一个user-web.zip文件上传到服务器,
先切换到自己的目录

cd /root/myService/testUserWeb/

使用命令

rz

将压缩包传到服务器上
然后解压

unzip user-web.zip

此时需要nginx对路径做配置

安装nginx

参考博客:linux环境下载安装linux
如果不知道对应的版本,建议使用docker安装
参考博客
安装nginx docker
如果买了阿里云服务器,可以登录阿里云官网,在ecs实例页面,搭建微信小程序的第2步有安装nginx的步骤,可以按照步骤安装
在这里插入图片描述
本人是阿里云服务器,按照截图中的步骤安装。

配置nginx

切换到nginx目录下

cd /etc/nginx

备份配置文件

cp nginx.conf nginx.conf.bak

修改配置文件
a.进入编辑模式

vim nginx.conf

添加如下内容

server {
        listen       9001;
        server_name localhost;
	root  /root/myService/testUserWeb/user-web;
	location / {
	   try_files $uri $uri/ /index.html;
	}

	location /api {
	   proxy_pass http://127.0.0.1:12001;
	}

    }

注意:root后面是前端包的路径,需要跟前端包名保持一致
重启nginx

nginx -s reload

最后在浏览器输入公网ip+端口,显示页面,前后端分离项目发布成功。(功能验证步骤跳过)

在这里插入图片描述

源码

后端源码地址:testUser源码地址
前端源码地址:testUserWeb源码地址

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐