diff --git a/README.md b/README.md
index 80d49f3..26f1c99 100644
--- a/README.md
+++ b/README.md
@@ -17,3 +17,24 @@ yarn build
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
+
+### 库
+
+```
+ vuex、numeral
+
+ 依赖-> sass-loader/ node-sass/
+```
+
+*sass 需要cnpm装,npm安装报错*
+
+> 原型链接:https://org.modao.cc/app/d33151880c5a6a975b9f3af1868bf3a125a8923b?simulator_type=outside_artboard&sticky
+> 设计稿链接:https://lanhuapp.com/web/#/item/project/board?pid=ea91cb92-0502-40c9-a746-e68d121e26fd
+
+### ipx 底部适配高度函数
+
+```css
+ padding-bottom: 0;
+ padding-bottom: calc( 0 + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */
+ padding-bottom: calc( 0 + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */
+```
\ No newline at end of file
diff --git a/package.json b/package.json
index 2a5eee7..a0908ec 100644
--- a/package.json
+++ b/package.json
@@ -80,8 +80,12 @@
"jest": "^25.4.0",
"mini-types": "*",
"miniprogram-api-typings": "*",
+ "node-sass": "^5.0.0",
+ "numeral": "^2.0.6",
"postcss-comment": "^2.0.0",
- "vue-template-compiler": "^2.6.11"
+ "sass-loader": "^10.1.1",
+ "vue-template-compiler": "^2.6.11",
+ "vuex": "^3.6.0"
},
"browserslist": [
"Android >= 4",
diff --git a/src/App.vue b/src/App.vue
index 8c2b732..08441c9 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -14,4 +14,27 @@
diff --git a/src/components/authorize_modal/authorize_modal.vue b/src/components/authorize_modal/authorize_modal.vue
new file mode 100644
index 0000000..a1252a8
--- /dev/null
+++ b/src/components/authorize_modal/authorize_modal.vue
@@ -0,0 +1,149 @@
+
+
+
+ 微信授权
+ 您的信息和数据将受到保护
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/js/api.js b/src/js/api.js
new file mode 100644
index 0000000..67f4729
--- /dev/null
+++ b/src/js/api.js
@@ -0,0 +1,12 @@
+export const ORIGIN = ``; // 测试
+// export const ORIGIN = ``; // 正式
+
+export const API = {
+ ex: `${ORIGIN}/test/test`,
+}
+
+
+export default { ORIGIN, API };
+
+
+
diff --git a/src/js/server.js b/src/js/server.js
new file mode 100644
index 0000000..e5cebad
--- /dev/null
+++ b/src/js/server.js
@@ -0,0 +1,91 @@
+import util from '../utils/util';
+// import { app as vm } from '../main';
+const islog = true;
+
+export class Server {
+ request(url,data,method,header,isDefaultGet,failMsg){
+ return new Promise(async (rs,rj)=>{
+ // const _store = vm.$store;
+ // let storeInfo = _store.state.storeInfo || null;
+ // if(storeInfo)data['brand_id'] = storeInfo.brand_id;
+
+ const _token = uni.getStorageSync('token') || '';
+ if(_token)data['token'] = _token;
+ if(method === 'POST'&&_token)url = url + `?token=${_token}`
+ uni.request({
+ url,
+ data,
+ method, // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
+ header: {...header}, // 设置请求的 header // {'custom-header': 'application/json'}
+ success: res=>{
+ if(islog)console.log('req success---->',{
+ link: url,
+ query: data,
+ method: method,
+ data: res,
+ })
+ if(isDefaultGet){
+ if(failMsg == '')throw Error('默认回调,失败提示不能为空 key -> failMsg');
+ defaultGet({
+ url,
+ data,
+ res,
+ failMsg,
+ resolve: rs,
+ reject: rj
+ });
+ return
+ }
+ rs(res);
+ },
+ fail: err=>{
+ if(islog)console.log('req fail---->',{
+ link: url,
+ query: data,
+ method: method,
+ data: err,
+ })
+ util.hideLoad();
+ if(typeof(err.errMsg) == 'string'&&(err.errMsg.indexOf('timeout')!=-1 || err.errMsg.indexOf('interrupted')!=-1 || err.errMsg.indexOf('请求超时')!=-1)){
+ util.showNone('网络超时!');
+ }else if(typeof(err.errMsg) == 'string'){
+ util.showNone(err.errMsg);
+ }else{
+ util.showNone('请求数据失败!请检查当前网络状态。');
+ }
+ rj(err);
+ },
+ })
+ })
+
+ function defaultGet({res,failMsg,resolve,reject,url,data}){
+ if(res.data.code == 0){
+ resolve(res.data.data);
+ }else{
+ util.hideLoad();
+ util.showNone(res.data.message || failMsg || '');
+ reject({url,res,data});
+ }
+ }
+ }
+ get({url,data={},header={},isDefaultGet=true,failMsg=''}){
+ return this.request(url,data,'GET',header,isDefaultGet,failMsg);
+ }
+
+ post({url,data={},header={'custom-header': 'application/json'},isDefaultGet=true,failMsg=''}){
+ return this.request(url,data,'POST',header,isDefaultGet,failMsg);
+ }
+
+ uploadFile({url,filePath,onProgressCallBack,formData={}}){
+ return new Promise((rs,rj)=>{
+ let uploadTask = wx.uploadFile({
+ url,filePath,formData,name:'file',success:rs,fail:rj
+ })
+ uploadTask.onProgressUpdate(res=>onProgressCallBack&&onProgressCallBack(res))
+ })
+ }
+}
+
+export const servers = new Server();
+
+export default { servers, Server };
\ No newline at end of file
diff --git a/src/pages.json b/src/pages.json
index 1aea851..bcbc40e 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -3,14 +3,31 @@
{
"path": "pages/index/index",
"style": {
- "navigationBarTitleText": "uni-app"
+ "navigationBarTitleText": "欧轩智能教裁助手"
+ }
+ },
+ {
+ "path": "pages/feedback/feedback",
+ "style": {
+ }
+ },
+
+ {
+ "path": "pages/message_list/message_list",
+ "style": {
+ }
+ },
+ {
+ "path": "pages/login/login",
+ "style": {
}
}
+
],
"globalStyle": {
- "navigationBarTextStyle": "black",
- "navigationBarTitleText": "uni-app",
- "navigationBarBackgroundColor": "#F8F8F8",
- "backgroundColor": "#F8F8F8"
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "欧轩智能教裁助手",
+ "navigationBarBackgroundColor": "#009874",
+ "backgroundColor": "#f2f2f7"
}
}
diff --git a/src/pages/feedback/feedback.vue b/src/pages/feedback/feedback.vue
new file mode 100644
index 0000000..5293459
--- /dev/null
+++ b/src/pages/feedback/feedback.vue
@@ -0,0 +1,151 @@
+
+
+
+
+
+ 上传照片(最多上传3张,只支持.jpg、png 格式)
+
+
+
+
+
+
+
+ 上传照片
+
+
+
+ 保存
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue
index bd118ba..54ab78c 100644
--- a/src/pages/index/index.vue
+++ b/src/pages/index/index.vue
@@ -1,49 +1,215 @@
-
-
-
- {{title}}
+
+
+
+
+
+ 欧轩智能场馆商家助手上线啦!
+
+
+ 99
+
+
+
+
+
+
+ 我的课程
+
+
+
+
+
+ 在线反馈
+
+
+
+
-
-
diff --git a/src/pages/login/login.vue b/src/pages/login/login.vue
new file mode 100644
index 0000000..db8ff22
--- /dev/null
+++ b/src/pages/login/login.vue
@@ -0,0 +1,205 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/pages/message_list/message_list.vue b/src/pages/message_list/message_list.vue
new file mode 100644
index 0000000..ba2f994
--- /dev/null
+++ b/src/pages/message_list/message_list.vue
@@ -0,0 +1,94 @@
+
+
+
+
+
+ 欧轩智能商家助手功能更新
+
+ 2020/11/23
+
+
+ 喜欢喜欢需和许 i 会修 hi 休闲鞋被选行啊学…休闲鞋被选行啊学…休闲鞋被选行啊学…
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/static/images/authorize.png b/src/static/images/authorize.png
new file mode 100644
index 0000000..bc7f1fb
Binary files /dev/null and b/src/static/images/authorize.png differ
diff --git a/src/static/logo.png b/src/static/logo.png
deleted file mode 100644
index b5771e2..0000000
Binary files a/src/static/logo.png and /dev/null differ
diff --git a/src/store/actions.js b/src/store/actions.js
new file mode 100644
index 0000000..73e1a6d
--- /dev/null
+++ b/src/store/actions.js
@@ -0,0 +1,16 @@
+// 异步方法
+import { servers } from '../js/server';
+import { API } from '../js/api';
+export default {
+ getBrandInfo({commit, state}){
+ return servers.get({
+ url: API.calc,
+ data: {},
+ failMsg: '加载数据失败!'
+ })
+ .then(res=>{
+ commit('setBrandInfo',res);
+ return res;
+ })
+ }
+}
\ No newline at end of file
diff --git a/src/store/index.js b/src/store/index.js
new file mode 100644
index 0000000..a776071
--- /dev/null
+++ b/src/store/index.js
@@ -0,0 +1,54 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import mutations from './mutations';
+import actions from './actions';
+import device from './device';
+Vue.use(Vuex);
+
+export default new Vuex.Store({
+ modules: {
+ device
+ },
+ state: {
+ // #ifdef H5
+ APPID: uni.getAccountInfoSync().miniProgram.appId,
+ // #endif
+ brandInfo: {
+ brand: {}
+ },
+ permissionObj: { // 权限代号对应
+ '1001': '营业额',
+ '1002': '收款记录',
+ '1003': '经营分析',
+ '1004': '预约订单',
+ '1005': '会员卡订单',
+ '1006': '积分订单',
+ '1007': '员工管理',
+ '1008': '查询核销',
+ '1009': '场地管理',
+ '1010': '设备管理',
+ },
+
+ // 场地占用提交页面信息
+ occupyInfo: {
+ storeInfo: {}, // 店铺信息
+ dateInfo: {}, // 时间信息
+ typeInfo: {}, // 球场类型
+ venueList: [], // 选择场地列表
+ }
+ },
+ mutations,
+ actions,
+ getters: {
+ permissionArr: state=>{
+ let _arr = [], _obj = state.permissionObj;
+ for(let key in _obj){
+ _arr.push({
+ key,
+ name: _obj[key],
+ })
+ }
+ return _arr;
+ }
+ }
+});
diff --git a/src/store/mutations.js b/src/store/mutations.js
new file mode 100644
index 0000000..99d4083
--- /dev/null
+++ b/src/store/mutations.js
@@ -0,0 +1,15 @@
+// 同步方法
+
+
+export default {
+ // 设置品牌信息
+ setBrandInfo(state, brandInfo){
+ // console.log(storeInfo,'-----')
+ state.brandInfo = brandInfo
+ },
+
+ // 场地占用信息
+ setOccupyInfo(state, _occupyInfo){
+ state.occupyInfo = _occupyInfo;
+ }
+}
\ No newline at end of file
diff --git a/src/style/public.scss b/src/style/public.scss
new file mode 100644
index 0000000..60305d8
--- /dev/null
+++ b/src/style/public.scss
@@ -0,0 +1,89 @@
+@charset "utf-8";
+
+$themeColor: #009874;
+
+/*每个页面公共css */
+/* view,scroll-view,text,picker{
+ box-sizing: border-box;
+ } */
+
+@mixin textHide($line) {
+ display: -webkit-box;
+ word-break: break-all;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp:$line;
+}
+
+@mixin centerFlex($justtify){
+ display: flex;
+ align-items: center;
+ justify-content: $justtify;
+}
+
+@mixin botLine{
+ border-bottom: 2upx solid #e5e5e5;
+}
+
+@mixin picBgc{
+ background-color: #f9f9f9;
+}
+
+
+@mixin closeIcon($width,$height,$color) {
+ transform: rotateZ(45deg);
+ &::before{
+ content: '';
+ display: block;
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%,-50%);
+ width: $width;
+ height: $height;
+ background-color: $color;
+ border-radius: $height;
+ }
+ &::after{
+ content: '';
+ display: block;
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%,-50%);
+ width: $height;
+ height: $width;
+ background-color: $color;
+ border-radius: $height;
+ }
+}
+
+@mixin hover {
+ position: relative;
+ overflow: hidden;
+ &::after{
+ content: '';
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ z-index: 2;
+ background-color: rgba(0,0,0,.1);
+ }
+}
+
+@mixin arrowIcon($size,$line,$radius,$angle,$color) {
+ &::after{
+ content:'';
+ display: inline-block;
+ vertical-align: middle;
+ transform: rotateZ($angle);
+ width: $size;
+ height: $size;
+ border-right: $line solid $color;
+ border-bottom: $line solid $color;
+ border-bottom-right-radius: $radius;
+ }
+}
diff --git a/src/utils/util.js b/src/utils/util.js
new file mode 100644
index 0000000..7c444a1
--- /dev/null
+++ b/src/utils/util.js
@@ -0,0 +1,338 @@
+// import {emojiMap,emojiUrl} from './emojiMap';
+
+export const phoneReg = new RegExp(/^1(3|4|5|6|7|8|9)\d{9}$/);
+export const mailReg = new RegExp(/^\w+((.\w+)|(-\w+))@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+).[A-Za-z0-9]+$/);
+export const specialReg = new RegExp("[^a-zA-Z0-9\_\u4e00-\u9fa5]","i");
+
+export const formatTime = date => {
+ const year = date.getFullYear()
+ const month = date.getMonth() + 1
+ const day = date.getDate()
+ const hour = date.getHours()
+ const minute = date.getMinutes()
+ const second = date.getSeconds()
+
+ return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
+}
+
+export const formatDate = ({ date= new Date(), partition= '-' }) => {
+ let _date;
+ if(typeof (date) === 'string'&&date.indexOf('-')!=-1){
+ _date = new Date(date.replace(/\-/g,'/'))
+ }else{
+ _date = new Date(date)
+ }
+ const year = _date.getFullYear();
+ const month = formatNumber(_date.getMonth() + 1);
+ const day = formatNumber(_date.getDate());
+
+ if(partition == 'zh')return `${year}年${month}月${day}日`
+ return [year, month, day].map(formatNumber).join(partition);
+}
+
+export const formatNumber = n => {
+ n = n.toString()
+ return n[1] ? n : '0' + n
+}
+// 路由跳转
+export const routeTo = (url,type) => {
+ switch(type){
+ case 'nT': uni.navigateTo({url});
+ break
+ case 'rT': uni.redirectTo({url});
+ break
+ case 'rL': uni.reLaunch({url});
+ break
+ case 'sT': uni.switchTab({url});
+ break
+ default: uni.navigateBack({delta: 1})
+ break
+ }
+}
+
+function showNone(txt,duration=1500){
+ uni.hideToast();
+ uni.hideLoading();
+ uni.showToast({
+ mask: true,
+ title: txt,
+ icon: 'none',
+ duration,
+ })
+}
+
+function showLoad(title='加载中', mask=true){
+ uni.showLoading({
+ mask,
+ title,
+ })
+}
+function hideLoad(){
+ uni.hideLoading()
+}
+function showModal({
+ title='提示',
+ content='',
+ showCancel=false,
+ cancelText='取消',
+ confirmText='确定',
+ confirmColor='#009874',
+ success,
+ fail,
+ complete
+}){
+ uni.showModal({
+ title,
+ content,
+ showCancel,
+ cancelText,
+ confirmColor,
+ confirmText,
+ success,
+ fail,
+ complete
+ })
+}
+
+function debounce(func, wait, immediate) {
+ let timeout, args, context, timestamp, result;
+ const later = function() {
+ // 据上一次触发时间间隔
+ const last = +new Date() - timestamp;
+ // 上次被包装函数被调用时间间隔last小于设定时间间隔wait
+ if (last < wait && last > 0) {
+ timeout = setTimeout(later, wait - last);
+ } else {
+ timeout = null;
+ // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
+ if (!immediate) {
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ }
+ }
+ }
+ return function(...args) {
+ context = this;
+ timestamp = +new Date();
+ const callNow = immediate && !timeout;
+ // 如果延时不存在,重新设定延时
+ if (!timeout) timeout = setTimeout(later, wait);
+ if (callNow) {
+ result = func.apply(context, args);
+ context = args = null;
+ }
+ return result;
+ }
+}
+
+function jsonStr(data){
+ return encodeURIComponent(JSON.stringify(data))
+}
+function jsonPar(json){
+ return JSON.parse(decodeURIComponent(json))
+}
+
+export let promisify = api => {
+ return (options, ...params) => {
+ return new Promise((resolve, reject) => {
+ api(Object.assign({}, options, { success: resolve, fail: reject }), ...params);
+ });
+ }
+}
+
+function previousPageFunction({fnName,query}){
+ return new Promise((rs,rj)=>{
+ try{
+ if(getCurrentPages().length>1){
+ console.log(getCurrentPages())
+ getCurrentPages()[getCurrentPages().length-2]['$vm'][fnName](query);
+ rs('success');
+ }else{
+ console.error('当前路由栈为一,无法调取上一页数据');
+ rj('当前路由栈为一,无法调取上一页数据');
+ }
+ }catch(err){
+ console.error('调用上一页面栈方法失败!',err);
+ rj('调用上一页面栈方法失败!');
+ }
+ })
+
+}
+
+// 获取节点信息
+function getNodeMes(selector,_this=null){
+ return new Promise(rs=>{
+ let query = _this ? uni.createSelectorQuery().in(_this) : uni.createSelectorQuery();
+ query.select(selector).boundingClientRect(res=>{
+ rs(res)
+ // this.height = uni.getSystemInfoSync().windowHeight - res.height;
+ }).exec()
+ })
+}
+
+export const convertBase64 = function(base64data){
+ const fsm = uni.getFileSystemManager();
+ const FILE_BASE_NAME = 'tmp_base64src';//临时文件名
+ return new Promise((resolve, reject) => {
+ const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || []; //去掉 base64 的头信息:
+ if (!format) {
+ reject(new Error('ERROR_BASE64SRC_PARSE'));
+ }
+ const filePath = `${uni.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;
+ const buffer = bodyData&&uni.base64ToArrayBuffer(bodyData); //将 base64 数据转换为 ArrayBuffer 数据
+ // console.log(uni.base64ToArrayBuffer(bodyData))
+ fsm.writeFile({ //将 ArrayBuffer 写为本地用户路径的二进制图片文件 //图片文件路径在 uni.env.USER_DATA_PATH 中
+ filePath,
+ data: buffer,
+ encoding: 'binary',
+ success() {
+ // console.log(buffer)
+ resolve(filePath);
+ },
+ fail() {
+ reject(new Error('ERROR_BASE64SRC_WRITE'));
+ },
+ });
+ });
+}
+export function failAuthorizeTosetting(content='调用失败,请打开检查授权状态'){
+ showModal({
+ title:'提示',
+ content,
+ showCancel:true,
+ confirmText:'打开',
+ success:res=>{if(res.confirm)uni.openSetting()}
+ })
+}
+
+// 解析小程序码 scene 参数
+export function getSceneQuery(scene){
+ const queryStr = decodeURIComponent(scene) || null;
+ let queryObj = queryStr.split('&').reduce((obj,el)=>{
+ let arr = el.split('=');
+ obj[`${arr[0]}`] = arr[1];
+ return obj;
+ },{}) || null;
+ return queryObj;
+}
+
+//获取地址栏里(URL)传递的参数
+function getUrlQuery(key,url){
+ var _url = decodeURI(url).split('?a=1').join(''); //剪切'?a=1'安卓兼容,再获取参数
+ if(_url.indexOf(`${key}=`) !=-1){
+ return _url.split(`${key}=`)[1].split('&')[0]
+ }
+ return null
+}
+
+//获取地址字段栏信息 腾讯获取授权码时
+function getQueryString(name) {
+ var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
+ var r = window.location.search.substr(1).match(reg);
+ if (r != null) return (r[2]); // 编码的字符串进行解码
+ return null;
+}
+
+function getRandom(min, max) {
+ return Math.round(Math.random() * (max - min)) + min;
+}
+
+export function get_zh_day(date){
+ if(isSameDay(new Date().getTime(),new Date(date).getTime()))return '今天'
+ const Arr = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
+ return Arr[new Date(date).getDay()] || '';
+}
+
+// 判断是否同一天
+export function isSameDay(timeStampA, timeStampB) {
+ let dateA = new Date(timeStampA);
+ let dateB = new Date(timeStampB);
+ return (dateA.setHours(0, 0, 0, 0) == dateB.setHours(0, 0, 0, 0));
+}
+
+// 获取中文日期
+export function get_zh_date(date = new Date()){
+ return `${new Date(date).getMonth()+1}月${new Date(date).getDate()}日`
+}
+
+export function substrDate(date){
+ if(!date)return;
+ return date.substr(0,10) || '-'
+}
+
+// package 貌似为保留字,作为参数时 编译报错
+export function requestPayment(query = {}){
+ showLoad();
+ uni.requestPayment({
+ timeStamp: query.timeStamp || '',
+ nonceStr: query.nonceStr || '',
+ package: query.package || '',
+ signType: query.signType || '',
+ paySign: query.paySign || '',
+ success: function(res){
+ query.success&&query.success(res)
+ },
+ fail: function(res){
+ query.fail&&query.fail(res)
+ },
+ complete: function(res){
+ hideLoad();
+ query.complete&&query.complete(res)
+ },
+ })
+}
+
+function getQueryStr({url,name}){
+ let queryArr = (url.split('?')[1] || '').split("&") || [];
+ // let vars = query.split("&");
+ for (let i=0;i '{}'
+function formatScene(sceneStr = ''){
+ let scene = decodeURIComponent(sceneStr);
+ let queryArr = scene.split('&');
+ return queryArr.reduce((obj,e,i)=>{
+ let _arr = e.split('=');
+ obj[_arr[0]] = _arr[1];
+ return obj;
+ },{}) || {};
+}
+
+function changeLowerCase(str){
+ return str.toString().toLocaleLowerCase();
+}
+
+export default {
+ formatTime,
+ formatNumber,
+ formatDate,
+ routeTo,
+ showNone,
+ showLoad,
+ hideLoad,
+ showModal,
+ debounce,
+ jsonStr,
+ jsonPar,
+ promisify,
+ previousPageFunction,
+ getNodeMes,
+ failAuthorizeTosetting,
+ getSceneQuery,
+ getUrlQuery,
+ getQueryString,
+ getRandom,
+ get_zh_day,
+ isSameDay,
+ get_zh_date,
+ substrDate,
+ requestPayment,
+ getQueryStr,
+ formatScene,
+ changeLowerCase
+}