作者 卢胜

bugxiugai

要显示太多修改。

为保证性能只显示 37 of 37+ 个文件。

... ... @@ -14,7 +14,6 @@
console.log('获取code');
getApp().authorization()
} else if (e.query.code) {
console.log(2);
getApp().getOpenid(e.query.code)
}
// else {
... ... @@ -106,7 +105,12 @@
display: flex;
align-items: center;
}
.flexbetom {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
}
.fw700 {
font-weight: 700;
}
... ...
... ... @@ -48,6 +48,9 @@ export const sort_list = (data) => request({url: 'arc/sort_list',method: 'post'
export const arc_list = (data) => request({url: 'arc/arc_list',method: 'post',data: data})
// 详情资讯
export const arc_detail = (arc_id) => request({url: 'arc/arc_detail',method: 'post',data: {arc_id}})
export const arc_detail = (arc_id,url) => request({url: 'arc/arc_detail',method: 'post',data: {arc_id,url}})
// 全部分类
export const sort_all = (keyword) => request({url: 'product/sort_all',method: 'post',data: {keyword}})
\ No newline at end of file
export const sort_all = (keyword) => request({url: 'product/sort_all',method: 'post',data: {keyword}})
//搜索弹窗分类
export const sort_search = (keyword) => request({url: 'product/sort_search',method: 'post',data: {keyword}})
... ...
<template>
<!--增加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>
... ...
<template>
<image
:mode="node.attr.mode"
: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,
};
},
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;
const { width, height } = e.mp.detail;
const recal = this.wxAutoImageCal(width, height);
const { imageheight, imageWidth } = recal;
const { padding, mode } = this.node.attr;
const { styleStr } = this.node;
const imageHeightStyle = mode === 'widthFix' ? '' : `height: ${imageheight}px;`;
this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px; padding: 0 ${+padding}px;`;
},
// 计算视觉优先的图片宽高
wxAutoImageCal(originalWidth, originalHeight) {
// 获取图片的原始长宽
const { padding } = this.node.attr;
const windowWidth = this.node.$screen.width - (2 * padding);
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>
... ...
<template>
<view>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--table类型-->
<block v-else-if="node.tag == 'table'">
<view :class="node.classStr" class="table" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<block v-else-if="node.node == 'text'">{{node.text}}</block>
</view>
</template>
<script>
import wxParseTemplate from './wxParseTemplate1';
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
export default {
name: 'wxParseTemplate0',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(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);
},
},
};
</script>
... ...
<template>
<view :class="(node.tag == 'li' ? node.classStr : (node.node==='text'?'text':''))">
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<!-- <view :class="node.classStr" :style="node.styleStr"> -->
<view :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<block v-else-if="node.node == 'text'">{{node.text}}</block>
</view>
</template>
<script>
import wxParseTemplate from './wxParseTemplate2';
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
export default {
name: 'wxParseTemplate1',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(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);
},
},
};
</script>
... ...
<template>
<view>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<block v-else-if="node.node == 'text'">{{node.text}}</block>
</view>
</template>
<script>
import wxParseTemplate from './wxParseTemplate11';
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
export default {
name: 'wxParseTemplate10',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(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);
},
},
};
</script>
... ...
<template>
<view>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<!--button类型-->
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
{{node.text}}
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
{{node.text}}
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :class="node.classStr" :style="node.styleStr">
{{node.text}}
</view>
</block>
</block>
<!--判断是否是文本节点-->
<block v-else-if="node.node == 'text'">{{node.text}}</block>
</view>
</template>
<script>
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
export default {
name: 'wxParseTemplate11',
props: {
node: {},
},
components: {
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(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);
},
},
};
</script>
... ...
<template>
<view>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<block v-else-if="node.node == 'text'">{{node.text}}</block>
</view>
</template>
<script>
import wxParseTemplate from './wxParseTemplate3';
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
export default {
name: 'wxParseTemplate2',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(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);
},
},
};
</script>
... ...
<template>
<view>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<block v-else-if="node.node == 'text'">{{node.text}}</block>
</view>
</template>
<script>
import wxParseTemplate from './wxParseTemplate4';
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
export default {
name: 'wxParseTemplate3',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(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);
},
},
};
</script>
... ...
<template>
<view>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<block v-else-if="node.node == 'text'">{{node.text}}</block>
</view>
</template>
<script>
import wxParseTemplate from './wxParseTemplate5';
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
export default {
name: 'wxParseTemplate4',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(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);
},
},
};
</script>
... ...
<template>
<view>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<block v-else-if="node.node == 'text'">{{node.text}}</block>
</view>
</template>
<script>
import wxParseTemplate from './wxParseTemplate6';
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
export default {
name: 'wxParseTemplate5',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(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);
},
},
};
</script>
... ...
<template>
<view>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<block v-else-if="node.node == 'text'">{{node.text}}</block>
</view>
</template>
<script>
import wxParseTemplate from './wxParseTemplate7';
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
export default {
name: 'wxParseTemplate6',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(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);
},
},
};
</script>
... ...
<template>
<view>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<block v-else-if="node.node == 'text'">{{node.text}}</block>
</view>
</template>
<script>
import wxParseTemplate from './wxParseTemplate8';
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
export default {
name: 'wxParseTemplate7',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(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);
},
},
};
</script>
... ...
<template>
<view>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<block v-else-if="node.node == 'text'">{{node.text}}</block>
</view>
</template>
<script>
import wxParseTemplate from './wxParseTemplate9';
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
export default {
name: 'wxParseTemplate8',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(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);
},
},
};
</script>
... ...
<template>
<view>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<block v-else-if="node.node == 'text'">{{node.text}}</block>
</view>
</template>
<script>
import wxParseTemplate from './wxParseTemplate10';
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
export default {
name: 'wxParseTemplate9',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(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);
},
},
};
</script>
... ...
<template>
<!--增加video标签支持,并循环添加-->
<view :class="node.classStr" :style="node.styleStr">
<video :class="node.classStr" class="video-video" :src="node.attr.src"></video>
</view>
</template>
<script>
export default {
name: 'wxParseVideo',
props: {
node: {},
},
};
</script>
... ...
/**
* 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 || '';
}
// 处理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;
}
if (customHandler.start) {
customHandler.start(node, results);
}
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;
}
if (customHandler.end) {
customHandler.end(node, results);
}
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,
};
if (customHandler.chars) {
customHandler.chars(node, results);
}
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;
... ...
/**
*
* 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;
... ...
// HTML 支持的数学符号
function strNumDiscode(str) {
str = str.replace(/&forall;/g, '∀');
str = str.replace(/&part;/g, '∂');
str = str.replace(/&exist;/g, '∃');
str = str.replace(/&empty;/g, '∅');
str = str.replace(/&nabla;/g, '∇');
str = str.replace(/&isin;/g, '∈');
str = str.replace(/&notin;/g, '∉');
str = str.replace(/&ni;/g, '∋');
str = str.replace(/&prod;/g, '∏');
str = str.replace(/&sum;/g, '∑');
str = str.replace(/&minus;/g, '−');
str = str.replace(/&lowast;/g, '∗');
str = str.replace(/&radic;/g, '√');
str = str.replace(/&prop;/g, '∝');
str = str.replace(/&infin;/g, '∞');
str = str.replace(/&ang;/g, '∠');
str = str.replace(/&and;/g, '∧');
str = str.replace(/&or;/g, '∨');
str = str.replace(/&cap;/g, '∩');
str = str.replace(/&cup;/g, '∪');
str = str.replace(/&int;/g, '∫');
str = str.replace(/&there4;/g, '∴');
str = str.replace(/&sim;/g, '∼');
str = str.replace(/&cong;/g, '≅');
str = str.replace(/&asymp;/g, '≈');
str = str.replace(/&ne;/g, '≠');
str = str.replace(/&le;/g, '≤');
str = str.replace(/&ge;/g, '≥');
str = str.replace(/&sub;/g, '⊂');
str = str.replace(/&sup;/g, '⊃');
str = str.replace(/&nsub;/g, '⊄');
str = str.replace(/&sube;/g, '⊆');
str = str.replace(/&supe;/g, '⊇');
str = str.replace(/&oplus;/g, '⊕');
str = str.replace(/&otimes;/g, '⊗');
str = str.replace(/&perp;/g, '⊥');
str = str.replace(/&sdot;/g, '⋅');
return str;
}
// HTML 支持的希腊字母
function strGreeceDiscode(str) {
str = str.replace(/&Alpha;/g, 'Α');
str = str.replace(/&Beta;/g, 'Β');
str = str.replace(/&Gamma;/g, 'Γ');
str = str.replace(/&Delta;/g, 'Δ');
str = str.replace(/&Epsilon;/g, 'Ε');
str = str.replace(/&Zeta;/g, 'Ζ');
str = str.replace(/&Eta;/g, 'Η');
str = str.replace(/&Theta;/g, 'Θ');
str = str.replace(/&Iota;/g, 'Ι');
str = str.replace(/&Kappa;/g, 'Κ');
str = str.replace(/&Lambda;/g, 'Λ');
str = str.replace(/&Mu;/g, 'Μ');
str = str.replace(/&Nu;/g, 'Ν');
str = str.replace(/&Xi;/g, 'Ν');
str = str.replace(/&Omicron;/g, 'Ο');
str = str.replace(/&Pi;/g, 'Π');
str = str.replace(/&Rho;/g, 'Ρ');
str = str.replace(/&Sigma;/g, 'Σ');
str = str.replace(/&Tau;/g, 'Τ');
str = str.replace(/&Upsilon;/g, 'Υ');
str = str.replace(/&Phi;/g, 'Φ');
str = str.replace(/&Chi;/g, 'Χ');
str = str.replace(/&Psi;/g, 'Ψ');
str = str.replace(/&Omega;/g, 'Ω');
str = str.replace(/&alpha;/g, 'α');
str = str.replace(/&beta;/g, 'β');
str = str.replace(/&gamma;/g, 'γ');
str = str.replace(/&delta;/g, 'δ');
str = str.replace(/&epsilon;/g, 'ε');
str = str.replace(/&zeta;/g, 'ζ');
str = str.replace(/&eta;/g, 'η');
str = str.replace(/&theta;/g, 'θ');
str = str.replace(/&iota;/g, 'ι');
str = str.replace(/&kappa;/g, 'κ');
str = str.replace(/&lambda;/g, 'λ');
str = str.replace(/&mu;/g, 'μ');
str = str.replace(/&nu;/g, 'ν');
str = str.replace(/&xi;/g, 'ξ');
str = str.replace(/&omicron;/g, 'ο');
str = str.replace(/&pi;/g, 'π');
str = str.replace(/&rho;/g, 'ρ');
str = str.replace(/&sigmaf;/g, 'ς');
str = str.replace(/&sigma;/g, 'σ');
str = str.replace(/&tau;/g, 'τ');
str = str.replace(/&upsilon;/g, 'υ');
str = str.replace(/&phi;/g, 'φ');
str = str.replace(/&chi;/g, 'χ');
str = str.replace(/&psi;/g, 'ψ');
str = str.replace(/&omega;/g, 'ω');
str = str.replace(/&thetasym;/g, 'ϑ');
str = str.replace(/&upsih;/g, 'ϒ');
str = str.replace(/&piv;/g, 'ϖ');
str = str.replace(/&middot;/g, '·');
return str;
}
function strcharacterDiscode(str) {
// 加入常用解析
str = str.replace(/&nbsp;/g, ' ');
str = str.replace(/&ensp;/g, ' ');
str = str.replace(/&emsp;/g, ' ');
str = str.replace(/&quot;/g, "'");
str = str.replace(/&amp;/g, '&');
str = str.replace(/&lt;/g, '<');
str = str.replace(/&gt;/g, '>');
str = str.replace(/&#8226;/g, '•');
return str;
}
// HTML 支持的其他实体
function strOtherDiscode(str) {
str = str.replace(/&OElig;/g, 'Œ');
str = str.replace(/&oelig;/g, 'œ');
str = str.replace(/&Scaron;/g, 'Š');
str = str.replace(/&scaron;/g, 'š');
str = str.replace(/&Yuml;/g, 'Ÿ');
str = str.replace(/&fnof;/g, 'ƒ');
str = str.replace(/&circ;/g, 'ˆ');
str = str.replace(/&tilde;/g, '˜');
str = str.replace(/&ensp;/g, '');
str = str.replace(/&emsp;/g, '');
str = str.replace(/&thinsp;/g, '');
str = str.replace(/&zwnj;/g, '');
str = str.replace(/&zwj;/g, '');
str = str.replace(/&lrm;/g, '');
str = str.replace(/&rlm;/g, '');
str = str.replace(/&ndash;/g, '–');
str = str.replace(/&mdash;/g, '—');
str = str.replace(/&lsquo;/g, '‘');
str = str.replace(/&rsquo;/g, '’');
str = str.replace(/&sbquo;/g, '‚');
str = str.replace(/&ldquo;/g, '“');
str = str.replace(/&rdquo;/g, '”');
str = str.replace(/&bdquo;/g, '„');
str = str.replace(/&dagger;/g, '†');
str = str.replace(/&Dagger;/g, '‡');
str = str.replace(/&bull;/g, '•');
str = str.replace(/&hellip;/g, '…');
str = str.replace(/&permil;/g, '‰');
str = str.replace(/&prime;/g, '′');
str = str.replace(/&Prime;/g, '″');
str = str.replace(/&lsaquo;/g, '‹');
str = str.replace(/&rsaquo;/g, '›');
str = str.replace(/&oline;/g, '‾');
str = str.replace(/&euro;/g, '€');
str = str.replace(/&trade;/g, '™');
str = str.replace(/&larr;/g, '←');
str = str.replace(/&uarr;/g, '↑');
str = str.replace(/&rarr;/g, '→');
str = str.replace(/&darr;/g, '↓');
str = str.replace(/&harr;/g, '↔');
str = str.replace(/&crarr;/g, '↵');
str = str.replace(/&lceil;/g, '⌈');
str = str.replace(/&rceil;/g, '⌉');
str = str.replace(/&lfloor;/g, '⌊');
str = str.replace(/&rfloor;/g, '⌋');
str = str.replace(/&loz;/g, '◊');
str = str.replace(/&spades;/g, '♠');
str = str.replace(/&clubs;/g, '♣');
str = str.replace(/&hearts;/g, '♥');
str = str.replace(/&diams;/g, '♦');
str = str.replace(/&#39;/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,
};
... ...
## uParse 适用于 uni-app/mpvue 的富文本解析组件
> 支持 Html、Markdown 解析,Fork自: [mpvue-wxParse](https://github.com/F-loat/mpvue-wxParse)
## 属性
| 名称 | 类型 | 默认值 | 描述 |
| -----------------|--------------- | ------------- | ---------------- |
| loading | Boolean | false | 数据加载状态 |
| className | String | — | 自定义 class 名称 |
| content | String | — | 渲染内容 |
| noData | String | 数据不能为空 | 空数据时的渲染展示 |
| startHandler | Function | 见源码 | 自定义 parser 函数 |
| endHandler | Function | null | 自定义 parser 函数 |
| charsHandler | Function | null | 自定义 parser 函数 |
| imageProp | Object | 见下文 | 图片相关参数 |
### 自定义 parser 函数具体介绍
* 传入的参数为当前节点 `node` 对象及解析结果 `results` 对象,例如 `startHandler(node, results)`
* 无需返回值,通过对传入的参数直接操作来完成需要的改动
* 自定义函数会在原解析函数处理之后执行
### imageProp 对象具体属性
| 名称 | 类型 | 默认值 | 描述 |
| -----------------|--------------- | ------------- | ------------------ |
| mode | String | 'aspectFit' | 图片裁剪、缩放的模式 |
| padding | Number | 0 | 图片内边距 |
| lazyLoad | Boolean | false | 图片懒加载 |
| domain | String | '' | 图片服务域名 |
## 事件
| 名称 | 参数 | 描述 |
| -----------------|----------------- | ---------------- |
| preview | 图片地址,原始事件 | 预览图片时触发 |
| navigate | 链接地址,原始事件 | 点击链接时触发 |
## 基本使用方法
``` vue
<template>
<div>
<u-parse :content="article" @preview="preview" @navigate="navigate" />
</div>
</template>
<script>
import uParse from '@/components/u-parse/u-parse.vue'
export default {
components: {
uParse
},
data () {
return {
article: '<div>我是HTML代码</div>'
}
},
methods: {
preview(src, e) {
// do something
},
navigate(href, e) {
// do something
}
}
}
</script>
<style>
@import url("@/components/u-parse/u-parse.css");
</style>
```
## 渲染 Markdown
> 先将 markdown 转换为 html 即可
```
npm install marked
```
``` js
import marked from 'marked'
import uParse from '@/components/u-parse/u-parse.vue'
export default {
components: {
uParse
},
data () {
return {
article: marked(`#hello, markdown!`)
}
}
}
```
... ...
/**
* 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
*/
.wxParse {
width: 100%;
font-family: Helvetica, sans-serif;
font-size: 30upx;
color: #666;
line-height: 1.8;
}
.wxParse view {
word-break: hyphenate;
}
.wxParse .inline {
display: inline;
margin: 0;
padding: 0;
}
.wxParse .div {
margin: 0;
padding: 0;
}
.wxParse .h1 .text {
font-size: 2em;
margin: 0.67em 0;
}
.wxParse .h2 .text {
font-size: 1.5em;
margin: 0.83em 0;
}
.wxParse .h3 .text {
font-size: 1.17em;
margin: 1em 0;
}
.wxParse .h4 .text {
margin: 1.33em 0;
}
.wxParse .h5 .text {
font-size: 0.83em;
margin: 1.67em 0;
}
.wxParse .h6 .text {
font-size: 0.67em;
margin: 2.33em 0;
}
.wxParse .h1 .text,
.wxParse .h2 .text,
.wxParse .h3 .text,
.wxParse .h4 .text,
.wxParse .h5 .text,
.wxParse .h6 .text,
.wxParse .b,
.wxParse .strong {
font-weight: bolder;
}
.wxParse .p {
margin: 1em 0;
}
.wxParse .i,
.wxParse .cite,
.wxParse .em,
.wxParse .var,
.wxParse .address {
font-style: italic;
}
.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;
}
.wxParse .code {
display: inline;
background: #f5f5f5;
}
.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 .s {
display: inline;
}
.wxParse .a {
color: deepskyblue;
}
.wxParse .video {
text-align: center;
margin: 22upx 0;
}
.wxParse .video-video {
width: 100%;
}
.wxParse .img {
display: inline-block;
width: 0;
height: 0;
max-width: 100%;
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: 33upx;
}
.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 .table {
width: 100%;
}
.wxParse .thead, .wxParse .tfoot, .wxParse .tr {
display: flex;
flex-direction: row;
}
.wxParse .tr {
width:100%;
display: flex;
border-right: 2upx solid #e0e0e0;
border-bottom: 2upx solid #e0e0e0;
}
.wxParse .th,
.wxParse .td {
display: flex;
width: 1276upx;
overflow: auto;
flex: 1;
padding: 11upx;
border-left: 2upx solid #e0e0e0;
}
.wxParse .td:last {
border-top: 2upx solid #e0e0e0;
}
.wxParse .th {
background: #f0f0f0;
border-top: 2upx solid #e0e0e0;
}
... ...
<!--**
* forked from:https://github.com/F-loat/mpvue-wxParse
*
* github地址: https://github.com/dcloudio/uParse
*
* for: uni-app框架下 富文本解析
*/-->
<template>
<!--基础元素-->
<div class="wxParse" :class="className" v-if="!loading">
<block v-for="(node,index) of nodes" :key="index">
<wxParseTemplate :node="node" />
</block>
</div>
</template>
<script>
import HtmlToJson from './libs/html2json';
import wxParseTemplate from './components/wxParseTemplate0';
export default {
name: 'wxParse',
props: {
loading: {
type: Boolean,
default: false,
},
className: {
type: String,
default: '',
},
content: {
type: String,
default: '',
},
noData: {
type: String,
default: '<div style="color: red;">数据不能为空</div>',
},
startHandler: {
type: Function,
default() {
return (node) => {
node.attr.class = null;
node.attr.style = null;
};
},
},
endHandler: {
type: Function,
default: null,
},
charsHandler: {
type: Function,
default: null,
},
imageProp: {
type: Object,
default() {
return {
mode: 'aspectFit',
padding: 0,
lazyLoad: false,
domain: '',
};
},
},
},
components: {
wxParseTemplate,
},
data() {
return {
imageUrls: [],
};
},
computed: {
nodes() {
const {
content,
noData,
imageProp,
startHandler,
endHandler,
charsHandler,
} = this;
const parseData = content || noData;
const customHandler = {
start: startHandler,
end: endHandler,
chars: charsHandler,
};
const results = HtmlToJson(parseData, customHandler, imageProp, this);
this.imageUrls = results.imageUrls;
console.log(results)
return results.nodes;
},
},
methods: {
navigate(href, $event) {
this.$emit('navigate', href, $event);
},
preview(src, $event) {
if (!this.imageUrls.length) return;
wx.previewImage({
current: src,
urls: this.imageUrls,
});
this.$emit('preview', src, $event);
},
removeImageUrl(src) {
const { imageUrls } = this;
imageUrls.splice(imageUrls.indexOf(src), 1);
},
},
};
</script>
... ...
{
"name" : "Bitcoin",
"appid" : "__UNI__D80DC8B",
"appid" : "__UNI__D7F2A57",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
... ...
... ... @@ -207,6 +207,15 @@
}
}
,{
"path" : "pages/index/grant",
"style" :
{
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
... ...
<template>
<view class="buydetail">
<view class="buytop">
<text class="buytitle"> 数字货币</text>
<!-- <text class="buytitle"> 数字货币</text> -->
<view class="buybox flexA">
<image :src="list1[0]" mode=""></image>
<view class="buymiss">
... ... @@ -120,9 +120,11 @@
is_cert: "",
},
show: false,
opid:"",
}
},
onLoad(options) {
this.opid=uni.getStorageSync('openId')
this.product_id = options.id
this.product_detail()
this.last_buy_data()
... ...
... ... @@ -6,11 +6,16 @@
<view class="time">
发布时间{{detail.publishtime}}
</view>
<image src="../../static/ic_fenxiang.png" mode=""></image>
<image src="../../static/ic_fenxiang.png" mode="" @click="shareModel=true"></image>
</view>
<rich-text :nodes="detail.content"></rich-text>
</view>
<view class="share" v-if="shareModel" @click="shareModel=false">
<image src="/static/detailShare.png" mode=""></image>
<view class="">
点击这里进行分享
</view>
</view>
</view>
</template>
... ... @@ -18,6 +23,8 @@
import {
arc_detail
} from '@/api/index.js'
var jweixin = require('jweixin-module');
console.log(jweixin, "000")
export default {
data() {
return {
... ... @@ -26,19 +33,31 @@
title: "",
publishtime: "",
content: "",
}
},
shareModel: false,
Images: "http://yuanjie.n.broing.cn/assets/img/share_logo.jpg",
jssdk:{},
}
},
onLoad(options) {
this.id = options.id
let title = uni.getStorageSync("deltitle")
uni.setNavigationBarTitle({
title: title //这是修改后的导航栏文字
})
this.arc_detail()
},
onUnload() {
uni.removeStorageSync("deltitle")
},
methods: {
//详情
async arc_detail() {
try {
const res = await arc_detail(this.id)
const res = await arc_detail(this.id, window.location.href)
this.detail = res.detail
this.jssdk = res.jssdk
this.share()
console.log('arc_detail', res)
// 保存数据
} catch (err) {
... ... @@ -49,6 +68,83 @@
console.log('arc_detail', err)
}
},
share() {
let that = this;
jweixin.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: that.jssdk.appId, // 必填,公众号的唯一标识
timestamp: that.jssdk.timestamp, // 必填,生成签名的时间戳
nonceStr: that.jssdk.nonceStr, // 必填,生成签名的随机串
signature: that.jssdk.signature, // 必填,签名
jsApiList: that.jssdk.jsApiList // 必填,需要使用的JS接口列表
})
jweixin.error(function(res) {
console.log(res, '错误')
});
console.log('分享了', that.jssdk.signature);
jweixin.ready(function() {
//分享给朋友
jweixin.onMenuShareAppMessage({
title: that.detail.title, // 分享标题
link: window.location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
desc: "【琉璃藏宝阁】数字藏品流转平台,顺利“琉”转,藏品“璃”手",
imgUrl: that.Images, // 分享图标
success: function() {
// 用户点击了分享后执行的回调函数
uni.showToast({
title: '分享成功',
duration: 2000
});
},
cancel: function(res) {
console.log('取消分享')
}
});
jweixin.updateAppMessageShareData({
title: that.detail.title, // 分享标题
link: window.location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
desc: "【琉璃藏宝阁】数字藏品流转平台,顺利“琉”转,藏品“璃”手",
imgUrl: that.Images, // 分享图标
success: function() {
console.log('设置分享给朋友成功')
},
cancel: function(res) {
console.log('取消分享')
}
});
//分享到朋友圈
jweixin.onMenuShareTimeline({
title: that.detail.title, // 分享标题
link: window.location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
desc: "【琉璃藏宝阁】数字藏品流转平台,顺利“琉”转,藏品“璃”手",
imgUrl: that.Images, // 分享图标
success: function() {
// 用户点击了分享后执行的回调函数
uni.showToast({
title: '分享成功',
duration: 2000
});
},
cancel: function(res) {
console.log('取消分享')
}
});
jweixin.updateTimelineShareData({
title: that.detail.title, // 分享标题
link: window.location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
desc: "【琉璃藏宝阁】数字藏品流转平台,顺利“琉”转,藏品“璃”手",
imgUrl: that.Images, // 分享图标
success: function() {
console.log('设置分享到朋友圈成功')
},
cancel: function(res) {
console.log('取消分享')
}
});
});
},
}
}
</script>
... ... @@ -70,4 +166,30 @@
}
}
}
.share {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .6);
image {
position: fixed;
right: 80rpx;
top: 4rpx;
width: 188rpx;
height: 262rpx;
}
view {
position: fixed;
right: 80rpx;
top: 300rpx;
color: rgba(255, 255, 255, 1);
font-size: 36rpx;
font-weight: 700;
}
}
</style>
... ...
... ... @@ -2,7 +2,7 @@
<view class="Detail">
<view class="topbg">
<view class="bgimage">
<u-swiper :list="list1" @change="change" @click="click" :height="375"></u-swiper>
<u-swiper :list="list1" @change="change" @click="onclick" :height="375"></u-swiper>
</view>
<view class="topmain">
<view class="toptitle">
... ... @@ -195,13 +195,19 @@
},
onShow() {
},
},
onLoad(options) {
this.id = options.id
this.product_detail()
this.report_list()
this.report_list()
},
methods: {
onclick(index){
uni.previewImage({
current: index,
urls: this.list1,
});
},
goTop(){
uni.pageScrollTo({
scrollTop: 0
... ... @@ -244,6 +250,7 @@
jweixin.onMenuShareAppMessage({
title: that.detail.name, // 分享标题
link: window.location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
desc:"【琉璃藏宝阁】数字藏品流转平台,顺利“琉”转,藏品“璃”手",
imgUrl: that.detail.images_preview[0], // 分享图标
success: function() {
// 用户点击了分享后执行的回调函数
... ... @@ -259,6 +266,7 @@
jweixin.updateAppMessageShareData({
title: that.detail.name, // 分享标题
link: window.location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
desc:"【琉璃藏宝阁】数字藏品流转平台,顺利“琉”转,藏品“璃”手",
imgUrl: that.detail.images_preview[0], // 分享图标
success: function() {
console.log('设置分享给朋友成功')
... ... @@ -271,6 +279,7 @@
jweixin.onMenuShareTimeline({
title: that.detail.name, // 分享标题
link: window.location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
desc:"【琉璃藏宝阁】数字藏品流转平台,顺利“琉”转,藏品“璃”手",
imgUrl: that.detail.images_preview[0], // 分享图标
success: function() {
// 用户点击了分享后执行的回调函数
... ... @@ -286,6 +295,7 @@
jweixin.updateTimelineShareData({
title: that.detail.name, // 分享标题
link: window.location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
desc:"【琉璃藏宝阁】数字藏品流转平台,顺利“琉”转,藏品“璃”手",
imgUrl: that.detail.images_preview[0], // 分享图标
success: function() {
console.log('设置分享到朋友圈成功')
... ... @@ -513,7 +523,9 @@
width: 168rpx;
}
.namelast {
.namelast {
width: 420rpx;
word-break: break-all;
color: rgba(0, 0, 0, 1);
font-size: 28rpx;
font-weight: 400;
... ...
<template>
<view>
<view>
<!-- url为要跳转外链的地址-->
<web-view :src="urls">
</web-view>
</view>
</view>
</template>
<!-- 公众号跳转
要跳转之前的位置js
gotogrant(url) {
console.log(url)
var url = url;
uni.navigateTo({
// 此处的链接为小程序上面新建的webview页面路径,参数url为要跳转外链的地址
url: "/pages/index/grant?url=" + encodeURIComponent(url)
});
}, -->
<script>
export default {
data() {
return {
urls:""
}
},
onLoad(val) {
console.log(val)
//解码
this.urls = decodeURIComponent(val.url);
// 设置当前的title 如果外链中有的话将被覆盖
// if(this.isNotEmpty(val.title)){
// this.setTitle(val.title);
// }
},
methods: {
isNotEmpty(obj) {
if (typeof obj == undefined || obj == null || obj == "" || obj == "undefined" || obj.length == 0) {
return false;
} else {
return true;
}
},
// 设置title
setTitle(title) {
uni.setNavigationBarTitle({
title: title
})
},
}
}
//公众号跳转
// gotogrant(url) {
// console.log(url)
// var url = url;
// uni.navigateTo({
// // 此处的链接为小程序上面新建的webview页面路径,参数url为要跳转外链的地址
// url: "/pages/index/grant?url=" + encodeURIComponent(url)
// });
// }
</script>
... ...
... ... @@ -3,7 +3,7 @@
<view class="logo">
<image src="/static/ic_logo.png" mode=""></image>
<view class="search" @click="gosourch">
<view class="tosear" >
<view class="tosear">
<input type="text" value="" placeholder="搜索"
placeholder-style="text-align: center;font-size: 28rpx; color: rgba(194,194,194,1);" />
<image src="/static/icon-search.png" mode=""></image>
... ... @@ -12,14 +12,14 @@
</view>
<view class="top">
<view class="banner">
<u-swiper keyName="image_preview" :list="list1" @click="click" :indicator="true" indicatorMode="dot"
<u-swiper keyName="image_preview" :list="list1" @click="toclick" :indicator="true" indicatorMode="dot"
radius="12" height="160" :circular="true">
</u-swiper>
</view>
</view>
<view class="contail">
<view class="nev">
<view class="bar" v-for="(item,index) in categoryList" :key="index" @click="tocate(item.id)">
<view class="bar" v-for="(item,index) in categoryList" :key="index" @click="tocate(item.id,item.name)">
<image class="barimg" :src="item.image_preview" mode=""></image>
<text>{{item.name}}</text>
</view>
... ... @@ -34,26 +34,27 @@
<view class="title">
相关资讯
</view>
<view class="more" @click="torealtime(1)">
<view class="more" @click="torealtime(1,'相关资讯')">
更多
<image src="/static/ic-arrow.png" mode=""></image>
</view>
</view>
<view class="newbar">
<view v-for="(item,index) in informationList" :key="index" @click="oncusdetail(item.id)">·{{item.title}}</view>
<view v-for="(item,index) in informationList" :key="index" @click="oncusdetail(item.id,item.title)">
·{{item.title}}</view>
</view>
</view>
<view class="rightbox" @click="torealtime(2)">
<view class="rightbox" @click="torealtime(2,'热门活动')">
<view class="righttitle">
<view class="title">
热门活动
</view>
<view class="active">
<!-- <view class="active">
充值活动
</view>
</view> -->
</view>
<view class="activeimg">
<image src="/static/Rectangle 2372.png" mode=""></image>
<image src="/static/6.jpg" mode="widthFix" ></image>
<!-- <image src="/static/logo.png" mode=""></image>
<image src="/static/logo.png" mode=""></image> -->
</view>
... ... @@ -124,8 +125,8 @@
return {
title: 'Hello',
list1: [],
nevlist: [1, 2, 3, 4, , 6, 7],
leftlist: [1, 2, 3],
nevlist: [],
leftlist: [],
fallindex: 1,
//瀑布
list: [],
... ... @@ -139,7 +140,7 @@
onShow() {
this.initial()
},
onLoad() {
onLoad(e) {
this.product_list(true)
},
onReachBottom() {
... ... @@ -147,31 +148,40 @@
this.product_list()
},
methods: {
goTop(){
toclick(index) {
console.log(this.list1[index].href)
uni.navigateTo({
// 此处的链接为小程序上面新建的webview页面路径,参数url为要跳转外链的地址
url: "/pages/index/grant?url=" + encodeURIComponent(this.list1[index].href)
});
},
goTop() {
uni.pageScrollTo({
scrollTop: 0
});
},
// 资讯详情
oncusdetail(e) {
oncusdetail(e,title) {
uni.setStorageSync("deltitle",title)
uni.navigateTo({
url: "/pages/index/consultationDetails?id=" + e
})
},
tocate(id) {
tocate(id, name) {
uni.navigateTo({
url: "/pages/index/product?sort_id="+id
url: "/pages/index/product?sort_id=" + id + "&sort_name=" + name
})
},
toallCate(){
toallCate() {
uni.navigateTo({
url: "/pages/index/category"
})
},
//咨询列表
torealtime(e) {
torealtime(e,title) {
uni.navigateTo({
url: "/pages/index/realTimeInfo?type=" + e
url: "/pages/index/realTimeInfo?type=" + e+"&title="+title
})
},
async product_report() {
... ... @@ -208,17 +218,17 @@
}
},
//产品列表
async product_list(x,state) {
async product_list(x, state) {
let obj = {
type: this.fallindex,
page: this.currentpage,
ids: this.fallindex == 1 && state? this.idgroup.join(",") : "",
ids: this.fallindex == 1 && state ? this.idgroup.join(",") : "",
pagenum: 15,
}
try {
const res = await product_list(obj)
console.log('产品列表', res)
this.idgroup=[]
this.idgroup = []
this.list = x ? res.list.data : this.list.concat(res.list.data)
this.list.forEach((item, index) => {
item.image = item.images_preview[0]
... ... @@ -268,12 +278,12 @@
}
},
changefall(e) {
let state = this.fallindex==e?1:0
let state = this.fallindex == e ? 1 : 0
this.fallindex = e
console.log(this.fallindex)
this.currentpage=1
this.list=[]
this.product_list(true,state)
this.currentpage = 1
this.list = []
this.product_list(true, state)
},
//跳转详情
godetail(item) {
... ... @@ -609,6 +619,7 @@
}
}
}
.goTop {
width: 96rpx;
height: 96rpx;
... ...
... ... @@ -48,14 +48,23 @@
keyword: "",
currentpage: 1,
sort_id: "",
sort_name:"",
}
},
onLoad(options) {
if (options.ktext) {
this.keyword = options.ktext
uni.setNavigationBarTitle({
title: "产品" //这是修改后的导航栏文字
})
}
if (options.sort_id) {
this.sort_id = options.sort_id
this.sort_name = options.sort_name
let that =this
uni.setNavigationBarTitle({
title: that.sort_name //这是修改后的导航栏文字
})
}
this.product_list(true)
},
... ...
... ... @@ -8,7 +8,7 @@
<view class="banner">
<scroll-view scroll-x="true" style="white-space:nowrap ">
<view class="nav" :class="{newnav:chooseindex==index}" v-for="(item,index) in typelist" :key="index"
@click="choose(index,item.id)">{{item.name}}
@click="choose(index,item.id,item.name)">{{item.name}}
<view class="tip" v-if="chooseindex==index">
</view>
</view>
... ... @@ -17,7 +17,7 @@
</view>
<view class="group">
<scroll-view scroll-y="true" @scrolltolower="scrolltolower" style="height: 100vh">
<view class="item" v-for="(item,idx) in sortlist" :key="idx" @click="ondetail(item.id)">
<view class="item" v-for="(item,idx) in sortlist" :key="idx" @click="ondetail(item.id,item.title)">
<view class="bot flexA">
<view class="left flexA">
<image :src="item.image_preview" mode=""></image>
... ... @@ -47,14 +47,21 @@
keyword: "",
sortlist: [],
currentpage: 1,
nametitle: "",
}
},
onLoad(options) {
this.type = options.type
let title=options.title
uni.setNavigationBarTitle({
title: title //这是修改后的导航栏文字
})
this.sort_list(true)
},
methods: {
ondetail(e) {
ondetail(e,title) {
uni.setStorageSync("deltitle",title)
uni.navigateTo({
url: "/pages/index/consultationDetails?id=" + e
})
... ... @@ -70,17 +77,20 @@
this.arc_list(true)
},
//类型选择
choose(e, id) {
this.chooseindex = e
this.sortlist = []
this.sort_id = id
this.arc_list(true)
choose(e, id, name) {
let that =this
that.chooseindex = e
that.sortlist = []
that.sort_id = id
that.nametitle = name
console.log(that.nametitle, name)
that.arc_list(true)
},
// 分类
async sort_list() {
console.log(this.type,"000")
console.log(this.type, "000")
let obj = {
type:this.type,
type: this.type,
keyword: this.keyword,
}
try {
... ...
<template>
<view class="top">
<u-search :showAction="true" actionText="搜索" :clearabled="true" v-model="ktext" @custom="onsouch(ktext)">
<u-search :showAction="true" actionText="搜索" :clearabled="true" v-model="ktext" @custom="onsouch(ktext)" @search="onsouch(ktext)">
</u-search>
<view class="main">
<view class="title" v-if="hostlist.length">
... ...
<template>
<view class="Send">
<view class="contail">
<view class="main">
<view class="bar">
<view class="name">
物品名称:
</view>
<view class="nameinput">
<input v-model="form.name" type="text" placeholder="请输入">
</view>
</view>
<view class="bar">
<view class="name">
所属分类:
</view>
<view class="barchoose flexA" @click="showCategory = true">
<text :style="{color:sortName=='请选择'?'grey':'#000'}">{{sortName}}</text>
<image src="/static/ic-arrow2.png" mode=""></image>
</view>
</view>
<view class="bar">
<view class="name">
价格:
</view>
<view class="nameinput">
<input @input="checkNumber" v-model="form.price" type="text" placeholder="请输入(元)">
</view>
</view>
<view class="newbar">
<view class="name">
物品介绍:
</view>
<u--textarea :autoHeight="true" maxlength="300" v-model="form.description" border="none" placeholder="请输入"></u--textarea>
</view>
<view class="newbar">
<view class="name">
物品图片:(最多五张)
</view>
<view class="upimg">
<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple
:maxCount="5"></u-upload>
</view>
</view>
</view>
<u-gap height="12" bgColor="#F6F6F6"></u-gap>
<view class="main">
<view class="title">
卖家信息
</view>
<view class="bar">
<view class="name">
姓名:
</view>
<view class="nameinput">
<input v-model="form.seller_name" type="text" placeholder="选填">
</view>
</view>
<view class="bar">
<view class="name">
手机号:
</view>
<view class="nameinput">
<input v-model="form.seller_mobile" type="text" placeholder="选填">
</view>
</view>
<view class="bar">
<view class="name">
<text>*</text>发送账户:
</view>
<view class="nameinput">
<input v-model="form.package_add" type="text" placeholder="请输入手机号或钱包地址">
</view>
</view>
<view class="bar">
<view class="name">
<text>*</text>微信号:
</view>
<view class="nameinput">
<input v-model="form.wechat_num" type="text" placeholder="请输入">
</view>
</view>
<view class="bar">
<view class="name">
<text>*</text>保证金:{{lastInfo.cert_withdraw_price}}
</view>
<view class="barlast" v-if="lastInfo.is_cert_withdraw!=1">
去缴纳<image src="/static/arrowR.png" mode=""></image>
<template>
<view class="Send">
<view class="contail">
<view class="main">
<view class="bar">
<view class="name">
物品名称:
</view>
<view class="barlast" v-else style="color: #18D18E;">
已缴纳
</view>
</view>
<view class="bar" @click="show = true">
<view class="name">
<text>*</text>实名认证:
</view>
<view class="barlast" v-if="lastInfo.is_cert==0" >
去认证<image src="/static/arrowR.png" mode=""></image>
<view class="nameinput">
<input v-model="form.name" type="text" placeholder="请输入">
</view>
</view>
<view class="bar">
<view class="name">
所属分类:
</view>
<!-- @click="showCategory = true" -->
<view class="barchoose flexA">
<input type="text" v-model="sortName" placeholder="搜索选择所属分类"
placeholder-style="font-size: 32rpx;" @input="showbox" >
<!-- <text :style="{color:sortName=='请选择'?'grey':'#000'}">{{sortName}}</text> -->
<!-- <image src="/static/ic-arrow2.png" mode=""></image> -->
</view>
<view class="barbox" v-if="sortName&&isshowbox">
<scroll-view scroll-y="true" style="height: 100%;">
<view class="bartip" v-for="(item,index) in columns" :key="index" @click="selctCategory(item)">{{item.name}}</view>
</scroll-view>
</view>
</view>
<view class="bar">
<view class="name">
价格:
</view>
<view class="nameinput">
<input @input="checkNumber" v-model="form.price" type="text" placeholder="请输入(元)">
</view>
</view>
<view class="newbar">
<view class="name">
物品介绍:
</view>
<u--textarea :autoHeight="true" maxlength="300" v-model="form.description" border="none"
placeholder="请输入"></u--textarea>
</view>
<view class="newbar">
<view class="name">
物品图片:(最多五张)
</view>
<view class="upimg">
<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple
:maxCount="5"></u-upload>
</view>
</view>
</view>
<u-gap height="12" bgColor="#F6F6F6"></u-gap>
<view class="main">
<view class="title">
卖家信息
</view>
<view class="bar">
<view class="name">
姓名:
</view>
<view class="nameinput">
<input v-model="form.seller_name" type="text" placeholder="选填">
</view>
</view>
<view class="bar">
<view class="name">
手机号:
</view>
<view class="nameinput">
<input v-model="form.seller_mobile" type="text" placeholder="选填">
</view>
</view>
<view class="bar">
<view class="name">
<text>*</text>发送账户:
</view>
<view class="nameinput">
<input v-model="form.package_add" type="text" placeholder="请输入手机号或钱包地址">
</view>
</view>
<view class="bar">
<view class="name">
<text>*</text>微信号:
</view>
<view class="nameinput">
<input v-model="form.wechat_num" type="text" placeholder="请输入">
</view>
</view>
<view class="bar">
<view class="name">
<text>*</text>保证金:{{lastInfo.cert_withdraw_price}}
</view>
<view class="barlast" v-if="lastInfo.is_cert_withdraw!=1">
去缴纳<image src="/static/arrowR.png" mode=""></image>
</view>
<view class="barlast" v-else style="color: #18D18E;">
已缴纳
</view>
</view>
<view class="bar" @click="show = true">
<view class="name">
<text>*</text>实名认证:
</view>
<view class="barlast" v-if="lastInfo.is_cert==0">
去认证<image src="/static/arrowR.png" mode=""></image>
</view>
<view class="barlast" v-else style="color: #18D18E;">
已认证
</view>
</view>
</view>
</view>
</view>
<view style="height: 200rpx;"></view>
<view class="btn">
<view class="paybtn" @click="send">
提交
</view>
</view>
<view style="height: 200rpx;"></view>
<view class="btn">
<view class="paybtn" @click="send">
提交
</view>
</view>
<u-popup :show="showmoney" :closeOnClickOverlay="false" @close="close" @open="open" mode="center" :round="12">
<view class="popname">
<view class="title">
缴纳保证金
</view>
<view class="contant">
为了保证平台用户交易的安全性,您需要缴纳{{lastInfo.cert_withdraw_price}}元保证金后方可在平台中进行发布物品操作。交易完成后,可在余额中心中进行退回。
</view>
<view class="btngroup" >
<view class="concle" @click="back">
暂不缴纳
</view>
<view class="requt" @click="authorization">
立即缴纳
</view>
</view>
</view>
<u-popup :show="showmoney" :closeOnClickOverlay="false" @close="close" @open="open" mode="center"
:round="12">
<view class="popname">
<view class="title">
缴纳保证金
</view>
<view class="contant">
为了保证平台用户交易的安全性,您需要缴纳{{lastInfo.cert_withdraw_price}}元保证金后方可在平台中进行发布物品操作。交易完成后,可在余额中心中进行退回。
</view>
<view class="btngroup">
<view class="concle" @click="back">
暂不缴纳
</view>
<view class="requt" @click="authorization">
立即缴纳
</view>
</view>
</view>
</u-popup>
<u-popup :show="show" :closeOnClickOverlay="false" @close="close" @open="open" mode="center" :round="12">
<view class="popname">
... ... @@ -139,7 +149,7 @@
<view class="contant">
为了保证平台用户交易的安全性,您需要实名认证后,才能在平台中进行发布物品操作
</view>
<view class="btngroup" >
<view class="btngroup">
<view class="concle" @click="back">
暂不认证
</view>
... ... @@ -148,167 +158,215 @@
</view>
</view>
</view>
</u-popup>
</u-popup>
</view>
<u-picker :show="showCategory" @cancel="showCategory=false" @confirm="selctCategory" :columns="columns" keyName="name"></u-picker>
<Botton :flag="3"></Botton>
</view>
</template>
<!-- <u-picker :show="showCategory" @cancel="showCategory=false" @confirm="selctCategory" :columns="columns"
keyName="name"></u-picker> -->
<Botton :flag="3"></Botton>
</view>
</template>
<script>
var that
var that
var wx = require('jweixin-module')
import {baseURL} from '@/utils/request.js'
import {
baseURL
} from '@/utils/request.js'
import Botton from "@/components/Botton.vue"
import {sortList,product_detail} from '@/api/index'
import {toa} from '@/utils/toast.js'
import { getCategory,sendProduct,getLastInfo,payGuarantee,authorization ,getOpenid,userCertWithdraw} from '@/api/send'
import {
sortList,
product_detail,
sort_search
} from '@/api/index'
import {
toa
} from '@/utils/toast.js'
import {
getCategory,
sendProduct,
getLastInfo,
payGuarantee,
authorization,
getOpenid,
userCertWithdraw
} from '@/api/send'
export default {
name:'send',
name: 'send',
components: {
Botton
},
data() {
return {
fileList1: [],
show: false,
},
data() {
return {
fileList1: [],
show: false,
showmoney: false,
showCategory:false,
content:'',
showCategory: false,
content: '',
isshowbox: true,
columns: [],
lastInfo:{},
sortName:'请选择',
form:{
product_id:'', // string 否 物品id
name:'', // string 是 物品名称
sort_id:'', // integer 是 所属分类
price:'', // string 是 价格
description:'', // string 是 物品介绍
images:'', // string 是 物品图片
seller_name:'', // string 否 卖家姓名
seller_mobile:'', // string 否 手机号
package_add:'', // string 是 钱包地址
wechat_num:'', // string 是 微信号
lastInfo: {},
sortName: '',
form: {
product_id: '', // string 否 物品id
name: '', // string 是 物品名称
sort_id: '', // integer 是 所属分类
price: '', // string 是 价格
description: '', // string 是 物品介绍
images: '', // string 是 物品图片
seller_name: '', // string 否 卖家姓名
seller_mobile: '', // string 否 手机号
package_add: '', // string 是 钱包地址
wechat_num: '', // string 是 微信号
},
code:''
}
code: ''
}
},
onLoad(e) {
that = this
if(e.id){
if (e.id) {
this.form.product_id = e.id
this.getDetail()
}
this.code = e.code || ''
this.getLastInfo()
this.sortList()
if(this.code){
if (this.code) {
this.getOpenid()
}
},
onShow() {
},
onShow() {},
methods: {
back(){
//所属分类搜索
async showbox() {
let that = this
that.isshowbox = true
try {
const res = await sort_search(that.sortName)
console.log('sort_search', res)
that.columns = res.list
// 保存数据
} catch (err) {
uni.showToast({
title: err,
icon: 'none'
})
console.log('sort_search', err)
}
},
//所属分类确定
// showok() {
// that.isshowbox = false
// },
//列表选择
back() {
uni.navigateBack({})
this.showmoney=false
this.showmoney = false
},
// 获取openid
async getOpenid(){
try {
const res = await getOpenid(this.code)
console.log('getOpenid', res)
uni.setStorageSync('openId',res.openid)
this.userCertWithdraw()
// 保存数据
} catch (err) {
setTimeout(()=>{
uni.showToast({ title:err,icon:'none' })
},300)
uni.redirectTo({
url:'/pages/index/index'
})
console.log('getOpenid', err)
}
async getOpenid() {
try {
const res = await getOpenid(this.code)
console.log('getOpenid', res)
uni.setStorageSync('openId', res.openid)
this.userCertWithdraw()
// 保存数据
} catch (err) {
setTimeout(() => {
uni.showToast({
title: err,
icon: 'none'
})
}, 300)
uni.redirectTo({
url: '/pages/index/index'
})
console.log('getOpenid', err)
}
},
// 缴纳保证金
async userCertWithdraw(){
try {
const openId = uni.getStorageSync('openId')
const res = await userCertWithdraw(openId)
console.log(res.pay_data);
console.log('userCertWithdraw', res)
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: res.pay_data.appId, // 必填,公众号的唯一标识
timestamp: res.pay_data.timeStamp, // 必填,生成签名的时间戳
nonceStr: res.pay_data.nonceStr, // 必填,生成签名的随机串
signature: res.pay_data.paySign, // 必填,签名
jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表
})
wx.ready(function () {
wx.chooseWXPay({
timestamp: res.pay_data.timeStamp, // 时间戳
nonceStr: res.pay_data.nonceStr, // 随机数
package: res.pay_data.package, //
signType: res.pay_data.signType,
paySign: res.pay_data.paySign, // 签名
success: function () {
that.lastInfo.is_cert_withdraw = 1
that.showmoney = false
that.getLastInfo()
toa.success('支付成功')
},
cancel: function () {
setTimeout(()=>{
toa.toast('取消失败')
},200)
uni.navigateBack({})
},
fail: function () {
setTimeout(()=>{
toa.toast('支付失败')
},200)
uni.navigateBack({})
}
})
})
// 保存数据
} catch (err) {
uni.showToast({ title:err,icon:'none' })
console.log('userCertWithdraw', err)
}
async userCertWithdraw() {
try {
const openId = uni.getStorageSync('openId')
const res = await userCertWithdraw(openId)
console.log(res.pay_data);
console.log('userCertWithdraw', res)
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: res.pay_data.appId, // 必填,公众号的唯一标识
timestamp: res.pay_data.timeStamp, // 必填,生成签名的时间戳
nonceStr: res.pay_data.nonceStr, // 必填,生成签名的随机串
signature: res.pay_data.paySign, // 必填,签名
jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表
})
wx.ready(function() {
wx.chooseWXPay({
timestamp: res.pay_data.timeStamp, // 时间戳
nonceStr: res.pay_data.nonceStr, // 随机数
package: res.pay_data.package, //
signType: res.pay_data.signType,
paySign: res.pay_data.paySign, // 签名
success: function() {
that.lastInfo.is_cert_withdraw = 1
that.showmoney = false
that.getLastInfo()
toa.success('支付成功')
},
cancel: function() {
setTimeout(() => {
toa.toast('取消失败')
}, 200)
uni.navigateBack({})
},
fail: function() {
setTimeout(() => {
toa.toast('支付失败')
}, 200)
uni.navigateBack({})
}
})
})
// 保存数据
} catch (err) {
uni.showToast({
title: err,
icon: 'none'
})
console.log('userCertWithdraw', err)
}
},
// 获取详情
async getDetail(){
try {
const res = await product_detail(this.form.product_id)
// this.form = res.detail
this.form.sort_id = res.detail.sort.id
this.sortName = res.detail.sort.name
this.form.product_id = res.detail.id
this.form.name = res.detail.name
this.form.price = res.detail.price
this.form.description = res.detail.description
res.detail.fileList.forEach(it=>{
it.shortUrl = it.url
it.url = it.fullUrl
})
this.fileList1 = res.detail.fileList
console.log(this.fileList1,'图片');
console.log('getDetail', res)
// 保存数据
} catch (err) {
uni.showToast({ title:err,icon:'none' })
console.log('getDetail', err)
}
async getDetail() {
try {
const res = await product_detail(this.form.product_id)
// this.form = res.detail
this.form.sort_id = res.detail.sort.id
this.sortName = res.detail.sort.name
this.form.product_id = res.detail.id
this.form.name = res.detail.name
this.form.price = res.detail.price
this.form.description = res.detail.description
res.detail.fileList.forEach(it => {
it.shortUrl = it.url
it.url = it.fullUrl
})
this.fileList1 = res.detail.fileList
console.log(this.fileList1, '图片');
console.log('getDetail', res)
// 保存数据
} catch (err) {
uni.showToast({
title: err,
icon: 'none'
})
console.log('getDetail', err)
}
},
checkNumber(e) {
let val = e.target.value.replace(/(^\s*)|(\s*$)/g, "")
var reg = /[^\d.]/g
// 只能是数字和小数点,不能是其他输入
val = val.replace(reg, "")
// // 保证第一位只能是数字,不能是点
... ... @@ -322,347 +380,395 @@
this.form.price = val;
})
},
async sortList(){
try {
const res = await sortList(2)
this.columns = [res.list]
console.log('sortList', res)
// 保存数据
} catch (err) {
uni.showToast({ title:err,icon:'none' })
console.log('sortList', err)
}
async sortList() {
try {
const res = await sortList(2)
this.columns = res.list
console.log('sortList', this.columns, "0")
// 保存数据
} catch (err) {
uni.showToast({
title: err,
icon: 'none'
})
console.log('sortList', err)
}
},
async getLastInfo() {
try {
const res = await getLastInfo()
this.lastInfo = res.detail
console.log(1);
if (res.detail.is_cert == 0) {
return this.show = true
}
if (res.detail.is_cert_withdraw != 1 && !this.code) {
this.showmoney = true
}
console.log(2);
console.log(res.detail.is_cert_withdraw != 1, !this.code);
this.form.seller_mobile = res.detail.seller_mobile
this.form.seller_name = res.detail.seller_name
this.form.package_add = res.detail.package_add
this.form.wechat_num = res.detail.wechat_num
console.log('getLastInfo', res)
// 保存数据
} catch (err) {
uni.showToast({
title: err,
icon: 'none'
})
console.log('getLastInfo', err)
}
},
open() {
// console.log('open');
},
close() {
this.show = false
this.showmoney = false
// console.log('close');
},
async getLastInfo(){
try {
const res = await getLastInfo()
this.lastInfo = res.detail
console.log(1);
if(res.detail.is_cert==0){ return this.show = true}
if(res.detail.is_cert_withdraw!=1 && !this.code){ this.showmoney = true}
console.log(2);
console.log(res.detail.is_cert_withdraw!=1,!this.code);
this.form.seller_mobile = res.detail.seller_mobile
this.form.seller_name = res.detail.seller_name
this.form.package_add = res.detail.package_add
this.form.wechat_num = res.detail.wechat_num
console.log('getLastInfo', res)
// 保存数据
} catch (err) {
uni.showToast({ title:err,icon:'none' })
console.log('getLastInfo', err)
}
},
open() {
// console.log('open');
},
close() {
this.show = false
this.showmoney = false
// console.log('close');
},
// 删除图片
deletePic(event) {
this[`fileList${event.name}`].splice(event.index, 1)
},
// 新增图片
async afterRead(event) {
// 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file)
let fileListLen = this[`fileList${event.name}`].length
lists.map((item) => {
this[`fileList${event.name}`].push({
...item,
status: 'uploading',
message: '上传中'
})
})
for (let i = 0; i < lists.length; i++) {
// 删除图片
deletePic(event) {
this[`fileList${event.name}`].splice(event.index, 1)
},
// 新增图片
async afterRead(event) {
// 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file)
let fileListLen = this[`fileList${event.name}`].length
lists.map((item) => {
this[`fileList${event.name}`].push({
...item,
status: 'uploading',
message: '上传中'
})
})
for (let i = 0; i < lists.length; i++) {
const result = await this.uploadFilePromise(lists[i].url)
console.log(result,'获取的结构');
let item = this[`fileList${event.name}`][fileListLen]
this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
console.log(result, '获取的结构');
let item = this[`fileList${event.name}`][fileListLen]
this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
url: result.fullurl,
shortUrl:result.url
}))
fileListLen++
}
},
uploadFilePromise(url) {
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: baseURL + 'common/upload', // 仅为示例,非真实的接口地址
filePath: url,
name: 'file',
shortUrl: result.url
}))
fileListLen++
}
},
uploadFilePromise(url) {
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: baseURL + 'common/upload', // 仅为示例,非真实的接口地址
filePath: url,
name: 'file',
formData: {
token:uni.getStorageSync('token') || ''
},
success: (res) => {
setTimeout(() => {
resolve(JSON.parse(res.data).data)
}, 1000)
}
});
})
token: uni.getStorageSync('token') || ''
},
success: (res) => {
setTimeout(() => {
resolve(JSON.parse(res.data).data)
}, 1000)
}
});
})
},
selctCategory(e){
this.sortName = e.value[0].name
this.form.sort_id = e.value[0].id
this.showCategory = false
console.log(e);
selctCategory(e) {
console.log(e)
this.sortName = e.name
this.form.sort_id = e.id
this.isshowbox = false
console.log(this.sortName,this.form.sort_id);
},
// 发布
send(){
send() {
console.log(this.lastInfo);
if(this.lastInfo.is_cert_withdraw!=1 ) return this.showmoney = true
if(this.lastInfo.is_cert==0) return this.show = true
if(this.fileList1.length){
this.form.images = this.fileList1.map(it=>it.shortUrl).join(',')
if (this.lastInfo.is_cert_withdraw != 1) return this.showmoney = true
if (this.lastInfo.is_cert == 0) return this.show = true
if (this.fileList1.length) {
this.form.images = this.fileList1.map(it => it.shortUrl).join(',')
}
console.log(this.form);
this.sendProduct()
},
async sendProduct(){
try {
const res = await sendProduct(this.form)
console.log('sendProduct', res)
setTimeout(()=>{
toa.success(this.form.product_id?'修改成功':'发布成功')
},400)
uni.redirectTo({
url:'/pages/mine/myRelease'
})
// 保存数据
} catch (err) {
uni.showToast({ title:err,icon:'none' })
console.log('sendProduct', err)
}
async sendProduct() {
try {
const res = await sendProduct(this.form)
console.log('sendProduct', res)
setTimeout(() => {
toa.success(this.form.product_id ? '修改成功' : '发布成功')
}, 400)
uni.redirectTo({
url: '/pages/mine/myRelease'
})
// 保存数据
} catch (err) {
uni.showToast({
title: err,
icon: 'none'
})
console.log('sendProduct', err)
}
},
goRealName(){
goRealName() {
uni.navigateTo({
url:'/pages/index/realName'
url: '/pages/index/realName'
})
},
// 拿code
async authorization(){
try {
const openId = uni.getStorageSync('openId')
if(openId) return this.userCertWithdraw()
const res = await authorization(window.location.href)
console.log('authorization', res)
window.location.href = res.url
// 保存数据
} catch (err) {
uni.showToast({ title:err,icon:'none' })
console.log('authorization', err)
}
async authorization() {
try {
const openId = uni.getStorageSync('openId')
if (openId) return this.userCertWithdraw()
const res = await authorization(window.location.href)
console.log('authorization', res)
window.location.href = res.url
// 保存数据
} catch (err) {
uni.showToast({
title: err,
icon: 'none'
})
console.log('authorization', err)
}
},
}
}
</script>
<style lang="scss">
page {
background-color: #ffffff;
}
.Send {
.contail {
padding-bottom: 160rpx;
.title {
padding: 32rpx;
box-sizing: border-box;
color: rgba(0, 0, 0, 1);
font-size: 28rpx;
font-weight: 600;
font-family: "PingFang SC";
}
.main {
padding: 0 32rpx;
.bar {
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding: 32rpx 0;
border-bottom: 1px solid #F0f0f0;
.name {
color: rgba(0, 0, 0, 1);
font-size: 28rpx;
font-weight: 400;
font-family: "PingFang SC";
text {
color: rgba(252, 67, 56, 1);
font-size: 28rpx;
font-weight: 400;
font-family: "PingFang SC";
}
}
.barchoose {
color: rgba(0, 0, 0, 0.4);
font-size: 28rpx;
font-weight: 400;
font-family: "PingFang SC";
image{
width: 24rpx;
height: 16rpx;
}
}
.barlast {
display: flex;
align-items: center;
color: rgba(33, 83, 212, 1);
font-size: 28rpx;
font-weight: 400;
font-family: "PingFang SC";
image {
margin-left: 12rpx;
width: 16rpx;
height: 32rpx;
}
}
input {
text-align: right;
}
}
.newbar {
padding: 32rpx 0;
box-sizing: border-box;
border-bottom: 1px solid #F0f0f0;
.name {
color: rgba(0, 0, 0, 1);
font-size: 28rpx;
font-weight: 400;
font-family: "PingFang SC";
}
textarea {
margin-top: 32rpx;
padding: 24rpx;
width: 100%;
height: 200rpx;
box-sizing: border-box;
background-color: #F6F6F6;
}
.upimg {
margin-top: 32rpx;
}
}
}
.popname {
padding: 32rpx;
box-sizing: border-box;
width: 622rpx;
text-align: center;
.title {
color: rgba(0, 0, 0, 0.9);
font-size: 32rpx;
font-weight: 600;
font-family: "PingFang SC";
text-align: center;
}
.contant {
color: rgba(179, 179, 179, 1);
font-size: 28rpx;
font-weight: 400;
font-family: "PingFang SC";
text-align: center;
}
.btngroup {
margin-top: 80rpx;
display: flex;
align-items: center;
justify-content: space-between;
.concle {
width: 264rpx;
height: 76rpx;
border-radius: 16rpx;
opacity: 1;
line-height: 76rpx;
color: rgba(0, 0, 0, 0.9);
font-size: 28rpx;
font-weight: 500;
font-family: "PingFang SC";
text-align: center;
background: rgba(246, 246, 246, 1);
}
.requt {
width: 264rpx;
height: 76rpx;
color: rgba(0, 0, 0, 0.9);
font-size: 28rpx;
font-weight: 500;
font-family: "PingFang SC";
text-align: center;
line-height: 76rpx;
border-radius: 16rpx;
opacity: 1;
background: rgba(254, 208, 0, 1);
}
}
}
.btn {
position: fixed;
bottom: 50rpx;
left: 0;
width: 100%;
// height: 128rpx;
}
}
</script>
<style lang="scss">
page {
background-color: #ffffff;
}
.Send {
.contail {
padding-bottom: 160rpx;
.title {
padding: 32rpx;
box-sizing: border-box;
color: rgba(0, 0, 0, 1);
font-size: 28rpx;
font-weight: 600;
font-family: "PingFang SC";
}
.main {
padding: 0 32rpx;
.bar {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding: 32rpx 0;
border-bottom: 1px solid #F0f0f0;
.name {
color: rgba(0, 0, 0, 1);
font-size: 28rpx;
font-weight: 400;
font-family: "PingFang SC";
text {
color: rgba(252, 67, 56, 1);
font-size: 28rpx;
font-weight: 400;
font-family: "PingFang SC";
}
}
.barchoose {
color: rgba(0, 0, 0, 0.4);
font-size: 28rpx;
font-weight: 400;
font-family: "PingFang SC";
input {
text-align: right;
}
image {
width: 24rpx;
height: 16rpx;
}
}
.barlast {
display: flex;
align-items: center;
color: rgba(33, 83, 212, 1);
font-size: 28rpx;
font-weight: 400;
font-family: "PingFang SC";
image {
margin-left: 12rpx;
width: 16rpx;
height: 32rpx;
}
}
.nameinput {
flex: 1;
input {
text-align: right;
}
}
.barbox {
position: absolute;
right: 0;
z-index: 99;
bottom: -400rpx;
padding: 0 24rpx;
height: 400rpx;
font-size: 28rpx;
font-weight: 400;
font-family: "PingFang SC";
box-sizing: border-box;
background-color: #ffffff;
border: 1px solid #F0f0f0;
box-shadow: 5rpx 5rpx 5rpx rgba(0, 0, 0, 0.1);
.bartip {
padding: 24rpx 0;
box-sizing: border-box;
}
}
}
.newbar {
padding: 32rpx 0;
box-sizing: border-box;
border-bottom: 1px solid #F0f0f0;
.name {
color: rgba(0, 0, 0, 1);
font-size: 28rpx;
font-weight: 400;
font-family: "PingFang SC";
}
textarea {
margin-top: 32rpx;
padding: 24rpx;
width: 100%;
height: 200rpx;
box-sizing: border-box;
background-color: #F6F6F6;
}
.upimg {
margin-top: 32rpx;
}
}
}
.popname {
padding: 32rpx;
box-sizing: border-box;
width: 622rpx;
text-align: center;
.title {
color: rgba(0, 0, 0, 0.9);
font-size: 32rpx;
font-weight: 600;
font-family: "PingFang SC";
text-align: center;
}
.contant {
color: rgba(179, 179, 179, 1);
font-size: 28rpx;
font-weight: 400;
font-family: "PingFang SC";
text-align: center;
}
.btngroup {
margin-top: 80rpx;
display: flex;
align-items: center;
justify-content: space-between;
.concle {
width: 264rpx;
height: 76rpx;
border-radius: 16rpx;
opacity: 1;
line-height: 76rpx;
color: rgba(0, 0, 0, 0.9);
font-size: 28rpx;
font-weight: 500;
font-family: "PingFang SC";
text-align: center;
background: rgba(246, 246, 246, 1);
}
.requt {
width: 264rpx;
height: 76rpx;
color: rgba(0, 0, 0, 0.9);
font-size: 28rpx;
font-weight: 500;
font-family: "PingFang SC";
text-align: center;
line-height: 76rpx;
border-radius: 16rpx;
opacity: 1;
background: rgba(254, 208, 0, 1);
}
}
}
.btn {
position: fixed;
bottom: 50rpx;
left: 0;
width: 100%;
// height: 128rpx;
padding: 16rpx 32rpx;
padding-bottom: 100rpx;
box-sizing: border-box;
opacity: 1;
background: rgba(255, 255, 255, 1);
.paybtn {
width: 100%;
height: 96rpx;
line-height: 96rpx;
text-align: center;
border-radius: 28rpx;
opacity: 1;
color: rgba(0, 0, 0, 0.9);
font-size: 32rpx;
font-weight: 600;
font-family: "PingFang SC";
background: linear-gradient(134.8deg, rgba(255, 232, 100, 1) 0%, rgba(255, 216, 0, 1) 100%);
}
}
}
padding-bottom: 100rpx;
box-sizing: border-box;
opacity: 1;
background: rgba(255, 255, 255, 1);
.paybtn {
width: 100%;
height: 96rpx;
line-height: 96rpx;
text-align: center;
border-radius: 28rpx;
opacity: 1;
color: rgba(0, 0, 0, 0.9);
font-size: 32rpx;
font-weight: 600;
font-family: "PingFang SC";
background: linear-gradient(134.8deg, rgba(255, 232, 100, 1) 0%, rgba(255, 216, 0, 1) 100%);
}
}
}
}
.u-textarea {
margin-top: 32rpx;
min-height: 200rpx;
background: #f4f5f7;
}
/deep/ .uni-textarea-wrapper {
height: 100% !important;
}
}
</style>
... ...
<template>
<view class="">
<rich-text :nodes="text"></rich-text>
</view>
</template>
<view class="" style="padding: 32rpx;">
<!-- <rich-text :nodes="text"></rich-text> -->
<u-parse :content="text" noData="数据加载中..." @preview="preview" @navigate="navigate" ></u-parse>
</view>
</template>
<script>
import { getAgreement } from '@/api/login.js'
import {
getAgreement
} from '@/api/login.js'
import uParse from '@/components/u-parse/u-parse.vue'
export default {
components: {
uParse
},
data() {
return {
text: '',
type:''
type: ''
}
},
onLoad(e) {
this.type = e.type
wx.setNavigationBarTitle({ title: e.type==1?'用户协议':e.type==2?'隐私政策':'' })
wx.setNavigationBarTitle({
title: e.type == 1 ? '用户协议' : e.type == 2 ? '隐私政策' : ''
})
this.getAgreement()
},
methods: {
async getAgreement(){
try {
const res = await getAgreement(this.type)
this.text = res.agreement
console.log('getAgreement', res)
// 保存数据
} catch (err) {
uni.showToast({ title:err,icon:'none' })
console.log('getAgreement', err)
}
async getAgreement() {
uni.showLoading({
title: '加载中',
mask: true
})
try {
const res = await getAgreement(this.type)
this.text = res.agreement
uni.hideLoading();
// 保存数据
} catch (err) {
uni.showToast({ title:err,icon:'none' })
}
},
},
}
</script>
<style>
}
</script>
<style>
@import url("@/components/u-parse/u-parse.css");
</style>
... ...
... ... @@ -5,10 +5,10 @@
<view class="bar flexwrap">
<view class="name">
用户名
手机号
</view>
<view class="last name">
<input v-model="account" maxlength="16" type="text" value="" placeholder="请输入用户名" />
<input v-model="account" maxlength="16" type="text" value="" placeholder="请输入手机号" />
</view>
</view>
<view class="bar flexwrap">
... ... @@ -16,7 +16,7 @@
密码:
</view>
<view class="last name">
<input v-model="password" maxlength="16" type="password" value="" placeholder="请输入密码" />
<input v-model="password" maxlength="16" type="password" value="" placeholder="请输入密码"/>
</view>
</view>
<view class="loginbtn" @click="doLogin">
... ...
... ... @@ -17,7 +17,7 @@
验证码:
</view>
<view class="lastname">
<input v-model="captcha" maxlength="" type="number" value="" placeholder="请输入验证码" />
<input v-model="captcha" maxlength="4" type="number" value="" placeholder="请输入验证码" />
<view class="code" @click="getCode">
{{num==0?'获取验证码':num + '秒重新发送'}}
</view>
... ...