①创建一台opencloud8的腾讯云服务器
②用xshell连接服务器
③vue中新建.env.development配置文件
.env.development:
VUE_APP_BASEURL='http://localhost:9090'
.env.production:
VUE_APP_BASEURL='http://服务器ip:9090'
④修改main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import request from "@/utils/request";
Vue.config.productionTip = false
Vue.use(ElementUI,{size:'small'});
Vue.prototype.$request=request //引入request
Vue.prototype.$baseUrl=process.env.VUE_APP_BASEURL
new Vue({router,render: h => h(App)
}).$mount('#app')
⑤修改request.js:
request:
import axios from 'axios'
import router from "@/router";// 创建可一个新的axios对象
const request = axios.create({baseURL: process.env.VUE_APP_BASEURL, // 后端的接口地址 ip:porttimeout: 30000
})// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {config.headers['Content-Type'] = 'application/json;charset=utf-8';let user=JSON.parse(localStorage.getItem("honey-user")||'{}')// let user = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : nullconfig.headers['token'] = user.token // 设置请求头return config
}, error => {console.error('request error: ' + error) // for debugreturn Promise.reject(error)
});// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(response => {let res = response.data;// 兼容服务端返回的字符串数据if (typeof res === 'string') {res = res ? JSON.parse(res) : res}if(res.code === '401'){router.push('/login')}return res;},error => {console.error('response error: ' + error) // for debugreturn Promise.reject(error)}
)export default request
⑤修改User页
User:
<template><div><div><el-input style="width: 200px" placeholder="查询用户名" v-model="username"></el-input><el-input style="width: 200px;margin: 0 10px" placeholder="查询姓名" v-model="name"></el-input><el-button type="primary" @click="load(1)">查询</el-button><el-button type="info" @click="reset">重置</el-button></div><div style="margin: 10px 0"><el-button type="primary" @click="handleAdd">新增</el-button><el-button type="danger" @click="delbatch">批量删除</el-button><el-button type="info" @click="exportData" plain>批量导出</el-button><el-upload :action="$baseUrl+'/user/import'" :headers="{token:user.token}" style="display: inline-block;margin-left: 10px" :show-file-list="false" :on-success="handleImport"><el-button type="primary" plain>批量导入</el-button></el-upload></div><el-table @selection-change="handleSelectionChange" :data="tableData" stripe :header-cell-style="{backgroundColor:'aliceblue',color:'#666'} "><el-table-column type="selection" width="55" align="center"></el-table-column><el-table-column prop="id" label="ID" width="70"></el-table-column><el-table-column prop="username" label="用户名"></el-table-column><el-table-column prop="name" label="姓名"></el-table-column><el-table-column prop="phone" label="手机号"></el-table-column><el-table-column prop="email" label="邮箱"></el-table-column><el-table-column prop="address" label="地址"></el-table-column><el-table-column label="头像"><template v-slot="scope"><div style="display: flex;align-items: center"><el-image style="width: 50px;height: 50px;border-radius: 50%" v-if="scope.row.avatar" :src="scope.row.avatar" :preview-src-list="[scope.row.avatar]"></el-image></div></template></el-table-column><el-table-column prop="role" label="角色"></el-table-column><el-table-column label="操作" align="center" width="180"><template v-slot="scope"><div style="display: flex"><el-button type="primary" plain size="mini" @click="handleEdit(scope.row)">编辑</el-button><el-button type="danger" plain size="mini" @click="del(scope.row.id)">删除</el-button></div></template></el-table-column></el-table><div class="block" style="margin: 10px 0"><el-pagination@current-change="handleCurrentChange":current-page="pageNum":page-sizes="[100, 200, 300, 400]":page-size="pageSize"layout="total, prev, pager, next":total="total"></el-pagination></div><el-dialog title="收货地址" :visible.sync="formVisible" width="30%"><el-form :model="form" label-width="80px" style="padding-right: 20px" :rules="rules" ref="formRef"><el-form-item label="用户名" prop="username"><el-input v-model="form.username" ></el-input></el-form-item><el-form-item label="姓名" prop="name"><el-input v-model="form.name"></el-input></el-form-item><el-form-item label="电话" prop="phone"><el-input v-model="form.phone"></el-input></el-form-item><el-form-item label="邮箱" prop="email"><el-input v-model="form.email"></el-input></el-form-item><el-form-item label="地址" prop="address"><el-input type="textarea" v-model="form.address"></el-input></el-form-item><el-form-item label="角色" prop="role"><el-radio-group v-model="form.role"><el-radio label="管理员"></el-radio><el-radio label="用户"></el-radio></el-radio-group></el-form-item><el-form-item label="头像"><el-uploadclass="avatar-uploader":action="$baseUrl+'/file/upload'":headers="{ token: user.token }":file-list="form.avatar?[form.avatar]:[]"list-type="picture":on-success="handleAvatarSuccess"><el-button type="primary">上传头像</el-button></el-upload></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible = false">取 消</el-button><el-button type="primary" @click="save">确 定</el-button></div></el-dialog></div>
</template><script>
export default {name:'User',data(){return{tableData:[],pageNum:1,pageSize:5,username:'',name:'',total:0,formVisible:false,form:{},user:JSON.parse(localStorage.getItem('honey-user'||'{}')),rules:{username:[{required:true,message:'请输入用户名',trigger:'blur'}]},ids:[]}},created() {this.load()},methods:{handleImport(res,file,fileList){if(res.code==='200'){this.$message.success("操作成功")this.load(1)}else{this.$message.error(res.msg)}},exportData(){if(!this.ids.length){window.open(this.$baseUrl+"/user/export?token="+this.user.token+"&username="+this.username+"&name="+this.name)}else{let idStr=this.ids.join(',')window.open(this.$baseUrl+"/user/export?token="+this.user.token+"&ids="+idStr)}},delbatch(){if(!this.ids.length){this.$message.warning("请选择数据")return}this.$confirm('您确认删除吗','确认删除',{type:'warning'}).then(response=>{this.$request.delete('/user/delete/batch',{data:this.ids}).then(res=>{if(res.code === '200'){this.$message.success('操作成功')this.load(1)}else{this.$message.error(res.msg)}})}).catch(()=>{})},handleSelectionChange(rows){this.ids=rows.map(v=>v.id)},del(id){this.$confirm('您确认删除吗','确认删除',{type:'warning'}).then(response=>{this.$request.delete('/user/delete/'+id).then(res=>{if(res.code === '200'){this.$message.success('操作成功')this.load(1)}else{this.$message.error(res.msg)}})}).catch(()=>{})},handleEdit(row){this.form=JSON.parse(JSON.stringify(row))this.formVisible=true},handleAdd(){this.form={role:'用户'}this.formVisible=true},save(){this.$refs.formRef.validate((valid)=>{if(valid){this.$request({url:this.form.id? '/user/update' : '/user/add',method:this.form.id? 'PUT' : 'POST',data:this.form}).then(res=>{if(res.code === '200'){this.$message.success('保存成功')this.load(1)this.formVisible=false}else{this.$message.error(res.msg)}})}})},handleAvatarSuccess(response,file,fileList){console.log(response)this.form.avatar=response.data},reset(){this.name=''this.username=''this.load()},load(pageNum){if(pageNum){this.pageNum=pageNum}this.$request.get('/user/selectByPage',{params:{pageNum:this.pageNum,pageSize:this.pageSize,username:this.username,name:this.name}}).then(res=>{this.tableData=res.data.recordsthis.total=res.data.total})},handleCurrentChange(pageNum){this.load(pageNum)},}
}
</script><style scoped></style>
⑥修改Person页
Person:
<template><div><el-card style="width: 50%"><el-form :model="user" label-width="80px" style="padding-right: 20px"><div style="margin: 15px;text-align: center"><el-uploadclass="avatar-uploader":action="$baseUrl+'/file/upload'":headers="{ token: user.token }":show-file-list="false":on-success="handleAvatarSuccess"><img v-if="user.avatar" :src="user.avatar" class="avatar"><i v-else class="el-icon-plus avatar-uploader-icon"></i></el-upload></div><el-form-item label="用户名" prop="username"><el-input v-model="user.username" disabled></el-input></el-form-item><el-form-item label="姓名" prop="name"><el-input v-model="user.name"></el-input></el-form-item><el-form-item label="电话" prop="phone"><el-input v-model="user.phone"></el-input></el-form-item><el-form-item label="邮箱" prop="email"><el-input v-model="user.email"></el-input></el-form-item><el-form-item label="地址" prop="address"><el-input type="textarea" v-model="user.address"></el-input></el-form-item></el-form><div style="text-align: center;margin-bottom: 20px"><el-button type="primary" @click="update">保存</el-button></div></el-card></div>
</template><script>
export default {data(){return{user:JSON.parse(localStorage.getItem('honey-user'||'{}'))}},methods:{update(){this.$request.put('/user/update',this.user).then(res=>{if(res.code==='200'){this.$message.success('保存成功')localStorage.setItem('honey-user',JSON.stringify(this.user))this.$emit('update:user',this.user)}else{this.$message.error(res.msg)}})},handleAvatarSuccess(response,file,fileList){console.log(response)this.user.avatar=response.data}}
}
</script><style scoped>
/deep/.el-form-item__label{font-weight: bold;
}
/deep/.el-upload{border-radius: 50%;
}
/deep/.avatar-uploader .el-upload {border: 1px dashed #d9d9d9;cursor: pointer;position: relative;overflow: hidden;border-radius: 50%;
}
/deep/.avatar-uploader .el-upload:hover {border-color: #409EFF;
}
.avatar-uploader-icon {font-size: 28px;color: #8c939d;width: 178px;height: 178px;line-height: 178px;text-align: center;border-radius: 50%;
}
.avatar {width: 178px;height: 178px;display: block;border-radius: 50%;
}
</style>
⑦打包vue文件
在终端进入vue的文件夹进行打包:
npm run build
生成dist文件夹说明打包成功:
⑧打包springboot文件
生成target文件夹:
⑨上传打包文件并部署服务器java和mysql环境
在xshell中打开xftp:
创建目录下的各种文件夹:
将jar包和application.yml拖入java文件夹;
修改application.yml:
server:port: 9090spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://${ip}:3306/honey2024?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8username: rootpassword: 123456servlet:multipart:max-file-size: 20MBmax-request-size: 20MB
ip: 服务器ip
在java目录下编辑启动脚本:vi start.vh
NAME=springboot-0.0.1-SNAPSHOT.jar
nohup java -jar $NAME > server.log 2>&1 &
echo 'start success'
编辑终止脚本:vi stop.sh
PORT=9090
pid=`netstat -tnlp | grep $PORT | grep -v grep | awk '{print $7}' | awk -F/ '{print $1}'`
if [ ${pid} ]; thenkill -9 $pidecho "kill $PORT"
elseecho 'stop sucess!'
fi
赋予java文件夹下读写权限:chmod +x *
dist拖入vue文件夹;
下载环境文件并上传至服务器的tmp文件夹下:
链接:https://pan.baidu.com/s/1H5WqBiq0iKACDnh1uBlAZA?pwd=anb8
提取码:anb8
安装jdk1.8:
tar -zxvf /tmp/jdk-8u371-linux-x64.tar.gz -C /usr/local/
mv /usr/local/jdk1.8.0_371 /usr/local/javavi /etc/profileexport JAVA_HOME=/usr/local/java
export PATH=$JAVA_HOME/bin:$PATHsource /etc/profile# 验证
java -version
安装 nginx:
#安装gcc
yum install gcc-c++#安装PCRE pcre-devel
yum install -y pcre pcre-devel#安装zlib
yum install -y zlib zlib-devel#安装Open SSL
yum install -y openssl openssl-devel
解压、编译 nginx 并安装:
mkdir /usr/local/nginx
tar -zxvf /tmp/nginx-1.24.0.tar.gz -C /usr/local/nginxcd /usr/local/nginx/nginx-1.24.0
# 编译安装
./configure --with-http_stub_status_module --with-http_ssl_module
make && make install
nginx 命令:
cd /usr/local/nginx/sbin
./nginx # 启动ps -ef | grep nginx # 查看
./nginx -s stop # 停止
./nginx -s reload # 重启
nginx 配置:
server {listen 80;server_name localhost;#charset koi8-r;#access_log logs/host.access.log main;location / {root /home/server/honey2024/vue/dist;index index.html index.htm;try_files $uri $uri/ /index.html;}
}
在 Manager 的 mouted 函数里加上这个判断即可 防止用户在未登录的情况下进入首页:
mounted() { // 页面加载完成之后触发if (!this.user.id) { // 当前的浏览器没有用户信息this.$router.push('/login')}
},
安装mysql:
rpm -qa | grep mariadb
yum remove -y mariadb-connector-c-3.1.11-2.oc8.1.x86_64
yum remove -y mariadb-connector-c-config-3.1.11-2.oc8.1.noarch
下载 mysql 并 上传到 /tmp 目录
安装 mysql 命令:
mkdir /data/mysql
tar -zxvf /tmp/mysql-5.7.42-el7-x86_64.tar.gz -C /usr/local
mv /usr/local/mysql-5.7.42-el7-x86_64 /usr/local/mysql# 添加用户组
groupadd mysql
useradd -r -g mysql mysql
chown -R mysql.mysql /usr/local/mysql
chown -R mysql.mysql /data/mysqlcd /usr/local/mysql
/usr/local/mysql/bin/mysqld --user=mysql --basedir=/usr/local/mysql/ --datadir=/data/mysql --initialize# 将mysql加入到服务中
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql# mysql快捷方式
ln -s /usr/local/mysql/bin/mysql /usr/bin
ln -s /usr/lib64/libtinfo.so.6.1 /usr/lib64/libtinfo.so.5
ln -s /usr/lib64/libncurses.so.6.1 /usr/lib64/libncurses.so.5
临时密码:STsrIurl7D>8
配置 mysql 配置文件 my.cnf
vi /etc/my.cnf
[mysqld]
datadir=/data/mysql
basedir=/usr/local/mysql
socket=/tmp/mysql.sock
user=mysql
port=3306
character-set-server=utf8
# 取消密码验证
# skip-grant-tables
# # Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
启动 mysql: **service mysql start **
开机启动: **chkconfig mysql on **
登录 mysql: **mysql -uroot -p **
输入临时密码进入 mysql
修改密码并设置权限:
SET PASSWORD = PASSWORD('123456');use mysql;
update user set host ='%'where user ='root' and host ='localhost';
flush privileges;
exit;
服务器开放3306端口用navicat连接数据库:
新建数据库:
将本地honey2024的user表拖入服务器的honey2024进行复制:一路点下一步
修改pom.xml对应部分:重新生成jar包上传
<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><mainClass>com.example.springboot.SpringbootApplication</mainClass><includeSystemScope>true</includeSystemScope></configuration><executions><execution><phase>package</phase><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin>
进入/home/server/honey2024/java运行start.sh脚本:
查看是否生效:tail -100f server.log,如图说明成功(此时还需要在服务器开放9090端口,不要忘了)
此时前后端都部署完成,网站上线成功