Jelajahi Sumber

0813-0219-h01

Zory 1 bulan lalu
induk
melakukan
c55d2f8604

+ 10 - 0
奥莱优品/App.vue

@@ -52,6 +52,16 @@ export default {
 		min-height: 30upx;
 		height: 100%;
 		width: 100%;
+	}
+	.mt15{margin-top: 15rpx;}
+	.skeleton-line.short{
+		width: 60%;
+	}
+	.skeleton-line.max{
+		height: 80upx;
+	}
+	.animate {
+		animation: skeleton 1.8s ease infinite
 	}
 	@keyframes skeleton {
 		0% {

+ 0 - 0
奥莱优品/api/auth.js


+ 10 - 0
奥莱优品/api/index.js

@@ -0,0 +1,10 @@
+// api/index.js
+const files = require.context('./model', false, /\.js$/)
+const modules = {}
+
+files.keys().forEach((key) => {
+  const module = files(key)
+  const moduleName = key.replace(/(\.\/|\.js)/g, '')
+  modules[moduleName] = module.default || module
+})
+export default modules

+ 10 - 0
奥莱优品/api/model/auth.js

@@ -0,0 +1,10 @@
+import request from '@/static/js/request.js'
+
+export default {
+	mobile: {
+		url: `/auth/mobile`,
+		post: async function(data={}) {
+			return await request.request(this.url,"POST",data,false,true,false)
+		}
+	}
+}

+ 3 - 1
奥莱优品/components/chat/emoji.vue

@@ -21,8 +21,9 @@
 								v-for="(item, index) in im"
 								:key="index"
 								:style="{ opacity: ix === opacityGroup && (index == 5 || index == 6 || index == 7) ? opacity : 1 }"
+								@click="chooseEmoji(item.text)"
 							>
-								<image class="img" :src="emojiUrl + item.image" @click="chooseEmoji(item.text)"></image>
+								<image class="img" :src="emojiUrl + item.image"></image>
 							</view>
 						</view>
 						<view class="img" style="height: 18vw"></view>
@@ -155,6 +156,7 @@ export default {
 		},
 		//选择表情
 		chooseEmoji(key) {
+			console.log("chooseEmoji",key)
 			this.$emit('onEmoji', key);
 		},
 		// 删除

+ 3 - 3
奥莱优品/components/chat/more.vue

@@ -28,17 +28,17 @@ export default {
 			list: [
 				{
 					type: 'img',
-					icon: 'https://jymini.oss-cn-guangzhou.aliyuncs.com/mini/pic.svg',
+					icon: 'https://jymini.oss-cn-guangzhou.aliyuncs.com/mini/msg-photo.svg',
 					title: '照片'
 				},
 				{
 					type: 'order',
-					icon: 'https://jymini.oss-cn-guangzhou.aliyuncs.com/mini/order.svg',
+					icon: 'https://jymini.oss-cn-guangzhou.aliyuncs.com/mini/msg-order.svg',
 					title: '订单'
 				},
 				// {
 				// 	type: 'video',
-				// 	icon: 'https://jymini.oss-cn-guangzhou.aliyuncs.com/mini/video.svg',
+				// 	icon: 'https://jymini.oss-cn-guangzhou.aliyuncs.com/mini/msg-order.svg',
 				// 	title: '视频'
 				// }
 			]

+ 14 - 5
奥莱优品/components/login/halfScreen.vue

@@ -28,7 +28,7 @@
 </template>
 
 <script>
-import * as Api from "@/api/auth.js";
+import { show } from '@/utils/js/index.js';
 export default {
 	data() {
 		return {
@@ -38,7 +38,9 @@ export default {
 	methods: {
 		closeLogin(){
 			uni.showTabBar()
-			this.$refs.loginPop.close()
+			this.$nextTick(()=>{
+				this.$refs.loginPop.close()
+			})
 		},
 		checkTrue(){
 			this.checkTrueState = !this.checkTrueState;
@@ -57,10 +59,17 @@ export default {
 		},
 		getPhoneNumberData(event){
 			uni.login({
-				success(resp) {
+				success: async (resp)=> {
 					var detail = event.detail
-					var resp = Api.login({"login":resp.code,"code":detail.code}).then((res)=>{
-
+					detail.login = resp.code;
+					var aresp = await this.$api.auth.mobile.post(detail);
+					if (aresp.code !== 1) {
+						return show(aresp.msg);
+					}
+					uni.setStorageSync("user_token", aresp.data.access_token)
+					uni.showTabBar()
+					this.$nextTick(()=>{
+						this.$refs.loginPop.close()
 					})
 				}
 			})

+ 5 - 0
奥莱优品/main.js

@@ -1,5 +1,10 @@
 import App from './App'
 
+import api from './api/index.js'
+Vue.prototype.$api = api
+
+import common from 'static/js/common.js';
+Vue.prototype.$dialog = common;
 
 import store from '@/store/index.js'; // 引入vuex
 Vue.prototype.$store = store

+ 10 - 0
奥莱优品/pages.json

@@ -37,6 +37,16 @@
 			"style": {
 				"navigationBarTitleText": ""
 			}
+		},
+		{
+			"path": "pages/goods/detail",
+			"style": {
+				"navigationBarTitleText": "商品详情",
+				"navigationBarBackgroundColor": "#ffffff",
+				"usingComponents": {
+					"pay-button-sdk": "tta5a3d31e3aecfb9b11://pay-button"
+				}
+			}
 		}
 	],
 	"globalStyle": {

+ 127 - 0
奥莱优品/pages/goods/detail.vue

@@ -0,0 +1,127 @@
+<template>
+	<view class="content">
+		<block v-if="loading">
+			<view class="skeleton-line max animate" style="height: 400rpx;"></view>
+			<view class="skeleton">
+				<view class="skeleton-line animate mt15"></view>
+				<view class="skeleton-line min animate mt15"></view>
+				<view class="skeleton-line min animate mt15"></view>
+			</view>
+			<view class="skeleton-line max animate mt15" style="height: 200upx;"></view>
+			<view class="skeleton-line max animate mt15" style="height: 200upx;"></view>
+		</block>
+		<view class="goods-content" v-else>
+			<scroll-view class="goods-body" scroll-y scroll-with-animation>
+			</scroll-view>
+			<view class="footer">
+				<view class="footer-op">
+					<view class="footer-left">
+						<view class="item" @click="toNav('home')"><image src="/static/image/goods/home.png"></image>首页</view>
+						<view class="item" @click="kfPop"><image src="/static/image/goods/service.png"></image>客服</view>
+						<view class="item" @click="toNav('order')"><image src="/static/image/goods/order.png"></image>订单</view>
+					</view>
+					<view class="footer-right" @click="buyOrder(1)" v-if="isLogin">立即购买 {{ goodsData?$dialog.formatMoney(goodsData.price):'0.00'}}</view>
+					<button class="footer-right" @click="toLogin" v-else>登录下单 {{ goodsData?$dialog.formatMoney(goodsData.price):''}}</button>
+				</view>
+				<view class="footer-safe"></view>
+			</view>
+		</view>
+		<halfLogin ref="loginCom"></halfLogin>
+		<kfService ref="kfService"></kfService>
+	</view>
+</template>
+
+<script>
+var app;
+export default {
+	data() {
+		return {
+			options:null,
+			isLogin:null,
+			loading:false,
+			goodsData:null
+		}
+	},
+	onLoad(options) {
+		app = this;
+		const data = uni.getLaunchOptionsSync();
+		options.scene = data.scene
+		app.options = options
+		app.isLogin = uni.getStorageSync("user_token");
+	},
+	methods: {
+		toLogin(){
+			this.$refs.loginCom.open();
+		},
+		kfPop(){
+			this.$refs.kfService.open();
+		},
+		toNav(type) {
+			var url = "";
+			switch (type) {
+				case "order":
+					url = "/pages/order/order"
+				break;
+				case "home":
+				default:
+					url = "/pages/index/index"
+				break;
+			}
+			uni.switchTab({
+				url:url
+			})
+		}
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+.content {
+	background-color: #fff;
+	height: 100vh;
+	.skeleton{
+		width: 95%;
+		margin: 0 auto;
+	}
+	.goods-content{
+		position: fixed;
+		z-index: 1;
+		top: 0;
+		left: 0;
+		bottom: 0;
+		right: 0;
+		background-color: #ededed;
+		display: flex;
+		flex-direction: column;
+	}
+	.goods-body{
+		height: 0;
+		flex: 1;
+	}
+	.footer{
+		background-color: #fff;padding: 20upx 20upx 0 20upx;border-top: 2upx solid #f8f8f8;
+		.footer-op{
+			display: flex;align-items: center;
+			.footer-left{
+				display: flex;align-items: center;gap: 40upx;justify-content: center;
+				.item{flex-direction: column;display: flex;font-size: 24rpx;color: #333;align-items: center;}
+				image{width: 40upx;height: 40upx;}
+			}
+			.footer-right{
+				background-color: $main-color;
+				color: #fff;
+				font-size: 28rpx;
+				flex: 1;
+				margin-left: 40upx;
+				height: 80upx;
+				border-radius: 10upx;
+				line-height: 80upx;
+				text-align: center;
+			}
+		}
+		.footer-safe {
+			height: env(safe-area-inset-bottom);width: 100%;
+		}
+	}
+}
+</style>

+ 11 - 2
奥莱优品/pages/index/index.vue

@@ -27,7 +27,7 @@
 				<view class="title-more">全部商品 <image src="/static/image/right.svg"></image> </view>
 			</view>
 			<view class="goods-list">
-				<view class="list-item" v-for="(item,index) in 10" :key="index" @click="test">
+				<view class="list-item" v-for="(item,index) in 10" :key="index" @click="toDetail(index)">
 					<view class="image">
 						<image src="https://washmy.oss-cn-guangzhou.aliyuncs.com/storage/20260727/2e9fd491e2def96b0dd0677f43d7a31913cf959e.png"></image>
 						<text>2.7折</text>
@@ -63,7 +63,16 @@ export default {
 	methods: {
 		test(){
 			this.$refs.loginCom.open();
-			this.loginState = true;
+		},
+		toDetail(id){
+			const isLogin = uni.getStorageSync("user_token");
+			if (!isLogin) {
+				this.$refs.loginCom.open();
+				return ;
+			}
+			uni.navigateTo({
+				url:`/pages/goods/detail?id=${id}`
+			})
 		},
 		kfPop(){
 			this.$refs.kfService.open();

+ 113 - 55
奥莱优品/pages/service/chat.vue

@@ -1,60 +1,63 @@
 <template>
-	<view class="content" @touchmove="touchmove">
-		<scroll-view class="chat-body" scroll-y scroll-with-animation :scroll-top="scrollTop" scroll-with-animation @scroll="scroll" @scrolltoupper="scrolltoupper" @scrolltolower="scrolltolower" upper-threshold="80" :scroll-into-view="scrollIntoViewId" refresher-background="transparent">
-			<view class="msgLoading" v-if="msgData.flag">数据加载中...</view>
-			<view class="scroll-view-msg" style="padding: 30rpx 30rpx;">
-				<template v-for="(item, index) in msgData.list">
-					<view class="msgContent" :id="'msg-' + item.messageId">
-						<view class="text_26 color__ time">
-							{{ renderMessageDate(item, index) }}
-						</view>
-						<view class="message" :class="[item.userType]">
-							<image :src="item.avatar" v-if="item.userType === 'friend'" class="avatar" mode="widthFix"></image>
-							<view class="message-con">
-								<view v-if="item.msgType == 'text'">
-									<view v-html="renderTextMessage(item.content)"></view>
+	<view class="content">
+		<!-- <view class="send-load" v-if="msgData.flag">数据加载中...</view> -->
+		<view class="send-load" v-if="msgData.isSend">发送中...</view>
+		<view class="chat-content" @touchmove="touchmove">
+			<scroll-view class="chat-body" scroll-y scroll-with-animation :scroll-top="scrollTop" scroll-with-animation @scroll="scroll" @scrolltoupper="scrolltoupper" @scrolltolower="scrolltolower" upper-threshold="80" :scroll-into-view="scrollIntoViewId" refresher-background="transparent">
+				<!-- <view class="msgLoading" v-if="msgData.flag">数据加载中...</view> -->
+				<view class="scroll-view-msg" style="padding: 30rpx 30rpx;">
+					<template v-for="(item, index) in msgData.list">
+						<view class="msgContent" :id="'msg-' + item.messageId">
+							<view class="text_26 color__ time">
+								{{ renderMessageDate(item, index) }}
+							</view>
+							<view class="message" :class="[item.userType]">
+								<image :src="item.avatar" v-if="item.userType === 'friend'" class="avatar" mode="widthFix"></image>
+								<view class="message-con">
+									<view v-if="item.msgType == 'text'">
+										<view v-html="renderTextMessage(item.content)"></view>
+									</view>
+									<view class="" v-if="item.msgType == 'quick'">
+										<view class="quickCon">{{item.content}}</view>
+										<view class="quickList" v-if="item.list.length > 0">
+											<view class="list-items" v-for="(qItem,indx) in item.list" @click="quickQs(qItem)">
+											{{qItem.question}}
+											</view>
+										</view>
+									</view>
 								</view>
+								<image :src="item.avatar" v-if="item.userType === 'self'" class="avatar" mode="widthFix"></image>
 							</view>
-							<image :src="item.avatar" v-if="item.userType === 'self'" class="avatar" mode="widthFix"></image>
 						</view>
+					</template>
+				</view>
+			</scroll-view>
+			<view class="tool">
+				<view class="tool-option">
+					<view class="input-text">
+						<textarea class="input" placeholder="输入点什么呢..." auto-height="true" confirm-type="send" type="text"
+							:maxlength="-1" :adjust-position="false" v-model="text" confirm-hold @focus="focus" :focus="isFocus" @blur="isFocus = false"
+							:show-confirm-bar="false" @confirm="sendingText" @keyboardheightchange="keyboardheightchange" />
+					</view>
+					<view class="check-img">
+						<view class="check-icon" @click="tapEmoji"><image src="@/static/image/face.svg" mode="aspectFill"></image></view>
+						<view class="check-icon" @click="tapMore"><image src="@/static/image/more.svg" mode="aspectFill"></image></view>
 					</view>
-				</template>
-			</view>
-		</scroll-view>
-		<view class="tool">
-			<view class="tool-bar">
-				<view class="bar-item">
-					<image src="https://jymini.oss-cn-guangzhou.aliyuncs.com/mini/order.svg"></image>
-					<view class="name">我的订单</view>
-				</view>
-				<view class="bar-item">
-					<image src="https://jymini.oss-cn-guangzhou.aliyuncs.com/mini/order.svg"></image>
-					<view class="name">转人工</view>
 				</view>
 			</view>
-			<view class="tool-option">
-				<view class="input-text">
-					<textarea class="input" placeholder="输入点什么呢..." auto-height="true" confirm-type="send" type="text"
-						:maxlength="-1" :adjust-position="false" v-model="text" confirm-hold
-						:show-confirm-bar="false" @confirm="sendingText" @keyboardheightchange="keyboardheightchange" />
-				</view>
-				<view class="check-img">
-					<view class="check-icon" @click="tapEmoji"><image src="@/static/image/face.svg" mode="aspectFill"></image></view>
-					<view class="check-icon" @click="tapMore"><image src="@/static/image/more.svg" mode="aspectFill"></image></view>
-				</view>
-			</view>
+			<template v-if="keyboardHeight>0">
+				<view class="keyboardheight" :style="{ height: keyboardHeight + 'px' }"></view>
+			</template>
+			<emoji v-model="isEmoji" @onEmoji="onEmoji" @deleteFn="deleteFn" @sendingText="sendingText" @sendingEmojiPack="sendingEmojiPack"></emoji>
+			<more v-model="isMore" @onMore="sendingMore"></more>
 		</view>
-		<template v-if="keyboardHeight>0">
-			<view class="keyboardheight" :style="{ height: keyboardHeight + 'px' }"></view>
-		</template>
-		<emoji v-model="isEmoji" @onEmoji="onEmoji" @deleteFn="deleteFn" @sendingText="sendingText" @sendingEmojiPack="sendingEmojiPack"></emoji>
-		<more v-model="isMore" @onMore="sendingMore"></more>
 	</view>
 </template>
 
 <script>
 var app;
-let cursor = 0; //输入框光标
+let cursor = 0; //输入框光标
+let getSelectedTextRangeSetInterval = null;
 import { mapState } from 'vuex';
 import {
 	show,
@@ -91,13 +94,16 @@ export default {
 				rows:20,	//每页数量
 				page:1,	//页码
 				flag:true,	// 请求开关
+				isSend:false,
+				last:0
 			},
 			screenWidth:0,
 			pushData: {
 				obj:null,
 				auth:"https://tran.jsshuita.cn/plugin/webman/push/auth",
 				url: 'wss://tran.jsshuita.cn/ws',
-			}
+			},
+			isFocus:false
 		}
 	},
 	onLoad() {
@@ -119,8 +125,18 @@ export default {
 				return '';
 			};
 		},
-	}),
+	}),
+	beforeDestroy() {
+		cursor = 0;
+		clearInterval(getSelectedTextRangeSetInterval);
+	},
 	methods: {
+		focus(){
+			this.setCursor();
+		},
+		setCursor() {
+
+		},
 		scroll(){},
 		// 滚动到顶部
 		scrolltoupper(){
@@ -162,8 +178,20 @@ export default {
 				this.scrollToBottom()
 			}, 150)
 		},
-		sendingMore(data){
-			console.log("sendingMore",data)
+		sendingMore(data){
+			switch (data.type) {
+				case 'img':
+					show("暂未开通");
+					// this.sendImageMessage();
+					break;
+				case 'video':
+					show("暂未开通");
+					break;
+				case 'order':
+					show("暂未开通");
+					// this.showOrder(1);
+					break;
+			}
 		},
 		scrollToBottom() {
 			if (this.isEmoji) {
@@ -208,14 +236,32 @@ export default {
 				this.text = this.text.substring(0, this.text.length - 1);
 			}
 		},
-		sendingText(){},
+		sendingText(){
+			if (app.text === '') return ;
+			app.msgData.isSend = true;
+			const sendMsg = app.text;
+			app.text = ''
+			setTimeout(function(){
+				app.msgData.isSend = false;
+				app.sendMessage(sendMsg,"text");
+				app.scrollToBottom()
+			},2000)
+		},
+		sendMessage(content,type){
+			const message = {
+				content: content,
+				userType: 'self',
+				avatar: "/static/logo.jpg",
+				msgType:type,
+				list:[],
+				messageId: Date.now(),
+				timestamp: Date.now(),
+			};
+			app.msgData.list.unshift(message);
+		},
 		getMessage(){
 			let get = async ()=>{
 				this.msgData.allLoaded = true;
-				console.log("loading",{
-					page:this.msgData.page,
-					rows: this.msgData.page == 3 ? 5 : this.msgData.rows
-				})
 				let data = await getHistoryMsg({
 					page:this.msgData.page,
 					rows: this.msgData.page == 3 ? 5 : this.msgData.rows
@@ -232,7 +278,6 @@ export default {
 						// 当前消息数据条数小于请求要求条数时,则无更多消息,不再允许请求。
 						// 可在此处编写无更多消息数据时的逻辑
 					}else{
-						console.log('到这了...')
 						this.msgData.flag = true;
 						this.msgData.allLoaded = false;
 						this.msgData.page ++;
@@ -253,7 +298,7 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.content{
+.chat-content{
     position: fixed;
     z-index: 1;
     top: 0;
@@ -263,6 +308,19 @@ export default {
     background-color: #ededed;
 	display: flex;
 	flex-direction: column;
+	z-index: 98;
+}
+.send-load {
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	z-index: 99;
+	text-align: center;
+	font-size: 28rpx;
+	color: $main-text-color;
+	background-color: #f4f4f5;
+	padding: 10rpx 0;
 }
 .msgLoading{
 	text-align: center;

TEMPAT SAMPAH
奥莱优品/static/image/goods/home.png


TEMPAT SAMPAH
奥莱优品/static/image/goods/order.png


TEMPAT SAMPAH
奥莱优品/static/image/goods/service.png


+ 1 - 0
奥莱优品/static/image/msg-order.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1786544665756" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1662" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M618.666667 192v170.666667a42.666667 42.666667 0 0 0 42.666666 42.666666h170.666667v384a42.666667 42.666667 0 0 1-42.666667 42.666667H277.333333a42.666667 42.666667 0 0 1-42.666666-42.666667V234.666667a42.666667 42.666667 0 0 1 42.666666-42.666667h341.333334z m42.666666 0l170.666667 170.666667h-149.333333a21.333333 21.333333 0 0 1-21.333334-21.333334V192zM362.666667 490.666667a21.333333 21.333333 0 0 0 0 42.666666h256a21.333333 21.333333 0 0 0 0-42.666666H362.666667z m0 128a21.333333 21.333333 0 0 0 0 42.666666h256a21.333333 21.333333 0 0 0 0-42.666666H362.666667z" fill="#515151" p-id="1663"></path></svg>

+ 1 - 0
奥莱优品/static/image/msg-photo.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1786544642108" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1360" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M832 689.066667V746.666667a42.666667 42.666667 0 0 1-42.666667 42.666666H234.666667a42.666667 42.666667 0 0 1-42.666667-42.666666v-57.984l149.162667-258.346667a21.333333 21.333333 0 0 1 29.141333-7.808L832 689.066667z m0-45.12L373.546667 379.264a42.666667 42.666667 0 0 0-58.282667 15.616L192 608.362667V277.333333a42.666667 42.666667 0 0 1 42.666667-42.666666h554.666666a42.666667 42.666667 0 0 1 42.666667 42.666666v366.613334zM682.666667 426.666667a42.666667 42.666667 0 1 0 0-85.333334 42.666667 42.666667 0 0 0 0 85.333334z" fill="#515151" p-id="1361"></path></svg>

+ 180 - 0
奥莱优品/static/js/common.js

@@ -0,0 +1,180 @@
+export default {
+	shopId: function() {
+		return "10108575743725";
+	},
+	clearUri(url){
+		var userInfo = uni.getStorageSync("user_data");
+		if(!userInfo){
+			uni.showLoading({
+				title:"加载中..."
+			});
+			setTimeout(function(){
+				uni.hideLoading();
+				uni.$u.route({
+					url:'/pages/user/user',
+					type:"switchTab",
+					animationType:"slide-in-bottom"
+				});
+			},800);
+			return ;
+		}
+		uni.$u.route({
+			url:url,
+			animationType:"slide-in-bottom",
+			animationDuration:300
+		});
+	},
+	jumpUri(url,type){
+		var userInfo = uni.getStorageSync("user_token");
+		if(!userInfo){
+			setTimeout(function(){
+				uni.hideLoading();
+				uni.navigateTo({
+					url:'/pages/auth/login',
+					animationType:"slide-in-bottom"
+				});
+			},800);
+			return false;
+		}
+		if(type == 1 && !userInfo){
+			uni.showToast({
+				title:"请先登录",
+				icon:"none"
+			});
+			return true;
+		}
+		uni.navigateTo({
+			url:url
+		})
+	},
+	//判断是否登录
+	navTo: function(url,param) {
+		uni.$u.route(url,param);
+	},
+	//判断是否登录
+	isLogin: function() {
+		return uni.getStorageSync("user") ? true : false
+	},
+	
+	/**
+	 * 操作成功提示框
+	 * @param {*} msg 
+	 * @param {*} callback 
+	 * @param {*} icon 
+	 */
+	showSuccess(msg,icon,callback){
+		uni.showToast({
+			title: msg,
+			icon: icon?icon:'none',
+			mask: true,
+			duration: 1500,
+			success() {
+				callback && (setTimeout(function() {
+					callback();
+				}, 1500));
+			}
+		});
+	},
+
+	/**
+	 * 操作错误提示
+	 * @param {*} msg 
+	 * @param {*} showCancel 
+	 * @param {*} callback 
+	 * @param {*} title 
+	 */
+	showError(msg,callback,title = "友情提示",showCancel = true){
+		uni.showModal({
+			title: title,
+			content: msg,
+			showCancel: showCancel,
+			success(res) {
+				callback && callback(res);
+			}
+		});
+	},
+	
+	showConfirm(msg,callback,title,yes,cancel){
+		plus.nativeUI.confirm(msg, function(e){
+				callback && callback(e);
+			},
+			{"title":title,"buttons":[yes?yes:"确定",cancel?cancel:"取消"]}
+		);
+	},
+	
+	showSysAlert(msg,callback,title,showCancel){
+		plus.nativeUI.alert(msg,callback,title,showCancel);
+	},
+	showSysMsg(msg){
+		plus.nativeUI.toast(msg);
+	},
+	/**
+	 * loading
+	 * @param {Object} msg
+	 * @param {Object} callback
+	 */
+	loading(msg,callback){
+		uni.showLoading({
+			title:msg ?? '请求中...',
+			mask:true,
+			success(res) {
+				callback && callback(res);
+			}
+		})
+	},
+	hideLoad(){
+		uni.hideLoading();
+	},
+	formatDate(value) {
+		const data = new Date(value);
+		const month = data.getMonth() + 1;
+		const day = data.getDate();
+		const year = data.getFullYear();
+		const hours = data.getHours();
+		const minutes = data.getMinutes();
+		const seconds = data.getSeconds();
+		const formattedTime = `${year}-${month}-${day}`;
+		// const formattedTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+		return formattedTime;
+	},
+	formatMoney(num,double = false) {
+		if (num == 0) return "¥0.00";
+		if (!double) {
+			return "¥"+num.toFixed(2);
+		}
+		return "¥"+(num / 100).toFixed(2);
+		// return Intl.NumberFormat("zh-CN", {
+		// 	style: "currency",
+		// 	currency: "CNY",
+		// 	minimumFractionDigits: 2,
+		// 	maximumFractionDigits: 2,
+		// }).format(num / 100);
+	},
+	disFormat(num,num2) {
+		if (!num) return "0";
+		if (!num2) return "0";
+		var total = ((num*100)/(num2*100)*10)
+		return total.toFixed(1)
+	},
+	dateFormat(date, fmt='yyyy-MM-dd hh:mm:ss') {
+		date = new Date(date)
+		var o = {
+			"M+" : date.getMonth()+1,                 //月份
+			"d+" : date.getDate(),                    //日
+			"h+" : date.getHours(),                   //小时
+			"m+" : date.getMinutes(),                 //分
+			"s+" : date.getSeconds(),                 //秒
+			"q+" : Math.floor((date.getMonth()+3)/3), //季度
+			"S"  : date.getMilliseconds()             //毫秒
+		};
+		if(/(y+)/.test(fmt)) {
+			fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
+		}
+		for(var k in o) {
+			if(new RegExp("("+ k +")").test(fmt)){
+				fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
+			}
+		}
+		return fmt;
+	}
+}

+ 267 - 0
奥莱优品/static/js/form.js

@@ -0,0 +1,267 @@
+/**
+ * 表单验证
+ * @author dingyong
+ * @version 1.4.0
+ **/
+
+const form = {
+	//当出现错误时返回错误消息,否则返回空即为验证通过
+	/*
+	 formData:Object 表单对象。{key:value,key:value},key==rules.name
+	 rules: Array [{name:name,rule:[],msg:[]},{name:name,rule:[],msg:[]}]
+			name:name 属性=> 元素的名称
+			rule:字符串数组 ["required","isMobile","isEmail","isCarNo","isIdCard","isAmount","isNum","isChinese","isEnglish",isEnAndNo","isSpecial","isEmoji",""isDate","isUrl","isSame:key","range:[1,9]","minLength:9","maxLength:Number"]
+			msg:数组 []。 与数组 rule 长度相同,对应的错误提示信息
+	*/
+	validation: function(formData, rules) {
+		for (let item of rules) {
+			let key = item.name;
+			let rule = item.rule;
+			let msgArr = item.msg;
+			if (!key || !rule || rule.length === 0 || !msgArr || msgArr.length === 0) {
+				continue;
+			}
+			for (let i = 0, length = rule.length; i < length; i++) {
+				let ruleItem = rule[i];
+				let msg = msgArr[i];
+				if (!ruleItem || !msg) {
+					continue;
+				}
+				//数据处理
+				let value = null;
+				if (~ruleItem.indexOf(":")) {
+					let temp = ruleItem.split(":");
+					ruleItem = temp[0];
+					value = temp[1];
+				}
+				let isError = false;
+				switch (ruleItem) {
+					case "required":
+						isError = form._isNullOrEmpty(formData[key]);
+						break;
+					case "isMobile":
+						isError = !form._isMobile(formData[key]);
+						break;
+					case "isEmail":
+						isError = !form._isEmail(formData[key]);
+						break;
+					case "isCarNo":
+						isError = !form._isCarNo(formData[key]);
+						break;
+					case "isIdCard":
+						isError = !form._isIdCard(formData[key]);
+						break;
+					case "isAmount":
+						isError = !form._isAmount(formData[key]);
+						break;
+					case "isNum":
+						isError = !form._isNum(formData[key]);
+						break;
+					case "isChinese":
+						isError = !form._isChinese(formData[key]);
+						break;
+					case "isEnglish":
+						isError = !form._isEnglish(formData[key]);
+						break;
+					case "isEnAndNo":
+						isError = !form._isEnAndNo(formData[key]);
+						break;
+					case "isEnOrNo":
+						isError = !form._isEnOrNo(formData[key]);
+						break;
+					case "isSpecial":
+						isError = form._isSpecial(formData[key]);
+						break;
+					case "isEmoji":
+						isError = form._isEmoji(formData[key]);
+						break;
+					case "isDate":
+						isError = !form._isDate(formData[key]);
+						break;
+					case "isUrl":
+						isError = !form._isUrl(formData[key]);
+						break;
+					case "isSame":
+						isError = !form._isSame(formData[key], formData[value]);
+						break;
+					case "range":
+						let range = null;
+						try {
+							range = JSON.parse(value);
+							if (range.length <= 1) {
+								throw new Error("range值传入有误!")
+							}
+						} catch (e) {
+							return "range值传入有误!"
+						}
+						isError = !form._isRange(formData[key], range[0], range[1])
+						break;
+					case "minLength":
+						isError = !form._minLength(formData[key], value)
+						break;
+					case "maxLength":
+						isError = !form._maxLength(formData[key], value)
+						break;
+					default:
+						break;
+				}
+				if (isError) {
+					return msg;
+				}
+			}
+		}
+		return "";
+	},
+	_isNullOrEmpty: function(value) {
+		return (value === null || value === '' || value === undefined) ? true : false;
+	},
+	_isMobile: function(value) {
+		return /^(?:13\d|14\d|15\d|16\d|17\d|18\d|19\d)\d{5}(\d{3}|\*{3})$/.test(value);
+	},
+	_isEmail: function(value) {
+		return /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/.test(value);
+	},
+	_isCarNo: function(value) {
+		// 新能源车牌
+		const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/;
+		// 旧车牌
+		const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/;
+		if (value.length === 7) {
+			return creg.test(value);
+		} else if (value.length === 8) {
+			return xreg.test(value);
+		} else {
+			return false;
+		}
+	},
+	_isIdCard: function(value) {
+		let idCard = value;
+		if (idCard.length == 15) {
+			return this.__isValidityBrithBy15IdCard;
+		} else if (idCard.length == 18) {
+			let arrIdCard = idCard.split("");
+			if (this.__isValidityBrithBy18IdCard(idCard) && this.__isTrueValidateCodeBy18IdCard(arrIdCard)) {
+				return true;
+			} else {
+				return false;
+			}
+		} else {
+			return false;
+		}
+	},
+	__isTrueValidateCodeBy18IdCard: function(arrIdCard) {
+		let sum = 0;
+		let Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1];
+		let ValideCode = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2];
+		if (arrIdCard[17].toLowerCase() == 'x') {
+			arrIdCard[17] = 10;
+		}
+		for (let i = 0; i < 17; i++) {
+			sum += Wi[i] * arrIdCard[i];
+		}
+		let valCodePosition = sum % 11;
+		if (arrIdCard[17] == ValideCode[valCodePosition]) {
+			return true;
+		} else {
+			return false;
+		}
+	},
+	__isValidityBrithBy18IdCard: function(idCard18) {
+		let year = idCard18.substring(6, 10);
+		let month = idCard18.substring(10, 12);
+		let day = idCard18.substring(12, 14);
+		let temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day));
+		if (temp_date.getFullYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1 || temp_date.getDate() !=
+			parseFloat(day)) {
+			return false;
+		} else {
+			return true;
+		}
+	},
+	__isValidityBrithBy15IdCard: function(idCard15) {
+		let year = idCard15.substring(6, 8);
+		let month = idCard15.substring(8, 10);
+		let day = idCard15.substring(10, 12);
+		let temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day));
+
+		if (temp_date.getYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1 || temp_date.getDate() !=
+			parseFloat(day)) {
+			return false;
+		} else {
+			return true;
+		}
+	},
+	_isAmount: function(value) {
+		//金额,只允许保留两位小数
+		return /^([0-9]*[.]?[0-9])[0-9]{0,1}$/.test(value);
+	},
+	_isNum: function(value) {
+		//只能为数字
+		return /^[0-9]+$/.test(value);
+	},
+	_isChinese: function(value) {
+		let reg = /.*[\u4e00-\u9fa5]+.*$/;
+		return value !== "" && reg.test(value) && !form._isSpecial(value) && !form._isEmoji(value)
+	},
+	_isEnglish: function(value) {
+		return /^[a-zA-Z]*$/.test(value)
+	},
+	_isEnAndNo: function(value) {
+		//8~20位数字和字母组合
+		return /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/.test(value);
+	},
+	_isEnOrNo: function(value) {
+		//英文或者数字
+		let reg = /.*[\u4e00-\u9fa5]+.*$/;
+		let result = true;
+		if (reg.test(value) || form._isSpecial(value) || form._isEmoji(value)) {
+			result = false
+		}
+		return result
+	},
+	_isSpecial: function(value) {
+		//是否包含特殊字符
+		let regEn = /[`~!@#$%^&*()_+<>?:"{},.\/;'[\]]/im,
+			regCn = /[·!#¥(——):;“”‘、,|《。》?、【】[\]]/im;
+		if (regEn.test(value) || regCn.test(value)) {
+			return true;
+		}
+		return false;
+	},
+	_isEmoji: function(value) {
+		//是否包含表情
+		return /\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g.test(value);
+	},
+	_isDate: function(value) {
+		//2019-10-12
+		const reg =
+			/^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/;
+		return reg.test(value);
+	},
+	_isUrl: function(value) {
+		return /^((https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/.test(value);
+	},
+	_isSame: function(value1, value2) {
+		return value1 === value2
+	},
+	_isRange: function(value, range1, range2) {
+		if ((!range1 && range1 != 0) && (!range2 && range2 != 0)) {
+			return true;
+		} else if (!range1 && range1 != 0) {
+			return value <= range2
+		} else if (!range2 && range2 != 0) {
+			return value >= range1
+		} else {
+			return value >= range1 && value <= range2
+		}
+	},
+	_minLength: function(value, min) {
+		return value.length >= Number(min)
+	},
+	_maxLength: function(value, max) {
+		return value.length <= Number(max)
+	}
+};
+module.exports = {
+	validation: form.validation
+};

File diff ditekan karena terlalu besar
+ 1 - 0
奥莱优品/static/js/pako.es5.min.js


+ 574 - 0
奥莱优品/static/js/push.js

@@ -0,0 +1,574 @@
+// tiktok-push.js
+// 抖音小程序 WebSocket 推送模块(完整修复版)
+// 支持频道订阅、心跳保活、自动重连、私有频道认证
+
+// ==================== 辅助函数 ====================
+function getGlobalObject() {
+  if (typeof global !== 'undefined') return global;
+  if (typeof window !== 'undefined') return window;
+  return this;
+}
+
+// ==================== CallbackRegistry ====================
+function CallbackRegistry() {
+  this._callbacks = {};
+}
+
+function prefix(name) {
+  return '_' + name;
+}
+
+CallbackRegistry.prototype.get = function (name) {
+  var key = prefix(name);
+  return this._callbacks[key] || [];
+};
+
+CallbackRegistry.prototype.add = function (name, callback, context) {
+  var key = prefix(name);
+  if (!this._callbacks[key]) {
+    this._callbacks[key] = [];
+  }
+  this._callbacks[key].push({
+    fn: callback,
+    context: context
+  });
+};
+
+CallbackRegistry.prototype.remove = function (name, callback, context) {
+  if (!name && !callback && !context) {
+    this._callbacks = {};
+    return;
+  }
+  var names = name ? [prefix(name)] : Object.keys(this._callbacks);
+  for (var i = 0; i < names.length; i++) {
+    var key = names[i];
+    if (!this._callbacks[key]) continue;
+    if (callback || context) {
+      var filtered = [];
+      for (var j = 0; j < this._callbacks[key].length; j++) {
+        var cb = this._callbacks[key][j];
+        if ((callback && callback !== cb.fn) || (context && context !== cb.context)) {
+          filtered.push(cb);
+        }
+      }
+      if (filtered.length === 0) {
+        delete this._callbacks[key];
+      } else {
+        this._callbacks[key] = filtered;
+      }
+    } else {
+      delete this._callbacks[key];
+    }
+  }
+};
+
+// ==================== Dispatcher ====================
+function Dispatcher(failThrough) {
+  this.callbacks = new CallbackRegistry();
+  this.global_callbacks = [];
+  this.failThrough = failThrough;
+}
+
+Dispatcher.prototype.on = function (eventName, callback, context) {
+  this.callbacks.add(eventName, callback, context);
+  return this;
+};
+
+Dispatcher.prototype.on_global = function (callback) {
+  if (typeof callback === 'function') {
+    this.global_callbacks.push(callback);
+  }
+  return this;
+};
+
+Dispatcher.prototype.off = function (eventName, callback, context) {
+  this.callbacks.remove(eventName, callback, context);
+  return this;
+};
+
+Dispatcher.prototype.emit = function (eventName, data) {
+  // 全局回调
+  if (Array.isArray(this.global_callbacks)) {
+    for (var i = 0; i < this.global_callbacks.length; i++) {
+      var gc = this.global_callbacks[i];
+      if (typeof gc === 'function') {
+        try {
+          gc(eventName, data);
+        } catch (e) {
+          console.error('global callback error:', e);
+        }
+      }
+    }
+  }
+
+  // 获取事件回调列表
+  var callbacks = null;
+  try {
+    callbacks = this.callbacks && this.callbacks.get ? this.callbacks.get(eventName) : null;
+  } catch (e) {
+    console.warn('get callbacks error:', e);
+  }
+
+  if (callbacks && Array.isArray(callbacks) && callbacks.length > 0) {
+    for (var j = 0; j < callbacks.length; j++) {
+      var item = callbacks[j];
+      if (item && typeof item.fn === 'function') {
+        var ctx = item.context || getGlobalObject();
+        try {
+          item.fn.call(ctx, data);
+        } catch (e) {
+          console.error('callback error for event "' + eventName + '":', e);
+        }
+      }
+    }
+  } else if (this.failThrough && typeof this.failThrough === 'function') {
+    this.failThrough(eventName, data);
+  }
+
+  return this;
+};
+
+// ==================== Channel ====================
+function Channel(connection, channel_name) {
+  this.subscribed = false;
+  this.dispatcher = new Dispatcher();
+  this.connection = connection;
+  this.channelName = channel_name;
+  this.subscribeCb = null;
+  this.queue = [];
+
+  // 绑定 dispatcher 方法,确保 this 指向 dispatcher
+  this.on = this.dispatcher.on.bind(this.dispatcher);
+  this.off = this.dispatcher.off.bind(this.dispatcher);
+  this.emit = this.dispatcher.emit.bind(this.dispatcher);
+  this.on_global = this.dispatcher.on_global.bind(this.dispatcher);
+}
+
+Channel.prototype.processSubscribe = function () {
+  if (this.connection.state !== 'connected') {
+    return;
+  }
+  if (this.subscribeCb) {
+    this.subscribeCb();
+  }
+};
+
+Channel.prototype.processQueue = function () {
+  if (this.connection.state !== 'connected' || !this.subscribed) {
+    return;
+  }
+  for (var i = 0; i < this.queue.length; i++) {
+    try {
+      this.queue[i]();
+    } catch (e) {
+      console.error('processQueue error:', e);
+    }
+  }
+  this.queue = [];
+};
+
+Channel.prototype.trigger = function (event, data) {
+  if (event.indexOf('client-') !== 0) {
+    throw new Error("Event '" + event + "' should start with 'client-'");
+  }
+  var self = this;
+  this.queue.push(function () {
+    self.connection.send(JSON.stringify({ event: event, data: data, channel: self.channelName }));
+  });
+  this.processQueue();
+};
+
+// ==================== Connection ====================
+function Connection(options) {
+  this.dispatcher = new Dispatcher();
+
+  // 绑定 dispatcher 方法
+  this.on = this.dispatcher.on.bind(this.dispatcher);
+  this.off = this.dispatcher.off.bind(this.dispatcher);
+  this.emit = this.dispatcher.emit.bind(this.dispatcher);
+  this.on_global = this.dispatcher.on_global.bind(this.dispatcher);
+
+  this.options = options;
+  this.state = 'initialized';
+  this.doNotConnect = 0;
+  this.reconnectInterval = 1000;
+  this.socketTask = null;
+  this.reconnectTimer = 0;
+  this.socket_id = null;
+
+  this.connect();
+}
+
+Connection.prototype.updateNetworkState = function (state) {
+  var old_state = this.state;
+  this.state = state;
+  if (old_state !== state) {
+    this.emit('state_change', { previous: old_state, current: state });
+  }
+};
+
+Connection.prototype.connect = function () {
+  var self = this;
+  this.doNotConnect = 0;
+
+  if (this.state === 'connected') {
+    console.log('networkState is "' + this.state + '" , no need to connect');
+    return;
+  }
+
+  if (this.reconnectTimer) {
+    clearTimeout(this.reconnectTimer);
+    this.reconnectTimer = 0;
+  }
+
+  this.closeAndClean();
+
+  var url = this.options.url;
+  var app_key = this.options.app_key;
+  var fullUrl = url + '/app/' + app_key;
+
+  this.socketTask = tt.connectSocket({
+    url: fullUrl,
+    success: function (res) {
+      console.log('WebSocket connect success, socketTaskId:', res.socketTaskId);
+    },
+    fail: function (err) {
+      console.error('WebSocket connect fail:', err);
+      self.updateNetworkState('disconnected');
+      if (!self.doNotConnect) {
+        self.waitReconnect();
+      }
+      if (self.options.onError) {
+        self.options.onError(err);
+      }
+    }
+  });
+
+  this.socketTask.onOpen(function (res) {
+    self.reconnectInterval = 1000;
+    if (self.doNotConnect) {
+      self.updateNetworkState('disconnected');
+      self.socketTask.close();
+      return;
+    }
+    self.updateNetworkState('connected');
+    if (self.options.onOpen) {
+      self.options.onOpen(res);
+    }
+  });
+
+  this.socketTask.onMessage(function (res) {
+    if (self.options.onMessage) {
+      self.options.onMessage(res);
+    }
+  });
+
+  this.socketTask.onClose(function (res) {
+	  console.log('WebSocket closed, code:', res);
+    self.updateNetworkState('disconnected');
+    if (!self.doNotConnect) {
+      self.waitReconnect();
+    }
+    if (self.options.onClose) {
+      self.options.onClose(res);
+    }
+  });
+
+  this.socketTask.onError(function (res) {
+	  console.log('WebSocket error, code:', res);
+    self.updateNetworkState('disconnected');
+    if (!self.doNotConnect) {
+      self.waitReconnect();
+    }
+    if (self.options.onError) {
+      self.options.onError(res);
+    }
+  });
+
+  this.updateNetworkState('connecting');
+};
+
+Connection.prototype.closeAndClean = function () {
+  if (this.socketTask) {
+    try {
+      this.socketTask.close();
+    } catch (e) {
+      console.warn('closeAndClean error:', e);
+    }
+    this.socketTask = null;
+  }
+  this.updateNetworkState('disconnected');
+};
+
+Connection.prototype.waitReconnect = function () {
+  if (this.state === 'connected' || this.state === 'connecting') {
+    return;
+  }
+  if (!this.doNotConnect) {
+    this.updateNetworkState('connecting');
+    var self = this;
+    if (this.reconnectTimer) {
+      clearTimeout(this.reconnectTimer);
+    }
+    this.reconnectTimer = setTimeout(function () {
+      self.connect();
+    }, this.reconnectInterval);
+    if (this.reconnectInterval < 1000) {
+      this.reconnectInterval = 1000;
+    } else {
+      this.reconnectInterval = Math.min(this.reconnectInterval * 2, 2000);
+    }
+  }
+};
+
+Connection.prototype.send = function (data) {
+  if (this.state !== 'connected') {
+    console.warn('state is "' + this.state + '", cannot send:', data);
+    return;
+  }
+  this.socketTask.send({
+    data: data,
+    fail: function (err) {
+      console.error('send fail:', err);
+    }
+  });
+};
+
+Connection.prototype.close = function () {
+  this.doNotConnect = 1;
+  this.updateNetworkState('disconnected');
+  if (this.socketTask) {
+    this.socketTask.close();
+  }
+};
+
+// ==================== Push 客户端 ====================
+function Push(options) {
+  this.doNotConnect = 0;
+  options = options || {};
+  options.heartbeat = options.heartbeat || 25000;
+  options.pingTimeout = options.pingTimeout || 10000;
+  this.config = options;
+  this.uid = 0;
+  this.channels = {};
+  this.connection = null;
+  this.pingTimeoutTimer = 0;
+  Push.instances.push(this);
+  this.createConnection();
+}
+
+Push.instances = [];
+
+Push.prototype.checkoutPing = function () {
+  var self = this;
+  setTimeout(function () {
+    if (self.connection.state === 'connected') {
+      self.connection.send('hi');
+      if (self.pingTimeoutTimer) {
+        clearTimeout(self.pingTimeoutTimer);
+        self.pingTimeoutTimer = 0;
+      }
+      self.pingTimeoutTimer = setTimeout(function () {
+        self.connection.closeAndClean();
+        if (!self.connection.doNotConnect) {
+          self.connection.waitReconnect();
+        }
+      }, self.config.pingTimeout);
+    }
+  }, this.config.heartbeat);
+};
+
+Push.prototype.channel = function (name) {
+  return this.channels[name];
+};
+
+Push.prototype.allChannels = function () {
+  return this.channels;
+};
+
+Push.prototype.createConnection = function () {
+  if (this.connection) {
+    throw new Error('Connection already exists');
+  }
+
+  var self = this;
+  var url = this.config.url;
+  var app_key = this.config.app_key;
+
+  function updateSubscribed() {
+    for (var i in self.channels) {
+      if (self.channels[i]) {
+        self.channels[i].subscribed = false;
+      }
+    }
+  }
+
+  this.connection = new Connection({
+    url: url,
+    app_key: app_key,
+    onOpen: function () {
+      self.connection.state = 'connected';
+      self.checkoutPing();
+    },
+    onMessage: function (res) {
+      if (self.pingTimeoutTimer) {
+        clearTimeout(self.pingTimeoutTimer);
+        self.pingTimeoutTimer = 0;
+      }
+
+      var params;
+      try {
+        params = JSON.parse(res.data);
+      } catch (e) {
+        console.warn('parse message error:', e, res.data);
+        return;
+      }
+
+      var event = params.event;
+      var channel_name = params.channel;
+
+      if (event === 'pusher:pong') {
+        self.checkoutPing();
+        return;
+      }
+      if (event === 'pusher:error') {
+        throw new Error(params.data && params.data.message);
+      }
+
+      var data = params.data;
+      var channel;
+
+      if (event === 'pusher_internal:subscription_succeeded') {
+        channel = self.channels[channel_name];
+        if (channel) {
+          channel.subscribed = true;
+          channel.processQueue();
+          channel.emit('pusher:subscription_succeeded');
+        }
+        return;
+      }
+
+      if (event === 'pusher:connection_established') {
+        self.connection.socket_id = data.socket_id;
+        self.connection.state = 'connected';
+        self.subscribeAll();
+        return;
+      }
+
+      if (event && event.indexOf('pusher_internal') !== -1) {
+        console.log('Event "' + event + '" not implemented');
+        return;
+      }
+
+      channel = self.channels[channel_name];
+      if (channel) {
+        if (typeof data === 'string') {
+          try {
+            data = JSON.parse(data);
+          } catch (e) {}
+        }
+        channel.emit(event, data);
+      }
+    },
+    onClose: function () {
+      updateSubscribed();
+    },
+    onError: function () {
+      updateSubscribed();
+    }
+  });
+};
+
+Push.prototype.disconnect = function () {
+  this.connection.doNotConnect = 1;
+  this.connection.close();
+};
+
+Push.prototype.subscribeAll = function () {
+  if (this.connection.state !== 'connected') {
+    return;
+  }
+  for (var channel_name in this.channels) {
+    if (this.channels[channel_name]) {
+      this.channels[channel_name].processSubscribe();
+    }
+  }
+};
+
+Push.prototype.unsubscribe = function (channel_name) {
+  if (this.channels[channel_name]) {
+    delete this.channels[channel_name];
+    if (this.connection.state === 'connected') {
+      this.connection.send(JSON.stringify({ event: 'pusher:unsubscribe', data: { channel: channel_name } }));
+    }
+  }
+};
+
+Push.prototype.unsubscribeAll = function () {
+  for (var channel_name in this.channels) {
+    this.unsubscribe(channel_name);
+  }
+  this.channels = {};
+};
+
+Push.prototype.subscribe = function (channel_name) {
+  if (this.channels[channel_name]) {
+    return this.channels[channel_name];
+  }
+  if (channel_name.indexOf('private-') === 0) {
+    return createPrivateChannel(channel_name, this);
+  }
+  if (channel_name.indexOf('presence-') === 0) {
+    return createPresenceChannel(channel_name, this);
+  }
+  return createChannel(channel_name, this);
+};
+
+// ==================== 频道创建辅助函数 ====================
+function createChannel(channel_name, push) {
+  var channel = new Channel(push.connection, channel_name);
+  push.channels[channel_name] = channel;
+  channel.subscribeCb = function () {
+    push.connection.send(JSON.stringify({ event: 'pusher:subscribe', data: { channel: channel_name } }));
+  };
+  channel.processSubscribe();
+  return channel;
+}
+
+function createPrivateChannel(channel_name, push) {
+  var channel = new Channel(push.connection, channel_name);
+  push.channels[channel_name] = channel;
+  channel.subscribeCb = function () {
+    tt.request({
+      url: push.config.auth,
+      method: 'POST',
+      data: { channel_name: channel_name, socket_id: push.connection.socket_id },
+      success: function (res) {
+        var data;
+        try {
+          data = res.data;
+        } catch (e) {
+          console.error('parse auth response error:', e);
+          return;
+        }
+        data.channel = channel_name;
+        push.connection.send(JSON.stringify({ event: 'pusher:subscribe', data: data }));
+      },
+      fail: function (err) {
+        console.error('auth request fail:', err);
+        throw new Error(err.errMsg);
+      }
+    });
+  };
+  channel.processSubscribe();
+  return channel;
+}
+
+function createPresenceChannel(channel_name, push) {
+  return createPrivateChannel(channel_name, push);
+}
+
+// ==================== 导出 ====================
+module.exports = {
+  Push: Push
+};

+ 277 - 0
奥莱优品/static/js/request.js

@@ -0,0 +1,277 @@
+/**
+ * 常用方法封装 请求,文件上传等
+ * @author echo.
+ **/
+
+ import pako from './pako.es5.min.js'
+
+const axg = {
+	shopId: function() {
+		return "7644106137976965139";
+	},
+	//接口地址
+	interfaceUrl: function() {
+		// #ifdef H5
+		return '/api';
+		// #endif
+		// #ifdef MP
+		// return 'https://tran.jsshuita.cn/v2'
+		return 'http://127.0.0.1:9881/v2'
+		// #endif
+	},
+	toast: function(text, duration, success) {
+		// #ifdef APP-PLUS
+		plus.nativeUI.toast(text || "出错啦~");
+		// #endif
+		// #ifndef MP
+		uni.showToast({
+			title: text || "出错啦~",
+			icon: success ? 'success' : 'none',
+			duration: duration || 2000
+		})
+		// #endif
+	},
+	modal: function(title, content, showCancel, callback, confirmColor, confirmText) {
+		uni.showModal({
+			title: title || '提示',
+			content: content,
+			showCancel: showCancel,
+			cancelColor: "#555",
+			confirmColor: confirmColor || "#5677fc",
+			confirmText: confirmText || "确定",
+			success(res) {
+				if (res.confirm) {
+					callback && callback(true)
+				} else {
+					callback && callback(false)
+				}
+			}
+		})
+	},
+	isAndroid: function() {
+		const res = uni.getSystemInfoSync();
+		if(res.platform.toLocaleLowerCase() == 'android')
+		{
+			return true;
+		}
+		return false;
+	},
+	isPhoneX: function() {
+		const res = uni.getSystemInfoSync();
+		let iphonex = false;
+		let models=['iphonex','iphonexr','iphonexsmax','iphone11','iphone11pro','iphone11promax']
+		const model=res.model.replace(/\s/g,"").toLowerCase()
+		if (models.includes(model)) {
+			iphonex = true;
+		}
+		return iphonex;
+	},
+	constNum: function() {
+		let time = 0;
+		// #ifdef APP-PLUS
+		time = this.isAndroid() ? 300 : 0;
+		// #endif
+		return time
+	},
+	delayed: null,
+	decompress(str) {
+		try {
+			return pako.inflateRaw(axg.base64ToUint8Array(str), {
+				to: 'string'
+			});
+		} catch (error) {
+			console.error('解压数据失败:', error);
+			throw error;
+		}
+	},
+	base64ToUint8Array(base64String) {
+	  let padding = '='.repeat((4 - base64String.length % 4) % 4);
+	  let base64 = (base64String + padding)
+	    .replace(/\-/g, '+')
+	    .replace(/_/g, '/');
+	  let rawData = axg.atob(base64);
+	  let outputArray = new Uint8Array(rawData.length);
+	  for (let i = 0; i < rawData.length; ++i) {
+	    outputArray[i] = rawData.charCodeAt(i);
+	  }
+	  return outputArray;
+	},
+	atob(input) {
+	  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+	  let str = input.replace(/=+$/, '');
+	  let output = '';
+	  if (str.length % 4 === 1) {
+	    throw new Error('InvalidLengthError');
+	  }
+	  for (let i = 0, len = str.length; i < len; i += 4) {
+	    const a = chars.indexOf(str.charAt(i));
+	    const b = chars.indexOf(str.charAt(i + 1));
+	    const c = chars.indexOf(str.charAt(i + 2));
+	    const d = chars.indexOf(str.charAt(i + 3));
+	    const sum = (a << 18) | (b << 12) | (c << 6) | d;
+	    output += String.fromCharCode((sum >> 16) & 0xFF, (sum >> 8) & 0xFF, sum & 0xFF);
+	  }
+
+	  return output;
+	},
+	/**
+	 * 请求数据处理
+	 * @param string url 请求地址
+	 * @param string method 请求方式
+	 *  GET or POST
+	 * @param {*} postData 请求参数
+	 * @param bool isDelay 是否延迟显示loading
+	 * @param bool isForm 数据格式
+	 *  true: 'application/x-www-form-urlencoded'
+	 *  false:'application/json'
+	 * @param bool hideLoading 是否隐藏loading
+	 *  true: 隐藏
+	 *  false:显示
+	 */
+	request: function(url, method, postData, isDelay, isForm, hideLoading) {
+		//接口请求
+		let loadding = false;
+		axg.delayed && uni.hideLoading();
+		clearTimeout(axg.delayed);
+		axg.delayed = null;
+		if (!hideLoading) {
+			axg.delayed = setTimeout(() => {
+				uni.showLoading({
+					mask: true,
+					title: '请求中...',
+					success(res) {
+						loadding = true
+					}
+				})
+			}, isDelay ? 1000 : 0)
+		}
+		var header = {
+			'Content-Type': isForm ? 'application/x-www-form-urlencoded' : 'application/json',
+			'authorization': "Bearer "+axg.getToken(),
+			'api-type': "mini"
+		}
+		// postData.shop = axg.shopId();
+
+		return new Promise((resolve, reject) => {
+			uni.request({
+				url: axg.interfaceUrl() + url,
+				data: postData,
+				header: header,
+				method: method, //'GET','POST'
+				dataType: 'json',
+				success: (res) => {
+					clearTimeout(axg.delayed)
+					axg.delayed = null;
+					uni.hideLoading()
+					if (loadding && !hideLoading) {
+						uni.hideLoading()
+					}
+					if (res.data && res.data.code == 401) {
+						uni.showToast({
+							title: res.data.msg,
+							icon: 'none',
+							mask: true,
+							duration: 1500,
+							success() {
+								uni.clearStorageSync();
+								uni.navigateTo({
+									url:"/pages/auth/login"
+								});
+							}
+						});
+						return ;
+					}
+					if (res.data && res.data.encode) {
+						try
+						{
+							res.data = JSON.parse(axg.decompress(res.data.data));
+						}catch(e){
+							res.data = axg.decompress(decodeURI(res.data.data));
+						}
+					}
+					resolve(res.data)
+				},
+				fail: (res) => {
+					clearTimeout(axg.delayed)
+					axg.delayed = null;
+					axg.toast("网络不给力,请稍后再试~")
+					reject(res)
+				}
+			})
+		})
+	},
+	/**
+	 * 上传文件
+	 * @param string url 请求地址
+	 * @param string src 文件路径
+	 */
+	uploadFile: function(url, src, param) {
+		return new Promise((resolve, reject) => {
+			const uploadTask = uni.uploadFile({
+				url: axg.interfaceUrl() + url,
+				filePath: src,
+				name: 'file',
+				header: {
+					'authorization': "Bearer "+axg.getToken(),
+					'platform': "mini",
+					'api-type': "mini"
+				},
+				formData:param,
+				success: function(res) {
+					uni.hideLoading()
+					console.log(res)
+					let d = JSON.parse(res.data.replace(/\ufeff/g, "") || "{}")
+					if (res.statusCode == 200) {
+						//返回图片地址
+						let fileObj = d.data;
+						resolve(res.data)
+					} else {
+						axg.toast("系统响应错误");
+					}
+				},
+				fail: function(res) {
+					console.log('上传错误:',res)
+					reject(res)
+					axg.toast(res.msg);
+				}
+			})
+		})
+	},
+	tuiJsonp: function(url, callback, callbackname) {
+		// #ifdef H5
+		window[callbackname] = callback;
+		let tuiScript = document.createElement("script");
+		tuiScript.src = url;
+		tuiScript.type = "text/javascript";
+		document.head.appendChild(tuiScript);
+		document.head.removeChild(tuiScript);
+		// #endif
+	},
+	//设置用户信息
+	setUserInfo: function(mobile, token) {
+		//uni.setStorageSync("thorui_token", token)
+		uni.setStorageSync("user_token", mobile)
+	},
+	//获取token
+	getToken() {
+		return uni.getStorageSync("user_token") || 'None'
+	},
+	//判断是否登录
+	isLogin: function() {
+		return uni.getStorageSync("user_token") ? true : false
+	},
+	//跳转页面,校验登录状态
+	href(url, isVerify) {
+		if (isVerify && !axg.isLogin()) {
+			uni.navigateTo({
+				url: '/pages/user/login/login'
+			})
+		} else {
+			uni.navigateTo({
+				url: url
+			});
+		}
+	}
+}
+
+export default axg

+ 0 - 833
奥莱优品/utils/js/push.js

@@ -1,833 +0,0 @@
-
-function Push(options) {
-    this.doNotConnect = 0;
-    options = options || {};
-    options.heartbeat  = options.heartbeat || 25000;
-    options.pingTimeout = options.pingTimeout || 10000;
-    this.config = options;
-    this.uid = 0;
-    this.channels = {};
-    this.connection = null;
-    this.pingTimeoutTimer = 0;
-    Push.instances.push(this);
-    this.createConnection();
-}
-
-Push.prototype.checkoutPing = function() {
-    var _this = this;
-    _this.checkoutPingTimer && clearTimeout(_this.checkoutPingTimer);
-    _this.checkoutPingTimer = setTimeout(function () {
-        _this.checkoutPingTimer = 0;
-        if (_this.connection.state === 'connected') {
-            _this.connection.send('{"event":"pusher:ping","data":{}}');
-            if (_this.pingTimeoutTimer) {
-                clearTimeout(_this.pingTimeoutTimer);
-                _this.pingTimeoutTimer = 0;
-            }
-            _this.pingTimeoutTimer = setTimeout(function () {
-                _this.connection.closeAndClean();
-                if (!_this.connection.doNotConnect) {
-                    _this.connection.waitReconnect();
-                }
-            }, _this.config.pingTimeout);
-        }
-    }, this.config.heartbeat);
-};
-
-Push.prototype.channel = function (name) {
-    return this.channels.find(name);
-};
-Push.prototype.allChannels = function () {
-    return this.channels.all();
-};
-Push.prototype.createConnection = function () {
-    if (this.connection) {
-        throw Error('Connection already exist');
-    }
-    var _this = this;
-    var url = this.config.url;
-    function updateSubscribed () {
-        for (var i in _this.channels) {
-            _this.channels[i].subscribed = false;
-        }
-    }
-    this.connection = new Connection({
-        url: url,
-        app_key: this.config.app_key,
-        onOpen: function () {
-            _this.connection.state  = 'connecting';
-            _this.checkoutPing();
-        },
-        onMessage: function(params) {
-            if(_this.pingTimeoutTimer) {
-                clearTimeout(_this.pingTimeoutTimer);
-                _this.pingTimeoutTimer = 0;
-            }
-
-            params = JSON.parse(params.data);
-            var event = params.event;
-            var channel_name = params.channel;
-
-            if (event === 'pusher:pong') {
-                _this.checkoutPing();
-                return;
-            }
-            if (event === 'pusher:error') {
-                throw Error(params.data.message);
-            }
-            var data = JSON.parse(params.data), channel;
-            if (event === 'pusher_internal:subscription_succeeded') {
-                channel = _this.channels[channel_name];
-                channel.subscribed = true;
-                channel.processQueue();
-                channel.emit('pusher:subscription_succeeded');
-                return;
-            }
-            if (event === 'pusher:connection_established') {
-                _this.connection.socket_id = data.socket_id;
-                _this.connection.updateNetworkState('connected');
-                _this.subscribeAll();
-            }
-            if (event.indexOf('pusher_internal') !== -1) {
-                console.log("Event '"+event+"' not implement");
-                return;
-            }
-            channel = _this.channels[channel_name];
-            if (channel) {
-                channel.emit(event, data);
-            }
-        },
-        onClose: function () {
-            updateSubscribed();
-        },
-        onError: function () {
-            updateSubscribed();
-        }
-    });
-};
-Push.prototype.disconnect = function () {
-    this.connection.doNotConnect = 1;
-    this.connection.close();
-};
-
-Push.prototype.subscribeAll = function () {
-    if (this.connection.state !== 'connected') {
-        return;
-    }
-    for (var channel_name in this.channels) {
-        //this.connection.send(JSON.stringify({event:"pusher:subscribe", data:{channel:channel_name}}));
-        this.channels[channel_name].processSubscribe();
-    }
-};
-
-Push.prototype.unsubscribe = function (channel_name) {
-    if (this.channels[channel_name]) {
-        delete this.channels[channel_name];
-        if (this.connection.state === 'connected') {
-            this.connection.send(JSON.stringify({event:"pusher:unsubscribe", data:{channel:channel_name}}));
-        }
-    }
-};
-Push.prototype.unsubscribeAll = function () {
-    var channels = Object.keys(this.channels);
-    if (channels.length) {
-        if (this.connection.state === 'connected') {
-            for (var channel_name in this.channels) {
-                this.unsubscribe(channel_name);
-            }
-        }
-    }
-    this.channels = {};
-};
-Push.prototype.subscribe = function (channel_name) {
-    if (this.channels[channel_name]) {
-        return this.channels[channel_name];
-    }
-    if (channel_name.indexOf('private-') === 0) {
-        return createPrivateChannel(channel_name, this);
-    }
-    if (channel_name.indexOf('presence-') === 0) {
-        return createPresenceChannel(channel_name, this);
-    }
-    return createChannel(channel_name, this);
-};
-Push.instances = [];
-
-function createChannel(channel_name, push)
-{
-    var channel = new Channel(push.connection, channel_name);
-    push.channels[channel_name] = channel;
-    channel.subscribeCb = function () {
-        push.connection.send(JSON.stringify({event:"pusher:subscribe", data:{channel:channel_name}}));
-    }
-    channel.processSubscribe();
-    return channel;
-}
-
-function createPrivateChannel(channel_name, push)
-{
-    var channel = new Channel(push.connection, channel_name);
-    push.channels[channel_name] = channel;
-    channel.subscribeCb = function () {
-        __ajax({
-            url: push.config.auth,
-            type: 'POST',
-            data: {channel_name: channel_name, socket_id: push.connection.socket_id},
-            success: function (data) {
-                data = JSON.parse(data);
-                data.channel = channel_name;
-                push.connection.send(JSON.stringify({event:"pusher:subscribe", data:data}));
-            },
-            error: function (e) {
-                throw Error(e);
-            }
-        });
-    };
-    channel.processSubscribe();
-    return channel;
-}
-
-function createPresenceChannel(channel_name, push)
-{
-    return createPrivateChannel(channel_name, push);
-}
-
-uni.onNetworkStatusChange(function (res) {
-    if(res.isConnected) {
-        for (var i in Push.instances) {
-            var con = Push.instances[i].connection;
-            con.reconnectInterval = 1;
-            if (con.state === 'connecting') {
-                con.connect();
-            }
-        }
-    }
-});
-
-function Connection(options) {
-    this.dispatcher = new Dispatcher();
-    __extends(this, this.dispatcher);
-    var properies = ['on', 'off', 'emit'];
-    for (var i in properies) {
-        this[properies[i]] = this.dispatcher[properies[i]];
-    }
-    this.options = options;
-    this.state = 'initialized'; //initialized connecting connected disconnected
-    this.doNotConnect = 0;
-    this.reconnectInterval = 1;
-    this.connection = null;
-    this.reconnectTimer = 0;
-    this.connect();
-}
-
-Connection.prototype.updateNetworkState = function(state){
-    var old_state = this.state;
-    this.state = state;
-    if (old_state !== state) {
-        this.emit('state_change', { previous: old_state, current: state });
-    }
-};
-
-Connection.prototype.connect = function () {
-    this.doNotConnect = 0;
-    if (this.networkState == 'connecting' || this.networkState == 'established') {
-        console.log('networkState is ' + this.networkState + ' and do not need connect');
-        return;
-    }
-    if (this.reconnectTimer) {
-        clearTimeout(this.reconnectTimer);
-        this.reconnectTimer = 0;
-    }
-
-    this.closeAndClean();
-
-    var options = this.options;
-    var _this = this;
-    _this.updateNetworkState('connecting');
-    var cb = function(){
-        uni.onSocketOpen(function (res) {
-            _this.reconnectInterval = 1;
-            if (_this.doNotConnect) {
-                _this.updateNetworkState('closing');
-                uni.closeSocket();
-                return;
-            }
-            _this.updateNetworkState('established');
-            if (options.onOpen) {
-                options.onOpen(res);
-            }
-        });
-
-        if (options.onMessage) {
-            uni.onSocketMessage(options.onMessage);
-        }
-
-        uni.onSocketClose(function (res) {
-            _this.updateNetworkState('disconnected');
-            if (!_this.doNotConnect) {
-                _this.waitReconnect();
-            }
-            if (options.onClose) {
-                options.onClose(res);
-            }
-        });
-
-        uni.onSocketError(function (res) {
-            _this.close();
-            if (!_this.doNotConnect) {
-                _this.waitReconnect();
-            }
-            if (options.onError) {
-                options.onError(res);
-            }
-        });
-    };
-    uni.connectSocket({
-        url: options.url,
-        fail: function (res) {
-            console.log('uni.connectSocket fail');
-            console.log(res);
-            _this.updateNetworkState('disconnected');
-            _this.waitReconnect();
-        },
-        success: function() {
-
-        }
-    });
-    cb();
-}
-
-Connection.prototype.connect = function () {
-    this.doNotConnect = 0;
-    if (this.state === 'connected') {
-        console.log('networkState is "' + this.state + '" and do not need connect');
-        return;
-    }
-    if (this.reconnectTimer) {
-        clearTimeout(this.reconnectTimer);
-        this.reconnectTimer = 0;
-    }
-
-    this.closeAndClean();
-
-    var options = this.options;
-
-    this.updateNetworkState('connecting');
-
-    var _this = this;
-    var cb = function(){
-        uni.onSocketOpen(function (res) {
-            _this.reconnectInterval = 1;
-            if (_this.doNotConnect) {
-                _this.updateNetworkState('disconnected');
-                uni.closeSocket();
-                return;
-            }
-            if (options.onOpen) {
-                options.onOpen(res);
-            }
-        });
-
-        if (options.onMessage) {
-            uni.onSocketMessage(options.onMessage);
-        }
-
-        uni.onSocketClose(function (res) {
-            _this.updateNetworkState('disconnected');
-            if (!_this.doNotConnect) {
-                _this.waitReconnect();
-            }
-            if (options.onClose) {
-                options.onClose(res);
-            }
-        });
-
-        uni.onSocketError(function (res) {
-            _this.close();
-            if (!_this.doNotConnect) {
-                _this.waitReconnect();
-            }
-            if (options.onError) {
-                options.onError(res);
-            }
-        });
-    };
-    uni.connectSocket({
-        url: options.url+'/app/'+options.app_key,
-        fail: function (res) {
-            console.log('uni.connectSocket fail');
-            console.log(res);
-            _this.updateNetworkState('disconnected');
-            _this.waitReconnect();
-        },
-        success: function() {
-
-        }
-    });
-    cb();
-}
-
-Connection.prototype.closeAndClean = function () {
-    if (this.state === 'connected') {
-        uni.closeSocket();
-    }
-    this.updateNetworkState('disconnected');
-};
-
-Connection.prototype.waitReconnect = function () {
-    if (this.state === 'connected' || this.state === 'connecting') {
-        return;
-    }
-    if (!this.doNotConnect) {
-        this.updateNetworkState('connecting');
-        var _this = this;
-        if (this.reconnectTimer) {
-            clearTimeout(this.reconnectTimer);
-        }
-        this.reconnectTimer = setTimeout(function(){
-            _this.connect();
-        }, this.reconnectInterval);
-        if (this.reconnectInterval < 1000) {
-            this.reconnectInterval = 1000;
-        } else {
-            // 每次重连间隔增大一倍
-            this.reconnectInterval = this.reconnectInterval * 2;
-        }
-        // 有网络的状态下,重连间隔最大2秒
-        if (this.reconnectInterval > 2000) {
-            uni.getNetworkType({
-                success: function (res) {
-                    if (res.networkType != 'none') {
-                        _this.reconnectInterval = 1000;
-                    }
-                }
-            });
-        }
-    }
-}
-
-Connection.prototype.send = function(data) {
-    if (this.state !== 'connected') {
-        console.trace('networkState is "' + this.state + '", can not send ' + data);
-        return;
-    }
-    uni.sendSocketMessage({
-        data: data
-    });
-}
-
-Connection.prototype.close = function(){
-    this.updateNetworkState('disconnected');
-    uni.closeSocket();
-}
-
-var __extends = (this && this.__extends) || function (d, b) {
-    for (var p in b) if (b.hasOwnProperty(p)) {d[p] = b[p];}
-    function __() { this.constructor = d; }
-    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-};
-
-function Channel(connection, channel_name) {
-    this.subscribed = false;
-    this.dispatcher = new Dispatcher();
-    this.connection = connection;
-    this.channelName = channel_name;
-    this.subscribeCb = null;
-    this.queue = [];
-    __extends(this, this.dispatcher);
-    var properies = ['on', 'off', 'emit'];
-    for (var i in properies) {
-        this[properies[i]] = this.dispatcher[properies[i]];
-    }
-}
-
-Channel.prototype.processSubscribe = function () {
-    if (this.connection.state !== 'connected') {
-        return;
-    }
-    this.subscribeCb();
-};
-
-Channel.prototype.processQueue = function () {
-    if (this.connection.state !== 'connected' || !this.subscribed) {
-        return;
-    }
-    for (var i in this.queue) {
-        this.queue[i]();
-    }
-    this.queue = [];
-};
-
-Channel.prototype.trigger = function (event, data) {
-    if (event.indexOf('client-') !== 0) {
-        throw new Error("Event '" + event + "' should start with 'client-'");
-    }
-    var _this = this;
-    this.queue.push(function () {
-        _this.connection.send(JSON.stringify({ event: event, data: data, channel: _this.channelName }));
-    });
-    this.processQueue();
-};
-
-////////////////
-var Collections = (function () {
-    var exports = {};
-    function extend(target) {
-        var sources = [];
-        for (var _i = 1; _i < arguments.length; _i++) {
-            sources[_i - 1] = arguments[_i];
-        }
-        for (var i = 0; i < sources.length; i++) {
-            var extensions = sources[i];
-            for (var property in extensions) {
-                if (extensions[property] && extensions[property].constructor &&
-                    extensions[property].constructor === Object) {
-                    target[property] = extend(target[property] || {}, extensions[property]);
-                }
-                else {
-                    target[property] = extensions[property];
-                }
-            }
-        }
-        return target;
-    }
-
-    exports.extend = extend;
-    function stringify() {
-        var m = ["Push"];
-        for (var i = 0; i < arguments.length; i++) {
-            if (typeof arguments[i] === "string") {
-                m.push(arguments[i]);
-            }
-            else {
-                m.push(safeJSONStringify(arguments[i]));
-            }
-        }
-        return m.join(" : ");
-    }
-
-    exports.stringify = stringify;
-    function arrayIndexOf(array, item) {
-        var nativeIndexOf = Array.prototype.indexOf;
-        if (array === null) {
-            return -1;
-        }
-        if (nativeIndexOf && array.indexOf === nativeIndexOf) {
-            return array.indexOf(item);
-        }
-        for (var i = 0, l = array.length; i < l; i++) {
-            if (array[i] === item) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    exports.arrayIndexOf = arrayIndexOf;
-    function objectApply(object, f) {
-        for (var key in object) {
-            if (Object.prototype.hasOwnProperty.call(object, key)) {
-                f(object[key], key, object);
-            }
-        }
-    }
-
-    exports.objectApply = objectApply;
-    function keys(object) {
-        var keys = [];
-        objectApply(object, function (_, key) {
-            keys.push(key);
-        });
-        return keys;
-    }
-
-    exports.keys = keys;
-    function values(object) {
-        var values = [];
-        objectApply(object, function (value) {
-            values.push(value);
-        });
-        return values;
-    }
-
-    exports.values = values;
-    function apply(array, f, context) {
-        for (var i = 0; i < array.length; i++) {
-            f.call(context || (window), array[i], i, array);
-        }
-    }
-
-    exports.apply = apply;
-    function map(array, f) {
-        var result = [];
-        for (var i = 0; i < array.length; i++) {
-            result.push(f(array[i], i, array, result));
-        }
-        return result;
-    }
-
-    exports.map = map;
-    function mapObject(object, f) {
-        var result = {};
-        objectApply(object, function (value, key) {
-            result[key] = f(value);
-        });
-        return result;
-    }
-
-    exports.mapObject = mapObject;
-    function filter(array, test) {
-        test = test || function (value) {
-            return !!value;
-        };
-        var result = [];
-        for (var i = 0; i < array.length; i++) {
-            if (test(array[i], i, array, result)) {
-                result.push(array[i]);
-            }
-        }
-        return result;
-    }
-
-    exports.filter = filter;
-    function filterObject(object, test) {
-        var result = {};
-        objectApply(object, function (value, key) {
-            if ((test && test(value, key, object, result)) || Boolean(value)) {
-                result[key] = value;
-            }
-        });
-        return result;
-    }
-
-    exports.filterObject = filterObject;
-    function flatten(object) {
-        var result = [];
-        objectApply(object, function (value, key) {
-            result.push([key, value]);
-        });
-        return result;
-    }
-
-    exports.flatten = flatten;
-    function any(array, test) {
-        for (var i = 0; i < array.length; i++) {
-            if (test(array[i], i, array)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    exports.any = any;
-    function all(array, test) {
-        for (var i = 0; i < array.length; i++) {
-            if (!test(array[i], i, array)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    exports.all = all;
-    function encodeParamsObject(data) {
-        return mapObject(data, function (value) {
-            if (typeof value === "object") {
-                value = safeJSONStringify(value);
-            }
-            return encodeURIComponent(base64_1["default"](value.toString()));
-        });
-    }
-
-    exports.encodeParamsObject = encodeParamsObject;
-    function buildQueryString(data) {
-        var params = filterObject(data, function (value) {
-            return value !== undefined;
-        });
-        return map(flatten(encodeParamsObject(params)), util_1["default"].method("join", "=")).join("&");
-    }
-
-    exports.buildQueryString = buildQueryString;
-    function decycleObject(object) {
-        var objects = [], paths = [];
-        return (function derez(value, path) {
-            var i, name, nu;
-            switch (typeof value) {
-                case 'object':
-                    if (!value) {
-                        return null;
-                    }
-                    for (i = 0; i < objects.length; i += 1) {
-                        if (objects[i] === value) {
-                            return {$ref: paths[i]};
-                        }
-                    }
-                    objects.push(value);
-                    paths.push(path);
-                    if (Object.prototype.toString.apply(value) === '[object Array]') {
-                        nu = [];
-                        for (i = 0; i < value.length; i += 1) {
-                            nu[i] = derez(value[i], path + '[' + i + ']');
-                        }
-                    }
-                    else {
-                        nu = {};
-                        for (name in value) {
-                            if (Object.prototype.hasOwnProperty.call(value, name)) {
-                                nu[name] = derez(value[name], path + '[' + JSON.stringify(name) + ']');
-                            }
-                        }
-                    }
-                    return nu;
-                case 'number':
-                case 'string':
-                case 'boolean':
-                    return value;
-            }
-        }(object, '$'));
-    }
-
-    exports.decycleObject = decycleObject;
-    function safeJSONStringify(source) {
-        try {
-            return JSON.stringify(source);
-        }
-        catch (e) {
-            return JSON.stringify(decycleObject(source));
-        }
-    }
-
-    exports.safeJSONStringify = safeJSONStringify;
-    return exports;
-})();
-
-var Dispatcher = (function () {
-    function Dispatcher(failThrough) {
-        this.callbacks = new CallbackRegistry();
-        this.global_callbacks = [];
-        this.failThrough = failThrough;
-    }
-    Dispatcher.prototype.on = function (eventName, callback, context) {
-        this.callbacks.add(eventName, callback, context);
-        return this;
-    };
-    Dispatcher.prototype.on_global = function (callback) {
-        this.global_callbacks.push(callback);
-        return this;
-    };
-    Dispatcher.prototype.off = function (eventName, callback, context) {
-        this.callbacks.remove(eventName, callback, context);
-        return this;
-    };
-    Dispatcher.prototype.emit = function (eventName, data) {
-        var i;
-        for (i = 0; i < this.global_callbacks.length; i++) {
-            this.global_callbacks[i](eventName, data);
-        }
-        var callbacks = this.callbacks.get(eventName);
-        if (callbacks && callbacks.length > 0) {
-            for (i = 0; i < callbacks.length; i++) {
-                callbacks[i].fn.call(callbacks[i].context || (window), data);
-            }
-        }
-        else if (this.failThrough) {
-            this.failThrough(eventName, data);
-        }
-        return this;
-    };
-    return Dispatcher;
-}());
-
-var CallbackRegistry = (function () {
-    function CallbackRegistry() {
-        this._callbacks = {};
-    }
-    CallbackRegistry.prototype.get = function (name) {
-        return this._callbacks[prefix(name)];
-    };
-    CallbackRegistry.prototype.add = function (name, callback, context) {
-        var prefixedEventName = prefix(name);
-        this._callbacks[prefixedEventName] = this._callbacks[prefixedEventName] || [];
-        this._callbacks[prefixedEventName].push({
-            fn: callback,
-            context: context
-        });
-    };
-    CallbackRegistry.prototype.remove = function (name, callback, context) {
-        if (!name && !callback && !context) {
-            this._callbacks = {};
-            return;
-        }
-        var names = name ? [prefix(name)] : Collections.keys(this._callbacks);
-        if (callback || context) {
-            this.removeCallback(names, callback, context);
-        }
-        else {
-            this.removeAllCallbacks(names);
-        }
-    };
-    CallbackRegistry.prototype.removeCallback = function (names, callback, context) {
-        Collections.apply(names, function (name) {
-            this._callbacks[name] = Collections.filter(this._callbacks[name] || [], function (oning) {
-                return (callback && callback !== oning.fn) ||
-                    (context && context !== oning.context);
-            });
-            if (this._callbacks[name].length === 0) {
-                delete this._callbacks[name];
-            }
-        }, this);
-    };
-    CallbackRegistry.prototype.removeAllCallbacks = function (names) {
-        Collections.apply(names, function (name) {
-            delete this._callbacks[name];
-        }, this);
-    };
-    return CallbackRegistry;
-}());
-function prefix(name) {
-    return "_" + name;
-}
-
-function __ajax(options){
-    options=options||{};
-    options.type=(options.type||'GET').toUpperCase();
-    options.dataType=options.dataType||'json';
-    var params=formatParams(options.data);
-
-    var xhr;
-    if(window.XMLHttpRequest){
-        xhr=new XMLHttpRequest();
-    }else{
-        xhr=ActiveXObject('Microsoft.XMLHTTP');
-    }
-
-    xhr.onreadystatechange=function(){
-        if(xhr.readyState === 4){
-            var status=xhr.status;
-            if(status>=200 && status<300){
-                options.success&&options.success(xhr.responseText,xhr.responseXML);
-            }else{
-                options.error&&options.error(status);
-            }
-        }
-    }
-
-    if(options.type==='GET'){
-        xhr.open('GET',options.url+'?'+params,true);
-        xhr.send(null);
-    }else if(options.type==='POST'){
-        xhr.open('POST',options.url,true);
-        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
-        xhr.send(params);
-    }
-}
-
-function formatParams(data){
-    var arr=[];
-    for(var name in data){
-        arr.push(encodeURIComponent(name)+'='+encodeURIComponent(data[name]));
-    }
-    return arr.join('&');
-}
-
-export default Push

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini