From 1a36fef1028f1bb7a7c9c9476011bc8289e0bf03 Mon Sep 17 00:00:00 2001
From: zengh <123456>
Date: Fri, 09 Jul 2021 09:42:58 +0800
Subject: [PATCH] 初版集成
---
router/router.js | 38
components/feng-parse/components/wxParseTemplate5.vue | 107 +
components/uni-nav-bar/uni-nav-bar.vue | 251 ++
components/e-picker/e-picker.vue | 138 +
components/feng-parse/components/wxParseTable.vue | 56
components/feng-parse/components/wxParseTemplate0.vue | 116 +
components/submit/submit.vue | 447 ++++
components/submit/emoji/emoji.vue | 75
components/feng-parse/components/wxParseVideo.vue | 55
components/uni-nav-bar/uni-status-bar.vue | 25
components/outAdmin/uni-Popup.vue | 121 +
components/uni-load-more/uni-load-more.vue | 362 +++
components/seeImges/seeImges.vue | 169 +
App.vue | 60
components/feng-parse/components/wxParseTemplate6.vue | 107 +
components/feng-parse/components/wxParseImg.vue | 94 +
store/index.js | 65
components/feng-parse/components/wxParseAudio.vue | 28
components/feng-parse/libs/html2json.js | 308 +++
components/contacts/contacts.vue | 236 ++
components/feng-parse/components/wxParseTemplate10.vue | 107 +
components/feng-parse/components/wxParseTemplate7.vue | 107 +
static/lib/axios.js | 3
components/feng-parse/parse.vue | 237 ++
components/feng-parse/parse.css | 258 ++
components/feng-parse/components/wxParseTemplate11.vue | 105 +
pages/login/login-account.vue | 208 +
components/feng-parse/libs/htmlparser.js | 156 +
components/feng-parse/components/wxParseTemplate3.vue | 107 +
components/nav-bar-top/nav-bar-top.vue | 72
components/feng-parse/components/wxParseTemplate2.vue | 107 +
components/feng-parse/components/wxParseTemplate8.vue | 107 +
static/lib/wxStorage.js | 27
components/e-picker/e-picker.js | 1
components/feng-parse/components/wxParseTemplate4.vue | 107 +
components/feng-parse/components/wxParseTemplate1.vue | 107 +
components/feng-parse/components/wxParseVideo1.vue | 25
components/pColumn/pColumn.vue | 275 ++
package.json | 24
components/feng-parse/libs/wxDiscode.js | 209 ++
store/mutations.js | 54
components/feng-parse/components/wxParseTemplate9.vue | 107 +
components/squareBut/squareBut.vue | 61
store/actions.js | 90
44 files changed, 5,437 insertions(+), 82 deletions(-)
diff --git a/App.vue b/App.vue
index b25466f..7a4e426 100644
--- a/App.vue
+++ b/App.vue
@@ -1,19 +1,67 @@
<script>
+ import WxStorage from "./static/lib/wxStorage.js" //微信Storage
export default {
- onLaunch: function() {
- console.log('App Launch')
+ data() {
+ return {
+ login: '',
+ }
},
- onShow: function() {
- console.log('App Show')
+ methods: {
+ judgeAdmin() {
+ var scss = this.$route.path == "/pages/loging/loging";
+ wx.getSystemInfo({
+ success(res) {
+ console.log(res)
+ }
+ })
+ console.log(this.$store.state.logPath, 'scss')
+ if (scss) {
+ return
+ }
+ this.login = WxStorage.get("init");
+ // console.log(this.login, 'login')
+ if (this.login == "false") {
+ wx.navigateTo({
+ url: 'pages/loging/loging?id=1',
+ })
+ }
+ }
+ },
+ watch: {},
+ mounted() {},
+ onLaunch: function() { //初始化完成时触发(全局只触发一次)
+ if (WxStorage.get("init") == '') {
+ WxStorage.set("init", 'false');
+ console.log('第一次进入')
+ }
+ // this.judgeAdmin();
+ },
+ onShow: function() { //当 uni-app 启动,或从后台进入前台显示 //监听用户进入小程序
+ // console.log('App Show')
+ // this.judgeAdmin();
},
onHide: function() {
- console.log('App Hide')
+ // console.log('App Hide')
}
}
</script>
+
<style lang="scss">
+ // @import '@smallwei/avue/lib/index.css';
/*uview全局样式*/
@import "uview-ui/index.scss";
/*app全局样式*/
@import 'static/style/app.scss';
-</style>
\ No newline at end of file
+
+ uni-page-wrapper {
+ width: 100%;
+ height: 100%;
+ }
+
+ uni-page-body {
+ width: 100%;
+ height: 100%;
+ }
+
+ /*每个页面公共css */
+</style>
diff --git a/components/contacts/contacts.vue b/components/contacts/contacts.vue
new file mode 100644
index 0000000..28acda7
--- /dev/null
+++ b/components/contacts/contacts.vue
@@ -0,0 +1,236 @@
+<template>
+ <view class="pColumn" >
+ <view class="inPColumn" v-if="fromW == 0">
+ <view class="left" @click="chating">
+ <view class="top">
+ <view class="userImg">
+ <img class="img" :src=Pdata.avatar>
+ </view>
+ <view class="t-type">{{Pdata.recipientName}}</view>
+ <view class="t-id">{{Pdata.postTime}}</view>
+ </view>
+ <view class="bottom">{{Pdata.postMessage}}</view>
+ </view>
+ </view>
+ <view class="inPColumn" v-if="fromW == 1">
+ <view class="left" @click="QZchating">
+ <view class="top">
+ <view class="userImg">
+ <img class="img" :src=Pdata.avatar>
+ </view>
+ <view class="t-type">{{Pdata.GroupName}}</view>
+ <!-- <view class="t-id">{{Pdata.postTime}}</view> -->
+ </view>
+ <view class="bottom">{{Pdata.GroupContent}}</view>
+ </view>
+ </view>
+ <view class="inPColumn" v-if="fromW == 2">
+ <view class="left" @click="TXLchating">
+ <view class="top">
+ <view class="userImg">
+ <img class="img" :src=Pdata.avatar>
+ </view>
+ <view class="t-type">{{Pdata.realName}}</view>
+ <!-- <view class="t-id">{{Pdata.postTime}}</view> -->
+ </view>
+ <view class="bottom">电话:{{Pdata.phone}}</view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ export default {
+ props: ['fromW', 'Pdata'],
+ data() {
+ return {
+ popuShow: false,
+ bmainb: ''
+ }
+ },
+ methods: {
+ beginObj() {
+ this.bmainb = '3rem';
+ //#ifdef MP-WEIXIN
+ this.bmainb = '0';
+ //#endif
+ },
+ chating(){
+ //发起聊天
+ var datas = this.Pdata;
+ //alert(datas.name)
+ uni.navigateTo({
+ url: '/pages/groupChat/chating?chatID=' + datas.recipientId.toString()
+ });
+ },
+ QZchating(){
+ //发起聊天
+ var datas = this.Pdata;
+ //alert(datas.name)
+ uni.navigateTo({
+ url: '/pages/groupChat/chatingQZ?chatID=' + datas.id.toString()
+ });
+ },
+ TXLchating(){
+ //发起聊天
+ var datas = this.Pdata;
+ //alert(datas.name)
+ uni.navigateTo({
+ url: '/pages/groupChat/chating?chatID=' + datas.id.toString()
+ });
+ },
+ onClose() { //触摸遮罩事件
+ this.setData({
+ popuShow: false
+ });
+ },
+ },
+ mounted() {
+ this.beginObj();
+ }
+
+ }
+</script>
+
+<style lang="scss" scoped>
+ /* components/pColumn/pColumn.wxss */
+ .pColumn,
+ .inPColumn,
+ .left,
+ .right,
+ .top {
+ display: flex;
+ }
+
+ .userImg {
+ // border: 1px solid #007AFF;
+
+ .img {
+ width: 100rpx;
+ height: 100rpx;
+ border-radius: 100rpx;
+ // border: 1px solid #007AFF;
+ }
+ }
+
+ .pColumn {
+ width: 100%;
+ align-items: center;
+ justify-content: center;
+ padding-top: 0.5rem;
+
+ .inPColumn {
+ margin: 0.2rem 0 0.4rem 0;
+ width: 95%;
+ height: 4rem;
+ border-bottom: 1px rgb(207, 207, 207) solid;
+ align-items: center;
+ justify-content: space-between;
+
+ .left {
+ width: 80%;
+ /* border: 1px rgb(114, 250, 159) solid; */
+ flex-direction: column;
+
+ .top {
+ .t-type {
+ padding-left: 0.7rem;
+ font-size: 1.1rem;
+ color: #000000;
+ }
+
+ .t-id {
+ color: #8b8b8b;
+ font-size: 0.8rem;
+ line-height: 1.6rem;
+ position: absolute;
+ right: 1.2rem;
+ }
+ }
+
+ .bottom {
+ color: #8b8b8b;
+ font-size: 0.9rem;
+ position: relative;
+ bottom: 1rem;
+ left: 4rem;
+ }
+ }
+
+ .right {
+ width: 20%;
+ /* border: 1px rgb(143, 114, 250) solid; */
+ justify-content: space-around;
+
+ /* align-items: center; */
+ .butPopup {
+ z-index: 4;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba($color: #000000, $alpha: 0.5);
+
+ .b-main {
+ position: absolute;
+ z-index: 2;
+ // bottom: 3rem;//小程序不兼容
+ width: 100%;
+ // border: 1px solid #007AFF;
+ border-radius: 1.5rem;
+ background-color: #fff;
+
+ // height: 20rem;
+ .b-m-title {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 2.8rem;
+ }
+
+ .b-m-Y,
+ .b-m-N {
+ color: #fff;
+ border-radius: 0;
+ }
+
+ .b-m-Y {
+ background-color: #07C160 !important;
+ }
+
+ .b-m-Y-hove {
+ background-color: #048c44 !important;
+ }
+
+ .b-m-N {
+ background-color: #FF976A !important;
+ }
+
+ .b-m-N-hove {
+ background-color: #e1855d !important;
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+
+
+ // .buttitle {
+ // display: flex;
+ // align-items: center;
+ // justify-content: center;
+ // width: 100%;
+ // height: 2.8rem;
+ // }
+
+ // .popups {
+ // width: 100%;
+ // padding-bottom: 0 !important;
+ // /* border: 1px solid seagreen; */
+ // }
+</style>
diff --git a/components/e-picker/e-picker.js b/components/e-picker/e-picker.js
new file mode 100644
index 0000000..9d724c7
--- /dev/null
+++ b/components/e-picker/e-picker.js
@@ -0,0 +1 @@
+"use strict";function getDayArr(e,t){for(var r=e%4==0&&e%100!=0&&e%400!=0,a=[31,r?29:28,31,30,31,30,31,31,30,31,30,31],n=[],o=0;o<a[t-1];o++)n.push(fmt(o+1)+"日");return n}function getArr(e){var t=[],r=1,a=13,n="月";e>2&&(r=0,3==e&&(a=24,n="时"),e>3&&(a=60,4==e&&(n="分"),5==e&&(n="秒")));for(var o=r;o<a;o++)t.push(fmt(o)+n);return t}function fmt(e){return e>9?e:"0"+e}function checkShowValue(e,t){if("date"!=e&&"dateTime"!=e&&"time"!=e)throw Error("mode无"+e+"该选项配置");if("date"==e&&10!=t.length||"time"==e&&8!=t.length||"dateTime"==e&&19!=t.length)throw Error("'showValue'有误,请根据当前mode 正确设置格式")}function getDateTimeValue(e,t){var r=fmt(parseInt(e[0])),a=fmt(parseInt(e[1])),n=fmt(parseInt(e[2])),o=fmt(parseInt(e[3])),m=fmt(parseInt(e[4])),u=fmt(parseInt(e[5]));return"date"==t?r+"-"+a+"-"+n:"dateTime"==t?r+"-"+a+"-"+n+" "+o+":"+m+":"+u:r+":"+a+":"+n}function getLocalTime(e){var t=new Date;switch(e){case"dateTime":return t.getFullYear()+"-"+fmt(t.getMonth()+1)+"-"+fmt(t.getDate())+" "+fmt(t.getHours())+":"+fmt(t.getMinutes())+":"+fmt(t.getSeconds());case"time":return fmt(t.getHours())+":"+fmt(t.getMinutes())+":"+fmt(t.getSeconds());default:return t.getFullYear()+"-"+fmt(t.getMonth()+1)+"-"+fmt(t.getDate())}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.getDayArr=getDayArr,exports.getArr=getArr,exports.checkShowValue=checkShowValue,exports.getDateTimeValue=getDateTimeValue,exports.getLocalTime=getLocalTime;
\ No newline at end of file
diff --git a/components/e-picker/e-picker.vue b/components/e-picker/e-picker.vue
new file mode 100644
index 0000000..6a7b1bb
--- /dev/null
+++ b/components/e-picker/e-picker.vue
@@ -0,0 +1,138 @@
+<template>
+ <picker mode="multiSelector" :range="range" :value="value" @change="change" @columnchange="columnchange">
+ <slot></slot>
+ </picker>
+</template>
+
+<script>
+ import * as utils from "./e-picker.js";
+ let defaultValue;
+ export default {
+ data() {
+ return {
+ range: [],
+ value: []
+ };
+ },
+ props: {
+ mode: {
+ type: String,
+ default: "date"
+ },
+ showValue: String,
+ startYear: {
+ type: [Number, String],
+ default: 1949
+ },
+ endYear: {
+ type: [String, Number],
+ default: new Date().getFullYear()
+ }
+ },
+ watch: {
+ showValue(v) {
+ this.init()
+ }
+ },
+ created() {
+ this.init();
+ },
+ methods: {
+ init() {
+ this.range = [];
+ this.value = [];
+ let l;
+ defaultValue = utils.getLocalTime(this.mode)
+ if (this.showValue) {
+ defaultValue = this.showValue
+ }
+ utils.checkShowValue(this.mode, defaultValue);
+ this.mode == "dateTime" ? (l = 6) : (l = 3);
+ for (let i = 0; i < l; i++) {
+ this.range.push([]);
+ this.value.push(0);
+ this.setColumns(i);
+ }
+ },
+ setColumns(index) {
+ const m = this.mode;
+ if (m != "time") {
+ const showYear = defaultValue.substring(0, 4),
+ showMonth = defaultValue.substring(5, 7),
+ showDay = defaultValue.substring(8, 10);
+ switch (index) {
+ case 0:
+ const s = +this.startYear,
+ e = +this.endYear;
+ for (let i = s; i < e + 1; i++) {
+ this.range[index].push(i + "年");
+ }
+ this.value[index] = this.range[index].indexOf(showYear + "年");
+ break;
+ case 1:
+ this.range[index] = utils.getArr(1);
+ this.value[index] = this.range[index].indexOf(showMonth + "月");
+ break;
+ case 2:
+ this.range[index] = utils.getDayArr(+showYear, +showMonth);
+ this.value[index] = this.range[index].indexOf(showDay + "日");
+ break;
+ case 3:
+ const show_h = defaultValue.substring(11, 13);
+ this.range[index] = utils.getArr(3);
+ this.value[index] = this.range[index].indexOf(show_h + "时");
+ break;
+ case 4:
+ const show_m = defaultValue.substring(14, 16);
+ this.range[index] = utils.getArr(4);
+ this.value[index] = this.range[index].indexOf(show_m + "分");
+ break;
+ case 5:
+ const show_s = defaultValue.substring(17, 19);
+ this.range[index] = utils.getArr(5);
+ this.value[index] = this.range[index].indexOf(show_s + "秒");
+ break;
+ }
+ } else {
+ switch (index) {
+ case 0:
+ const show_h = defaultValue.substring(0, 2);
+ this.range[index] = utils.getArr(3);
+ this.value[index] = this.range[index].indexOf(show_h + "时");
+ break;
+ case 1:
+ const show_m = defaultValue.substring(3, 5);
+ this.range[index] = utils.getArr(4);
+ this.value[index] = this.range[index].indexOf(show_m + "分");
+ break;
+ case 2:
+ const show_s = defaultValue.substring(6, 8);
+ this.range[index] = utils.getArr(5);
+ this.value[index] = this.range[index].indexOf(show_s + "秒");
+ break;
+ }
+ }
+ this.$forceUpdate()
+ },
+ columnchange(e) {
+ if (this.mode == "time") return;
+ const column = e.detail.column,
+ value = e.detail.value;
+ if (column == 1 || !column) {
+ this.value[column] = value;
+ }
+ const y = parseInt(this.range[0][this.value[0]]),
+ m = parseInt(this.range[1][this.value[1]]);
+ this.range[2] = utils.getDayArr(y, m);
+ this.$forceUpdate()
+ },
+ change(e) {
+ const value = e.detail.value;
+ const timeArr = value.map((v, i) => {
+ return this.range[i][v];
+ });
+ this.$emit("change", utils.getDateTimeValue(timeArr, this.mode));
+ }
+ }
+ };
+</script>
diff --git a/components/feng-parse/components/wxParseAudio.vue b/components/feng-parse/components/wxParseAudio.vue
new file mode 100644
index 0000000..b277717
--- /dev/null
+++ b/components/feng-parse/components/wxParseAudio.vue
@@ -0,0 +1,28 @@
+<template>
+ <!-- '<audio/>' 组件不再维护,建议使用能力更强的 'uni.createInnerAudioContext' 接口 有时间再改-->
+ <!--增加audio标签支持-->
+ <audio
+ :id="node.attr.id"
+ :class="node.classStr"
+ :style="node.styleStr"
+ :src="node.attr.src"
+ :loop="node.attr.loop"
+ :poster="node.attr.poster"
+ :name="node.attr.name"
+ :author="node.attr.author"
+ controls></audio>
+</template>
+
+<script>
+export default {
+ name: 'wxParseAudio',
+ props: {
+ node: {
+ type: Object,
+ default() {
+ return {};
+ },
+ },
+ },
+};
+</script>
diff --git a/components/feng-parse/components/wxParseImg.vue b/components/feng-parse/components/wxParseImg.vue
new file mode 100644
index 0000000..50893c1
--- /dev/null
+++ b/components/feng-parse/components/wxParseImg.vue
@@ -0,0 +1,94 @@
+<template>
+ <image
+ mode="widthFix"
+ :lazy-load="node.attr.lazyLoad"
+ :class="node.classStr"
+ :style="newStyleStr || node.styleStr"
+ :data-src="node.attr.src"
+ :src="node.attr.src"
+ @tap="wxParseImgTap"
+ @load="wxParseImgLoad"
+ />
+</template>
+
+<script>
+export default {
+ name: 'wxParseImg',
+ data() {
+ return {
+ newStyleStr: '',
+ preview: true
+ };
+ },
+ inject: ['parseWidth'],
+ mounted() {},
+ props: {
+ node: {
+ type: Object,
+ default() {
+ return {};
+ }
+ }
+ },
+
+ methods: {
+ wxParseImgTap(e) {
+ if (!this.preview) return;
+ const { src } = e.currentTarget.dataset;
+ if (!src) return;
+ let parent = this.$parent;
+ while (!parent.preview || typeof parent.preview !== 'function') {
+ // TODO 遍历获取父节点执行方法
+ parent = parent.$parent;
+ }
+ parent.preview(src, e);
+ },
+ // 图片视觉宽高计算函数区
+ wxParseImgLoad(e) {
+ const { src } = e.currentTarget.dataset;
+ if (!src) return;
+ let { width, height } = e.mp.detail;
+
+ const recal = this.wxAutoImageCal(width, height);
+
+ const { imageheight, imageWidth } = recal;
+ const { padding, mode } = this.node.attr;//删除padding
+ // const { mode } = this.node.attr;
+
+ const { styleStr } = this.node;
+ const imageHeightStyle = mode === 'widthFix' ? '' : `height: ${imageheight}px;`;
+
+ if(!styleStr) this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px; padding: 0 ${+padding}px;`;//删除padding
+ // this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px;`;
+ },
+ // 计算视觉优先的图片宽高
+ wxAutoImageCal(originalWidth, originalHeight) {
+ // 获取图片的原始长宽
+ const windowWidth = this.parseWidth.value;
+ const results = {};
+
+ if (originalWidth < 60 || originalHeight < 60) {
+ const { src } = this.node.attr;
+ let parent = this.$parent;
+ while (!parent.preview || typeof parent.preview !== 'function') {
+ parent = parent.$parent;
+ }
+ parent.removeImageUrl(src);
+ this.preview = false;
+ }
+
+ // 判断按照那种方式进行缩放
+ if (originalWidth > windowWidth) {
+ // 在图片width大于手机屏幕width时候
+ results.imageWidth = windowWidth;
+ results.imageheight = windowWidth * (originalHeight / originalWidth);
+ } else {
+ // 否则展示原来的数据
+ results.imageWidth = originalWidth;
+ results.imageheight = originalHeight;
+ }
+ return results;
+ }
+ }
+};
+</script>
diff --git a/components/feng-parse/components/wxParseTable.vue b/components/feng-parse/components/wxParseTable.vue
new file mode 100644
index 0000000..18278c9
--- /dev/null
+++ b/components/feng-parse/components/wxParseTable.vue
@@ -0,0 +1,56 @@
+<template>
+ <div class='tablebox'>
+ <rich-text :nodes="nodes" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text>
+ </div>
+</template>
+<script>
+export default {
+ name: 'wxParseTable',
+ props: {
+ node: {
+ type: Object,
+ default() {
+ return {};
+ },
+ },
+ },
+ inject: ['parseSelect'],
+ data() {
+ return {
+ nodes:[]
+ };
+ },
+ mounted() {
+ this.nodes=this.loadNode([this.node]);
+ },
+ methods: {
+ loadNode(node) {
+ console.log(node)
+ let obj = [];
+ for (let children of node) {
+ if (children.node=='element') {
+ let t = {
+ name:children.tag,
+ attrs: {
+ class: children.classStr,
+ style: children.styleStr,
+ },
+ children: children.nodes?this.loadNode(children.nodes):[]
+ }
+
+ obj.push(t)
+ } else if(children.node=='text'){
+ obj.push({
+ type: 'text',
+ text: children.text
+ })
+ }
+ }
+ return obj
+ }
+ }
+};
+</script>
+<style>
+ @import url("../parse.css");
+</style>
\ No newline at end of file
diff --git a/components/feng-parse/components/wxParseTemplate0.vue b/components/feng-parse/components/wxParseTemplate0.vue
new file mode 100644
index 0000000..5cbe790
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate0.vue
@@ -0,0 +1,116 @@
+<template>
+ <!--判断是否是标签节点-->
+ <block v-if="node.node == 'element'">
+ <!--button类型-->
+ <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+ <wx-parse-template :node="node" />
+ </button>
+
+ <!--a类型-->
+ <view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--li类型-->
+ <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--table类型-->
+ <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+
+ <!--br类型-->
+ <!-- #ifndef H5 -->
+ <text v-else-if="node.tag == 'br'">\n</text>
+ <!-- #endif -->
+ <!-- #ifdef H5 -->
+ <br v-else-if="node.tag == 'br'">
+ <!-- #endif -->
+
+ <!--video类型-->
+ <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+
+ <!--audio类型-->
+ <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+
+ <!--img类型-->
+ <wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+
+ <!--strong标签-->
+ <view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--span标签-->
+ <view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--em标签-->
+ <view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--其他标签-->
+ <view v-else :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ </block>
+
+ <!--判断是否是文本节点-->
+ <block v-else-if="node.node == 'text'">{{node.text}}</block>
+</template>
+
+<script>
+ // #ifdef APP-PLUS | H5
+ import wxParseTemplate from './wxParseTemplate0';
+ // #endif
+ // #ifdef MP
+ import wxParseTemplate from './wxParseTemplate1';
+ // #endif
+ import wxParseImg from './wxParseImg';
+ import wxParseVideo from './wxParseVideo';
+ import wxParseAudio from './wxParseAudio';
+ import wxParseTable from './wxParseTable';
+
+ export default {
+ // #ifdef APP-PLUS | H5
+ name: 'wxParseTemplate',
+ // #endif
+ // #ifdef MP
+ name: 'wxParseTemplate0',
+ // #endif
+ props: {
+ node: {},
+ },
+ components: {
+ wxParseTemplate,
+ wxParseImg,
+ wxParseVideo,
+ wxParseAudio,
+ wxParseTable
+ },
+ methods: {
+ wxParseATap(attr,e) {
+ const {
+ href
+ } = e.currentTarget.dataset;// TODO currentTarget才有dataset
+ if (!href) return;
+ let parent = this.$parent;
+ while(!parent.preview || typeof parent.preview !== 'function') {// TODO 遍历获取父节点执行方法
+ parent = parent.$parent;
+ }
+ parent.navigate(href, e, attr);
+ }
+ }
+ };
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate1.vue b/components/feng-parse/components/wxParseTemplate1.vue
new file mode 100644
index 0000000..70779e3
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate1.vue
@@ -0,0 +1,107 @@
+<template>
+ <!--判断是否是标签节点-->
+ <block v-if="node.node == 'element'">
+ <!--button类型-->
+ <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+ <wx-parse-template :node="node" />
+ </button>
+
+ <!--a类型-->
+ <view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--li类型-->
+ <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--table类型-->
+ <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+
+ <!--br类型-->
+ <!-- #ifndef H5 -->
+ <text v-else-if="node.tag == 'br'">\n</text>
+ <!-- #endif -->
+ <!-- #ifdef H5 -->
+ <br v-else-if="node.tag == 'br'">
+ <!-- #endif -->
+
+ <!--strong标签-->
+ <view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--span标签-->
+ <view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--em标签-->
+ <view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+
+ <!--video类型-->
+ <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+
+ <!--audio类型-->
+ <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+
+ <!--img类型-->
+ <wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+
+ <!--其他标签-->
+ <view v-else :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+ </block>
+
+ <!--判断是否是文本节点-->
+ <block v-else-if="node.node == 'text'">{{node.text}}</block>
+</template>
+
+<script>
+ import wxParseTemplate from './wxParseTemplate2';
+ import wxParseImg from './wxParseImg';
+ import wxParseVideo from './wxParseVideo';
+ import wxParseAudio from './wxParseAudio';
+ import wxParseTable from './wxParseTable';
+
+ export default {
+ name: 'wxParseTemplate1',
+ props: {
+ node: {},
+ },
+ components: {
+ wxParseTemplate,
+ wxParseImg,
+ wxParseVideo,
+ wxParseAudio,
+ wxParseTable
+ },
+ methods: {
+ wxParseATap(attr,e) {
+ const {
+ href
+ } = e.currentTarget.dataset;
+ if (!href) return;
+ let parent = this.$parent;
+ while(!parent.preview || typeof parent.preview !== 'function') {
+ parent = parent.$parent;
+ }
+ parent.navigate(href, e, attr);
+ }
+ }
+ };
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate10.vue b/components/feng-parse/components/wxParseTemplate10.vue
new file mode 100644
index 0000000..891c8c3
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate10.vue
@@ -0,0 +1,107 @@
+<template>
+ <!--判断是否是标签节点-->
+ <block v-if="node.node == 'element'">
+ <!--button类型-->
+ <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+ <wx-parse-template :node="node" />
+ </button>
+
+ <!--a类型-->
+ <view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--li类型-->
+ <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--table类型-->
+ <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+
+ <!--br类型-->
+ <!-- #ifndef H5 -->
+ <text v-else-if="node.tag == 'br'">\n</text>
+ <!-- #endif -->
+ <!-- #ifdef H5 -->
+ <br v-else-if="node.tag == 'br'">
+ <!-- #endif -->
+
+ <!--video类型-->
+ <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+
+ <!--audio类型-->
+ <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+
+ <!--img类型-->
+ <wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+
+ <!--strong标签-->
+ <view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--span标签-->
+ <view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--em标签-->
+ <view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+
+ <!--其他标签-->
+ <view v-else :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+ </block>
+
+ <!--判断是否是文本节点-->
+ <block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+ import wxParseTemplate from './wxParseTemplate11';
+ import wxParseImg from './wxParseImg';
+ import wxParseVideo from './wxParseVideo';
+ import wxParseAudio from './wxParseAudio';
+ import wxParseTable from './wxParseTable';
+
+ export default {
+ name: 'wxParseTemplate10',
+ props: {
+ node: {},
+ },
+ components: {
+ wxParseTemplate,
+ wxParseImg,
+ wxParseVideo,
+ wxParseAudio,
+ wxParseTable
+ },
+ methods: {
+ wxParseATap(attr,e) {
+ const {
+ href
+ } = e.currentTarget.dataset;
+ if (!href) return;
+ let parent = this.$parent;
+ while(!parent.preview || typeof parent.preview !== 'function') {
+ parent = parent.$parent;
+ }
+ parent.navigate(href, e, attr);
+ }
+ }
+ };
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate11.vue b/components/feng-parse/components/wxParseTemplate11.vue
new file mode 100644
index 0000000..d38efbd
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate11.vue
@@ -0,0 +1,105 @@
+<template>
+ <!--判断是否是标签节点-->
+ <block v-if="node.node == 'element'">
+ <!--button类型-->
+ <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+ <rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text>
+ </button>
+
+ <!--a类型-->
+ <view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--li类型-->
+ <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text>
+ </block>
+ </view>
+
+ <!--table类型-->
+ <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+
+ <!--br类型-->
+ <!-- #ifndef H5 -->
+ <text v-else-if="node.tag == 'br'">\n</text>
+ <!-- #endif -->
+ <!-- #ifdef H5 -->
+ <br v-else-if="node.tag == 'br'">
+ <!-- #endif -->
+
+ <!--video类型-->
+ <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+
+ <!--audio类型-->
+ <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+
+ <!--img类型-->
+ <wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
+
+ <!--strong标签-->
+ <view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--span标签-->
+ <view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--em标签-->
+ <view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+
+ <!--其他标签-->
+ <view v-else :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text>
+ </block>
+ </view>
+ </block>
+
+ <!--判断是否是文本节点-->
+ <block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+ import wxParseImg from './wxParseImg';
+ import wxParseVideo from './wxParseVideo';
+ import wxParseAudio from './wxParseAudio';
+ import wxParseTable from './wxParseTable';
+
+ export default {
+ name: 'wxParseTemplate11',
+ props: {
+ node: {},
+ },
+ components: {
+ wxParseImg,
+ wxParseVideo,
+ wxParseAudio,
+ wxParseTable
+ },
+ methods: {
+ wxParseATap(attr,e) {
+ const {
+ href
+ } = e.currentTarget.dataset;
+ if (!href) return;
+ let parent = this.$parent;
+ while(!parent.preview || typeof parent.preview !== 'function') {
+ parent = parent.$parent;
+ }
+ parent.navigate(href, e, attr);
+ }
+ }
+ };
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate2.vue b/components/feng-parse/components/wxParseTemplate2.vue
new file mode 100644
index 0000000..c68b226
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate2.vue
@@ -0,0 +1,107 @@
+<template>
+ <!--判断是否是标签节点-->
+ <block v-if="node.node == 'element'">
+ <!--button类型-->
+ <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+ <wx-parse-template :node="node" />
+ </button>
+
+ <!--a类型-->
+ <view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--li类型-->
+ <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--table类型-->
+ <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+
+ <!--br类型-->
+ <!-- #ifndef H5 -->
+ <text v-else-if="node.tag == 'br'">\n</text>
+ <!-- #endif -->
+ <!-- #ifdef H5 -->
+ <br v-else-if="node.tag == 'br'">
+ <!-- #endif -->
+
+ <!--video类型-->
+ <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+
+ <!--audio类型-->
+ <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+
+ <!--img类型-->
+ <wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+
+ <!--strong标签-->
+ <view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--span标签-->
+ <view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--em标签-->
+ <view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+
+ <!--其他标签-->
+ <view v-else :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+ </block>
+
+ <!--判断是否是文本节点-->
+ <block v-else-if="node.node == 'text'">{{node.text}}</block>
+</template>
+
+<script>
+ import wxParseTemplate from './wxParseTemplate3';
+ import wxParseImg from './wxParseImg';
+ import wxParseVideo from './wxParseVideo';
+ import wxParseAudio from './wxParseAudio';
+ import wxParseTable from './wxParseTable';
+
+ export default {
+ name: 'wxParseTemplate2',
+ props: {
+ node: {},
+ },
+ components: {
+ wxParseTemplate,
+ wxParseImg,
+ wxParseVideo,
+ wxParseAudio,
+ wxParseTable
+ },
+ methods: {
+ wxParseATap(attr,e) {
+ const {
+ href
+ } = e.currentTarget.dataset;
+ if (!href) return;
+ let parent = this.$parent;
+ while(!parent.preview || typeof parent.preview !== 'function') {
+ parent = parent.$parent;
+ }
+ parent.navigate(href, e, attr);
+ }
+ }
+ };
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate3.vue b/components/feng-parse/components/wxParseTemplate3.vue
new file mode 100644
index 0000000..1a1bb29
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate3.vue
@@ -0,0 +1,107 @@
+<template>
+ <!--判断是否是标签节点-->
+ <block v-if="node.node == 'element'">
+ <!--button类型-->
+ <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+ <wx-parse-template :node="node" />
+ </button>
+
+ <!--a类型-->
+ <view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--li类型-->
+ <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--table类型-->
+ <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+
+ <!--br类型-->
+ <!-- #ifndef H5 -->
+ <text v-else-if="node.tag == 'br'">\n</text>
+ <!-- #endif -->
+ <!-- #ifdef H5 -->
+ <br v-else-if="node.tag == 'br'">
+ <!-- #endif -->
+
+ <!--strong标签-->
+ <view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--span标签-->
+ <view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--em标签-->
+ <view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+
+ <!--video类型-->
+ <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+
+ <!--audio类型-->
+ <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+
+ <!--img类型-->
+ <wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+
+ <!--其他标签-->
+ <view v-else :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+ </block>
+
+ <!--判断是否是文本节点-->
+ <block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+ import wxParseTemplate from './wxParseTemplate4';
+ import wxParseImg from './wxParseImg';
+ import wxParseVideo from './wxParseVideo';
+ import wxParseAudio from './wxParseAudio';
+ import wxParseTable from './wxParseTable';
+
+ export default {
+ name: 'wxParseTemplate3',
+ props: {
+ node: {},
+ },
+ components: {
+ wxParseTemplate,
+ wxParseImg,
+ wxParseVideo,
+ wxParseAudio,
+ wxParseTable
+ },
+ methods: {
+ wxParseATap(attr,e) {
+ const {
+ href
+ } = e.currentTarget.dataset;
+ if (!href) return;
+ let parent = this.$parent;
+ while(!parent.preview || typeof parent.preview !== 'function') {
+ parent = parent.$parent;
+ }
+ parent.navigate(href, e, attr);
+ }
+ }
+ };
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate4.vue b/components/feng-parse/components/wxParseTemplate4.vue
new file mode 100644
index 0000000..c3497b8
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate4.vue
@@ -0,0 +1,107 @@
+<template>
+ <!--判断是否是标签节点-->
+ <block v-if="node.node == 'element'">
+ <!--button类型-->
+ <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+ <wx-parse-template :node="node" />
+ </button>
+
+ <!--a类型-->
+ <view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--li类型-->
+ <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--table类型-->
+ <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+
+ <!--br类型-->
+ <!-- #ifndef H5 -->
+ <text v-else-if="node.tag == 'br'">\n</text>
+ <!-- #endif -->
+ <!-- #ifdef H5 -->
+ <br v-else-if="node.tag == 'br'">
+ <!-- #endif -->
+
+ <!--video类型-->
+ <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+
+ <!--audio类型-->
+ <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+
+ <!--img类型-->
+ <wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+
+ <!--strong标签-->
+ <view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--span标签-->
+ <view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--em标签-->
+ <view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+
+ <!--其他标签-->
+ <view v-else :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+ </block>
+
+ <!--判断是否是文本节点-->
+ <block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+ import wxParseTemplate from './wxParseTemplate5';
+ import wxParseImg from './wxParseImg';
+ import wxParseVideo from './wxParseVideo';
+ import wxParseAudio from './wxParseAudio';
+ import wxParseTable from './wxParseTable';
+
+ export default {
+ name: 'wxParseTemplate4',
+ props: {
+ node: {},
+ },
+ components: {
+ wxParseTemplate,
+ wxParseImg,
+ wxParseVideo,
+ wxParseAudio,
+ wxParseTable
+ },
+ methods: {
+ wxParseATap(attr,e) {
+ const {
+ href
+ } = e.currentTarget.dataset;
+ if (!href) return;
+ let parent = this.$parent;
+ while(!parent.preview || typeof parent.preview !== 'function') {
+ parent = parent.$parent;
+ }
+ parent.navigate(href, e, attr);
+ }
+ }
+ };
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate5.vue b/components/feng-parse/components/wxParseTemplate5.vue
new file mode 100644
index 0000000..5e66618
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate5.vue
@@ -0,0 +1,107 @@
+<template>
+ <!--判断是否是标签节点-->
+ <block v-if="node.node == 'element'">
+ <!--button类型-->
+ <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+ <wx-parse-template :node="node" />
+ </button>
+
+ <!--a类型-->
+ <view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--li类型-->
+ <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--table类型-->
+ <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+
+ <!--br类型-->
+ <!-- #ifndef H5 -->
+ <text v-else-if="node.tag == 'br'">\n</text>
+ <!-- #endif -->
+ <!-- #ifdef H5 -->
+ <br v-else-if="node.tag == 'br'">
+ <!-- #endif -->
+
+ <!--video类型-->
+ <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+
+ <!--audio类型-->
+ <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+
+ <!--img类型-->
+ <wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+
+ <!--strong标签-->
+ <view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--span标签-->
+ <view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--em标签-->
+ <view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+
+ <!--其他标签-->
+ <view v-else :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+ </block>
+
+ <!--判断是否是文本节点-->
+ <block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+ import wxParseTemplate from './wxParseTemplate6';
+ import wxParseImg from './wxParseImg';
+ import wxParseVideo from './wxParseVideo';
+ import wxParseAudio from './wxParseAudio';
+ import wxParseTable from './wxParseTable';
+
+ export default {
+ name: 'wxParseTemplate5',
+ props: {
+ node: {},
+ },
+ components: {
+ wxParseTemplate,
+ wxParseImg,
+ wxParseVideo,
+ wxParseAudio,
+ wxParseTable
+ },
+ methods: {
+ wxParseATap(attr,e) {
+ const {
+ href
+ } = e.currentTarget.dataset;
+ if (!href) return;
+ let parent = this.$parent;
+ while(!parent.preview || typeof parent.preview !== 'function') {
+ parent = parent.$parent;
+ }
+ parent.navigate(href, e, attr);
+ }
+ }
+ };
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate6.vue b/components/feng-parse/components/wxParseTemplate6.vue
new file mode 100644
index 0000000..dc44621
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate6.vue
@@ -0,0 +1,107 @@
+<template>
+ <!--判断是否是标签节点-->
+ <block v-if="node.node == 'element'">
+ <!--button类型-->
+ <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+ <wx-parse-template :node="node" />
+ </button>
+
+ <!--a类型-->
+ <view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--li类型-->
+ <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--table类型-->
+ <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+
+ <!--br类型-->
+ <!-- #ifndef H5 -->
+ <text v-else-if="node.tag == 'br'">\n</text>
+ <!-- #endif -->
+ <!-- #ifdef H5 -->
+ <br v-else-if="node.tag == 'br'">
+ <!-- #endif -->
+
+ <!--video类型-->
+ <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+
+ <!--audio类型-->
+ <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+
+ <!--img类型-->
+ <wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+
+ <!--strong标签-->
+ <view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--span标签-->
+ <view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--em标签-->
+ <view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+
+ <!--其他标签-->
+ <view v-else :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+ </block>
+
+ <!--判断是否是文本节点-->
+ <block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+ import wxParseTemplate from './wxParseTemplate7';
+ import wxParseImg from './wxParseImg';
+ import wxParseVideo from './wxParseVideo';
+ import wxParseAudio from './wxParseAudio';
+ import wxParseTable from './wxParseTable';
+
+ export default {
+ name: 'wxParseTemplate6',
+ props: {
+ node: {},
+ },
+ components: {
+ wxParseTemplate,
+ wxParseImg,
+ wxParseVideo,
+ wxParseAudio,
+ wxParseTable
+ },
+ methods: {
+ wxParseATap(attr,e) {
+ const {
+ href
+ } = e.currentTarget.dataset;
+ if (!href) return;
+ let parent = this.$parent;
+ while(!parent.preview || typeof parent.preview !== 'function') {
+ parent = parent.$parent;
+ }
+ parent.navigate(href, e, attr);
+ }
+ }
+ };
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate7.vue b/components/feng-parse/components/wxParseTemplate7.vue
new file mode 100644
index 0000000..71636dc
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate7.vue
@@ -0,0 +1,107 @@
+<template>
+ <!--判断是否是标签节点-->
+ <block v-if="node.node == 'element'">
+ <!--button类型-->
+ <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+ <wx-parse-template :node="node" />
+ </button>
+
+ <!--a类型-->
+ <view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--li类型-->
+ <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--table类型-->
+ <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+
+ <!--br类型-->
+ <!-- #ifndef H5 -->
+ <text v-else-if="node.tag == 'br'">\n</text>
+ <!-- #endif -->
+ <!-- #ifdef H5 -->
+ <br v-else-if="node.tag == 'br'">
+ <!-- #endif -->
+
+ <!--video类型-->
+ <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+
+ <!--audio类型-->
+ <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+
+ <!--img类型-->
+ <wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+
+ <!--strong标签-->
+ <view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--span标签-->
+ <view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--em标签-->
+ <view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+
+ <!--其他标签-->
+ <view v-else :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+ </block>
+
+ <!--判断是否是文本节点-->
+ <block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+ import wxParseTemplate from './wxParseTemplate8';
+ import wxParseImg from './wxParseImg';
+ import wxParseVideo from './wxParseVideo';
+ import wxParseAudio from './wxParseAudio';
+ import wxParseTable from './wxParseTable';
+
+ export default {
+ name: 'wxParseTemplate7',
+ props: {
+ node: {},
+ },
+ components: {
+ wxParseTemplate,
+ wxParseImg,
+ wxParseVideo,
+ wxParseAudio,
+ wxParseTable
+ },
+ methods: {
+ wxParseATap(attr,e) {
+ const {
+ href
+ } = e.currentTarget.dataset;
+ if (!href) return;
+ let parent = this.$parent;
+ while(!parent.preview || typeof parent.preview !== 'function') {
+ parent = parent.$parent;
+ }
+ parent.navigate(href, e, attr);
+ }
+ }
+ };
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate8.vue b/components/feng-parse/components/wxParseTemplate8.vue
new file mode 100644
index 0000000..326115d
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate8.vue
@@ -0,0 +1,107 @@
+<template>
+ <!--判断是否是标签节点-->
+ <block v-if="node.node == 'element'">
+ <!--button类型-->
+ <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+ <wx-parse-template :node="node" />
+ </button>
+
+ <!--a类型-->
+ <view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--li类型-->
+ <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--table类型-->
+ <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+
+ <!--br类型-->
+ <!-- #ifndef H5 -->
+ <text v-else-if="node.tag == 'br'">\n</text>
+ <!-- #endif -->
+ <!-- #ifdef H5 -->
+ <br v-else-if="node.tag == 'br'">
+ <!-- #endif -->
+
+ <!--video类型-->
+ <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+
+ <!--audio类型-->
+ <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+
+ <!--img类型-->
+ <wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+
+ <!--strong标签-->
+ <view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--span标签-->
+ <view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--em标签-->
+ <view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+
+ <!--其他标签-->
+ <view v-else :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+ </block>
+
+ <!--判断是否是文本节点-->
+ <block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+ import wxParseTemplate from './wxParseTemplate9';
+ import wxParseImg from './wxParseImg';
+ import wxParseVideo from './wxParseVideo';
+ import wxParseAudio from './wxParseAudio';
+ import wxParseTable from './wxParseTable';
+
+ export default {
+ name: 'wxParseTemplate8',
+ props: {
+ node: {},
+ },
+ components: {
+ wxParseTemplate,
+ wxParseImg,
+ wxParseVideo,
+ wxParseAudio,
+ wxParseTable
+ },
+ methods: {
+ wxParseATap(attr,e) {
+ const {
+ href
+ } = e.currentTarget.dataset;
+ if (!href) return;
+ let parent = this.$parent;
+ while(!parent.preview || typeof parent.preview !== 'function') {
+ parent = parent.$parent;
+ }
+ parent.navigate(href, e, attr);
+ }
+ }
+ };
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate9.vue b/components/feng-parse/components/wxParseTemplate9.vue
new file mode 100644
index 0000000..f1224a3
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate9.vue
@@ -0,0 +1,107 @@
+<template>
+ <!--判断是否是标签节点-->
+ <block v-if="node.node == 'element'">
+ <!--button类型-->
+ <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+ <wx-parse-template :node="node" />
+ </button>
+
+ <!--a类型-->
+ <view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--li类型-->
+ <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+
+ <!--table类型-->
+ <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+
+ <!--br类型-->
+ <!-- #ifndef H5 -->
+ <text v-else-if="node.tag == 'br'">\n</text>
+ <!-- #endif -->
+ <!-- #ifdef H5 -->
+ <br v-else-if="node.tag == 'br'">
+ <!-- #endif -->
+
+ <!--video类型-->
+ <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+
+ <!--audio类型-->
+ <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+
+ <!--img类型-->
+ <wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+
+ <!--strong标签-->
+ <view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--span标签-->
+ <view v-else-if="node.tag == 'span'" :class="node.classStr" :style="node.styleStr" style="display: inline;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+ <!--em标签-->
+ <view v-else-if="node.tag == 'em'" :class="node.classStr" :style="node.styleStr" style="display: inline;font-style: italic;">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node"/>
+ </block>
+ </view>
+
+ <!--其他标签-->
+ <view v-else :class="node.classStr" :style="node.styleStr">
+ <block v-for="(node, index) of node.nodes" :key="index">
+ <wx-parse-template :node="node" />
+ </block>
+ </view>
+ </block>
+
+ <!--判断是否是文本节点-->
+ <block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+ import wxParseTemplate from './wxParseTemplate10';
+ import wxParseImg from './wxParseImg';
+ import wxParseVideo from './wxParseVideo';
+ import wxParseAudio from './wxParseAudio';
+ import wxParseTable from './wxParseTable';
+
+ export default {
+ name: 'wxParseTemplate9',
+ props: {
+ node: {},
+ },
+ components: {
+ wxParseTemplate,
+ wxParseImg,
+ wxParseVideo,
+ wxParseAudio,
+ wxParseTable
+ },
+ methods: {
+ wxParseATap(attr,e) {
+ const {
+ href
+ } = e.currentTarget.dataset;
+ if (!href) return;
+ let parent = this.$parent;
+ while(!parent.preview || typeof parent.preview !== 'function') {
+ parent = parent.$parent;
+ }
+ parent.navigate(href, e, attr);
+ }
+ }
+ };
+</script>
diff --git a/components/feng-parse/components/wxParseVideo.vue b/components/feng-parse/components/wxParseVideo.vue
new file mode 100644
index 0000000..1cd9b70
--- /dev/null
+++ b/components/feng-parse/components/wxParseVideo.vue
@@ -0,0 +1,55 @@
+<template>
+ <!-- 这个模板用来解决原生video总是浮在最上层的问题,使用view替换video,播放是再替换回,监听一个事件,用来被遮盖时做替换video -->
+ <!--增加video标签支持,并循环添加-->
+ <view @click="play">
+ <view v-if="!playState" :class="node.classStr" :style="node.styleStr" style="display: inline-block;margin: auto;max-width: 100%;" class="video-video">
+ <view style="display: flex;width: 100%;height:100%;flex-direction: row; justify-content: center;align-items: center;">
+ <image src="https://gwbj.tongwenkeji.com/html/static/play.png" style="width: 20%;" mode="widthFix"></image>
+ </view>
+ </view>
+ <video
+ :autoplay="false"
+ :class="node.classStr"
+ :style="node.styleStr"
+ class="video-video"
+ v-if="playState"
+ :src="node.attr.src"></video>
+
+ </view>
+
+</template>
+
+<script>
+export default {
+ name: 'wxParseVideo',
+ props: {
+ node: {},
+ },
+ data(){
+ return{
+ playState:true,
+ videoStyle:'width: 100%;'
+ }
+ },
+ methods:{
+ play(){
+ console.log('点击了video 播放')
+ //显示播放器并播放播放器
+ this.playState = !this.playState
+ }
+ },
+ mounted() {
+ //捕获侧滑菜单的遮盖行为,隐藏video
+ uni.$on('slideMenuShow',e=>{
+ console.log('捕获事件:'+e)
+ if(e == 'show' && this.playState){
+ //正在播放则停止
+ this.playState = false
+ }
+ })
+ }
+};
+</script>
+<style>
+ .video-video{background: #000000;}
+</style>
diff --git a/components/feng-parse/components/wxParseVideo1.vue b/components/feng-parse/components/wxParseVideo1.vue
new file mode 100644
index 0000000..0d37e10
--- /dev/null
+++ b/components/feng-parse/components/wxParseVideo1.vue
@@ -0,0 +1,25 @@
+<template>
+ <!-- 这个模板用来渲染原生video -->
+ <!--增加video标签支持,并循环添加-->
+ <view style="max-width: 100%;">
+ <video
+ :autoplay="playState"
+ :class="node.classStr"
+ :style="node.styleStr"
+ class="video-video"
+ v-if="playState"
+ :src="node.attr.src"></video>
+ </view>
+</template>
+
+<script>
+export default {
+ name: 'wxParseVideo',
+ props: {
+ node: {},
+ }
+};
+</script>
+<style>
+ .video-video{z-index: 1;}
+</style>
diff --git a/components/feng-parse/libs/html2json.js b/components/feng-parse/libs/html2json.js
new file mode 100644
index 0000000..bf3082d
--- /dev/null
+++ b/components/feng-parse/libs/html2json.js
@@ -0,0 +1,308 @@
+/**
+ * html2Json 改造来自: https://github.com/Jxck/html2json
+ *
+ *
+ * author: Di (微信小程序开发工程师)
+ * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
+ * 垂直微信小程序开发交流社区
+ *
+ * github地址: https://github.com/icindy/wxParse
+ *
+ * for: 微信小程序富文本解析
+ * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
+ */
+
+import wxDiscode from './wxDiscode';
+import HTMLParser from './htmlparser';
+
+function makeMap(str) {
+ const obj = {};
+ const items = str.split(',');
+ for (let i = 0; i < items.length; i += 1) obj[items[i]] = true;
+ return obj;
+}
+
+// Block Elements - HTML 5
+const block = makeMap(
+ 'br,code,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'
+);
+
+// Inline Elements - HTML 5
+const inline = makeMap(
+ 'a,abbr,acronym,applet,b,basefont,bdo,big,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'
+);
+
+// Elements that you can, intentionally, leave open
+// (and which close themselves)
+const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');
+
+function removeDOCTYPE(html) {
+ const isDocument = /<body.*>([^]*)<\/body>/.test(html);
+ return isDocument ? RegExp.$1 : html;
+}
+
+function trimHtml(html) {
+ return html
+ .replace(/<!--.*?-->/gi, '')
+ .replace(/\/\*.*?\*\//gi, '')
+ // .replace(/[ ]+</gi, '<')
+ .replace(/<script[^]*<\/script>/gi, '')
+ .replace(/<style[^]*<\/style>/gi, '');
+}
+
+function getScreenInfo() {
+ const screen = {};
+ wx.getSystemInfo({
+ success: (res) => {
+ screen.width = res.windowWidth;
+ screen.height = res.windowHeight;
+ },
+ });
+ return screen;
+}
+
+function html2json(html, customHandler, imageProp, host) {
+ // 处理字符串
+ html = removeDOCTYPE(html);
+ html = trimHtml(html);
+ html = wxDiscode.strDiscode(html);
+ // 生成node节点
+ const bufArray = [];
+ const results = {
+ nodes: [],
+ imageUrls: [],
+ };
+
+ const screen = getScreenInfo();
+
+ function Node(tag) {
+ this.node = 'element';
+ this.tag = tag;
+
+ this.$screen = screen;
+ }
+
+ HTMLParser(html, {
+ start(tag, attrs, unary) {
+ // node for this element
+ const node = new Node(tag);
+
+ if (bufArray.length !== 0) {
+ const parent = bufArray[0];
+ if (parent.nodes === undefined) {
+ parent.nodes = [];
+ }
+ }
+
+ if (block[tag]) {
+ node.tagType = 'block';
+ } else if (inline[tag]) {
+ node.tagType = 'inline';
+ } else if (closeSelf[tag]) {
+ node.tagType = 'closeSelf';
+ }
+
+ node.attr = attrs.reduce((pre, attr) => {
+ const {
+ name
+ } = attr;
+ let {
+ value
+ } = attr;
+ if (name === 'class') {
+ node.classStr = value;
+ }
+ // has multi attibutes
+ // make it array of attribute
+ if (name === 'style') {
+ node.styleStr = value;
+ }
+ if (value.match(/ /)) {
+ value = value.split(' ');
+ }
+
+ // if attr already exists
+ // merge it
+ if (pre[name]) {
+ if (Array.isArray(pre[name])) {
+ // already array, push to last
+ pre[name].push(value);
+ } else {
+ // single value, make it array
+ pre[name] = [pre[name], value];
+ }
+ } else {
+ // not exist, put it
+ pre[name] = value;
+ }
+
+ return pre;
+ }, {});
+
+ // 优化样式相关属性
+ if (node.classStr) {
+ node.classStr += ` ${node.tag}`;
+ } else {
+ node.classStr = node.tag;
+ }
+ if (node.tagType === 'inline') {
+ node.classStr += ' inline';
+ }
+
+ // 对img添加额外数据
+ if (node.tag === 'img') {
+ let imgUrl = node.attr.src;
+ imgUrl = wxDiscode.urlToHttpUrl(imgUrl, imageProp.domain);
+ Object.assign(node.attr, imageProp, {
+ src: imgUrl || '',
+ });
+ if (imgUrl) {
+ results.imageUrls.push(imgUrl);
+ }
+ }
+
+ // 处理a标签属性
+ if (node.tag === 'a') {
+ node.attr.href = node.attr.href || '';
+ }
+
+ //处理table
+ if (node.tag === 'table' || node.tag === 'tr' || node.tag === 'td') {
+ node.styleStr = ""
+ if (node.attr.width) {
+ node.styleStr += "width:" + node.attr.width + 'px;'
+ if (node.attr.width > node.$screen.width) {
+ //等比缩放height
+ if (node.attr.height) {
+ node.attr.height = (node.$screen.width * node.attr.height) / node.attr.width
+ }
+ }
+ }
+ if (node.attr.height) {
+ node.styleStr += "height:" + node.attr.height + 'px;'
+ }
+
+ }
+ //处理video
+ if (node.tag === 'video') {
+ node.styleStr = ""
+ if (node.attr.width) {
+ node.styleStr += "width:" + node.attr.width + 'px;'
+ if (node.attr.width > node.$screen.width) {
+ //等比缩放height
+ if (node.attr.height) {
+ node.attr.height = (node.$screen.width * node.attr.height) / node.attr.width
+ }
+ }
+ }
+ if (node.attr.height) {
+ node.styleStr += "height:" + node.attr.height + 'px;'
+ }
+
+ }
+
+ // 处理font标签样式属性
+ if (node.tag === 'font') {
+ const fontSize = [
+ 'x-small',
+ 'small',
+ 'medium',
+ 'large',
+ 'x-large',
+ 'xx-large',
+ '-webkit-xxx-large',
+ ];
+ const styleAttrs = {
+ color: 'color',
+ face: 'font-family',
+ size: 'font-size',
+ };
+ if (!node.styleStr) node.styleStr = '';
+ Object.keys(styleAttrs).forEach((key) => {
+ if (node.attr[key]) {
+ const value = key === 'size' ? fontSize[node.attr[key] - 1] : node.attr[key];
+ node.styleStr += `${styleAttrs[key]}: ${value};`;
+ }
+ });
+ }
+
+ // 临时记录source资源
+ if (node.tag === 'source') {
+ results.source = node.attr.src;
+ }
+ //#ifndef MP-BAIDU
+ if (customHandler.start) {
+ customHandler.start(node, results);
+ }
+ //#endif
+
+ if (unary) {
+ // if this tag doesn't have end tag
+ // like <img src="hoge.png"/>
+ // add to parents
+ const parent = bufArray[0] || results;
+ if (parent.nodes === undefined) {
+ parent.nodes = [];
+ }
+ parent.nodes.push(node);
+ } else {
+ bufArray.unshift(node);
+ }
+ },
+ end(tag) {
+ // merge into parent tag
+ const node = bufArray.shift();
+ if (node.tag !== tag) {
+ console.error('invalid state: mismatch end tag');
+ }
+
+ // 当有缓存source资源时于于video补上src资源
+ if (node.tag === 'video' && results.source) {
+ node.attr.src = results.source;
+ delete results.source;
+ }
+ //#ifndef MP-BAIDU
+ if (customHandler && customHandler.end) {
+ customHandler.end(node, results);
+ }
+ //#endif
+
+ if (bufArray.length === 0) {
+ results.nodes.push(node);
+ } else {
+ const parent = bufArray[0];
+ if (!parent.nodes) {
+ parent.nodes = [];
+ }
+ parent.nodes.push(node);
+ }
+ },
+ chars(text) {
+ if (!text.trim()) return;
+
+ const node = {
+ node: 'text',
+ text,
+ };
+ //#ifndef MP-BAIDU
+ if (customHandler.chars) {
+ customHandler.chars(node, results);
+ }
+ //#endif
+
+ if (bufArray.length === 0) {
+ results.nodes.push(node);
+ } else {
+ const parent = bufArray[0];
+ if (parent.nodes === undefined) {
+ parent.nodes = [];
+ }
+ parent.nodes.push(node);
+ }
+ },
+ });
+
+ return results;
+}
+
+export default html2json;
diff --git a/components/feng-parse/libs/htmlparser.js b/components/feng-parse/libs/htmlparser.js
new file mode 100644
index 0000000..2939da3
--- /dev/null
+++ b/components/feng-parse/libs/htmlparser.js
@@ -0,0 +1,156 @@
+/**
+ *
+ * htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser
+ *
+ * author: Di (微信小程序开发工程师)
+ * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
+ * 垂直微信小程序开发交流社区
+ *
+ * github地址: https://github.com/icindy/wxParse
+ *
+ * for: 微信小程序富文本解析
+ * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
+ */
+// Regular Expressions for parsing tags and attributes
+
+const startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z0-9_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
+const endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
+const attr = /([a-zA-Z0-9_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;
+
+function makeMap(str) {
+ const obj = {};
+ const items = str.split(',');
+ for (let i = 0; i < items.length; i += 1) obj[items[i]] = true;
+ return obj;
+}
+
+// Empty Elements - HTML 5
+const empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr');
+
+// Block Elements - HTML 5
+const block = makeMap('address,code,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video');
+
+// Inline Elements - HTML 5
+const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var');
+
+// Elements that you can, intentionally, leave open
+// (and which close themselves)
+const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');
+
+// Attributes that have their values filled in disabled="disabled"
+const fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected');
+
+function HTMLParser(html, handler) {
+ let index;
+ let chars;
+ let match;
+ let last = html;
+ const stack = [];
+
+ stack.last = () => stack[stack.length - 1];
+
+ function parseEndTag(tag, tagName) {
+ // If no tag name is provided, clean shop
+ let pos;
+ if (!tagName) {
+ pos = 0;
+ } else {
+ // Find the closest opened tag of the same type
+ tagName = tagName.toLowerCase();
+ for (pos = stack.length - 1; pos >= 0; pos -= 1) {
+ if (stack[pos] === tagName) break;
+ }
+ }
+ if (pos >= 0) {
+ // Close all the open elements, up the stack
+ for (let i = stack.length - 1; i >= pos; i -= 1) {
+ if (handler.end) handler.end(stack[i]);
+ }
+
+ // Remove the open elements from the stack
+ stack.length = pos;
+ }
+ }
+
+ function parseStartTag(tag, tagName, rest, unary) {
+ tagName = tagName.toLowerCase();
+
+ if (block[tagName]) {
+ while (stack.last() && inline[stack.last()]) {
+ parseEndTag('', stack.last());
+ }
+ }
+
+ if (closeSelf[tagName] && stack.last() === tagName) {
+ parseEndTag('', tagName);
+ }
+
+ unary = empty[tagName] || !!unary;
+
+ if (!unary) stack.push(tagName);
+
+ if (handler.start) {
+ const attrs = [];
+
+ rest.replace(attr, function genAttr(matches, name) {
+ const value = arguments[2] || arguments[3] || arguments[4] || (fillAttrs[name] ? name : '');
+
+ attrs.push({
+ name,
+ value,
+ escaped: value.replace(/(^|[^\\])"/g, '$1\\"'), // "
+ });
+ });
+
+ if (handler.start) {
+ handler.start(tagName, attrs, unary);
+ }
+ }
+ }
+
+ while (html) {
+ chars = true;
+
+ if (html.indexOf('</') === 0) {
+ match = html.match(endTag);
+
+ if (match) {
+ html = html.substring(match[0].length);
+ match[0].replace(endTag, parseEndTag);
+ chars = false;
+ }
+
+ // start tag
+ } else if (html.indexOf('<') === 0) {
+ match = html.match(startTag);
+
+ if (match) {
+ html = html.substring(match[0].length);
+ match[0].replace(startTag, parseStartTag);
+ chars = false;
+ }
+ }
+
+ if (chars) {
+ index = html.indexOf('<');
+ let text = '';
+ while (index === 0) {
+ text += '<';
+ html = html.substring(1);
+ index = html.indexOf('<');
+ }
+ text += index < 0 ? html : html.substring(0, index);
+ html = index < 0 ? '' : html.substring(index);
+
+ if (handler.chars) handler.chars(text);
+ }
+
+ if (html === last) throw new Error(`Parse Error: ${html}`);
+ last = html;
+ }
+
+ // Clean up any remaining tags
+ parseEndTag();
+}
+
+export default HTMLParser;
diff --git a/components/feng-parse/libs/wxDiscode.js b/components/feng-parse/libs/wxDiscode.js
new file mode 100644
index 0000000..15d9a95
--- /dev/null
+++ b/components/feng-parse/libs/wxDiscode.js
@@ -0,0 +1,209 @@
+// HTML 支持的数学符号
+function strNumDiscode(str) {
+str = str.replace(/∀|∀|∀/g, '∀');
+str = str.replace(/∂|∂|∂/g, '∂');
+str = str.replace(/∃|∃|∃/g, '∃');
+str = str.replace(/∅|∅|∅/g, '∅');
+str = str.replace(/∇|∇|∇/g, '∇');
+str = str.replace(/∈|∈|∈/g, '∈');
+str = str.replace(/∉|∉|∉/g, '∉');
+str = str.replace(/∋|∋|∋/g, '∋');
+str = str.replace(/∏|∏|∏/g, '∏');
+str = str.replace(/∑|∑|∑/g, '∑');
+str = str.replace(/−|−|−/g, '−');
+str = str.replace(/∗|∗|∗/g, '∗');
+str = str.replace(/√|√|√/g, '√');
+str = str.replace(/∝|∝|∝/g, '∝');
+str = str.replace(/∞|∞|∞/g, '∞');
+str = str.replace(/∠|∠|∠/g, '∠');
+str = str.replace(/∧|∧|∧/g, '∧');
+str = str.replace(/∨|∨|∨/g, '∨');
+str = str.replace(/∩|∩|∩/g, '∩');
+str = str.replace(/∪|∪|∪/g, '∪');
+str = str.replace(/∫|∫|∫/g, '∫');
+str = str.replace(/∴|∴|∴/g, '∴');
+str = str.replace(/∼|∼|∼/g, '∼');
+str = str.replace(/≅|≅|≅/g, '≅');
+str = str.replace(/≈|≈|≈/g, '≈');
+str = str.replace(/≠|≠|≠/g, '≠');
+str = str.replace(/≤|≤|≤/g, '≤');
+str = str.replace(/≥|≥|≥/g, '≥');
+str = str.replace(/⊂|⊂|⊂/g, '⊂');
+str = str.replace(/⊃|⊃|⊃/g, '⊃');
+str = str.replace(/⊄|⊄|⊄/g, '⊄');
+str = str.replace(/⊆|⊆|⊆/g, '⊆');
+str = str.replace(/⊇|⊇|⊇/g, '⊇');
+str = str.replace(/⊕|⊕|⊕/g, '⊕');
+str = str.replace(/⊗|⊗|⊗/g, '⊗');
+str = str.replace(/⊥|⊥|⊥/g, '⊥');
+str = str.replace(/⋅|⋅|⋅/g, '⋅');
+return str;
+}
+
+// HTML 支持的希腊字母
+function strGreeceDiscode(str) {
+str = str.replace(/Α|Α|Α/g, 'Α');
+str = str.replace(/Β|Β|Β/g, 'Β');
+str = str.replace(/Γ|Γ|Γ/g, 'Γ');
+str = str.replace(/Δ|Δ|Δ/g, 'Δ');
+str = str.replace(/Ε|Ε|Ε/g, 'Ε');
+str = str.replace(/Ζ|Ζ|Ζ/g, 'Ζ');
+str = str.replace(/Η|Η|Η/g, 'Η');
+str = str.replace(/Θ|Θ|Θ/g, 'Θ');
+str = str.replace(/Ι|Ι|Ι/g, 'Ι');
+str = str.replace(/Κ|Κ|Κ/g, 'Κ');
+str = str.replace(/Λ|Λ|Λ/g, 'Λ');
+str = str.replace(/Μ|Μ|Μ/g, 'Μ');
+str = str.replace(/Ν|Ν|Ν/g, 'Ν');
+str = str.replace(/Ξ|Ν|Ν/g, 'Ν');
+str = str.replace(/Ο|Ο|Ο/g, 'Ο');
+str = str.replace(/Π|Π|Π/g, 'Π');
+str = str.replace(/Ρ|Ρ|Ρ/g, 'Ρ');
+str = str.replace(/Σ|Σ|Σ/g, 'Σ');
+str = str.replace(/Τ|Τ|Τ/g, 'Τ');
+str = str.replace(/Υ|Υ|Υ/g, 'Υ');
+str = str.replace(/Φ|Φ|Φ/g, 'Φ');
+str = str.replace(/Χ|Χ|Χ/g, 'Χ');
+str = str.replace(/Ψ|Ψ|Ψ/g, 'Ψ');
+str = str.replace(/Ω|Ω|Ω/g, 'Ω');
+
+str = str.replace(/α|α|α/g, 'α');
+str = str.replace(/β|β|β/g, 'β');
+str = str.replace(/γ|γ|γ/g, 'γ');
+str = str.replace(/δ|δ|δ/g, 'δ');
+str = str.replace(/ε|ε|ε/g, 'ε');
+str = str.replace(/ζ|ζ|ζ/g, 'ζ');
+str = str.replace(/η|η|η/g, 'η');
+str = str.replace(/θ|θ|θ/g, 'θ');
+str = str.replace(/ι|ι|ι/g, 'ι');
+str = str.replace(/κ|κ|κ/g, 'κ');
+str = str.replace(/λ|λ|λ/g, 'λ');
+str = str.replace(/μ|μ|μ/g, 'μ');
+str = str.replace(/ν|ν|ν/g, 'ν');
+str = str.replace(/ξ|ξ|ξ/g, 'ξ');
+str = str.replace(/ο|ο|ο/g, 'ο');
+str = str.replace(/π|π|π/g, 'π');
+str = str.replace(/ρ|ρ|ρ/g, 'ρ');
+str = str.replace(/ς|ς|ς/g, 'ς');
+str = str.replace(/σ|σ|σ/g, 'σ');
+str = str.replace(/τ|τ|τ/g, 'τ');
+str = str.replace(/υ|υ|υ/g, 'υ');
+str = str.replace(/φ|φ|φ/g, 'φ');
+str = str.replace(/χ|χ|χ/g, 'χ');
+str = str.replace(/ψ|ψ|ψ/g, 'ψ');
+str = str.replace(/ω|ω|ω/g, 'ω');
+str = str.replace(/ϑ|ϑ|ϑ/g, 'ϑ');
+str = str.replace(/ϒ|ϒ|ϒ/g, 'ϒ');
+str = str.replace(/ϖ|ϖ|ϖ/g, 'ϖ');
+str = str.replace(/·|·|·/g, '·');
+return str;
+}
+
+function strcharacterDiscode(str) {
+// 加入常用解析
+
+str = str.replace(/ | | /g, " ");
+str = str.replace(/ | | /g, ' ');
+str = str.replace(/ | /g, '<span class=\'spaceshow\'> </span>');
+str = str.replace(/ | | /g, ' ');
+str = str.replace(/"|"|"/g, "\"");
+str = str.replace(/'|'|'/g, "'");
+str = str.replace(/´|´|´/g, "´");
+str = str.replace(/×|×|×/g, "×");
+str = str.replace(/÷|÷|÷/g, "÷");
+str = str.replace(/&|&|&/g, '&');
+str = str.replace(/<|<|</g, '<');
+str = str.replace(/>|>|>/g, '>');
+
+
+
+
+str = str.replace(/ | | /g, "<span class='spaceshow'> </span>");
+str = str.replace(/ | | /g, '<span class=\'spaceshow\'> </span>');
+str = str.replace(/ | /g, '<span class=\'spaceshow\'> </span>');
+str = str.replace(/ | | /g, '<span class=\'spaceshow\'> </span>');
+str = str.replace(/"|"|"/g, "\"");
+str = str.replace(/"|'|'/g, "'");
+str = str.replace(/´|´|´/g, "´");
+str = str.replace(/×|×|×/g, "×");
+str = str.replace(/÷|÷|÷/g, "÷");
+str = str.replace(/&|&|&/g, '&');
+str = str.replace(/<|<|</g, '<');
+str = str.replace(/>|>|>/g, '>');
+return str;
+}
+
+// HTML 支持的其他实体
+function strOtherDiscode(str) {
+str = str.replace(/Œ|Œ|Œ/g, 'Œ');
+str = str.replace(/œ|œ|œ/g, 'œ');
+str = str.replace(/Š|Š|Š/g, 'Š');
+str = str.replace(/š|š|š/g, 'š');
+str = str.replace(/Ÿ|Ÿ|Ÿ/g, 'Ÿ');
+str = str.replace(/ƒ|ƒ|ƒ/g, 'ƒ');
+str = str.replace(/ˆ|ˆ|ˆ/g, 'ˆ');
+str = str.replace(/˜|˜|˜/g, '˜');
+str = str.replace(/ |$#8201;| /g, '<span class=\'spaceshow\'> </span>');
+str = str.replace(/‌|‌|‌/g, '<span class=\'spaceshow\'></span>');
+str = str.replace(/‍|$#8205;|‍/g, '<span class=\'spaceshow\'></span>');
+str = str.replace(/‎|$#8206;|‎/g, '<span class=\'spaceshow\'></span>');
+str = str.replace(/‏|‏|‏/g, '<span class=\'spaceshow\'></span>');
+str = str.replace(/–|–|–/g, '–');
+str = str.replace(/—|—|—/g, '—');
+str = str.replace(/‘|‘|‘/g, '‘');
+str = str.replace(/’|’|’/g, '’');
+str = str.replace(/‚|‚|‚/g, '‚');
+str = str.replace(/“|“|“/g, '“');
+str = str.replace(/”|”|”/g, '”');
+str = str.replace(/„|„|„/g, '„');
+str = str.replace(/†|†|†/g, '†');
+str = str.replace(/‡|‡|‡/g, '‡');
+str = str.replace(/•|•|•/g, '•');
+str = str.replace(/…|…|…/g, '…');
+str = str.replace(/‰|‰|‰/g, '‰');
+str = str.replace(/′|′|′/g, '′');
+str = str.replace(/″|″|″/g, '″');
+str = str.replace(/‹|‹|‹/g, '‹');
+str = str.replace(/›|›|›/g, '›');
+str = str.replace(/‾|‾|‾/g, '‾');
+str = str.replace(/€|€|€/g, '€');
+str = str.replace(/™|™|™/g, '™');
+str = str.replace(/←|←|←/g, '←');
+str = str.replace(/↑|↑|↑/g, '↑');
+str = str.replace(/→|→|→/g, '→');
+str = str.replace(/↓|↓|↓/g, '↓');
+str = str.replace(/↔|↔|↔/g, '↔');
+str = str.replace(/↵|↵|↵/g, '↵');
+str = str.replace(/⌈|⌈|⌈/g, '⌈');
+str = str.replace(/⌉|⌉|⌉/g, '⌉');
+str = str.replace(/⌊|⌊|⌊/g, '⌊');
+str = str.replace(/⌋|⌋|⌋/g, '⌋');
+str = str.replace(/◊|◊|◊/g, '◊');
+str = str.replace(/♠|♠|♠/g, '♠');
+str = str.replace(/♣|♣|♣/g, '♣');
+str = str.replace(/♥|♥|♥/g, '♥');
+str = str.replace(/♦|♦|♦/g, '♦');
+return str;
+}
+
+function strDiscode(str) {
+ str = strNumDiscode(str);
+ str = strGreeceDiscode(str);
+ str = strcharacterDiscode(str);
+ str = strOtherDiscode(str);
+ return str;
+}
+
+function urlToHttpUrl(url, domain) {
+ if (/^\/\//.test(url)) {
+ return `https:${url}`;
+ } else if (/^\//.test(url)) {
+ return `https://${domain}${url}`;
+ }
+ return url;
+}
+
+export default {
+ strDiscode,
+ urlToHttpUrl,
+};
diff --git a/components/feng-parse/parse.css b/components/feng-parse/parse.css
new file mode 100644
index 0000000..e7adce1
--- /dev/null
+++ b/components/feng-parse/parse.css
@@ -0,0 +1,258 @@
+/**
+ * author: Di (微信小程序开发工程师)
+ * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
+ * 垂直微信小程序开发交流社区
+ *
+ * github地址: https://github.com/icindy/wxParse
+ *
+ * for: 微信小程序富文本解析
+ * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
+ */
+/**
+ * 请在全局下引入该文件,@import '/static/wxParse.css';
+ */
+.wxParse {
+ user-select:none;
+ width: 100%;
+ font-family: Helvetica, "PingFangSC", 'Microsoft Yahei', '微软雅黑', Arial, sans-serif;
+ color: #333;
+ line-height: 1.5;
+ font-size: 1em;
+ text-align:justify;/* //左右两端对齐 */
+}
+.wxParse view ,.wxParse uni-view{
+ word-break: break-word;
+}
+.wxParse .p {
+ padding-bottom: 0.5em;
+ clear: both;
+ /* letter-spacing: 0;//字间距 */
+}
+.wxParse .inline {
+ display: inline;
+ margin: 0;
+ padding: 0;
+}
+
+.wxParse .div {
+ margin: 0;
+ padding: 0;
+ display: block;
+}
+
+.wxParse .h1{
+ font-size: 2em;
+ line-height: 1.2em;
+ margin: 0.67em 0;
+}
+.wxParse .h2{
+ font-size: 1.5em;
+ margin: 0.83em 0;
+}
+.wxParse .h3{
+ font-size: 1.17em;
+ margin: 1em 0;
+}
+.wxParse .h4{
+ margin: 1.33em 0;
+}
+.wxParse .h5{
+ font-size: 0.83em;
+ margin: 1.67em 0;
+}
+.wxParse .h6{
+ font-size: 0.83em;
+ margin: 1.67em 0;
+}
+
+.wxParse .h1,
+.wxParse .h2,
+.wxParse .h3,
+.wxParse .h4,
+.wxParse .h5,
+.wxParse .h6,
+.wxParse .b,
+.wxParse .strong{
+ font-weight: bolder;
+}
+
+.wxParse .i,
+.wxParse .cite,
+.wxParse .em,
+.wxParse .var,
+.wxParse .address {
+ font-style: italic;
+}
+.wxParse .spaceshow{
+ white-space: pre;
+}
+.wxParse .pre,
+.wxParse .tt,
+.wxParse .code,
+.wxParse .kbd,
+.wxParse .samp {
+ font-family: monospace;
+}
+.wxParse .pre {
+ overflow: auto;
+ background: #f5f5f5;
+ padding: 16upx;
+ white-space: pre;
+ margin: 1em 0upx;
+ font-size: 24upx;
+}
+.wxParse .code {
+ overflow: auto;
+ padding: 16upx;
+ white-space: pre;
+ margin: 1em 0upx;
+ background: #f5f5f5;
+ font-size: 24upx;
+}
+
+.wxParse .big {
+ font-size: 1.17em;
+}
+
+.wxParse .small,
+.wxParse .sub,
+.wxParse .sup {
+ font-size: 0.83em;
+}
+
+.wxParse .sub {
+ vertical-align: sub;
+}
+.wxParse .sup {
+ vertical-align: super;
+}
+
+.wxParse .s,
+.wxParse .strike,
+.wxParse .del {
+ text-decoration: line-through;
+}
+
+.wxParse .strong,
+.wxParse .text,
+.wxParse .span,
+.wxParse .s {
+ display: inline;
+}
+
+.wxParse .a {
+ color: deepskyblue;
+}
+
+.wxParse .video {
+ text-align: center;
+ margin: 22upx 0;
+}
+
+.wxParse .video-video {
+ width: 100%;
+}
+.wxParse .uni-image{
+ max-width: 100%;
+}
+.wxParse .img {
+ display: block;
+ max-width: 100%;
+ margin-bottom: 0em;/* //与p标签底部padding同时修改 */
+ overflow: hidden;
+}
+
+.wxParse .blockquote {
+ margin: 10upx 0;
+ padding: 22upx 0 22upx 22upx;
+ font-family: Courier, Calibri, "宋体";
+ background: #f5f5f5;
+ border-left: 6upx solid #dbdbdb;
+}
+.wxParse .blockquote .p {
+ margin: 0;
+}
+.wxParse .ul, .wxParse .ol {
+ display: block;
+ margin: 1em 0;
+ padding-left: 2em;
+}
+.wxParse .ol {
+ list-style-type: disc;
+}
+.wxParse .ol {
+ list-style-type: decimal;
+}
+.wxParse .ol>weixin-parse-template,.wxParse .ul>weixin-parse-template {
+ display: list-item;
+ align-items: baseline;
+ text-align: match-parent;
+}
+
+.wxParse .ol>.li,.wxParse .ul>.li {
+ display: list-item;
+ align-items: baseline;
+ text-align: match-parent;
+}
+.wxParse .ul .ul, .wxParse .ol .ul {
+ list-style-type: circle;
+}
+.wxParse .ol .ol .ul, .wxParse .ol .ul .ul, .wxParse .ul .ol .ul, .wxParse .ul .ul .ul {
+ list-style-type: square;
+}
+
+.wxParse .u {
+ text-decoration: underline;
+}
+.wxParse .hide {
+ display: none;
+}
+.wxParse .del {
+ display: inline;
+}
+.wxParse .figure {
+ overflow: hidden;
+}
+.wxParse .tablebox{
+ overflow: auto;
+ background-color: #f5f5f5;
+ background: #f5f5f5;
+ font-size: 13px;
+ padding: 8px;
+}
+.wxParse .table .table,.wxParse .table{
+ border-collapse:collapse;
+ box-sizing: border-box;
+ /* 内边框 */
+ /* width: 100%; */
+ overflow: auto;
+ white-space: pre;
+}
+.wxParse .tbody{
+ border-collapse:collapse;
+ box-sizing: border-box;
+ /* 内边框 */
+ border: 1px solid #dadada;
+}
+.wxParse .table .thead, .wxParse .table .tfoot, .wxParse .table .th{
+ border-collapse:collapse;
+ box-sizing: border-box;
+ background: #ececec;
+ font-weight: 40;
+}
+.wxParse .table .tr {
+ border-collapse:collapse;
+ box-sizing: border-box;
+ /* border: 2px solid #F0AD4E; */
+ overflow:auto;
+}
+.wxParse .table .th,
+.wxParse .table .td{
+ border-collapse:collapse;
+ box-sizing: border-box;
+ border: 2upx solid #dadada;
+ overflow:auto;
+}
+.wxParse .audio, .wxParse .uni-audio-default{
+ display: block;
+}
\ No newline at end of file
diff --git a/components/feng-parse/parse.vue b/components/feng-parse/parse.vue
new file mode 100644
index 0000000..38adc4f
--- /dev/null
+++ b/components/feng-parse/parse.vue
@@ -0,0 +1,237 @@
+<!--**
+ * forked from:https://github.com/F-loat/mpvue-wxParse
+ *
+ * github地址: https://github.com/dcloudio/uParse
+ *
+ * for: uni-app框架下 富文本解析
+ *
+ * 优化 by zhiqiang.feng@qq.com
+ */-->
+
+<template>
+
+ <!--基础元素-->
+ <view class="wxParse" :class="className" :style="'user-select:' + userSelect">
+ <block v-for="(node, index) of nodes" :key="index" v-if="!loading">
+ <wxParseTemplate :node="node" />
+ </block>
+ </view>
+</template>
+
+<script>
+import HtmlToJson from './libs/html2json';
+import wxParseTemplate from './components/wxParseTemplate0';
+
+ export default {
+ name: 'wxParse',
+ props: {
+ // user-select:none;
+ userSelect: {
+ type: String,
+ default: 'text' //none |text| all | element
+ },
+ imgOptions: {
+ type: [Object, Boolean],
+ default: function() {
+ return {
+ loop: false,
+ indicator: 'number',
+ longPressActions: false
+ // longPressActions: {
+ // itemList: ['发送给朋友', '保存图片', '收藏'],
+ // success: function (res) {
+ // console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
+ // },
+ // fail: function (res) {
+ // console.log(res.errMsg);
+ // }
+ // }
+ // }
+ }
+ }
+ },
+ loading: {
+ type: Boolean,
+ default: false
+ },
+ className: {
+ type: String,
+ default: ''
+ },
+ content: {
+ type: String,
+ default: ''
+ },
+ noData: {
+ type: String,
+ default: ''
+ },
+ startHandler: {
+ type: Function,
+ default () {
+ return node => {
+ node.attr.class = null;
+ node.attr.style = null;
+ };
+ }
+ },
+ endHandler: {
+ type: Function,
+ default() {
+ return node => {
+ node = node
+ };
+ }
+ },
+ charsHandler: {
+ type: Function,
+ default() {
+ return node => {
+ node = node
+ };
+ }
+ },
+ imageProp: {
+ type: Object,
+ default () {
+ return {
+ mode: 'aspectFit',
+ padding: 0,
+ lazyLoad: false,
+ domain: ''
+ };
+ }
+ }
+ },
+ components: {
+ wxParseTemplate
+ },
+ data() {
+ return {
+ nodes: {},
+ imageUrls: [],
+ wxParseWidth: {
+ value: 0
+ }
+ };
+ },
+ computed: {},
+ mounted() {
+ this.setHtml()
+ },
+ methods: {
+ setHtml() {
+ this.getWidth().then((data) => {
+ this.wxParseWidth.value = data;
+ })
+ let {
+ content,
+ noData,
+ imageProp,
+ startHandler,
+ endHandler,
+ charsHandler
+ } = this;
+ let parseData = content || noData;
+ let customHandler = {
+ start: startHandler,
+ end: endHandler,
+ chars: charsHandler
+ };
+ let results = HtmlToJson(parseData, customHandler, imageProp, this);
+
+ this.imageUrls = results.imageUrls;
+ // this.nodes = results.nodes;
+
+ this.nodes = [];
+ results.nodes.forEach((item) => {
+ setTimeout(() => {
+ if(item.node){
+ this.nodes.push(item)
+ }
+ }, 0);
+ })
+
+ },
+ getWidth() {
+ return new Promise((res, rej) => {
+ // #ifndef MP-ALIPAY || MP-BAIDU
+ uni.createSelectorQuery()
+ .in(this)
+ .select('.wxParse')
+ .fields({
+ size: true,
+ scrollOffset: true
+ },
+ data => {
+ res(data.width);
+ }
+ ).exec();
+ // #endif
+ // #ifdef MP-BAIDU
+ const query = swan.createSelectorQuery();
+ query.select('.wxParse').boundingClientRect();
+ query.exec(obj => {
+ const rect = obj[0]
+ if (rect) {
+ res(rect.width);
+ }
+ });
+ // #endif
+ // #ifdef MP-ALIPAY
+ my.createSelectorQuery()
+ .select('.wxParse')
+ .boundingClientRect().exec((ret) => {
+ res(ret[0].width);
+ });
+ // #endif
+ });
+ },
+ navigate(href, $event, attr) {
+ console.log(href, attr);
+ this.$emit('navigate', href, $event);
+ },
+ preview(src, $event) {
+ if (!this.imageUrls.length || typeof this.imgOptions === 'boolean') {
+
+ } else {
+ uni.previewImage({
+ current: src,
+ urls: this.imageUrls,
+ loop: this.imgOptions.loop,
+ indicator: this.imgOptions.indicator,
+ longPressActions: this.imgOptions.longPressActions
+ });
+ }
+ this.$emit('preview', src, $event);
+ },
+ removeImageUrl(src) {
+ const {
+ imageUrls
+ } = this;
+ imageUrls.splice(imageUrls.indexOf(src), 1);
+ }
+ },
+ // 父组件中提供
+ provide() {
+ return {
+ parseWidth: this.wxParseWidth,
+ parseSelect: this.userSelect
+ // 提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。
+ };
+ },
+ watch: {
+ content(val){
+ this.setHtml()
+ }
+ // content: {
+ // handler: function(newVal, oldVal) {
+ // if (newVal !== oldVal) {
+ //
+ // }
+ // },
+ // deep: true
+ // }
+ }
+ };
+</script>
diff --git a/components/nav-bar-top/nav-bar-top.vue b/components/nav-bar-top/nav-bar-top.vue
new file mode 100644
index 0000000..28a9944
--- /dev/null
+++ b/components/nav-bar-top/nav-bar-top.vue
@@ -0,0 +1,72 @@
+<template name="navBarTop">
+ <!-- 自定义顶部导航栏 -->
+ <!-- <view class="nav-bar-top" @click="gotoMyself()">
+ <view class="nav-bar-top-left">
+ <image :src="navBarImage" />
+ </view>
+ <view class="nav-bar-top-title">我要查</view>
+ </view> -->
+
+ <uni-nav-bar class="uni-nav-bar-info" :fixed="true" :status-bar="true" >
+ <view class="title" slot="default">{{title}}</view>
+ <view slot="left" class="uni-nav-bar-left" @click="gotoMyself()">
+ <image :src="avatarImage"></image>
+ </view>
+ </uni-nav-bar>
+</template>
+
+<script>
+ import uniNavBar from '../../components/uni-nav-bar/uni-nav-bar.vue'
+ export default{
+ props:['title'],
+ components:{uniNavBar},
+ name:"navBarTop",
+ data(){
+ // console.log(title);
+ return{
+ avatarImage:this.$store.state.avatar,
+ }
+ },
+ methods:{
+ //跳转至我的页面
+ gotoMyself(){
+ uni.navigateTo({
+ url:'../myself/myself'
+ // animationType: 'pop-in',
+ // animationDuration: 200
+ })
+
+ // uni.navigateBack({
+ // delta:1,
+ // animationType:'pop-out',
+ // animationDuration:200
+ // });
+ }
+ }
+ }
+</script>
+
+<style lang="scss">
+ .uni-nav-bar-info {
+ // font-weight: 550;
+
+ .title{
+ position: fixed;
+ right: 45%;
+ font-weight: 550;
+ }
+
+ .uni-nav-bar-left{
+ display: flex;
+ justify-items: center;
+
+ image{
+ // background-color: #00BFFF;
+ margin-left: 1rem;
+ width: 1.8rem;
+ height: 1.8rem;
+ border-radius: 100px;
+ }
+ }
+ }
+</style>
diff --git a/components/outAdmin/uni-Popup.vue b/components/outAdmin/uni-Popup.vue
new file mode 100644
index 0000000..5d03f1f
--- /dev/null
+++ b/components/outAdmin/uni-Popup.vue
@@ -0,0 +1,121 @@
+<template>
+ <view>
+ <view class="show-box-bg wx-login-box" @tap.self="$emit('cancel')">
+ <view class="conten">
+ <view class="titl">
+ {{ textmsg.title }}
+ </view>
+ <view class="text">
+ {{ textmsg.content }}
+ </view>
+ <view class="text" style="margin-bottom: 50rpx;">
+ {{ textmsg.contentTwo || '' }}
+ </view>
+ <view class="btn-box">
+ <view class="cancel" @tap="$emit('cancel')">
+ {{ textmsg.cancel }}
+ </view>
+ <view class="confirm" @tap="$emit('confirm',textmsg.type)">
+ {{ textmsg.confirm }}
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ export default {
+ props:['textmsg'],
+ data() {
+ return {
+
+ }
+ },
+ methods:{
+ operation(e){
+ let type = e
+ this.$emit('operation',type);
+ },
+ }
+ }
+</script>
+
+<style scoped lang="scss">
+ .wx-login-box {
+ width: 100%;
+ position: fixed;
+ top: 0;
+ left: 0;
+ height: 100%;
+ background-color: rgba(0, 0, 0, 0.6);
+ z-index: 901;
+ .conten {
+ width: 78%;
+ // height: 400upx;
+ background-color: #ffffff;
+ z-index: 1000;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%,-50%);
+ border-radius: 14upx;
+ overflow: hidden;
+ .titl {
+ width: 90%;
+ height: 110rpx;
+ font-size: 40rpx;
+ padding: 0 5%;
+ color: #000000;
+ text-align: center;
+ line-height: 140rpx;
+ }
+ .text {
+ width: 90%;
+ font-size: 28rpx;
+ color: #000000;
+ padding: 0 5%;
+ text-align: center;
+ }
+ .memberY {
+ width: 90%;
+ font-size: 28rpx;
+ color: #07c1ea;
+ padding: 0 5%;
+ text-align: center;
+ }
+ .memberB {
+ width: 90%;
+ font-size: 28rpx;
+ color: #007AFF;
+ padding: 0 5%;
+ text-align: center;
+ }
+ .btn-box {
+ width: 100%;
+ height: 90rpx;
+ display: flex;
+ border-top: 2rpx solid #969696;
+ .cancel {
+ width: 50%;
+ height: 100%;
+ font-size: 40rpx;
+ color: #999;
+ text-align: center;
+ line-height: 89rpx;
+ border-right: 2rpx solid #969696;
+ }
+ .confirm {
+ width: 50%;
+ height: 100%;
+ font-size: 40rpx;
+ color: #07c1ea;
+ text-align: center;
+ line-height: 99rpx;
+ }
+ }
+ }
+
+ }
+
+</style>
\ No newline at end of file
diff --git a/components/pColumn/pColumn.vue b/components/pColumn/pColumn.vue
new file mode 100644
index 0000000..a10ff47
--- /dev/null
+++ b/components/pColumn/pColumn.vue
@@ -0,0 +1,275 @@
+<template>
+ <view class="pColumn">
+ <view class="inPColumn">
+ <view class="left">
+ <view class="top">
+ <view class="t-type">{{Pdata.alarmType}} </view>
+ <view class="t-id"> 警单编号:{{Pdata.id}}</view>
+ </view>
+ <view class="image-time">
+ <image src="../../static/images/pColumn/alarm.png"></image>
+ <view class="t-time"> {{Pdata.alarmTime}}</view>
+ </view>
+ <view class="image-place">
+ <image src="../../static/images/pColumn/position-bule.png"></image>
+ <view class="place">{{Pdata.place}}</view>
+ </view>
+ </view>
+ <view class="right">
+ <button type="default" @click="PClick">{{fromW == 0?'详情':fromW == 1?'接受':""}}</button>
+ <view class="butPopup" v-show="popuShow">
+ <view class="b-main" :style="{bottom: bmainb}">
+ <view class="b-m-title">
+ 是否接该任务
+ </view>
+ <button class="b-m-Y" hover-class='b-m-Y-hove' type="default" @click="popupBY">接受</button>
+ <button class="b-m-N" hover-class='b-m-N-hove' type="default" @click="popupBN">取消</button>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ export default {
+ props: ['fromW', 'Pdata'],
+ data() {
+ return {
+ popuShow: false,
+ bmainb: ''
+ }
+ },
+ methods: {
+ beginObj() {
+ this.bmainb = '3rem';
+ //#ifdef MP-WEIXIN
+ this.bmainb = '0';
+ //#endif
+ },
+ receives() {
+ var url = this.$store.state.piAPI + "/alarm/alarm/APP-setAlarm",
+ Pid = this.Pdata.id,
+ id = this.$store.state.puserID, //警察id
+ name = this.$store.state.puserName, //警察id
+ data = {
+ id: Pid,
+ securityId: id,
+ alarmPeople: name
+ },
+ that = this;
+ // console.log(data);
+ wx.request({
+ url: url,
+ data: data,
+ header: {
+ "content-type": "application/x-www-form-urlencoded"
+ },
+ method: 'POST',
+ success(res) {
+ // console.log(res.data.msg);
+ }
+ })
+ },
+ PClick(val) {
+ if (this.fromW == 0) { //打开详情页面
+ // wx.navigateTo({url: '/pages/map/map'});
+ var datas = this.Pdata;
+ datas.state = 0;
+ datas.dtype = 0;
+ datas.size = 300;
+ // console.log(datas)
+ var data = [datas]; //传给地图的参数
+ wx.navigateTo({
+ url: '/pages/map/map?data=' + JSON.stringify(data)
+ });
+ } else if (this.fromW == 1) { //打开提交弹窗
+ this.popuShow = true;
+ }
+ },
+ onClose() { //触摸遮罩事件
+ this.setData({
+ popuShow: false
+ });
+ },
+ popupBY() {
+ this.receives();
+ // console.log('接收成功');
+ this.$emit('refreshTask', this.fromW)
+ // this.triggerEvent('myevent', this.data.fromW);
+ this.popuShow = false;
+ },
+ popupBN() {
+ // console.log('接收取消');
+ this.popuShow = false;
+ }
+ },
+ mounted() {
+ this.beginObj();
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ /* components/pColumn/pColumn.wxss */
+ .pColumn,
+ .inPColumn,
+ .left,
+ .right,
+ .image-time,
+ .image-place,
+ .top {
+ display: flex;
+ }
+
+ .pColumn {
+ width: 100%;
+ align-items: center;
+ justify-content: center;
+ padding-top: 0.8rem;
+
+ .inPColumn {
+ // background-color: #00BFFF;
+ margin: 0.2rem 0 0.4rem 0;
+ width: 95%;
+ height: 5rem;
+ border-bottom: 1px rgb(207, 207, 207) solid;
+ align-items: center;
+ justify-content: space-between;
+
+ .left {
+ width: 80%;
+ /* border: 1px rgb(114, 250, 159) solid; */
+ flex-direction: column;
+
+ .top {
+ .t-type {
+ font-size: 1.1rem;
+ color: #ff0000;
+ letter-spacing: 1px;
+ }
+
+ .t-id {
+ color: #00aaff;
+ font-size: 0.8rem;
+ line-height: 1.6rem;
+ position: relative;
+ left: 0.7rem;
+ }
+ }
+
+ .image-time{
+ align-items: center;
+ height: 30px;
+
+ image{
+ width: 35rpx;
+ height: 35rpx;
+ }
+
+ .t-time{
+ font-size: 0.8rem;
+ color: #808080;
+ height: 20rpx;
+ line-height: 20rpx;
+ margin-left: 15rpx;
+ }
+ }
+
+ .image-place{
+ align-items: center;
+ height: 20px;
+
+ image{
+ width: 35rpx;
+ height: 35rpx;
+ }
+
+ .place {
+ font-size: 0.8rem;
+ margin-left: 15rpx;
+ color: #808080;
+ height: 20rpx;
+ line-height: 20rpx;
+ }
+ }
+
+ }
+
+ .right {
+ width: 20%;
+ /* border: 1px rgb(143, 114, 250) solid; */
+ justify-content: space-around;
+
+ /* align-items: center; */
+ .butPopup {
+ z-index: 4;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba($color: #000000, $alpha: 0.5);
+
+ .b-main {
+ position: absolute;
+ z-index: 2;
+ // bottom: 3rem;//小程序不兼容
+ width: 100%;
+ // border: 1px solid #007AFF;
+ border-radius: 1.5rem;
+ background-color: #fff;
+
+ // height: 20rem;
+ .b-m-title {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 2.8rem;
+ }
+
+ .b-m-Y,
+ .b-m-N {
+ color: #fff;
+ border-radius: 0;
+ }
+
+ .b-m-Y {
+ background-color: #07C160 !important;
+ }
+
+ .b-m-Y-hove {
+ background-color: #048c44 !important;
+ }
+
+ .b-m-N {
+ background-color: #FF976A !important;
+ }
+
+ .b-m-N-hove {
+ background-color: #e1855d !important;
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+
+
+ // .buttitle {
+ // display: flex;
+ // align-items: center;
+ // justify-content: center;
+ // width: 100%;
+ // height: 2.8rem;
+ // }
+
+ // .popups {
+ // width: 100%;
+ // padding-bottom: 0 !important;
+ // /* border: 1px solid seagreen; */
+ // }
+</style>
diff --git a/components/seeImges/seeImges.vue b/components/seeImges/seeImges.vue
new file mode 100644
index 0000000..59d2797
--- /dev/null
+++ b/components/seeImges/seeImges.vue
@@ -0,0 +1,169 @@
+<template>
+ <view class="seeImgs" v-if="imgs.length != 0 || videos.length != 0 ">
+ <view class="imgs" v-for="(item, index) in imgs" :key="index" v-if="type == 'imgs'">
+ <image :src="item.src" mode="scaleToFill" @click="previewImage(index)"></image>
+ <view class="close" @click="delelteImg(index)">
+ X
+ </view>
+ </view>
+ <view class="videos" v-for="(item, index) in videos" :key="index" v-if="type == 'videos'">
+
+ <!-- <image :src="item.src" mode="scaleToFill" @click="previewImage(index)"></image> -->
+ <video :src="item.src" controls></video>
+
+ <view class="close" @click="deleltevideo(index)">
+ X
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ export default {
+ props: ['imgs', 'videos', 'type'],
+ // props: [{
+ // imgs:{
+ // type: Array,
+ // default: []
+ // },
+ // videos:{
+ // type: Object,
+ // default: []
+ // },
+ // type:{
+ // type: String,
+ // default: null
+ // },
+ // }],
+ data() {
+ return {
+
+ }
+ },
+ methods: {
+ //图片删除
+ delelteImg(index) {
+ var that = this;
+ wx.showModal({
+ title: '提示',
+ content: '确定要删除该照片吗?',
+ cancelText: '取消',
+ confirmText: '确定',
+ success: res => {
+ if (res.confirm) {
+ // console.log(index)
+ // that.imgs.splice(index, 1);
+ that.$emit('del', index);
+ }
+ }
+ });
+ },
+
+ //图片预览
+ previewImage(index) {
+ let photoList = this.imgs.map(item => {
+ return item.src;
+ });
+ // console.log(index)
+ // console.log(photoList)
+ wx.previewImage({
+ current: photoList[index],
+ urls: photoList
+ });
+ },
+
+ //视频删除
+ deleltevideo(index) {
+ var that = this;
+ wx.showModal({
+ title: '提示',
+ content: '确定要删除该视频吗?',
+ cancelText: '取消',
+ confirmText: '确定',
+ success: res => {
+ if (res.confirm) {
+ // console.log(index)
+ // that.imgs.splice(index, 1);
+ that.$emit('del', index);
+ }
+ }
+ });
+ },
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ .seeImgs {
+ width: 100%;
+ height: 4.3rem;
+ // border: 1px solid #0000FF;
+ white-space: nowrap;
+ box-sizing: border-box;
+ overflow: auto;
+ // display: flex;
+ // align-items: center;
+ // position: absolute;
+ // right: 0;
+ // z-index: 110;
+
+ .imgs {
+ display: inline-block;
+ padding-top: 0.5rem;
+ width: 4rem;
+ height: 4rem;
+ padding: 0 0.2rem 0 0.2rem;
+ margin: 0 0.2rem 0 0.2rem;
+ // border-right: 1px solid rgba($color: #000000, $alpha: 0.5);
+ position: relative;
+ // border: 1px solid #0000FF;
+ top: 0.22rem;
+
+ image {
+ width: 100%;
+ height: 100%;
+ }
+
+
+ }
+
+ .videos {
+ display: inline-block;
+ padding-top: 0.5rem;
+ width: 4rem;
+ height: 4rem;
+ padding: 0 0.2rem 0 0.2rem;
+ margin: 0 0.2rem 0 0.2rem;
+ // border-right: 1px solid rgba($color: #000000, $alpha: 0.5);
+ position: relative;
+ // border: 1px solid #0000FF;
+ top: 0.22rem;
+
+ video {
+ width: 100%;
+ height: 100%;
+ }
+ }
+ }
+
+ .close {
+ background-color: #fff;
+ width: 0.9rem;
+ height: 0.9rem;
+ text-align: center;
+ line-height: 0.8rem;
+ position: absolute;
+ top: 0.1rem;
+ right: 0.2rem;
+ font-size: 0.5rem;
+ color: red;
+ border-radius: 1.5rem;
+ border: 1px solid red;
+ z-index: 111;
+
+ &:hover {
+ color: red;
+ border: 1px solid red;
+ }
+ }
+</style>
diff --git a/components/squareBut/squareBut.vue b/components/squareBut/squareBut.vue
new file mode 100644
index 0000000..c162d9d
--- /dev/null
+++ b/components/squareBut/squareBut.vue
@@ -0,0 +1,61 @@
+<template>
+ <view class="squareBut">
+ <view class="once" v-for="(item,index) in data" :key="index" @click="goHref(index)">
+ <view class="imgs">
+ <image :src="item.imgSrc" mode=""></image>
+ </view>
+ <view class="title">
+ {{item.title}}
+ </view>
+ </view>
+ <view style="clear:left"></view>
+ </view>
+</template>
+
+<script>
+ export default {
+ props: ['data'],
+ methods:{
+ goHref(index){
+ // console.log(this.data[index].goHref)
+ wx.navigateTo({
+ url:this.data[index].goHref
+ })
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ .squareBut {
+ width: 95%;
+ margin: 0 auto;
+ border: 1px solid rgba($color: #000000, $alpha: 0.03);
+ border-radius: 1rem;
+ .once {
+ width: 6rem;
+ height: 6rem;
+ border-right: 1px solid rgba($color: #000000, $alpha: 0.3);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+ border-radius: 1rem;
+ box-shadow: 0.1rem 0.1rem 0.5rem 0.01rem #dadada;
+ float: left;
+ margin: 0.65rem;
+
+ .imgs {
+ width: 4rem;
+ height: 4rem;
+
+ image {
+ width: 100%;
+ height: 100%;
+ }
+ }
+
+ .title {}
+ }
+ }
+</style>
diff --git a/components/submit/emoji/emoji.vue b/components/submit/emoji/emoji.vue
new file mode 100644
index 0000000..f9970d0
--- /dev/null
+++ b/components/submit/emoji/emoji.vue
@@ -0,0 +1,75 @@
+<template>
+ <view class="emoji"
+ :style="{height:height + 'px'}">
+ <view class="emoji-line"
+ v-for="(line, i) in emoji"
+ :key="i">
+ <view class="emoji-line-item"
+ v-for="(item, index) in line"
+ :key="index"
+ @tap="clickEmoji(item)">
+ {{ item }}
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ export default {
+ props:{
+ height: {
+ type: Number,
+ default: 260
+ }
+ },
+ data() {
+ return {
+ emoji:[
+ ['😀', '😁', '😂', '🤣', '😃', '😅'],
+ ['😆', '😉', '😊', '😋', '😎', '😍'],
+ ['😘', '😗', '😙', '😚', '🙂', '🤗'],
+ ['🤔', '😐', '😑', '😶', '🙄', '😏'],
+ ['😣', '😥', '😮', '🤐', '😯', '😪'],
+ ['😫', '😴', '😌', '😛', '😜', '😝'],
+ ['🤤', '😓', '😔', '😕', '🙃', '🤑'],
+ ['😲', '🙁', '😖', '😞', '😟', '😤'],
+ ['😢', '😭', '😦', '😧', '😨', '😩'],
+ ['😬', '😱', '😳', '😵', '😳', '😵'],
+ ['💼', '🌂', '💍', '💄', '⛑', '🎓'],
+ ['👒', '🎩', '👑', '👢', '👡', '👠'],
+ ['👟', '👞', '👝', '👜', '👛', '👚'],
+ ['🍇', '🍈', '🍉', '🍊', '🍌', '🍒'],
+ ['☠', '🛀', '💣', '⏰', '🎎', '📻'],
+ ['💘', '❤', '💔', '💢', '💮', '🕜'],
+ ]
+ };
+ },
+ methods: {
+ clickEmoji(e) {
+ this.$emit('emotion', e)
+ }
+ }
+ }
+</script>
+
+<style lang="scss">
+ .emoji{
+ width: 100%;
+ padding: 16rpx 10rpx 180rpx 10rpx;
+ box-sizing: border-box;
+ overflow: hidden;
+ overflow-y: auto;
+
+ .emoji-line {
+ display: flex;
+
+ .emoji-line-item {
+ flex: 1;
+ text-align: center;
+ font-size: 52rpx;
+ line-height: 80rpx;
+ }
+ }
+ }
+
+</style>
diff --git a/components/submit/submit.vue b/components/submit/submit.vue
new file mode 100644
index 0000000..1098c75
--- /dev/null
+++ b/components/submit/submit.vue
@@ -0,0 +1,447 @@
+<template>
+ <view>
+ <view class="submit">
+ <view class="submit-chat">
+ <view class="bt-img">
+ <image src="../../static/images/chatroom/voice.png"
+ mode=""
+ @tap="records"/>
+ </view>
+ <textarea auto-height="true"
+ class="chat-send btn"
+ :class="{displaynone: isrecord}"
+ @input="inputs"
+ v-model="msg"
+ @focus="focus"/>
+ <view class="record btn"
+ :class="{displaynone: !isrecord}"
+ @touchstart="touchstart"
+ @touchend="touchend"
+ @touchmove="touchmove"
+ >
+ 按住说话
+ </view>
+ <view class="bt-img">
+ <image src="../../static/images/chatroom/emoji.png"
+ mode=""
+ @tap="emoji"/>
+ </view>
+ <view class="bt-img">
+ <image src="../../static/images/chatroom/add.png"
+ mode=""
+ @tap="more"/>
+ </view>
+ </view>
+ <view class="emoji"
+ :class="{ displaynone: !isemoji }">
+ <view class="emoji-send">
+ <view class="emoji-send-del"
+ @tap="emojiBack">
+ 删除
+ </view>
+ <view class="emoji-send-bt"
+ @tap="emojiSend">
+ 发送
+ </view>
+ </view>
+ <emoji @emotion="emotion"
+ :height="260" />
+ </view>
+
+ <view class="more"
+ :class="{ displaynone: !ismore }">
+ <view class="more-list"
+ @tap="sendImg('album')">
+ <image src="../../static/images/chatroom/photo.png"/>
+ <text class="more-list-title">图片</text>
+ </view>
+ <view class="more-list"
+ @tap="sendImg('camera')">
+ <image src="../../static/images/chatroom/camera.png"/>
+ <text class="more-list-title">拍照</text>
+ </view>
+ <view class="more-list">
+ <image src="../../static/images/chatroom/file.png"/>
+ <text class="more-list-title">文件</text>
+ </view>
+ <view class="more-list"
+ @tap="chooseLocation()">
+ <image src="../../static/images/chatroom/location.png"/>
+ <text class="more-list-title">位置</text>
+ </view>
+ <view class="more-list">
+ <image src="../../static/images/chatroom/vedio.png"/>
+ <text class="more-list-title">视频</text>
+ </view>
+ </view>
+ </view>
+
+ <!-- 录制语音遮罩 -->
+ <view class="voice-bg"
+ :class="{displaynone: !voicebg}">
+ <view class="voice-bg-len">
+ <view class="voice-bg-time"
+ :style="{width:vlength/0.6 + '%'}">
+ {{ vlength }} "
+ </view>
+ </view>
+ <view class="voice-del">上滑取消取消录音</view>
+ </view>
+ </view>
+</template>
+
+<script>
+ import emoji from './emoji/emoji.vue'
+
+ const recorderManager = uni.getRecorderManager()
+
+ export default {
+ data() {
+ return {
+ isrecord: false,
+ isemoji: false,
+ ismore: false,
+ voicebg: false,
+ msg: '',
+ timer: '',
+ vlength: 0,
+ pageY: 0,
+ };
+ },
+ components:{
+ emoji,
+ },
+ methods:{
+ // 获取高度
+ _getElementHeight() {
+ const query = uni.createSelectorQuery().in(this);
+ query.select('.submit').boundingClientRect(data => {
+ this.$emit('heights', data.height)
+ }).exec();
+ },
+ // 点击切换音频
+ records() {
+ this.isrecord = !this.isrecord
+ this.isemoji = false
+ this.ismore = false
+ setTimeout(() => {
+ this._getElementHeight()
+ }, 10)
+ },
+ // 点击弹出表情
+ emoji() {
+ this.isemoji = !this.isemoji
+ this.ismore = false
+ this.isrecord = false
+ setTimeout(() => {
+ this._getElementHeight()
+ }, 10)
+ },
+ // 点击弹出更多
+ more() {
+ this.ismore = !this.ismore
+ this.isemoji = false
+ this.isrecord = false
+ setTimeout(() => {
+ this._getElementHeight()
+ }, 10)
+ },
+ // 接收表情
+ emotion(e) {
+ this.msg = this.msg + e
+ },
+ // 文字发送
+ inputs(e) {
+ let chatm = e.detail.value
+ let pos = chatm.indexOf('\n')
+ if(pos != -1 && chatm.length > 1) {
+ this.send(this.msg,0)
+ }
+ setTimeout(() => {
+ this._getElementHeight()
+ },10)
+ },
+ // 输入框聚焦
+ focus(){
+ this.isemoji = false;
+ this.ismore = false;
+ setTimeout(() => {
+ this._getElementHeight()
+ },10)
+ },
+ // 表情内发送
+ emojiSend() {
+ if(this.msg.length > 0) {
+ this.send(this.msg, 0)
+ }
+ setTimeout(() => {
+ this._getElementHeight()
+ },10)
+ },
+ // 表情退格
+ emojiBack() {
+ if(this.msg.length > 0){
+ this.msg = this.msg.substring(0, this.msg.length-1)
+ }
+ },
+ // 发送消息
+ send(msg, type) {
+ let data = {
+ message: msg,
+ types: type
+ }
+ this.$emit('inputs', data)
+ setTimeout(() => {
+ this.msg = ''
+ }, 0)
+ setTimeout(() => {
+ this._getElementHeight()
+ },10)
+ },
+ // 发送图片
+ sendImg(e) {
+ let count = 9;
+ if(e == 'album') {
+ count = 9
+ }else {
+ count = 1
+ }
+ uni.chooseImage({
+ count: count,
+ sizeType: ['original', 'comperssed'],
+ sourceType: [e],
+ success: (res) => {
+ const filePath = res.tempFilePaths
+ for (let i in filePath){
+ this.send(filePath[i], 1)
+ }
+ }
+ })
+ setTimeout(() => {
+ this._getElementHeight()
+ },10)
+ },
+ // 音频处理
+ touchstart(e) {
+ // 此时的Y轴位置
+ this.pageY = e.changedTouches[0].pageY
+ let startIndex = 1
+ this.voicebg = true
+ this.timer = setInterval(() => {
+ this.vlength = startIndex
+ startIndex++
+ if(startIndex > 60) {
+ clearInterval(this.timer)
+ this.touchend();
+ }
+ }, 1000)
+ recorderManager.start()
+ },
+ touchend() {
+ clearInterval(this.timer)
+ recorderManager.stop()
+ recorderManager.onStop((res) => {
+ let data = {
+ voice: res.tempFilePath,
+ time: this.vlength
+ }
+ if(this.voicebg){
+ this.send(data, 2);
+ }
+ this.vlength = 0
+ this.voicebg = false
+ })
+ },
+ touchmove(e) {
+ if(this.pageY - e.changedTouches[0].pageY > 200) {
+ this.voicebg = false
+ }
+ },
+ // 定位
+ chooseLocation() {
+ uni.chooseLocation({
+ success: (res) => {
+ let data = {
+ name: res.name,
+ address: res.address,
+ latitude: res.latitude,
+ longitude: res.longitude
+ }
+ this.send(data, 3)
+ console.log('位置名称' + res.name)
+ console.log('详细地址' + res.address)
+ console.log('维度' + res.latitude)
+ console.log('经度' + res.longitude)
+ }
+ })
+ }
+ }
+ }
+</script>
+
+<style lang="scss">
+ .submit {
+ background-color: rgba(244, 244, 244, .96);
+ border-top: 1px solid $uni-border-color;
+ width: 100%;
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ z-index: 1002;
+ padding-bottom: env(safe-area-inset-bottom);
+ }
+
+ .submit-chat {
+ width: 100%;
+ display: flex;
+ align-items: flex-end;
+ box-sizing: border-box;
+ padding: 14rpx 10rpx;
+
+ image {
+ width: 56rpx;
+ height: 56rpx;
+ margin: 0 10rpx;
+ flex: auto;
+ }
+
+ .btn {
+ flex: auto;
+ background-color: #fff;
+ border-radius: 10rpx;
+ padding: 20rpx;
+ max-height: 160rpx;
+ margin: 0 10rpx;
+ }
+
+ .chat-send {
+ line-height: 44rpx !important;
+ }
+
+ .record {
+ text-align: center;
+ font-size: $uni-font-size-lg;
+ color: $uni-text-color-grey;
+ font-weight: bold;
+ }
+
+ }
+ .displaynone {
+ display: none;
+ }
+
+ .emoji {
+ width: 100%;
+ height: 460rpx;
+ background: rgba(236, 237, 238, 1);
+ box-shadow: 0 -1rpx 0 0 rgba(0, 0, 0, 1);
+
+ .emoji-send {
+ width: 260rpx;
+ height: 104rpx;
+ background: rgba(236, 237, 238, .9);
+ position: fixed;
+ bottom: env(safe-area-inset-bottom);
+ right: 0;
+ padding-top: 24rpx;
+ display: flex;
+
+ .emoji-send-bt {
+ flex: 1;
+ height: 80rpx;
+ margin: 0 32rpx 0 20rpx;
+ background: rgba(255, 228, 49 ,1);
+ border-radius: 240rpx;
+ font-size: 32rpx;
+ text-align: center;
+ line-height: 80rpx;
+ border-radius: 12rpx;
+ }
+
+ .emoji-send-del {
+ flex: 1;
+ height: 80rpx;
+ background: #fff;
+ border-radius: 240rpx;
+ font-size: 32rpx;
+ text-align: center;
+ line-height: 80rpx;
+ border-radius: 12rpx;
+ margin-left: 24rpx;
+ }
+ }
+ }
+ .more {
+ width: 100%;
+ height: 436rpx;
+ background: rgba(236, 237, 238, 1);
+ box-shadow: rgba(0, 0, 0, .1);
+ bottom: env(safe-area-inset-bottom);
+ padding: 0 20rpx;
+ box-sizing: border-box;
+
+ .more-list {
+ width: 25%;
+ text-align: center;
+ float: left;
+ margin-top: 32rpx;
+
+ image {
+ width: 72rpx;
+ height: 72rpx;
+ padding: 24rpx;
+ background: rgba(255, 255, 255, 1);
+ border-radius: 24rpx;
+ }
+
+ .more-list-title {
+ color: rgba(30, 40, 50, .5);
+ line-height: 34rpx;
+ font-size: 24rpx;
+ display: block;
+ }
+ }
+ }
+
+ .voice-bg {
+ height: 100%;
+ width: 100%;
+ background: rgba(0, 0, 0, .3);
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ z-index: 1001;
+ // position: relative;
+
+ .voice-bg-len {
+ height: 84rpx;
+ width: 600rpx;
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ margin: auto;
+ background: rgba(255, 255, 255, .2);
+ border-radius: 42rpx;
+ text-align: center;
+ .voice-bg-time {
+ display: inline-block;
+ line-height: 84rpx;
+ background-color: $uni-color-primary;
+ border-radius: 42rpx;
+ min-width: 120rpx;
+ }
+ }
+
+ .voice-del {
+ position: absolute;
+ bottom: 148rpx;
+ margin-bottom: env(safe-area-inset-bottom);
+ width: 100%;
+ text-align: center;
+ color: #fff;
+ font-size: $uni-font-size-base;
+ }
+ }
+</style>
diff --git a/components/uni-load-more/uni-load-more.vue b/components/uni-load-more/uni-load-more.vue
new file mode 100644
index 0000000..a53a843
--- /dev/null
+++ b/components/uni-load-more/uni-load-more.vue
@@ -0,0 +1,362 @@
+<template>
+ <view class="uni-load-more" @click="onClick">
+ <!-- #ifdef APP-NVUE -->
+ <loading-indicator v-if="!webviewHide && status === 'loading' && showIcon" :style="{color: color,width:iconSize+'px',height:iconSize+'px'}" :animating="true" class="uni-load-more__img uni-load-more__img--nvue"></loading-indicator>
+ <!-- #endif -->
+ <!-- #ifdef H5 -->
+ <svg width="24" height="24" viewBox="25 25 50 50" v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon"
+ :style="{width:iconSize+'px',height:iconSize+'px'}" class="uni-load-more__img uni-load-more__img--android-H5">
+ <circle cx="50" cy="50" r="20" fill="none" :style="{color:color}" :stroke-width="3"></circle>
+ </svg>
+ <!-- #endif -->
+ <!-- #ifndef APP-NVUE || H5 -->
+ <view v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon"
+ :style="{width:iconSize+'px',height:iconSize+'px'}" class="uni-load-more__img uni-load-more__img--android-MP">
+ <view :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
+ <view :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
+ <view :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
+ </view>
+ <!-- #endif -->
+ <!-- #ifndef APP-NVUE -->
+ <view v-else-if="!webviewHide && status === 'loading' && showIcon" :style="{width:iconSize+'px',height:iconSize+'px'}" class="uni-load-more__img uni-load-more__img--ios-H5">
+ <image src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzlBMzU3OTlEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzlBMzU3OUFEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDOUEzNTc5N0Q5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDOUEzNTc5OEQ5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pt+ALSwAAA6CSURBVHja1FsLkFZVHb98LM+F5bHL8khA1iSeiyQBCRM+YGqKUnnJTDLGI0BGZlKDIU2MMglUiDApEZvSsZnQtBRJtKwQNKQMFYeRDR10WOLd8ljYXdh+v8v5fR3Od+797t1dnOnO/Ofce77z+J//+b/P+ZqtXbs2sJ9MJhNUV1cHJ06cCJo3bx7EPc2aNcvpy7pWrVoF+/fvDyoqKoI2bdoE9fX1F7TjN8a+EXBn/fkfvw942Tf+wYMHg9mzZwfjxo0LDhw4EPa1x2MbFw/fOGfPng1qa2tzcCkILsLDydq2bRsunpOTMM7TD/W/tZDZhPdeKD+yGxHhdu3aBV27dg3OnDlzMVANMheLAO3btw8KCwuDmpoaX5OxbgUIMEq7K8IcPnw4KCsrC/r37x8cP378/4cAXAB3vqSkJMuiDhTkw+XcuXNhOWbMmKBly5YhUT8xArhyFvP0BfwRsAuwxJZJsm/nzp2DTp06he/OU+cZ64K6o0ePBkOHDg2GDx8e6gEbJ5Q/NHNuAJQ1hgBeHUDlR7nVTkY8rQAvAi4z34vR/mPs1FoRsaCgIJThI0eOBC1atEiFGGV+5MiRoS45efJkqFjJFXV1dQuA012m2WcwTw98fy6CqBdsaiIO4CScrGPHjvk4odhavPquRtFWXEC25VgkREKOCh/qDSq+vn37htzD/mZTOmOc5U7zKzBPEedygWshcDyWvs30igAbU+6oyMgJBCFhwQE0fccxN60Ay9iebbjoDh06hMowjQxT4fXq1SskArmHZpkArvixp/kWzHdMeArExSJEaiXIjjRjRJ4DaAGWpibLzXN3Fm1vA5teBgh3j1Rv3bp1YgKwPdmf2p9zcyNYYgPKMfY0T5f5nNYdw158nJ8QawW4CLKwiOBSEgO/hok2eBydR+3dYH+PLxA5J8Vv0KBBwenTp0P2JWAx6+yFEBfs8lMY+y0SWMBNI9E4ThKi58VKTg3FQZS1RQF1cz27eC0QHMu+3E0SkUowjhVt5VdaWhp07949ZHv2Qd1EjDXM2cla1M0nl3GxAs3J9yREzyTdFVKVFOaE9qRA8GM0WebRuo9JGZKA7Mv2SeS/Z8+eoQ9BArMfFrLGo6jvxbhHbJZnKX2Rzz1O7QhJJ9Cs2ZMaWIyq/zhdeqPNfIoHd58clIQD+JSXl4dKlyIAuBdVXZwFVWKspSSoxE++h8x4k3uCnEhE4I5KwRiFWGOU0QWKiCYLbdoRMRKAu2kQ9vkfLU6dOhX06NEjlH+yMRZSinnuyWnYosVcji8CEA/6Cg2JF+IIUBqnGKUTCNwtwBN4f89RiK1R96DEgO2o0NDmtEdvVFdVVYV+P3UAPUEs6GFwV3PHmXkD4vh74iDFJysVI/MlaQhwKeBNTLYX5VuA8T4/gZxA4MRGFxDB6R7OmYPfyykGRJbyie+XnGYnQIC/coH9+vULiYrxrkL9ZA9+0ykaHIfEpM7ge8TiJ2CsHYwyMfafAF1yCGBHYIbCVDjDjKt7BeB51D+LgQa6OkG7IDYEEtvQ7lnXLKLtLdLuJBpE4gPUXcW2+PkZwOex+4cGDhwYDBkyRL7/HFcEwUGPo/8uWRUpYnfxGHco8HkewLHLyYmAawAPuIFZxhOpDfJQ8gbUv41yORAptMWBNr6oqMhWird5+u+iHmBb2nhjDV7HWBNQTgK8y11l5NetWzc5ULscAtSj7nbNI0skhWeUZCc0W4nyH/jO4Vz0u1IeYhbk4AiwM6tjxIWByHsoZ9qcIBPJd/y+DwPfBESOmCa/QF3WiZHucLlEDpNxcNhmheEOPgdQNx6/VZFQzFZ5TN08AHXQt2Ii3EdyFuUsPtTcGPhW5iMiCNELvz+Gdn9huG4HUJaW/w3g0wxV0XaG7arG2WeKiUWYM4Y7GO5ezshTARbbWGw/DvXkpp/ivVvE0JVoMxN4rpGzJMhE5Pl+xlATsDIqikP9F9D2z3h9nOksEUFhK+qO4rcPkoalMQ/HqJLIyb3F3JdjrCcw1yZ8joyJLR5gCo54etlag7qIoeNh1N1BRYj3DTFJ0elotxPlVzkGuYAmL0VSJVGAJA41c4Z6A3BzTLfn0HYwYKEI6CUAMzZEWvLsIcQOo1AmmyyM72nHJCfYsogflGV6jEk9vyQZXSuq6w4c16NsGcGZbwOPr+H1RkOk2LEzjNepxQkihHSCQ4ynAYNRx2zMKV92CQMWqj8J0BRE8EShxRFN6YrfCRhC0x3r/Zm4IbQCcmJoV0kMamllccR6FjHqUC5F2R/wS2dcymOlfAKOS4KmzQb5cpNC2MC7JhVn5wjXoJ44rYhLh8n0eXOCorJxa7POjbSlCGVczr34/RsAmrcvo9s+wGp3tzVhntxiXiJ4nvEYb4FJkf0O8HocAePmLvCxnL0AORraVekJk6TYjDabRVXfRE2lCN1h6ZQRN1+InUbsCpKwoBZHh0dODN9JBCUffItXxEavTQkUtnfTVAplCWL3JISz29h4NjotnuSsQKJCk8dF+kJR6RARjrqFVmfPnj3ZbK8cIJ0msd6jgHPGtfVTQ8VLmlvh4mct9sobRmPic0DyDQQnx/NlfYUgyz59+oScsH379pAwXABD32nTpoUHIToESeI5mnbE/UqDdyLcafEBf2MCqgC7NwxIbMREJQ0g4D4sfJwnD+AmRrII05cfMWJE+L1169bQr+fip06dGp4oJ83lmYd5wj/EmMa4TaHivo4EeCguYZBnkB5g2aWA69OIEnUHOaGysjIYMGBAMGnSpODYsWPZwCpFmm4lNq+4gSLQA7jcX8DwtjEyRC8wjabnXEx9kfWnTJkSJkAo90xpJVV+FmcVNeYAF5zWngS4C4O91MBxmAv8blLEpbjI5sz9MTdAhcgkCT1RO8mZkAjfiYpTEvStAS53Uw1vAiUGgZ3GpuQEYvoiBqlIan7kSDHnTwJQFNiPu0+5VxCVYhcZIjNrdXUDdp+Eq5AZ3Gkg8QAyVZRZIk4Tl4QAbF9cXJxNYZMAtAokgs4BrNxEpCtteXg7DDTMDKYNSuQdKsnJBek7HxewvxaosWxLYXtw+cJp18217wql4aKCfBNoEu0O5VU+PhctJ0YeXD4C6JQpyrlpSLTojpGGGN5YwNziChdIZLk4lvLcFJ9jMX3QdiImY9bmGQU+TRUL5CHITTRlgF8D9ouD1MfmLoEPl5xokIumZ2cfgMpHt47IW9N64Hsh7wQYYjyIugWuF5fCqYncXRd5vPMWyizzvhi/32+nvG0dZc9vR6fZOu0md5e+uC408FvKSIOZwXlGvxPv95izA2Vtvg1xKFWARI+vMX66HUhpQQb643uW1bSjuTWyw2SBvDrBvjFic1eGGlz5esq3ko9uSIlBRqPuFcCv8F4WIcN12nVaBd0SaYwI6PDDImR11JkqgHcPmQssjxIn6bUshygDFJUTxPMpHk+jfjPgupgdnYV2R/g7xSjtpah8RJBewhwf0gGK6XI92u4wXFEU40afJ4DN4h5LcAd+40HI3JgJecuT0c062W0i2hQJUTcxan3/CMW1PF2K6bbA+Daz4xRs1D3Br1Cm0OihKCqizW78/nXAF/G5TXrEcVzaNMH6CyMswqsAHqDyDLEyou8lwOXnKF8DjI6KjV3KzMBiXkDH8ij/H214J5A596ekrZ3F0zXlWeL7+P5eUrNo3/QwC15uxthuzidy7DzKRwEDaAViiDgKbTbz7CJnzo0bN7pIfIiid8SuPwn25o3QCmpnyjlZkyxPP8EomCJzrGb7GJMx7tNsq4MT2xMUYaiErZOluTzKsnz3gwCeCZyVRZJfYplNEokEjwrPtxlxjeYAk+F1F74VAzPxQRNYYdtpOUvWs8J1sGhBJMNsb7igN8plJs1eSmLIhLKE4rvaCX27gOhLpLOsIzJ7qn/i+wZzcvSOZ23/du8TZjwV8zHIXoP4R3ifBxiFz1dcVpa3aPntPE+c6TmIWE9EtcMmAcPdWAhYhAXxcLOQi9L1WhD1Sc8p1d2oL7XGiRKp8F4A2i8K/nfI+y/gsTDJ/YC/8+AD5Uh04KHiGl+cIFPnBDDrPMjwRGkLXyxO4VGbfQWnDH2v0bVWE3C9QOXlepbgjEfIJQI6XDG3z5ahD9cw2pS78ipB85wyScNTvsVzlzzhL8/jRrnmVjfFJK/m3m4nj9vbgQTguT8XZTjsm672R5uJKEaQmBI/c58gyus8ZDagLpEVSJBIyHp4jn++xqPV71OgQgJYEWOtZ/haxRtKmWOBu8xdBLftWltsY84zE6WIEy/eIOWL+BaayMx+KHtL7EAkqdNDLiEXmEMUHniedtJqg9HmZtfvt26vNi0BdG3Ft3g8ZOf7PAu59TxtzivLNIekyi+wD1i8CuUiD9FXAa8C+/xS3JPmZnomyc7H+fb4/Se0bk41Fel621r4cgVxbq91V4jVqwB7HTe2M7jgB+QWHavZkDRPmZcASoZEmBx6i75bGjPcMdL4/VKGFAGWZkGzPG0XAbdL9A81G5LOmUnC9hHKJeO7dcUMjblSl12867ElFTtaGl20xvvLGPdVz/8TVuU7y0x1PG7vtNg24oz9Uo/Z412++VFWI7Fcog9tu9Lm6gvRmIPv9x1xmQAu6RDkXtbOtlGEmpgD5Nvnyc0dcv0EE6cfdi1HmhMf9wDF3k3gtRvEedhxjpgfqPb9PU9iEJHnyOUA7bQUXh6kq/D7l2iTjWv7XOD530BDr8jIrus+srXjt4MzumJMHuTsBa63YKE1+RR5lBjEikCCnWKWiHdzOgKO+nRIBAF88za/IFmJ3eMZov4CYxGBabcpGL8EYx+SeMXJeRwHNsV/h+vdxeuhEpN3ZyNY78Gm2fknJxVGhyjixPiQvVkNzT1elD9Py/aTAL64Hb9vcYmC9zfdXdT/C1LeGbg4rnBaAihDFJH12W5ulfNCNe/xTsP3bp8ikzJs5BF+5PNfAQYAPaseTdsEcaYAAAAASUVORK5CYII="
+ mode="widthFix"></image>
+ </view>
+ <!-- #endif -->
+ <text class="uni-load-more__text" :style="{color: color}">{{ status === 'more' ? contentText.contentdown : status === 'loading' ? contentText.contentrefresh : contentText.contentnomore }}</text>
+ </view>
+</template>
+
+<script>
+ let platform
+ setTimeout(() => {
+ platform = uni.getSystemInfoSync().platform
+ }, 16)
+
+ /**
+ * LoadMore 加载更多
+ * @description 用于列表中,做滚动加载使用,展示 loading 的各种状态
+ * @tutorial https://ext.dcloud.net.cn/plugin?id=29
+ * @property {String} status = [more|loading|noMore] loading 的状态
+ * @value more loading前
+ * @value loading loading中
+ * @value noMore 没有更多了
+ * @property {Number} iconSize 指定图标大小
+ * @property {Boolean} iconSize = [true|false] 是否显示 loading 图标
+ * @property {String} iconType = [snow|circle|auto] 指定图标样式
+ * @value snow ios雪花加载样式
+ * @value circle 安卓唤醒加载样式
+ * @value auto 根据平台自动选择加载样式
+ * @property {String} color 图标和文字颜色
+ * @property {Object} contentText 各状态文字说明,值为:{contentdown: "上拉显示更多",contentrefresh: "正在加载...",contentnomore: "没有更多数据了"}
+ * @event {Function} clickLoadMore 点击加载更多时触发
+ */
+ export default {
+ name: 'UniLoadMore',
+ props: {
+ status: {
+ // 上拉的状态:more-loading前;loading-loading中;noMore-没有更多了
+ type: String,
+ default: 'more'
+ },
+ showIcon: {
+ type: Boolean,
+ default: true
+ },
+ iconType: {
+ type: String,
+ default: 'auto'
+ },
+ iconSize: {
+ type: Number,
+ default: 24
+ },
+ color: {
+ type: String,
+ default: '#777777'
+ },
+ contentText: {
+ type: Object,
+ default () {
+ return {
+ contentdown: '上拉显示更多',
+ contentrefresh: '正在加载...',
+ contentnomore: '没有更多数据了'
+ }
+ }
+ }
+ },
+ data() {
+ return {
+ webviewHide: false,
+ platform: platform
+ }
+ },
+ // #ifndef APP-NVUE
+ computed:{
+ iconSnowWidth(){
+ return (Math.floor(this.iconSize/24)||1)*2
+ }
+ },
+ // #endif
+ mounted() {
+ // #ifdef APP-PLUS
+ var pages = getCurrentPages();
+ var page = pages[pages.length - 1];
+ var currentWebview = page.$getAppWebview();
+ currentWebview.addEventListener('hide', () => {
+ this.webviewHide = true
+ })
+ currentWebview.addEventListener('show', () => {
+ this.webviewHide = false
+ })
+ // #endif
+ },
+ methods: {
+ onClick() {
+ this.$emit('clickLoadMore', {
+ detail: {
+ status: this.status,
+ }
+ })
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+
+ .uni-load-more {
+ /* #ifndef APP-NVUE */
+ display: flex;
+ /* #endif */
+ flex-direction: row;
+ height: 40px;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .uni-load-more__text {
+ font-size: 15px;
+ }
+
+ .uni-load-more__img {
+ width: 24px;
+ height: 24px;
+ margin-right: 8px;
+ }
+
+ .uni-load-more__img--nvue {
+ color: #666666;
+ }
+
+ .uni-load-more__img--android,
+ .uni-load-more__img--ios {
+ width: 24px;
+ height: 24px;
+ transform: rotate(0deg);
+ }
+
+ /* #ifndef APP-NVUE */
+ .uni-load-more__img--android {
+ animation: loading-ios 1s 0s linear infinite;
+ }
+
+ @keyframes loading-android {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+
+ .uni-load-more__img--ios-H5 {
+ position: relative;
+ animation: loading-ios-H5 1s 0s step-end infinite;
+ }
+
+ .uni-load-more__img--ios-H5>image {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ left: 0;
+ top: 0;
+ }
+
+ @keyframes loading-ios-H5 {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 8% {
+ transform: rotate(30deg);
+ }
+
+ 16% {
+ transform: rotate(60deg);
+ }
+
+ 24% {
+ transform: rotate(90deg);
+ }
+
+ 32% {
+ transform: rotate(120deg);
+ }
+
+ 40% {
+ transform: rotate(150deg);
+ }
+
+ 48% {
+ transform: rotate(180deg);
+ }
+
+ 56% {
+ transform: rotate(210deg);
+ }
+
+ 64% {
+ transform: rotate(240deg);
+ }
+
+ 73% {
+ transform: rotate(270deg);
+ }
+
+ 82% {
+ transform: rotate(300deg);
+ }
+
+ 91% {
+ transform: rotate(330deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+
+ /* #endif */
+
+ /* #ifdef H5 */
+ .uni-load-more__img--android-H5 {
+ animation: loading-android-H5-rotate 2s linear infinite;
+ transform-origin: center center;
+ }
+
+ .uni-load-more__img--android-H5>circle {
+ display: inline-block;
+ animation: loading-android-H5-dash 1.5s ease-in-out infinite;
+ stroke: currentColor;
+ stroke-linecap: round;
+ }
+
+ @keyframes loading-android-H5-rotate {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+
+ @keyframes loading-android-H5-dash {
+ 0% {
+ stroke-dasharray: 1, 200;
+ stroke-dashoffset: 0;
+ }
+
+ 50% {
+ stroke-dasharray: 90, 150;
+ stroke-dashoffset: -40;
+ }
+
+ 100% {
+ stroke-dasharray: 90, 150;
+ stroke-dashoffset: -120;
+ }
+ }
+
+ /* #endif */
+
+ /* #ifndef APP-NVUE || H5 */
+ .uni-load-more__img--android-MP {
+ position: relative;
+ width: 24px;
+ height: 24px;
+ transform: rotate(0deg);
+ animation: loading-ios 1s 0s ease infinite;
+ }
+
+ .uni-load-more__img--android-MP>view {
+ position: absolute;
+ box-sizing: border-box;
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+ border: solid 2px transparent;
+ border-top: solid 2px #777777;
+ transform-origin: center;
+ }
+
+ .uni-load-more__img--android-MP>view:nth-child(1){
+ animation: loading-android-MP-1 1s 0s linear infinite;
+ }
+
+ .uni-load-more__img--android-MP>view:nth-child(2){
+ animation: loading-android-MP-2 1s 0s linear infinite;
+ }
+
+ .uni-load-more__img--android-MP>view:nth-child(3){
+ animation: loading-android-MP-3 1s 0s linear infinite;
+ }
+
+ @keyframes loading-android {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+
+ @keyframes loading-android-MP-1{
+ 0%{
+ transform: rotate(0deg);
+ }
+ 50%{
+ transform: rotate(90deg);
+ }
+ 100%{
+ transform: rotate(360deg);
+ }
+ }
+ @keyframes loading-android-MP-2{
+ 0%{
+ transform: rotate(0deg);
+ }
+ 50%{
+ transform: rotate(180deg);
+ }
+ 100%{
+ transform: rotate(360deg);
+ }
+ }
+ @keyframes loading-android-MP-3{
+ 0%{
+ transform: rotate(0deg);
+ }
+ 50%{
+ transform: rotate(270deg);
+ }
+ 100%{
+ transform: rotate(360deg);
+ }
+ }
+ /* #endif */
+</style>
diff --git a/components/uni-nav-bar/uni-nav-bar.vue b/components/uni-nav-bar/uni-nav-bar.vue
new file mode 100644
index 0000000..30aa6eb
--- /dev/null
+++ b/components/uni-nav-bar/uni-nav-bar.vue
@@ -0,0 +1,251 @@
+<template>
+ <view class="uni-navbar">
+ <view :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }" :style="{ 'background-color': backgroundColor }"
+ class="uni-navbar__content">
+ <status-bar v-if="statusBar" />
+ <view :style="{ color: color,backgroundColor: backgroundColor }" class="uni-navbar__header uni-navbar__content_view">
+ <view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left uni-navbar__content_view">
+ <view class="uni-navbar__content_view" v-if="leftIcon.length">
+ <uni-icons :color="color" :type="leftIcon" size="24" />
+ </view>
+ <view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length }" class="uni-navbar-btn-text uni-navbar__content_view"
+ v-if="leftText.length">
+ <text :style="{ color: color, fontSize: '14px' }">{{ leftText }}</text>
+ </view>
+ <slot name="left" />
+ </view>
+ <view class="uni-navbar__header-container uni-navbar__content_view" @tap="onClickTitle">
+ <view class="uni-navbar__header-container-inner uni-navbar__content_view" v-if="title.length">
+ <text class="uni-nav-bar-text" :style="{color: color }">{{ title }}</text>
+ </view>
+ <!-- 标题插槽 -->
+ <slot />
+ </view>
+ <view :class="title.length ? 'uni-navbar__header-btns-right' : ''" @tap="onClickRight" class="uni-navbar__header-btns uni-navbar__content_view">
+ <view class="uni-navbar__content_view" v-if="rightIcon.length">
+ <uni-icons :color="color" :type="rightIcon" size="24" />
+ </view>
+ <!-- 优先显示图标 -->
+ <view class="uni-navbar-btn-text uni-navbar__content_view" v-if="rightText.length && !rightIcon.length">
+ <text class="uni-nav-bar-right-text">{{ rightText }}</text>
+ </view>
+ <slot name="right" />
+ </view>
+ </view>
+ </view>
+ <view class="uni-navbar__placeholder" v-if="fixed">
+ <status-bar v-if="statusBar" />
+ <view class="uni-navbar__placeholder-view" />
+ </view>
+ </view>
+</template>
+
+<script>
+ import statusBar from "./uni-status-bar.vue";
+
+ /**
+ * NavBar 自定义导航栏
+ * @description 导航栏组件,主要用于头部导航
+ * @tutorial https://ext.dcloud.net.cn/plugin?id=52
+ * @property {String} title 标题文字
+ * @property {String} leftText 左侧按钮文本
+ * @property {String} rightText 右侧按钮文本
+ * @property {String} leftIcon 左侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
+ * @property {String} rightIcon 右侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
+ * @property {String} color 图标和文字颜色
+ * @property {String} backgroundColor 导航栏背景颜色
+ * @property {Boolean} fixed = [true|false] 是否固定顶部
+ * @property {Boolean} statusBar = [true|false] 是否包含状态栏
+ * @property {Boolean} shadow = [true|false] 导航栏下是否有阴影
+ * @event {Function} clickLeft 左侧按钮点击时触发
+ * @event {Function} clickRight 右侧按钮点击时触发
+ * @event {Function} clickTitle 中间标题点击时触发
+ */
+ export default {
+ name: "UniNavBar",
+ components: {
+ statusBar
+ },
+ props: {
+ title: {
+ type: String,
+ default: ""
+ },
+ leftText: {
+ type: String,
+ default: ""
+ },
+ rightText: {
+ type: String,
+ default: ""
+ },
+ leftIcon: {
+ type: String,
+ default: ""
+ },
+ rightIcon: {
+ type: String,
+ default: ""
+ },
+ fixed: {
+ type: [Boolean, String],
+ default: false
+ },
+ color: {
+ type: String,
+ default: "#000000"
+ },
+ backgroundColor: {
+ type: String,
+ default: "#FFFFFF"
+ },
+ statusBar: {
+ type: [Boolean, String],
+ default: false
+ },
+ shadow: {
+ type: [Boolean, String],
+ default: false
+ },
+ border: {
+ type: [Boolean, String],
+ default: true
+ }
+ },
+ mounted() {
+ if(uni.report && this.title !== '') {
+ uni.report('title', this.title)
+ }
+ },
+ methods: {
+ onClickLeft() {
+ this.$emit("clickLeft");
+ },
+ onClickRight() {
+ this.$emit("clickRight");
+ },
+ onClickTitle() {
+ this.$emit("clickTitle");
+ }
+ }
+ };
+</script>
+
+<style lang="scss" scoped>
+ $nav-height: 44px;
+ .uni-nav-bar-text {
+ /* #ifdef APP-PLUS */
+ font-size: 34rpx;
+ /* #endif */
+ /* #ifndef APP-PLUS */
+ font-size: $uni-font-size-lg;
+ /* #endif */
+ }
+
+ .uni-nav-bar-right-text {
+ font-size: $uni-font-size-base;
+ }
+
+ .uni-navbar__content {
+ position: relative;
+ background-color: $uni-bg-color;
+ overflow: hidden;
+ // width: 750rpx;
+ }
+
+ .uni-navbar__content_view {
+ /* #ifndef APP-NVUE */
+ display: flex;
+ /* #endif */
+ align-items: center;
+ flex-direction: row;
+ // background-color: #FFFFFF;
+ }
+
+ .uni-navbar__header {
+ /* #ifndef APP-NVUE */
+ display: flex;
+ /* #endif */
+ flex-direction: row;
+ height: $nav-height;
+ line-height: $nav-height;
+ font-size: 16px;
+ // background-color: #ffffff;
+ }
+
+ .uni-navbar__header-btns {
+ /* #ifndef APP-NVUE */
+ display: flex;
+ /* #endif */
+ flex-wrap: nowrap;
+ width: 120rpx;
+ padding: 0 6px;
+ justify-content: center;
+ align-items: center;
+ /* #ifdef H5 */
+ cursor: pointer;
+ /* #endif */
+ }
+
+ .uni-navbar__header-btns-left {
+ /* #ifndef APP-NVUE */
+ display: flex;
+ /* #endif */
+ width: 150rpx;
+ justify-content: flex-start;
+ }
+
+ .uni-navbar__header-btns-right {
+ /* #ifndef APP-NVUE */
+ display: flex;
+ /* #endif */
+ width: 150rpx;
+ padding-right: 30rpx;
+ justify-content: flex-end;
+ }
+
+ .uni-navbar__header-container {
+ flex: 1;
+ }
+
+ .uni-navbar__header-container-inner {
+ /* #ifndef APP-NVUE */
+ display: flex;
+ /* #endif */
+ flex: 1;
+ align-items: center;
+ justify-content: center;
+ font-size: $uni-font-size-base;
+ }
+
+
+ .uni-navbar__placeholder-view {
+ height: $nav-height;
+ }
+
+ .uni-navbar--fixed {
+ position: fixed;
+ z-index: 998;
+ /* #ifdef H5 */
+ left: var(--window-left);
+ right: var(--window-right);
+ /* #endif */
+ /* #ifndef H5 */
+ left:0;
+ right: 0;
+ /* #endif */
+
+ }
+
+ .uni-navbar--shadow {
+ /* #ifndef APP-NVUE */
+ box-shadow: 0 1px 6px #ccc;
+ /* #endif */
+ }
+
+ .uni-navbar--border {
+ border-bottom-width: 1rpx;
+ border-bottom-style: solid;
+ border-bottom-color: $uni-border-color;
+ }
+</style>
diff --git a/components/uni-nav-bar/uni-status-bar.vue b/components/uni-nav-bar/uni-status-bar.vue
new file mode 100644
index 0000000..47179d3
--- /dev/null
+++ b/components/uni-nav-bar/uni-status-bar.vue
@@ -0,0 +1,25 @@
+<template>
+ <view :style="{ height: statusBarHeight }" class="uni-status-bar">
+ <slot />
+ </view>
+</template>
+
+<script>
+ var statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px'
+ export default {
+ name: 'UniStatusBar',
+ data() {
+ return {
+ statusBarHeight: statusBarHeight
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ .uni-status-bar {
+ // width: 750rpx;
+ height: 20px;
+ // height: var(--status-bar-height);
+ }
+</style>
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..6575e6a
--- /dev/null
+++ b/package.json
@@ -0,0 +1,24 @@
+{
+ "dependencies": {
+ "@smallwei/avue": "^2.8.14",
+ "axios": "^0.21.1",
+ "js-md5": "^0.7.3",
+ "uni-read-pages": "^1.0.5",
+ "uview-ui": "^1.8.4"
+ },
+ "name": "qfqk-android",
+ "version": "1.0.0",
+ "main": "main.js",
+ "devDependencies": {},
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "http://192.168.0.105:10010/r/qfqk-android.git"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "description": ""
+}
diff --git a/pages/login/login-account.vue b/pages/login/login-account.vue
index bc56f8e..d620843 100644
--- a/pages/login/login-account.vue
+++ b/pages/login/login-account.vue
@@ -3,46 +3,45 @@
<u-navbar :is-fixed="false" :border-bottom="false" :is-back="false" back-icon-name="arrow-leftward" title="登录"
:background="{ background: '#fff' }" title-color="#000000">
<view class="" slot="right">
- <image src="/static/images/user/c8.png" class="set-icon" mode="widthFix"></image>
+ <image src="/static/images/login/c8.png" class="set-icon" mode="widthFix"></image>
</view>
</u-navbar>
<view class="content">
<view class="top">
- <image src="/static/images/logo.png" class="logo" mode="widthFix"></image>
+ <view class="titie">
+ <span>智慧保安互联网APP</span>
+ </view>
<view class="cell">
<view class="name">账号</view>
<view class="input-box">
- <input type="text" v-model="username" placeholder="请输入账号" class="ipt" placeholder-class="hold"
+ <input type="text" v-model="names" placeholder="请输入账号" class="ipt" placeholder-class="hold"
@blur="handleInputCheck" />
</view>
</view>
<view class="cell">
<view class="name">密码</view>
<view class="input-box">
- <input type="password" v-model="password" placeholder="请输入密码" class="ipt"
+ <input type="password" v-model="passwords" placeholder="请输入密码" class="ipt"
placeholder-class="hold" @blur="handleInputCheck" />
</view>
</view>
+
<!-- <view class="agree">
登录即代表同意
<text class="a">《用户协议》</text>
和
<text class="a">《隐私政策》</text>
</view> -->
- <button class="submit" @click="submit" :disabled="disabled">登录</button>
- <view class="tip">未注册用户验证后将自动注册并登录</view>
- <navigator url="/pages/login/login-phone" hover-class="none" class="change">手机登录 ></navigator>
+ <button class="submit" @click="longing(names,passwords)" :disabled="disabled">登录</button>
+ <view class="tip">未注册用户注册审核通过后才可登录</view>
+ <navigator url="/pages/registerUser/registerUser" hover-class="none" class="change">注册 ></navigator>
</view>
<!-- 社交账号登录 -->
<view class="bottom">
- <view class="tag">社交账号登录</view>
- <view class="chat-arr">
- <image src="/static/images/wx.png" class="icon" mode=""></image>
- <image src="/static/images/qq.png" class="icon" mode=""></image>
- <image src="/static/images/wb.png" class="icon" mode=""></image>
- </view>
+ <view class="tag"></view>
+ <!-- <view class="tsp">江西北邮信息通信技术有限公司</view> -->
</view>
</view>
<!-- -->
@@ -50,39 +49,131 @@
</template>
<script>
- import md5 from '@/utils/md5.js'
+ import WxStorage from "../../static/lib/wxStorage.js" //微信Storage
export default {
data() {
return {
- tenantId: '000000',
- username: '',
- password: '',
+ icons: '',
+ names: '',
+ passwords: '',
+ msg: '',
+ colors: '#123456',
disabled: true
- };
+ }
+ },
+ computed: {
+ OURpass() {
+ return this.$store.state.loging;
+ }
},
methods: {
- submit() {
- this.$u.api.token(this.tenantId, this.username, md5(this.password)).then(data => {
- this.$u.func.login(data)
- }).catch(err => {
- console.log(err)
- this.$u.func.showToast({
- title: '用户名或密码错误',
- })
- })
+ judgeUse() {
+ var login = WxStorage.get("init") //重复登录
+ var name = WxStorage.get("name")
+ var userID = WxStorage.get("ids")
+ var accounts = WxStorage.get("accounts");
+ var pass = WxStorage.get("pass");
+ console.log(login);
+ if (login == "true" && name != '') {
+ //获取用户信息
+ var data = {
+ userName: name,
+ userID: userID
+ }
+ this.$store.commit('getUse', data)
+ // wx.reLaunch({
+ // url: '/pages/alarm_list/alarm_list?login=' + data.userName
+ // })
+ this.names = accounts;
+ this.passwords = pass;
+ }
+ },
+ judgeMsg() {
+ this.msg = this.names == '' ? (this.passwords == '' ? '账号密码不能为空' : '账号不能为空') : (this.passwords == '' ?
+ '密码不能为空' : this.passwords.length <= 5 ? '密码最少6位' :
+ '格式正确');
+ if (this.msg == "格式正确") {
+ this.icons = 'success';
+ this.colors = '#4ac503';
+ this.disabled = false
+ } else {
+ this.icons = 'warn';
+ this.colors = '#d53c00';
+ }
+ },
+ longing(name, pass) {
+ var data = {
+ name: name,
+ pass: pass,
+ }
+ this.judgeMsg();
+ if (this.msg == "格式正确") {
+ uni.showNavigationBarLoading();
+ this.$store.dispatch('loging', data)
+ }else{
+ uni.showToast({
+ title: '格式错误,请重试',
+ icon:'none',
+ duration: 2000
+ });
+ }
},
handleInputCheck() {
- this.disabled = false
+ //this.disabled = false
},
+ zhuce(){
+ uni.navigateTo({
+ url:'/pages/registerUser/registerUser'
+ })
+ }
+ },
+ created() {
+ this.judgeUse();
+ },
+ watch: {
+ names() {
+ this.judgeMsg();
+ },
+ passwords() {
+ this.judgeMsg();
+ },
+ OURpass() {
+ if (this.OURpass == true) {
+ this.passwords = '******';
+ uni.hideNavigationBarLoading();
+ uni.reLaunch({
+ url: '../home/home'
+ })
+ return '成功登录'
+ } else {
+ this.icons = 'warn';
+ this.colors = '#d53c00';
+ this.msg = '账号密码错误';
+ this.$store.commit('loginReset', this); //重置登录
+ uni.hideNavigationBarLoading();
+ return '未成功登录'
+ }
+ }
}
- };
+ }
</script>
<style lang="scss">
+ .titie{
+ display: block;
+ width: 420rpx;
+ height: auto;
+ margin: 0 auto 120rpx;
+ span {
+ font-weight: 600;
+ font-size: 6vw;
+ color: #14b9c8;
+ }
+ }
.container {
min-height: 100vh;
overflow: hidden;
-
+
.set-icon {
vertical-align: middle;
width: 41rpx;
@@ -90,33 +181,33 @@
margin-right: 35rpx;
}
}
-
+
.content {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
-
+
height: 90vh;
width: 100%;
-
+
.top {
width: 100%;
}
-
+
.logo {
display: block;
width: 281rpx;
height: auto;
margin: 0 auto 120rpx;
}
-
+
.cell {
width: 100%;
padding: 0 85rpx;
box-sizing: border-box;
margin-top: 36rpx;
-
+
.name {
font-size: 22rpx;
font-family: Source Han Sans CN;
@@ -125,31 +216,31 @@
line-height: 30rpx;
opacity: 0.72;
}
-
+
.input-box {
padding: 30rpx 0;
border-bottom: 2rpx solid #f6f6f6;
display: flex;
align-items: center;
-
+
.code {
font-size: 22rpx;
font-family: Source Han Sans CN;
font-weight: 400;
color: #0d0d0d;
line-height: 30rpx;
-
+
text {
color: #14b9c8;
}
}
-
+
.ipt {
flex: 1;
// height: 24rpx;
font-size: 24rpx;
}
-
+
.hold {
font-size: 26rpx;
font-family: Source Han Sans CN;
@@ -160,7 +251,7 @@
}
}
}
-
+
.agree {
margin: 27rpx 95rpx 0;
font-size: 22rpx;
@@ -168,12 +259,12 @@
font-weight: normal;
color: #cacaca;
line-height: 34rpx;
-
+
.a {
color: #000000;
}
}
-
+
.submit {
margin: 60rpx 90rpx 0;
border: none;
@@ -184,15 +275,15 @@
border-radius: 15rpx;
background-color: #14b9c8;
color: #ffffff;
-
+
&::after {
content: none;
}
-
+
&::before {
content: none;
}
-
+
&[disabled='true'] {
background: #e4e4e4;
font-size: 36rpx;
@@ -201,7 +292,7 @@
color: #ffffff;
}
}
-
+
.tip {
margin-top: 30rpx;
text-align: center;
@@ -211,7 +302,16 @@
color: #cacaca;
line-height: 34rpx;
}
-
+ .tsp {
+ margin-top: 30rpx;
+ text-align: center;
+ font-size: 28rpx;
+ font-family: Adobe Heiti Std;
+ font-weight: normal;
+ color: #a8a8a8;
+ line-height: 34rpx;
+ }
+
.change {
margin-top: 20rpx;
text-align: center;
@@ -221,7 +321,7 @@
color: #14b9c8;
line-height: 34rpx;
}
-
+
.tag {
display: flex;
justify-content: center;
@@ -231,7 +331,7 @@
font-weight: normal;
color: #9f9f9f;
line-height: 34rpx;
-
+
&::before {
content: '';
display: block;
@@ -240,7 +340,7 @@
background: #d8d8d8;
opacity: 0.86;
}
-
+
&::after {
content: '';
display: block;
@@ -250,13 +350,13 @@
opacity: 0.86;
}
}
-
+
.chat-arr {
margin-top: 50rpx;
display: flex;
align-items: center;
justify-content: space-between;
-
+
.icon {
width: 73rpx;
height: 73rpx;
diff --git a/router/router.js b/router/router.js
new file mode 100644
index 0000000..75082d1
--- /dev/null
+++ b/router/router.js
@@ -0,0 +1,38 @@
+// router.js
+import {
+ RouterMount,
+ createRouter
+} from 'uni-simple-router';
+import WxStorage from "../static/lib/wxStorage.js" //微信Storage
+
+const router = createRouter({
+ platform: process.env.VUE_APP_PLATFORM,
+ routes: [...ROUTES]
+});
+//全局路由前置守卫
+router.beforeEach((to, from, next) => {
+ console.log('跳转开始')
+ if (to.name == 'loging') {
+ next();
+ return
+ }
+ var inTher = WxStorage.get("init");
+ console.log(inTher);
+ if (inTher == "false") {
+ next({
+ name: 'loging'
+ });
+ } else if (inTher == "true") {
+ next();
+ }
+
+});
+// 全局路由后置守卫
+router.afterEach((to, from) => {
+ console.log('跳转结束')
+})
+
+export {
+ router,
+ RouterMount
+}
diff --git a/static/lib/axios.js b/static/lib/axios.js
new file mode 100644
index 0000000..fc6c8b6
--- /dev/null
+++ b/static/lib/axios.js
@@ -0,0 +1,3 @@
+/* axios v0.21.1 | (c) 2020 by Matt Zabriskie */
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.axios=t():e.axios=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";function r(e){var t=new i(e),n=s(i.prototype.request,t);return o.extend(n,i.prototype,t),o.extend(n,t),n}var o=n(2),s=n(3),i=n(4),a=n(22),u=n(10),c=r(u);c.Axios=i,c.create=function(e){return r(a(c.defaults,e))},c.Cancel=n(23),c.CancelToken=n(24),c.isCancel=n(9),c.all=function(e){return Promise.all(e)},c.spread=n(25),c.isAxiosError=n(26),e.exports=c,e.exports.default=c},function(e,t,n){"use strict";function r(e){return"[object Array]"===R.call(e)}function o(e){return"undefined"==typeof e}function s(e){return null!==e&&!o(e)&&null!==e.constructor&&!o(e.constructor)&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function i(e){return"[object ArrayBuffer]"===R.call(e)}function a(e){return"undefined"!=typeof FormData&&e instanceof FormData}function u(e){var t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer}function c(e){return"string"==typeof e}function f(e){return"number"==typeof e}function p(e){return null!==e&&"object"==typeof e}function d(e){if("[object Object]"!==R.call(e))return!1;var t=Object.getPrototypeOf(e);return null===t||t===Object.prototype}function l(e){return"[object Date]"===R.call(e)}function h(e){return"[object File]"===R.call(e)}function m(e){return"[object Blob]"===R.call(e)}function y(e){return"[object Function]"===R.call(e)}function g(e){return p(e)&&y(e.pipe)}function v(e){return"undefined"!=typeof URLSearchParams&&e instanceof URLSearchParams}function x(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function w(){return("undefined"==typeof navigator||"ReactNative"!==navigator.product&&"NativeScript"!==navigator.product&&"NS"!==navigator.product)&&("undefined"!=typeof window&&"undefined"!=typeof document)}function b(e,t){if(null!==e&&"undefined"!=typeof e)if("object"!=typeof e&&(e=[e]),r(e))for(var n=0,o=e.length;n<o;n++)t.call(null,e[n],n,e);else for(var s in e)Object.prototype.hasOwnProperty.call(e,s)&&t.call(null,e[s],s,e)}function E(){function e(e,n){d(t[n])&&d(e)?t[n]=E(t[n],e):d(e)?t[n]=E({},e):r(e)?t[n]=e.slice():t[n]=e}for(var t={},n=0,o=arguments.length;n<o;n++)b(arguments[n],e);return t}function j(e,t,n){return b(t,function(t,r){n&&"function"==typeof t?e[r]=S(t,n):e[r]=t}),e}function C(e){return 65279===e.charCodeAt(0)&&(e=e.slice(1)),e}var S=n(3),R=Object.prototype.toString;e.exports={isArray:r,isArrayBuffer:i,isBuffer:s,isFormData:a,isArrayBufferView:u,isString:c,isNumber:f,isObject:p,isPlainObject:d,isUndefined:o,isDate:l,isFile:h,isBlob:m,isFunction:y,isStream:g,isURLSearchParams:v,isStandardBrowserEnv:w,forEach:b,merge:E,extend:j,trim:x,stripBOM:C}},function(e,t){"use strict";e.exports=function(e,t){return function(){for(var n=new Array(arguments.length),r=0;r<n.length;r++)n[r]=arguments[r];return e.apply(t,n)}}},function(e,t,n){"use strict";function r(e){this.defaults=e,this.interceptors={request:new i,response:new i}}var o=n(2),s=n(5),i=n(6),a=n(7),u=n(22);r.prototype.request=function(e){"string"==typeof e?(e=arguments[1]||{},e.url=arguments[0]):e=e||{},e=u(this.defaults,e),e.method?e.method=e.method.toLowerCase():this.defaults.method?e.method=this.defaults.method.toLowerCase():e.method="get";var t=[a,void 0],n=Promise.resolve(e);for(this.interceptors.request.forEach(function(e){t.unshift(e.fulfilled,e.rejected)}),this.interceptors.response.forEach(function(e){t.push(e.fulfilled,e.rejected)});t.length;)n=n.then(t.shift(),t.shift());return n},r.prototype.getUri=function(e){return e=u(this.defaults,e),s(e.url,e.params,e.paramsSerializer).replace(/^\?/,"")},o.forEach(["delete","get","head","options"],function(e){r.prototype[e]=function(t,n){return this.request(u(n||{},{method:e,url:t,data:(n||{}).data}))}}),o.forEach(["post","put","patch"],function(e){r.prototype[e]=function(t,n,r){return this.request(u(r||{},{method:e,url:t,data:n}))}}),e.exports=r},function(e,t,n){"use strict";function r(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}var o=n(2);e.exports=function(e,t,n){if(!t)return e;var s;if(n)s=n(t);else if(o.isURLSearchParams(t))s=t.toString();else{var i=[];o.forEach(t,function(e,t){null!==e&&"undefined"!=typeof e&&(o.isArray(e)?t+="[]":e=[e],o.forEach(e,function(e){o.isDate(e)?e=e.toISOString():o.isObject(e)&&(e=JSON.stringify(e)),i.push(r(t)+"="+r(e))}))}),s=i.join("&")}if(s){var a=e.indexOf("#");a!==-1&&(e=e.slice(0,a)),e+=(e.indexOf("?")===-1?"?":"&")+s}return e}},function(e,t,n){"use strict";function r(){this.handlers=[]}var o=n(2);r.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},r.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},r.prototype.forEach=function(e){o.forEach(this.handlers,function(t){null!==t&&e(t)})},e.exports=r},function(e,t,n){"use strict";function r(e){e.cancelToken&&e.cancelToken.throwIfRequested()}var o=n(2),s=n(8),i=n(9),a=n(10);e.exports=function(e){r(e),e.headers=e.headers||{},e.data=s(e.data,e.headers,e.transformRequest),e.headers=o.merge(e.headers.common||{},e.headers[e.method]||{},e.headers),o.forEach(["delete","get","head","post","put","patch","common"],function(t){delete e.headers[t]});var t=e.adapter||a.adapter;return t(e).then(function(t){return r(e),t.data=s(t.data,t.headers,e.transformResponse),t},function(t){return i(t)||(r(e),t&&t.response&&(t.response.data=s(t.response.data,t.response.headers,e.transformResponse))),Promise.reject(t)})}},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t,n){return r.forEach(n,function(n){e=n(e,t)}),e}},function(e,t){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},function(e,t,n){"use strict";function r(e,t){!s.isUndefined(e)&&s.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}function o(){var e;return"undefined"!=typeof XMLHttpRequest?e=n(12):"undefined"!=typeof process&&"[object process]"===Object.prototype.toString.call(process)&&(e=n(12)),e}var s=n(2),i=n(11),a={"Content-Type":"application/x-www-form-urlencoded"},u={adapter:o(),transformRequest:[function(e,t){return i(t,"Accept"),i(t,"Content-Type"),s.isFormData(e)||s.isArrayBuffer(e)||s.isBuffer(e)||s.isStream(e)||s.isFile(e)||s.isBlob(e)?e:s.isArrayBufferView(e)?e.buffer:s.isURLSearchParams(e)?(r(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):s.isObject(e)?(r(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(e){}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,validateStatus:function(e){return e>=200&&e<300}};u.headers={common:{Accept:"application/json, text/plain, */*"}},s.forEach(["delete","get","head"],function(e){u.headers[e]={}}),s.forEach(["post","put","patch"],function(e){u.headers[e]=s.merge(a)}),e.exports=u},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t){r.forEach(e,function(n,r){r!==t&&r.toUpperCase()===t.toUpperCase()&&(e[t]=n,delete e[r])})}},function(e,t,n){"use strict";var r=n(2),o=n(13),s=n(16),i=n(5),a=n(17),u=n(20),c=n(21),f=n(14);e.exports=function(e){return new Promise(function(t,n){var p=e.data,d=e.headers;r.isFormData(p)&&delete d["Content-Type"];var l=new XMLHttpRequest;if(e.auth){var h=e.auth.username||"",m=e.auth.password?unescape(encodeURIComponent(e.auth.password)):"";d.Authorization="Basic "+btoa(h+":"+m)}var y=a(e.baseURL,e.url);if(l.open(e.method.toUpperCase(),i(y,e.params,e.paramsSerializer),!0),l.timeout=e.timeout,l.onreadystatechange=function(){if(l&&4===l.readyState&&(0!==l.status||l.responseURL&&0===l.responseURL.indexOf("file:"))){var r="getAllResponseHeaders"in l?u(l.getAllResponseHeaders()):null,s=e.responseType&&"text"!==e.responseType?l.response:l.responseText,i={data:s,status:l.status,statusText:l.statusText,headers:r,config:e,request:l};o(t,n,i),l=null}},l.onabort=function(){l&&(n(f("Request aborted",e,"ECONNABORTED",l)),l=null)},l.onerror=function(){n(f("Network Error",e,null,l)),l=null},l.ontimeout=function(){var t="timeout of "+e.timeout+"ms exceeded";e.timeoutErrorMessage&&(t=e.timeoutErrorMessage),n(f(t,e,"ECONNABORTED",l)),l=null},r.isStandardBrowserEnv()){var g=(e.withCredentials||c(y))&&e.xsrfCookieName?s.read(e.xsrfCookieName):void 0;g&&(d[e.xsrfHeaderName]=g)}if("setRequestHeader"in l&&r.forEach(d,function(e,t){"undefined"==typeof p&&"content-type"===t.toLowerCase()?delete d[t]:l.setRequestHeader(t,e)}),r.isUndefined(e.withCredentials)||(l.withCredentials=!!e.withCredentials),e.responseType)try{l.responseType=e.responseType}catch(t){if("json"!==e.responseType)throw t}"function"==typeof e.onDownloadProgress&&l.addEventListener("progress",e.onDownloadProgress),"function"==typeof e.onUploadProgress&&l.upload&&l.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then(function(e){l&&(l.abort(),n(e),l=null)}),p||(p=null),l.send(p)})}},function(e,t,n){"use strict";var r=n(14);e.exports=function(e,t,n){var o=n.config.validateStatus;n.status&&o&&!o(n.status)?t(r("Request failed with status code "+n.status,n.config,null,n.request,n)):e(n)}},function(e,t,n){"use strict";var r=n(15);e.exports=function(e,t,n,o,s){var i=new Error(e);return r(i,t,n,o,s)}},function(e,t){"use strict";e.exports=function(e,t,n,r,o){return e.config=t,n&&(e.code=n),e.request=r,e.response=o,e.isAxiosError=!0,e.toJSON=function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:this.config,code:this.code}},e}},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){return{write:function(e,t,n,o,s,i){var a=[];a.push(e+"="+encodeURIComponent(t)),r.isNumber(n)&&a.push("expires="+new Date(n).toGMTString()),r.isString(o)&&a.push("path="+o),r.isString(s)&&a.push("domain="+s),i===!0&&a.push("secure"),document.cookie=a.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},function(e,t,n){"use strict";var r=n(18),o=n(19);e.exports=function(e,t){return e&&!r(t)?o(e,t):t}},function(e,t){"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},function(e,t){"use strict";e.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},function(e,t,n){"use strict";var r=n(2),o=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];e.exports=function(e){var t,n,s,i={};return e?(r.forEach(e.split("\n"),function(e){if(s=e.indexOf(":"),t=r.trim(e.substr(0,s)).toLowerCase(),n=r.trim(e.substr(s+1)),t){if(i[t]&&o.indexOf(t)>=0)return;"set-cookie"===t?i[t]=(i[t]?i[t]:[]).concat([n]):i[t]=i[t]?i[t]+", "+n:n}}),i):i}},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){function e(e){var t=e;return n&&(o.setAttribute("href",t),t=o.href),o.setAttribute("href",t),{href:o.href,protocol:o.protocol?o.protocol.replace(/:$/,""):"",host:o.host,search:o.search?o.search.replace(/^\?/,""):"",hash:o.hash?o.hash.replace(/^#/,""):"",hostname:o.hostname,port:o.port,pathname:"/"===o.pathname.charAt(0)?o.pathname:"/"+o.pathname}}var t,n=/(msie|trident)/i.test(navigator.userAgent),o=document.createElement("a");return t=e(window.location.href),function(n){var o=r.isString(n)?e(n):n;return o.protocol===t.protocol&&o.host===t.host}}():function(){return function(){return!0}}()},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t){function n(e,t){return r.isPlainObject(e)&&r.isPlainObject(t)?r.merge(e,t):r.isPlainObject(t)?r.merge({},t):r.isArray(t)?t.slice():t}function o(o){r.isUndefined(t[o])?r.isUndefined(e[o])||(s[o]=n(void 0,e[o])):s[o]=n(e[o],t[o])}t=t||{};var s={},i=["url","method","data"],a=["headers","auth","proxy","params"],u=["baseURL","transformRequest","transformResponse","paramsSerializer","timeout","timeoutMessage","withCredentials","adapter","responseType","xsrfCookieName","xsrfHeaderName","onUploadProgress","onDownloadProgress","decompress","maxContentLength","maxBodyLength","maxRedirects","transport","httpAgent","httpsAgent","cancelToken","socketPath","responseEncoding"],c=["validateStatus"];r.forEach(i,function(e){r.isUndefined(t[e])||(s[e]=n(void 0,t[e]))}),r.forEach(a,o),r.forEach(u,function(o){r.isUndefined(t[o])?r.isUndefined(e[o])||(s[o]=n(void 0,e[o])):s[o]=n(void 0,t[o])}),r.forEach(c,function(r){r in t?s[r]=n(e[r],t[r]):r in e&&(s[r]=n(void 0,e[r]))});var f=i.concat(a).concat(u).concat(c),p=Object.keys(e).concat(Object.keys(t)).filter(function(e){return f.indexOf(e)===-1});return r.forEach(p,o),s}},function(e,t){"use strict";function n(e){this.message=e}n.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},n.prototype.__CANCEL__=!0,e.exports=n},function(e,t,n){"use strict";function r(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise(function(e){t=e});var n=this;e(function(e){n.reason||(n.reason=new o(e),t(n.reason))})}var o=n(23);r.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},r.source=function(){var e,t=new r(function(t){e=t});return{token:t,cancel:e}},e.exports=r},function(e,t){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}},function(e,t){"use strict";e.exports=function(e){return"object"==typeof e&&e.isAxiosError===!0}}])});
+//# sourceMappingURL=axios.min.map
\ No newline at end of file
diff --git a/static/lib/wxStorage.js b/static/lib/wxStorage.js
new file mode 100644
index 0000000..e2a8c38
--- /dev/null
+++ b/static/lib/wxStorage.js
@@ -0,0 +1,27 @@
+const _getStorage = (key)=>{
+ return wx.getStorageSync( key );
+}
+
+// 设置本地存储对应key
+const _setStorage = (key,value)=>{
+ return wx.setStorageSync( key,value );
+}
+
+// 清除全部本地存储
+const _clearStorage = ()=>{
+ wx.clearStorageSync();
+}
+
+// 清除指定key本地存储
+const _removeStorage = ( key )=>{
+ wx.removeStorageSync( key );
+}
+
+const WxStorage = {
+ get : _getStorage,
+ set : _setStorage,
+ clear : _clearStorage,
+ remov : _removeStorage,
+}
+
+export default WxStorage
\ No newline at end of file
diff --git a/store/actions.js b/store/actions.js
new file mode 100644
index 0000000..c144777
--- /dev/null
+++ b/store/actions.js
@@ -0,0 +1,90 @@
+import md5 from 'js-md5'
+import axios from 'axios'
+const actions = {
+ loging(store, data) {
+ var user = [{
+ name: '1',
+ password: '111111'
+ },
+ {
+ name: '2',
+ password: '222222'
+ },
+ {
+ name: '3',
+ password: '333333'
+ },
+ ],
+ pasw = md5(data.pass),
+ url = 'http://s16s652780.51mypc.cn/api/blade-auth/oauth/token?tenantId=963841&username=' + data.name +
+ ' &password=' + pasw + '&grant_type=password&scope=all&type=account';
+ // url ='http://192.168.0.109:82/blade-auth/oauth/token';
+ // url ='http://192.168.0.109:82/blade-auth/oauth/token?tenantId=000000&username=admin&password=93369e86dc5fa854a0eaf75558c4039d&grant_type=password';
+ // url ='http://web.byisf.com/api/blade-auth/oauth/token?tenantId=000000&username=admin&password=93369e86dc5fa854a0eaf75558c4039d&grant_type=password&scope=all';
+ // console.log(url);
+ wx.request({ //uniapp 自带axios
+ url: url, //仅为示例,并非真实接口地址。
+ // data: d,
+ // data: {
+ // tenantId: '000000',
+ // username: data.name,
+ // password: pasw,
+ // grant_type: 'password',
+ // scope: 'all',
+ // type: "account"
+ // },
+ header: {
+ // "Content-Type":"",
+ "Authorization": "Basic c2FiZXI6c2FiZXJfc2VjcmV0",
+ "Tenant-Id": "963841"
+
+ // "Cookie": "JSESSIONID=maOJY05vT2jj4nHwsQGSPgWWVFH1mY-TGWOLYCSh"
+ },
+ method: "post",
+ // // dataType: 'JSON',
+ success: (res) => {
+ if (res.statusCode == 200) {
+ if(res.data.error_code == "400"){
+ uni.showToast({
+ title: '密码错误,请重试',
+ icon:'none',
+ duration: 2000
+ });
+ return;
+ }
+ store.commit('getUserData',res.data)
+ // console.log(res.data,123542);
+ data.isit = true;
+ data.userName = res.data.nick_name; //警袁姓名
+ data.userID = res.data.user_id; //警袁id
+ data.avatar = res.data.avatar; //头像
+ data.accounts = data.name;
+ data.pass = data.pass;
+ // data.userPhon = res.user_id;
+ store.commit('login', data);
+ }
+ },
+ fail: (res) => {
+ console.log('失去连接 请稍等');
+ // console.log(res);
+ }
+ });
+ // var time = setTimeout(() => { //模拟请求时间
+ // var ud = user,
+ // isit = false;
+ // for (var key in ud) {
+ // if (ud[key].name == data.name && ud[key].password == data.pass) {
+ // isit = true;
+ // break;
+ // } else {
+ // isit = false;
+ // }
+ // }
+ // data.isit = isit;
+ // store.commit('login', data);
+ // }, 2000)
+
+ }
+}
+
+export default actions
diff --git a/store/index.js b/store/index.js
index 8d35dd4..74276f9 100644
--- a/store/index.js
+++ b/store/index.js
@@ -1,5 +1,7 @@
import Vue from 'vue'
import Vuex from 'vuex'
+import mutations from './mutations.js'
+import actions from './actions.js'
Vue.use(Vuex)
let lifeData = {};
@@ -41,29 +43,48 @@
isLogin: lifeData.isLogin ? lifeData.isLogin : false,
// 如果version无需保存到本地永久存储,无需lifeData.version方式
version: '1.0.0',
+ loging: false,
+ message: {
+ useName: '过客 ',
+ },
+ logPath: '',
+ piAPI: 'http://s16s652780.51mypc.cn/api/',
+ // piAPI: 'http://localhost:82/',
+ puserName: '',
+ puserID: '',
+ puserIphone:'',
+ avatar:"../../static/logo.png",
+ UserData: {},
+ tabbar:[{
+ iconPath: "/static/tabbar/index01.png",
+ selectedIconPath: "/static/tabbar/index02.png",
+ text: '首页',
+ pagePath: "/pages/home/home"
+ },
+ {
+ iconPath: "/static/tabbar/article.png",
+ selectedIconPath: "/static/tabbar/articleH.png",
+ text: '资讯',
+ pagePath: "/pages/article/article"
+ },
+ {
+ iconPath: "/static/tabbar/workbench.png",
+ selectedIconPath: "/static/tabbar/workbenchH.png",
+ text: '工作台',
+ count: 2,
+ isDot: false,
+ pagePath: "/pages/business/business"
+ },
+ {
+ iconPath: "/static/tabbar/my.png",
+ selectedIconPath: "/static/tabbar/my-blue.png",
+ text: '我的',
+ pagePath: "/pages/myself/myself"
+ },
+ ]
},
- mutations: {
- $uStore(state, payload) {
- // 判断是否多层级调用,state中为对象存在的情况,诸如user.info.score = 1
- let nameArr = payload.name.split('.');
- let saveKey = '';
- let len = nameArr.length;
- if (nameArr.length >= 2) {
- let obj = state[nameArr[0]];
- for (let i = 1; i < len - 1; i++) {
- obj = obj[nameArr[i]];
- }
- obj[nameArr[len - 1]] = payload.value;
- saveKey = nameArr[0];
- } else {
- // 单层级变量,在state就是一个普通变量的情况
- state[payload.name] = payload.value;
- saveKey = payload.name;
- }
- // 保存变量到本地,见顶部函数定义
- saveLifeData(saveKey, state[saveKey])
- }
- }
+ mutations: mutations,
+ actions:actions
})
export default store
diff --git a/store/mutations.js b/store/mutations.js
new file mode 100644
index 0000000..c3df85f
--- /dev/null
+++ b/store/mutations.js
@@ -0,0 +1,54 @@
+import WxStorage from "../static/lib/wxStorage.js" //微信Storage
+
+const mutations = {
+ $uStore(state, payload) {
+ // 判断是否多层级调用,state中为对象存在的情况,诸如user.info.score = 1
+ let nameArr = payload.name.split('.');
+ let saveKey = '';
+ let len = nameArr.length;
+ if (nameArr.length >= 2) {
+ let obj = state[nameArr[0]];
+ for (let i = 1; i < len - 1; i++) {
+ obj = obj[nameArr[i]];
+ }
+ obj[nameArr[len - 1]] = payload.value;
+ saveKey = nameArr[0];
+ } else {
+ // 单层级变量,在state就是一个普通变量的情况
+ state[payload.name] = payload.value;
+ saveKey = payload.name;
+ }
+ // 保存变量到本地,见顶部函数定义
+ saveLifeData(saveKey, state[saveKey])
+ },
+ login(state, data) {
+ // console.log(data);
+ state.loging = data.isit; //登录状态
+ if (data.isit) { //写入用户数据
+ state.message.useName = data.userName;
+ state.puserName = data.userName;
+ state.puserID = data.userID;
+ state.avatar = data.avatar;
+ }
+ //储存用户
+ WxStorage.set("init", "true");
+ WxStorage.set("name", data.userName);
+ WxStorage.set("ids", data.userID);
+ WxStorage.set("accounts", data.accounts);
+ WxStorage.set("pass", data.pass);
+ },
+ loginReset(state) { //重置
+ state.loging = false;
+ state.message.useName = '过客 ';
+ WxStorage.clear();
+ },
+ getUse(state,data){
+ state.puserName = data.userName;
+ state.puserID = data.userID;
+ },
+ getUserData(state,data){
+ state.UserData = data;
+ }
+}
+
+export default mutations
--
Gitblit v1.9.3