第3章 基础项目的搭建

本文详细介绍了如何搭建基于Java Spring Boot的后端项目,包括从Gitee下载脚手架、配置修改、启动类设置等。接着讲解了前端项目的创建,涉及WebStorm导入、依赖安装及项目启动。最后,阐述了微信小程序的搭建过程,包括新建项目、页面创建、接口调用工具包编写等步骤。
摘要由CSDN通过智能技术生成

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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨鱼老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值