小程序稻草人图床神器,前后端开源

本文介绍了稻草人图床神器,这是一款结合小程序和JAVA后端的开源项目。小程序部分涉及网络状态判断、授权、页面跳转和文件上传等功能,后端采用Spring Boot,实现微信登录、JWT授权、七牛云文件上传等。项目还涵盖了数据库设计、代码详解,包括七牛云文件操作、接口限流、Docker部署和Nginx的HTTPS配置。
摘要由CSDN通过智能技术生成

稻草人图床神器

项目服务器到期,所以线上无法使用小程序

源码地址:

小程序源码 https://github.com/w77996/mini-straw  
后台源码 https://github.com/w77996/hi-straw  

体验一下

image

之前乘着换工作的间隙撸的,一方面练习一下小程序,学过之后没怎么应用,一方面写点笔记啥的,项目断断续续做了两个月,只是一个简单的图片上传工具,觉得不错的话记得给个star

小程序

  1. 小程序授权,登录
  2. 父组件与子组件相互通信
  3. 小程序分享,意见与建议,客服功能,文件上传
  4. flex布局的使用
  5. Promise的使用,业务model封装
  6. 插槽的使用,动画效果

项目目录结构

mini-straw
    ├── component -- 组件
    |    ├── file -- 文件组件
    |    ├── image-button -- 图片按钮组件
    |    ├── search -- 查找页面组件
    |    ├── tag -- 标签组件
    ├── images -- 图片目录
    |    ├── icon -- icon图片
    |    ├── tab -- tab图片
    ├── model -- 封装的model
    ├── pages -- 页面
    |    ├── about -- 关于页
    |    ├── auth -- 授权页
    |    ├── file -- 文件页
    |    ├── index -- 首页
    |    ├── launch -- 启动页面
    |    ├── my -- 个人中心
    └── utils -- 工具

小程序文档

后台:

技术栈:spring boot + druid + mybatis + jwt

  1. 微信登录,jwt授权
  2. 注解及AOP的使用
  3. maven多环境打包,docker使用
  4. shell脚本自动化部署
  5. nginx反向代理及https配置
  6. 七牛云文件操作

项目目录结构

hi-straw
├── common -- 公共模块
├── config -- 配置模块
├── controller -- controller接口
├── core -- 核心业务模块
|    ├── annontaion -- 注解
|    ├── aop -- aop实现
|    ├── constant -- 常量
|    ├── filter -- 拦截器
|    ├── jwt -- jwt相关
|    └── result -- 结果返回
├── entity -- 实体类
|    ├── dto -- 数据传输
|    └── vo -- 页面传输
├── exception -- 全局异常
├── mapper -- dao层
├── service -- service层
└── util -- 工具类

后台文档

小程序详解


mini-straw

项目结构

mini-straw
    ├── component -- 组件
    |    ├── file -- 文件组件
    |    ├── image-button -- 图片按钮组件
    |    ├── search -- 查找页面组件
    |    ├── tag -- 标签组件
    ├── images -- 图片目录
    |    ├── icon -- icon图片
    |    ├── tab -- tab图片
    ├── model -- 封装的model
    ├── pages -- 页面
    |    ├── about -- 关于页
    |    ├── auth -- 授权页
    |    ├── file -- 文件页
    |    ├── index -- 首页
    |    ├── launch -- 启动页面
    |    ├── my -- 个人中心
    └── utils -- 工具

开屏页

1.判断网络状态

使用wx.getNetworkType({})可获取当前网络状态,networkTypewifi/2g/3g/4g/unknown(Android下不常见的网络类型)/none(无网络)

 //判断网络状态
wx.getNetworkType({
    success: res => {
    if (res.networkType == "none") {
        wx.showToast({
            title: '嗷~~网络不可用',
            icon: 'none',
            duration: 2000
        })
        return;
    }
    },
})

2.判断授权状态

使用wx.getSetting({})获取授权状态,在获得data后取data.authSetting['scope.userInfo']判断授权状态

 // 获取授权的状态
wx.getSetting({
    success: data => {
    if (data.authSetting['scope.userInfo']) {
        //已授权,执行登陆
        wx.getUserInfo({
            success: data => {
                    console.log("userInfo {}", data)
                    let userInfo = data.userInfo;
                    wx.setStorageSync('userInfo', userInfo);
                    //执行登陆操作
                    this._userLoginGetCode(userInfo);
            }
        });
        wx.setStorageSync('authorized', true);
    } else {
        console.log("未授权")
        //跳转至授权页
        let timer = setTimeout(() => {
                wx.redirectTo({
                        url: '/pages/auth/auth'
                })
        }, 2000)

    }
    }
});

