通过咸虾米项目的开发经历,了解Uniapp项目整体开发过程(微信小程序名称:月色东升壁纸)
目录
- 一、学习背景
- 二、学习过程与前期准备
- 三、项目初期:基于咸虾米接口的前台开发
- 四、项目进阶:自建后端与若依框架集成
- 五、AI 在开发中的应用
- 六、Uniapp 项目开发详解
- 七、项目部署与上线
- 八、项目成果与收获总结
一、学习背景
一年前,姐夫的一位朋友想找我帮忙做个小程序,那时我还是一名只会写 Java 后端的开发,对前端和小程序几乎一窍不通,一个人实在扛不下整个项目,这事只好不了了之。
一年后,我觉得是时候把前端的短板补上了,于是从 HTML、CSS、JavaScript 开始系统学习,又陆续接触了 Ajax、TypeScript、Vue2 和 Vue3。有了一定 Vue 基础后,我开始考虑做小程序,经过了解发现 Uniapp 非常契合我的情况:多端适配、条件编译、支持 Vue 语法,简直就是为我量身定做的方案。
说干就干,我在网上找了两个 Uniapp 课程,收获最大的就是 B 站 UP 主咸虾米的实战教程。跟着敲完代码,我对 Uniapp 的整体开发流程心里有了底。接着,基于自己 Java 后端的优势,我重写了所有接口,并结合若依框架搭建了管理后台,自己开发页面、对接接口。后来为了真正让项目上线,又买了域名、租了服务器,进行小程序和域名 ICP 认证的流程(目前小程序已认证通过,域名备案进行中)。
这一趟下来,从后端到前端,从开发到部署,真真切切地走了一遍全栈流程,对项目开发的认识深了不少,所以想用这篇博客把这段经历和踩过的坑记录下来。
二、学习过程与前期准备
1、跟着B站UP主-咸虾米入门,其余自己摸索
- B站UP主-咸虾米:新课uniapp零基础入门到项目打包(微信小程序/H5/vue/安卓apk)全掌握
- B站UP主-咸虾米:零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战……
总结:通过上面两个课程,我们基本可以了解uniapp如何开发微信小程序项目了
2、即时设计的使用(画原型/UI)
2.1、官网
即时设计官网:https://js.design
2.2、设计图为什么需要设置成750px
注意:Uniapp 默认以 750rpx 为屏幕宽度,设计稿通常也是 750px,所以 100vw 等价于 750px,这是 uniapp 推荐的适配基准。因此代码开发中我们不使用px,而是使用vw,所以设计图需要调整为750px。
2.3、如何将设计图设置成750px
将图片拖进即时设计编辑页面,选中图片,点击上面的等比缩放按钮:

将宽度调整为750px,然后点击退出等比缩放按钮,其他图片按照这种方式依次调节即可。

三、项目初期:基于咸虾米接口的前台开发
1、微信申请个人小程序
1.1、注册微信小程序(已注册可跳过)
访问微信公众平台官网,点击右上角立即注册按钮,根据要求完成注册

1.2、登录微信公众平台
访问微信公众平台官网,微信扫码登录即可

1.3、补充小程序信息
注意:小程序信息和小程序类目根据提示补充即可。小程序备案需要政府部门审核,时间上会慢一些(比如我审批用了10天)。微信认证需要等待程序写好后在认证(个人认证收费30元,不认证影响分享功能,甚至连开发环境的都会影响,比如分享到朋友圈和好友)
1.4、配置开发管理
主要是配置服务器域名,其中request域名是发送普通请求用的,然后downloadFile合法域名是下载文件用的,当然还有其他域名类型,按需填写即可,避免无法发送请求

1.5、查找AppID(小程序ID)
该ID在开发过程中会使用到

2、使用UP主提供的接口完成前台功能
- 项目视频:零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战……
- 项目API地址: 咸虾米壁纸API
- 项目接口Token续期方法:获取access-key秘钥
- 项目资料+代码网址:源码开源地址
四、项目进阶:自建后端与若依框架集成
1、为什么需要自己写接口
- 使用受限:使用作者的接口虽好,但是某一天作者接口无法使用了,我的程序就废了
- 需要扩展:作者是开发的引路人,我不能仅仅站在他的肩膀上看世界,有些功能需要自己开发,比如我在基础上开发了微信登录、邮箱登录等功能,让这个小程序更加像那回事
2、引入若依作为后台管理系统
上面目录提到了自己写接口的原因,那写接口必然需要后端代码。作为一个java后端程序员,我就在若依的基础上进行二次开发,从而将作者的接口变成我自己的接口,其中接口返回值基本按照作者的来,避免产生大的改动

