- 申请可以支持上传视频、观看视频、分享视频的小程序具体需要什么资质?
我们是一家在线教育公司,近期考虑想做一个让用户上传自己学习视频的小程序,然后用户可以观看自己上传的视频,也可以分享给别人,总的来说有点像打卡学习记录。这个小程序不打算引进外部视频观看、不引入自己的课程视频,只是单纯地让用户上传自己的视频。请问在申请小程序的时候,属于什么类目? A:属于【教育-在线教育】类,不需要提交审核资质 B:属于【教育-在线视频课程】类,需要三选一资质《事业单位法人证书》、区、县级教育部门颁发的《民办学校办学许可证》、《网络文化经营许可证》(经营范围含网络表演) C:属于【社交-笔记】类,需要资质《非经营性互联网信息服务备案核准》。 我自己查看了一下,可能比较沾边的有以上A/B/C三种类目和对应的资质条件,但是不确定属于哪一种。我个人理解应该可能更偏向于A。因为B的话,我们想做的小程序确实不会引入自己的课程视频,经营范围也没有网络表演。C的话我们并不是社交平台,而是教育平台。 总的来说,申请类目和需要的资质条件不太确定选哪个,请各位大神帮忙回答下
2019-12-19 - 使用 Wux Weapp 快速开发一个小程序 - 01
使用 Wux Weapp 快速开发一个小程序 - 01 Wux Weapp Wux Weapp 是一套组件化、可复用、易扩展的微信小程序 UI 组件库。 特性 UI 样式可配置,拓展灵活,轻松适应不同的设计风格 80+ 丰富的组件,能够满足移动端开发的基本需求 文档链接: https://wux-weapp.github.io/wux-weapp-docs/#/introduce UI 组件库的选择 常见的 UI 组件库少说有10种了吧,如何选择一个适合自己的/团队的组件库呢? 切合项目需求。如果是简单明了的小程序,使用官方组件库就基本能满足基础的界面需求。 扩展性。考虑到业务后期改动,样式界面可能改来改去,一套UI库一般很重,改起来很麻烦。 可复用性。组件就是为了复用的吧,不管自己写组件还是用别人的组件。 文档是否完善,社区是否活跃等等。。。 之前用过官方和 vant ui。之前都是自己写组件,后面开发速度更不上,使用的vant ui,在电商这块vant还是很舒服的。就怕遇到有灵魂的设计师,后期真的是噩梦了,改起来好痛苦。。。 看了各大网站的测评,自己也用了一天体验小程序,最后选择 Wux ,组件很丰富,灵活,也和我即将开始做的需求贴合,开搞 官方文档 官方文档用 docsify 构建,部署在github,访问速度感人,让人有放弃的冲动。 搬梯子看有的不方便,突然想到可以找到文档地址,部署在本地,不知道这样合适不合适,,但是github.io访问速度真的难受,开搞。 wux文档地址: https://github.com/wux-weapp/wux-weapp-docs。 docsify文档地址: https://docsify.js.org/#/zh-cn/quickstart。 [代码]//安装 docsify npm i docsify-cli -g // cd 文档目录 docsify serve ./ [代码] 定制自己的 UI 库 文档:随着组件库越来越丰富,文件的体积也越来越大,某些时候我们可能只需要其中的一个或多个组件,如果直接引入整个组件库的话是不合适的,这时候就需要我们将要使用到组件给单独抽离出来。 demo 下载出来看文件大小还是挺大的 951KB。 [图片] 根据官方推荐的方式我们进行抽离。官方推荐 使用 定制主题 功能自动抽离组件。千万别尝试手动~~ [代码]// 使用方法,早上不知怎么 git clone 一直失败,手动下载3秒搞定。 git clone https://github.com/wux-weapp/wux-weapp.git // 克隆项目到本地,或手动下载也可 cd wux-weapp // 进入项目根目录 touch config.custom.json // 新建一个配置文件,若已创建可忽略此步骤 npm install // 安装依赖包 npm run build -- --config ./config.custom.json --output ./build // 编译文件 [代码] [图片] 自定义后 160多KB,完全可以接受,很舒服。 Wux 使用 微信开发者工具创建新项目。 将定制编译后的文件拖到项目文件里 这里不用使用 npm 构建了,正常组件使用 复制个官方demo跑一下,看是否报错 简单的定制后跑的一个demo: https://github.com/Grainfills/Wux-Weapp 有同样使用wux的踩过坑的小伙伴来交流一下哈
2019-12-10 - 阅读 9小时搞定微信小程序开发 源码总结(小书架)。
目录与页面模块 读代码首先应该认真阅读文档的[代码]README.md[代码]。 看下小书架页面模块、目录结构清晰,虽然模块不多,实际业务开发中首先应该构思拆解业务模块,确定目录结构。小程序包大小超过 2M 需要分包,所以从一开始确定目录结构的时候就要考虑进去,不然线上跑起来再去分包会有点小麻烦。 目录结构 [代码]├── config │ └── config.js ├── images ├── pages │ ├── books │ │ ├── books.js │ │ ├── books.json │ │ ├── books.wxml │ │ └── books.wxss │ ├── comment │ │ ├── comment.js │ │ ├── comment.js │ │ ├── comment.js │ │ └── comment.wxss │ ├── detail │ │ ├── detail.js │ │ ├── detail.js │ │ ├── detail.js │ │ └── detail.wxss │ ├── my │ │ ├── my.js │ │ ├── my.js │ │ ├── my.js │ │ └── my.wxss │ └── myBooks │ ├── myBooks.js │ ├── myBooks.js │ ├── myBooks.js │ └── myBooks.wxss ├── utils │ └── util.js ├── app.js ├── app.json ├── app.wxss └── project.config.json [代码] 各页面模块 页面 描述 books 首页/书籍列表页 comment 评论页面 detail 书籍详情页 my 个人中心页 myBooks 已购书籍页 接口封装 小书架没有对 wx.request 封装。考虑到是入门教程,没做处理也是正常。接口请求路径封装在 config.js [代码]// 服务器域名 const baseUrl = 'http://127.0.0.1:[your port]/'; // 获取书籍信息接口地址(可选择全部或单个书籍) const getBooksUrl = baseUrl + 'api/book/getBooks'; //... module.exports = { getBooksUrl: getBooksUrl //... }; [代码] 也可以根据个人习惯进行封装,这里一定要写注释以及考虑后期维护 [代码]let returnCancel = (memberId, refundId) => http.post(`api/return/goods/cancel`, { memberId: memberId, refundId: refundId}) export default { returnCancel }; [代码] 页面 book book.js 代码干净、整洁。注释很详细,虽然这是入门教程,但我们开发的时候也要养成这样的好习惯。 data [代码]data: { bookList: [], // 书籍列表数组 indicatorDots: false, // 是否显示轮播指示点 autoplay: false, // 是否自动播放轮播 sideMargin: '100rpx', // 幻灯片前后边距 showLoading: true // 是否显示loading态 //... }, [代码] onLoad getBookList 方法获取所有书籍列表,不要把所有的 wx.request 都写在load里面,简单封装下可维护性大大提高 [代码]/** * 获取所有书籍列表 */ getBookList: function() { let that = this; wx.request({ url: api.getBooksUrl, data: { is_all: 1 }, success: function(res) { let data = res.data; // console.log(data); if (data.result === 0) { setTimeout(function() { that.setData({ bookList: data.data, showLoading: false }); }, 800); } }, error: function(err) { console.log(err); } }); }, onLoad: function(options) { let that = this; that.getBookList(); }, [代码] loading处理 [代码]<block wx:if="{{showLoading}}"> <view class="donut-container"> <view class="donut"></view> </view> </block> // 默认 true 。getBookList 方法成功回调里设为 false。没有错误处,接口请求失败的话应该也做下处理的 [代码] comment comment.js 封装了检查用户输入的方法,实际业务中如果输入较多的话,可以提炼到 unit.js。封装了 wx.showToast [代码]// 检查输入是否为空,起名称注意语义话 checkEmpty: function(input) { return input === ''; }, /** * 检查用户是否输入了非法字符 */ checkIllegal: function(input) { let patern = /[`#^<>:"?{}\/;'[\]]/im; let _result = patern.test(input); return _result; }, /** * 检查用户输入 */ checkUserInput: function() { /* * 检测用户输入 * 1. 是否包含非法字符 * 2. 是否为空 * 3. 是否超出长度限制 */ let that = this; let comment = that.data.comment; let showToastFlag = false; let toastWording = ''; if (that.checkEmpty(comment)) { showToastFlag = true; toastWording = '输入不能为空'; } else if (that.checkIllegal(comment)) { showToastFlag = true; toastWording = '含有非法字符'; } else if (comment.length > 140) { showToastFlag = true; toastWording = '长度超出限制'; } if (showToastFlag) { that.showInfo(toastWording); return false; } else { return true; } }, [代码] 封装toast [代码]showInfo: function(info, icon = 'none', callback = () => {}) { wx.showToast({ title: info, icon: icon, duration: 1500, mask: true, success: callback }); }, [代码] detail 简单的返回刷新处理以及下载进度条 [代码]// 从上级页面返回时 重新拉去评论列表 backRefreshPage: function() { let that = this; that.setData({ commentLoading: true }); that.getPageData(); }, /** * 生命周期函数--监听页面显示 */ onShow: function() { if (wx.getStorageSync('isFromBack')) { wx.removeStorageSync('isFromBack') this.backRefreshPage(); } } [代码] 进度条(这个还是很少见的需求,很可爱) [代码]<!-- 下载进度条 --> <view class="loading-container" wx:if="{{downloading}}"> <progress percent="{{downloadPercent}}" stroke-width="6" activeColor="#1aad19" backgroundColor="#cdcdcd" show-info /> </view> [代码] my 主要是检查登陆。myBooks没有什么亮眼的操作,就不上场了。 [代码]data: { userInfo: {}, // 用户信息 hasLogin: wx.getStorageSync('loginFlag') ? true : false // 是否登录,根据后台返回的skey判断 }, [代码] app.js 主要负责检查处理登陆信息 [代码]App({ // 小程序启动生命周期 onLaunch: function () { let that = this; // 检查登录状态 that.checkLoginStatus(); }, // 检查本地 storage 中是否有登录态标识 checkLoginStatus: function () { let that = this; let loginFlag = wx.getStorageSync('loginFlag'); if (loginFlag) { // 检查 session_key 是否过期 wx.checkSession({ // session_key 有效(为过期) success: function () { // 直接从Storage中获取用户信息 let userStorageInfo = wx.getStorageSync('userInfo'); if (userStorageInfo) { that.globalData.userInfo = JSON.parse(userStorageInfo); } else { that.showInfo('缓存信息缺失'); console.error('登录成功后将用户信息存在Storage的userStorageInfo字段中,该字段丢失'); } }, // session_key 过期 fail: function () { // session_key过期 that.doLogin(); } }); } else { // 无登录态 that.doLogin(); } }, // 登录动作 doLogin: function (callback = () => {}) { let that = this; wx.login({ success: function (loginRes) { if (loginRes.code) { /* * @desc: 获取用户信息 期望数据如下 * * @param: userInfo [Object] * @param: rawData [String] * @param: signature [String] * @param: encryptedData [String] * @param: iv [String] **/ wx.getUserInfo({ withCredentials: true, // 非必填, 默认为true success: function (infoRes) { console.log(infoRes,'>>>') // 请求服务端的登录接口 wx.request({ url: api.loginUrl, data: { code: loginRes.code, // 临时登录凭证 rawData: infoRes.rawData, // 用户非敏感信息 signature: infoRes.signature, // 签名 encryptedData: infoRes.encryptedData, // 用户敏感信息 iv: infoRes.iv // 解密算法的向量 }, success: function (res) { console.log('login success'); res = res.data; if (res.result == 0) { that.globalData.userInfo = res.userInfo; wx.setStorageSync('userInfo', JSON.stringify(res.userInfo)); wx.setStorageSync('loginFlag', res.skey); callback(); } else { that.showInfo(res.errmsg); } }, fail: function (error) { // 调用服务端登录接口失败 that.showInfo('调用接口失败'); console.log(error); } }); }, fail: function (error) { // 获取 userInfo 失败,去检查是否未开启权限 wx.hideLoading(); that.checkUserInfoPermission(); } }); } else { // 获取 code 失败 that.showInfo('登录失败'); console.log('调用wx.login获取code失败'); } }, fail: function (error) { // 调用 wx.login 接口失败 that.showInfo('接口调用失败'); console.log(error); } }); }, // 检查用户信息授权设置 checkUserInfoPermission: function (callback = () => { }) { wx.getSetting({ success: function (res) { if (!res.authSetting['scope.userInfo']) { wx.openSetting({ success: function (authSetting) { console.log(authSetting) } }); } }, fail: function (error) { console.log(error); } }); }, // 获取用户登录标示 供全局调用 getLoginFlag: function () { return wx.getStorageSync('loginFlag'); }, // app全局数据 globalData: { userInfo: null } }); [代码] 中规中矩的小程序,入门还是可以的,代码简洁干净。新手的话撸一遍还是可以的。这样不知道算不算侵权,侵删。
2019-11-15