若授权,则调用wx.getUserInfo({})获取微信用户信息,信息获取完成后调用wx.login({})获取小程序的code,通过code向后台获取用户openId及token。

//后台获取code
_userLoginGetCode(userInfo) {
    console.log("发起_userLoginGetCode请求");
    wx.login({
        success(res) {
        console.log("wx.login {}", res);
        if (res.code) {
            // 发起网络请求
            const code = res.code;
            userInfo.code = code;
            userModel.getTokenByCode(userInfo).then((res) => {
                console.log("userModel getUserInfo {}", res);
                wx.setStorageSync("token", res.data.data.token);
                let timer = setTimeout(() =>
                    wx.switchTab({
                            url: '/pages/index/index',
                    }), 2000)
            });
        } else {
                console.log('登录失败!' + res.errMsg)
        }
        }
    })
},

3.跳转页面

  • 跳转/pages/auth/auth页面使用的是wx.redirectTo({})
  • 跳转/pages/index/index页面使用的是wx.switchTab({})
    因为/pages/index/index是小程序tab页,使用wx.redirectTo({})无法跳转

授权页

授权需制定button按钮,加入open-type='getUserInfo'属性,bindgetuserinfo调用自定义方法onGetUserInfo

 <button class="auth-button" open-type='getUserInfo' bindgetuserinfo="onGetUserInfo">好的</button>

onGetUserInfo接受授权状态及授权获取的用户信息,再进行code获取,通过code向后台获取用户openId及token。

onGetUserInfo: function(e) {
    console.log(e)
    const userInfo = e.detail.userInfo;
    if (userInfo) {
            //通过`code`向后台获取用户openId及token。
            this._userLoginGetCode(userInfo);
    }
},

主页

1. 图片按钮插槽组件

component目录下的images-button组件,做了简单的图片插槽统一,在分享按钮,用户登录按钮,文件上传按钮均可以使用。plain="{ {true}}"代表button背景透明

<button  open-type="{
  {openType}}" plain="{
  {true}}" class="container">
  <slot name="img"></slot>
</button>

options需要开启插槽功能,添加multipleSlots: true
open-type="{ {openType}}"父组件将参数传入子组件,子组件在properties属性中可以获取到父组件传来的openType数据,通过this.properties.openType可以获取属性值

options: {
    // 开启插槽
    multipleSlots: true
  },
/**
   * 组件的属性列表
   */
  properties: {
    openType: {
      type: String
    }
  },

index页面引入组件,需要在index.json中添加组件路径

{
  "usingComponents": {
    "btn-cmp": "/component/image-button/index"
  }
}

2. 上传文件

主要使用到wx.chooseImage({})进行图片的选择,选择后使用wx.uploadFile({})上传图片至服务器

//上传文件
onUpload(event) {
let _this = this;
wx.chooseImage({
  count: 1, // 默认9
  sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
  sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
  success: function(res) {
    // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
    let tempFilePaths = res.tempFilePaths;
    console.log(tempFilePaths)
    wx.uploadFile({
      header: {
        "Authorization": "Bearer " + wx.getStorageSync("token")
      },
      url: config.apiBaseUrl + '/file/upload',
      filePath: tempFilePaths[0],
      name: 'file',
      success: (res) => {
        wx.showToast({
          title: "上传成功~",
          icon: 'none',
          duration: 2000
        })
      },
      fail: (res) => {
        wx.showToast({
          title: res.data.msg,
          icon: 'none',
          duration: 2000
        })
      }
    })

  }
})
}

列表页

1.search组件的显示和隐藏

固定列表页搜索header位置,点击header显示search组件,在search组件点击取消则隐藏search组件,此处设计子组件向父组件传递消息

  • 引入search组件
 "usingComponents": {
    ...
    "search-cmp": "/component/search/index"
  }
  • 使用searchPage参数判断search组件的,默认为false,在点击header时更新searchPage为true,显示search组件
<view wx:if="{
  {!searchPage}}" class="container">
  ...
</view>

<search-cmp  wx:if="{
  {searchPage}}" ></search-cmp>
  • search页面点击取消,向父组件发送一个this.triggerEvent('cancel', {}, {});事件,在xml中的search-cmp添加cancel事件的通知绑定
#file页面中的search-cmp组件
<search-cmp  wx:if="{
  {searchPage}}" bind:cancel="onCancel"></search-cmp>

父组件file页面绑定子组件传来的cancel事件通知,就调用onCancel方法,
onCancel方法中获取事件响应,将searchPage参数修改为false,search组件就隐藏起来了

//cancel searching page 
onCancel(event) {
  console.info(event)
  this.triggerEvent('cancel', {}, {});
 
},

2.文件列表

1.获取列表信息传递给fi
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值