3、数据库与接口设计简表
3.1、新增壁纸表:xianxiami_wallpaper
CREATE TABLE `xianxiami_wallpaper` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`classid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '所属分类classid(关联classify.classid)',
`description` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '描述',
`small_picurl` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '小图',
`big_picurl` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '大图/原图',
`tabs` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '标签,JSON数组字符串',
`score` decimal(2, 1) NULL DEFAULT 5.0 COMMENT '评分(支持小数,如4.5)',
`nickname` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '发布者昵称',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建者',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新者',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_classid`(`classid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 329 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '壁纸' ROW_FORMAT = Dynamic;
3.2、新增壁纸评分表:xianxiami_wallpaper_score
CREATE TABLE `xianxiami_wallpaper_score` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`wallpaper_id` bigint(20) NOT NULL COMMENT '壁纸ID',
`score` decimal(2, 1) NOT NULL COMMENT '评分(如4.5)',
`user_id` bigint(20) NULL DEFAULT NULL COMMENT '评分用户ID',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '评分时间',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_wallpaper_id`(`wallpaper_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '壁纸评分' ROW_FORMAT = Dynamic;
3.3、新增壁纸下载记录表:xianxiami_wallpaper_download_record
CREATE TABLE `xianxiami_wallpaper_download_record` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`wallpaper_id` bigint(20) NOT NULL COMMENT '壁纸ID',
`user_id` bigint(20) NULL DEFAULT NULL COMMENT '下载用户ID',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '下载时间',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_wallpaper_id`(`wallpaper_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '壁纸下载记录' ROW_FORMAT = Dynamic;
3.4、新增资讯公告表:xianxiami_notice
CREATE TABLE `xianxiami_notice` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '标题',
`author` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '作者',
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '内容(HTML)',
`view_count` int(11) NULL DEFAULT 0 COMMENT '阅读数',
`is_select` tinyint(1) NULL DEFAULT 0 COMMENT '是否推荐(0-否,1-是)',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建者',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新者',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间(作为发布日期)',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '资讯公告' ROW_FORMAT = Dynamic;
3.5、新增壁纸分类表:xianxiami_classify
CREATE TABLE `xianxiami_classify` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '分类名称',
`sort` int(11) NULL DEFAULT 0 COMMENT '排序',
`picurl` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '分类图片',
`is_select` tinyint(1) NULL DEFAULT 1 COMMENT '是否推荐(0-否,1-是)',
`is_show` tinyint(1) NULL DEFAULT 1 COMMENT '是否展示(0-否,1-是)',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建者',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新者',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 19 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '壁纸分类' ROW_FORMAT = Dynamic;
3.6、修改系统用户表(sys_user),新增weixin_openid字段
-- 在 sys_user 表中新增微信 openid 字段,允许为空(因为并非所有用户都通过微信登录)
ALTER TABLE sys_user
ADD COLUMN weixin_openid VARCHAR(64) NULL COMMENT '微信小程序openid';
五、AI 在开发中的应用
关于咸虾米作者写的那些页面,我是自己敲了一遍,但是集成微信一键登录、邮箱登录的前端页面代码和后端代码,我通过AI 辅助来写,然后我进行审校与微调
六、Uniapp 项目开发详解
1、项目创建与基础配置(插件、appid、H5 模式)
1.1、下载HbuilderX
官网下载地址:https://www.dcloud.io/hbuilderx.html
1.2、创建项目

输入项目信息,创建项目:

1.3、安装插件
1.3.1、进入插件市场
官方插件市场网址:https://ext.dcloud.net.cn/
1.3.2、安装插件
首先需要打开HBuilderX,然后找到合适的插件后,点击下载插件并导入HbuilderX,此时会弹出窗口,我们点击打开HBuilderX:
此时HBuilderX中会弹出一个弹窗,需要选择插件安装的项目名称,然后点击确定按钮:

如果后续弹出窗口让你进行合并操作,你直接点击合并即可,HbuilderX会自动处理合并事宜。
1.3.3、卸载插件
当插件安装之后,就会进入uni_modules目录下,找到对应插件目录删除即可

1.4、配合微信开发工具使用
1.4.1、配置微信小程序APPID

1.4.2、让HBuilderX能够调用微信开发者工具
1.4.2.1、下载微信开发者工具
1.4.2.2、在HBuilderX中配置微信开发者工具安装路径
打开配置页面:

将微信开发者工具安装路径配置一下:

1.4.2.3、在HBuilderX中调用微信开发者工具

1.4.3、项目开发调试
如果安装新插件之后,最好手动关闭微信开发者工具,然后在HBuilderX中重新运行微信小程序,这样HbuilderX会自动启动微信开发者工具,避免新代码不生效
1.4.4、清理缓存、授权

1.4.5、发布微信小程序
首先关闭微信小程序开发工具,然后在HBuilderX中执行如下操作:

填写基本信息,然后点击发行按钮:

然后HBuilderX会唤醒微信小程序开发工具,之后点击上传按钮:

填写相关信息后,点击上传按钮即可:

1.5、配合谷歌浏览器使用
1.5.1、运行到谷歌浏览器
1.5.1.1、配置web服务器
将谷歌浏览器的路径配置到下面

1.5.1.2、运行项目到浏览器

1.5.2、打包成H5页面
1.5.2.1、配置Web信息

1.5.2.2、打包

点击发行即可打包

打包结果是web目录(如下图),当然也会在HBuilderX控制台打印出完整路径

2、工程化:Sass 变量、全局 API 封装
2.1、Sass变量
2.1.1、uni.scss(全局sass变量定义入口)
- 定义sass变量:例如
$uni-text-color:#000;//基本色 - 引入其他sass类型文件:
@import '@/common/style/base-style.scss';
2.1.2、定义其他sass类型文件
说明: 文件内容如下,然后在uni.scss中使用@import关键字引入即可(上面已解释,不在赘述)。下面文件中的变量从引入之后也是全局sass变量
/* 文字基本颜色 */
$uni-text-color:#000;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#666;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
// 品牌主体色
$brand-theme-color:#28B389;
// 设置uni-icons标签中的color属性
// 用法:<uni-icons type="search" size="20" color="var(--uni-text-color-grey)"></uni-icons>
:root {
--uni-text-color-grey: #{$uni-text-color-grey};
--brand-theme-color: #{$brand-theme-color}
}
2.1.3、使用sass变量

2.2、全局 API 封装
2.2.1、API定义js文件
import {BASE_URL} from '@/utils/request.js'
// 处理路径的方法
export const getFullImageUrl = (path) => {
if (!path) return ''
if (path.startsWith('http') || path.startsWith('//')) return path
// 确保路径以 / 开头
const normalizedPath = path.startsWith('/') ? path : `/${path}`
return BASE_URL + normalizedPath
}
2.2.2、在main.js中挂载全局API方法
import App from './App'
import { getFullImageUrl } from '@/utils/imageHelper'
// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
// Vue2 挂载全局方法
Vue.prototype.$getFullImageUrl = getFullImageUrl
const app = new Vue({
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
// Vue3 挂载全局方法
app.config.globalProperties.$getFullImageUrl = getFullImageUrl
return {
app
}
}
// #endif
2.2.3、使用全局方法
2.2.3.1、在html中使用
全局API不需要引入,直接使用即可

2.2.3.2、在js脚本中使用(vue3语法)
<script setup>
import {
getCurrentInstance
} from 'vue'
const {
proxy
} = getCurrentInstance()
// 示例
const image = await new Promise((resolve, reject) => {
uni.getImageInfo({
// 使用方法如下
src: proxy.$getFullImageUrl(currentPicture.value.bigPicurl),
success: resolve,
fail: reject
})
})
</script>
3、页面与组件拆分、Pinia 状态管理
3.1、页面与组件拆分
3.1.1、页面
在pages目录下创建vue文件,这些都是做页面用的,和pages.json文件中的页面信息一一对应

3.1.2、组件
在根目录下创建components目录,然后该目录下面创建vue文件,这就是组件

在components目录下创建的组件,如果需要在pages目录下的vue文件中使用,不需要引入,直接使用即可,这是uniapp都处理好的
但是在components目录下创建的组件需要互相引入,不能直接使用,只能通过import方式引入后才能使用组件
3.2、Pinia 状态管理
3.2.1、创建状态信息—js文件
例如存储用户信息的功能,可以创建stores》user.js文件
// stores/user.js
import {
defineStore
} from 'pinia'
import {
setToken,
getToken,
setUserInfo,
getUserInfo,
removeToken,
removeUserInfo
} from '@/utils/storage'
import { getFullImageUrl } from '@/utils/imageHelper.js' // 根据实际路径导入
export const useUserStore = defineStore('user', {
state: () => ({
token: '',
userInfo: null
}),
actions: {
// 初始化:从本地恢复数据
restore() {
this.token = getToken()
this.userInfo = getUserInfo()
},
// 登录成功:保存到 Pinia 和本地
recordToken(token) {
this.token = token
setToken(token)
},
recordUserInfo(userInfo) {
this.userInfo = userInfo
setUserInfo(userInfo)
},
// 退出登录
logout() {
this.token = ''
this.userInfo = null
removeToken()
removeUserInfo()
},
// 更新用户信息(通用方法)
updateUserInfo(updates) {
// 合并更新对象
this.userInfo = {
...this.userInfo,
...updates
}
// 同步到本地存储
setUserInfo(this.userInfo)
}
},
getters: {
userAvatar() {
if (this.userInfo?.avatar) {
return getFullImageUrl(this.userInfo.avatar)
}
return '/static/images/xxmLogo.png'
}
}
})
3.2.2、在main.js中安装pinia
import App from './App'
import * as Pinia from 'pinia';
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
// 安装pinia
app.use(Pinia.createPinia());
return {
app,
Pinia, // 此处必须将 Pinia 返回
}
}
// #endif
3.2.3、使用pinia
3.2.3.1、在script中使用
import {
useUserStore
} from '@/stores/user'
const userStore = useUserStore()
// 解构pinia变量/方法
const {
userInfo
} = storeToRefs(userStore)
// 通用上传函数:将临时路径上传到服务器
const uploadAvatar = async (tempFilePath) => {
uni.showLoading({ title: '上传中...', mask: true })
try {
const uploadRes = await uni.uploadFile({
url: BASE_URL + '/system/user/profile/avatar',
filePath: tempFilePath,
name: 'avatarfile',
// 使用pinia变量
header: { Authorization: `Bearer ${userStore.token}` }
})
const resData = JSON.parse(uploadRes.data)
if (resData.code === 200) {
// 使用pinia方法
userStore.updateUserInfo({ avatar: resData.imgUrl })
uni.showToast({ title: '头像更新成功', icon: 'success' })
} else {
throw new Error(resData.msg || '上传失败')
}
} catch (err) {
console.error(err)
uni.showToast({ title: '头像上传失败', icon: 'none' })
} finally {
uni.hideLoading()
}
}
3.2.3.2、在html中使用
<template>
<view class="profile-edit">
<!-- 头像区域 -->
<view class="avatar-wrapper">
<!-- 使用pinia状态 -->
<image class="avatar" :src="userStore.userAvatar" mode="aspectFill" />
<!-- #ifdef MP-WEIXIN -->
<button class="avatar-btn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar" />
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<button class="avatar-btn" @click="chooseImageH5">选择头像</button>
<!-- #endif -->
</view>
4、生命周期与 Vue 相关 API 的统一引入
使用unplugin-auto-import插件,解决引入 ref、reactive、onLoad、onShow 这些 API的问题,请看博客
5、开发中遇到的坑与解决(样式不生效、真机调试差异等)
一般关闭微信小程序开发工具,重启服务即可解决问题
6、其他知识点
6.1、生命周期
官方网址:页面生命周期,uniapp的生命周期不同于Vue的生命周期,uniapp常用生命周期钩子如下:
- onLoad:比较适合的操作是:接受上页的参数,联网取数据,更新data。
- onUnload:监听页面卸载
- onShow和onHide:注意页面显示,是一个会重复触发的事件。进入页面触发当前页面的onShow生命周期,离开页面触发当前页面的onHide生命周期
- onReachBottom:比如设为50,那么滚动页面到距离底部50px时,就会触发onReachBottom事件。可在pages.json里定义具体页面底部的触发距离onReachBottomDistance,默认值是50px
- onPageScroll:监听滚动事件
- onPullDownRefresh:监听用户下拉动作,一般用于下拉刷新
- onShareAppMessage:用户点击右上角分享
- onShareTimeline:监听用户点击右上角转发到朋友圈
6.2、html标签
在uniapp中,已经不在使用传统的html标签,只能使用uniapp自定义的标签,其实就是uniapp自定义的组件
6.3、API
- 网络请求:不在使用axios,而是使用它自定义的api,点我查看文档
6.4、编译器(条件编译)
uniapp是一套代码,每一种情况都能使用,虽然uniapp官方已经进行了大部分兼容工作,但是肯定不可能做完,如果我们想让不同的小程序展示不同的效果,那就需要使用条件编译,点我查看官方文档
6.5、相关网址
- 教程:uniapp的介绍信息、使用信息、相关用法,也包括vue在unaipp中的用法、条件编译等
- 全局文件:包括pages.json(页面信息)、manifest.json(小程序、网页等配置信息)、vite.config.js等内容讲解
- 组件:相当于html中的标签
- API:uniapp内置的api方法
- 插件:需要啥插件直接去插件市场搜索即可,不过需要注意适配的vue版本,以及最近更新时间,避免出现没人维护的情况
七、项目部署与上线
1、域名申请与备案、微信小程序认证
1.1、域名申请与备案
- 域名申请:可以在腾讯云或者阿里云等网址购买域名,比如我是在腾讯云买的,首年免费,2年起购
- 域名备案:通过域名访问到服务器,需要进行ICP备案才行,我是通过阿里云进行的ICP备案,点击我官网
1.2、微信小程序认证
针对个人用户来说,需要支付30元进行微信小程序认证,否则不能上线,但是企业用户的还不知道啥情况。这一步最好放到网站域名可用,服务开发完成时在进行微信小程序认证,不然小程序都不能使用,那认证也没法通过
2、服务器环境搭建(MySQL、Redis、Nginx)
2.1、MySQL
2.1.1、拉取镜像
docker pull mysql5.7
2.1.2、创建目录
mkdir -p /data/docker-volumes/mysql/{log,data,conf}
2.1.3、创建配置文件
进入/data/docker-volumes/mysql/conf,执行vim my.cnf,将以下内容复制到文件中,然后保存即可。其中cnf文件名称无所谓,其中容器会加载并引入 /etc/mysql/conf.d/ 目录下所有以 .cnf 结尾的文件
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
# 字符集设置
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
# 连接初始化设置
init_connect='SET NAMES utf8mb4'
init_connect='SET collation_connection = utf8mb4_unicode_ci'
# 跳过客户端字符集协商(强制使用服务器端设置)
skip-character-set-client-handshake
# 禁用 DNS 反向解析(加速连接,避免 DNS 问题)
skip-name-resolve
# 解决时区问题
default-time-zone = '+08:00'
2.1.4、启动容器
docker run -d --name mysql5.7 -p 13306:3306 --privileged=true --restart=always \
-v /data/docker-volumes/mysql/log:/var/log/mysql \
-v /data/docker-volumes/mysql/data:/var/lib/mysql \
-v /data/docker-volumes/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
2.2、Redis
2.2.1、拉取镜像
docker pull redis:6.0.8
2.1.2、创建目录
mkdir -p /data/docker-volumes/redis/{data,conf}
2.1.3、创建配置文件
进入/data/docker-volumes/redis/conf,执行vim redis.conf,将以下内容复制到文件中,然后保存即可。
// 将以下链接中的redis.conf文件复制到conf目录下
链接:https://pan.baidu.com/s/1OLPyYh0NcwmXlHIKhFr3dQ?pwd=oq8y
更改参数说明:1、开启密码验证,搜索“requirepass”可见;2、注释“bind 127.0.0.1”,允许外部连接;3、设置“daemonize no”,避免和docker run中-d参数冲突,导致容器启动失败;4、设置“appendonly yes ”,开启容器持久化
2.2.4、启动容器
docker run -d -p 16379:6379 --privileged=true \
--name="redis6.0.8" --restart=always \
-v /data/docker-volumes/redis/conf/redis.conf:/etc/redis/redis.conf \
-v /data/docker-volumes/redis/data:/data redis:6.0.8 \
redis-server /etc/redis/redis.conf
2.3、Nginx
2.3.1、拉取镜像
docker pull nginx:alpine
2.3.2、创建目录
mkdir -p /data/docker-volumes/nginx/{html,conf,ssl-cert}
2.3.3、创建配置文件—default.conf
进入目录/data/docker-volumes/nginx/conf,执行vim default.conf,将以下内容赋值进去,根据你的来改哈,这是我的配置。
说一下哈,conf目录下以conf结尾的文件都会被根配置文件自动引入,所以我们自定义的配置文件里面只需要添加server配置即可。
# 处理 HTTP 访问:
# 1. 访问 http://www.eastmoonlight.com → 301 重定向到 HTTPS 版本
# 2. 访问 http://eastmoonlight.com → 也重定向到 https://www.eastmoonlight.com(避免证书错误)
server {
listen 80 default_server;
client_max_body_size 20M;
server_name www.eastmoonlight.com;
return 301 https://www.eastmoonlight.com$request_uri;
}
# HTTPS 核心配置(只针对 www.eastmoonlight.com)
server {
listen 443 ssl http2;
client_max_body_size 20M;
server_name www.eastmoonlight.com; # 只能写这一个域名
# SSL 证书路径(替换成你实际的文件名)
ssl_certificate /etc/nginx/ssl/www.eastmoonlight.com.pem;
ssl_certificate_key /etc/nginx/ssl/www.eastmoonlight.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_prefer_server_ciphers on;
# ----- 以下是你原有的网站配置,保持不变 -----
# 全局根目录
root /usr/share/nginx/html;
# 重定向到项目
location / {
return 301 /xxm-h5/;
}
# 处理前端路由(SPA)
location /xxm-admin/ {
try_files $uri $uri/ /xxm-admin/index.html;
}
location /xxm-h5/ {
try_files $uri $uri/ /xxm-h5/index.html;
}
# 静态资源(带扩展名)直接返回,不经过前端路由
location ~* ^/(xxm-admin|xxm-h5)/.*\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
# 后端 API 代理
location /xxm-api/ {
proxy_pass http://172.17.0.1:18080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
2.3.4、配置ssl证书
2.3.4.1、证书作用
如果不申请证书,域名前面就没法使用https协议,这样微信小程序中的图片就没法展示了(微信要求图片的链接必须是https协议)
2.3.4.2、申请ssl配置文件
对于个人网站来说,可以申请测试证书即可,阿里云每年提供20次ssl证书申请机会,每次申请的证书有效期是90天。点我去申请证书 阿里云官网网址,需要进行一次认证,一般都是配合申请域名的平台添加一个解析链接就可以认证了
2.3.4.3、下载证书
当验证完成后,就可以下载证书了

当证书下载完成后,里面有两个文件

2.3.4.4、安装证书
进入目录/data/docker-volumes/nginx/ssl-cert,将上面两个配置文件复制到上述目录
2.3.5、启动容器
docker run -d --name nginx -p 80:80 -p 443:443 \
-v /data/docker-volumes/nginx/conf:/etc/nginx/conf.d \
-v /data/docker-volumes/nginx/html:/usr/share/nginx/html \
-v /data/docker-volumes/nginx/ssl-cert:/etc/nginx/ssl:ro nginx:alpine
3、前后端服务部署
3.1、部署后端服务
3.1.1、放置jar包
创建目录/home/xxm-wallpaper/backend,然后将jar包复制到该目录下

3.1.2、创建启动配置文件
进入目录/etc/systemd/system,创建文件xxm-backend.service,将以下内容复制进去
[Unit]
Description=XXM Wallpaper Backend
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/home/xxm-wallpaper/backend
ExecStart=/usr/bin/java -jar /home/xxm-wallpaper/backend/ruoyi-admin.jar --spring.profiles.active=prod -Duser.timezone=Asia/Shanghai
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
3.1.3、启动服务
# 重新加载 systemd 配置
sudo systemctl daemon-reload
# 启动服务
sudo systemctl start xxm-backend
# 查看状态
sudo systemctl status xxm-backend
# 设置开机自启
sudo systemctl enable xxm-backend
3.1.4、日常维护命令
systemctl stop ruoyi # 停止
systemctl restart ruoyi # 重启
journalctl -u ruoyi -f # 实时查看日志
3.2、部署前端服务
3.2.1、上传压缩包并解压
将打包完成的结果,直接上传到nginx外挂的html目录下

3.2.2、前端配置:网页访问前缀
3.2.2.1、uniapp项目

3.2.2.2、普通vue3项目
vite配置文件:

路由配置:

3.2.3、前端配置:访问后端地址
3.2.3.1、uniapp项目
可以在本地使用,也向外暴露了,哪个地方需要哪里引入即可,一处更改,处处生效

3.2.3.2、普通vue3项目
.env.production配置:

request.js配置:

这样配置之后,前端会自动使用域名+/xxm-api去访问后端接口,当然我已经在nginx配置文件中声明好了,系统会自动将请求转到后端服务
3.2.4、后端配置:接口访问前缀
配置成/即可,我已经在nginx中配置好了,系统会自动将/xxm-api前缀的请求转发到后端服务中
八、项目成果与收获总结
1、管理后台

2、H5端

3、小程序端
微信小程序名称: 月色东升壁纸

更多推荐

所有评论(0)