代码更新
This commit is contained in:
parent
d27814d0b9
commit
f63f640a7b
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
// launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
|
||||||
|
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
|
||||||
|
"version" : "0.0",
|
||||||
|
"configurations" : [
|
||||||
|
{
|
||||||
|
"app-plus" : {
|
||||||
|
"launchtype" : "local"
|
||||||
|
},
|
||||||
|
"default" : {
|
||||||
|
"launchtype" : "local"
|
||||||
|
},
|
||||||
|
"type" : "uniCloud"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"playground" : "custom",
|
||||||
|
"type" : "uni-app:app-android"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
import request from "@/utils/request.js";
|
||||||
|
import requesta from "@/utils/requesta.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直播列表
|
||||||
|
*/
|
||||||
|
export function live(data) {
|
||||||
|
return request.get("zhibo/live" ,data);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 直播详情
|
||||||
|
*/
|
||||||
|
export function liveDetail(data) {
|
||||||
|
return request.get("zhibo/liveDetail" ,data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取直播详情接口
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建直播间
|
||||||
|
*/
|
||||||
|
export function createPushLive(data) {
|
||||||
|
return request.post("zhibo/createPushLive", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭直播间
|
||||||
|
*/
|
||||||
|
export function stopPushLive(data) {
|
||||||
|
return request.post("zhibo/stopPushLive", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定用户client客户
|
||||||
|
*/
|
||||||
|
export function bindUser(data) {
|
||||||
|
return request.post("zhibo/bindUser", data,{});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加入直播间聊天室
|
||||||
|
*/
|
||||||
|
export function joinChatRoom(data) {
|
||||||
|
return request.post("zhibo/joinChatRoom", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直播间聊天室发言
|
||||||
|
*/
|
||||||
|
export function sendGroupMessage(data) {
|
||||||
|
return request.post("zhibo/sendGroupMessage", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//商品列表
|
||||||
|
export function good(data) {
|
||||||
|
return requesta.get("product/spu/lst", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户信息
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function getUserInfo() {
|
||||||
|
return request.get('user');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//关注
|
||||||
|
export function getfans(id,data) {
|
||||||
|
return requesta.post('community/fans/'+id,data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//我关注的人
|
||||||
|
export function getfocuslst(data) {
|
||||||
|
return requesta.post('community/focus/lst',data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//关注我的人
|
||||||
|
export function getfanslst(data) {
|
||||||
|
return requesta.post('community/fans/lst',data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//用户送礼
|
||||||
|
export function reward(data) {
|
||||||
|
return request.post('zhibo/reward',data);
|
||||||
|
}
|
||||||
|
//获取礼物
|
||||||
|
export function rewardList(data) {
|
||||||
|
return requesta.get('zhibo/rewardList',data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取礼物
|
||||||
|
export function giftList(data) {
|
||||||
|
return request.get('zhibo/giftList',data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取房间人数
|
||||||
|
export function liveAudience(data) {
|
||||||
|
return request.get('zhibo/liveAudience',data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取用户余额
|
||||||
|
export function getuser(data) {
|
||||||
|
return requesta.get('user',data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//送礼
|
||||||
|
export function sendGift(data) {
|
||||||
|
return request.post('zhibo/sendGift',data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 充值金额选择
|
||||||
|
*/
|
||||||
|
export function getRechargeApi() {
|
||||||
|
return requesta.get("common/recharge_quota");
|
||||||
|
}
|
||||||
|
|
||||||
|
//历史直播记录
|
||||||
|
|
||||||
|
export function playbackList(data) {
|
||||||
|
return request.get("zhibo/playbackList",data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取直播回放详情
|
||||||
|
export function playbackDetail(data) {
|
||||||
|
return request.get("zhibo/playbackDetail",data);
|
||||||
|
}
|
||||||
|
//获取观众关注主播状态
|
||||||
|
export function getAjuser(data) {
|
||||||
|
return requesta.get("community/user/info/"+data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 滑块信息
|
||||||
|
* @param {Object} data
|
||||||
|
*/
|
||||||
|
export function getAjcaptcha(data) {
|
||||||
|
return requesta.get("ajcaptcha", data, {
|
||||||
|
noAuth: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 滑块验证
|
||||||
|
* @param {Object} data
|
||||||
|
*/
|
||||||
|
export function ajcaptchaCheck(data) {
|
||||||
|
return requesta.post("ajcheck", data, {
|
||||||
|
noAuth: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
import request from "@/utils/requesta.js";
|
||||||
|
|
||||||
|
export function getVersion() {
|
||||||
|
return request.get("version",{},{noAuth: true});
|
||||||
|
}
|
||||||
|
export function commonAuth(data) {
|
||||||
|
return request.post(
|
||||||
|
"auth", data, {
|
||||||
|
noAuth: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
import request from "@/utils/requesta.js";
|
||||||
|
|
||||||
|
|
||||||
|
export function getAdminApplyListAPI(merId) {
|
||||||
|
return request.get(`admin/${merId}/lis_apply`);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取用户信息
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function getUserInfo() {
|
||||||
|
return request.get('user');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function editAvatar(data) {
|
||||||
|
return request.post('user/change/info', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改昵称
|
||||||
|
export function updateInfo(data) {
|
||||||
|
return request.post('user/change/avatar', data);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* h5用户登录
|
||||||
|
* @param data object 用户账号密码
|
||||||
|
*/
|
||||||
|
export function loginH5(data) {
|
||||||
|
return request.post("auth/login", data, {
|
||||||
|
noAuth: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* h5用户手机号登录
|
||||||
|
* @param data object 用户手机号 也只能
|
||||||
|
*/
|
||||||
|
export function loginMobile(data) {
|
||||||
|
return request.post("auth/smslogin", data, {
|
||||||
|
noAuth: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* h5用户手机号登录
|
||||||
|
* @param data object 用户手机号 也只能
|
||||||
|
*/
|
||||||
|
export function loginMpPhone(data) {
|
||||||
|
return request.post("auth/mp_phone", data, {
|
||||||
|
noAuth: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 验证码key
|
||||||
|
*/
|
||||||
|
export function getCodeApi() {
|
||||||
|
return request.get("verify_code", {}, {
|
||||||
|
noAuth: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* h5用户发送验证码
|
||||||
|
* @param data object 用户手机号
|
||||||
|
*/
|
||||||
|
export function registerVerify(data) {
|
||||||
|
return request.post("auth/verify", data, {
|
||||||
|
noAuth: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* h5用户手机号注册
|
||||||
|
* @param data object 用户手机号 验证码 密码
|
||||||
|
*/
|
||||||
|
export function register(data) {
|
||||||
|
return request.post("auth/register", data, {
|
||||||
|
noAuth: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户手机号修改密码
|
||||||
|
* @param data object 用户手机号 验证码 密码
|
||||||
|
*/
|
||||||
|
export function registerReset(data) {
|
||||||
|
return request.post("/register/reset", data, {
|
||||||
|
noAuth: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 用户手机号忘记密码
|
||||||
|
*/
|
||||||
|
export function registerForget(data) {
|
||||||
|
return request.post("user/change_pwd", data, {
|
||||||
|
noAuth: true
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
<template>
|
||||||
|
<view class="empty-box">
|
||||||
|
<image src="/static/images/empty-box.png"></image>
|
||||||
|
<view class="txt">{{title}}</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
export default{
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: '暂无记录',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.empty-box{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 200rpx;
|
||||||
|
image{
|
||||||
|
width: 414rpx;
|
||||||
|
height: 240rpx;
|
||||||
|
}
|
||||||
|
.txt{
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,168 @@
|
||||||
|
<template>
|
||||||
|
<view class="men-ban box " v-if ='isShow' @touchmove.stop.prevent="">
|
||||||
|
<view class="box_next">
|
||||||
|
<view class="box_next_title">
|
||||||
|
<text class="box_next_title_z">{{title}}</text>
|
||||||
|
</view>
|
||||||
|
<slot></slot>
|
||||||
|
<view class="box_next_but_d" v-if="isBut">
|
||||||
|
<view @click='show' class="box_next_but_d_but">
|
||||||
|
<text class="box_next_but_d_but_text">{{nName}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="box_next_but_s" v-else>
|
||||||
|
<view class="box_next_but_s_lbut" @click="lEvent">
|
||||||
|
<text class="box_next_but_d_but_text">{{lName}}</text>
|
||||||
|
</view>
|
||||||
|
<view @click="rEvent" class="box_next_but_s_rbut" hover-class="zcolor-while1">
|
||||||
|
<text class="box_next_but_d_but_text">{{rName}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: "温馨提示"
|
||||||
|
},
|
||||||
|
isShow: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
nName: String,
|
||||||
|
lName: String,
|
||||||
|
rName: String,
|
||||||
|
isBut: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
show() {
|
||||||
|
|
||||||
|
this.$emit('show');
|
||||||
|
},
|
||||||
|
lEvent() {
|
||||||
|
this.$emit('lEvent');
|
||||||
|
},
|
||||||
|
rEvent() {
|
||||||
|
this.$emit('rEvent');
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.men-ban {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 999999;
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.box_next {
|
||||||
|
background-color: #ffffff;
|
||||||
|
width: 550rpx;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box_next_title {
|
||||||
|
padding: 30rpx 30rpx 0 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box_next_title_z {
|
||||||
|
font-size: 31rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box_next_but_d {
|
||||||
|
width: 550rpx;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 130rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box_next_but_d_but {
|
||||||
|
width: 500rpx;
|
||||||
|
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 80rpx;
|
||||||
|
border-radius: 50rpx;
|
||||||
|
background-color: #fee610;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box_next_but_d_but_text {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box_next_but_s {
|
||||||
|
width: 550rpx;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
height: 130rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box_next_but_s_lbut {
|
||||||
|
width: 200rpx;
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 80rpx;
|
||||||
|
border-radius: 50rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box_next_but_s_rbut {
|
||||||
|
width: 200rpx;
|
||||||
|
background-color: #fee610;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 80rpx;
|
||||||
|
border-radius: 50rpx;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,815 @@
|
||||||
|
<!--
|
||||||
|
parser 主模块组件
|
||||||
|
github:https://github.com/jin-yufeng/Parser
|
||||||
|
docs:https://jin-yufeng.github.io/Parser
|
||||||
|
插件市场:https://ext.dcloud.net.cn/plugin?id=805
|
||||||
|
author:JinYufeng
|
||||||
|
update:2020/04/14
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<slot v-if="!nodes.length" />
|
||||||
|
<!--#ifdef APP-PLUS-NVUE-->
|
||||||
|
<web-view id="top" ref="web" :src="src" :style="'margin-top:-2px;height:'+height+'px'" @onPostMessage="_message" />
|
||||||
|
<!--#endif-->
|
||||||
|
<!--#ifndef APP-PLUS-NVUE-->
|
||||||
|
<view id="top" :style="showAm+(selectable?';user-select:text;-webkit-user-select:text':'')" :animation="scaleAm" @tap="_tap"
|
||||||
|
@touchstart="_touchstart" @touchmove="_touchmove">
|
||||||
|
<!--#ifdef H5-->
|
||||||
|
<div :id="'rtf'+uid"></div>
|
||||||
|
<!--#endif-->
|
||||||
|
<!--#ifndef H5-->
|
||||||
|
<trees :nodes="nodes" :lazy-load="lazyLoad" :loadVideo="loadVideo" />
|
||||||
|
<image v-for="(item, index) in imgs" v-bind:key="index" :id="index" :src="item" hidden @load="_load" />
|
||||||
|
<!--#endif-->
|
||||||
|
<image v-for="(item, index) in imgs" v-bind:key="index" :id="index" :src="item" hidden @load="_load" />
|
||||||
|
</view>
|
||||||
|
<!--#endif-->
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// #ifndef H5 || APP-PLUS-NVUE
|
||||||
|
import trees from './libs/trees';
|
||||||
|
var cache = {},
|
||||||
|
// #ifdef MP-WEIXIN || MP-TOUTIAO
|
||||||
|
fs = uni.getFileSystemManager ? uni.getFileSystemManager() : null,
|
||||||
|
// #endif
|
||||||
|
Parser = require('./libs/MpHtmlParser.js');
|
||||||
|
var document; // document 补丁包 https://jin-yufeng.github.io/Parser/#/instructions?id=document
|
||||||
|
// 计算 cache 的 key
|
||||||
|
function hash(str) {
|
||||||
|
for (var i = str.length, val = 5381; i--;)
|
||||||
|
val += (val << 5) + str.charCodeAt(i);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5 || APP-PLUS-NVUE
|
||||||
|
var rpx = uni.getSystemInfoSync().screenWidth / 750,
|
||||||
|
cfg = require('./libs/config.js');
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS-NVUE
|
||||||
|
var dom = weex.requireModule('dom');
|
||||||
|
// #endif
|
||||||
|
export default {
|
||||||
|
name: 'parser',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
loadVideo: false,
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
uid: this._uid,
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS-NVUE
|
||||||
|
src: '',
|
||||||
|
height: 1,
|
||||||
|
// #endif
|
||||||
|
// #ifndef APP-PLUS-NVUE
|
||||||
|
scaleAm: '',
|
||||||
|
showAm: '',
|
||||||
|
imgs: [],
|
||||||
|
// #endif
|
||||||
|
nodes: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// #ifndef H5 || APP-PLUS-NVUE
|
||||||
|
components: {
|
||||||
|
trees
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
props: {
|
||||||
|
'html': null,
|
||||||
|
// #ifndef MP-ALIPAY
|
||||||
|
'autopause': {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
'autosetTitle': {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// #ifndef H5 || APP-PLUS-NVUE
|
||||||
|
'compress': Number,
|
||||||
|
'useCache': Boolean,
|
||||||
|
'xml': Boolean,
|
||||||
|
// #endif
|
||||||
|
'domain': String,
|
||||||
|
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||||
|
'gestureZoom': Boolean,
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN || MP-QQ || H5 || APP-PLUS
|
||||||
|
'lazyLoad': Boolean,
|
||||||
|
// #endif
|
||||||
|
'selectable': Boolean,
|
||||||
|
'tagStyle': Object,
|
||||||
|
'showWithAnimation': Boolean,
|
||||||
|
'useAnchor': Boolean
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
html(html) {
|
||||||
|
this.setContent(html);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// 图片数组
|
||||||
|
this.imgList = [];
|
||||||
|
this.imgList.each = function(f) {
|
||||||
|
for (var i = 0, len = this.length; i < len; i++)
|
||||||
|
this.setItem(i, f(this[i], i, this));
|
||||||
|
}
|
||||||
|
this.imgList.setItem = function(i, src) {
|
||||||
|
if (i == void 0 || !src) return;
|
||||||
|
// #ifndef MP-ALIPAY || APP-PLUS
|
||||||
|
// 去重
|
||||||
|
if (src.indexOf('http') == 0 && this.includes(src)) {
|
||||||
|
var newSrc = '';
|
||||||
|
for (var j = 0, c; c = src[j]; j++) {
|
||||||
|
if (c == '/' && src[j - 1] != '/' && src[j + 1] != '/') break;
|
||||||
|
newSrc += Math.random() > 0.5 ? c.toUpperCase() : c;
|
||||||
|
}
|
||||||
|
newSrc += src.substr(j);
|
||||||
|
return this[i] = newSrc;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
this[i] = src;
|
||||||
|
// 暂存 data src
|
||||||
|
if (src.includes('data:image')) {
|
||||||
|
var filePath, info = src.match(/data:image\/(\S+?);(\S+?),(.+)/);
|
||||||
|
if (!info) return;
|
||||||
|
// #ifdef MP-WEIXIN || MP-TOUTIAO
|
||||||
|
filePath = `${wx.env.USER_DATA_PATH}/${Date.now()}.${info[1]}`;
|
||||||
|
fs && fs.writeFile({
|
||||||
|
filePath,
|
||||||
|
data: info[3],
|
||||||
|
encoding: info[2],
|
||||||
|
success: () => this[i] = filePath
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
filePath = `_doc/parser_tmp/${Date.now()}.${info[1]}`;
|
||||||
|
var bitmap = new plus.nativeObj.Bitmap();
|
||||||
|
bitmap.loadBase64Data(src, () => {
|
||||||
|
bitmap.save(filePath, {}, () => {
|
||||||
|
bitmap.clear()
|
||||||
|
this[i] = filePath;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.html) this.setContent(this.html);
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
// #ifdef H5
|
||||||
|
if (this._observer) this._observer.disconnect();
|
||||||
|
// #endif
|
||||||
|
this.imgList.each(src => {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
if (src && src.includes('_doc')) {
|
||||||
|
plus.io.resolveLocalFileSystemURL(src, entry => {
|
||||||
|
entry.remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN || MP-TOUTIAO
|
||||||
|
if (src && src.includes(uni.env.USER_DATA_PATH))
|
||||||
|
fs && fs.unlink({
|
||||||
|
filePath: src
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
})
|
||||||
|
clearInterval(this._timer);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// #ifdef H5 || APP-PLUS-NVUE
|
||||||
|
_Dom2Str(nodes) {
|
||||||
|
var str = '';
|
||||||
|
for (var node of nodes) {
|
||||||
|
if (node.type == 'text')
|
||||||
|
str += node.text;
|
||||||
|
else {
|
||||||
|
str += ('<' + node.name);
|
||||||
|
for (var attr in node.attrs || {})
|
||||||
|
str += (' ' + attr + '="' + node.attrs[attr] + '"');
|
||||||
|
if (!node.children || !node.children.length) str += '>';
|
||||||
|
else str += ('>' + this._Dom2Str(node.children) + '</' + node.name + '>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
},
|
||||||
|
_handleHtml(html, append) {
|
||||||
|
if (typeof html != 'string') html = this._Dom2Str(html.nodes || html);
|
||||||
|
// 处理 rpx
|
||||||
|
if (html.includes('rpx'))
|
||||||
|
html = html.replace(/[0-9.]+\s*rpx/g, $ => parseFloat($) * rpx + 'px');
|
||||||
|
if (!append) {
|
||||||
|
// 处理 tag-style 和 userAgentStyles
|
||||||
|
var style = '<style>@keyframes show{0%{opacity:0}100%{opacity:1}}';
|
||||||
|
for (var item in cfg.userAgentStyles)
|
||||||
|
style += `${item}{${cfg.userAgentStyles[item]}}`;
|
||||||
|
for (item in this.tagStyle)
|
||||||
|
style += `${item}{${this.tagStyle[item]}}`;
|
||||||
|
style += '</style>';
|
||||||
|
html = style + html;
|
||||||
|
}
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
setContent(html, append) {
|
||||||
|
// #ifdef APP-PLUS-NVUE
|
||||||
|
if (!html) {
|
||||||
|
this.src = '';
|
||||||
|
this.height = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (append) return;
|
||||||
|
plus.io.resolveLocalFileSystemURL('_doc', entry => {
|
||||||
|
entry.getDirectory('parser_tmp', {
|
||||||
|
create: true
|
||||||
|
}, entry => {
|
||||||
|
var fileName = Date.now() + '.html';
|
||||||
|
entry.getFile(fileName, {
|
||||||
|
create: true
|
||||||
|
}, entry => {
|
||||||
|
entry.createWriter(writer => {
|
||||||
|
writer.onwriteend = () => {
|
||||||
|
this.nodes = [1];
|
||||||
|
this.src = '_doc/parser_tmp/' + fileName;
|
||||||
|
this.$nextTick(function() {
|
||||||
|
entry.remove();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
html =
|
||||||
|
'<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1' +
|
||||||
|
(this.selectable ? '' : ',user-scalable=no') +
|
||||||
|
'"><script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></' +
|
||||||
|
'script><base href="' + this.domain + '">' + this._handleHtml(html) +
|
||||||
|
'<script>"use strict";function post(t){uni.postMessage({data:t})}' +
|
||||||
|
(this.showWithAnimation ? 'document.body.style.animation="show .5s",' : '') +
|
||||||
|
'document.addEventListener("UniAppJSBridgeReady",function(){post({action:"load",text:document.body.innerText});var t=document.getElementsByTagName("title");t.length&&post({action:"getTitle",title:t[0].innerText});for(var e,o=document.getElementsByTagName("img"),n=[],i=0,r=0;e=o[i];i++)e.onerror=function(){post({action:"error",source:"img",target:this})},e.hasAttribute("ignore")||"A"==e.parentElement.nodeName||(e.i=r++,n.push(e.src),e.onclick=function(){post({action:"preview",img:{i:this.i,src:this.src}})});post({action:"getImgList",imgList:n});for(var a,s=document.getElementsByTagName("a"),c=0;a=s[c];c++)a.onclick=function(){var t,e=this.getAttribute("href");if("#"==e[0]){var r=document.getElementById(e.substr(1));r&&(t=r.offsetTop)}return post({action:"linkpress",href:e,offset:t}),!1};;for(var u,m=document.getElementsByTagName("video"),d=0;u=m[d];d++)u.style.maxWidth="100%;",u.onerror=function(){post({action:"error",source:"video",target:this})}' +
|
||||||
|
(this.autopause ? ',u.onplay=function(){for(var t,e=0;t=m[e];e++)t!=this&&t.pause()}' : '') +
|
||||||
|
';for(var g,l=document.getElementsByTagName("audio"),p=0;g=l[p];p++)g.onerror=function(){post({action:"error",source:"audio",target:this})};window.onload=function(){post({action:"ready",height:document.body.scrollHeight})}});</' +
|
||||||
|
'script>';
|
||||||
|
writer.write(html);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
if (!html) {
|
||||||
|
if (this.rtf && !append) this.rtf.parentNode.removeChild(this.rtf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var div = document.createElement('div');
|
||||||
|
if (!append) {
|
||||||
|
if (this.rtf) this.rtf.parentNode.removeChild(this.rtf);
|
||||||
|
this.rtf = div;
|
||||||
|
} else {
|
||||||
|
if (!this.rtf) this.rtf = div;
|
||||||
|
else this.rtf.appendChild(div);
|
||||||
|
}
|
||||||
|
div.innerHTML = this._handleHtml(html, append);
|
||||||
|
for (var styles = this.rtf.getElementsByTagName('style'), i = 0, style; style = styles[i++];) {
|
||||||
|
style.innerHTML = style.innerHTML.replace(/body/g, '#rtf' + this._uid);
|
||||||
|
style.setAttribute('scoped', 'true');
|
||||||
|
}
|
||||||
|
// 懒加载
|
||||||
|
if (!this._observer && this.lazyLoad && IntersectionObserver) {
|
||||||
|
this._observer = new IntersectionObserver(changes => {
|
||||||
|
for (let item, i = 0; item = changes[i++];) {
|
||||||
|
if (item.isIntersecting) {
|
||||||
|
item.target.src = item.target.getAttribute('data-src');
|
||||||
|
item.target.removeAttribute('data-src');
|
||||||
|
this._observer.unobserve(item.target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
rootMargin: '900px 0px 900px 0px'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
var _ts = this;
|
||||||
|
// 获取标题
|
||||||
|
var title = this.rtf.getElementsByTagName('title');
|
||||||
|
if (title.length && this.autosetTitle)
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: title[0].innerText
|
||||||
|
})
|
||||||
|
// 图片处理
|
||||||
|
this.imgList.length = 0;
|
||||||
|
var imgs = this.rtf.getElementsByTagName('img');
|
||||||
|
for (let i = 0, j = 0, img; img = imgs[i]; i++) {
|
||||||
|
img.style.maxWidth = '100%';
|
||||||
|
var src = img.getAttribute('src');
|
||||||
|
if (this.domain && src) {
|
||||||
|
if (src[0] == '/') {
|
||||||
|
if (src[1] == '/')
|
||||||
|
img.src = (this.domain.includes('://') ? this.domain.split('://')[0] : '') + ':' + src;
|
||||||
|
else img.src = this.domain + src;
|
||||||
|
} else if (!src.includes('://')) img.src = this.domain + '/' + src;
|
||||||
|
}
|
||||||
|
if (!img.hasAttribute('ignore') && img.parentElement.nodeName != 'A') {
|
||||||
|
img.i = j++;
|
||||||
|
_ts.imgList.push(img.src || img.getAttribute('data-src'));
|
||||||
|
img.onclick = function() {
|
||||||
|
var preview = true;
|
||||||
|
this.ignore = () => preview = false;
|
||||||
|
_ts.$emit('imgtap', this);
|
||||||
|
if (preview) {
|
||||||
|
uni.previewImage({
|
||||||
|
current: this.i,
|
||||||
|
urls: _ts.imgList
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
img.onerror = function() {
|
||||||
|
_ts.$emit('error', {
|
||||||
|
source: 'img',
|
||||||
|
target: this
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (_ts.lazyLoad && this._observer && img.src && img.i != 0) {
|
||||||
|
img.setAttribute('data-src', img.src);
|
||||||
|
img.removeAttribute('src');
|
||||||
|
this._observer.observe(img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 链接处理
|
||||||
|
var links = this.rtf.getElementsByTagName('a');
|
||||||
|
for (var link of links) {
|
||||||
|
link.onclick = function() {
|
||||||
|
var jump = true,
|
||||||
|
href = this.getAttribute('href');
|
||||||
|
_ts.$emit('linkpress', {
|
||||||
|
href,
|
||||||
|
ignore: () => jump = false
|
||||||
|
});
|
||||||
|
if (jump && href) {
|
||||||
|
if (href[0] == '#') {
|
||||||
|
if (_ts.useAnchor) {
|
||||||
|
_ts.navigateTo({
|
||||||
|
id: href.substr(1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (href.indexOf('http') == 0 || href.indexOf('//') == 0)
|
||||||
|
return true;
|
||||||
|
else {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: href
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 视频处理
|
||||||
|
var videos = this.rtf.getElementsByTagName('video');
|
||||||
|
_ts.videoContexts = videos;
|
||||||
|
for (let video, i = 0; video = videos[i++];) {
|
||||||
|
video.style.maxWidth = '100%';
|
||||||
|
video.onerror = function() {
|
||||||
|
_ts.$emit('error', {
|
||||||
|
source: 'video',
|
||||||
|
target: this
|
||||||
|
});
|
||||||
|
}
|
||||||
|
video.onplay = function() {
|
||||||
|
if (_ts.autopause)
|
||||||
|
for (let item, i = 0; item = _ts.videoContexts[i++];)
|
||||||
|
if (item != this) item.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 音频处理
|
||||||
|
var audios = this.rtf.getElementsByTagName('audios');
|
||||||
|
for (var audio of audios)
|
||||||
|
audio.onerror = function() {
|
||||||
|
_ts.$emit('error', {
|
||||||
|
source: 'audio',
|
||||||
|
target: this
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.document = this.rtf;
|
||||||
|
if (!append) document.getElementById('rtf' + this._uid).appendChild(this.rtf);
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.nodes = [1];
|
||||||
|
this.$emit('load');
|
||||||
|
})
|
||||||
|
setTimeout(() => this.showAm = '', 500);
|
||||||
|
// #endif
|
||||||
|
// #ifndef H5 || APP-PLUS-NVUE
|
||||||
|
var nodes;
|
||||||
|
if (!html)
|
||||||
|
return this.nodes = [];
|
||||||
|
else if (typeof html == 'string') {
|
||||||
|
let parser = new Parser(html, this);
|
||||||
|
// 缓存读取
|
||||||
|
if (this.useCache) {
|
||||||
|
var hashVal = hash(html);
|
||||||
|
if (cache[hashVal])
|
||||||
|
nodes = cache[hashVal];
|
||||||
|
else {
|
||||||
|
nodes = parser.parse();
|
||||||
|
cache[hashVal] = nodes;
|
||||||
|
}
|
||||||
|
} else nodes = parser.parse();
|
||||||
|
this.$emit('parse', nodes);
|
||||||
|
} else if (Object.prototype.toString.call(html) == '[object Array]') {
|
||||||
|
// 非本插件产生的 array 需要进行一些转换
|
||||||
|
if (html.length && html[0].PoweredBy != 'Parser') {
|
||||||
|
let parser = new Parser(html, this);
|
||||||
|
(function f(ns) {
|
||||||
|
for (var i = 0, n; n = ns[i]; i++) {
|
||||||
|
if (n.type == 'text') continue;
|
||||||
|
n.attrs = n.attrs || {};
|
||||||
|
for (var item in n.attrs)
|
||||||
|
if (typeof n.attrs[item] != 'string') n.attrs[item] = n.attrs[item].toString();
|
||||||
|
parser.matchAttr(n, parser);
|
||||||
|
if (n.children && n.children.length) {
|
||||||
|
parser.STACK.push(n);
|
||||||
|
f(n.children);
|
||||||
|
parser.popNode(parser.STACK.pop());
|
||||||
|
} else n.children = void 0;
|
||||||
|
}
|
||||||
|
})(html);
|
||||||
|
}
|
||||||
|
nodes = html;
|
||||||
|
} else if (typeof html == 'object' && html.nodes) {
|
||||||
|
nodes = html.nodes;
|
||||||
|
console.warn('错误的 html 类型:object 类型已废弃');
|
||||||
|
} else
|
||||||
|
return console.warn('错误的 html 类型:' + typeof html);
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
this.loadVideo = false;
|
||||||
|
// #endif
|
||||||
|
if (document) this.document = new document(this.nodes, 'nodes', this);
|
||||||
|
if (append) this.nodes = this.nodes.concat(nodes);
|
||||||
|
else this.nodes = nodes;
|
||||||
|
if (nodes.length && nodes[0].title && this.autosetTitle)
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: nodes[0].title
|
||||||
|
})
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.imgList.length = 0;
|
||||||
|
this.videoContexts = [];
|
||||||
|
// #ifdef MP-TOUTIAO
|
||||||
|
setTimeout(() => {
|
||||||
|
// #endif
|
||||||
|
var f = (cs) => {
|
||||||
|
for (let i = 0, c; c = cs[i++];) {
|
||||||
|
if (c.$options.name == 'trees') {
|
||||||
|
for (var j = c.nodes.length, item; item = c.nodes[--j];) {
|
||||||
|
if (item.c) continue;
|
||||||
|
if (item.name == 'img') {
|
||||||
|
this.imgList.setItem(item.attrs.i, item.attrs.src);
|
||||||
|
// #ifndef MP-ALIPAY
|
||||||
|
if (!c.observer && !c.imgLoad && item.attrs.i != '0') {
|
||||||
|
if (this.lazyLoad && uni.createIntersectionObserver) {
|
||||||
|
c.observer = uni.createIntersectionObserver(c);
|
||||||
|
c.observer.relativeToViewport({
|
||||||
|
top: 900,
|
||||||
|
bottom: 900
|
||||||
|
}).observe('._img', () => {
|
||||||
|
c.imgLoad = true;
|
||||||
|
c.observer.disconnect();
|
||||||
|
})
|
||||||
|
} else
|
||||||
|
c.imgLoad = true;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
// #ifndef MP-ALIPAY
|
||||||
|
else if (item.name == 'video') {
|
||||||
|
var ctx = uni.createVideoContext(item.attrs.id, c);
|
||||||
|
ctx.id = item.attrs.id;
|
||||||
|
this.videoContexts.push(ctx);
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||||
|
if (item.attrs && item.attrs.id) {
|
||||||
|
this.anchors = this.anchors || [];
|
||||||
|
this.anchors.push({
|
||||||
|
id: item.attrs.id,
|
||||||
|
node: c
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c.$children.length)
|
||||||
|
f(c.$children)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f(this.$children);
|
||||||
|
// #ifdef MP-TOUTIAO
|
||||||
|
}, 200)
|
||||||
|
this.$emit('load');
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loadVideo = true;
|
||||||
|
}, 3000);
|
||||||
|
// #endif
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
// #ifndef APP-PLUS-NVUE
|
||||||
|
var height;
|
||||||
|
clearInterval(this._timer);
|
||||||
|
this._timer = setInterval(() => {
|
||||||
|
// #ifdef H5
|
||||||
|
var res = [this.rtf.getBoundingClientRect()];
|
||||||
|
// #endif
|
||||||
|
// #ifndef H5
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
uni.createSelectorQuery().in(this)
|
||||||
|
// #endif
|
||||||
|
// #ifndef APP-PLUS
|
||||||
|
this.createSelectorQuery()
|
||||||
|
// #endif
|
||||||
|
.select('#top').boundingClientRect().exec(res => {
|
||||||
|
// #endif
|
||||||
|
this.width = res[0].width;
|
||||||
|
if (res[0].height == height) {
|
||||||
|
this.$emit('ready', res[0])
|
||||||
|
clearInterval(this._timer);
|
||||||
|
}
|
||||||
|
height = res[0].height;
|
||||||
|
// #ifndef H5
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
}, 350)
|
||||||
|
if (this.showWithAnimation && !append) this.showAm = 'animation:show .5s';
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
getText(ns = this.nodes) {
|
||||||
|
// #ifdef APP-PLUS-NVUE
|
||||||
|
return this._text;
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
return this.rtf.innerText;
|
||||||
|
// #endif
|
||||||
|
// #ifndef H5 || APP-PLUS-NVUE
|
||||||
|
var txt = '';
|
||||||
|
for (var i = 0, n; n = ns[i++];) {
|
||||||
|
if (n.type == 'text') txt += n.text.replace(/ /g, '\u00A0').replace(/</g, '<').replace(/>/g, '>')
|
||||||
|
.replace(/&/g, '&');
|
||||||
|
else if (n.type == 'br') txt += '\n';
|
||||||
|
else {
|
||||||
|
// 块级标签前后加换行
|
||||||
|
var block = n.name == 'p' || n.name == 'div' || n.name == 'tr' || n.name == 'li' || (n.name[0] == 'h' && n.name[1] >
|
||||||
|
'0' && n.name[1] < '7');
|
||||||
|
if (block && txt && txt[txt.length - 1] != '\n') txt += '\n';
|
||||||
|
if (n.children) txt += this.getText(n.children);
|
||||||
|
if (block && txt[txt.length - 1] != '\n') txt += '\n';
|
||||||
|
else if (n.name == 'td' || n.name == 'th') txt += '\t';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return txt;
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
navigateTo(obj) {
|
||||||
|
if (!this.useAnchor)
|
||||||
|
return obj.fail && obj.fail({
|
||||||
|
errMsg: 'Anchor is disabled'
|
||||||
|
})
|
||||||
|
// #ifdef APP-PLUS-NVUE
|
||||||
|
if (!obj.id)
|
||||||
|
dom.scrollToElement(this.$refs.web);
|
||||||
|
else
|
||||||
|
this.$refs.web.evalJs('var pos=document.getElementById("' + obj.id +
|
||||||
|
'");if(pos)post({action:"linkpress",href:"#",offset:pos.offsetTop})');
|
||||||
|
return obj.success && obj.success({
|
||||||
|
errMsg: 'pageScrollTo:ok'
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
if (!obj.id) {
|
||||||
|
window.scrollTo(0, this.rtf.offsetTop);
|
||||||
|
return obj.success && obj.success({
|
||||||
|
errMsg: 'pageScrollTo:ok'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var target = document.getElementById(obj.id);
|
||||||
|
if (!target) return obj.fail && obj.fail({
|
||||||
|
errMsg: 'Label not found'
|
||||||
|
});
|
||||||
|
obj.scrollTop = this.rtf.offsetTop + target.offsetTop;
|
||||||
|
uni.pageScrollTo(obj);
|
||||||
|
// #endif
|
||||||
|
// #ifndef H5
|
||||||
|
var Scroll = (selector, component) => {
|
||||||
|
uni.createSelectorQuery().in(component ? component : this).select(selector).boundingClientRect().selectViewport()
|
||||||
|
.scrollOffset()
|
||||||
|
.exec(res => {
|
||||||
|
if (!res || !res[0])
|
||||||
|
return obj.fail && obj.fail({
|
||||||
|
errMsg: 'Label not found'
|
||||||
|
});
|
||||||
|
obj.scrollTop = res[1].scrollTop + res[0].top;
|
||||||
|
uni.pageScrollTo(obj);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (!obj.id) Scroll('#top');
|
||||||
|
else {
|
||||||
|
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||||
|
Scroll('#top >>> #' + obj.id + ', #top >>> .' + obj.id);
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||||
|
for (var anchor of this.anchors)
|
||||||
|
if (anchor.id == obj.id)
|
||||||
|
Scroll('#' + obj.id + ', .' + obj.id, anchor.node);
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
getVideoContext(id) {
|
||||||
|
// #ifndef APP-PLUS-NVUE
|
||||||
|
if (!id) return this.videoContexts;
|
||||||
|
else
|
||||||
|
for (var i = this.videoContexts.length; i--;)
|
||||||
|
if (this.videoContexts[i].id == id) return this.videoContexts[i];
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
// 预加载
|
||||||
|
preLoad(html, num) {
|
||||||
|
// #ifdef H5 || APP-PLUS-NVUE
|
||||||
|
if (html.constructor == Array)
|
||||||
|
html = this._Dom2Str(html);
|
||||||
|
var script = "var contain=document.createElement('div');contain.innerHTML='" + html.replace(/'/g, "\\'") +
|
||||||
|
"';for(var imgs=contain.querySelectorAll('img'),i=imgs.length-1;i>=" + num +
|
||||||
|
";i--)imgs[i].removeAttribute('src');";
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS-NVUE
|
||||||
|
this.$refs.web.evalJs(script);
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
eval(script);
|
||||||
|
// #endif
|
||||||
|
// #ifndef H5 || APP-PLUS-NVUE
|
||||||
|
if (typeof html == 'string') {
|
||||||
|
var id = hash(html);
|
||||||
|
html = new Parser(html, this).parse();
|
||||||
|
cache[id] = html;
|
||||||
|
}
|
||||||
|
var wait = [];
|
||||||
|
(function f(ns) {
|
||||||
|
for (var i = 0, n; n = ns[i++];) {
|
||||||
|
if (n.name == 'img' && n.attrs.src && !wait.includes(n.attrs.src))
|
||||||
|
wait.push(n.attrs.src);
|
||||||
|
f(n.children || []);
|
||||||
|
}
|
||||||
|
})(html);
|
||||||
|
if (num) wait = wait.slice(0, num);
|
||||||
|
this._wait = (this._wait || []).concat(wait);
|
||||||
|
if (!this.imgs) this.imgs = this._wait.splice(0, 15);
|
||||||
|
else if (this.imgs.length < 15)
|
||||||
|
this.imgs = this.imgs.concat(this._wait.splice(0, 15 - this.imgs.length));
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
// #ifdef APP-PLUS-NVUE
|
||||||
|
_message(e) {
|
||||||
|
// 接收 web-view 消息
|
||||||
|
var data = e.detail.data[0];
|
||||||
|
if (data.action == 'load') {
|
||||||
|
this.$emit('load');
|
||||||
|
this._text = data.text;
|
||||||
|
} else if (data.action == 'getTitle') {
|
||||||
|
if (this.autosetTitle)
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: data.title
|
||||||
|
})
|
||||||
|
} else if (data.action == 'getImgList') {
|
||||||
|
this.imgList.length = 0;
|
||||||
|
for (var i = data.imgList.length; i--;)
|
||||||
|
this.imgList.setItem(i, data.imgList[i]);
|
||||||
|
} else if (data.action == 'preview') {
|
||||||
|
var preview = true;
|
||||||
|
data.img.ignore = () => preview = false;
|
||||||
|
this.$emit('imgtap', data.img);
|
||||||
|
if (preview)
|
||||||
|
uni.previewImage({
|
||||||
|
current: data.img.i,
|
||||||
|
urls: this.imgList
|
||||||
|
})
|
||||||
|
} else if (data.action == 'linkpress') {
|
||||||
|
var jump = true,
|
||||||
|
href = data.href;
|
||||||
|
this.$emit('linkpress', {
|
||||||
|
href,
|
||||||
|
ignore: () => jump = false
|
||||||
|
})
|
||||||
|
if (jump && href) {
|
||||||
|
if (href[0] == '#') {
|
||||||
|
if (this.useAnchor)
|
||||||
|
dom.scrollToElement(this.$refs.web, {
|
||||||
|
offset: data.offset
|
||||||
|
})
|
||||||
|
} else if (href.includes('://'))
|
||||||
|
plus.runtime.openWeb(href);
|
||||||
|
else
|
||||||
|
uni.navigateTo({
|
||||||
|
url: href
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (data.action == 'error')
|
||||||
|
this.$emit('error', {
|
||||||
|
source: data.source,
|
||||||
|
target: data.target
|
||||||
|
})
|
||||||
|
else if (data.action == 'ready') {
|
||||||
|
this.height = data.height;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
uni.createSelectorQuery().in(this).select('#top').boundingClientRect().exec(res => {
|
||||||
|
this.rect = res[0];
|
||||||
|
this.$emit('ready', res[0]);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifndef APP-PLUS-NVUE
|
||||||
|
// #ifndef H5
|
||||||
|
_load(e) {
|
||||||
|
if (this._wait.length)
|
||||||
|
this.$set(this.imgs, e.target.id, this._wait.shift());
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
_tap(e) {
|
||||||
|
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||||
|
if (this.gestureZoom && e.timeStamp - this._lastT < 300) {
|
||||||
|
var initY = e.touches[0].pageY - e.currentTarget.offsetTop;
|
||||||
|
if (this._zoom) {
|
||||||
|
this._scaleAm.translateX(0).scale(1).step();
|
||||||
|
uni.pageScrollTo({
|
||||||
|
scrollTop: (initY + this._initY) / 2 - e.touches[0].clientY,
|
||||||
|
duration: 400
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
var initX = e.touches[0].pageX - e.currentTarget.offsetLeft;
|
||||||
|
this._initY = initY;
|
||||||
|
this._scaleAm = uni.createAnimation({
|
||||||
|
transformOrigin: `${initX}px ${this._initY}px 0`,
|
||||||
|
timingFunction: 'ease-in-out'
|
||||||
|
});
|
||||||
|
// #ifdef MP-TOUTIAO
|
||||||
|
this._scaleAm.opacity(1);
|
||||||
|
// #endif
|
||||||
|
this._scaleAm.scale(2).step();
|
||||||
|
this._tMax = initX / 2;
|
||||||
|
this._tMin = (initX - this.width) / 2;
|
||||||
|
this._tX = 0;
|
||||||
|
}
|
||||||
|
this._zoom = !this._zoom;
|
||||||
|
this.scaleAm = this._scaleAm.export();
|
||||||
|
}
|
||||||
|
this._lastT = e.timeStamp;
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
_touchstart(e) {
|
||||||
|
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||||
|
if (e.touches.length == 1)
|
||||||
|
this._initX = this._lastX = e.touches[0].pageX;
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
_touchmove(e) {
|
||||||
|
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
|
||||||
|
var diff = e.touches[0].pageX - this._lastX;
|
||||||
|
if (this._zoom && e.touches.length == 1 && Math.abs(diff) > 20) {
|
||||||
|
this._lastX = e.touches[0].pageX;
|
||||||
|
if ((this._tX <= this._tMin && diff < 0) || (this._tX >= this._tMax && diff > 0))
|
||||||
|
return;
|
||||||
|
this._tX += (diff * Math.abs(this._lastX - this._initX) * 0.05);
|
||||||
|
if (this._tX < this._tMin) this._tX = this._tMin;
|
||||||
|
if (this._tX > this._tMax) this._tX = this._tMax;
|
||||||
|
this._scaleAm.translateX(this._tX).step();
|
||||||
|
this.scaleAm = this._scaleAm.export();
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@keyframes show {
|
||||||
|
0% {
|
||||||
|
opacity: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #ifdef MP-WEIXIN */
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
overflow: scroll;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
</style>
|
|
@ -0,0 +1,111 @@
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
解析和匹配 Css 的选择器
|
||||||
|
github:https://github.com/jin-yufeng/Parser
|
||||||
|
docs:https://jin-yufeng.github.io/Parser
|
||||||
|
author:JinYufeng
|
||||||
|
update:2020/03/15
|
||||||
|
*/
|
||||||
|
var cfg = require('./config.js');
|
||||||
|
class CssHandler {
|
||||||
|
constructor(tagStyle) {
|
||||||
|
var styles = Object.assign({}, cfg.userAgentStyles);
|
||||||
|
for (var item in tagStyle)
|
||||||
|
styles[item] = (styles[item] ? styles[item] + ';' : '') + tagStyle[item];
|
||||||
|
this.styles = styles;
|
||||||
|
}
|
||||||
|
getStyle = data => this.styles = new CssParser(data, this.styles).parse();
|
||||||
|
match(name, attrs) {
|
||||||
|
var tmp, matched = (tmp = this.styles[name]) ? tmp + ';' : '';
|
||||||
|
if (attrs.class) {
|
||||||
|
var items = attrs.class.split(' ');
|
||||||
|
for (var i = 0, item; item = items[i]; i++)
|
||||||
|
if (tmp = this.styles['.' + item])
|
||||||
|
matched += tmp + ';';
|
||||||
|
}
|
||||||
|
if (tmp = this.styles['#' + attrs.id])
|
||||||
|
matched += tmp + ';';
|
||||||
|
return matched;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = CssHandler;
|
||||||
|
class CssParser {
|
||||||
|
constructor(data, init) {
|
||||||
|
this.data = data;
|
||||||
|
this.floor = 0;
|
||||||
|
this.i = 0;
|
||||||
|
this.list = [];
|
||||||
|
this.res = init;
|
||||||
|
this.state = this.Space;
|
||||||
|
}
|
||||||
|
parse() {
|
||||||
|
for (var c; c = this.data[this.i]; this.i++)
|
||||||
|
this.state(c);
|
||||||
|
return this.res;
|
||||||
|
}
|
||||||
|
section = () => this.data.substring(this.start, this.i);
|
||||||
|
isLetter = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
|
||||||
|
// 状态机
|
||||||
|
Space(c) {
|
||||||
|
if (c == '.' || c == '#' || this.isLetter(c)) {
|
||||||
|
this.start = this.i;
|
||||||
|
this.state = this.Name;
|
||||||
|
} else if (c == '/' && this.data[this.i + 1] == '*')
|
||||||
|
this.Comment();
|
||||||
|
else if (!cfg.blankChar[c] && c != ';')
|
||||||
|
this.state = this.Ignore;
|
||||||
|
}
|
||||||
|
Comment() {
|
||||||
|
this.i = this.data.indexOf('*/', this.i) + 1;
|
||||||
|
if (!this.i) this.i = this.data.length;
|
||||||
|
this.state = this.Space;
|
||||||
|
}
|
||||||
|
Ignore(c) {
|
||||||
|
if (c == '{') this.floor++;
|
||||||
|
else if (c == '}' && !--this.floor) this.state = this.Space;
|
||||||
|
}
|
||||||
|
Name(c) {
|
||||||
|
if (cfg.blankChar[c]) {
|
||||||
|
this.list.push(this.section());
|
||||||
|
this.state = this.NameSpace;
|
||||||
|
} else if (c == '{') {
|
||||||
|
this.list.push(this.section());
|
||||||
|
this.Content();
|
||||||
|
} else if (c == ',') {
|
||||||
|
this.list.push(this.section());
|
||||||
|
this.Comma();
|
||||||
|
} else if (!this.isLetter(c) && (c < '0' || c > '9') && c != '-' && c != '_')
|
||||||
|
this.state = this.Ignore;
|
||||||
|
}
|
||||||
|
NameSpace(c) {
|
||||||
|
if (c == '{') this.Content();
|
||||||
|
else if (c == ',') this.Comma();
|
||||||
|
else if (!cfg.blankChar[c]) this.state = this.Ignore;
|
||||||
|
}
|
||||||
|
Comma() {
|
||||||
|
while (cfg.blankChar[this.data[++this.i]]);
|
||||||
|
if (this.data[this.i] == '{') this.Content();
|
||||||
|
else {
|
||||||
|
this.start = this.i--;
|
||||||
|
this.state = this.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Content() {
|
||||||
|
this.start = ++this.i;
|
||||||
|
if ((this.i = this.data.indexOf('}', this.i)) == -1) this.i = this.data.length;
|
||||||
|
var content = this.section();
|
||||||
|
for (var i = 0, item; item = this.list[i++];)
|
||||||
|
if (this.res[item]) this.res[item] += ';' + content;
|
||||||
|
else this.res[item] = content;
|
||||||
|
this.list = [];
|
||||||
|
this.state = this.Space;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,586 @@
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
将 html 解析为适用于小程序 rich-text 的 DOM 结构
|
||||||
|
github:https://github.com/jin-yufeng/Parser
|
||||||
|
docs:https://jin-yufeng.github.io/Parser
|
||||||
|
author:JinYufeng
|
||||||
|
update:2020/04/13
|
||||||
|
*/
|
||||||
|
var cfg = require('./config.js'),
|
||||||
|
blankChar = cfg.blankChar,
|
||||||
|
CssHandler = require('./CssHandler.js'),
|
||||||
|
{
|
||||||
|
screenWidth,
|
||||||
|
system
|
||||||
|
} = wx.getSystemInfoSync();
|
||||||
|
// #ifdef MP-BAIDU || MP-ALIPAY || MP-TOUTIAO
|
||||||
|
var entities = {
|
||||||
|
lt: '<',
|
||||||
|
gt: '>',
|
||||||
|
amp: '&',
|
||||||
|
quot: '"',
|
||||||
|
apos: "'",
|
||||||
|
nbsp: '\xA0',
|
||||||
|
ensp: '\u2002',
|
||||||
|
emsp: '\u2003',
|
||||||
|
ndash: '–',
|
||||||
|
mdash: '—',
|
||||||
|
middot: '·',
|
||||||
|
lsquo: '‘',
|
||||||
|
rsquo: '’',
|
||||||
|
ldquo: '“',
|
||||||
|
rdquo: '”',
|
||||||
|
bull: '•',
|
||||||
|
hellip: '…',
|
||||||
|
permil: '‰',
|
||||||
|
copy: '©',
|
||||||
|
reg: '®',
|
||||||
|
trade: '™',
|
||||||
|
times: '×',
|
||||||
|
divide: '÷',
|
||||||
|
cent: '¢',
|
||||||
|
pound: '£',
|
||||||
|
yen: '¥',
|
||||||
|
euro: '€',
|
||||||
|
sect: '§'
|
||||||
|
};
|
||||||
|
// #endif
|
||||||
|
var emoji; // emoji 补丁包 https://jin-yufeng.github.io/Parser/#/instructions?id=emoji
|
||||||
|
class MpHtmlParser {
|
||||||
|
constructor(data, options = {}) {
|
||||||
|
this.attrs = {};
|
||||||
|
this.compress = options.compress;
|
||||||
|
this.CssHandler = new CssHandler(options.tagStyle, screenWidth);
|
||||||
|
this.data = data;
|
||||||
|
this.domain = options.domain;
|
||||||
|
this.DOM = [];
|
||||||
|
this.i = this.start = this.audioNum = this.imgNum = this.videoNum = 0;
|
||||||
|
this.protocol = this.domain && this.domain.includes('://') ? this.domain.split('://')[0] : '';
|
||||||
|
this.state = this.Text;
|
||||||
|
this.STACK = [];
|
||||||
|
this.useAnchor = options.useAnchor;
|
||||||
|
this.xml = options.xml;
|
||||||
|
}
|
||||||
|
parse() {
|
||||||
|
if (emoji) this.data = emoji.parseEmoji(this.data);
|
||||||
|
for (var c; c = this.data[this.i]; this.i++)
|
||||||
|
this.state(c);
|
||||||
|
if (this.state == this.Text) this.setText();
|
||||||
|
while (this.STACK.length) this.popNode(this.STACK.pop());
|
||||||
|
// #ifdef MP-BAIDU || MP-TOUTIAO
|
||||||
|
// 将顶层标签的一些样式提取出来给 rich-text
|
||||||
|
(function f(ns) {
|
||||||
|
for (var i = ns.length, n; n = ns[--i];) {
|
||||||
|
if (n.type == 'text') continue;
|
||||||
|
if (!n.c) {
|
||||||
|
var style = n.attrs.style;
|
||||||
|
if (style) {
|
||||||
|
var j, k, res;
|
||||||
|
if ((j = style.indexOf('display')) != -1)
|
||||||
|
res = style.substring(j, (k = style.indexOf(';', j)) == -1 ? style.length : k);
|
||||||
|
if ((j = style.indexOf('float')) != -1)
|
||||||
|
res += ';' + style.substring(j, (k = style.indexOf(';', j)) == -1 ? style.length : k);
|
||||||
|
n.attrs.contain = res;
|
||||||
|
}
|
||||||
|
} else f(n.children);
|
||||||
|
}
|
||||||
|
})(this.DOM);
|
||||||
|
// #endif
|
||||||
|
if (this.DOM.length) {
|
||||||
|
this.DOM[0].PoweredBy = 'Parser';
|
||||||
|
if (this.title) this.DOM[0].title = this.title;
|
||||||
|
}
|
||||||
|
return this.DOM;
|
||||||
|
}
|
||||||
|
// 设置属性
|
||||||
|
setAttr() {
|
||||||
|
var name = this.getName(this.attrName);
|
||||||
|
if (cfg.trustAttrs[name]) {
|
||||||
|
if (!this.attrVal) {
|
||||||
|
if (cfg.boolAttrs[name]) this.attrs[name] = 'T';
|
||||||
|
} else if (name == 'src') this.attrs[name] = this.getUrl(this.attrVal.replace(/&/g, '&'));
|
||||||
|
else this.attrs[name] = this.attrVal;
|
||||||
|
}
|
||||||
|
this.attrVal = '';
|
||||||
|
while (blankChar[this.data[this.i]]) this.i++;
|
||||||
|
if (this.isClose()) this.setNode();
|
||||||
|
else {
|
||||||
|
this.start = this.i;
|
||||||
|
this.state = this.AttrName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 设置文本节点
|
||||||
|
setText() {
|
||||||
|
var back, text = this.section();
|
||||||
|
if (!text) return;
|
||||||
|
text = (cfg.onText && cfg.onText(text, () => back = true)) || text;
|
||||||
|
if (back) {
|
||||||
|
this.data = this.data.substr(0, this.start) + text + this.data.substr(this.i);
|
||||||
|
let j = this.start + text.length;
|
||||||
|
for (this.i = this.start; this.i < j; this.i++) this.state(this.data[this.i]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.pre) {
|
||||||
|
// 合并空白符
|
||||||
|
var tmp = [];
|
||||||
|
for (let i = text.length, c; c = text[--i];)
|
||||||
|
if (!blankChar[c] || (!blankChar[tmp[0]] && (c = ' '))) tmp.unshift(c);
|
||||||
|
text = tmp.join('');
|
||||||
|
if (text == ' ') return;
|
||||||
|
}
|
||||||
|
// 处理实体
|
||||||
|
var siblings = this.siblings(),
|
||||||
|
i = -1,
|
||||||
|
j, en;
|
||||||
|
while (1) {
|
||||||
|
if ((i = text.indexOf('&', i + 1)) == -1) break;
|
||||||
|
if ((j = text.indexOf(';', i + 2)) == -1) break;
|
||||||
|
if (text[i + 1] == '#') {
|
||||||
|
en = parseInt((text[i + 2] == 'x' ? '0' : '') + text.substring(i + 2, j));
|
||||||
|
if (!isNaN(en)) text = text.substr(0, i) + String.fromCharCode(en) + text.substring(j + 1);
|
||||||
|
} else {
|
||||||
|
en = text.substring(i + 1, j);
|
||||||
|
// #ifdef MP-WEIXIN || MP-QQ || APP-PLUS
|
||||||
|
if (en == 'nbsp') text = text.substr(0, i) + '\xA0' + text.substr(j + 1); // 解决 失效
|
||||||
|
else if (en != 'lt' && en != 'gt' && en != 'amp' && en != 'ensp' && en != 'emsp' && en != 'quot' && en != 'apos') {
|
||||||
|
i && siblings.push({
|
||||||
|
type: 'text',
|
||||||
|
text: text.substr(0, i)
|
||||||
|
})
|
||||||
|
siblings.push({
|
||||||
|
type: 'text',
|
||||||
|
text: `&${en};`,
|
||||||
|
en: 1
|
||||||
|
})
|
||||||
|
text = text.substr(j + 1);
|
||||||
|
i = -1;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-BAIDU || MP-ALIPAY || MP-TOUTIAO
|
||||||
|
if (entities[en]) text = text.substr(0, i) + entities[en] + text.substr(j + 1);
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
text && siblings.push({
|
||||||
|
type: 'text',
|
||||||
|
text
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 设置元素节点
|
||||||
|
setNode() {
|
||||||
|
var node = {
|
||||||
|
name: this.tagName.toLowerCase(),
|
||||||
|
attrs: this.attrs
|
||||||
|
},
|
||||||
|
close = cfg.selfClosingTags[node.name] || (this.xml && this.data[this.i] == '/');
|
||||||
|
this.attrs = {};
|
||||||
|
if (!cfg.ignoreTags[node.name]) {
|
||||||
|
this.matchAttr(node);
|
||||||
|
if (!close) {
|
||||||
|
node.children = [];
|
||||||
|
if (node.name == 'pre' && cfg.highlight) {
|
||||||
|
this.remove(node);
|
||||||
|
this.pre = node.pre = true;
|
||||||
|
}
|
||||||
|
this.siblings().push(node);
|
||||||
|
this.STACK.push(node);
|
||||||
|
} else if (!cfg.filter || cfg.filter(node, this) != false)
|
||||||
|
this.siblings().push(node);
|
||||||
|
} else {
|
||||||
|
if (!close) this.remove(node);
|
||||||
|
else if (node.name == 'source') {
|
||||||
|
var parent = this.STACK[this.STACK.length - 1],
|
||||||
|
attrs = node.attrs;
|
||||||
|
if (parent && attrs.src)
|
||||||
|
if (parent.name == 'video' || parent.name == 'audio')
|
||||||
|
parent.attrs.source.push(attrs.src);
|
||||||
|
else {
|
||||||
|
var i, media = attrs.media;
|
||||||
|
if (parent.name == 'picture' && !parent.attrs.src && !(attrs.src.indexOf('.webp') && system.includes('iOS')) &&
|
||||||
|
(!media || (media.includes('px') &&
|
||||||
|
(((i = media.indexOf('min-width')) != -1 && (i = media.indexOf(':', i + 8)) != -1 && screenWidth > parseInt(
|
||||||
|
media.substr(i + 1))) ||
|
||||||
|
((i = media.indexOf('max-width')) != -1 && (i = media.indexOf(':', i + 8)) != -1 && screenWidth < parseInt(
|
||||||
|
media.substr(i + 1)))))))
|
||||||
|
parent.attrs.src = attrs.src;
|
||||||
|
}
|
||||||
|
} else if (node.name == 'base' && !this.domain) this.domain = node.attrs.href;
|
||||||
|
}
|
||||||
|
if (this.data[this.i] == '/') this.i++;
|
||||||
|
this.start = this.i + 1;
|
||||||
|
this.state = this.Text;
|
||||||
|
}
|
||||||
|
// 移除标签
|
||||||
|
remove(node) {
|
||||||
|
var name = node.name,
|
||||||
|
j = this.i;
|
||||||
|
while (1) {
|
||||||
|
if ((this.i = this.data.indexOf('</', this.i + 1)) == -1) {
|
||||||
|
if (name == 'pre' || name == 'svg') this.i = j;
|
||||||
|
else this.i = this.data.length;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.start = (this.i += 2);
|
||||||
|
while (!blankChar[this.data[this.i]] && !this.isClose()) this.i++;
|
||||||
|
if (this.getName(this.section()) == name) {
|
||||||
|
// 代码块高亮
|
||||||
|
if (name == 'pre') {
|
||||||
|
this.data = this.data.substr(0, j + 1) + cfg.highlight(this.data.substring(j + 1, this.i - 5), node.attrs) +
|
||||||
|
this.data.substr(this.i - 5);
|
||||||
|
return this.i = j;
|
||||||
|
} else if (name == 'style')
|
||||||
|
this.CssHandler.getStyle(this.data.substring(j + 1, this.i - 7));
|
||||||
|
else if (name == 'title')
|
||||||
|
this.title = this.data.substring(j + 1, this.i - 7);
|
||||||
|
if ((this.i = this.data.indexOf('>', this.i)) == -1) this.i = this.data.length;
|
||||||
|
// 处理 svg
|
||||||
|
if (name == 'svg') {
|
||||||
|
var src = this.data.substring(j, this.i + 1);
|
||||||
|
if (!node.attrs.xmlns) src = ' xmlns="http://www.w3.org/2000/svg"' + src;
|
||||||
|
var i = j;
|
||||||
|
while (this.data[j] != '<') j--;
|
||||||
|
src = this.data.substring(j, i) + src;
|
||||||
|
var parent = this.STACK[this.STACK.length - 1];
|
||||||
|
if (node.attrs.width == '100%' && parent && (parent.attrs.style || '').includes('inline'))
|
||||||
|
parent.attrs.style = 'width:300px;max-width:100%;' + parent.attrs.style;
|
||||||
|
this.siblings().push({
|
||||||
|
name: 'img',
|
||||||
|
attrs: {
|
||||||
|
src: 'data:image/svg+xml;utf8,' + src.replace(/#/g, '%23'),
|
||||||
|
ignore: 'T'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 处理属性
|
||||||
|
matchAttr(node) {
|
||||||
|
var attrs = node.attrs,
|
||||||
|
style = this.CssHandler.match(node.name, attrs, node) + (attrs.style || ''),
|
||||||
|
styleObj = {};
|
||||||
|
if (attrs.id) {
|
||||||
|
if (this.compress & 1) attrs.id = void 0;
|
||||||
|
else if (this.useAnchor) this.bubble();
|
||||||
|
}
|
||||||
|
if ((this.compress & 2) && attrs.class) attrs.class = void 0;
|
||||||
|
switch (node.name) {
|
||||||
|
case 'img':
|
||||||
|
if (attrs['data-src']) {
|
||||||
|
attrs.src = attrs.src || attrs['data-src'];
|
||||||
|
attrs['data-src'] = void 0;
|
||||||
|
}
|
||||||
|
if (attrs.src && !attrs.ignore) {
|
||||||
|
if (this.bubble()) attrs.i = (this.imgNum++).toString();
|
||||||
|
else attrs.ignore = 'T';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
case 'ad':
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
case 'iframe':
|
||||||
|
case 'embed':
|
||||||
|
// #endif
|
||||||
|
this.bubble();
|
||||||
|
break;
|
||||||
|
case 'font':
|
||||||
|
if (attrs.color) {
|
||||||
|
styleObj['color'] = attrs.color;
|
||||||
|
attrs.color = void 0;
|
||||||
|
}
|
||||||
|
if (attrs.face) {
|
||||||
|
styleObj['font-family'] = attrs.face;
|
||||||
|
attrs.face = void 0;
|
||||||
|
}
|
||||||
|
if (attrs.size) {
|
||||||
|
var size = parseInt(attrs.size);
|
||||||
|
if (size < 1) size = 1;
|
||||||
|
else if (size > 7) size = 7;
|
||||||
|
var map = ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'];
|
||||||
|
styleObj['font-size'] = map[size - 1];
|
||||||
|
attrs.size = void 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'video':
|
||||||
|
case 'audio':
|
||||||
|
if (!attrs.id) attrs.id = node.name + (++this[`${node.name}Num`]);
|
||||||
|
else this[`${node.name}Num`]++;
|
||||||
|
if (node.name == 'video') {
|
||||||
|
if (attrs.width) {
|
||||||
|
style = `width:${parseFloat(attrs.width) + (attrs.width.includes('%') ? '%' : 'px')};${style}`;
|
||||||
|
attrs.width = void 0;
|
||||||
|
}
|
||||||
|
if (attrs.height) {
|
||||||
|
style = `height:${parseFloat(attrs.height) + (attrs.height.includes('%') ? '%' : 'px')};${style}`;
|
||||||
|
attrs.height = void 0;
|
||||||
|
}
|
||||||
|
if (this.videoNum > 3) node.lazyLoad = true;
|
||||||
|
}
|
||||||
|
attrs.source = [];
|
||||||
|
if (attrs.src) attrs.source.push(attrs.src);
|
||||||
|
if (!attrs.controls && !attrs.autoplay)
|
||||||
|
console.warn(`存在没有 controls 属性的 ${node.name} 标签,可能导致无法播放`, node);
|
||||||
|
this.bubble();
|
||||||
|
break;
|
||||||
|
case 'td':
|
||||||
|
case 'th':
|
||||||
|
if (attrs.colspan || attrs.rowspan)
|
||||||
|
for (var k = this.STACK.length, item; item = this.STACK[--k];)
|
||||||
|
if (item.name == 'table') {
|
||||||
|
item.c = void 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (attrs.align) {
|
||||||
|
styleObj['text-align'] = attrs.align;
|
||||||
|
attrs.align = void 0;
|
||||||
|
}
|
||||||
|
// 压缩 style
|
||||||
|
var styles = style.replace(/"/g, '"').replace(/&/g, '&').split(';');
|
||||||
|
style = '';
|
||||||
|
for (var i = 0, len = styles.length; i < len; i++) {
|
||||||
|
var info = styles[i].split(':');
|
||||||
|
if (info.length < 2) continue;
|
||||||
|
let key = info[0].trim().toLowerCase(),
|
||||||
|
value = info.slice(1).join(':').trim();
|
||||||
|
if (value.includes('-webkit') || value.includes('-moz') || value.includes('-ms') || value.includes('-o') || value
|
||||||
|
.includes(
|
||||||
|
'safe'))
|
||||||
|
style += `;${key}:${value}`;
|
||||||
|
else if (!styleObj[key] || value.includes('import') || !styleObj[key].includes('import'))
|
||||||
|
styleObj[key] = value;
|
||||||
|
}
|
||||||
|
if (node.name == 'img' && parseInt(styleObj.width || attrs.width) > screenWidth)
|
||||||
|
styleObj.height = 'auto';
|
||||||
|
for (var key in styleObj) {
|
||||||
|
var value = styleObj[key];
|
||||||
|
if (key.includes('flex') || key == 'order' || key == 'self-align') node.c = 1;
|
||||||
|
// 填充链接
|
||||||
|
if (value.includes('url')) {
|
||||||
|
var j = value.indexOf('(');
|
||||||
|
if (j++ != -1) {
|
||||||
|
while (value[j] == '"' || value[j] == "'" || blankChar[value[j]]) j++;
|
||||||
|
value = value.substr(0, j) + this.getUrl(value.substr(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 转换 rpx
|
||||||
|
else if (value.includes('rpx'))
|
||||||
|
value = value.replace(/[0-9.]+\s*rpx/g, $ => parseFloat($) * screenWidth / 750 + 'px');
|
||||||
|
else if (key == 'white-space' && value.includes('pre'))
|
||||||
|
this.pre = node.pre = true;
|
||||||
|
style += `;${key}:${value}`;
|
||||||
|
}
|
||||||
|
style = style.substr(1);
|
||||||
|
if (style) attrs.style = style;
|
||||||
|
}
|
||||||
|
// 节点出栈处理
|
||||||
|
popNode(node) {
|
||||||
|
// 空白符处理
|
||||||
|
if (node.pre) {
|
||||||
|
node.pre = this.pre = void 0;
|
||||||
|
for (let i = this.STACK.length; i--;)
|
||||||
|
if (this.STACK[i].pre)
|
||||||
|
this.pre = true;
|
||||||
|
}
|
||||||
|
if (node.name == 'head' || (cfg.filter && cfg.filter(node, this) == false))
|
||||||
|
return this.siblings().pop();
|
||||||
|
var attrs = node.attrs;
|
||||||
|
// 替换一些标签名
|
||||||
|
if (node.name == 'picture') {
|
||||||
|
node.name = 'img';
|
||||||
|
if (!attrs.src && (node.children[0] || '').name == 'img')
|
||||||
|
attrs.src = node.children[0].attrs.src;
|
||||||
|
if (attrs.src && !attrs.ignore)
|
||||||
|
attrs.i = (this.imgNum++).toString();
|
||||||
|
return node.children = void 0;
|
||||||
|
}
|
||||||
|
if (cfg.blockTags[node.name]) node.name = 'div';
|
||||||
|
else if (!cfg.trustTags[node.name]) node.name = 'span';
|
||||||
|
// 处理列表
|
||||||
|
if (node.c) {
|
||||||
|
if (node.name == 'ul') {
|
||||||
|
var floor = 1;
|
||||||
|
for (let i = this.STACK.length; i--;)
|
||||||
|
if (this.STACK[i].name == 'ul') floor++;
|
||||||
|
if (floor != 1)
|
||||||
|
for (let i = node.children.length; i--;)
|
||||||
|
node.children[i].floor = floor;
|
||||||
|
} else if (node.name == 'ol') {
|
||||||
|
for (let i = 0, num = 1, child; child = node.children[i++];)
|
||||||
|
if (child.name == 'li') {
|
||||||
|
child.type = 'ol';
|
||||||
|
child.num = ((num, type) => {
|
||||||
|
if (type == 'a') return String.fromCharCode(97 + (num - 1) % 26);
|
||||||
|
if (type == 'A') return String.fromCharCode(65 + (num - 1) % 26);
|
||||||
|
if (type == 'i' || type == 'I') {
|
||||||
|
num = (num - 1) % 99 + 1;
|
||||||
|
var one = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'],
|
||||||
|
ten = ['X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'],
|
||||||
|
res = (ten[Math.floor(num / 10) - 1] || '') + (one[num % 10 - 1] || '');
|
||||||
|
if (type == 'i') return res.toLowerCase();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
})(num++, attrs.type) + '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 处理表格的边框
|
||||||
|
if (node.name == 'table') {
|
||||||
|
var padding = attrs.cellpadding,
|
||||||
|
spacing = attrs.cellspacing,
|
||||||
|
border = attrs.border;
|
||||||
|
if (node.c) {
|
||||||
|
this.bubble();
|
||||||
|
if (!padding) padding = 2;
|
||||||
|
if (!spacing) spacing = 2;
|
||||||
|
}
|
||||||
|
if (border) attrs.style = `border:${border}px solid gray;${attrs.style || ''}`;
|
||||||
|
if (spacing) attrs.style = `border-spacing:${spacing}px;${attrs.style || ''}`;
|
||||||
|
if (border || padding)
|
||||||
|
(function f(ns) {
|
||||||
|
for (var i = 0, n; n = ns[i]; i++) {
|
||||||
|
if (n.name == 'th' || n.name == 'td') {
|
||||||
|
if (border) n.attrs.style = `border:${border}px solid gray;${n.attrs.style}`;
|
||||||
|
if (padding) n.attrs.style = `padding:${padding}px;${n.attrs.style}`;
|
||||||
|
} else f(n.children || []);
|
||||||
|
}
|
||||||
|
})(node.children)
|
||||||
|
}
|
||||||
|
this.CssHandler.pop && this.CssHandler.pop(node);
|
||||||
|
// 自动压缩
|
||||||
|
if (node.name == 'div' && !Object.keys(attrs).length) {
|
||||||
|
var siblings = this.siblings();
|
||||||
|
if (node.children.length == 1 && node.children[0].name == 'div')
|
||||||
|
siblings[siblings.length - 1] = node.children[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 工具函数
|
||||||
|
bubble() {
|
||||||
|
for (var i = this.STACK.length, item; item = this.STACK[--i];) {
|
||||||
|
if (cfg.richOnlyTags[item.name]) {
|
||||||
|
if (item.name == 'table' && !Object.hasOwnProperty.call(item, 'c')) item.c = 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
item.c = 1;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
getName = val => this.xml ? val : val.toLowerCase();
|
||||||
|
getUrl(url) {
|
||||||
|
if (url[0] == '/') {
|
||||||
|
if (url[1] == '/') url = this.protocol + ':' + url;
|
||||||
|
else if (this.domain) url = this.domain + url;
|
||||||
|
} else if (this.domain && url.indexOf('data:') != 0 && !url.includes('://'))
|
||||||
|
url = this.domain + '/' + url;
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
isClose = () => this.data[this.i] == '>' || (this.data[this.i] == '/' && this.data[this.i + 1] == '>');
|
||||||
|
section = () => this.data.substring(this.start, this.i);
|
||||||
|
siblings = () => this.STACK.length ? this.STACK[this.STACK.length - 1].children : this.DOM;
|
||||||
|
// 状态机
|
||||||
|
Text(c) {
|
||||||
|
if (c == '<') {
|
||||||
|
var next = this.data[this.i + 1],
|
||||||
|
isLetter = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
|
||||||
|
if (isLetter(next)) {
|
||||||
|
this.setText();
|
||||||
|
this.start = this.i + 1;
|
||||||
|
this.state = this.TagName;
|
||||||
|
} else if (next == '/') {
|
||||||
|
this.setText();
|
||||||
|
if (isLetter(this.data[++this.i + 1])) {
|
||||||
|
this.start = this.i + 1;
|
||||||
|
this.state = this.EndTag;
|
||||||
|
} else
|
||||||
|
this.Comment();
|
||||||
|
} else if (next == '!') {
|
||||||
|
this.setText();
|
||||||
|
this.Comment();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Comment() {
|
||||||
|
var key;
|
||||||
|
if (this.data.substring(this.i + 2, this.i + 4) == '--') key = '-->';
|
||||||
|
else if (this.data.substring(this.i + 2, this.i + 9) == '[CDATA[') key = ']]>';
|
||||||
|
else key = '>';
|
||||||
|
if ((this.i = this.data.indexOf(key, this.i + 2)) == -1) this.i = this.data.length;
|
||||||
|
else this.i += key.length - 1;
|
||||||
|
this.start = this.i + 1;
|
||||||
|
this.state = this.Text;
|
||||||
|
}
|
||||||
|
TagName(c) {
|
||||||
|
if (blankChar[c]) {
|
||||||
|
this.tagName = this.section();
|
||||||
|
while (blankChar[this.data[this.i]]) this.i++;
|
||||||
|
if (this.isClose()) this.setNode();
|
||||||
|
else {
|
||||||
|
this.start = this.i;
|
||||||
|
this.state = this.AttrName;
|
||||||
|
}
|
||||||
|
} else if (this.isClose()) {
|
||||||
|
this.tagName = this.section();
|
||||||
|
this.setNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AttrName(c) {
|
||||||
|
var blank = blankChar[c];
|
||||||
|
if (blank) {
|
||||||
|
this.attrName = this.section();
|
||||||
|
c = this.data[this.i];
|
||||||
|
}
|
||||||
|
if (c == '=') {
|
||||||
|
if (!blank) this.attrName = this.section();
|
||||||
|
while (blankChar[this.data[++this.i]]);
|
||||||
|
this.start = this.i--;
|
||||||
|
this.state = this.AttrValue;
|
||||||
|
} else if (blank) this.setAttr();
|
||||||
|
else if (this.isClose()) {
|
||||||
|
this.attrName = this.section();
|
||||||
|
this.setAttr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AttrValue(c) {
|
||||||
|
if (c == '"' || c == "'") {
|
||||||
|
this.start++;
|
||||||
|
if ((this.i = this.data.indexOf(c, this.i + 1)) == -1) return this.i = this.data.length;
|
||||||
|
this.attrVal = this.section();
|
||||||
|
this.i++;
|
||||||
|
} else {
|
||||||
|
for (; !blankChar[this.data[this.i]] && !this.isClose(); this.i++);
|
||||||
|
this.attrVal = this.section();
|
||||||
|
}
|
||||||
|
this.setAttr();
|
||||||
|
}
|
||||||
|
EndTag(c) {
|
||||||
|
if (blankChar[c] || c == '>' || c == '/') {
|
||||||
|
var name = this.getName(this.section());
|
||||||
|
for (var i = this.STACK.length; i--;)
|
||||||
|
if (this.STACK[i].name == name) break;
|
||||||
|
if (i != -1) {
|
||||||
|
var node;
|
||||||
|
while ((node = this.STACK.pop()).name != name);
|
||||||
|
this.popNode(node);
|
||||||
|
} else if (name == 'p' || name == 'br')
|
||||||
|
this.siblings().push({
|
||||||
|
name,
|
||||||
|
attrs: {}
|
||||||
|
});
|
||||||
|
this.i = this.data.indexOf('>', this.i);
|
||||||
|
this.start = this.i + 1;
|
||||||
|
if (this.i == -1) this.i = this.data.length;
|
||||||
|
else this.state = this.Text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = MpHtmlParser;
|
|
@ -0,0 +1,89 @@
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
/* 配置文件 */
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
const canIUse = wx.canIUse('editor'); // 高基础库标识,用于兼容
|
||||||
|
// #endif
|
||||||
|
module.exports = {
|
||||||
|
// 过滤器函数
|
||||||
|
filter: null,
|
||||||
|
// 代码高亮函数
|
||||||
|
highlight: null,
|
||||||
|
// 文本处理函数
|
||||||
|
onText: null,
|
||||||
|
blankChar: makeMap(' ,\xA0,\t,\r,\n,\f'),
|
||||||
|
// 块级标签,将被转为 div
|
||||||
|
blockTags: makeMap('address,article,aside,body,caption,center,cite,footer,header,html,nav,section' + (
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
canIUse ? '' :
|
||||||
|
// #endif
|
||||||
|
',pre')),
|
||||||
|
// 将被移除的标签
|
||||||
|
ignoreTags: makeMap(
|
||||||
|
'area,base,basefont,canvas,command,frame,input,isindex,keygen,link,map,meta,param,script,source,style,svg,textarea,title,track,use,wbr'
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
+ (canIUse ? ',rp' : '')
|
||||||
|
// #endif
|
||||||
|
// #ifndef APP-PLUS
|
||||||
|
+ ',embed,iframe'
|
||||||
|
// #endif
|
||||||
|
),
|
||||||
|
// 只能被 rich-text 显示的标签
|
||||||
|
richOnlyTags: makeMap('a,colgroup,fieldset,legend,picture,table'
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
+ (canIUse ? ',bdi,bdo,caption,rt,ruby' : '')
|
||||||
|
// #endif
|
||||||
|
),
|
||||||
|
// 自闭合的标签
|
||||||
|
selfClosingTags: makeMap(
|
||||||
|
'area,base,basefont,br,col,circle,ellipse,embed,frame,hr,img,input,isindex,keygen,line,link,meta,param,path,polygon,rect,source,track,use,wbr'
|
||||||
|
),
|
||||||
|
// 信任的属性
|
||||||
|
trustAttrs: makeMap(
|
||||||
|
'align,alt,app-id,author,autoplay,border,cellpadding,cellspacing,class,color,colspan,controls,data-src,dir,face,height,href,id,ignore,loop,media,muted,name,path,poster,rowspan,size,span,src,start,style,type,unit-id,width,xmlns'
|
||||||
|
),
|
||||||
|
// bool 型的属性
|
||||||
|
boolAttrs: makeMap('autoplay,controls,ignore,loop,muted'),
|
||||||
|
// 信任的标签
|
||||||
|
trustTags: makeMap(
|
||||||
|
'a,abbr,ad,audio,b,blockquote,br,code,col,colgroup,dd,del,dl,dt,div,em,fieldset,h1,h2,h3,h4,h5,h6,hr,i,img,ins,label,legend,li,ol,p,q,source,span,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,title,ul,video'
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
+ (canIUse ? ',bdi,bdo,caption,pre,rt,ruby' : '')
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
+ ',embed,iframe'
|
||||||
|
// #endif
|
||||||
|
),
|
||||||
|
// 默认的标签样式
|
||||||
|
userAgentStyles: {
|
||||||
|
address: 'font-style:italic',
|
||||||
|
big: 'display:inline;font-size:1.2em',
|
||||||
|
blockquote: 'background-color:#f6f6f6;border-left:3px solid #dbdbdb;color:#6c6c6c;padding:5px 0 5px 10px',
|
||||||
|
caption: 'display:table-caption;text-align:center',
|
||||||
|
center: 'text-align:center',
|
||||||
|
cite: 'font-style:italic',
|
||||||
|
dd: 'margin-left:40px',
|
||||||
|
img: 'max-width:100%',
|
||||||
|
mark: 'background-color:yellow',
|
||||||
|
picture: 'max-width:100%',
|
||||||
|
pre: 'font-family:monospace;white-space:pre;overflow:scroll',
|
||||||
|
s: 'text-decoration:line-through',
|
||||||
|
small: 'display:inline;font-size:0.8em',
|
||||||
|
u: 'text-decoration:underline'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeMap(str) {
|
||||||
|
var map = {},
|
||||||
|
list = str.split(',');
|
||||||
|
for (var i = list.length; i--;)
|
||||||
|
map[list[i]] = true;
|
||||||
|
return map;
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
var inlineTags = {
|
||||||
|
abbr: 1,
|
||||||
|
b: 1,
|
||||||
|
big: 1,
|
||||||
|
code: 1,
|
||||||
|
del: 1,
|
||||||
|
em: 1,
|
||||||
|
i: 1,
|
||||||
|
ins: 1,
|
||||||
|
label: 1,
|
||||||
|
q: 1,
|
||||||
|
small: 1,
|
||||||
|
span: 1,
|
||||||
|
strong: 1
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
// 从顶层标签的样式中取出一些给 rich-text
|
||||||
|
getStyle: function(style) {
|
||||||
|
if (style) {
|
||||||
|
var i, j, res = '';
|
||||||
|
if ((i = style.indexOf('display')) != -1)
|
||||||
|
res = style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
|
||||||
|
if ((i = style.indexOf('float')) != -1)
|
||||||
|
res += ';' + style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getNode: function(item) {
|
||||||
|
return [item];
|
||||||
|
},
|
||||||
|
// 是否通过 rich-text 显示
|
||||||
|
useRichText: function(item) {
|
||||||
|
return !item.c && !inlineTags[item.name] && (item.attrs.style || '').indexOf('display:inline') == -1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
var inlineTags = {
|
||||||
|
abbr: 1,
|
||||||
|
b: 1,
|
||||||
|
big: 1,
|
||||||
|
code: 1,
|
||||||
|
del: 1,
|
||||||
|
em: 1,
|
||||||
|
i: 1,
|
||||||
|
ins: 1,
|
||||||
|
label: 1,
|
||||||
|
q: 1,
|
||||||
|
small: 1,
|
||||||
|
span: 1,
|
||||||
|
strong: 1
|
||||||
|
}
|
||||||
|
module.exports = {
|
||||||
|
// 从顶层标签的样式中取出一些给 rich-text
|
||||||
|
getStyle: function(style) {
|
||||||
|
if (style) {
|
||||||
|
var i, j, res = '';
|
||||||
|
if ((i = style.indexOf('display')) != -1)
|
||||||
|
res = style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
|
||||||
|
if ((i = style.indexOf('float')) != -1)
|
||||||
|
res += ';' + style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 处理懒加载
|
||||||
|
getNode: function(item, imgLoad) {
|
||||||
|
if (!imgLoad && item.attrs.i != '0') {
|
||||||
|
var img = {
|
||||||
|
name: 'img',
|
||||||
|
attrs: JSON.parse(JSON.stringify(item.attrs))
|
||||||
|
}
|
||||||
|
delete img.attrs.src;
|
||||||
|
img.attrs.style += ';width:20px;height:20px';
|
||||||
|
return [img];
|
||||||
|
} else return [item];
|
||||||
|
},
|
||||||
|
// 是否通过 rich-text 显示
|
||||||
|
useRichText: function(item) {
|
||||||
|
return !item.c && !inlineTags[item.name] && (item.attrs.style || '').indexOf('display:inline') == -1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,485 @@
|
||||||
|
<!--
|
||||||
|
trees 递归显示组件
|
||||||
|
github:https://github.com/jin-yufeng/Parser
|
||||||
|
docs:https://jin-yufeng.github.io/Parser
|
||||||
|
插件市场:https://ext.dcloud.net.cn/plugin?id=805
|
||||||
|
author:JinYufeng
|
||||||
|
update:2020/04/13
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<view class="interlayer">
|
||||||
|
<block v-for="(n, index) in nodes" v-bind:key="index">
|
||||||
|
<!--图片-->
|
||||||
|
<!--#ifdef MP-WEIXIN || MP-QQ || MP-ALIPAY || APP-PLUS-->
|
||||||
|
<rich-text v-if="n.name=='img'" :id="n.attrs.id" class="_img" :style="''+handler.getStyle(n.attrs.style)" :nodes="handler.getNode(n,!lazyLoad||imgLoad)"
|
||||||
|
:data-attrs="n.attrs" @tap="imgtap" @longpress="imglongtap" />
|
||||||
|
<!--#endif-->
|
||||||
|
<!--#ifdef MP-BAIDU || MP-TOUTIAO-->
|
||||||
|
<rich-text v-if="n.name=='img'" :id="n.attrs.id" class="_img" :style="n.attrs.contain" :nodes='[n]' :data-attrs="n.attrs"
|
||||||
|
@tap="imgtap" @longpress="imglongtap" />
|
||||||
|
<!--#endif-->
|
||||||
|
<!--文本-->
|
||||||
|
<!--#ifdef MP-WEIXIN || MP-QQ || APP-PLUS-->
|
||||||
|
<rich-text v-else-if="n.decode" class="_entity" :nodes="[n]"></rich-text>
|
||||||
|
<!--#endif-->
|
||||||
|
<text v-else-if="n.type=='text'" decode>{{n.text}}</text>
|
||||||
|
<text v-else-if="n.name=='br'">\n</text>
|
||||||
|
<!--视频-->
|
||||||
|
<view v-else-if="n.name=='video'">
|
||||||
|
<view v-if="(!loadVideo||n.lazyLoad)&&!(controls[n.attrs.id]&&controls[n.attrs.id].play)" :id="n.attrs.id" :class="'_video '+(n.attrs.class||'')"
|
||||||
|
:style="n.attrs.style" @tap="_loadVideo" />
|
||||||
|
<video v-else :id="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style" :autoplay="n.attrs.autoplay||(controls[n.attrs.id]&&controls[n.attrs.id].play)"
|
||||||
|
:controls="n.attrs.controls" :loop="n.attrs.loop" :muted="n.attrs.muted" :poster="n.attrs.poster" :src="n.attrs.source[(controls[n.attrs.id]&&controls[n.attrs.id].index)||0]"
|
||||||
|
:unit-id="n.attrs['unit-id']" :data-id="n.attrs.id" data-from="video" data-source="source" @error="error" @play="play" />
|
||||||
|
</view>
|
||||||
|
<!--音频-->
|
||||||
|
<audio v-else-if="n.name=='audio'" :class="n.attrs.class" :style="n.attrs.style" :author="n.attrs.author" :autoplay="n.attrs.autoplay"
|
||||||
|
:controls="n.attrs.controls" :loop="n.attrs.loop" :name="n.attrs.name" :poster="n.attrs.poster" :src="n.attrs.source[(controls[n.attrs.id]&&controls[n.attrs.id].index)||0]"
|
||||||
|
:data-id="n.attrs.id" data-from="audio" data-source="source" @error="error" @play="play" />
|
||||||
|
<!--链接-->
|
||||||
|
<view v-else-if="n.name=='a'" :class="'_a '+(n.attrs.class||'')" hover-class="_hover" :style="n.attrs.style"
|
||||||
|
:data-attrs="n.attrs" @tap="linkpress">
|
||||||
|
<trees class="_span" :nodes="n.children" />
|
||||||
|
</view>
|
||||||
|
<!--广告(按需打开注释)-->
|
||||||
|
<!--#ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO-->
|
||||||
|
<!--<ad v-else-if="n.name=='ad'" :class="n.attrs.class" :style="n.attrs.style" :unit-id="n.attrs['unit-id']"
|
||||||
|
data-from="ad" @error="error" />-->
|
||||||
|
<!--#endif-->
|
||||||
|
<!--#ifdef MP-BAIDU-->
|
||||||
|
<!--<ad v-else-if="n.name=='ad'" :class="n.attrs.class" :style="n.attrs.style" :appid="n.attrs.appid"
|
||||||
|
:apid="n.attrs.apid" :type="n.attrs.type" data-from="ad" @error="error" />-->
|
||||||
|
<!--#endif-->
|
||||||
|
<!--#ifdef APP-PLUS-->
|
||||||
|
<!--<ad v-else-if="n.name=='ad'" :class="n.attrs.class" :style="n.attrs.style" :adpid="n.attrs.adpid"
|
||||||
|
data-from="ad" @error="error" />-->
|
||||||
|
<!--#endif-->
|
||||||
|
<!--列表-->
|
||||||
|
<view v-else-if="n.name=='li'" :id="n.attrs.id" :class="n.attrs.class" :style="(n.attrs.style||'')+';display:flex'">
|
||||||
|
<view v-if="n.type=='ol'" class="_ol-bef">{{n.num}}</view>
|
||||||
|
<view v-else class="_ul-bef">
|
||||||
|
<view v-if="n.floor%3==0" class="_ul-p1">█</view>
|
||||||
|
<view v-else-if="n.floor%3==2" class="_ul-p2" />
|
||||||
|
<view v-else class="_ul-p1" style="border-radius:50%">█</view>
|
||||||
|
</view>
|
||||||
|
<!--#ifdef MP-ALIPAY-->
|
||||||
|
<view class="_li">
|
||||||
|
<trees :nodes="n.children" />
|
||||||
|
</view>
|
||||||
|
<!--#endif-->
|
||||||
|
<!--#ifndef MP-ALIPAY-->
|
||||||
|
<trees class="_li" :nodes="n.children" :lazyLoad="lazyLoad" :loadVideo="loadVideo" />
|
||||||
|
<!--#endif-->
|
||||||
|
</view>
|
||||||
|
<!--表格-->
|
||||||
|
<view v-else-if="n.name=='table'&&n.c" :id="n.attrs.id" :class="n.attrs.class" :style="(n.attrs.style||'')+';display:table'">
|
||||||
|
<view v-for="(tbody, i) in n.children" v-bind:key="i" :class="tbody.attrs.class" :style="(tbody.attrs.style||'')+(tbody.name[0]=='t'?';display:table-'+(tbody.name=='tr'?'row':'row-group'):'')">
|
||||||
|
<view v-for="(tr, j) in tbody.children" v-bind:key="j" :class="tr.attrs.class" :style="(tr.attrs.style||'')+(tr.name[0]=='t'?';display:table-'+(tr.name=='tr'?'row':'cell'):'')">
|
||||||
|
<trees v-if="tr.name=='td'" :nodes="tr.children" :lazyLoad="lazyLoad" :loadVideo="loadVideo" />
|
||||||
|
<block v-else>
|
||||||
|
<!--#ifdef MP-ALIPAY-->
|
||||||
|
<view v-for="(td, k) in tr.children" v-bind:key="k" :class="td.attrs.class" :style="(td.attrs.style||'')+(td.name[0]=='t'?';display:table-'+(td.name=='tr'?'row':'cell'):'')">
|
||||||
|
<trees :nodes="td.children" />
|
||||||
|
</view>
|
||||||
|
<!--#endif-->
|
||||||
|
<!--#ifndef MP-ALIPAY-->
|
||||||
|
<trees v-for="(td, k) in tr.children" v-bind:key="k" :class="td.attrs.class" :style="(td.attrs.style||'')+(td.name[0]=='t'?';display:table-'+(td.name=='tr'?'row':'cell'):'')"
|
||||||
|
:nodes="td.children" :lazyLoad="lazyLoad" :loadVideo="loadVideo" />
|
||||||
|
<!--#endif-->
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!--#ifdef APP-PLUS-->
|
||||||
|
<iframe v-else-if="n.name=='iframe'" :style="n.attrs.style" :allowfullscreen="n.attrs.allowfullscreen" :frameborder="n.attrs.frameborder"
|
||||||
|
:width="n.attrs.width" :height="n.attrs.height" :src="n.attrs.src" />
|
||||||
|
<embed v-else-if="n.name=='embed'" :style="n.attrs.style" :width="n.attrs.width" :height="n.attrs.height" :src="n.attrs.src" />
|
||||||
|
<!--#endif-->
|
||||||
|
<!--富文本-->
|
||||||
|
<!--#ifdef MP-WEIXIN || MP-QQ || MP-ALIPAY || APP-PLUS-->
|
||||||
|
<rich-text v-else-if="handler.useRichText(n)" :id="n.attrs.id" :class="'_p __'+n.name" :nodes="[n]" />
|
||||||
|
<!--#endif-->
|
||||||
|
<!--#ifdef MP-BAIDU || MP-TOUTIAO-->
|
||||||
|
<rich-text v-else-if="!(n.c||n.continue)" :id="n.attrs.id" :class="_p" :style="n.attrs.contain" :nodes="[n]" />
|
||||||
|
<!--#endif-->
|
||||||
|
<!--#ifdef MP-ALIPAY-->
|
||||||
|
<view v-else :id="n.attrs.id" :class="'_'+n.name+' '+(n.attrs.class||'')" :style="n.attrs.style">
|
||||||
|
<trees :nodes="n.children" />
|
||||||
|
</view>
|
||||||
|
<!--#endif-->
|
||||||
|
<!--#ifndef MP-ALIPAY-->
|
||||||
|
<trees v-else :class="(n.attrs.id||'')+' _'+n.name+' '+(n.attrs.class||'')" :style="n.attrs.style" :nodes="n.children"
|
||||||
|
:lazyLoad="lazyLoad" :loadVideo="loadVideo" />
|
||||||
|
<!--#endif-->
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script module="handler" lang="wxs" src="./handler.wxs"></script>
|
||||||
|
<script module="handler" lang="sjs" src="./handler.sjs"></script>
|
||||||
|
<script>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
global.Parser = {};
|
||||||
|
import trees from './trees'
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
trees
|
||||||
|
},
|
||||||
|
name: 'trees',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
controls: {},
|
||||||
|
// #ifdef MP-WEIXIN || MP-QQ || APP-PLUS
|
||||||
|
imgLoad: false,
|
||||||
|
// #endif
|
||||||
|
// #ifndef APP-PLUS
|
||||||
|
loadVideo: true
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
nodes: Array,
|
||||||
|
// #ifdef MP-WEIXIN || MP-QQ || H5 || APP-PLUS
|
||||||
|
lazyLoad: Boolean,
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
loadVideo: Boolean
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// 获取顶层组件
|
||||||
|
this.top = this.$parent;
|
||||||
|
while (this.top.$options.name != 'parser') {
|
||||||
|
if (this.top.top) {
|
||||||
|
this.top = this.top.top;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.top = this.top.$parent;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// #ifdef MP-WEIXIN || MP-QQ || APP-PLUS
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.observer)
|
||||||
|
this.observer.disconnect();
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
methods: {
|
||||||
|
// #ifndef MP-ALIPAY
|
||||||
|
play(e) {
|
||||||
|
if (this.top.videoContexts.length > 1 && this.top.autopause)
|
||||||
|
for (var i = this.top.videoContexts.length; i--;)
|
||||||
|
if (this.top.videoContexts[i].id != e.currentTarget.dataset.id)
|
||||||
|
this.top.videoContexts[i].pause();
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
imgtap(e) {
|
||||||
|
var attrs = e.currentTarget.dataset.attrs;
|
||||||
|
if (!attrs.ignore) {
|
||||||
|
var preview = true, data = {
|
||||||
|
id: e.target.id,
|
||||||
|
src: attrs.src,
|
||||||
|
ignore: () => preview = false
|
||||||
|
};
|
||||||
|
global.Parser.onImgtap && global.Parser.onImgtap(data);
|
||||||
|
this.top.$emit('imgtap', data);
|
||||||
|
if (preview) {
|
||||||
|
var urls = this.top.imgList,
|
||||||
|
current = urls[attrs.i] ? parseInt(attrs.i) : (urls = [attrs.src], 0);
|
||||||
|
uni.previewImage({
|
||||||
|
current,
|
||||||
|
urls
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
imglongtap(e) {
|
||||||
|
var attrs = e.item.dataset.attrs;
|
||||||
|
if (!attrs.ignore)
|
||||||
|
this.top.$emit('imglongtap', {
|
||||||
|
id: e.target.id,
|
||||||
|
src: attrs.src
|
||||||
|
})
|
||||||
|
},
|
||||||
|
linkpress(e) {
|
||||||
|
var jump = true,
|
||||||
|
attrs = e.currentTarget.dataset.attrs;
|
||||||
|
attrs.ignore = () => jump = false;
|
||||||
|
global.Parser.onLinkpress && global.Parser.onLinkpress(attrs);
|
||||||
|
this.top.$emit('linkpress', attrs);
|
||||||
|
if (jump) {
|
||||||
|
// #ifdef MP
|
||||||
|
if (attrs['app-id']) {
|
||||||
|
return uni.navigateToMiniProgram({
|
||||||
|
appId: attrs['app-id'],
|
||||||
|
path: attrs.path
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
if (attrs.href) {
|
||||||
|
if (attrs.href[0] == '#') {
|
||||||
|
if (this.top.useAnchor)
|
||||||
|
this.top.navigateTo({
|
||||||
|
id: attrs.href.substring(1)
|
||||||
|
})
|
||||||
|
} else if (attrs.href.indexOf('http') == 0 || attrs.href.indexOf('//') == 0) {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
plus.runtime.openWeb(attrs.href);
|
||||||
|
// #endif
|
||||||
|
// #ifndef APP-PLUS
|
||||||
|
uni.setClipboardData({
|
||||||
|
data: attrs.href,
|
||||||
|
success: () =>
|
||||||
|
uni.showToast({
|
||||||
|
title: '链接已复制'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
} else
|
||||||
|
uni.navigateTo({
|
||||||
|
url: attrs.href
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error(e) {
|
||||||
|
var context, target = e.currentTarget,
|
||||||
|
source = target.dataset.from;
|
||||||
|
if (source == 'video' || source == 'audio') {
|
||||||
|
// 加载其他 source
|
||||||
|
var index = this.controls[target.id] ? this.controls[target.id].index + 1 : 1;
|
||||||
|
if (index < target.dataset.source.length)
|
||||||
|
this.$set(this.controls, target.id + '.index', index);
|
||||||
|
if (source == 'video') context = uni.createVideoContext(target.id, this);
|
||||||
|
}
|
||||||
|
this.top && this.top.$emit('error', {
|
||||||
|
source,
|
||||||
|
target,
|
||||||
|
errMsg: e.detail.errMsg,
|
||||||
|
errCode: e.detail.errCode,
|
||||||
|
context
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_loadVideo(e) {
|
||||||
|
this.$set(this.controls, e.currentTarget.id, {
|
||||||
|
play: true,
|
||||||
|
index: 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* 在这里引入自定义样式 */
|
||||||
|
|
||||||
|
/* 链接和图片效果 */
|
||||||
|
._a {
|
||||||
|
display: inline;
|
||||||
|
color: #366092;
|
||||||
|
word-break: break-all;
|
||||||
|
padding: 1.5px 0 1.5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
._hover {
|
||||||
|
opacity: 0.7;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
._img {
|
||||||
|
display: inline-block;
|
||||||
|
text-indent: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #ifdef MP-WEIXIN */
|
||||||
|
:host {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef MP */
|
||||||
|
.interlayer {
|
||||||
|
align-content: inherit;
|
||||||
|
align-items: inherit;
|
||||||
|
display: inherit;
|
||||||
|
flex-direction: inherit;
|
||||||
|
flex-wrap: inherit;
|
||||||
|
justify-content: inherit;
|
||||||
|
width: 100%;
|
||||||
|
white-space: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
._b,
|
||||||
|
._strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
._blockquote,
|
||||||
|
._div,
|
||||||
|
._p,
|
||||||
|
._ol,
|
||||||
|
._ul,
|
||||||
|
._li {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
._code {
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
._del {
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
||||||
|
._em,
|
||||||
|
._i {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
._h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
._h2 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
._h3 {
|
||||||
|
font-size: 1.17em;
|
||||||
|
}
|
||||||
|
|
||||||
|
._h5 {
|
||||||
|
font-size: 0.83em;
|
||||||
|
}
|
||||||
|
|
||||||
|
._h6 {
|
||||||
|
font-size: 0.67em;
|
||||||
|
}
|
||||||
|
|
||||||
|
._h1,
|
||||||
|
._h2,
|
||||||
|
._h3,
|
||||||
|
._h4,
|
||||||
|
._h5,
|
||||||
|
._h6 {
|
||||||
|
display: block;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
._ins {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
._li {
|
||||||
|
flex: 1;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
._ol-bef {
|
||||||
|
margin-right: 5px;
|
||||||
|
text-align: right;
|
||||||
|
width: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
._ul-bef {
|
||||||
|
line-height: normal;
|
||||||
|
margin: 0 12px 0 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
._ol-bef,
|
||||||
|
._ul_bef {
|
||||||
|
flex: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
._ul-p1 {
|
||||||
|
display: inline-block;
|
||||||
|
height: 0.3em;
|
||||||
|
line-height: 0.3em;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
._ul-p2 {
|
||||||
|
border: 0.05em solid black;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
height: 0.23em;
|
||||||
|
width: 0.23em;
|
||||||
|
}
|
||||||
|
|
||||||
|
._q::before {
|
||||||
|
content: '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
._q::after {
|
||||||
|
content: '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
._sub {
|
||||||
|
font-size: smaller;
|
||||||
|
vertical-align: sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
._sup {
|
||||||
|
font-size: smaller;
|
||||||
|
vertical-align: super;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #ifndef MP-WEIXIN */
|
||||||
|
._abbr,
|
||||||
|
._b,
|
||||||
|
._code,
|
||||||
|
._del,
|
||||||
|
._em,
|
||||||
|
._i,
|
||||||
|
._ins,
|
||||||
|
._label,
|
||||||
|
._q,
|
||||||
|
._span,
|
||||||
|
._strong,
|
||||||
|
._sub,
|
||||||
|
._sup {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef MP-WEIXIN || MP-QQ || MP-ALIPAY */
|
||||||
|
.__bdo,
|
||||||
|
.__bdi,
|
||||||
|
.__ruby,
|
||||||
|
.__rt,
|
||||||
|
._entity {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
._video {
|
||||||
|
background-color: black;
|
||||||
|
display: inline-block;
|
||||||
|
height: 225px;
|
||||||
|
position: relative;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
._video::after {
|
||||||
|
border-color: transparent transparent transparent white;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 15px 0 15px 30px;
|
||||||
|
content: '';
|
||||||
|
left: 50%;
|
||||||
|
margin: -15px 0 0 -15px;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,183 @@
|
||||||
|
<template>
|
||||||
|
<view class="msg-view">
|
||||||
|
<scroll-view class="msg-view-p" scroll-y="true" :scroll-top="msgPanelScrollTop">
|
||||||
|
<view id="chatArea">
|
||||||
|
<view class="chat-area-line" v-for="(item,index) in msgList">
|
||||||
|
|
||||||
|
<view class="system-msg"
|
||||||
|
:style="{'flex-direction':((item.userName.length + item.content.length)<15?'row':'')}"
|
||||||
|
v-if="item.msg_type == 'system'">
|
||||||
|
<view class="system-msg-detail ">
|
||||||
|
<text class="system-msg-detail-username " v-for="i in item.userName">{{i}}</text>
|
||||||
|
<text class="system-msg-detail-content " v-for="i in ':'">{{i}}</text>
|
||||||
|
<text class="system-msg-detail-content " v-for="i in item.content">{{i}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="user-msg"
|
||||||
|
:style="{'flex-direction':((item.userName.length + item.content.length)<15?'row':'')}" v-else>
|
||||||
|
|
||||||
|
<view class="user-msg-detail">
|
||||||
|
<view class="user-msg-detail-tag">
|
||||||
|
<!-- <text style="text-align: center;font-size: 20px;color: #DD524D;">★1</text> -->
|
||||||
|
<!-- 这里可以根据用户等级显示图片 -->
|
||||||
|
<image :src="item.avatar" class="user-msg-detail-tag"></image>
|
||||||
|
</view>
|
||||||
|
<text class="user-msg-detail-username" v-for="i in item.userName"
|
||||||
|
@click="test(item.userName)">{{i}}</text>
|
||||||
|
<text class="user-msg-detail-content" v-for="i in ':'">{{i}}</text>
|
||||||
|
<text class="user-msg-detail-content" v-for="i in item.content">{{i}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'MhMsgList',
|
||||||
|
props: {
|
||||||
|
msgList: {
|
||||||
|
type: [Object, Array],
|
||||||
|
default: [{
|
||||||
|
userName: "系统通知",
|
||||||
|
content: "直播倡导绿色直播,严禁发布涉黄涉毒涉赌,严禁发布涉政、违法及低俗违规内容。健康直播,文明互动",
|
||||||
|
cmd: "say",
|
||||||
|
|
||||||
|
msg_type: "system"
|
||||||
|
}, ]
|
||||||
|
},
|
||||||
|
msgPanelScrollTop: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
test(e) {
|
||||||
|
uni.showToast({
|
||||||
|
title: e,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
setMsgPanelScroll() {
|
||||||
|
var that = this;
|
||||||
|
setTimeout(function() {
|
||||||
|
const query = uni.createSelectorQuery().in(that);
|
||||||
|
query.select('#chatArea').boundingClientRect(data => {
|
||||||
|
that.msgPanelScrollTop = data.height - 200;
|
||||||
|
}).exec();
|
||||||
|
}, 50)
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.msg-view-p {
|
||||||
|
display: flex;
|
||||||
|
width: 550rpx;
|
||||||
|
height: 550rpx;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.chat-area-line {
|
||||||
|
width: 550upx;
|
||||||
|
|
||||||
|
flex-direction: row;
|
||||||
|
margin-bottom: 5upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.system-msg {
|
||||||
|
width: 550upx;
|
||||||
|
margin-bottom: 5upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.system-msg-detail {
|
||||||
|
// max-width: 550upx;
|
||||||
|
|
||||||
|
padding: 10upx;
|
||||||
|
border-radius: 30upx;
|
||||||
|
background-color: rgba($color: #000000, $alpha: 0.4);
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-right: 14upx;
|
||||||
|
|
||||||
|
>.system-msg-detail-username {
|
||||||
|
color: red;
|
||||||
|
font-size: 32upx;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 40upx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
>.system-msg-detail-content {
|
||||||
|
font-size: 32upx;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 40upx;
|
||||||
|
color: #A0CFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-line {
|
||||||
|
// max-width: 530upx;
|
||||||
|
padding: 10upx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
flex-direction: row;
|
||||||
|
border-radius: 30upx;
|
||||||
|
background-color: rgba($color: #000000, $alpha: 0.4);
|
||||||
|
margin-right: 14upx;
|
||||||
|
font-size: 28upx;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 40upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-msg {
|
||||||
|
width: 530upx;
|
||||||
|
|
||||||
|
|
||||||
|
margin-bottom: 5upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-msg-detail-tag {
|
||||||
|
width: 40upx;
|
||||||
|
height: 40upx;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-msg-detail {
|
||||||
|
padding: 10upx;
|
||||||
|
border-radius: 30upx;
|
||||||
|
background-color: rgba($color: #000000, $alpha: 0.4);
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-right: 14upx;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
>.user-msg-detail-username {
|
||||||
|
color: #A0CFFF;
|
||||||
|
font-size: 32upx;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 40upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
>.user-msg-detail-content {
|
||||||
|
font-size: 32upx;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 40upx;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,488 @@
|
||||||
|
<template>
|
||||||
|
<view class="containers">
|
||||||
|
<view class="header">
|
||||||
|
<view class="search">
|
||||||
|
<text class="iconfont icon-xiazai5"></text>
|
||||||
|
<input type="text" placeholder="请输入商品名称" v-model="searchVal" @input="setValue" confirm-type="search"
|
||||||
|
@confirm="searchBut()" placeholder-class='placeholder'>
|
||||||
|
</view>
|
||||||
|
<view class="iconclose" @click="close">
|
||||||
|
<image src="@/static/img/close.png" mode="aspectFit"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="main">
|
||||||
|
<scroll-view scroll-y="true" @touchmove.stop>
|
||||||
|
<block>
|
||||||
|
|
||||||
|
<view v-if="bought.length>0" @touchmove="onTouchmove" id="goods" class="goods">
|
||||||
|
<view class="picTxt acea-row" v-for="(item, i) in bought" :key="i">
|
||||||
|
<view class="checkbox">
|
||||||
|
<text @click.stop="goodsCheck(item)" v-if="item.check" class="iconfont icon-xuanzhong1"
|
||||||
|
style="color: red;"></text>
|
||||||
|
<text @click.stop="goodsCheck(item)" v-else class="iconfont icon-weixuanzhong"></text>
|
||||||
|
</view>
|
||||||
|
<view class='pictrue'>
|
||||||
|
<image :src='item.image'></image>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class='text'>
|
||||||
|
<view class='line2 name'>{{item.store_name}}</view>
|
||||||
|
<view class="" style="margin-top: 20rpx;">
|
||||||
|
{{item.price}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="empty">
|
||||||
|
<image src="/static/images/no_thing.png"></image>
|
||||||
|
<text>暂无内容哦~</text>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</scroll-view>
|
||||||
|
<view class="foot_bar">
|
||||||
|
<button class="confirm_btn" @click="submit">确定({{checkedArr.length}})</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import subtractive from '@/components/subtractive/subtractive.vue';
|
||||||
|
|
||||||
|
import {
|
||||||
|
good
|
||||||
|
} from '@/api/api.js'
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
checkedObj: {
|
||||||
|
type: Array,
|
||||||
|
default: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
subtractive
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isActive: 0,
|
||||||
|
loadedb: false,
|
||||||
|
loadingb: false,
|
||||||
|
loadedc: false,
|
||||||
|
loadingc: false,
|
||||||
|
loadeds: false,
|
||||||
|
loadings: false,
|
||||||
|
whereb: {
|
||||||
|
page: 1,
|
||||||
|
limit: 10,
|
||||||
|
keyword: '',
|
||||||
|
},
|
||||||
|
peicenumber: 0,
|
||||||
|
|
||||||
|
searchVal: '',
|
||||||
|
checked: [],
|
||||||
|
list: [],
|
||||||
|
|
||||||
|
bought: [],
|
||||||
|
|
||||||
|
checkedArr: [],
|
||||||
|
aryys: [],
|
||||||
|
// picker下拉数据源
|
||||||
|
storageCustomList: [],
|
||||||
|
index: 0,
|
||||||
|
pickerData: '请选择',
|
||||||
|
itstock: '',
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
checkedObj: {
|
||||||
|
handler(n) {
|
||||||
|
this.checkedArr = n
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
this.checkedArr = this.checkedObj
|
||||||
|
this.aryys = this.checkedObj
|
||||||
|
this.getBounht();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
//价格
|
||||||
|
producrprice(e, i, item) {
|
||||||
|
this.bought[i].price = e.detail.value
|
||||||
|
this.$set(item, 'check', false);
|
||||||
|
for (let i in this.checkedArr) {
|
||||||
|
if (this.checkedArr[i].product_id == item.product_id) {
|
||||||
|
this.checkedArr.splice(i, 1)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
incrementTotal(e, i, item) {
|
||||||
|
// console.log(e, i, item)
|
||||||
|
this.$set(item, 'check', false);
|
||||||
|
for (let i in this.checkedArr) {
|
||||||
|
if (this.checkedArr[i].product_id == item.product_id) {
|
||||||
|
this.checkedArr.splice(i, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
// picker修改事件
|
||||||
|
bindPickerChange: function(e, storage, num) {
|
||||||
|
this.bought[num].attrValue[this.index].sku = storage[e.detail.value].sku
|
||||||
|
this.bought[num].attrValue[this.index].stock = storage[e.detail.value].stock
|
||||||
|
this.bought[num].product_attr_unique = storage[e.detail.value].unique
|
||||||
|
this.pickerData = storage[this.index] // 这里就是选中的对象
|
||||||
|
if (this.bought[num].attrValue[this.index].stock == 0) {
|
||||||
|
this.$util.Tips({
|
||||||
|
title: '库存不足'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 点击关闭按钮
|
||||||
|
close() {
|
||||||
|
this.$emit('close');
|
||||||
|
},
|
||||||
|
numberChange(data, i) {
|
||||||
|
this.peicenumber = data.number;
|
||||||
|
this.bought[i].number = data.number
|
||||||
|
|
||||||
|
},
|
||||||
|
setValue: function(event) {
|
||||||
|
this.$set(this.whereb, 'keyword', event.detail.value);
|
||||||
|
if (!event.detail.value) {
|
||||||
|
this.whereb.page = 1
|
||||||
|
this.loadedb = false
|
||||||
|
this.getBounht()
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
searchBut() {
|
||||||
|
this.bought = []
|
||||||
|
this.whereb.page = 1
|
||||||
|
this.loadedb = false
|
||||||
|
this.getBounht()
|
||||||
|
},
|
||||||
|
tabs(index) {
|
||||||
|
this.isActive = index
|
||||||
|
this.$set(this.whereb, 'keyword', '');
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
onTouchmove(e) {
|
||||||
|
if (this.loadendb) return;
|
||||||
|
if (this.loadingb) return;
|
||||||
|
const query = uni.createSelectorQuery().in(this);
|
||||||
|
query.select('#goods').boundingClientRect(data => {
|
||||||
|
if (data.bottom < 1500 && data.top < 0) {
|
||||||
|
this.getBounht();
|
||||||
|
}
|
||||||
|
}).exec();
|
||||||
|
|
||||||
|
// 模拟触底刷新
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
getBounht() {
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
// if (that.loadingb || that.loadedb) return;
|
||||||
|
// that.loadingb = true;
|
||||||
|
|
||||||
|
good(that.whereb).then(
|
||||||
|
res => {
|
||||||
|
that.loadingb = false;
|
||||||
|
that.loadedb = res.data.list.length < that.whereb.limit;
|
||||||
|
that.bought.push.apply(that.bought, res.data.list);
|
||||||
|
that.whereb.page = that.whereb.page + 1;
|
||||||
|
that.getInitchecked(that.bought);
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
|
||||||
|
console.log(error.msg)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*获取初始化选中的数据*/
|
||||||
|
getInitchecked(arr) {
|
||||||
|
let that = this;
|
||||||
|
arr.forEach((item, index) => {
|
||||||
|
that.$set(item, 'check', false);
|
||||||
|
that.checkedArr.forEach((val, i) => {
|
||||||
|
if (item.product_id == val.product_id) {
|
||||||
|
that.$set(item, 'check', true);
|
||||||
|
that.$set(item, 'number', val.number);
|
||||||
|
that.$set(item, 'price', val.price);
|
||||||
|
that.peicenumber = val.number
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
/*已选中的商品打钩*/
|
||||||
|
getCheckedGoods() {
|
||||||
|
this.checked = []
|
||||||
|
this.checkedArr.forEach((item, index) => {
|
||||||
|
this.checkedArr.push(item)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/*点击选中与否*/
|
||||||
|
goodsCheck(item) {
|
||||||
|
this.$set(item, 'check', !item.check);
|
||||||
|
if (item.check) {
|
||||||
|
this.checkedArr.push(item)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.checkedArr.splice(this.checkedArr.findIndex(itemn => ((itemn.product_id == item.product_id))), 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/*确定提交*/
|
||||||
|
submit() {
|
||||||
|
this.$emit('getProduct', this.checkedArr);
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.containers {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 16rpx 16rpx 0 0;
|
||||||
|
padding: 40rpx 0;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.header {
|
||||||
|
position: relative;
|
||||||
|
padding: 0 30rpx;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
text {
|
||||||
|
position: relative;
|
||||||
|
margin: 0 50rpx;
|
||||||
|
color: #999999;
|
||||||
|
font-size: 30rpx;
|
||||||
|
|
||||||
|
&.on {
|
||||||
|
color: #333333;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 34rpx;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
width: 40rpx;
|
||||||
|
height: 5rpx;
|
||||||
|
background: var(--view-theme);
|
||||||
|
position: absolute;
|
||||||
|
bottom: -10rpx;
|
||||||
|
left: 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconclose {
|
||||||
|
width: 44rpx;
|
||||||
|
height: 44rpx;
|
||||||
|
line-height: 44rpx;
|
||||||
|
|
||||||
|
border-radius: 50%;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: -150rpx;
|
||||||
|
right: 30rpx;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.sub_title {
|
||||||
|
color: #282828;
|
||||||
|
font-size: 26rpx;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
color: #8A8A8A;
|
||||||
|
font-size: 28rpx;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 30rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scroll-view {
|
||||||
|
height: 650rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
height: 650rpx;
|
||||||
|
margin: 40rpx 0 80rpx;
|
||||||
|
padding: 0 30rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.picTxt {
|
||||||
|
width: 100%;
|
||||||
|
padding: 25rpx 0;
|
||||||
|
position: relative;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
border-top: 2rpx solid #E7E6E4;
|
||||||
|
|
||||||
|
.picTxt_one {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picTxt_one {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
|
||||||
|
|
||||||
|
.slecte {
|
||||||
|
margin-right: 30rpx;
|
||||||
|
width: 280rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
line-height: 60rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-family: PingFang SC-Regular, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #959595;
|
||||||
|
background-color: #E7E6E4;
|
||||||
|
border-radius: 10rpx 10rpx 10rpx 10rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
margin-right: 30rpx;
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-size: 38rpx;
|
||||||
|
color: #CCCCCC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-xuanzhong1 {
|
||||||
|
color: var(--view-theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabled {
|
||||||
|
pointer-events: none;
|
||||||
|
cursor: default;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pictrue {
|
||||||
|
width: 160rpx;
|
||||||
|
height: 160rpx;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
width: 430rpx;
|
||||||
|
margin-left: 30rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #282828;
|
||||||
|
position: relative;
|
||||||
|
height: 160rpx;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
color: #282828;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.money {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
color: var(--view-priceColor);
|
||||||
|
font-size: 22rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.foot_bar {
|
||||||
|
width: 100%;
|
||||||
|
position: fixed;
|
||||||
|
// bottom: 54px;
|
||||||
|
left: 0;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
z-index: 5;
|
||||||
|
|
||||||
|
.confirm_btn {
|
||||||
|
width: 710rpx;
|
||||||
|
height: 86rpx;
|
||||||
|
line-height: 86rpx;
|
||||||
|
color: #ffffff;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
background-color: red;
|
||||||
|
border-radius: 43rpx;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty {
|
||||||
|
margin: 130rpx 0 150rpx;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
image,
|
||||||
|
uni-image {
|
||||||
|
display: inline-block;
|
||||||
|
width: 414rpx;
|
||||||
|
height: 305rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
text {
|
||||||
|
display: block;
|
||||||
|
color: #999999;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,217 @@
|
||||||
|
<template>
|
||||||
|
<view class="uni-numbox">
|
||||||
|
<!-- -部分 -->
|
||||||
|
<view class="uni-numbox-minus" @click="_calcValue('subtract')">
|
||||||
|
<text :class="minDisabled?'uni-numbox-disabled': ''">-</text>
|
||||||
|
</view>
|
||||||
|
<!-- 中间输入数值部分 -->
|
||||||
|
<input class="uni-numbox-value" type="number" :disabled="disabled" :value="inputValue" @blur="_onBlur">
|
||||||
|
<!-- + 部分 -->
|
||||||
|
<view class="uni-numbox-plus" @click="_calcValue('add')">
|
||||||
|
<text :class="maxDisabled?'uni-numbox-disabled': ''">+</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'uni-number-box',
|
||||||
|
props: {
|
||||||
|
// isMax 是否有上限设置
|
||||||
|
isMax: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// isMin 是否有下限设置
|
||||||
|
isMin: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// index 唯一值,如果一个页面有多个数量增减组件时,起到唯一的作用
|
||||||
|
index: {
|
||||||
|
type: String,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
// value 是数值
|
||||||
|
value: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
// min 最小值
|
||||||
|
min: {
|
||||||
|
type: Number,
|
||||||
|
default: -Infinity
|
||||||
|
},
|
||||||
|
// max 最大值
|
||||||
|
max: {
|
||||||
|
type: Number,
|
||||||
|
default: Infinity
|
||||||
|
},
|
||||||
|
// step 步长
|
||||||
|
step: {
|
||||||
|
type: Number,
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
|
// disabled 是否禁用
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
inputValue: this.value,
|
||||||
|
minDisabled: false,
|
||||||
|
maxDisabled: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.maxDisabled = this.isMax;
|
||||||
|
this.minDisabled = this.isMin;
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
inputValue(number) {
|
||||||
|
const data = {
|
||||||
|
number: number,
|
||||||
|
index: this.index
|
||||||
|
}
|
||||||
|
this.$emit('eventChange', data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
_calcValue(type) {
|
||||||
|
const scale = this._getDecimalScale();
|
||||||
|
let value = this.inputValue * scale;
|
||||||
|
let newValue = 0;
|
||||||
|
let step = this.step * scale;
|
||||||
|
|
||||||
|
if (type === 'subtract') {
|
||||||
|
newValue = value - step;
|
||||||
|
if (newValue <= this.min) {
|
||||||
|
this.minDisabled = true;
|
||||||
|
}
|
||||||
|
if (newValue < this.min) {
|
||||||
|
newValue = this.min
|
||||||
|
this.$util.Tips({
|
||||||
|
title: '达到最小值了',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (newValue < this.max && this.maxDisabled === true) {
|
||||||
|
this.maxDisabled = false;
|
||||||
|
}
|
||||||
|
} else if (type === 'add') {
|
||||||
|
newValue = value + step;
|
||||||
|
if (newValue >= this.max) {
|
||||||
|
this.maxDisabled = true;
|
||||||
|
}
|
||||||
|
if (newValue > this.max) {
|
||||||
|
this.$util.Tips({
|
||||||
|
title: '达到最大值了',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
newValue = this.max
|
||||||
|
}
|
||||||
|
if (newValue > this.min && this.minDisabled === true) {
|
||||||
|
this.minDisabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newValue === value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.inputValue = newValue / scale;
|
||||||
|
this.$emit('increment', this.inputValue)
|
||||||
|
},
|
||||||
|
_getDecimalScale() {
|
||||||
|
let scale = 1;
|
||||||
|
// 浮点型
|
||||||
|
if (~~this.step !== this.step) {
|
||||||
|
scale = Math.pow(10, (this.step + '').split('.')[1].length);
|
||||||
|
}
|
||||||
|
return scale;
|
||||||
|
},
|
||||||
|
_onBlur(event) {
|
||||||
|
let value = event.detail.value;
|
||||||
|
if (!value) {
|
||||||
|
this.inputValue = 0;
|
||||||
|
return
|
||||||
|
}
|
||||||
|
value = +value;
|
||||||
|
if (value > this.max) {
|
||||||
|
value = this.max;
|
||||||
|
} else if (value < this.min) {
|
||||||
|
value = this.min
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inputValue = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.uni-numbox {
|
||||||
|
/* position:absolute; */
|
||||||
|
/* left: 30upx;
|
||||||
|
bottom: 0; */
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
width: 200upx;
|
||||||
|
height: 50upx;
|
||||||
|
/* background:#f5f5f5; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-numbox-minus {
|
||||||
|
background: #EEEEEE !important;
|
||||||
|
|
||||||
|
color: #909399 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-numbox-minus,
|
||||||
|
.uni-numbox-plus {
|
||||||
|
margin: 0;
|
||||||
|
width: 53rpx;
|
||||||
|
height: 53rpx;
|
||||||
|
background-color: #F84221;
|
||||||
|
opacity: 1;
|
||||||
|
line-height: 53rpx;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 40upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-numbox-minus .yticon,
|
||||||
|
.uni-numbox-plus .yticon {
|
||||||
|
font-size: 36upx;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-numbox-minus {
|
||||||
|
/* border-right: none;
|
||||||
|
border-top-left-radius: 6upx;
|
||||||
|
border-bottom-left-radius: 6upx; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-numbox-plus {
|
||||||
|
/* border-left: none;
|
||||||
|
border-top-right-radius: 6upx;
|
||||||
|
border-bottom-right-radius: 6upx; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-numbox-value {
|
||||||
|
position: relative;
|
||||||
|
/* background-color: #f5f5f5; */
|
||||||
|
width: 90upx;
|
||||||
|
height: 50upx;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 30upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-numbox-disabled.yticon {
|
||||||
|
color: #d6d6d6;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,241 @@
|
||||||
|
<template>
|
||||||
|
<view v-if="showPopup" class="uni-popup" @touchmove.stop.prevent="clear">
|
||||||
|
<uni-transition :mode-class="['fade']" :styles="maskClass" :show="showTrans" @click="onTap" />
|
||||||
|
<uni-transition :mode-class="ani" :styles="transClass" :show="showTrans" @click="onTap">
|
||||||
|
<view class="uni-popup__wrapper-box" @click.stop="clear">
|
||||||
|
<slot />
|
||||||
|
</view>
|
||||||
|
</uni-transition>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
|
||||||
|
props: {
|
||||||
|
// 开启动画
|
||||||
|
animation: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'center'
|
||||||
|
},
|
||||||
|
// maskClick
|
||||||
|
maskClick: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
ani: [],
|
||||||
|
showPopup: false,
|
||||||
|
showTrans: false,
|
||||||
|
maskClass: {
|
||||||
|
'position': 'fixed',
|
||||||
|
'bottom': 0,
|
||||||
|
'top': 0,
|
||||||
|
'left': 0,
|
||||||
|
'right': 0,
|
||||||
|
'backgroundColor': 'rgba(0, 0, 0, 0)'
|
||||||
|
},
|
||||||
|
transClass: {
|
||||||
|
'position': 'fixed',
|
||||||
|
'left': 0,
|
||||||
|
'right': 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
type: {
|
||||||
|
handler: function(newVal) {
|
||||||
|
switch (this.type) {
|
||||||
|
case 'top':
|
||||||
|
this.ani = ['slide-top']
|
||||||
|
this.transClass = {
|
||||||
|
'position': 'fixed',
|
||||||
|
'left': 0,
|
||||||
|
'right': 0,
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'bottom':
|
||||||
|
this.ani = ['slide-bottom']
|
||||||
|
this.transClass = {
|
||||||
|
'position': 'fixed',
|
||||||
|
'left': 0,
|
||||||
|
'right': 0,
|
||||||
|
'bottom': 0
|
||||||
|
}
|
||||||
|
console.log('直播调用弹窗')
|
||||||
|
break
|
||||||
|
case 'center':
|
||||||
|
this.ani = ['zoom-out', 'fade']
|
||||||
|
this.transClass = {
|
||||||
|
'position': 'fixed',
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
'display': 'flex',
|
||||||
|
'flexDirection': 'column',
|
||||||
|
/* #endif */
|
||||||
|
'bottom': 0,
|
||||||
|
'left': 0,
|
||||||
|
'right': 0,
|
||||||
|
'top': 0,
|
||||||
|
'justifyContent': 'center',
|
||||||
|
'alignItems': 'center'
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {},
|
||||||
|
methods: {
|
||||||
|
clear(e) {
|
||||||
|
// TODO nvue 取消冒泡
|
||||||
|
e.stopPropagation()
|
||||||
|
},
|
||||||
|
open() {
|
||||||
|
this.showPopup = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showTrans = true
|
||||||
|
}, 0);
|
||||||
|
})
|
||||||
|
this.$emit('change', {
|
||||||
|
show: true
|
||||||
|
})
|
||||||
|
},
|
||||||
|
close(type) {
|
||||||
|
this.showTrans = false
|
||||||
|
this.$nextTick(() => {
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
this.timer = setTimeout(() => {
|
||||||
|
this.$emit('change', {
|
||||||
|
show: false
|
||||||
|
})
|
||||||
|
this.showPopup = false
|
||||||
|
}, 0)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onTap() {
|
||||||
|
if (!this.maskClick) return
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.uni-popup {
|
||||||
|
position: fixed;
|
||||||
|
/* #ifdef H5 */
|
||||||
|
top: var(--window-top);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef H5 */
|
||||||
|
top: 0;
|
||||||
|
/* #endif */
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
z-index: 99;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__mask {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-ani {
|
||||||
|
transition-property: opacity;
|
||||||
|
transition-duration: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-top-mask {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-bottom-mask {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-center-mask {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__wrapper {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: block;
|
||||||
|
/* #endif */
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
transform: translateY(-500px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
transform: translateY(500px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
/* #endif */
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
transform: scale(1.2);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__wrapper-box {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: block;
|
||||||
|
/* #endif */
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-ani {
|
||||||
|
/* transition: transform 0.3s;
|
||||||
|
*/
|
||||||
|
transition-property: transform, opacity;
|
||||||
|
transition-duration: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.uni-top-content {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-bottom-content {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-center-content {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,241 @@
|
||||||
|
<template>
|
||||||
|
<view v-if="showPopup" class="uni-popup" @touchmove.stop.prevent="clear">
|
||||||
|
<uni-transition :mode-class="['fade']" :styles="maskClass" :show="showTrans" @click="onTap" />
|
||||||
|
<uni-transition :mode-class="ani" :styles="transClass" :show="showTrans" @click="onTap">
|
||||||
|
<view class="uni-popup__wrapper-box" @click.stop="clear">
|
||||||
|
<slot />
|
||||||
|
</view>
|
||||||
|
</uni-transition>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
props: {
|
||||||
|
// 开启动画
|
||||||
|
animation: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'center'
|
||||||
|
},
|
||||||
|
// maskClick
|
||||||
|
maskClick: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
ani: [],
|
||||||
|
showPopup: false,
|
||||||
|
showTrans: false,
|
||||||
|
maskClass: {
|
||||||
|
'position': 'fixed',
|
||||||
|
'bottom': 0,
|
||||||
|
'top': 0,
|
||||||
|
'left': 0,
|
||||||
|
'right': 0,
|
||||||
|
'backgroundColor': 'rgba(0, 0, 0, 0.4)'
|
||||||
|
},
|
||||||
|
transClass: {
|
||||||
|
'position': 'fixed',
|
||||||
|
'left': 0,
|
||||||
|
'right': 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
type: {
|
||||||
|
handler: function(newVal) {
|
||||||
|
switch (this.type) {
|
||||||
|
case 'top':
|
||||||
|
this.ani = ['slide-top']
|
||||||
|
this.transClass = {
|
||||||
|
'position': 'fixed',
|
||||||
|
'left': 0,
|
||||||
|
'right': 0,
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'bottom':
|
||||||
|
this.ani = ['slide-bottom']
|
||||||
|
this.transClass = {
|
||||||
|
'position': 'fixed',
|
||||||
|
'left': 0,
|
||||||
|
'right': 0,
|
||||||
|
'bottom': 0
|
||||||
|
}
|
||||||
|
console.log('底部条用')
|
||||||
|
console.log(this.type)
|
||||||
|
break
|
||||||
|
case 'center':
|
||||||
|
this.ani = ['zoom-out', 'fade']
|
||||||
|
this.transClass = {
|
||||||
|
'position': 'fixed',
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
'display': 'flex',
|
||||||
|
'flexDirection': 'column',
|
||||||
|
/* #endif */
|
||||||
|
'bottom': 0,
|
||||||
|
'left': 0,
|
||||||
|
'right': 0,
|
||||||
|
'top': 0,
|
||||||
|
'justifyContent': 'center',
|
||||||
|
'alignItems': 'center'
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {},
|
||||||
|
methods: {
|
||||||
|
clear(e) {
|
||||||
|
// TODO nvue 取消冒泡
|
||||||
|
e.stopPropagation()
|
||||||
|
},
|
||||||
|
open() {
|
||||||
|
this.showPopup = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showTrans = true
|
||||||
|
}, 50);
|
||||||
|
})
|
||||||
|
this.$emit('change', {
|
||||||
|
show: true
|
||||||
|
})
|
||||||
|
},
|
||||||
|
close(type) {
|
||||||
|
this.showTrans = false
|
||||||
|
this.$nextTick(() => {
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
this.timer = setTimeout(() => {
|
||||||
|
this.$emit('change', {
|
||||||
|
show: false
|
||||||
|
})
|
||||||
|
this.showPopup = false
|
||||||
|
}, 300)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onTap() {
|
||||||
|
if (!this.maskClick) return
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.uni-popup {
|
||||||
|
position: fixed;
|
||||||
|
/* #ifdef H5 */
|
||||||
|
top: var(--window-top);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef H5 */
|
||||||
|
top: 0;
|
||||||
|
/* #endif */
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
z-index: 99;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__mask {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-ani {
|
||||||
|
transition-property: opacity;
|
||||||
|
transition-duration: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-top-mask {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-bottom-mask {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-center-mask {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__wrapper {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: block;
|
||||||
|
/* #endif */
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
transform: translateY(-500px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
transform: translateY(500px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
/* #endif */
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
transform: scale(1.2);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__wrapper-box {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: block;
|
||||||
|
/* #endif */
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-ani {
|
||||||
|
/* transition: transform 0.3s;
|
||||||
|
*/
|
||||||
|
transition-property: transform, opacity;
|
||||||
|
transition-duration: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.uni-top-content {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-bottom-content {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-center-content {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,12 @@
|
||||||
|
// import CryptoJS from './crypto-js.js'
|
||||||
|
/**
|
||||||
|
* @word 要加密的内容
|
||||||
|
* @keyWord String 服务器随机返回的关键字
|
||||||
|
* */
|
||||||
|
export function aesEncrypt(word,keyWord="XwKsGlMcdPMEhR1B"){
|
||||||
|
// var key = CryptoJS.enc.Utf8.parse(keyWord);
|
||||||
|
// var srcs = CryptoJS.enc.Utf8.parse(word);
|
||||||
|
// var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
|
||||||
|
// return encrypted.toString();
|
||||||
|
return word
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,544 @@
|
||||||
|
<template>
|
||||||
|
<view style="position: relative">
|
||||||
|
<view class="verify-image-out" v-show="showImage">
|
||||||
|
<view class="verify-image-panel" :style="{'width': imgSize.width,
|
||||||
|
'height': imgSize.height,
|
||||||
|
'margin-bottom': vSpace + 'px'}">
|
||||||
|
<view class="verify-refresh" style="z-index:3" @click="refresh" v-show="showRefresh">
|
||||||
|
<text class="iconfont icon-refresh"></text>
|
||||||
|
</view>
|
||||||
|
<image :src="pointBackImgBase?('data:image/png;base64,'+pointBackImgBase):defaultImg" id="image"
|
||||||
|
ref="canvas" style="width:100%;height:100%;display:block"
|
||||||
|
@click=" bindingClick? canvasClick($event): undefined"></image>
|
||||||
|
<view v-for="(tempPoint, index) in tempPoints" :key="index" class="point-area" :style="{
|
||||||
|
'background-color':'#1abd6c',
|
||||||
|
color:'#fff',
|
||||||
|
'z-index':9999,
|
||||||
|
width:'20px',
|
||||||
|
height:'20px',
|
||||||
|
'text-align':'center',
|
||||||
|
'line-height':'20px',
|
||||||
|
'border-radius': '50%',
|
||||||
|
position:'absolute',
|
||||||
|
top:parseInt(tempPoint.y-10) + 'px',
|
||||||
|
left:parseInt(tempPoint.x-10) + 'px'
|
||||||
|
}">
|
||||||
|
{{index + 1}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 'height': this.barSize.height, -->
|
||||||
|
<view class="verify-bar-area" :style="{'width': imgSize.width,
|
||||||
|
'color': barAreaColor,
|
||||||
|
'border-color': barAreaBorderColor,
|
||||||
|
'line-height':'40px'}">
|
||||||
|
<text class="verify-msg">{{text}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script type="text/babel">
|
||||||
|
/**
|
||||||
|
* VerifyPoints
|
||||||
|
* @description 点选
|
||||||
|
* */
|
||||||
|
import {aesEncrypt} from "./../utils/ase.js"
|
||||||
|
import {getAjcaptcha,ajcaptchaCheck} from '@/api/api.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'VerifyPoints',
|
||||||
|
props: {
|
||||||
|
//弹出式pop,固定fixed
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'fixed'
|
||||||
|
},
|
||||||
|
captchaType:{
|
||||||
|
type:String,
|
||||||
|
},
|
||||||
|
//间隔
|
||||||
|
vSpace: {
|
||||||
|
type: Number,
|
||||||
|
default: 5
|
||||||
|
},
|
||||||
|
imgSize: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
width: '310px',
|
||||||
|
height: '155px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
barSize: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
width: '310px',
|
||||||
|
height: '40px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultImg: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
secretKey:'', //后端返回的加密秘钥 字段
|
||||||
|
checkNum:3, //
|
||||||
|
fontPos: [], // 选中的坐标信息
|
||||||
|
checkPosArr: [], //用户点击的坐标
|
||||||
|
num: 1, //点击的记数
|
||||||
|
pointBackImgBase:'', //后端获取到的背景图片
|
||||||
|
poinTextList:[], //后端返回的点击字体顺序
|
||||||
|
backToken:'', //后端返回的token值
|
||||||
|
imgRand: 0, //随机的背景图片
|
||||||
|
setSize: {
|
||||||
|
imgHeight: 0,
|
||||||
|
imgWidth: 0,
|
||||||
|
barHeight: 0,
|
||||||
|
barWidth: 0
|
||||||
|
},
|
||||||
|
showImage: true,
|
||||||
|
tempPoints: [],
|
||||||
|
text: '',
|
||||||
|
barAreaColor: '#fff',
|
||||||
|
barAreaBorderColor: "#fff",
|
||||||
|
showRefresh: true,
|
||||||
|
bindingClick: true,
|
||||||
|
imgLeft:'' ,
|
||||||
|
imgTop:'',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
//加载页面
|
||||||
|
this.fontPos.splice(0, this.fontPos.length)
|
||||||
|
this.checkPosArr.splice(0, this.checkPosArr.length)
|
||||||
|
this.num = 1
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.refresh();
|
||||||
|
this.$parent.$emit('ready', this)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
canvasClick(e) {
|
||||||
|
const query = uni.createSelectorQuery().in(this);
|
||||||
|
query.select('#image').boundingClientRect(data => {
|
||||||
|
this.imgLeft =Math.ceil(data.left)
|
||||||
|
this.imgTop =Math.ceil(data.top)
|
||||||
|
this.checkPosArr.push(this.getMousePos(this.$refs.canvas, e));
|
||||||
|
if (this.num == this.checkNum) {
|
||||||
|
this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e));
|
||||||
|
//按比例转换坐标值
|
||||||
|
this.checkPosArr = this.pointTransfrom(this.checkPosArr,this.imgSize);
|
||||||
|
//等创建坐标执行完
|
||||||
|
setTimeout(() => {
|
||||||
|
//发送后端请求
|
||||||
|
var captchaVerification =this.secretKey? aesEncrypt(this.backToken+'---'+JSON.stringify(this.checkPosArr),this.secretKey):this.backToken+'---'+JSON.stringify(this.checkPosArr)
|
||||||
|
let data = {
|
||||||
|
captchaType:this.captchaType,
|
||||||
|
"pointJson":this.secretKey? aesEncrypt(JSON.stringify(this.checkPosArr),this.secretKey):JSON.stringify(this.checkPosArr),
|
||||||
|
"token":this.backToken
|
||||||
|
}
|
||||||
|
ajcaptchaCheck(data).then(result => {
|
||||||
|
let res = result.data
|
||||||
|
this.barAreaColor = '#4cae4c'
|
||||||
|
this.barAreaBorderColor = '#5cb85c'
|
||||||
|
this.text = '验证成功'
|
||||||
|
this.bindingClick = false
|
||||||
|
setTimeout(()=>{
|
||||||
|
if (this.mode=='pop') {
|
||||||
|
this.$parent.clickShow = false;
|
||||||
|
}
|
||||||
|
this.refresh();
|
||||||
|
},1500)
|
||||||
|
this.$parent.$emit('success', {captchaVerification})
|
||||||
|
}).catch(res=>{
|
||||||
|
this.$parent.$emit('error', this)
|
||||||
|
this.barAreaColor = '#d9534f'
|
||||||
|
this.barAreaBorderColor = '#d9534f'
|
||||||
|
this.text = '验证失败'
|
||||||
|
setTimeout(() => {
|
||||||
|
this.refresh();
|
||||||
|
}, 700);
|
||||||
|
})
|
||||||
|
}, 400);
|
||||||
|
}
|
||||||
|
if (this.num < this.checkNum) {
|
||||||
|
this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e));
|
||||||
|
}
|
||||||
|
}).exec();
|
||||||
|
},
|
||||||
|
//获取坐标
|
||||||
|
getMousePos: function (obj, e) {
|
||||||
|
let position = {
|
||||||
|
x:Math.ceil(e.detail.x)-this.imgLeft,
|
||||||
|
y:Math.ceil(e.detail.y)-this.imgTop,
|
||||||
|
}
|
||||||
|
return position
|
||||||
|
},
|
||||||
|
//创建坐标点
|
||||||
|
createPoint: function (pos) {
|
||||||
|
this.tempPoints.push(Object.assign({}, pos))
|
||||||
|
return ++this.num;
|
||||||
|
},
|
||||||
|
refresh: function () {
|
||||||
|
this.tempPoints.splice(0, this.tempPoints.length)
|
||||||
|
this.barAreaColor = '#000'
|
||||||
|
this.barAreaBorderColor = '#ddd'
|
||||||
|
this.bindingClick = true
|
||||||
|
|
||||||
|
this.fontPos.splice(0, this.fontPos.length)
|
||||||
|
this.checkPosArr.splice(0, this.checkPosArr.length)
|
||||||
|
this.num = 1
|
||||||
|
|
||||||
|
this.getPictrue();
|
||||||
|
|
||||||
|
// this.text = '验证失败'
|
||||||
|
this.showRefresh = true
|
||||||
|
},
|
||||||
|
// 请求背景图片和验证图片
|
||||||
|
getPictrue(){
|
||||||
|
let data = {
|
||||||
|
captchaType:this.captchaType,
|
||||||
|
clientUid: uni.getStorageSync('point'),
|
||||||
|
ts: Date.now(), // 现在的时间戳
|
||||||
|
}
|
||||||
|
getAjcaptcha(data).then((result) => {
|
||||||
|
let res = result.data
|
||||||
|
this.pointBackImgBase = res.originalImageBase64
|
||||||
|
this.backToken = res.token
|
||||||
|
this.secretKey = res.secretKey
|
||||||
|
this.poinTextList = res.wordList
|
||||||
|
this.text = '请依次点击【' + this.poinTextList.join(",") + '】'
|
||||||
|
}).catch(()=>{
|
||||||
|
this.pointBackImgBase = null
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//坐标转换函数
|
||||||
|
pointTransfrom(pointArr,imgSize){
|
||||||
|
var newPointArr = pointArr.map(p=>{
|
||||||
|
let x = Math.round(310 * p.x/parseInt(imgSize.width))
|
||||||
|
let y =Math.round(155 * p.y/parseInt(imgSize.height))
|
||||||
|
return {x,y}
|
||||||
|
})
|
||||||
|
// console.log(newPointArr,"newPointArr");
|
||||||
|
return newPointArr
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// type变化则全面刷新
|
||||||
|
type: {
|
||||||
|
immediate: true,
|
||||||
|
handler() {
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// console.log(this.defaultImg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.verifybox {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: 1px solid #e4e7eb;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, .3);
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.verifybox-top {
|
||||||
|
padding: 0 15px;
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #45494c;
|
||||||
|
border-bottom: 1px solid #e4e7eb;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verifybox-bottom {
|
||||||
|
/* padding: 15px; */
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verifybox-close {
|
||||||
|
position: absolute;
|
||||||
|
top: 13px;
|
||||||
|
right: 9px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1001;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
background: rgba(0, 0, 0, .3);
|
||||||
|
/* display: none; */
|
||||||
|
transition: all .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-tips {
|
||||||
|
position: absolute;
|
||||||
|
left: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
background-color: rgb(231, 27, 27, .5);
|
||||||
|
line-height: 30px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips-enter,
|
||||||
|
.tips-leave-to {
|
||||||
|
bottom: -30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips-enter-active,
|
||||||
|
.tips-leave-active {
|
||||||
|
transition: bottom .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------- */
|
||||||
|
/*常规验证码*/
|
||||||
|
.verify-code {
|
||||||
|
font-size: 20px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cerify-code-panel {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-code-area {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-input-area {
|
||||||
|
float: left;
|
||||||
|
width: 60%;
|
||||||
|
padding-right: 10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-change-area {
|
||||||
|
line-height: 30px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.varify-input-code {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-change-code {
|
||||||
|
color: #337AB7;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-btn {
|
||||||
|
width: 200px;
|
||||||
|
height: 30px;
|
||||||
|
background-color: #337AB7;
|
||||||
|
color: #FFFFFF;
|
||||||
|
border: none;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*滑动验证码*/
|
||||||
|
.verify-bar-area {
|
||||||
|
position: relative;
|
||||||
|
background: #FFFFFF;
|
||||||
|
text-align: center;
|
||||||
|
-webkit-box-sizing: content-box;
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-bar-area .verify-move-block {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
left: 0;
|
||||||
|
background: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-box-sizing: content-box;
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
box-shadow: 0 0 2px #888888;
|
||||||
|
-webkit-border-radius: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-bar-area .verify-move-block:hover {
|
||||||
|
background-color: #337ab7;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-bar-area .verify-left-bar {
|
||||||
|
position: absolute;
|
||||||
|
top: -1px;
|
||||||
|
left: -1px;
|
||||||
|
background: #f0fff0;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-box-sizing: content-box;
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-image-panel {
|
||||||
|
margin: 0;
|
||||||
|
-webkit-box-sizing: content-box;
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
border-radius: 3px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-image-panel .verify-refresh {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-image-panel .icon-refresh {
|
||||||
|
font-size: 20px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-image-panel .verify-gap {
|
||||||
|
background-color: #fff;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-bar-area .verify-move-block .verify-sub-block {
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 3;
|
||||||
|
/* border: 1px solid #fff; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-bar-area .verify-move-block .verify-icon {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-bar-area .verify-msg {
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*字体图标的css*/
|
||||||
|
/*@font-face {font-family: "iconfont";*/
|
||||||
|
/*src: url('../fonts/iconfont.eot?t=1508229193188'); !* IE9*!*/
|
||||||
|
/*src: url('../fonts/iconfont.eot?t=1508229193188#iefix') format('embedded-opentype'), !* IE6-IE8 *!*/
|
||||||
|
/*url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAaAAAsAAAAACUwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFZW7kiSY21hcAAAAYAAAAB3AAABuM+qBlRnbHlmAAAB+AAAAnQAAALYnrUwT2hlYWQAAARsAAAALwAAADYPNwajaGhlYQAABJwAAAAcAAAAJAfeA4dobXR4AAAEuAAAABMAAAAYF+kAAGxvY2EAAATMAAAADgAAAA4CvAGsbWF4cAAABNwAAAAfAAAAIAEVAF1uYW1lAAAE/AAAAUUAAAJtPlT+fXBvc3QAAAZEAAAAPAAAAE3oPPXPeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2Bk/sM4gYGVgYOpk+kMAwNDP4RmfM1gxMjBwMDEwMrMgBUEpLmmMDgwVDxbwtzwv4EhhrmBoQEozAiSAwAw1A0UeJzFkcENgCAMRX8RjCGO4gTe9eQcnhzAfXC2rqG/hYsT8MmD9gdS0gJIAAaykAjIBYHppCvuD8juR6zMJ67A89Zdn/f1aNPikUn8RvYo8G20CjKim6Rf6b9m34+WWd/vBr+oW8V6q3vF5qKlYrPRp4L0Ad5nGL8AeJxFUc9rE0EYnTezu8lMsrvtbrqb3TRt0rS7bdOmdI0JbWmCtiItIv5oi14qevCk9SQVLFiQgqAF8Q9QLKIHLx48FkHo3ZNnFUXwD5C2B6dO6sFhmI83w7z3fe8RnZCjb2yX5YlLhskkmScXCIFRxYBFiyjH9Rqtoqes9/g5i8WVuJyqDNTYLPwBI+cljXrkGynDhoU+nCgnjbhGY5yst+gMEq8IBIXwsjPU67CnEPm4b0su0h309Fd67da4XBhr55KSm17POk7gOE/Shq6nKdVsC7d9j+tcGPKVboc9u/0jtB/ZIA7PXTVLBef6o/paccjnwOYm3ELJetPuDrvV3gg91wlSXWY6H5qVwRzWf2TybrYYfSdqoXOwh/Qa8RWIjBTiSI3h614/vKSNRhONOrsnQi6Xf4nQFQDTmJE1NKbhI6crHEJO/+S5QPxhYJRRyvBFBP+5T9EPpEAIVzzRQIrjmJ6jY1WTo+NXTMchuBsKuS8PRZATSMl9oTA4uNLkeIA0V1UeqOoGQh7IAxGo+7T83fn3T+voqCNPPAUazUYUI7LgKSV1Jk2oUeghYGhZ+cKOe2FjVu5ZKEY2VkE13AK1+jI4r1KLbPlZfrKiPhOXKPRj7q9sj9XJ7LFHNmrKJS3VCdhXGSdKrtmoQaWeMjQVt0KD6sGPOx0oH2fgtzoNROxtNq8F3tzYM/n+TjKSX5qf2jx941276TIr9FjXxKr8eX/6bK4yuopwo9py1sw8F9kdw4AmurRpLUM3tYx5ZnKpfHPi8dzz19vJ6MjyxYUrpqeb1uLs3eGV6vr21pSqpeWkqonAN9oUyIiXpv8XvlN5e3icY2BkYGAA4n0vN4fG89t8ZeBmYQCBa9wPPRH0/wcsDMwmQC4HAxNIFABAfAqaAHicY2BkYGBu+N/AEMPCAAJAkpEBFbABAEcMAm94nGNhYGBgfsnAwMKAigESnwEBAAAAAAAAdgCkANoBCAFsAAB4nGNgZGBgYGMIZGBlAAEmIOYCQgaG/2A+AwARSAFzAHicZY9NTsMwEIVf+gekEqqoYIfkBWIBKP0Rq25YVGr3XXTfpk6bKokjx63UA3AejsAJOALcgDvwSCebNpbH37x5Y08A3OAHHo7fLfeRPVwyO3INF7gXrlN/EG6QX4SbaONVuEX9TdjHM6bCbXRheYPXuGL2hHdhDx18CNdwjU/hOvUv4Qb5W7iJO/wKt9Dx6sI+5l5XuI1HL/bHVi+cXqnlQcWhySKTOb+CmV7vkoWt0uqca1vEJlODoF9JU51pW91T7NdD5yIVWZOqCas6SYzKrdnq0AUb5/JRrxeJHoQm5Vhj/rbGAo5xBYUlDowxQhhkiMro6DtVZvSvsUPCXntWPc3ndFsU1P9zhQEC9M9cU7qy0nk6T4E9XxtSdXQrbsuelDSRXs1JErJCXta2VELqATZlV44RelzRiT8oZ0j/AAlabsgAAAB4nGNgYoAALgbsgI2RiZGZkYWRlZGNkZ2BsYI1OSM1OZs1OSe/OJW1KDM9o4S9KDWtKLU4g4EBAJ79CeQ=') format('woff'),*/
|
||||||
|
/*url('../fonts/iconfont.ttf?t=1508229193188') format('truetype'), !* chrome, firefox, opera, Safari, Android, iOS 4.2+*!*/
|
||||||
|
/*url('../fonts/iconfont.svg?t=1508229193188#iconfont') format('svg'); !* iOS 4.1- *!*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-family: "iconfont" !important;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-check:before {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
background-image: url("@/static/images/arrow-good.png");
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-close:before {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
background-image: url("@/static/images/arrow-close.png");
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-right:before {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-size: cover;
|
||||||
|
z-index: 9999;
|
||||||
|
background-image: url("@/static/images/arrow-right.png");
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-refresh:before {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
background-image: url("@/static/images/refresh.png");
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,648 @@
|
||||||
|
<template>
|
||||||
|
<view style="position: relative;">
|
||||||
|
<view v-if="type === '2'" class="verify-img-out" :style="{height: (parseInt(imgSize.height) + vSpace) + 'px'}">
|
||||||
|
<view class="verify-img-panel" :style="{width: imgSize.width,
|
||||||
|
height: imgSize.height,}">
|
||||||
|
|
||||||
|
<image :src="backImgBase?('data:image/png;base64,'+backImgBase):defaultImg" alt=""
|
||||||
|
style="width:100%;height:100%;display:block"></image>
|
||||||
|
<view class="verify-refresh" @click="refresh" v-show="showRefresh">
|
||||||
|
<text class="iconfont icon-refresh"></text>
|
||||||
|
</view>
|
||||||
|
<transition name="tips">
|
||||||
|
<text class="verify-tips" v-if="tipWords" :class="passFalg ? 'suc-bg':'err-bg'">{{tipWords}}</text>
|
||||||
|
</transition>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 公共部分 -->
|
||||||
|
<view class="verify-bar-area" :style="{width: imgSize.width,
|
||||||
|
height: '40px',
|
||||||
|
'line-height':'40px'}">
|
||||||
|
<text class="verify-msg" v-text="text"></text>
|
||||||
|
<view class="verify-left-bar"
|
||||||
|
:style="{width: leftBarWidth?leftBarWidth:'40px', height: '40px', 'border-color': leftBarBorderColor, transaction: transitionWidth}">
|
||||||
|
<text class="verify-msg" v-text="finishText"></text>
|
||||||
|
<view class="verify-move-block" @touchstart="start" @touchend="end" @touchmove="move"
|
||||||
|
:style="{width:'40px', height: '40px', 'background-color': moveBlockBackgroundColor, left: moveBlockLeft, transition: transitionLeft}">
|
||||||
|
<text :class="['verify-icon iconfont', iconClass]" :style="{color: iconColor}"></text>
|
||||||
|
<view v-if="type === '2'" class="verify-sub-block" :style="{'width':Math.floor(parseInt(imgSize.width)*47/310)+ 'px' ,
|
||||||
|
'height': imgSize.height,
|
||||||
|
'top':'-' + (parseInt(imgSize.height) + vSpace) + 'px',
|
||||||
|
}">
|
||||||
|
<image :src="'data:image/png;base64,'+blockBackImgBase" alt=""
|
||||||
|
style="width:100%;height:100%;display:block"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* VerifySlide
|
||||||
|
* @description 滑块
|
||||||
|
* */
|
||||||
|
import {
|
||||||
|
aesEncrypt
|
||||||
|
} from "./../utils/ase.js"
|
||||||
|
import {
|
||||||
|
getAjcaptcha,
|
||||||
|
ajcaptchaCheck
|
||||||
|
} from '@/api/api.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'VerifySlide',
|
||||||
|
props: {
|
||||||
|
captchaType: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: '1'
|
||||||
|
},
|
||||||
|
//弹出式pop,固定fixed
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'fixed'
|
||||||
|
},
|
||||||
|
vSpace: {
|
||||||
|
type: Number,
|
||||||
|
default: 5
|
||||||
|
},
|
||||||
|
explain: {
|
||||||
|
type: String,
|
||||||
|
default: '向右滑动完成验证'
|
||||||
|
},
|
||||||
|
imgSize: {
|
||||||
|
type: Object,
|
||||||
|
default () {
|
||||||
|
return {
|
||||||
|
width: '310px',
|
||||||
|
height: '155px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
blockSize: {
|
||||||
|
type: Object,
|
||||||
|
default () {
|
||||||
|
return {
|
||||||
|
width: '50px',
|
||||||
|
height: '50px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
barSize: {
|
||||||
|
type: Object,
|
||||||
|
default () {
|
||||||
|
return {
|
||||||
|
width: '100%',
|
||||||
|
height: '40px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultImg: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
secretKey: '', //后端返回的加密秘钥 字段
|
||||||
|
passFalg: false, //请求通过与否
|
||||||
|
backImgBase: '', //验证码背景图片
|
||||||
|
blockBackImgBase: '', //验证滑块的背景图片
|
||||||
|
backToken: "", //后端返回的唯一token值
|
||||||
|
startMoveTime: "", //移动开始的时间
|
||||||
|
endMovetime: '', //移动结束的时间
|
||||||
|
tipsBackColor: '', //提示词的北京颜色
|
||||||
|
tipWords: '',
|
||||||
|
text: '',
|
||||||
|
finishText: '',
|
||||||
|
setSize: {
|
||||||
|
imgHeight: 0,
|
||||||
|
imgWidth: 0,
|
||||||
|
barHeight: 0,
|
||||||
|
barWidth: 0
|
||||||
|
},
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
moveBlockLeft: undefined,
|
||||||
|
leftBarWidth: undefined,
|
||||||
|
// 移动中样式
|
||||||
|
moveBlockBackgroundColor: undefined,
|
||||||
|
leftBarBorderColor: '#ddd',
|
||||||
|
iconColor: undefined,
|
||||||
|
iconClass: 'icon-right',
|
||||||
|
status: false, //鼠标状态
|
||||||
|
isEnd: false, //是够验证完成
|
||||||
|
showRefresh: true,
|
||||||
|
transitionLeft: '',
|
||||||
|
transitionWidth: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
this.text = this.explain
|
||||||
|
this.getPictrue();
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$parent.$emit('ready', this)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
//鼠标按下
|
||||||
|
start: function(e) {
|
||||||
|
this.startMoveTime = new Date().getTime(); //开始滑动的时间
|
||||||
|
if (this.isEnd == false) {
|
||||||
|
this.text = ''
|
||||||
|
this.moveBlockBackgroundColor = '#337ab7'
|
||||||
|
this.leftBarBorderColor = '#337AB7'
|
||||||
|
this.iconColor = '#fff'
|
||||||
|
e.stopPropagation();
|
||||||
|
this.status = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//鼠标移动
|
||||||
|
move: function(e) {
|
||||||
|
var query = uni.createSelectorQuery().in(this);
|
||||||
|
this.barArea = query.select('.verify-bar-area')
|
||||||
|
var bar_area_left, barArea_offsetWidth;
|
||||||
|
this.barArea.boundingClientRect(data => {
|
||||||
|
bar_area_left = Math.ceil(data.left)
|
||||||
|
barArea_offsetWidth = Math.ceil(data.width)
|
||||||
|
|
||||||
|
if (this.status && this.isEnd == false) {
|
||||||
|
if (!e.touches) { //兼容移动端
|
||||||
|
var x = Math.ceil(e.clientX);
|
||||||
|
} else { //兼容PC端
|
||||||
|
var x = Math.ceil(e.touches[0].pageX);
|
||||||
|
}
|
||||||
|
// var bar_area_left = this.getLeft(this.barArea);
|
||||||
|
|
||||||
|
var move_block_left = x - bar_area_left //小方块相对于父元素的left值
|
||||||
|
if (this.type !== '1') { //图片滑动
|
||||||
|
if (move_block_left >= barArea_offsetWidth - parseInt(parseInt(this.blockSize
|
||||||
|
.width) / 2) - 2) {
|
||||||
|
move_block_left = barArea_offsetWidth - parseInt(parseInt(this.blockSize
|
||||||
|
.width) / 2) - 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (move_block_left <= 0) {
|
||||||
|
move_block_left = parseInt(parseInt(this.blockSize.width) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//拖动后小方块的left值
|
||||||
|
this.moveBlockLeft = (move_block_left - parseInt(parseInt(this.blockSize.width) / 2)) +
|
||||||
|
"px"
|
||||||
|
this.leftBarWidth = (move_block_left - parseInt(parseInt(this.blockSize.width) / 2)) +
|
||||||
|
"px"
|
||||||
|
|
||||||
|
}
|
||||||
|
}).exec();
|
||||||
|
},
|
||||||
|
|
||||||
|
//鼠标松开
|
||||||
|
end: function() {
|
||||||
|
this.endMovetime = new Date().getTime();
|
||||||
|
var _this = this;
|
||||||
|
// 判断是否重合
|
||||||
|
if (this.status && this.isEnd == false) {
|
||||||
|
if (this.type !== '1') { //图片滑动
|
||||||
|
var moveLeftDistance = parseInt((this.moveBlockLeft || '').replace('px', ''));
|
||||||
|
|
||||||
|
moveLeftDistance = moveLeftDistance * 310 / parseInt(this.imgSize.width)
|
||||||
|
|
||||||
|
var captchaVerification = this.secretKey ? aesEncrypt(this.backToken + '---' + JSON.stringify({
|
||||||
|
x: moveLeftDistance,
|
||||||
|
y: 5.0
|
||||||
|
}), this.secretKey) : this.backToken + '---' + JSON.stringify({
|
||||||
|
x: moveLeftDistance,
|
||||||
|
y: 5.0
|
||||||
|
})
|
||||||
|
let data = {
|
||||||
|
captchaType: this.captchaType,
|
||||||
|
"pointJson": this.secretKey ? aesEncrypt(JSON.stringify({
|
||||||
|
x: moveLeftDistance,
|
||||||
|
y: 5.0
|
||||||
|
}), this.secretKey) : JSON.stringify({
|
||||||
|
x: moveLeftDistance,
|
||||||
|
y: 5.0
|
||||||
|
}),
|
||||||
|
"token": this.backToken
|
||||||
|
}
|
||||||
|
ajcaptchaCheck(data).then((result) => {
|
||||||
|
let res = result.data
|
||||||
|
this.moveBlockBackgroundColor = '#5cb85c'
|
||||||
|
this.leftBarBorderColor = '#5cb85c'
|
||||||
|
this.iconColor = '#fff'
|
||||||
|
this.iconClass = 'icon-check'
|
||||||
|
this.showRefresh = true
|
||||||
|
this.isEnd = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.mode == 'pop') {
|
||||||
|
this.$parent.clickShow = false;
|
||||||
|
}
|
||||||
|
this.refresh();
|
||||||
|
}, 1500)
|
||||||
|
this.passFalg = true
|
||||||
|
this.tipWords =
|
||||||
|
`${((this.endMovetime-this.startMoveTime)/1000).toFixed(2)}s验证成功`
|
||||||
|
setTimeout(() => {
|
||||||
|
this.tipWords = ""
|
||||||
|
this.$emit('success', {
|
||||||
|
captchaVerification
|
||||||
|
})
|
||||||
|
}, 1000)
|
||||||
|
}).catch(res => {
|
||||||
|
this.moveBlockBackgroundColor = '#d9534f'
|
||||||
|
this.leftBarBorderColor = '#d9534f'
|
||||||
|
this.iconColor = '#fff'
|
||||||
|
this.iconClass = 'icon-close'
|
||||||
|
this.passFalg = false
|
||||||
|
setTimeout(() => {
|
||||||
|
this.refresh();
|
||||||
|
}, 1000);
|
||||||
|
this.$parent.$emit('error', this)
|
||||||
|
this.tipWords = "验证失败"
|
||||||
|
setTimeout(() => {
|
||||||
|
this.tipWords = ""
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.status = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
refresh: function() {
|
||||||
|
this.showRefresh = true
|
||||||
|
this.finishText = ''
|
||||||
|
this.transitionLeft = 'left .3s'
|
||||||
|
this.moveBlockLeft = 0
|
||||||
|
this.leftBarWidth = false
|
||||||
|
this.transitionWidth = 'width .3s'
|
||||||
|
this.leftBarBorderColor = '#ddd'
|
||||||
|
this.moveBlockBackgroundColor = '#fff'
|
||||||
|
this.iconColor = '#000'
|
||||||
|
this.iconClass = 'icon-right'
|
||||||
|
this.getPictrue()
|
||||||
|
this.isEnd = false
|
||||||
|
setTimeout(() => {
|
||||||
|
this.transitionWidth = ''
|
||||||
|
this.transitionLeft = ''
|
||||||
|
this.text = this.explain
|
||||||
|
}, 300)
|
||||||
|
},
|
||||||
|
|
||||||
|
//获取left值
|
||||||
|
getLeft: function(node) {
|
||||||
|
let leftValue = 0;
|
||||||
|
while (node) {
|
||||||
|
leftValue += node.offsetLeft;
|
||||||
|
node = node.offsetParent;
|
||||||
|
}
|
||||||
|
let finalvalue = leftValue;
|
||||||
|
return finalvalue;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 请求背景图片和验证图片
|
||||||
|
getPictrue() {
|
||||||
|
let data = {
|
||||||
|
captchaType: this.captchaType,
|
||||||
|
clientUid: uni.getStorageSync('slider'),
|
||||||
|
ts: Date.now(), // 现在的时间戳
|
||||||
|
}
|
||||||
|
getAjcaptcha(data).then((result) => {
|
||||||
|
let res = result.data
|
||||||
|
this.backImgBase = res.originalImageBase64
|
||||||
|
this.blockBackImgBase = res.jigsawImageBase64
|
||||||
|
this.backToken = res.token
|
||||||
|
this.secretKey = res.secretKey
|
||||||
|
}).catch(() => {
|
||||||
|
this.backImgBase = null
|
||||||
|
this.blockBackImgBase = null
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// type变化则全面刷新
|
||||||
|
type: {
|
||||||
|
immediate: true,
|
||||||
|
handler() {
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.verifybox {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: 1px solid #e4e7eb;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, .3);
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.verifybox-top {
|
||||||
|
padding: 0 15px;
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #45494c;
|
||||||
|
border-bottom: 1px solid #e4e7eb;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verifybox-bottom {
|
||||||
|
/* padding: 15px; */
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verifybox-close {
|
||||||
|
position: absolute;
|
||||||
|
top: 13px;
|
||||||
|
right: 9px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1001;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
background: rgba(0, 0, 0, .3);
|
||||||
|
/* display: none; */
|
||||||
|
transition: all .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-tips {
|
||||||
|
position: absolute;
|
||||||
|
left: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
background-color: rgb(231, 27, 27, .5);
|
||||||
|
line-height: 30px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.suc-bg {
|
||||||
|
background-color: rgba(92, 184, 92, .5);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#7f5CB85C, endcolorstr=#7f5CB85C);
|
||||||
|
}
|
||||||
|
|
||||||
|
.err-bg {
|
||||||
|
background-color: rgba(217, 83, 79, .5);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#7fD9534F, endcolorstr=#7fD9534F);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.tips-enter,
|
||||||
|
.tips-leave-to {
|
||||||
|
bottom: -30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips-enter-active,
|
||||||
|
.tips-leave-active {
|
||||||
|
transition: bottom .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------- */
|
||||||
|
/*常规验证码*/
|
||||||
|
.verify-code {
|
||||||
|
font-size: 20px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cerify-code-panel {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-code-area {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-input-area {
|
||||||
|
float: left;
|
||||||
|
width: 60%;
|
||||||
|
padding-right: 10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-change-area {
|
||||||
|
line-height: 30px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.varify-input-code {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-change-code {
|
||||||
|
color: #337AB7;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-btn {
|
||||||
|
width: 200px;
|
||||||
|
height: 30px;
|
||||||
|
background-color: #337AB7;
|
||||||
|
color: #FFFFFF;
|
||||||
|
border: none;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*滑动验证码*/
|
||||||
|
.verify-bar-area {
|
||||||
|
position: relative;
|
||||||
|
background: #FFFFFF;
|
||||||
|
text-align: center;
|
||||||
|
-webkit-box-sizing: content-box;
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-bar-area .verify-move-block {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
left: 0;
|
||||||
|
background: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-box-sizing: content-box;
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
box-shadow: 0 0 2px #888888;
|
||||||
|
-webkit-border-radius: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-bar-area .verify-move-block:hover {
|
||||||
|
background-color: #337ab7;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-bar-area .verify-left-bar {
|
||||||
|
position: absolute;
|
||||||
|
top: -1px;
|
||||||
|
left: -1px;
|
||||||
|
background: #f0fff0;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-box-sizing: content-box;
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-img-panel {
|
||||||
|
margin: 0;
|
||||||
|
-webkit-box-sizing: content-box;
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
border-radius: 3px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-img-panel .verify-refresh {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-img-panel .icon-refresh {
|
||||||
|
font-size: 20px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-img-panel .verify-gap {
|
||||||
|
background-color: #fff;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-bar-area .verify-move-block .verify-sub-block {
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 3;
|
||||||
|
/* border: 1px solid #fff; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-bar-area .verify-move-block .verify-icon {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify-bar-area .verify-msg {
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*字体图标的css*/
|
||||||
|
/*@font-face {font-family: "iconfont";*/
|
||||||
|
/*src: url('../fonts/iconfont.eot?t=1508229193188'); !* IE9*!*/
|
||||||
|
/*src: url('../fonts/iconfont.eot?t=1508229193188#iefix') format('embedded-opentype'), !* IE6-IE8 *!*/
|
||||||
|
/*url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAaAAAsAAAAACUwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFZW7kiSY21hcAAAAYAAAAB3AAABuM+qBlRnbHlmAAAB+AAAAnQAAALYnrUwT2hlYWQAAARsAAAALwAAADYPNwajaGhlYQAABJwAAAAcAAAAJAfeA4dobXR4AAAEuAAAABMAAAAYF+kAAGxvY2EAAATMAAAADgAAAA4CvAGsbWF4cAAABNwAAAAfAAAAIAEVAF1uYW1lAAAE/AAAAUUAAAJtPlT+fXBvc3QAAAZEAAAAPAAAAE3oPPXPeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2Bk/sM4gYGVgYOpk+kMAwNDP4RmfM1gxMjBwMDEwMrMgBUEpLmmMDgwVDxbwtzwv4EhhrmBoQEozAiSAwAw1A0UeJzFkcENgCAMRX8RjCGO4gTe9eQcnhzAfXC2rqG/hYsT8MmD9gdS0gJIAAaykAjIBYHppCvuD8juR6zMJ67A89Zdn/f1aNPikUn8RvYo8G20CjKim6Rf6b9m34+WWd/vBr+oW8V6q3vF5qKlYrPRp4L0Ad5nGL8AeJxFUc9rE0EYnTezu8lMsrvtbrqb3TRt0rS7bdOmdI0JbWmCtiItIv5oi14qevCk9SQVLFiQgqAF8Q9QLKIHLx48FkHo3ZNnFUXwD5C2B6dO6sFhmI83w7z3fe8RnZCjb2yX5YlLhskkmScXCIFRxYBFiyjH9Rqtoqes9/g5i8WVuJyqDNTYLPwBI+cljXrkGynDhoU+nCgnjbhGY5yst+gMEq8IBIXwsjPU67CnEPm4b0su0h309Fd67da4XBhr55KSm17POk7gOE/Shq6nKdVsC7d9j+tcGPKVboc9u/0jtB/ZIA7PXTVLBef6o/paccjnwOYm3ELJetPuDrvV3gg91wlSXWY6H5qVwRzWf2TybrYYfSdqoXOwh/Qa8RWIjBTiSI3h614/vKSNRhONOrsnQi6Xf4nQFQDTmJE1NKbhI6crHEJO/+S5QPxhYJRRyvBFBP+5T9EPpEAIVzzRQIrjmJ6jY1WTo+NXTMchuBsKuS8PRZATSMl9oTA4uNLkeIA0V1UeqOoGQh7IAxGo+7T83fn3T+voqCNPPAUazUYUI7LgKSV1Jk2oUeghYGhZ+cKOe2FjVu5ZKEY2VkE13AK1+jI4r1KLbPlZfrKiPhOXKPRj7q9sj9XJ7LFHNmrKJS3VCdhXGSdKrtmoQaWeMjQVt0KD6sGPOx0oH2fgtzoNROxtNq8F3tzYM/n+TjKSX5qf2jx941276TIr9FjXxKr8eX/6bK4yuopwo9py1sw8F9kdw4AmurRpLUM3tYx5ZnKpfHPi8dzz19vJ6MjyxYUrpqeb1uLs3eGV6vr21pSqpeWkqonAN9oUyIiXpv8XvlN5e3icY2BkYGAA4n0vN4fG89t8ZeBmYQCBa9wPPRH0/wcsDMwmQC4HAxNIFABAfAqaAHicY2BkYGBu+N/AEMPCAAJAkpEBFbABAEcMAm94nGNhYGBgfsnAwMKAigESnwEBAAAAAAAAdgCkANoBCAFsAAB4nGNgZGBgYGMIZGBlAAEmIOYCQgaG/2A+AwARSAFzAHicZY9NTsMwEIVf+gekEqqoYIfkBWIBKP0Rq25YVGr3XXTfpk6bKokjx63UA3AejsAJOALcgDvwSCebNpbH37x5Y08A3OAHHo7fLfeRPVwyO3INF7gXrlN/EG6QX4SbaONVuEX9TdjHM6bCbXRheYPXuGL2hHdhDx18CNdwjU/hOvUv4Qb5W7iJO/wKt9Dx6sI+5l5XuI1HL/bHVi+cXqnlQcWhySKTOb+CmV7vkoWt0uqca1vEJlODoF9JU51pW91T7NdD5yIVWZOqCas6SYzKrdnq0AUb5/JRrxeJHoQm5Vhj/rbGAo5xBYUlDowxQhhkiMro6DtVZvSvsUPCXntWPc3ndFsU1P9zhQEC9M9cU7qy0nk6T4E9XxtSdXQrbsuelDSRXs1JErJCXta2VELqATZlV44RelzRiT8oZ0j/AAlabsgAAAB4nGNgYoAALgbsgI2RiZGZkYWRlZGNkZ2BsYI1OSM1OZs1OSe/OJW1KDM9o4S9KDWtKLU4g4EBAJ79CeQ=') format('woff'),*/
|
||||||
|
/*url('../fonts/iconfont.ttf?t=1508229193188') format('truetype'), !* chrome, firefox, opera, Safari, Android, iOS 4.2+*!*/
|
||||||
|
/*url('../fonts/iconfont.svg?t=1508229193188#iconfont') format('svg'); !* iOS 4.1- *!*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-family: "iconfont" !important;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-check:before {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
background-image: url("@/static/images/arrow-good.png");
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-close:before {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
background-image: url("@/static/images/arrow-close.png");
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-right:before {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-size: cover;
|
||||||
|
z-index: 9999;
|
||||||
|
background-image: url("@/static/images/arrow-right.png");
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-refresh:before {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
position: absolute;
|
||||||
|
margin: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
background-image: url("@/static/images/refresh.png");
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,73 @@
|
||||||
|
// #ifdef H5
|
||||||
|
let VUE_APP_WS_URL = `ws://${location.hostname}?type=user`
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
let openPlantGrass = '-openPlantGrass-'
|
||||||
|
let httpApi
|
||||||
|
|
||||||
|
// 在打包之前请检查当前环境是否正确
|
||||||
|
const env = 'dev'; // 开发
|
||||||
|
// const env = 'prod'; // 生产
|
||||||
|
// const env = 'prew'; // 预上线
|
||||||
|
|
||||||
|
switch (env) {
|
||||||
|
case 'prod':
|
||||||
|
httpApi = 'https://shop.lihaink.cn' // 生产
|
||||||
|
httpApione = 'http://ceshi-zhibo.lihaink.cn'
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'prew':
|
||||||
|
httpApi = 'https://test.shop.lihaink.cn' //预发布环境
|
||||||
|
httpApione = 'http://ceshi-zhibo.lihaink.cn'
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
httpApi = "https://crmeb-test.shop.lihaink.cn" // 测试
|
||||||
|
httpApione = 'https://ceshi-zhibo.lihaink.cn'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 聊天接口修改此字符 小程序聊天要求wss 例如:wss://mer.crmeb.net
|
||||||
|
// let wsApi = 'ws://192.168.3.20:8324'
|
||||||
|
let wsApi = 'wss://ceshi-zhibo.lihaink.cn/chat_room'
|
||||||
|
// console.log(httpApione,'11111111111')
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
// 请求域名 格式: https://您的域名
|
||||||
|
// #ifdef MP || APP-PLUS
|
||||||
|
// HTTP_REQUEST_URL: httpApi,
|
||||||
|
HTTP_REQUEST_URL: httpApi,
|
||||||
|
HTTP_REQUEST_URL_ONE: httpApione,
|
||||||
|
|
||||||
|
VUE_APP_WS_URL: wsApi,
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
HTTP_REQUEST_URL: httpApi,
|
||||||
|
HTTP_REQUEST_URL_ONE: httpApione,
|
||||||
|
//H5接口是浏览器地址
|
||||||
|
// 聊天长连接地址
|
||||||
|
VUE_APP_WS_URL: VUE_APP_WS_URL,
|
||||||
|
// #endif
|
||||||
|
openPlantGrass: openPlantGrass,
|
||||||
|
HEADER: {
|
||||||
|
'content-type': 'application/json',
|
||||||
|
|
||||||
|
//#ifdef H5
|
||||||
|
// 'Form-type': navigator.userAgent.toLowerCase().indexOf("micromessenger") !== -1 ? 'wechat' : 'h5',
|
||||||
|
//#endif
|
||||||
|
//#ifdef MP
|
||||||
|
'Form-type': 'routine',
|
||||||
|
//#endif
|
||||||
|
//#ifdef APP-PLUS
|
||||||
|
'Form-type': 'app',
|
||||||
|
//#endif
|
||||||
|
},
|
||||||
|
// 回话密钥名称 请勿修改此配置
|
||||||
|
TOKENNAME: 'X-Token',
|
||||||
|
// 缓存时间 0 永久
|
||||||
|
EXPIRE: 0,
|
||||||
|
};
|
|
@ -0,0 +1,43 @@
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
module.exports = {
|
||||||
|
//token
|
||||||
|
LOGIN_STATUS: 'LOGIN_STATUS_TOKEN',
|
||||||
|
// uid
|
||||||
|
UID:'UID',
|
||||||
|
//<2F>û<EFBFBD>
|
||||||
|
USER_INFO: 'USER_INFO',
|
||||||
|
//token<65><6E><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
|
||||||
|
EXPIRES_TIME: 'EXPIRES_TIME',
|
||||||
|
//<2F>Ƿ<EFBFBD><C7B7><EFBFBD>Ȩ
|
||||||
|
WX_AUTH: 'WX_AUTH',
|
||||||
|
//<2F><><EFBFBD>ں<EFBFBD><DABA><EFBFBD>Ȩcode
|
||||||
|
STATE_KEY: 'wx_authorize_state',
|
||||||
|
//<2F>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
LOGINTYPE: 'loginType',
|
||||||
|
//<2F><><EFBFBD>ں<EFBFBD><DABA><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
|
||||||
|
BACK_URL: 'login_back_url',
|
||||||
|
// С<><D0A1><EFBFBD><EFBFBD>code
|
||||||
|
STATE_R_KEY: 'roution_authorize_state',
|
||||||
|
//<2F><>ȨlogoС<6F><D0A1><EFBFBD><EFBFBD>
|
||||||
|
LOGO_URL: 'LOGO_URL',
|
||||||
|
//模板缓存
|
||||||
|
SUBSCRIBE_MESSAGE: 'SUBSCRIBE_MESSAGE',
|
||||||
|
|
||||||
|
TIPS_KEY: 'TIPS_KEY',
|
||||||
|
|
||||||
|
SPREAD: 'spread',
|
||||||
|
//缓存经度
|
||||||
|
CACHE_LONGITUDE: 'LONGITUDE',
|
||||||
|
//缓存纬度
|
||||||
|
CACHE_LATITUDE: 'LATITUDE',
|
||||||
|
//缓存地址信息
|
||||||
|
ADRESS_LOCATION:'ADRESS_LOCATION'
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
disabled: false,
|
||||||
|
text: "获取验证码"
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
sendCode() {
|
||||||
|
if (this.disabled) return;
|
||||||
|
this.disabled = true;
|
||||||
|
let n = 60;
|
||||||
|
this.text = "剩余 " + n + "s";
|
||||||
|
const run = setInterval(() => {
|
||||||
|
n = n - 1;
|
||||||
|
if (n < 0) {
|
||||||
|
clearInterval(run);
|
||||||
|
}
|
||||||
|
this.text = "剩余 " + n + "s";
|
||||||
|
if (this.text < "剩余 " + 0 + "s") {
|
||||||
|
this.disabled = false;
|
||||||
|
this.text = "重新获取";
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,25 @@
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | Author: CRMEB Team <admin@crmeb.com>
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
import { history } from '@/api/public.js'
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getHistory() {
|
||||||
|
// console.log(this.$util.getNowUrl(),'page')
|
||||||
|
history({
|
||||||
|
page:this.$util.getNowUrl()
|
||||||
|
}).then(res=>{})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,84 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<live-pusher id='livePusher' ref="livePusher" class="livePusher" :url="url" mode="SD" :muted="true"
|
||||||
|
:enable-camera="true" :auto-focus="true" :beauty="1" whiteness="2" aspect="9:16" @statechange="statechange"
|
||||||
|
@netstatus="netstatus" @error="error"
|
||||||
|
:style="'width: '+ windowWidth +'px; height: '+ windowHeight +'px;z-inde:-1;'">
|
||||||
|
</live-pusher>
|
||||||
|
<sd-float-page :room='room' @switchCamera='switchCamera' :msgList='msgList'
|
||||||
|
:style="'width: '+ windowWidth +'px; height: '+ windowHeight +'px;position: absolute;z-index:999999;' "></sd-float-page>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import sdFloatPage from '@/components/sd-live-page/livepage.nvue';
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
sdFloatPage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
url: '',
|
||||||
|
windowHeight: 0,
|
||||||
|
windowWidth: 0,
|
||||||
|
room: {},
|
||||||
|
pusherContext: null,
|
||||||
|
userName:this.userName,
|
||||||
|
inputModel:'',
|
||||||
|
msgList:[]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onReady() {
|
||||||
|
// this.context = uni.createLivePusherContext('livePusher', this);
|
||||||
|
// this.context.switchCamera() // 摄像头切换(切换为后置)
|
||||||
|
// this.context.startPreview() // 摄像头预览 (不加会黑屏)
|
||||||
|
this.windowWidth = uni.getSystemInfoSync().screenWidth //获取屏幕宽度
|
||||||
|
this.windowHeight = uni.getSystemInfoSync().screenHeight; //获取屏幕高度
|
||||||
|
// 监听窗口大小的变化
|
||||||
|
uni.onWindowResize((res) => {
|
||||||
|
this.windowHeight = res.size.windowHeight;
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
onLoad(options) {
|
||||||
|
|
||||||
|
this.room = JSON.parse(decodeURIComponent(options.data));
|
||||||
|
this.url = this.room.push_url
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.pusherContext = uni.createLivePusherContext('livePusher', this);
|
||||||
|
// console.log('创建 pusherContext:', this.pusherContext);
|
||||||
|
|
||||||
|
//开始推流
|
||||||
|
this.pusherContext.start(function(e) {
|
||||||
|
console.log('推流情况')
|
||||||
|
// console.log(e)
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
statechange(e) {
|
||||||
|
// console.log("statechange:" + JSON.stringify(e));
|
||||||
|
},
|
||||||
|
//切换摄像头
|
||||||
|
switchCamera: function() {
|
||||||
|
this.pusherContext.switchCamera({
|
||||||
|
success: (a) => {
|
||||||
|
console.log("livePusher.switchCamera:" + JSON.stringify(a));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
netstatus(e) {
|
||||||
|
// console.log("netstatus:" + JSON.stringify(e));
|
||||||
|
},
|
||||||
|
error(e) {
|
||||||
|
// console.log("error:" + JSON.stringify(e));
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,104 @@
|
||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<view :style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;z-inde:-1;'">
|
||||||
|
<!--
|
||||||
|
1.这里的 swiper 不是用来控制视频滑动的,而是用来控制左右滑动的,如果不需要的可以改成 view
|
||||||
|
2.为了 视频无限加载,已经把 21 行的 appear 去掉了,加上了 loadmore 方法(第10行)
|
||||||
|
3.由于方法比较多,可以采取下面的方式查看代码:
|
||||||
|
(1)Mac:按住 option 键,然后点击方法名,即可跳转到方法
|
||||||
|
(2)windows:按住 Alt 键,然后鼠标左击,即可跳转到方法
|
||||||
|
-->
|
||||||
|
<view class="root">
|
||||||
|
<video ref="videoPlayer" :src="currentSrc" controls @ended="playNext" :object-fit="object_fit" :style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;z-inde:-1;'"></video>
|
||||||
|
</view>
|
||||||
|
<sd-float-page :room='room' :msgList='msgList'
|
||||||
|
:style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;position: absolute;' "></sd-float-page>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import sdFloatPage from '@/components/sd-live-page/histroy.nvue';
|
||||||
|
|
||||||
|
import {
|
||||||
|
playbackDetail
|
||||||
|
} from '@/api/api.js'
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
sdFloatPage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
rtmpSources: [],
|
||||||
|
currentIndex: 0,
|
||||||
|
room: {},
|
||||||
|
wHeight: 0, //获取的屏幕高度🌟💗
|
||||||
|
boxStyle: { //视频,图片封面样式🌟💗
|
||||||
|
'height': 0,
|
||||||
|
'width': 0,
|
||||||
|
},
|
||||||
|
object_fit: 'cover', //视频样式默认包含🌟💗
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
currentSrc() {
|
||||||
|
return this.rtmpSources[this.currentIndex];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad(options) {
|
||||||
|
this.room = JSON.parse(decodeURIComponent(options.data));
|
||||||
|
this.platform = uni.getSystemInfoSync().platform
|
||||||
|
this.windowWidth = uni.getSystemInfoSync().screenWidth //获取屏幕宽度
|
||||||
|
this.boxStyle.width = this.windowWidth + 'px' //给宽度加px
|
||||||
|
this.wHeight = uni.getSystemInfoSync().screenHeight; //获取屏幕高度
|
||||||
|
this.boxStyle.height = this.wHeight; //改变视频高度
|
||||||
|
this.get()
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
// 初始化时播放第一个源
|
||||||
|
this.playCurrent();
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
playCurrent() {
|
||||||
|
this.$refs.videoPlayer.load();
|
||||||
|
this.$refs.videoPlayer.play();
|
||||||
|
},
|
||||||
|
playNext() {
|
||||||
|
this.currentIndex++;
|
||||||
|
if (this.currentIndex >= this.rtmpSources.length) {
|
||||||
|
this.currentIndex = 0; // 回到第一个源
|
||||||
|
}
|
||||||
|
this.playCurrent();
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
get() {
|
||||||
|
let that = this
|
||||||
|
console.log(this.room)
|
||||||
|
playbackDetail({
|
||||||
|
app_name: 'shop',
|
||||||
|
live_stream_id: this.room.live_stream_id
|
||||||
|
}).then((res) => {
|
||||||
|
// console.log(res.data, '1111')
|
||||||
|
|
||||||
|
this.rtmpSources = res.data.playback_url;
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,358 @@
|
||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<view :style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;z-inde:-1;'">
|
||||||
|
<!--
|
||||||
|
1.这里的 swiper 不是用来控制视频滑动的,而是用来控制左右滑动的,如果不需要的可以改成 view
|
||||||
|
2.为了 视频无限加载,已经把 21 行的 appear 去掉了,加上了 loadmore 方法(第10行)
|
||||||
|
3.由于方法比较多,可以采取下面的方式查看代码:
|
||||||
|
(1)Mac:按住 option 键,然后点击方法名,即可跳转到方法
|
||||||
|
(2)windows:按住 Alt 键,然后鼠标左击,即可跳转到方法
|
||||||
|
-->
|
||||||
|
<list @loadmore="getData" @scroll="scrolls" :loadmoreoffset="wHeight*1" :show-scrollbar="false"
|
||||||
|
ref="listBox" :pagingEnabled="true" :scrollable="true">
|
||||||
|
<!-- 循环数据 -->
|
||||||
|
<cell v-for="(item,i) in dataList" :key="i">
|
||||||
|
<!-- 用div把视频模组套起来 -->
|
||||||
|
<div :style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;'">
|
||||||
|
<!-- <view v-if="Math.abs(k-i)<=1"> -->
|
||||||
|
<view v-if="Math.abs(k-i)<=1">
|
||||||
|
<view class="root">
|
||||||
|
<video :ref="'item'+i" :id="item.id" :loop="true" :autoplay="i == k"
|
||||||
|
:src="item.pull_url" :muted="item.isplay" :enable-progress-gesture="false"
|
||||||
|
:page-gesture="false" :controls="false" :show-loading="true" :is-live='true'
|
||||||
|
@error='vedioerr' :show-fullscreen-btn="false" :show-center-play-btn="false"
|
||||||
|
:style="boxStyle" :object-fit="object_fit" @timeupdate="timeupdate($event,i)">
|
||||||
|
|
||||||
|
</video>
|
||||||
|
<!-- {{item}} {{i}} -->
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<sd-float-page :room='room' :msgList='msgList'
|
||||||
|
:style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;position: absolute;' "></sd-float-page>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</cell>
|
||||||
|
</list>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import list from '@/uni_modules/uview-ui/libs/config/props/list';
|
||||||
|
import sdFloatPage from '@/components/sd-live-page/livepage.nvue';
|
||||||
|
import {
|
||||||
|
VUE_APP_WS_URL
|
||||||
|
} from '@/config/app';
|
||||||
|
|
||||||
|
import json from '../../static/js/json';
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
sdFloatPage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
imgHost: '',
|
||||||
|
//下面打🌟号的是必须要的基础字段
|
||||||
|
//下面打💗号的是拥有滑动条的必须字段
|
||||||
|
dataList: [], //用于数据循环的列表🌟💗
|
||||||
|
wHeight: 0, //获取的屏幕高度🌟💗
|
||||||
|
boxStyle: { //视频,图片封面样式🌟💗
|
||||||
|
'height': 0,
|
||||||
|
'width': 0,
|
||||||
|
},
|
||||||
|
k: 0, //默认为0🌟💗
|
||||||
|
max: 2,
|
||||||
|
playIngIds: [], //正在播放的视频id列队,列队用于处理滑动过快导致的跳频问题🌟💗
|
||||||
|
ready: false, //可忽略
|
||||||
|
isDragging: false, //false代表停止滑动🌟💗
|
||||||
|
refreshing: true, //用于下拉刷新🌟💗
|
||||||
|
windowWidth: 0, //获取屏幕宽度🌟💗
|
||||||
|
windowHeight: 0,
|
||||||
|
dex: [0, 0], //用于判断是上滑还是下滑,第一个存旧值,第二个存新值【目前在1.0.7已经废弃】
|
||||||
|
currents: 0, //用于左右滑动,0代表视频界面,1代表右滑界面🌟💗
|
||||||
|
platform: '', //用于获取操作系统:ios、android🌟💗
|
||||||
|
playIng: false, //用于视频初始化时是否播放,默认不播放🌟💗
|
||||||
|
videoTime: '', //视频总时长,这个主要用来截取时间数值💗
|
||||||
|
videoTimes: '', //视频时长,用这个来获取时间值,例如:00:30这个时间值💗
|
||||||
|
changeTime: '', //显示滑动进度条时变化的时间💗
|
||||||
|
isShowimage: false, //是否显示封面【1.0.4已废弃,但是意思需要记住】
|
||||||
|
currenttimes: 0, //当前时间💗
|
||||||
|
isShowProgressBarTime: false, //是否拖动进度条,如果拖动(true)则显示进度条时间,否则不显示(false)【1.0.4已废弃,但是意思需要记住】
|
||||||
|
ProgressBarOpacity: 0.7, //进度条不拖动时的默认值,就是透明的💗
|
||||||
|
dotWidth: 0, //播放的小圆点,默认没有💗
|
||||||
|
deleteHeight: 0, //测试高度🌟💗
|
||||||
|
percent: 0, //百分小数💗
|
||||||
|
currentPosition: 0, //滑块当前位置💗//2.0已弃用,现已用于后端参数
|
||||||
|
currentPositions: 0, //滑块当前位置的副本💗//2.0已弃用,现已用于后端参数
|
||||||
|
newTime: 0, //跟手滑动后的最新时间💗
|
||||||
|
timeNumber: 0, //🌟💗
|
||||||
|
ProgressBarBottom: 20, //进度条离底部的距离💗
|
||||||
|
object_fit: 'cover', //视频样式默认包含🌟💗
|
||||||
|
mode: 'aspectFit', //图片封面样式🌟💗
|
||||||
|
timeout: "", //🌟用来阻止 setTimeout()方法
|
||||||
|
voice: "", //🌟用来阻止 setTimeout()方法
|
||||||
|
oldVideo: "",
|
||||||
|
isAutoplay: false, //是否开启自动播放(默认不开启)
|
||||||
|
autoplayText: "开启自动播放",
|
||||||
|
msgList: [],
|
||||||
|
room: {},
|
||||||
|
socketTask: null,
|
||||||
|
userName: '',
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
async k(new_k, old_k) { //监听 k 值的变化,可以控制视频的播放与暂停
|
||||||
|
const max = new_k + 2;
|
||||||
|
if (this.max < max) {
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
// if (this.oldCurrent != this.currentNav) {
|
||||||
|
// this.oldCurrent = this.currentNav
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
this.dataList[old_k].playIng = false //如果视频暂停,就加载封面
|
||||||
|
this.dataList[old_k].isplay = true
|
||||||
|
this.dataList[old_k].state = 'pause'
|
||||||
|
// console.log('预留第' + (old_k) + '个视频:' + this.dataList[old_k].community_id)
|
||||||
|
// 2.0版本已经去掉了下面这一句,视频不用暂停,只需要把声音禁止就行
|
||||||
|
uni.createVideoContext(this.dataList[old_k].community_id, this)
|
||||||
|
.pause() //如果视频暂停,那么旧视频停止,这里的this.dataList[old_k].id + '' + old_k,后面加 old_k 是为了每一个视频的 id 值不同,这样就可以大程度的避免串音问题
|
||||||
|
// console.log('已经暂停 --> 第' + (old_k) + '个视频~') //提示
|
||||||
|
this.dataList[new_k].state = 'play'
|
||||||
|
this.dataList[new_k].isplay = false
|
||||||
|
this.dataList[new_k].playIng = true
|
||||||
|
uni.createVideoContext(this.dataList[new_k].community_id, this).play()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onShow() {
|
||||||
|
uni.hideLoading();
|
||||||
|
// console.log('回到前台' + this.dataList.length);
|
||||||
|
if (this.dataList.length !== 0) {
|
||||||
|
this.dataList[this.k].state = 'play';
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.createVideoContext(this.dataList[this.k].id, this).play()
|
||||||
|
}, 250)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onHide() {
|
||||||
|
this.dataList[this.k].state = 'pause'; //界面隐藏也要停止播放视频
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.createVideoContext(this.dataList[this.k].community_id, this).pause(); //暂停以后继续播放
|
||||||
|
}, 250)
|
||||||
|
// console.log('到后台');
|
||||||
|
},
|
||||||
|
onLoad(options) {
|
||||||
|
this.platform = uni.getSystemInfoSync().platform
|
||||||
|
this.windowWidth = uni.getSystemInfoSync().screenWidth //获取屏幕宽度
|
||||||
|
this.boxStyle.width = this.windowWidth + 'px' //给宽度加px
|
||||||
|
this.wHeight = uni.getSystemInfoSync().screenHeight; //获取屏幕高度
|
||||||
|
this.boxStyle.height = this.wHeight; //改变视频高度
|
||||||
|
console.log(this.boxStyle.height)
|
||||||
|
this.room = JSON.parse(decodeURIComponent(options.data));
|
||||||
|
|
||||||
|
this.get()
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
Ready() {},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
autoPlay() {
|
||||||
|
this.isAutoplay = !this.isAutoplay;
|
||||||
|
if (!this.isAutoplay) {
|
||||||
|
this.autoplayText = "开启自动播放"
|
||||||
|
uni.showToast({
|
||||||
|
title: "关闭自动播放",
|
||||||
|
icon: 'none',
|
||||||
|
duration: 3000
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.autoplayText = "关闭自动播放"
|
||||||
|
uni.showToast({
|
||||||
|
title: "开启自动播放",
|
||||||
|
icon: 'none',
|
||||||
|
duration: 3000
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getData() {
|
||||||
|
// 这里就是数据加载完以后再向后端发送数据的地方,
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
vedioerr(e) {
|
||||||
|
let timer = null
|
||||||
|
if (e.tye = 'error') {
|
||||||
|
timer = setInterval((res) => {
|
||||||
|
uni.createVideoContext('myVideo', this).play()
|
||||||
|
console.log('重新连接', '1111111111')
|
||||||
|
}, 600000)
|
||||||
|
} else {
|
||||||
|
timer = null
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
touchstart(event) {
|
||||||
|
this.dataList[this.k].isShowimage = true //刚触摸的时候就要显示预览视频图片了
|
||||||
|
this.dataList[this.k].isShowProgressBarTime = true //显示时间线
|
||||||
|
this.ProgressBarOpacity = 1 //让滑块显示起来更明显一点
|
||||||
|
this.dotWidth = 10 //让点显示起来更明显一点
|
||||||
|
},
|
||||||
|
touchend() { //当手松开后,跳到最新时间
|
||||||
|
uni.createVideoContext(this.dataList[this.k].community_id, this).seek(this.newTime)
|
||||||
|
if (this.dataList[this.k].state == 'pause') {
|
||||||
|
this.dataList[this.k].state = 'play'
|
||||||
|
uni.createVideoContext(this.dataList[this.k].community_id, this).play()
|
||||||
|
}
|
||||||
|
this.dataList[this.k].isShowProgressBarTime = false //触摸结束后,隐藏时间线
|
||||||
|
this.dataList[this.k].isShowimage = false //触摸结束后,隐藏时间预览
|
||||||
|
this.ProgressBarOpacity = 0.5 //隐藏起来进度条,不那么明显了
|
||||||
|
this.dotWidth = 0 //隐藏起来进度条,不那么明显了
|
||||||
|
},
|
||||||
|
touchmove(event) { //当手移动滑块时,计算位置、百分小数、新的时间
|
||||||
|
var msg = []
|
||||||
|
if (this.videoTime !== '') {
|
||||||
|
msg = this.videoTime.split(':')
|
||||||
|
}
|
||||||
|
var timeNumber = Number(msg[0]) * 60 + Number(msg[1])
|
||||||
|
this.currentPositions = event.changedTouches[0].screenX
|
||||||
|
this.percent = this.currentPositions / this.windowWidth
|
||||||
|
this.newTime = this.percent * timeNumber
|
||||||
|
this.currenttimes = parseInt(this.newTime)
|
||||||
|
let theTime = this.newTime
|
||||||
|
let middle = 0; // 分
|
||||||
|
if (theTime > 60) {
|
||||||
|
middle = parseInt(theTime / 60);
|
||||||
|
theTime = parseInt(theTime % 60);
|
||||||
|
}
|
||||||
|
this.changeTime =
|
||||||
|
`${Math.round(middle)>9?Math.round(middle):'0'+Math.round(middle)}:${Math.round(theTime)>9?Math.round(theTime):'0'+Math.round(theTime)}`
|
||||||
|
},
|
||||||
|
timeupdate(event, index) { //计算滑块当前位置,计算当前百分小数
|
||||||
|
if (index == this.k) {
|
||||||
|
var currenttime = event.detail.currentTime
|
||||||
|
this.timeNumber = Math.round(event.detail.duration)
|
||||||
|
this.getTime()
|
||||||
|
this.percent = currenttime / this.timeNumber
|
||||||
|
this.currentPosition = this.windowWidth * this.percent
|
||||||
|
let theTime = currenttime
|
||||||
|
let middle = 0; // 分
|
||||||
|
if (theTime > 60) {
|
||||||
|
middle = parseInt(theTime / 60);
|
||||||
|
theTime = parseInt(theTime % 60);
|
||||||
|
}
|
||||||
|
this.changeTime =
|
||||||
|
`${Math.round(middle)>9?Math.round(middle):'0'+Math.round(middle)}:${Math.round(theTime)>9?Math.round(theTime):'0'+Math.round(theTime)}`
|
||||||
|
//自动切换视频
|
||||||
|
if (this.isAutoplay) { //true,代表自动播放
|
||||||
|
if (Math.round(currenttime) == this.timeNumber - 1) {
|
||||||
|
const dom = uni.requireNativePlugin('dom')
|
||||||
|
let doms = 'item' + (this.k + 1)
|
||||||
|
setTimeout(() => {
|
||||||
|
let el = this.$refs[doms][0]
|
||||||
|
dom.scrollToElement(el, {
|
||||||
|
offset: 0,
|
||||||
|
animated: true
|
||||||
|
})
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getTime() { //得到时间函数
|
||||||
|
this.videoTime = this.formatSeconds(this.timeNumber);
|
||||||
|
var msg = []
|
||||||
|
if (this.videoTime !== '') {
|
||||||
|
msg = this.videoTime.split(':')
|
||||||
|
}
|
||||||
|
this.videoTimes = `${msg[0]>9?msg[0]:'0'+msg[0]}:${msg[1]>9?msg[1]:'0'+msg[1]}`;
|
||||||
|
},
|
||||||
|
formatSeconds(value) { //获取时间函数
|
||||||
|
let theTime = parseInt(value); // 秒
|
||||||
|
let middle = 0; // 分
|
||||||
|
if (theTime > 60) {
|
||||||
|
middle = parseInt(theTime / 60);
|
||||||
|
theTime = parseInt(theTime % 60);
|
||||||
|
}
|
||||||
|
return `${middle>9?middle:middle}:${theTime>9?theTime:theTime}`;
|
||||||
|
},
|
||||||
|
moreVideo(index) {
|
||||||
|
|
||||||
|
},
|
||||||
|
toVideo(index) {
|
||||||
|
|
||||||
|
},
|
||||||
|
scrolls(event) {
|
||||||
|
|
||||||
|
this.showManage = false;
|
||||||
|
this.isDragging = event.isDragging;
|
||||||
|
if (!event.isDragging) { //isDragging:判断用户是不是在滑动,滑动:true,停止滑动:false。我们要用户停止滑动时才给 k 赋值,这样就可以避免很多麻烦
|
||||||
|
var i = Math.round(Math.abs(event.contentOffset.y) / (this.wHeight - this.deleteHeight +
|
||||||
|
1)) //先用绝对值取出滑动的距离,然后除以屏幕高度,取一个整,就知道你现在滑动到哪一个视频了
|
||||||
|
if (i !== this.k) { //这里加判断是因为这个方法会执行很多次,会造成重复请求,所以这里写一个限制
|
||||||
|
if (uni.getSystemInfoSync().platform == 'ios') {
|
||||||
|
this.k = i //判断了用户没有滑动,确认了用户的确是在看这个视频,然后就赋值啦
|
||||||
|
this.dataList[this.k].state = 'play'
|
||||||
|
// console.log('正在播放 --> 第' + (this.k + 1) + '个视频~')
|
||||||
|
} else {
|
||||||
|
clearTimeout(this.timers);
|
||||||
|
this.timers = setTimeout(() => {
|
||||||
|
this.k = i //判断了用户没有滑动,确认了用户的确是在看这个视频,然后就赋值啦
|
||||||
|
this.dataList[this.k].state = 'play'
|
||||||
|
// console.log('正在播放 --> 第' + (this.k + 1) + '个视频~')
|
||||||
|
}, 80)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get() {
|
||||||
|
let that = this
|
||||||
|
var msg = [this.room];
|
||||||
|
console.log(this.room)
|
||||||
|
for (let i = 0; i < msg.length; i++) {
|
||||||
|
msg[i]['isMore'] = false
|
||||||
|
msg[i]['playIng'] = false
|
||||||
|
msg[i]['state'] = false
|
||||||
|
msg[i]['isplay'] = false
|
||||||
|
msg[i]['loading'] = false
|
||||||
|
msg[i]['id'] = msg[i]['live_stream_id']
|
||||||
|
}
|
||||||
|
this.dataList = msg;
|
||||||
|
|
||||||
|
if (this.dataList.length !== 0) {
|
||||||
|
|
||||||
|
this.dataList[this.k].state = 'play';
|
||||||
|
uni.createVideoContext(this.dataList[this.k].id, this).play()
|
||||||
|
this.page = that.page + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(this.dataList, this.dataList[this.k].id, 222222)
|
||||||
|
},
|
||||||
|
onpullingdown() {
|
||||||
|
this.refreshing = true
|
||||||
|
},
|
||||||
|
onrefresh() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.refreshing = false
|
||||||
|
}, 1000)
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
onReachBottom() {
|
||||||
|
uni.$emit('onReachBottom');
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,534 @@
|
||||||
|
<template name="create-float-page">
|
||||||
|
<view>
|
||||||
|
<view class="do-box">
|
||||||
|
<view class="do-box-top">
|
||||||
|
<text>请输入直播主题:</text>
|
||||||
|
<view class="cover-input">
|
||||||
|
<input type="text" v-model="livename" placeholder="请输入内容,吸引更多观众"
|
||||||
|
placeholder-class="cover-inputplaceholder" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="do-box-top" @click="chooseImage">
|
||||||
|
<text>请上传直播封面:</text>
|
||||||
|
<view class="cover-box">
|
||||||
|
<image :src="imageSrc" mode="aspectFill" v-if='imageSrc'></image>
|
||||||
|
<view class="cover-box-img" v-else>
|
||||||
|
|
||||||
|
<image src="@/static/img/xj.png" mode="aspectFit"></image>
|
||||||
|
</view>
|
||||||
|
<view class="cover-text web-font"v-if='imageSrc'>更新封面</view>
|
||||||
|
<view class="cover-text web-font"v-else style="color: #B3B3B3;">上传图片</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="do-box-check">
|
||||||
|
<view class="do-box-check-top">
|
||||||
|
<view class="do-box-check-left">
|
||||||
|
<view class="check-top-imga">
|
||||||
|
<image src="@/static/img/c2.png" mode="aspectFit"></image>
|
||||||
|
</view>
|
||||||
|
<view class="check-top-txt">请选择直播商品</view>
|
||||||
|
</view>
|
||||||
|
<view class="do-box-check-right">
|
||||||
|
<view class="check-top-imgb" @click="shop">
|
||||||
|
<image src="@/static/img/c1.png" mode="aspectFit"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" v-if="goodlist.length>0" @click="editshop(goodlist)">
|
||||||
|
<scroll-view scroll-x="true" scroll-left="0" style="width: 450rpx;white-space: nowrap;">
|
||||||
|
<view class="" v-for="(item,i) in goodlist" :key='i'
|
||||||
|
style="width: 100rpx;height: 100rpx;margin-right: 20rpx;display:inline-block;">
|
||||||
|
<image :src="item.app_goods_pic" mode="aspectFit" style="width: 100rpx;height: 100rpx;">
|
||||||
|
</image>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="start-but web-font" @click="create_live_room">开始直播</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<uni-popup ref="popup" type="bottom" style="height: 560rpx;">
|
||||||
|
<shoppinglist @getProduct="getProduct" :checkedObj="productList" @close='close'></shoppinglist>
|
||||||
|
</uni-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
HTTP_REQUEST_URL
|
||||||
|
} from '@/config/app';
|
||||||
|
|
||||||
|
import {
|
||||||
|
good,
|
||||||
|
createPushLive
|
||||||
|
} from '@/api/api.js'
|
||||||
|
import uniPopup from '@/components/uni-popup/uni-popup.vue';
|
||||||
|
import shoppinglist from '@/components/shoppinglist/shoppinglist.vue'
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
uniPopup,
|
||||||
|
shoppinglist
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
livename: '',
|
||||||
|
imageSrc: '',
|
||||||
|
cover_path: '',
|
||||||
|
inputValue: '新建直播间',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
productList: [],
|
||||||
|
goodlist: [],
|
||||||
|
userinfo: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.isUserInfoExist) {
|
||||||
|
console.log('用户信息存在');
|
||||||
|
} else {
|
||||||
|
console.log('用户信息不存在');
|
||||||
|
uni.showModal({
|
||||||
|
// title: '标题',
|
||||||
|
content: '用户信息不存在,是否重新登录',
|
||||||
|
showCancel: true,
|
||||||
|
cancelText: '取消',
|
||||||
|
confirmText: '确定',
|
||||||
|
success: function(res) {
|
||||||
|
if (res.confirm) {
|
||||||
|
// 用户点击了确定按钮
|
||||||
|
uni.redirectTo({
|
||||||
|
url: '/pages/login/login'
|
||||||
|
})
|
||||||
|
} else if (res.cancel) {
|
||||||
|
// 用户点击了取消按钮
|
||||||
|
console.log('用户点击了取消按钮');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
isUserInfoExist() {
|
||||||
|
const userInfo = this.$store.state.app.userInfo;
|
||||||
|
|
||||||
|
uni.sendHostEvent('userinfo', userInfo, (ret) => {
|
||||||
|
//发送消息成功回调
|
||||||
|
console.log('消息成功' + JSON.stringify(userInfo));
|
||||||
|
});
|
||||||
|
return !!userInfo; // 如果 userInfo 为空,则返回 false;否则返回 true
|
||||||
|
},
|
||||||
|
//关闭弹窗
|
||||||
|
close() {
|
||||||
|
this.$refs.popup.close()
|
||||||
|
},
|
||||||
|
//选择商品
|
||||||
|
shop() {
|
||||||
|
this.$refs.popup.open()
|
||||||
|
},
|
||||||
|
editshop(e) {
|
||||||
|
let arr1 = []
|
||||||
|
for (let i in e) {
|
||||||
|
arr1.push({
|
||||||
|
product_id: e[i].app_goods_id,
|
||||||
|
store_name: e[i].app_goods_name,
|
||||||
|
image: e[i].app_goods_pic,
|
||||||
|
price: e[i].app_goods_price,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.productList = arr1
|
||||||
|
this.$refs.popup.open()
|
||||||
|
},
|
||||||
|
//获取商品数据
|
||||||
|
getProduct(e) {
|
||||||
|
|
||||||
|
this.goodlist = []
|
||||||
|
for (let i in e) {
|
||||||
|
this.goodlist.push({
|
||||||
|
app_goods_id: e[i].product_id,
|
||||||
|
app_goods_name: e[i].store_name,
|
||||||
|
app_goods_pic: e[i].image,
|
||||||
|
app_goods_price: e[i].price,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$refs.popup.close()
|
||||||
|
},
|
||||||
|
|
||||||
|
//创建房间
|
||||||
|
create_live_room: function(e) {
|
||||||
|
|
||||||
|
if (this.cover_path == '') {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请上传封面',
|
||||||
|
duration: 2000,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.livename == '') {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请填写标题',
|
||||||
|
duration: 2000,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.goodlist.length == 0) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请添加商品',
|
||||||
|
duration: 2000,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
createPushLive({
|
||||||
|
live_name: this.livename,
|
||||||
|
cover: this.cover_path,
|
||||||
|
app_name: "shop",
|
||||||
|
app_user_id: this.$store.state.app.userInfo.uid,
|
||||||
|
goods: this.goodlist
|
||||||
|
}).then(res => {
|
||||||
|
console.log(res)
|
||||||
|
uni.sendHostEvent('log', res, (ret) => {
|
||||||
|
//发送消息成功回调
|
||||||
|
console.log('消息成功' + JSON.stringify(res));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.code == 1) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/live/anchor?data=' + encodeURIComponent(JSON.stringify(res
|
||||||
|
.data))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: res.msg,
|
||||||
|
duration: 2000,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((err) => {
|
||||||
|
uni.sendHostEvent('log', err, (ret) => {
|
||||||
|
//发送消息成功回调
|
||||||
|
console.log('消息成功' + JSON.stringify(err));
|
||||||
|
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
chooseImage: function() {
|
||||||
|
let that = this;
|
||||||
|
that.$util.uploadImageOne('upload/image', function(res) {
|
||||||
|
// console.log(res.data.path)
|
||||||
|
that.cover_path = res.data.path
|
||||||
|
that.imageSrc = res.data.path
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onBackPress() {
|
||||||
|
|
||||||
|
|
||||||
|
// this.$refs['showpopup'].close()
|
||||||
|
// this.$refs['showtip'].close()
|
||||||
|
// this.$refs['showimage'].close()
|
||||||
|
// this.$refs['showshare'].close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-do-box {
|
||||||
|
width: 90%;
|
||||||
|
margin: auto;
|
||||||
|
/* #ifdef MP-WEIXIN */
|
||||||
|
margin-top: 120upx;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
margin-top: 60upx;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.ico-box {
|
||||||
|
width: 70upx;
|
||||||
|
height: 70upx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ico {
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 48upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lico {
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 28upx;
|
||||||
|
margin-right: 4upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.do-box {
|
||||||
|
width: 90%;
|
||||||
|
padding: 40upx 0;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
margin: auto;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.do-box-top {
|
||||||
|
.cover-box {
|
||||||
|
width: 193rpx;
|
||||||
|
height: 193rpx;
|
||||||
|
background: #F4F4F4;
|
||||||
|
border-radius: 10upx;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
margin-top: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cover-box-img {
|
||||||
|
width: 72rpx;
|
||||||
|
height: 72rpx;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cover-inputplaceholder {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-family: PingFang SC-Regular, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #737373;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cover-input {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-family: PingFang SC-Regular, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #000;
|
||||||
|
margin-top: 32rpx;
|
||||||
|
margin-bottom: 70rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.cover-text {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 30rpx;
|
||||||
|
width: 100%;
|
||||||
|
height: 50upx;
|
||||||
|
line-height: 50upx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 28upx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cover-box image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.do-box-check {
|
||||||
|
margin-top: 35rpx;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.do-box-check-top {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
|
||||||
|
.do-box-check-left {
|
||||||
|
display: flex;
|
||||||
|
.check-top-imga {
|
||||||
|
width: 44rpx;
|
||||||
|
height: 44rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-top-txt {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-family: PingFang SC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.do-box-check-right {
|
||||||
|
.check-top-imgb {
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-lable {
|
||||||
|
width: 200upx;
|
||||||
|
height: 60upx;
|
||||||
|
line-height: 60upx;
|
||||||
|
border-radius: 60upx;
|
||||||
|
background-color: rgba(0, 0, 0, .2);
|
||||||
|
text-align: center;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 28upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-input {
|
||||||
|
background: none !important;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 40upx;
|
||||||
|
margin-top: 20upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部分享 */
|
||||||
|
.uni-share {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
/* #endif */
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 0 40upx;
|
||||||
|
border-top-left-radius: 20upx;
|
||||||
|
border-top-right-radius: 20upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-title {
|
||||||
|
line-height: 60rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
padding: 15rpx 0;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 2upx solid #F0F0F0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-content {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
/* display: flex; */
|
||||||
|
/* #endif */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
/* justify-content: space-around; */
|
||||||
|
padding: 15px 0;
|
||||||
|
/* padding-bottom: 0; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-image {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-content-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #333;
|
||||||
|
padding-top: 5px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-btn {
|
||||||
|
height: 90rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
font-size: 14px;
|
||||||
|
border-top-color: #f5f5f5;
|
||||||
|
border-top-width: 1px;
|
||||||
|
border-top-style: solid;
|
||||||
|
text-align: center;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.type-lable {
|
||||||
|
width: 20%;
|
||||||
|
margin-left: 2.5%;
|
||||||
|
height: 60upx;
|
||||||
|
line-height: 60upx;
|
||||||
|
border-radius: 60upx;
|
||||||
|
text-align: center;
|
||||||
|
color: #666666;
|
||||||
|
font-size: 24upx;
|
||||||
|
border: 2upx solid #F0F0F0;
|
||||||
|
margin-bottom: 20upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.type-lable-active {
|
||||||
|
background-color: #ff2d54;
|
||||||
|
border: 2upx solid #ff2d54;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ok-but {
|
||||||
|
width: 100%;
|
||||||
|
height: 90upx;
|
||||||
|
line-height: 90upx;
|
||||||
|
border-radius: 90upx;
|
||||||
|
font-size: 28upx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #ff2d54;
|
||||||
|
margin: 20upx auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ok-but-none {
|
||||||
|
background-color: #F0F0F0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loc-lable {
|
||||||
|
line-height: 70upx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loc-lable-active {
|
||||||
|
color: #ff2d54;
|
||||||
|
}
|
||||||
|
|
||||||
|
.start-but {
|
||||||
|
width: 60%;
|
||||||
|
height: 90upx;
|
||||||
|
line-height: 90upx;
|
||||||
|
border-radius: 90upx;
|
||||||
|
font-size: 36upx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #ff2d54;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 100upx;
|
||||||
|
left: 20%;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,590 @@
|
||||||
|
<template>
|
||||||
|
<view class="view_body">
|
||||||
|
<z-paging ref="paging" refresher-only @onRefresh="onRefresh">
|
||||||
|
<view class="" :style="'height:'+statusBarHeight+'px'">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<view class="search_content flex_a_c_j_sb">
|
||||||
|
<view class="flex_a_c">
|
||||||
|
<view class="iconfont icon-sousuo" style="font-size: 39rpx;"></view>
|
||||||
|
<input type="text" v-model="keyword" placeholder="搜索主播或关键字"
|
||||||
|
placeholder-style="font-size: 30rpx;" @input="change">
|
||||||
|
</view>
|
||||||
|
<button class="search_btn" @click="search">搜索</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="content-detail">
|
||||||
|
<view class="banner">
|
||||||
|
<view class="banner-detail" v-for="(item,i) in list" :key='i' @click="zhisort(i)">
|
||||||
|
<view class="banner-name">
|
||||||
|
{{item.name}}
|
||||||
|
</view>
|
||||||
|
<view class="banner-t" v-if="isindex==i">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class="content-detaila" @click="jump_url">
|
||||||
|
去开直播
|
||||||
|
<text class="iconfont icon-xiangyou"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<scroll-view scroll-top="0" scroll-y="true" class="goods_body_scroll" v-if="isindex==0">
|
||||||
|
<view class="roomsbox">
|
||||||
|
<view class="roomblock" v-for="(room,index) in roomList" :key="index" @click="jump(room)"
|
||||||
|
style="border: 1px solid #e1d9d4;">
|
||||||
|
<image :src="room.cover" mode="aspectFill" v-if="room.cover"></image>
|
||||||
|
<image src="/static/lw/6.gif" mode="aspectFill" v-else></image>
|
||||||
|
<view class="livetitle">{{room.live_name}}</view>
|
||||||
|
<view class="roomstatus-d" v-if="room.status==1" style="background-color: #09BB07;">
|
||||||
|
</view>
|
||||||
|
<view class="roomstatus-d" v-else style="background-color: #fa2306;">
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="roomstatus" style="color: #00B26A;" v-if="room.status==1">直播中
|
||||||
|
</view>
|
||||||
|
<view class="roomstatus" style="color: #fa2306;" v-else>已停播
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</scroll-view>
|
||||||
|
<scroll-view scroll-top="0" scroll-y="true" class="goods_body_scroll" v-if="isindex==1">
|
||||||
|
<view v-for="(pp,index) in roomList" :key="index">
|
||||||
|
<view class="roomsbox-a" v-for="(kk,i) in pp" :key="i">
|
||||||
|
<view class="roomsbox-title">
|
||||||
|
{{i}}
|
||||||
|
</view>
|
||||||
|
<view class="roomsbox">
|
||||||
|
<view class="roomblock" style="border: 1px solid #e1d9d4;" v-for="(room,j) in kk"
|
||||||
|
:key="j" @click="hsitroyjump(room)">
|
||||||
|
<image :src="room.cover" mode="aspectFill" v-if="room.cover"></image>
|
||||||
|
<image src="/static/lw/6.gif" mode="aspectFill" v-else></image>
|
||||||
|
<view class="livetitle">{{room.live_name}}</view>
|
||||||
|
<view class="roomstatus-d" v-if="room.status==1" style="background-color: #09BB07;">
|
||||||
|
</view>
|
||||||
|
<view class="roomstatus-d" v-else style="background-color: #fa2306;">
|
||||||
|
</view>
|
||||||
|
<view class="roomstatus-d" v-if="room.status==3" style="background-color: #e1d9d4;">
|
||||||
|
</view>
|
||||||
|
<view class="roomstatus" style="color: #00B26A;" v-if="room.status==1">直播中
|
||||||
|
</view>
|
||||||
|
<view class="roomstatus" style="color: #fa2306;" v-else>已停播
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</scroll-view>
|
||||||
|
<view class="noshuju" v-if="roomList.length==0">
|
||||||
|
<emptyPage title="暂无房间信息"></emptyPage>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</z-paging>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import emptyPage from '@/components/emptyPage.vue';
|
||||||
|
import {
|
||||||
|
live,
|
||||||
|
playbackList
|
||||||
|
} from '@/api/api.js'
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
emptyPage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
keyword: '',
|
||||||
|
statusBarHeight: 0,
|
||||||
|
page: 1,
|
||||||
|
dataindex: 1,
|
||||||
|
page_data: true,
|
||||||
|
list: [{
|
||||||
|
name: '直播精选'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '历史直播'
|
||||||
|
},
|
||||||
|
|
||||||
|
],
|
||||||
|
roomList: [],
|
||||||
|
user: [],
|
||||||
|
index: 0,
|
||||||
|
isGetLoginInfo: true,
|
||||||
|
isindex: 0,
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
|
||||||
|
this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.isUserInfoExist()) {
|
||||||
|
console.log('用户信息存在');
|
||||||
|
this.getRoomList()
|
||||||
|
} else {
|
||||||
|
console.log('用户信息不存在');
|
||||||
|
uni.showModal({
|
||||||
|
// title: '标题',
|
||||||
|
content: '用户信息不存在,是否重新登录',
|
||||||
|
showCancel: true,
|
||||||
|
cancelText: '取消',
|
||||||
|
confirmText: '确定',
|
||||||
|
success: function(res) {
|
||||||
|
if (res.confirm) {
|
||||||
|
// 用户点击了确定按钮
|
||||||
|
uni.redirectTo({
|
||||||
|
url: '/pages/login/login'
|
||||||
|
})
|
||||||
|
} else if (res.cancel) {
|
||||||
|
// 用户点击了取消按钮
|
||||||
|
console.log('用户点击了取消按钮');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
onShow() {},
|
||||||
|
onReachBottom() {
|
||||||
|
if (this.isindex == 0) {
|
||||||
|
this.getRoomList()
|
||||||
|
} else {
|
||||||
|
this.getbackList()
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
onPullDownRefresh: function() {
|
||||||
|
console.log('下拉刷新')
|
||||||
|
this.getRoomList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
//下拉刷新被触发
|
||||||
|
onRefresh() {
|
||||||
|
//以告知z-paging下拉刷新结束,这样才可以开始下一次的下拉刷新
|
||||||
|
setTimeout(() => {
|
||||||
|
//1.5秒之后停止刷新动画
|
||||||
|
if (this.isindex == 0) {
|
||||||
|
this.getRoomList()
|
||||||
|
} else {
|
||||||
|
this.getbackList()
|
||||||
|
}
|
||||||
|
this.$refs.paging.complete();
|
||||||
|
}, 1500)
|
||||||
|
},
|
||||||
|
isUserInfoExist() {
|
||||||
|
const userInfo = this.$store.state.app.userInfo;
|
||||||
|
uni.sendHostEvent('userinfo', userInfo, (ret) => {
|
||||||
|
//发送消息成功回调
|
||||||
|
console.log('消息成功' + JSON.stringify(userInfo));
|
||||||
|
});
|
||||||
|
return !!userInfo; // 如果 userInfo 为空,则返回 false;否则返回 true
|
||||||
|
},
|
||||||
|
//输入
|
||||||
|
change(e) {
|
||||||
|
// console.log(e)
|
||||||
|
if (e.detail.value.length <= 0) {
|
||||||
|
this.page = 1
|
||||||
|
this.getRoomList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//查询
|
||||||
|
search() {
|
||||||
|
|
||||||
|
this.page = 1
|
||||||
|
this.roomList = []
|
||||||
|
if (this.isindex == 0) {
|
||||||
|
this.getRoomList()
|
||||||
|
} else {
|
||||||
|
this.getbackList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//分类
|
||||||
|
zhisort(i) {
|
||||||
|
this.isindex = i
|
||||||
|
this.page = 1
|
||||||
|
this.roomList = []
|
||||||
|
if (i == 0) {
|
||||||
|
this.getRoomList()
|
||||||
|
} else {
|
||||||
|
this.getbackList()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getbackList: function() {
|
||||||
|
playbackList({
|
||||||
|
page_size: 100,
|
||||||
|
page: this.page,
|
||||||
|
app_name: 'shop',
|
||||||
|
keyword: this.keyword
|
||||||
|
}).then(res => {
|
||||||
|
// console.log(res)
|
||||||
|
if (res.data.code = 1) {
|
||||||
|
uni.hideLoading()
|
||||||
|
// this.roomList = res.data.lists
|
||||||
|
// this.roomList.push(res.data.lists)
|
||||||
|
if (res.data.lists.length > 0) {
|
||||||
|
const groupedArray = res.data.lists.reduce((acc, obj) => {
|
||||||
|
const date = obj.date;
|
||||||
|
if (!acc[date]) {
|
||||||
|
acc[date] = [];
|
||||||
|
}
|
||||||
|
acc[date].push(obj);
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
this.roomList.push(groupedArray)
|
||||||
|
// 输出结果
|
||||||
|
console.log(this.roomList);
|
||||||
|
}
|
||||||
|
// this.page = this.page + 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 拉取房间列表
|
||||||
|
* @return {[type]}
|
||||||
|
* [description]
|
||||||
|
*/
|
||||||
|
getRoomList: function() {
|
||||||
|
live({
|
||||||
|
page_size: 10,
|
||||||
|
page: this.page,
|
||||||
|
app_name: 'shop',
|
||||||
|
keyword: this.keyword
|
||||||
|
}).then(res => {
|
||||||
|
// console.log(res)
|
||||||
|
if (res.data.code = 1) {
|
||||||
|
uni.hideLoading()
|
||||||
|
if (res.data.lists.length > 0) {
|
||||||
|
let list = res.data.lists;
|
||||||
|
let productList = this.$util.SplitArray(list, this.roomList);
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$set(this, 'roomList', productList);
|
||||||
|
}, 500)
|
||||||
|
this.page = this.page + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
jump: function(e) {
|
||||||
|
console.log(e)
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/live/spectator' + '?data=' + encodeURIComponent(JSON.stringify(e))
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
//历史直播间
|
||||||
|
hsitroyjump: function(e) {
|
||||||
|
console.log(e)
|
||||||
|
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/live/histroyroom' + '?data=' + encodeURIComponent(JSON.stringify(e))
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
//创建直播间
|
||||||
|
jump_url() {
|
||||||
|
if (this.isUserInfoExist()) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/room/create_room'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.showModal({
|
||||||
|
// title: '标题',
|
||||||
|
content: '用户信息不存在,是否重新登录',
|
||||||
|
showCancel: true,
|
||||||
|
cancelText: '取消',
|
||||||
|
confirmText: '确定',
|
||||||
|
success: function(res) {
|
||||||
|
if (res.confirm) {
|
||||||
|
// 用户点击了确定按钮
|
||||||
|
uni.redirectTo({
|
||||||
|
url: '/pages/login/login'
|
||||||
|
})
|
||||||
|
} else if (res.cancel) {
|
||||||
|
// 用户点击了取消按钮
|
||||||
|
console.log('用户点击了取消按钮');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods_body_scroll {
|
||||||
|
margin-top: 50rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_content {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 724rpx;
|
||||||
|
height: 64rpx;
|
||||||
|
padding: 2px 2px 2px 21.05rpx;
|
||||||
|
border-radius: 175rpx;
|
||||||
|
background: #fff;
|
||||||
|
margin-bottom: 21rpx;
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 2rpx solid #FCB9AD;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
|
||||||
|
.icon-sousuo {
|
||||||
|
font-size: 26.32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #c8c7c6;
|
||||||
|
margin-right: 17.54rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_btn {
|
||||||
|
color: #fff;
|
||||||
|
width: 105.26rpx;
|
||||||
|
height: 56rpx;
|
||||||
|
line-height: 56rpx;
|
||||||
|
background: #f84221;
|
||||||
|
border-radius: 100px;
|
||||||
|
font-size: 28.07rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-detail {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner {
|
||||||
|
display: flex;
|
||||||
|
padding-left: 28rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.roomsbox-title {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-family: PingFang SC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333333;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner-detail {
|
||||||
|
width: 133rpx;
|
||||||
|
margin-right: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner-name {
|
||||||
|
font-size: 33rpx;
|
||||||
|
font-family: PingFang SC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333333;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-detaila {
|
||||||
|
font-size: 33rpx;
|
||||||
|
font-family: PingFang SC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333333;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner-t {
|
||||||
|
width: 46px;
|
||||||
|
height: 0rpx;
|
||||||
|
opacity: 1;
|
||||||
|
border: 2rpx solid #F84221;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noshuju {
|
||||||
|
height: 760upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mico-18 {
|
||||||
|
margin-top: 10upx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view_body {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roomstatus-d {
|
||||||
|
width: 20upx;
|
||||||
|
height: 20upx;
|
||||||
|
border-radius: 20upx;
|
||||||
|
position: absolute;
|
||||||
|
left: 20upx;
|
||||||
|
top: 20upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roomstatus {
|
||||||
|
position: absolute;
|
||||||
|
left: 40upx;
|
||||||
|
top: 10upx;
|
||||||
|
font-size: 28upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.livetitle {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 20upx;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
height: 70upx;
|
||||||
|
line-height: 70upx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top {
|
||||||
|
display: flex;
|
||||||
|
padding: 20upx;
|
||||||
|
top: 0;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
width: 95%;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_li {
|
||||||
|
font-size: 32upx;
|
||||||
|
padding: 0 20upx;
|
||||||
|
display: table-cell;
|
||||||
|
/* vertical-align:bottom; */
|
||||||
|
padding-top: 10upx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-lable-box {
|
||||||
|
/* #ifdef APP-PLUS */
|
||||||
|
/* flex: 1; */
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
font-size: 40upx;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #333333;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roomsbox {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.roomblock {
|
||||||
|
width: 45%;
|
||||||
|
height: 300upx;
|
||||||
|
border-radius: 10upx;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 20upx;
|
||||||
|
position: relative;
|
||||||
|
margin-left: 2.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right_top_scroll {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-view {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
line-height: 60rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 10rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.view_body {
|
||||||
|
background: #FFFFFF;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mico-14 {
|
||||||
|
margin-right: 4upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noshuju {
|
||||||
|
height: 750upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noshuju_ico {
|
||||||
|
width: 120upx;
|
||||||
|
height: 80upx;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 300rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.noshuju_ico image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mico-18 {
|
||||||
|
margin-top: 10upx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.create-but {
|
||||||
|
background-color: #1ce0c5;
|
||||||
|
width: 120upx;
|
||||||
|
height: 60upx;
|
||||||
|
line-height: 60upx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 10upx;
|
||||||
|
/* #ifdef MP-WEIXIN */
|
||||||
|
margin-left: 40upx;
|
||||||
|
/* #endif */
|
||||||
|
margin-top: 4upx;
|
||||||
|
}
|
||||||
|
</style>
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue