3.1 后端项目搭建
3.1.1 gitee下载脚手架
下载地址:https://gitee.com/77jubao2015/springbootdemo
打开浏览器输入以上地址,点击下载即可,如图所示:
3.1.2 把脚手架导入到idea开发工具
步骤01 把下载后的脚手架放到指定位置并解压,把解压后的文件夹名称改为pig_feet_rice即可,如图所示:
步骤02 打开IDEA开发选择Open,选择项目存放的路径,然后点击OK即可,如图所示:
步骤03 修改项目的名称为pig_feet_rice,如图所示:
步骤04 修改pom.xml文件
主要修改项目名称、Spring Boot版本号、JDK版本号等信息,代码如下所示:
<?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.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.xueden</groupId>
<artifactId>pig_feet_rice</artifactId>
<version>1.0.0</version>
<name>pig_feet_rice</name>
<description>springboot+Vue3 整合开发猪脚饭微信小程序</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Mysql依赖包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<!-- druid数据源驱动 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
<!--监控sql日志-->
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
<version>1.16</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.6.5</version>
</dependency>
</dependencies>
<build>
<finalName>xuedenpay1.0</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.4.5</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.1.3 修改配置文件application.yml
这里我们主要是修改数据源即可,如图所示:
代码如下所示:
server:
port: 8081
#配置数据源
spring:
datasource:
druid:
db-type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
url: jdbc:log4jdbc:mysql://127.0.0.1:3306/pig_feet_rice?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
username: root
password: root
# 初始化配置
initial-size: 3
# 最小连接数
min-idle: 3
# 最大连接数
max-active: 15
# 获取连接超时时间
max-wait: 5000
# 连接有效性检测时间
time-between-eviction-runs-millis: 90000
# 最大空闲时间
min-evictable-idle-time-millis: 1800000
test-while-idle: true
test-on-borrow: false
test-on-return: false
validation-query: select 1
# 配置监控统计拦截的filters
filters: stat
stat-view-servlet:
url-pattern: /druid/*
reset-enable: false
web-stat-filter:
url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
#配置jpa
jpa:
hibernate:
# 生产环境设置成 none,避免程序运行时自动更新数据库结构
ddl-auto: update
修改为自己本地电脑的数据库即可
3.1.4 修改启动类为PigFeetRiceApplication
如图所示:
3.2 前端项目搭建
3.2.1 从gitee下载前端demo
地址:https://gitee.com/77jubao2015/wxpaydemo
再浏览器打开上面的地址,点击下载即可,如图所示:
3.2.2 把项目导入到webstorm开发工具
步骤01 下载后直接解压,并把项目名称改为pig_feet_rice_web,如图所示:
步骤02 打开WebStorm 选择open,然后选择指定的项目即可,如图所示:
步骤03 修改标题
在src->store->modules->app.tsw文件下修改标题,如图所示:
改为如下所示:
3.2.3 在终端输入命令yarn install安装依赖
yarn install
如图所示
3.2.4 启动项目
选择左边npm,如图所示:
点击serve即可,如图所示:
3.3 系统后台登录功能实现
3.3.1 创建实体类Admin
在 cn.xueden.domain 包目录下新建一个 Admin实体类,代码如下所示:
package cn.xueden.domain;
import cn.xueden.base.BaseEntity;
import lombok.Data;
import javax.persistence.*;
/**功能描述:系统管理员实体类
* @author 梁志杰
* @Date:2022/5/5
* @Description:cn.xueden
* @version:1.0
*/
@Data
@Entity
@Table(name = "p_sys_admin")
@org.hibernate.annotations.Table(appliesTo = "p_sys_admin",comment="系统管理员信息表")
public class Admin extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Integer id;
@Column(name = "login_name")
private String loginName;
@Column(name = "password", length = 50)
private String password;
@Column(name = "status", nullable = false)
private Integer status;
}
在 cn.xueden.base 包目录下新建一个 BaseEntity实体类,代码如下所示:
package cn.xueden.base;
import cn.xueden.annotation.EnableXuedenCreateBy;
import cn.xueden.annotation.EnableXuedenUpdateBy;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.sql.Timestamp;
/**功能描述:公共Entity
* @Author:梁志杰
* @Date:2022/4/1
* @Description:cn.xueden.base
* @version:1.0
*/
@Getter
@Setter
@MappedSuperclass
public class BaseEntity implements Serializable {
/**
* 创建时间
*/
@Column(name = "create_time",nullable = false)
@CreationTimestamp
private Timestamp createTime;
/**
* 创建者ID
*/
@Column(name = "create_by")
@EnableXuedenCreateBy
private Long createBy;
/**
* 更新时间
*/
@Column(name = "update_time")
@UpdateTimestamp
private Timestamp updateTime;
/**
* 更新者ID
*/
@Column(name = "update_by")
@EnableXuedenUpdateBy
private Long updateBy;
/**
* 备注
*/
@Column(name = "remarks")
private String remarks;
public @interface Update {}
@Override
public String toString() {
ToStringBuilder builder = new ToStringBuilder(this);
Field[] fields = this.getClass().getDeclaredFields();
try {
for (Field f : fields) {
f.setAccessible(true);
builder.append(f.getName(), f.get(this)).append("\n");
}
} catch (Exception e) {
builder.append("toString builder encounter an error");
}
return builder.toString();
}
}
3.3.2 创建持久层接口AdminRepository
在 cn.xueden.repository 包目录下新建一个 AdminRepository接口,代码如下所示:
package cn.xueden.repository;
import cn.xueden.domain.Admin;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**系统管理员信息持久层
* @author 梁志杰
* @Date:2022/5/5
* @Description:cn.xueden.repository
* @version:1.0
*/
public interface AdminRepository extends JpaRepository<Admin, Long>, JpaSpecificationExecutor<Admin> {
}
3.3.3 创建业务接口IAdminService
在 cn.xueden.service包目录下新建一个 IAdminService接口,代码如下所示:
package cn.xueden.service;
/**功能描述:系统管理员业务接口
* @author:梁志杰
* @date:2022/5/5
* @description:cn.xueden.service
* @version:1.0
*/
public interface IAdminService {
}
3.3.4 创建业务接口实现类AdminServiceImpl
在 cn.xueden.service.impl包目录下新建一个 AdminServiceImpl接口实现类,代码如下所示:
package cn.xueden.service.impl;
import cn.xueden.repository.AdminRepository;
import cn.xueden.service.IAdminService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**功能描述:系统管理员业务接口实现类
* @author:梁志杰
* @date:2022/5/5
* @description:cn.xueden.service.impl
* @version:1.0
*/
@Service
@Transactional(readOnly = true)
public class AdminServiceImpl implements IAdminService {
private final AdminRepository adminRepository;
public AdminServiceImpl(AdminRepository adminRepository) {
this.adminRepository = adminRepository;
}
}
3.3.5 创建登录前端控制器LoginController
在一个名为controller的包新建一个LoginController类,代码如下所示:
package cn.xueden.controller;
import cn.xueden.service.IAdminService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**功能描述:系统后台登录前端控制器
* @author:梁志杰
* @date:2022/5/5
* @description:cn.xueden.controller
* @version:1.0
*/
@RestController
@RequestMapping("login")
public class LoginController {
private final IAdminService adminService;
public LoginController(IAdminService adminService) {
this.adminService = adminService;
}
}
3.3.6 新建一个登陆方法login
在LoginController类下新增一个登陆方法,代码如下所示:
/**
* 登录方法
* @param admin
* @return
*/
@PostMapping
public BaseResult login(@RequestBody Admin admin,HttpServletRequest request){
Admin dbAdmin = adminService.login(admin);
if(dbAdmin==null){
return BaseResult.fail("登录失败,账号不存在");
}else if(!dbAdmin.getPassword().equals(admin.getPassword())){
return BaseResult.fail("登录失败,密码不正确");
}else if(dbAdmin.getStatus()==0){
return BaseResult.fail("登录失败,账号被封禁");
}
// 生成token
String token = HutoolJWTUtil.createToken(dbAdmin);
request.getServletContext().setAttribute("token",token);
return BaseResult.success("登录成功",token);
}
3.3.7 在IAdminService接口下新增一个登陆方法login
代码如下所示:
/**
* 登录
* @param admin
* @return
*/
Admin login(Admin admin);
3.3.8 在AdminServiceImpl实现类下新建一个login方法
代码如下所示:
/**
* 登录
* @param admin
* @return
*/
@Override
public Admin login(Admin admin) {
Admin dbAdmin = adminRepository.findByLoginName(admin.getLoginName());
return dbAdmin;
}
3.3.9 在AdminRepository接口下新建一个findByLoginName方法
代码如下所示:
/**
* 根据登录名查找管理员信息
* @param loginName
* @return
*/
Admin findByLoginName(String loginName);
3.3.10 新建一个JWT工具类HutoolJWTUtil
代码如下所示:
package cn.xueden.utils;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.JWTValidator;
import cn.xueden.domain.Admin;
import java.util.HashMap;
import java.util.Map;
/**
* @author:梁志杰
* @date:2022/5/6
* @description:cn.xueden.utils
* @version:1.0
*/
public class HutoolJWTUtil {
/**
* 生成token
* @param admin
* @return
*/
public static String createToken(Admin admin){
DateTime now = DateTime.now();
DateTime newTime = now.offsetNew(DateField.MINUTE, 120);
Map<String,Object> payload = new HashMap<String,Object>();
//签发时间
payload.put(JWTPayload.ISSUED_AT, now);
//过期时间
payload.put(JWTPayload.EXPIRES_AT, newTime);
//生效时间
payload.put(JWTPayload.NOT_BEFORE, now);
//载荷
payload.put("loginName", admin.getLoginName());
payload.put("aid", admin.getId());
String key = "www.xueden.cn";
String token = JWTUtil.createToken(payload, key.getBytes());
return token;
}
/**
* 校验token
* @param token
* @return
*/
public static boolean JwtVerify(String token){
String key = "www.xueden.cn";
JWT jwt = JWTUtil.parseToken(token);
boolean verifyKey = jwt.setKey(key.getBytes()).verify();
System.out.println(verifyKey);
boolean verifyTime = jwt.validate(0);
System.out.println(verifyTime);
if(verifyKey&&verifyTime){
return true;
}
return false;
}
/**
* 解析token
* @param token
* @return
*/
public static Long parseToken(String token){
final JWT jwt = JWTUtil.parseToken(token);
return Long.parseLong(jwt.getPayload("aid").toString());
}
}
3.3.11 修改login目录下的index.vue文件
如图所示:
代码如下所示:
<template>
<div class="login-wrap" @keydown.enter="login">
<div class="login-con">
<el-card class="box-card">
<template #header>
<span class="login--header">登录</span>
</template>
<el-form
ref="loginForm"
:model="form"
:rules="rules"
class="login-form"
>
<el-form-item prop="loginName">
<el-input
v-model="form.loginName"
placeholder="请输入账号"
class="form--input"
>
<template #prefix>
<span class="svg-container">
<svg-icon icon-class="user" />
</span>
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="form.password"
show-password
:minlength="3"
:maxlength="18"
placeholder="请输入密码"
class="form--input"
>
<template #prefix>
<span class="svg-container">
<svg-icon icon-class="password" />
</span>
</template>
</el-input>
</el-form-item>
<el-form-item>
<el-button
:loading="loading"
type="primary"
class="login--button"
@click="login"
>
登录
</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, unref, reactive, watch } from 'vue'
import { useRouter } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'
import { permissionStore } from '@/store/modules/permission'
import { appStore } from '@/store/modules/app'
import wsCache from '@/cache'
import { ElNotification } from 'element-plus'
import { loginApi } from './api'
import { Message } from '_c/Message'
interface FormModule {
loginName: string,
password: string
}
interface RulesModule {
loginName: any[],
password: any[]
}
export default defineComponent({
name: 'Login',
setup() {
const { push, addRoute, currentRoute } = useRouter()
const loginForm = ref<HTMLElement | null>(null)
const loading = ref<boolean>(false)
const redirect = ref<string>('')
watch(() => {
return currentRoute.value
}, (route) => {
redirect.value = (route.query && route.query.redirect) as string
}, {
immediate: true
})
const form = reactive<FormModule>({
loginName: '',
password: ''
})
const rules = reactive<RulesModule>({
loginName: [{ required: true, message: '请输入账号' }],
password: [{ required: true, message: '请输入密码' }]
})
async function login(): Promise<void> {
const formWrap = unref(loginForm) as any
if (!formWrap) return
loading.value = true
try {
formWrap.validate(async(valid: boolean) => {
if (valid) {
const formData = unref(form)
const res = await loginApi({
data: formData
})
if (res.status !== 200) {
Message.error(res.message)
return false
}
wsCache.set(appStore.userInfo, form)
permissionStore.GenerateRoutes().then(() => {
permissionStore.addRouters.forEach(async(route: RouteRecordRaw) => {
await addRoute(route.name!, route) // 动态添加可访问路由表
})
permissionStore.SetIsAddRouters(true)
push({ path: redirect.value || '/' })
})
} else {
console.log('error submit!!')
return false
}
})
} catch (err) {
console.log(err)
} finally {
loading.value = false
}
}
return {
loginForm,
loading, redirect, form, rules,
login
}
}
})
</script>
<style lang="less" scoped>
.login-wrap {
width: 100%;
height: 100%;
background-image: url('~@/assets/img/login-bg.jpg');
background-size: cover;
background-position: center;
position: relative;
.box-card {
width: 400px;
.login--header {
font-size: 24px;
font-weight: 600;
}
.svg-container {
color: #889aa4;
vertical-align: middle;
width: 30px;
display: inline-block;
}
.form--input {
width: 100%;
@{deep}(.el-input__inner) {
padding-left: 40px;
}
}
.login--button {
width: 100%;
}
}
.login-con {
position: absolute;
right: 160px;
top: 50%;
transform: translateY(-60%);
}
}
</style>
3.3.12 在login目录下新建一个api.ts文件
如图所示:
代码如下所示:
import { fetch } from '@/axios-config/axios'
// 参数接口
interface PropsData {
params?: any,
data?: any
}
// 提交表单接口函数
export const loginApi = ({ data }: PropsData): any => {
return fetch({ url: 'login', method: 'post', data })
}
3.3.13 修改UserInfo目录下的index.vue文件
如图所示:
代码如下所示:
<template>
<el-dropdown class="avatar-container" trigger="hover">
<div id="user-container">
<div class="avatar-wrapper">
<img src="logo.png" class="user-avatar">
<span class="name-item">{{ userInfo.loginName }}</span>
</div>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item key="1">
<span style="display: block;" @click="toHome">首页</span>
</el-dropdown-item>
<el-dropdown-item key="2">
<span style="display: block;" @click="loginOut">退出登录</span>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<script lang="ts">
import { defineComponent, reactive, computed } from 'vue'
import { resetRouter } from '@/router'
import wsCache from '@/cache'
import { useRouter } from 'vue-router'
import { tagsViewStore } from '@/store/modules/tagsView'
import { appStore } from '@/store/modules/app'
export default defineComponent({
name: 'UserInfo',
setup() {
const { replace, push } = useRouter()
async function loginOut(): Promise<void> {
wsCache.clear()
// wsCache.delete(appStore.userToken)
await resetRouter() // 重置静态路由表
await tagsViewStore.delAllViews() // 删除所有的tags标签页
replace('/login')
}
const userInfo = wsCache.get(appStore.userInfo)
console.info('userInfo:-----------',userInfo)
function toHome() {
push('/')
}
return {
loginOut,
toHome,
userInfo
}
}
})
</script>
<style lang="less" scoped>
.avatar-container {
margin-right: 30px;
padding: 0 10px;
.avatar-wrapper {
display: flex;
align-items: center;
height: 100%;
cursor: pointer;
.user-avatar {
width: 30px;
height: 30px;
border-radius: 10px;
}
.name-item {
font-size: 14px;
font-weight: 600;
display: inline-block;
margin-left: 5px;
}
}
}
</style>
3.3.14 拦截器功能实现
步骤01 新建一个interceptor包,并在此包下自定义拦截器类AdminInterceptor
代码如下所示:
package cn.xueden.interceptor;
import cn.xueden.exception.BadRequestException;
import cn.xueden.utils.HutoolJWTUtil;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
/**拦截器
* @author:梁志杰
* @date:2022/5/6
* @description:cn.xueden.interceptor
* @version:1.0
*/
public class AdminInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Max-Age", "86400");
response.setHeader("Access-Control-Allow-Headers", "*");
if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
System.out.println("OPTIONS请求,放行");
return true;
}
//获取token
String token = request.getHeader("Authorization");
//判断用户是否登录
if (null==token){
throw new BadRequestException(HttpStatus.UNAUTHORIZED,"请先登录");
}
String tokenServletContext = (String)request.getServletContext().getAttribute("token");
// 判断用户登录是否过期
if (null==tokenServletContext){
throw new BadRequestException(HttpStatus.UNAUTHORIZED,"登录已过期,请重新登录");
}
// 校验token
boolean tokenStatus = HutoolJWTUtil.JwtVerify(token);
if(!tokenStatus){
throw new BadRequestException(HttpStatus.UNAUTHORIZED,"登录信息已过期,请重新登录");
}
return true;
}
}
步骤02 修改ConfigurerAdapter配置类,重写addInterceptors方法,代码如下所示:
@Override
public void addInterceptors(InterceptorRegistry registry) {
//addPathPatterns拦截的路径
String[] addPathPatterns = {
"/**"
};
//excludePathPatterns排除的路径
String[] excludePathPatterns = {
"/login","/wxapi/**","/uploadFile/**"
};
//创建用户拦截器对象并指定其拦截的路径和排除的路径
registry.addInterceptor(new AdminInterceptor()).addPathPatterns(addPathPatterns).excludePathPatterns(excludePathPatterns);
}
3.4 微信小程序项目搭建
3.4.1 新建猪脚饭微信小程序项目
步骤01 打开微信开发者工具,选择新建项目,如图所示:
步骤02 依次新建目录images->nav,把相关图片复制到nav目录下,如图所示:
步骤03 在目录images新建一个icon目录,把相关图片复制到此目录,如图所示:
3.4.2 新建一个名为category菜单页
打开app.json文件,在pages属性下添加如下代码即可:
"pages": [
"pages/index/index",
"pages/category/category"
],
3.4.3 新建一个名为index的购物车页面
打开app.json文件,在pages属性下添加如下代码即可:、
"pages": [
"pages/index/index",
"pages/category/category",
"pages/shop-cart/index"
],
3.4.4 新增一个名为index的我的页面
打开app.json文件,在pages属性下添加如下代码即可:
"pages": [
"pages/index/index",
"pages/category/category",
"pages/shop-cart/index",
"pages/my/index"
],
3.4.5 添加tabBar属性
打开app.json文件,添加tabBar属性,同时添加如下代码:
"tabBar": {
"color": "#6e6d6b",
"selectedColor": "#e64340",
"borderStyle": "white",
"backgroundColor": "#f6f0e3",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "images/nav/home-off.png",
"selectedIconPath": "images/nav/home-on.png",
"text": "首页"
},
{
"pagePath": "pages/category/category",
"iconPath": "images/nav/ic_catefory_normal.png",
"selectedIconPath": "images/nav/ic_catefory_pressed.png",
"text": "菜单"
},
{
"pagePath": "pages/shop-cart/index",
"iconPath": "images/nav/cart-off.png",
"selectedIconPath": "images/nav/cart-on.png",
"text": "购物车"
},
{
"pagePath": "pages/my/index",
"iconPath": "images/nav/my-off.png",
"selectedIconPath": "images/nav/my-on.png",
"text": "我的"
}
]
},
3.4.6 编写调用后台接口的工具包
新建一个名为wxapi的目录,并在此目录下新建一个名为main.js的文件,代码如下所示:
const API_BASE_URL = 'http://localhost:8081/wxapi'
const request = (url,method,data) => {
let _url = API_BASE_URL+'/'+url
retrun new Promise((resolve, reject) => {
wx.request({
url: _url,
method: method,
data: data,
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success(res) {
resolve(res.data)
},
fail(error){
reject(error)
},
complete(aaa){
// 加载完成
}
})
})
}
/**
* 小程序的promise没有finally方法,自己扩展下
*/
Promise.prototype.finally = function (callback) {
var Promise = this.constructor;
return this.then(
function (value) {
Promise.resolve(callback()).then(
function () {
return value;
}
);
},
function (reason) {
Promise.resolve(callback()).then(
function () {
throw reason;
}
);
}
);
}
module.exports = {
request
}
3.4.7 在根目录添加一个名为config.js的文件
代码如下所示:
module.exports = {
version: "0.0.1",
note: '图片url',
imgUrl: "http://192.168.0.5:8081/uploadFile"
}
3.4.8 整合weui组件库
开发文档地址:https://wechat-miniprogram.github.io/weui/docs/
步骤01 下载weui组件库,地址是:https://github.com/Tencent/weui-wxss
步骤02 新建一个weui目录,并把下载好的组件解压复制到此目录下,如图所示:
步骤03 修改app.wxss文件,代码如下所示:
@import 'weui/weui.wxss';
.page {
background-color: #f6f0e3;
min-height: 100vh;
box-sizing: border-box;
}
.wxParse-img {
display: block !important;
}
.space {
height:20rpx;
background-color: #F2f2f2;
}