正在显示
31 个修改的文件
包含
4788 行增加
和
0 行删除
App.vue
0 → 100644
1 | +<script> | ||
2 | +export default { | ||
3 | + onLaunch: function() {}, | ||
4 | + onShow: function() {}, | ||
5 | + onHide: function() {}, | ||
6 | + post: function(url, data) { | ||
7 | + var promise = new Promise((resolve, reject) => { | ||
8 | + //init | ||
9 | + let that = this, | ||
10 | + token = uni.getStorageSync('token'), | ||
11 | + header = { | ||
12 | + 'token': token || '' | ||
13 | + }, | ||
14 | + postData; | ||
15 | + //网络请求 | ||
16 | + uni.request({ | ||
17 | + url: this.globalData.baseUrl + url, | ||
18 | + data: data, | ||
19 | + method: 'POST', | ||
20 | + header: header, | ||
21 | + success: function(res) { | ||
22 | + //返回取得的数据 | ||
23 | + if (res.data.code == '1') { | ||
24 | + resolve(res.data.data); | ||
25 | + } else { | ||
26 | + uni.showToast({ | ||
27 | + title: res.data.msg, | ||
28 | + icon: 'none' | ||
29 | + }); | ||
30 | + reject(res.data); | ||
31 | + } | ||
32 | + }, | ||
33 | + fail: function(e) { | ||
34 | + reject('网络出错'); | ||
35 | + uni.hideNavigationBarLoading(); | ||
36 | + } | ||
37 | + }); | ||
38 | + }); | ||
39 | + return promise; | ||
40 | + }, | ||
41 | + globalData: { | ||
42 | + userInfo: null, | ||
43 | + baseUrl: 'https://cardxcx.w.broing.cn' | ||
44 | + }, | ||
45 | + | ||
46 | + | ||
47 | + | ||
48 | + | ||
49 | + | ||
50 | + // 上传图片 | ||
51 | + upload(file) { | ||
52 | + var promise = new Promise((resolve, reject) => { | ||
53 | + let url = 'https://cardxcx.w.broing.cn/api/common/upload'; | ||
54 | + let head = { | ||
55 | + 'token': uni.getStorageSync('token'), | ||
56 | + }; | ||
57 | + // let typename = { | ||
58 | + // filetype: filetype //其他参数 | ||
59 | + // }; | ||
60 | + uni.uploadFile({ | ||
61 | + url: url, //仅为示例,非真实的接口地址 | ||
62 | + filePath: file, | ||
63 | + name: 'file', | ||
64 | + header: head, | ||
65 | + // formData: typename, | ||
66 | + success: function(res) { | ||
67 | + let temdata = JSON.parse(res.data); | ||
68 | + let urlobj = { | ||
69 | + url: temdata.data.url, | ||
70 | + }; | ||
71 | + resolve(urlobj); | ||
72 | + uni.hideNavigationBarLoading(); | ||
73 | + uni.hideLoading(); | ||
74 | + }, | ||
75 | + fail: function(res) { | ||
76 | + reject('网络出错'); | ||
77 | + uni.hideNavigationBarLoading(); | ||
78 | + uni.hideLoading(); | ||
79 | + }, | ||
80 | + complete: () => { | ||
81 | + uni.hideNavigationBarLoading(); | ||
82 | + uni.hideLoading(); | ||
83 | + } | ||
84 | + }); | ||
85 | + }); | ||
86 | + return promise; | ||
87 | + } | ||
88 | +}; | ||
89 | +</script> | ||
90 | + | ||
91 | +<style > | ||
92 | + /*每个页面公共css */ | ||
93 | + | ||
94 | + image { | ||
95 | + width: 100%; | ||
96 | + height: 100%; | ||
97 | + display: block; | ||
98 | + } | ||
99 | + /* 布局 */ | ||
100 | + .layer_star { | ||
101 | + display: flex; | ||
102 | + display: -webkit-flex; | ||
103 | + flex-direction: row; | ||
104 | + justify-content: flex-start; | ||
105 | + align-items: center | ||
106 | + } | ||
107 | + | ||
108 | + .layer_nostar { | ||
109 | + display: flex; | ||
110 | + display: -webkit-flex; | ||
111 | + justify-content: flex-start; | ||
112 | + } | ||
113 | + | ||
114 | + .layer_center { | ||
115 | + display: flex; | ||
116 | + display: -webkit-flex; | ||
117 | + justify-content: center; | ||
118 | + align-items: center | ||
119 | + } | ||
120 | + | ||
121 | + .layer_nocenter { | ||
122 | + display: flex; | ||
123 | + display: -webkit-flex; | ||
124 | + justify-content: center; | ||
125 | + } | ||
126 | + | ||
127 | + .layer_end { | ||
128 | + display: flex; | ||
129 | + display: -webkit-flex; | ||
130 | + justify-content: flex-end; | ||
131 | + align-items: center | ||
132 | + } | ||
133 | + | ||
134 | + .layer_noend { | ||
135 | + display: flex; | ||
136 | + display: -webkit-flex; | ||
137 | + justify-content: flex-end; | ||
138 | + } | ||
139 | + | ||
140 | + .layer_between { | ||
141 | + display: flex; | ||
142 | + display: -webkit-flex; | ||
143 | + justify-content: space-between; | ||
144 | + align-items: center | ||
145 | + } | ||
146 | + | ||
147 | + .layer_nobetween { | ||
148 | + display: flex; | ||
149 | + display: -webkit-flex; | ||
150 | + justify-content: space-between; | ||
151 | + } | ||
152 | + | ||
153 | + .flex_star { | ||
154 | + display: flex; | ||
155 | + display: -webkit-flex; | ||
156 | + flex-direction: column; | ||
157 | + align-items: flex-start | ||
158 | + } | ||
159 | + .flex_column_center{ | ||
160 | + display: flex; | ||
161 | + display: -webkit-flex; | ||
162 | + flex-direction: column; | ||
163 | + justify-content: flex-start; | ||
164 | + align-items: center | ||
165 | + } | ||
166 | + .flex_column_nojustify{ | ||
167 | + display: flex; | ||
168 | + display: -webkit-flex; | ||
169 | + flex-direction: column; | ||
170 | + align-items: center; | ||
171 | + justify-content: center; | ||
172 | + } | ||
173 | + .flex_star_between { | ||
174 | + display: flex; | ||
175 | + display: -webkit-flex; | ||
176 | + flex-direction: column; | ||
177 | + justify-content: space-between; | ||
178 | + align-items: flex-start | ||
179 | + } | ||
180 | + | ||
181 | + .flex_center { | ||
182 | + display: flex; | ||
183 | + display: -webkit-flex; | ||
184 | + flex-direction: column; | ||
185 | + align-items: center; | ||
186 | + justify-content: center; | ||
187 | + } | ||
188 | + .flex_warp { | ||
189 | + display: flex; | ||
190 | + display: -webkit-flex; | ||
191 | + flex-wrap: wrap; | ||
192 | + align-items: center; | ||
193 | + justify-content: center; | ||
194 | + } | ||
195 | + .flex_wrap_between{ | ||
196 | + display: flex; | ||
197 | + display: -webkit-flex; | ||
198 | + flex-wrap: wrap; | ||
199 | + justify-content: space-between; | ||
200 | + } | ||
201 | + .flex_wrap_no{ | ||
202 | + display: flex; | ||
203 | + display: -webkit-flex; | ||
204 | + flex-wrap: wrap; | ||
205 | + } | ||
206 | + /* 模态框 */ | ||
207 | + | ||
208 | + .tx_mask { | ||
209 | + z-index: 99; | ||
210 | + width: 100%; | ||
211 | + height: 100vh; | ||
212 | + position: fixed; | ||
213 | + top: 0; | ||
214 | + left: 0; | ||
215 | + background-color: rgba(0, 0, 0, 0.5); | ||
216 | + } | ||
217 | + .mask_content{ | ||
218 | + background-color: rgba(255,255,255,1); | ||
219 | + width:686upx; | ||
220 | + /* height:298upx; */ | ||
221 | + border-radius:16upx; | ||
222 | + position: fixed; | ||
223 | + top: 50%; | ||
224 | + left: 50%; | ||
225 | + transform: translate(-50%,-50%); | ||
226 | + z-index: 100; | ||
227 | + } | ||
228 | + /* 购买弹窗 */ | ||
229 | + .mask_content_bottom{ | ||
230 | + background-color: #fff; | ||
231 | + position: fixed; | ||
232 | + left: 0; | ||
233 | + bottom: 0; | ||
234 | + z-index: 100; | ||
235 | + width: 100%; | ||
236 | + } | ||
237 | + .over_hide{ | ||
238 | + height: 100vh; | ||
239 | + overflow: hidden; | ||
240 | + } | ||
241 | + | ||
242 | +</style> |
1 | +<template> | ||
2 | + <!--增加audio标签支持--> | ||
3 | + <audio | ||
4 | + :id="node.attr.id" | ||
5 | + :class="node.classStr" | ||
6 | + :style="node.styleStr" | ||
7 | + :src="node.attr.src" | ||
8 | + :loop="node.attr.loop" | ||
9 | + :poster="node.attr.poster" | ||
10 | + :name="node.attr.name" | ||
11 | + :author="node.attr.author" | ||
12 | + controls></audio> | ||
13 | +</template> | ||
14 | + | ||
15 | +<script> | ||
16 | +export default { | ||
17 | + name: 'wxParseAudio', | ||
18 | + props: { | ||
19 | + node: { | ||
20 | + type: Object, | ||
21 | + default() { | ||
22 | + return {}; | ||
23 | + }, | ||
24 | + }, | ||
25 | + }, | ||
26 | +}; | ||
27 | +</script> |
components/u-parse/components/wxParseImg.vue
0 → 100644
1 | +<template> | ||
2 | + <image | ||
3 | + :mode="node.attr.mode" | ||
4 | + :lazy-load="node.attr.lazyLoad" | ||
5 | + :class="node.classStr" | ||
6 | + :style="newStyleStr || node.styleStr" | ||
7 | + :data-src="node.attr.src" | ||
8 | + :src="node.attr.src" | ||
9 | + @tap="wxParseImgTap" | ||
10 | + @load="wxParseImgLoad" | ||
11 | + /> | ||
12 | +</template> | ||
13 | + | ||
14 | +<script> | ||
15 | +export default { | ||
16 | + name: 'wxParseImg', | ||
17 | + data() { | ||
18 | + return { | ||
19 | + newStyleStr: '', | ||
20 | + preview: true, | ||
21 | + }; | ||
22 | + }, | ||
23 | + props: { | ||
24 | + node: { | ||
25 | + type: Object, | ||
26 | + default() { | ||
27 | + return {}; | ||
28 | + }, | ||
29 | + }, | ||
30 | + }, | ||
31 | + methods: { | ||
32 | + wxParseImgTap(e) { | ||
33 | + if (!this.preview) return; | ||
34 | + const { src } = e.currentTarget.dataset; | ||
35 | + if (!src) return; | ||
36 | + let parent = this.$parent; | ||
37 | + while(!parent.preview || typeof parent.preview !== 'function') {// TODO 遍历获取父节点执行方法 | ||
38 | + parent = parent.$parent; | ||
39 | + } | ||
40 | + parent.preview(src, e); | ||
41 | + }, | ||
42 | + // 图片视觉宽高计算函数区 | ||
43 | + wxParseImgLoad(e) { | ||
44 | + const { src } = e.currentTarget.dataset; | ||
45 | + if (!src) return; | ||
46 | + const { width, height } = e.mp.detail; | ||
47 | + const recal = this.wxAutoImageCal(width, height); | ||
48 | + const { imageheight, imageWidth } = recal; | ||
49 | + const { padding, mode } = this.node.attr; | ||
50 | + const { styleStr } = this.node; | ||
51 | + const imageHeightStyle = mode === 'widthFix' ? '' : `height: ${imageheight}px;`; | ||
52 | + this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px; padding: 0 ${+padding}px;`; | ||
53 | + }, | ||
54 | + // 计算视觉优先的图片宽高 | ||
55 | + wxAutoImageCal(originalWidth, originalHeight) { | ||
56 | + // 获取图片的原始长宽 | ||
57 | + const { padding } = this.node.attr; | ||
58 | + const windowWidth = this.node.$screen.width - (2 * padding); | ||
59 | + const results = {}; | ||
60 | + | ||
61 | + if (originalWidth < 60 || originalHeight < 60) { | ||
62 | + const { src } = this.node.attr; | ||
63 | + let parent = this.$parent; | ||
64 | + while(!parent.preview || typeof parent.preview !== 'function') { | ||
65 | + parent = parent.$parent; | ||
66 | + } | ||
67 | + parent.removeImageUrl(src); | ||
68 | + this.preview = false; | ||
69 | + } | ||
70 | + | ||
71 | + // 判断按照那种方式进行缩放 | ||
72 | + if (originalWidth > windowWidth) { | ||
73 | + // 在图片width大于手机屏幕width时候 | ||
74 | + results.imageWidth = windowWidth; | ||
75 | + results.imageheight = windowWidth * (originalHeight / originalWidth); | ||
76 | + } else { | ||
77 | + // 否则展示原来的数据 | ||
78 | + results.imageWidth = originalWidth; | ||
79 | + results.imageheight = originalHeight; | ||
80 | + } | ||
81 | + | ||
82 | + return results; | ||
83 | + }, | ||
84 | + }, | ||
85 | +}; | ||
86 | +</script> |
1 | +<template> | ||
2 | + <view> | ||
3 | + <!--判断是否是标签节点--> | ||
4 | + <block v-if="node.node == 'element'"> | ||
5 | + <block v-if="node.tag == 'button'"> | ||
6 | + <button type="default" size="mini"> | ||
7 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
8 | + <wx-parse-template :node="node" /> | ||
9 | + </block> | ||
10 | + </button> | ||
11 | + </block> | ||
12 | + | ||
13 | + <!--li类型--> | ||
14 | + <block v-else-if="node.tag == 'li'"> | ||
15 | + <view :class="node.classStr" :style="node.styleStr"> | ||
16 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
17 | + <wx-parse-template :node="node" /> | ||
18 | + </block> | ||
19 | + </view> | ||
20 | + </block> | ||
21 | + | ||
22 | + <!--video类型--> | ||
23 | + <block v-else-if="node.tag == 'video'"> | ||
24 | + <wx-parse-video :node="node" /> | ||
25 | + </block> | ||
26 | + | ||
27 | + <!--audio类型--> | ||
28 | + <block v-else-if="node.tag == 'audio'"> | ||
29 | + <wx-parse-audio :node="node" /> | ||
30 | + </block> | ||
31 | + | ||
32 | + <!--img类型--> | ||
33 | + <block v-else-if="node.tag == 'img'"> | ||
34 | + <wx-parse-img :node="node" /> | ||
35 | + </block> | ||
36 | + | ||
37 | + <!--a类型--> | ||
38 | + <block v-else-if="node.tag == 'a'"> | ||
39 | + <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | ||
40 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
41 | + <wx-parse-template :node="node" /> | ||
42 | + </block> | ||
43 | + </view> | ||
44 | + </block> | ||
45 | + | ||
46 | + <!--table类型--> | ||
47 | + <block v-else-if="node.tag == 'table'"> | ||
48 | + <view :class="node.classStr" class="table" :style="node.styleStr"> | ||
49 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
50 | + <wx-parse-template :node="node" /> | ||
51 | + </block> | ||
52 | + </view> | ||
53 | + </block> | ||
54 | + | ||
55 | + <!--br类型--> | ||
56 | + <block v-else-if="node.tag == 'br'"> | ||
57 | + <text>\n</text> | ||
58 | + </block> | ||
59 | + | ||
60 | + <!--其他标签--> | ||
61 | + <block v-else> | ||
62 | + <view :class="node.classStr" :style="node.styleStr"> | ||
63 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
64 | + <wx-parse-template :node="node" /> | ||
65 | + </block> | ||
66 | + </view> | ||
67 | + </block> | ||
68 | + | ||
69 | + </block> | ||
70 | + | ||
71 | + <!--判断是否是文本节点--> | ||
72 | + <block v-else-if="node.node == 'text'">{{node.text}}</block> | ||
73 | + </view> | ||
74 | +</template> | ||
75 | + | ||
76 | +<script> | ||
77 | + import wxParseTemplate from './wxParseTemplate1'; | ||
78 | + import wxParseImg from './wxParseImg'; | ||
79 | + import wxParseVideo from './wxParseVideo'; | ||
80 | + import wxParseAudio from './wxParseAudio'; | ||
81 | + | ||
82 | + export default { | ||
83 | + name: 'wxParseTemplate0', | ||
84 | + props: { | ||
85 | + node: {}, | ||
86 | + }, | ||
87 | + components: { | ||
88 | + wxParseTemplate, | ||
89 | + wxParseImg, | ||
90 | + wxParseVideo, | ||
91 | + wxParseAudio, | ||
92 | + }, | ||
93 | + methods: { | ||
94 | + wxParseATap(e) { | ||
95 | + const { | ||
96 | + href | ||
97 | + } = e.currentTarget.dataset;// TODO currentTarget才有dataset | ||
98 | + if (!href) return; | ||
99 | + let parent = this.$parent; | ||
100 | + while(!parent.preview || typeof parent.preview !== 'function') {// TODO 遍历获取父节点执行方法 | ||
101 | + parent = parent.$parent; | ||
102 | + } | ||
103 | + parent.navigate(href, e); | ||
104 | + }, | ||
105 | + }, | ||
106 | + }; | ||
107 | +</script> |
1 | +<template> | ||
2 | + <view :class="(node.tag == 'li' ? node.classStr : (node.node==='text'?'text':''))"> | ||
3 | + <!--判断是否是标签节点--> | ||
4 | + <block v-if="node.node == 'element'"> | ||
5 | + <block v-if="node.tag == 'button'"> | ||
6 | + <button type="default" size="mini"> | ||
7 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
8 | + <wx-parse-template :node="node" /> | ||
9 | + </block> | ||
10 | + </button> | ||
11 | + </block> | ||
12 | + | ||
13 | + <!--li类型--> | ||
14 | + <block v-else-if="node.tag == 'li'"> | ||
15 | + <!-- <view :class="node.classStr" :style="node.styleStr"> --> | ||
16 | + <view :style="node.styleStr"> | ||
17 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
18 | + <wx-parse-template :node="node" /> | ||
19 | + </block> | ||
20 | + </view> | ||
21 | + </block> | ||
22 | + | ||
23 | + <!--video类型--> | ||
24 | + <block v-else-if="node.tag == 'video'"> | ||
25 | + <wx-parse-video :node="node" /> | ||
26 | + </block> | ||
27 | + | ||
28 | + <!--audio类型--> | ||
29 | + <block v-else-if="node.tag == 'audio'"> | ||
30 | + <wx-parse-audio :node="node" /> | ||
31 | + </block> | ||
32 | + | ||
33 | + <!--img类型--> | ||
34 | + <block v-else-if="node.tag == 'img'"> | ||
35 | + <wx-parse-img :node="node" /> | ||
36 | + </block> | ||
37 | + | ||
38 | + <!--a类型--> | ||
39 | + <block v-else-if="node.tag == 'a'"> | ||
40 | + <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | ||
41 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
42 | + <wx-parse-template :node="node" /> | ||
43 | + </block> | ||
44 | + </view> | ||
45 | + </block> | ||
46 | + | ||
47 | + <!--br类型--> | ||
48 | + <block v-else-if="node.tag == 'br'"> | ||
49 | + <text>\n</text> | ||
50 | + </block> | ||
51 | + | ||
52 | + <!--其他标签--> | ||
53 | + <block v-else> | ||
54 | + <view :class="node.classStr" :style="node.styleStr"> | ||
55 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
56 | + <wx-parse-template :node="node" /> | ||
57 | + </block> | ||
58 | + </view> | ||
59 | + </block> | ||
60 | + | ||
61 | + </block> | ||
62 | + | ||
63 | + <!--判断是否是文本节点--> | ||
64 | + <block v-else-if="node.node == 'text'">{{node.text}}</block> | ||
65 | + </view> | ||
66 | +</template> | ||
67 | + | ||
68 | +<script> | ||
69 | + import wxParseTemplate from './wxParseTemplate2'; | ||
70 | + import wxParseImg from './wxParseImg'; | ||
71 | + import wxParseVideo from './wxParseVideo'; | ||
72 | + import wxParseAudio from './wxParseAudio'; | ||
73 | + | ||
74 | + export default { | ||
75 | + name: 'wxParseTemplate1', | ||
76 | + props: { | ||
77 | + node: {}, | ||
78 | + }, | ||
79 | + components: { | ||
80 | + wxParseTemplate, | ||
81 | + wxParseImg, | ||
82 | + wxParseVideo, | ||
83 | + wxParseAudio, | ||
84 | + }, | ||
85 | + methods: { | ||
86 | + wxParseATap(e) { | ||
87 | + const { | ||
88 | + href | ||
89 | + } = e.currentTarget.dataset; | ||
90 | + if (!href) return; | ||
91 | + let parent = this.$parent; | ||
92 | + while(!parent.preview || typeof parent.preview !== 'function') { | ||
93 | + parent = parent.$parent; | ||
94 | + } | ||
95 | + parent.navigate(href, e); | ||
96 | + }, | ||
97 | + }, | ||
98 | + }; | ||
99 | +</script> |
1 | +<template> | ||
2 | + <view> | ||
3 | + <!--判断是否是标签节点--> | ||
4 | + <block v-if="node.node == 'element'"> | ||
5 | + <block v-if="node.tag == 'button'"> | ||
6 | + <button type="default" size="mini"> | ||
7 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
8 | + <wx-parse-template :node="node" /> | ||
9 | + </block> | ||
10 | + </button> | ||
11 | + </block> | ||
12 | + | ||
13 | + <!--li类型--> | ||
14 | + <block v-else-if="node.tag == 'li'"> | ||
15 | + <view :class="node.classStr" :style="node.styleStr"> | ||
16 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
17 | + <wx-parse-template :node="node" /> | ||
18 | + </block> | ||
19 | + </view> | ||
20 | + </block> | ||
21 | + | ||
22 | + <!--video类型--> | ||
23 | + <block v-else-if="node.tag == 'video'"> | ||
24 | + <wx-parse-video :node="node" /> | ||
25 | + </block> | ||
26 | + | ||
27 | + <!--audio类型--> | ||
28 | + <block v-else-if="node.tag == 'audio'"> | ||
29 | + <wx-parse-audio :node="node" /> | ||
30 | + </block> | ||
31 | + | ||
32 | + <!--img类型--> | ||
33 | + <block v-else-if="node.tag == 'img'"> | ||
34 | + <wx-parse-img :node="node" /> | ||
35 | + </block> | ||
36 | + | ||
37 | + <!--a类型--> | ||
38 | + <block v-else-if="node.tag == 'a'"> | ||
39 | + <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | ||
40 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
41 | + <wx-parse-template :node="node" /> | ||
42 | + </block> | ||
43 | + </view> | ||
44 | + </block> | ||
45 | + | ||
46 | + <!--br类型--> | ||
47 | + <block v-else-if="node.tag == 'br'"> | ||
48 | + <text>\n</text> | ||
49 | + </block> | ||
50 | + | ||
51 | + <!--其他标签--> | ||
52 | + <block v-else> | ||
53 | + <view :class="node.classStr" :style="node.styleStr"> | ||
54 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
55 | + <wx-parse-template :node="node" /> | ||
56 | + </block> | ||
57 | + </view> | ||
58 | + </block> | ||
59 | + </block> | ||
60 | + | ||
61 | + <!--判断是否是文本节点--> | ||
62 | + <block v-else-if="node.node == 'text'">{{node.text}}</block> | ||
63 | + </view> | ||
64 | +</template> | ||
65 | + | ||
66 | +<script> | ||
67 | + import wxParseTemplate from './wxParseTemplate11'; | ||
68 | + import wxParseImg from './wxParseImg'; | ||
69 | + import wxParseVideo from './wxParseVideo'; | ||
70 | + import wxParseAudio from './wxParseAudio'; | ||
71 | + | ||
72 | + export default { | ||
73 | + name: 'wxParseTemplate10', | ||
74 | + props: { | ||
75 | + node: {}, | ||
76 | + }, | ||
77 | + components: { | ||
78 | + wxParseTemplate, | ||
79 | + wxParseImg, | ||
80 | + wxParseVideo, | ||
81 | + wxParseAudio, | ||
82 | + }, | ||
83 | + methods: { | ||
84 | + wxParseATap(e) { | ||
85 | + const { | ||
86 | + href | ||
87 | + } = e.currentTarget.dataset; | ||
88 | + if (!href) return; | ||
89 | + let parent = this.$parent; | ||
90 | + while(!parent.preview || typeof parent.preview !== 'function') { | ||
91 | + parent = parent.$parent; | ||
92 | + } | ||
93 | + parent.navigate(href, e); | ||
94 | + }, | ||
95 | + }, | ||
96 | + }; | ||
97 | +</script> |
1 | +<template> | ||
2 | + <view> | ||
3 | + <!--判断是否是标签节点--> | ||
4 | + <block v-if="node.node == 'element'"> | ||
5 | + <!--button类型--> | ||
6 | + <block v-if="node.tag == 'button'"> | ||
7 | + <button type="default" size="mini"> | ||
8 | + </button> | ||
9 | + </block> | ||
10 | + | ||
11 | + <!--li类型--> | ||
12 | + <block v-else-if="node.tag == 'li'"> | ||
13 | + <view :class="node.classStr" :style="node.styleStr"> | ||
14 | + {{node.text}} | ||
15 | + </view> | ||
16 | + </block> | ||
17 | + | ||
18 | + <!--video类型--> | ||
19 | + <block v-else-if="node.tag == 'video'"> | ||
20 | + <wx-parse-video :node="node" /> | ||
21 | + </block> | ||
22 | + | ||
23 | + <!--audio类型--> | ||
24 | + <block v-else-if="node.tag == 'audio'"> | ||
25 | + <wx-parse-audio :node="node" /> | ||
26 | + </block> | ||
27 | + | ||
28 | + <!--img类型--> | ||
29 | + <block v-else-if="node.tag == 'img'"> | ||
30 | + <wx-parse-img :node="node" /> | ||
31 | + </block> | ||
32 | + | ||
33 | + <!--a类型--> | ||
34 | + <block v-else-if="node.tag == 'a'"> | ||
35 | + <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | ||
36 | + {{node.text}} | ||
37 | + </view> | ||
38 | + </block> | ||
39 | + | ||
40 | + <!--br类型--> | ||
41 | + <block v-else-if="node.tag == 'br'"> | ||
42 | + <text>\n</text> | ||
43 | + </block> | ||
44 | + | ||
45 | + <!--其他标签--> | ||
46 | + <block v-else> | ||
47 | + <view :class="node.classStr" :style="node.styleStr"> | ||
48 | + {{node.text}} | ||
49 | + </view> | ||
50 | + </block> | ||
51 | + </block> | ||
52 | + | ||
53 | + <!--判断是否是文本节点--> | ||
54 | + <block v-else-if="node.node == 'text'">{{node.text}}</block> | ||
55 | + </view> | ||
56 | +</template> | ||
57 | + | ||
58 | +<script> | ||
59 | + import wxParseImg from './wxParseImg'; | ||
60 | + import wxParseVideo from './wxParseVideo'; | ||
61 | + import wxParseAudio from './wxParseAudio'; | ||
62 | + | ||
63 | + export default { | ||
64 | + name: 'wxParseTemplate11', | ||
65 | + props: { | ||
66 | + node: {}, | ||
67 | + }, | ||
68 | + components: { | ||
69 | + wxParseImg, | ||
70 | + wxParseVideo, | ||
71 | + wxParseAudio, | ||
72 | + }, | ||
73 | + methods: { | ||
74 | + wxParseATap(e) { | ||
75 | + const { | ||
76 | + href | ||
77 | + } = e.currentTarget.dataset; | ||
78 | + if (!href) return; | ||
79 | + let parent = this.$parent; | ||
80 | + while(!parent.preview || typeof parent.preview !== 'function') { | ||
81 | + parent = parent.$parent; | ||
82 | + } | ||
83 | + parent.navigate(href, e); | ||
84 | + }, | ||
85 | + }, | ||
86 | + }; | ||
87 | +</script> |
1 | +<template> | ||
2 | + <view> | ||
3 | + <!--判断是否是标签节点--> | ||
4 | + <block v-if="node.node == 'element'"> | ||
5 | + <block v-if="node.tag == 'button'"> | ||
6 | + <button type="default" size="mini"> | ||
7 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
8 | + <wx-parse-template :node="node" /> | ||
9 | + </block> | ||
10 | + </button> | ||
11 | + </block> | ||
12 | + | ||
13 | + <!--li类型--> | ||
14 | + <block v-else-if="node.tag == 'li'"> | ||
15 | + <view :class="node.classStr" :style="node.styleStr"> | ||
16 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
17 | + <wx-parse-template :node="node" /> | ||
18 | + </block> | ||
19 | + </view> | ||
20 | + </block> | ||
21 | + | ||
22 | + <!--video类型--> | ||
23 | + <block v-else-if="node.tag == 'video'"> | ||
24 | + <wx-parse-video :node="node" /> | ||
25 | + </block> | ||
26 | + | ||
27 | + <!--audio类型--> | ||
28 | + <block v-else-if="node.tag == 'audio'"> | ||
29 | + <wx-parse-audio :node="node" /> | ||
30 | + </block> | ||
31 | + | ||
32 | + <!--img类型--> | ||
33 | + <block v-else-if="node.tag == 'img'"> | ||
34 | + <wx-parse-img :node="node" /> | ||
35 | + </block> | ||
36 | + | ||
37 | + <!--a类型--> | ||
38 | + <block v-else-if="node.tag == 'a'"> | ||
39 | + <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | ||
40 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
41 | + <wx-parse-template :node="node" /> | ||
42 | + </block> | ||
43 | + </view> | ||
44 | + </block> | ||
45 | + | ||
46 | + <!--br类型--> | ||
47 | + <block v-else-if="node.tag == 'br'"> | ||
48 | + <text>\n</text> | ||
49 | + </block> | ||
50 | + | ||
51 | + <!--其他标签--> | ||
52 | + <block v-else> | ||
53 | + <view :class="node.classStr" :style="node.styleStr"> | ||
54 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
55 | + <wx-parse-template :node="node" /> | ||
56 | + </block> | ||
57 | + </view> | ||
58 | + </block> | ||
59 | + | ||
60 | + </block> | ||
61 | + | ||
62 | + <!--判断是否是文本节点--> | ||
63 | + <block v-else-if="node.node == 'text'">{{node.text}}</block> | ||
64 | + </view> | ||
65 | +</template> | ||
66 | + | ||
67 | +<script> | ||
68 | + import wxParseTemplate from './wxParseTemplate3'; | ||
69 | + import wxParseImg from './wxParseImg'; | ||
70 | + import wxParseVideo from './wxParseVideo'; | ||
71 | + import wxParseAudio from './wxParseAudio'; | ||
72 | + | ||
73 | + export default { | ||
74 | + name: 'wxParseTemplate2', | ||
75 | + props: { | ||
76 | + node: {}, | ||
77 | + }, | ||
78 | + components: { | ||
79 | + wxParseTemplate, | ||
80 | + wxParseImg, | ||
81 | + wxParseVideo, | ||
82 | + wxParseAudio, | ||
83 | + }, | ||
84 | + methods: { | ||
85 | + wxParseATap(e) { | ||
86 | + const { | ||
87 | + href | ||
88 | + } = e.currentTarget.dataset; | ||
89 | + if (!href) return; | ||
90 | + let parent = this.$parent; | ||
91 | + while(!parent.preview || typeof parent.preview !== 'function') { | ||
92 | + parent = parent.$parent; | ||
93 | + } | ||
94 | + parent.navigate(href, e); | ||
95 | + }, | ||
96 | + }, | ||
97 | + }; | ||
98 | +</script> |
1 | +<template> | ||
2 | + <view> | ||
3 | + <!--判断是否是标签节点--> | ||
4 | + <block v-if="node.node == 'element'"> | ||
5 | + <block v-if="node.tag == 'button'"> | ||
6 | + <button type="default" size="mini"> | ||
7 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
8 | + <wx-parse-template :node="node" /> | ||
9 | + </block> | ||
10 | + </button> | ||
11 | + </block> | ||
12 | + | ||
13 | + <!--li类型--> | ||
14 | + <block v-else-if="node.tag == 'li'"> | ||
15 | + <view :class="node.classStr" :style="node.styleStr"> | ||
16 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
17 | + <wx-parse-template :node="node" /> | ||
18 | + </block> | ||
19 | + </view> | ||
20 | + </block> | ||
21 | + | ||
22 | + <!--video类型--> | ||
23 | + <block v-else-if="node.tag == 'video'"> | ||
24 | + <wx-parse-video :node="node" /> | ||
25 | + </block> | ||
26 | + | ||
27 | + <!--audio类型--> | ||
28 | + <block v-else-if="node.tag == 'audio'"> | ||
29 | + <wx-parse-audio :node="node" /> | ||
30 | + </block> | ||
31 | + | ||
32 | + <!--img类型--> | ||
33 | + <block v-else-if="node.tag == 'img'"> | ||
34 | + <wx-parse-img :node="node" /> | ||
35 | + </block> | ||
36 | + | ||
37 | + <!--a类型--> | ||
38 | + <block v-else-if="node.tag == 'a'"> | ||
39 | + <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | ||
40 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
41 | + <wx-parse-template :node="node" /> | ||
42 | + </block> | ||
43 | + </view> | ||
44 | + </block> | ||
45 | + | ||
46 | + <!--br类型--> | ||
47 | + <block v-else-if="node.tag == 'br'"> | ||
48 | + <text>\n</text> | ||
49 | + </block> | ||
50 | + | ||
51 | + <!--其他标签--> | ||
52 | + <block v-else> | ||
53 | + <view :class="node.classStr" :style="node.styleStr"> | ||
54 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
55 | + <wx-parse-template :node="node" /> | ||
56 | + </block> | ||
57 | + </view> | ||
58 | + </block> | ||
59 | + | ||
60 | + </block> | ||
61 | + | ||
62 | + <!--判断是否是文本节点--> | ||
63 | + <block v-else-if="node.node == 'text'">{{node.text}}</block> | ||
64 | + </view> | ||
65 | +</template> | ||
66 | + | ||
67 | +<script> | ||
68 | + import wxParseTemplate from './wxParseTemplate4'; | ||
69 | + import wxParseImg from './wxParseImg'; | ||
70 | + import wxParseVideo from './wxParseVideo'; | ||
71 | + import wxParseAudio from './wxParseAudio'; | ||
72 | + | ||
73 | + export default { | ||
74 | + name: 'wxParseTemplate3', | ||
75 | + props: { | ||
76 | + node: {}, | ||
77 | + }, | ||
78 | + components: { | ||
79 | + wxParseTemplate, | ||
80 | + wxParseImg, | ||
81 | + wxParseVideo, | ||
82 | + wxParseAudio, | ||
83 | + }, | ||
84 | + methods: { | ||
85 | + wxParseATap(e) { | ||
86 | + const { | ||
87 | + href | ||
88 | + } = e.currentTarget.dataset; | ||
89 | + if (!href) return; | ||
90 | + let parent = this.$parent; | ||
91 | + while(!parent.preview || typeof parent.preview !== 'function') { | ||
92 | + parent = parent.$parent; | ||
93 | + } | ||
94 | + parent.navigate(href, e); | ||
95 | + }, | ||
96 | + }, | ||
97 | + }; | ||
98 | +</script> |
1 | +<template> | ||
2 | + <view> | ||
3 | + <!--判断是否是标签节点--> | ||
4 | + <block v-if="node.node == 'element'"> | ||
5 | + <block v-if="node.tag == 'button'"> | ||
6 | + <button type="default" size="mini"> | ||
7 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
8 | + <wx-parse-template :node="node" /> | ||
9 | + </block> | ||
10 | + </button> | ||
11 | + </block> | ||
12 | + | ||
13 | + <!--li类型--> | ||
14 | + <block v-else-if="node.tag == 'li'"> | ||
15 | + <view :class="node.classStr" :style="node.styleStr"> | ||
16 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
17 | + <wx-parse-template :node="node" /> | ||
18 | + </block> | ||
19 | + </view> | ||
20 | + </block> | ||
21 | + | ||
22 | + <!--video类型--> | ||
23 | + <block v-else-if="node.tag == 'video'"> | ||
24 | + <wx-parse-video :node="node" /> | ||
25 | + </block> | ||
26 | + | ||
27 | + <!--audio类型--> | ||
28 | + <block v-else-if="node.tag == 'audio'"> | ||
29 | + <wx-parse-audio :node="node" /> | ||
30 | + </block> | ||
31 | + | ||
32 | + <!--img类型--> | ||
33 | + <block v-else-if="node.tag == 'img'"> | ||
34 | + <wx-parse-img :node="node" /> | ||
35 | + </block> | ||
36 | + | ||
37 | + <!--a类型--> | ||
38 | + <block v-else-if="node.tag == 'a'"> | ||
39 | + <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | ||
40 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
41 | + <wx-parse-template :node="node" /> | ||
42 | + </block> | ||
43 | + </view> | ||
44 | + </block> | ||
45 | + | ||
46 | + <!--br类型--> | ||
47 | + <block v-else-if="node.tag == 'br'"> | ||
48 | + <text>\n</text> | ||
49 | + </block> | ||
50 | + | ||
51 | + <!--其他标签--> | ||
52 | + <block v-else> | ||
53 | + <view :class="node.classStr" :style="node.styleStr"> | ||
54 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
55 | + <wx-parse-template :node="node" /> | ||
56 | + </block> | ||
57 | + </view> | ||
58 | + </block> | ||
59 | + | ||
60 | + </block> | ||
61 | + | ||
62 | + <!--判断是否是文本节点--> | ||
63 | + <block v-else-if="node.node == 'text'">{{node.text}}</block> | ||
64 | + </view> | ||
65 | +</template> | ||
66 | + | ||
67 | +<script> | ||
68 | + import wxParseTemplate from './wxParseTemplate5'; | ||
69 | + import wxParseImg from './wxParseImg'; | ||
70 | + import wxParseVideo from './wxParseVideo'; | ||
71 | + import wxParseAudio from './wxParseAudio'; | ||
72 | + | ||
73 | + export default { | ||
74 | + name: 'wxParseTemplate4', | ||
75 | + props: { | ||
76 | + node: {}, | ||
77 | + }, | ||
78 | + components: { | ||
79 | + wxParseTemplate, | ||
80 | + wxParseImg, | ||
81 | + wxParseVideo, | ||
82 | + wxParseAudio, | ||
83 | + }, | ||
84 | + methods: { | ||
85 | + wxParseATap(e) { | ||
86 | + const { | ||
87 | + href | ||
88 | + } = e.currentTarget.dataset; | ||
89 | + if (!href) return; | ||
90 | + let parent = this.$parent; | ||
91 | + while(!parent.preview || typeof parent.preview !== 'function') { | ||
92 | + parent = parent.$parent; | ||
93 | + } | ||
94 | + parent.navigate(href, e); | ||
95 | + }, | ||
96 | + }, | ||
97 | + }; | ||
98 | +</script> |
1 | +<template> | ||
2 | + <view> | ||
3 | + <!--判断是否是标签节点--> | ||
4 | + <block v-if="node.node == 'element'"> | ||
5 | + <block v-if="node.tag == 'button'"> | ||
6 | + <button type="default" size="mini"> | ||
7 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
8 | + <wx-parse-template :node="node" /> | ||
9 | + </block> | ||
10 | + </button> | ||
11 | + </block> | ||
12 | + | ||
13 | + <!--li类型--> | ||
14 | + <block v-else-if="node.tag == 'li'"> | ||
15 | + <view :class="node.classStr" :style="node.styleStr"> | ||
16 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
17 | + <wx-parse-template :node="node" /> | ||
18 | + </block> | ||
19 | + </view> | ||
20 | + </block> | ||
21 | + | ||
22 | + <!--video类型--> | ||
23 | + <block v-else-if="node.tag == 'video'"> | ||
24 | + <wx-parse-video :node="node" /> | ||
25 | + </block> | ||
26 | + | ||
27 | + <!--audio类型--> | ||
28 | + <block v-else-if="node.tag == 'audio'"> | ||
29 | + <wx-parse-audio :node="node" /> | ||
30 | + </block> | ||
31 | + | ||
32 | + <!--img类型--> | ||
33 | + <block v-else-if="node.tag == 'img'"> | ||
34 | + <wx-parse-img :node="node" /> | ||
35 | + </block> | ||
36 | + | ||
37 | + <!--a类型--> | ||
38 | + <block v-else-if="node.tag == 'a'"> | ||
39 | + <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | ||
40 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
41 | + <wx-parse-template :node="node" /> | ||
42 | + </block> | ||
43 | + </view> | ||
44 | + </block> | ||
45 | + | ||
46 | + <!--br类型--> | ||
47 | + <block v-else-if="node.tag == 'br'"> | ||
48 | + <text>\n</text> | ||
49 | + </block> | ||
50 | + | ||
51 | + <!--其他标签--> | ||
52 | + <block v-else> | ||
53 | + <view :class="node.classStr" :style="node.styleStr"> | ||
54 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
55 | + <wx-parse-template :node="node" /> | ||
56 | + </block> | ||
57 | + </view> | ||
58 | + </block> | ||
59 | + | ||
60 | + </block> | ||
61 | + | ||
62 | + <!--判断是否是文本节点--> | ||
63 | + <block v-else-if="node.node == 'text'">{{node.text}}</block> | ||
64 | + </view> | ||
65 | +</template> | ||
66 | + | ||
67 | +<script> | ||
68 | + import wxParseTemplate from './wxParseTemplate6'; | ||
69 | + import wxParseImg from './wxParseImg'; | ||
70 | + import wxParseVideo from './wxParseVideo'; | ||
71 | + import wxParseAudio from './wxParseAudio'; | ||
72 | + | ||
73 | + export default { | ||
74 | + name: 'wxParseTemplate5', | ||
75 | + props: { | ||
76 | + node: {}, | ||
77 | + }, | ||
78 | + components: { | ||
79 | + wxParseTemplate, | ||
80 | + wxParseImg, | ||
81 | + wxParseVideo, | ||
82 | + wxParseAudio, | ||
83 | + }, | ||
84 | + methods: { | ||
85 | + wxParseATap(e) { | ||
86 | + const { | ||
87 | + href | ||
88 | + } = e.currentTarget.dataset; | ||
89 | + if (!href) return; | ||
90 | + let parent = this.$parent; | ||
91 | + while(!parent.preview || typeof parent.preview !== 'function') { | ||
92 | + parent = parent.$parent; | ||
93 | + } | ||
94 | + parent.navigate(href, e); | ||
95 | + }, | ||
96 | + }, | ||
97 | + }; | ||
98 | +</script> |
1 | +<template> | ||
2 | + <view> | ||
3 | + <!--判断是否是标签节点--> | ||
4 | + <block v-if="node.node == 'element'"> | ||
5 | + <block v-if="node.tag == 'button'"> | ||
6 | + <button type="default" size="mini"> | ||
7 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
8 | + <wx-parse-template :node="node" /> | ||
9 | + </block> | ||
10 | + </button> | ||
11 | + </block> | ||
12 | + | ||
13 | + <!--li类型--> | ||
14 | + <block v-else-if="node.tag == 'li'"> | ||
15 | + <view :class="node.classStr" :style="node.styleStr"> | ||
16 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
17 | + <wx-parse-template :node="node" /> | ||
18 | + </block> | ||
19 | + </view> | ||
20 | + </block> | ||
21 | + | ||
22 | + <!--video类型--> | ||
23 | + <block v-else-if="node.tag == 'video'"> | ||
24 | + <wx-parse-video :node="node" /> | ||
25 | + </block> | ||
26 | + | ||
27 | + <!--audio类型--> | ||
28 | + <block v-else-if="node.tag == 'audio'"> | ||
29 | + <wx-parse-audio :node="node" /> | ||
30 | + </block> | ||
31 | + | ||
32 | + <!--img类型--> | ||
33 | + <block v-else-if="node.tag == 'img'"> | ||
34 | + <wx-parse-img :node="node" /> | ||
35 | + </block> | ||
36 | + | ||
37 | + <!--a类型--> | ||
38 | + <block v-else-if="node.tag == 'a'"> | ||
39 | + <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | ||
40 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
41 | + <wx-parse-template :node="node" /> | ||
42 | + </block> | ||
43 | + </view> | ||
44 | + </block> | ||
45 | + | ||
46 | + <!--br类型--> | ||
47 | + <block v-else-if="node.tag == 'br'"> | ||
48 | + <text>\n</text> | ||
49 | + </block> | ||
50 | + | ||
51 | + <!--其他标签--> | ||
52 | + <block v-else> | ||
53 | + <view :class="node.classStr" :style="node.styleStr"> | ||
54 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
55 | + <wx-parse-template :node="node" /> | ||
56 | + </block> | ||
57 | + </view> | ||
58 | + </block> | ||
59 | + | ||
60 | + </block> | ||
61 | + | ||
62 | + <!--判断是否是文本节点--> | ||
63 | + <block v-else-if="node.node == 'text'">{{node.text}}</block> | ||
64 | + </view> | ||
65 | +</template> | ||
66 | + | ||
67 | +<script> | ||
68 | + import wxParseTemplate from './wxParseTemplate7'; | ||
69 | + import wxParseImg from './wxParseImg'; | ||
70 | + import wxParseVideo from './wxParseVideo'; | ||
71 | + import wxParseAudio from './wxParseAudio'; | ||
72 | + | ||
73 | + export default { | ||
74 | + name: 'wxParseTemplate6', | ||
75 | + props: { | ||
76 | + node: {}, | ||
77 | + }, | ||
78 | + components: { | ||
79 | + wxParseTemplate, | ||
80 | + wxParseImg, | ||
81 | + wxParseVideo, | ||
82 | + wxParseAudio, | ||
83 | + }, | ||
84 | + methods: { | ||
85 | + wxParseATap(e) { | ||
86 | + const { | ||
87 | + href | ||
88 | + } = e.currentTarget.dataset; | ||
89 | + if (!href) return; | ||
90 | + let parent = this.$parent; | ||
91 | + while(!parent.preview || typeof parent.preview !== 'function') { | ||
92 | + parent = parent.$parent; | ||
93 | + } | ||
94 | + parent.navigate(href, e); | ||
95 | + }, | ||
96 | + }, | ||
97 | + }; | ||
98 | +</script> |
1 | +<template> | ||
2 | + <view> | ||
3 | + <!--判断是否是标签节点--> | ||
4 | + <block v-if="node.node == 'element'"> | ||
5 | + <block v-if="node.tag == 'button'"> | ||
6 | + <button type="default" size="mini"> | ||
7 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
8 | + <wx-parse-template :node="node" /> | ||
9 | + </block> | ||
10 | + </button> | ||
11 | + </block> | ||
12 | + | ||
13 | + <!--li类型--> | ||
14 | + <block v-else-if="node.tag == 'li'"> | ||
15 | + <view :class="node.classStr" :style="node.styleStr"> | ||
16 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
17 | + <wx-parse-template :node="node" /> | ||
18 | + </block> | ||
19 | + </view> | ||
20 | + </block> | ||
21 | + | ||
22 | + <!--video类型--> | ||
23 | + <block v-else-if="node.tag == 'video'"> | ||
24 | + <wx-parse-video :node="node" /> | ||
25 | + </block> | ||
26 | + | ||
27 | + <!--audio类型--> | ||
28 | + <block v-else-if="node.tag == 'audio'"> | ||
29 | + <wx-parse-audio :node="node" /> | ||
30 | + </block> | ||
31 | + | ||
32 | + <!--img类型--> | ||
33 | + <block v-else-if="node.tag == 'img'"> | ||
34 | + <wx-parse-img :node="node" /> | ||
35 | + </block> | ||
36 | + | ||
37 | + <!--a类型--> | ||
38 | + <block v-else-if="node.tag == 'a'"> | ||
39 | + <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | ||
40 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
41 | + <wx-parse-template :node="node" /> | ||
42 | + </block> | ||
43 | + </view> | ||
44 | + </block> | ||
45 | + | ||
46 | + <!--br类型--> | ||
47 | + <block v-else-if="node.tag == 'br'"> | ||
48 | + <text>\n</text> | ||
49 | + </block> | ||
50 | + | ||
51 | + <!--其他标签--> | ||
52 | + <block v-else> | ||
53 | + <view :class="node.classStr" :style="node.styleStr"> | ||
54 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
55 | + <wx-parse-template :node="node" /> | ||
56 | + </block> | ||
57 | + </view> | ||
58 | + </block> | ||
59 | + | ||
60 | + </block> | ||
61 | + | ||
62 | + <!--判断是否是文本节点--> | ||
63 | + <block v-else-if="node.node == 'text'">{{node.text}}</block> | ||
64 | + </view> | ||
65 | +</template> | ||
66 | + | ||
67 | +<script> | ||
68 | + import wxParseTemplate from './wxParseTemplate8'; | ||
69 | + import wxParseImg from './wxParseImg'; | ||
70 | + import wxParseVideo from './wxParseVideo'; | ||
71 | + import wxParseAudio from './wxParseAudio'; | ||
72 | + | ||
73 | + export default { | ||
74 | + name: 'wxParseTemplate7', | ||
75 | + props: { | ||
76 | + node: {}, | ||
77 | + }, | ||
78 | + components: { | ||
79 | + wxParseTemplate, | ||
80 | + wxParseImg, | ||
81 | + wxParseVideo, | ||
82 | + wxParseAudio, | ||
83 | + }, | ||
84 | + methods: { | ||
85 | + wxParseATap(e) { | ||
86 | + const { | ||
87 | + href | ||
88 | + } = e.currentTarget.dataset; | ||
89 | + if (!href) return; | ||
90 | + let parent = this.$parent; | ||
91 | + while(!parent.preview || typeof parent.preview !== 'function') { | ||
92 | + parent = parent.$parent; | ||
93 | + } | ||
94 | + parent.navigate(href, e); | ||
95 | + }, | ||
96 | + }, | ||
97 | + }; | ||
98 | +</script> |
1 | +<template> | ||
2 | + <view> | ||
3 | + <!--判断是否是标签节点--> | ||
4 | + <block v-if="node.node == 'element'"> | ||
5 | + <block v-if="node.tag == 'button'"> | ||
6 | + <button type="default" size="mini"> | ||
7 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
8 | + <wx-parse-template :node="node" /> | ||
9 | + </block> | ||
10 | + </button> | ||
11 | + </block> | ||
12 | + | ||
13 | + <!--li类型--> | ||
14 | + <block v-else-if="node.tag == 'li'"> | ||
15 | + <view :class="node.classStr" :style="node.styleStr"> | ||
16 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
17 | + <wx-parse-template :node="node" /> | ||
18 | + </block> | ||
19 | + </view> | ||
20 | + </block> | ||
21 | + | ||
22 | + <!--video类型--> | ||
23 | + <block v-else-if="node.tag == 'video'"> | ||
24 | + <wx-parse-video :node="node" /> | ||
25 | + </block> | ||
26 | + | ||
27 | + <!--audio类型--> | ||
28 | + <block v-else-if="node.tag == 'audio'"> | ||
29 | + <wx-parse-audio :node="node" /> | ||
30 | + </block> | ||
31 | + | ||
32 | + <!--img类型--> | ||
33 | + <block v-else-if="node.tag == 'img'"> | ||
34 | + <wx-parse-img :node="node" /> | ||
35 | + </block> | ||
36 | + | ||
37 | + <!--a类型--> | ||
38 | + <block v-else-if="node.tag == 'a'"> | ||
39 | + <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | ||
40 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
41 | + <wx-parse-template :node="node" /> | ||
42 | + </block> | ||
43 | + </view> | ||
44 | + </block> | ||
45 | + | ||
46 | + <!--br类型--> | ||
47 | + <block v-else-if="node.tag == 'br'"> | ||
48 | + <text>\n</text> | ||
49 | + </block> | ||
50 | + | ||
51 | + <!--其他标签--> | ||
52 | + <block v-else> | ||
53 | + <view :class="node.classStr" :style="node.styleStr"> | ||
54 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
55 | + <wx-parse-template :node="node" /> | ||
56 | + </block> | ||
57 | + </view> | ||
58 | + </block> | ||
59 | + | ||
60 | + </block> | ||
61 | + | ||
62 | + <!--判断是否是文本节点--> | ||
63 | + <block v-else-if="node.node == 'text'">{{node.text}}</block> | ||
64 | + </view> | ||
65 | +</template> | ||
66 | + | ||
67 | +<script> | ||
68 | + import wxParseTemplate from './wxParseTemplate9'; | ||
69 | + import wxParseImg from './wxParseImg'; | ||
70 | + import wxParseVideo from './wxParseVideo'; | ||
71 | + import wxParseAudio from './wxParseAudio'; | ||
72 | + | ||
73 | + export default { | ||
74 | + name: 'wxParseTemplate8', | ||
75 | + props: { | ||
76 | + node: {}, | ||
77 | + }, | ||
78 | + components: { | ||
79 | + wxParseTemplate, | ||
80 | + wxParseImg, | ||
81 | + wxParseVideo, | ||
82 | + wxParseAudio, | ||
83 | + }, | ||
84 | + methods: { | ||
85 | + wxParseATap(e) { | ||
86 | + const { | ||
87 | + href | ||
88 | + } = e.currentTarget.dataset; | ||
89 | + if (!href) return; | ||
90 | + let parent = this.$parent; | ||
91 | + while(!parent.preview || typeof parent.preview !== 'function') { | ||
92 | + parent = parent.$parent; | ||
93 | + } | ||
94 | + parent.navigate(href, e); | ||
95 | + }, | ||
96 | + }, | ||
97 | + }; | ||
98 | +</script> |
1 | +<template> | ||
2 | + <view> | ||
3 | + <!--判断是否是标签节点--> | ||
4 | + <block v-if="node.node == 'element'"> | ||
5 | + <block v-if="node.tag == 'button'"> | ||
6 | + <button type="default" size="mini"> | ||
7 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
8 | + <wx-parse-template :node="node" /> | ||
9 | + </block> | ||
10 | + </button> | ||
11 | + </block> | ||
12 | + | ||
13 | + <!--li类型--> | ||
14 | + <block v-else-if="node.tag == 'li'"> | ||
15 | + <view :class="node.classStr" :style="node.styleStr"> | ||
16 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
17 | + <wx-parse-template :node="node" /> | ||
18 | + </block> | ||
19 | + </view> | ||
20 | + </block> | ||
21 | + | ||
22 | + <!--video类型--> | ||
23 | + <block v-else-if="node.tag == 'video'"> | ||
24 | + <wx-parse-video :node="node" /> | ||
25 | + </block> | ||
26 | + | ||
27 | + <!--audio类型--> | ||
28 | + <block v-else-if="node.tag == 'audio'"> | ||
29 | + <wx-parse-audio :node="node" /> | ||
30 | + </block> | ||
31 | + | ||
32 | + <!--img类型--> | ||
33 | + <block v-else-if="node.tag == 'img'"> | ||
34 | + <wx-parse-img :node="node" /> | ||
35 | + </block> | ||
36 | + | ||
37 | + <!--a类型--> | ||
38 | + <block v-else-if="node.tag == 'a'"> | ||
39 | + <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr"> | ||
40 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
41 | + <wx-parse-template :node="node" /> | ||
42 | + </block> | ||
43 | + </view> | ||
44 | + </block> | ||
45 | + | ||
46 | + <!--br类型--> | ||
47 | + <block v-else-if="node.tag == 'br'"> | ||
48 | + <text>\n</text> | ||
49 | + </block> | ||
50 | + | ||
51 | + <!--其他标签--> | ||
52 | + <block v-else> | ||
53 | + <view :class="node.classStr" :style="node.styleStr"> | ||
54 | + <block v-for="(node, index) of node.nodes" :key="index"> | ||
55 | + <wx-parse-template :node="node" /> | ||
56 | + </block> | ||
57 | + </view> | ||
58 | + </block> | ||
59 | + | ||
60 | + </block> | ||
61 | + | ||
62 | + <!--判断是否是文本节点--> | ||
63 | + <block v-else-if="node.node == 'text'">{{node.text}}</block> | ||
64 | + </view> | ||
65 | +</template> | ||
66 | + | ||
67 | +<script> | ||
68 | + import wxParseTemplate from './wxParseTemplate10'; | ||
69 | + import wxParseImg from './wxParseImg'; | ||
70 | + import wxParseVideo from './wxParseVideo'; | ||
71 | + import wxParseAudio from './wxParseAudio'; | ||
72 | + | ||
73 | + export default { | ||
74 | + name: 'wxParseTemplate9', | ||
75 | + props: { | ||
76 | + node: {}, | ||
77 | + }, | ||
78 | + components: { | ||
79 | + wxParseTemplate, | ||
80 | + wxParseImg, | ||
81 | + wxParseVideo, | ||
82 | + wxParseAudio, | ||
83 | + }, | ||
84 | + methods: { | ||
85 | + wxParseATap(e) { | ||
86 | + const { | ||
87 | + href | ||
88 | + } = e.currentTarget.dataset; | ||
89 | + if (!href) return; | ||
90 | + let parent = this.$parent; | ||
91 | + while(!parent.preview || typeof parent.preview !== 'function') { | ||
92 | + parent = parent.$parent; | ||
93 | + } | ||
94 | + parent.navigate(href, e); | ||
95 | + }, | ||
96 | + }, | ||
97 | + }; | ||
98 | +</script> |
1 | +<template> | ||
2 | + <!--增加video标签支持,并循环添加--> | ||
3 | + <view :class="node.classStr" :style="node.styleStr"> | ||
4 | + <video :class="node.classStr" class="video-video" :src="node.attr.src"></video> | ||
5 | + </view> | ||
6 | +</template> | ||
7 | + | ||
8 | +<script> | ||
9 | +export default { | ||
10 | + name: 'wxParseVideo', | ||
11 | + props: { | ||
12 | + node: {}, | ||
13 | + }, | ||
14 | +}; | ||
15 | +</script> |
components/u-parse/libs/html2json.js
0 → 100644
1 | +/** | ||
2 | + * html2Json 改造来自: https://github.com/Jxck/html2json | ||
3 | + * | ||
4 | + * | ||
5 | + * author: Di (微信小程序开发工程师) | ||
6 | + * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | ||
7 | + * 垂直微信小程序开发交流社区 | ||
8 | + * | ||
9 | + * github地址: https://github.com/icindy/wxParse | ||
10 | + * | ||
11 | + * for: 微信小程序富文本解析 | ||
12 | + * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | ||
13 | + */ | ||
14 | + | ||
15 | +import wxDiscode from './wxDiscode'; | ||
16 | +import HTMLParser from './htmlparser'; | ||
17 | + | ||
18 | +function makeMap(str) { | ||
19 | + const obj = {}; | ||
20 | + const items = str.split(','); | ||
21 | + for (let i = 0; i < items.length; i += 1) obj[items[i]] = true; | ||
22 | + return obj; | ||
23 | +} | ||
24 | + | ||
25 | +// Block Elements - HTML 5 | ||
26 | +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'); | ||
27 | + | ||
28 | +// Inline Elements - HTML 5 | ||
29 | +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'); | ||
30 | + | ||
31 | +// Elements that you can, intentionally, leave open | ||
32 | +// (and which close themselves) | ||
33 | +const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); | ||
34 | + | ||
35 | +function removeDOCTYPE(html) { | ||
36 | + const isDocument = /<body.*>([^]*)<\/body>/.test(html); | ||
37 | + return isDocument ? RegExp.$1 : html; | ||
38 | +} | ||
39 | + | ||
40 | +function trimHtml(html) { | ||
41 | + return html | ||
42 | + .replace(/<!--.*?-->/gi, '') | ||
43 | + .replace(/\/\*.*?\*\//gi, '') | ||
44 | + .replace(/[ ]+</gi, '<') | ||
45 | + .replace(/<script[^]*<\/script>/gi, '') | ||
46 | + .replace(/<style[^]*<\/style>/gi, ''); | ||
47 | +} | ||
48 | + | ||
49 | +function getScreenInfo() { | ||
50 | + const screen = {}; | ||
51 | + wx.getSystemInfo({ | ||
52 | + success: (res) => { | ||
53 | + screen.width = res.windowWidth; | ||
54 | + screen.height = res.windowHeight; | ||
55 | + }, | ||
56 | + }); | ||
57 | + return screen; | ||
58 | +} | ||
59 | + | ||
60 | +function html2json(html, customHandler, imageProp, host) { | ||
61 | + // 处理字符串 | ||
62 | + html = removeDOCTYPE(html); | ||
63 | + html = trimHtml(html); | ||
64 | + html = wxDiscode.strDiscode(html); | ||
65 | + // 生成node节点 | ||
66 | + const bufArray = []; | ||
67 | + const results = { | ||
68 | + nodes: [], | ||
69 | + imageUrls: [], | ||
70 | + }; | ||
71 | + | ||
72 | + const screen = getScreenInfo(); | ||
73 | + function Node(tag) { | ||
74 | + this.node = 'element'; | ||
75 | + this.tag = tag; | ||
76 | + | ||
77 | + this.$screen = screen; | ||
78 | + } | ||
79 | + | ||
80 | + HTMLParser(html, { | ||
81 | + start(tag, attrs, unary) { | ||
82 | + // node for this element | ||
83 | + const node = new Node(tag); | ||
84 | + | ||
85 | + if (bufArray.length !== 0) { | ||
86 | + const parent = bufArray[0]; | ||
87 | + if (parent.nodes === undefined) { | ||
88 | + parent.nodes = []; | ||
89 | + } | ||
90 | + } | ||
91 | + | ||
92 | + if (block[tag]) { | ||
93 | + node.tagType = 'block'; | ||
94 | + } else if (inline[tag]) { | ||
95 | + node.tagType = 'inline'; | ||
96 | + } else if (closeSelf[tag]) { | ||
97 | + node.tagType = 'closeSelf'; | ||
98 | + } | ||
99 | + | ||
100 | + node.attr = attrs.reduce((pre, attr) => { | ||
101 | + const { name } = attr; | ||
102 | + let { value } = attr; | ||
103 | + if (name === 'class') { | ||
104 | + node.classStr = value; | ||
105 | + } | ||
106 | + // has multi attibutes | ||
107 | + // make it array of attribute | ||
108 | + if (name === 'style') { | ||
109 | + node.styleStr = value; | ||
110 | + } | ||
111 | + if (value.match(/ /)) { | ||
112 | + value = value.split(' '); | ||
113 | + } | ||
114 | + | ||
115 | + // if attr already exists | ||
116 | + // merge it | ||
117 | + if (pre[name]) { | ||
118 | + if (Array.isArray(pre[name])) { | ||
119 | + // already array, push to last | ||
120 | + pre[name].push(value); | ||
121 | + } else { | ||
122 | + // single value, make it array | ||
123 | + pre[name] = [pre[name], value]; | ||
124 | + } | ||
125 | + } else { | ||
126 | + // not exist, put it | ||
127 | + pre[name] = value; | ||
128 | + } | ||
129 | + | ||
130 | + return pre; | ||
131 | + }, {}); | ||
132 | + | ||
133 | + // 优化样式相关属性 | ||
134 | + if (node.classStr) { | ||
135 | + node.classStr += ` ${node.tag}`; | ||
136 | + } else { | ||
137 | + node.classStr = node.tag; | ||
138 | + } | ||
139 | + if (node.tagType === 'inline') { | ||
140 | + node.classStr += ' inline'; | ||
141 | + } | ||
142 | + | ||
143 | + // 对img添加额外数据 | ||
144 | + if (node.tag === 'img') { | ||
145 | + let imgUrl = node.attr.src; | ||
146 | + imgUrl = wxDiscode.urlToHttpUrl(imgUrl, imageProp.domain); | ||
147 | + Object.assign(node.attr, imageProp, { | ||
148 | + src: imgUrl || '', | ||
149 | + }); | ||
150 | + if (imgUrl) { | ||
151 | + results.imageUrls.push(imgUrl); | ||
152 | + } | ||
153 | + } | ||
154 | + | ||
155 | + // 处理a标签属性 | ||
156 | + if (node.tag === 'a') { | ||
157 | + node.attr.href = node.attr.href || ''; | ||
158 | + } | ||
159 | + | ||
160 | + // 处理font标签样式属性 | ||
161 | + if (node.tag === 'font') { | ||
162 | + const fontSize = [ | ||
163 | + 'x-small', | ||
164 | + 'small', | ||
165 | + 'medium', | ||
166 | + 'large', | ||
167 | + 'x-large', | ||
168 | + 'xx-large', | ||
169 | + '-webkit-xxx-large', | ||
170 | + ]; | ||
171 | + const styleAttrs = { | ||
172 | + color: 'color', | ||
173 | + face: 'font-family', | ||
174 | + size: 'font-size', | ||
175 | + }; | ||
176 | + if (!node.styleStr) node.styleStr = ''; | ||
177 | + Object.keys(styleAttrs).forEach((key) => { | ||
178 | + if (node.attr[key]) { | ||
179 | + const value = key === 'size' ? fontSize[node.attr[key] - 1] : node.attr[key]; | ||
180 | + node.styleStr += `${styleAttrs[key]}: ${value};`; | ||
181 | + } | ||
182 | + }); | ||
183 | + } | ||
184 | + | ||
185 | + // 临时记录source资源 | ||
186 | + if (node.tag === 'source') { | ||
187 | + results.source = node.attr.src; | ||
188 | + } | ||
189 | + | ||
190 | + if (customHandler.start) { | ||
191 | + customHandler.start(node, results); | ||
192 | + } | ||
193 | + | ||
194 | + if (unary) { | ||
195 | + // if this tag doesn't have end tag | ||
196 | + // like <img src="hoge.png"/> | ||
197 | + // add to parents | ||
198 | + const parent = bufArray[0] || results; | ||
199 | + if (parent.nodes === undefined) { | ||
200 | + parent.nodes = []; | ||
201 | + } | ||
202 | + parent.nodes.push(node); | ||
203 | + } else { | ||
204 | + bufArray.unshift(node); | ||
205 | + } | ||
206 | + }, | ||
207 | + end(tag) { | ||
208 | + // merge into parent tag | ||
209 | + const node = bufArray.shift(); | ||
210 | + if (node.tag !== tag) { | ||
211 | + console.error('invalid state: mismatch end tag'); | ||
212 | + } | ||
213 | + | ||
214 | + // 当有缓存source资源时于于video补上src资源 | ||
215 | + if (node.tag === 'video' && results.source) { | ||
216 | + node.attr.src = results.source; | ||
217 | + delete results.source; | ||
218 | + } | ||
219 | + | ||
220 | + if (customHandler.end) { | ||
221 | + customHandler.end(node, results); | ||
222 | + } | ||
223 | + | ||
224 | + if (bufArray.length === 0) { | ||
225 | + results.nodes.push(node); | ||
226 | + } else { | ||
227 | + const parent = bufArray[0]; | ||
228 | + if (!parent.nodes) { | ||
229 | + parent.nodes = []; | ||
230 | + } | ||
231 | + parent.nodes.push(node); | ||
232 | + } | ||
233 | + }, | ||
234 | + chars(text) { | ||
235 | + if (!text.trim()) return; | ||
236 | + | ||
237 | + const node = { | ||
238 | + node: 'text', | ||
239 | + text, | ||
240 | + }; | ||
241 | + | ||
242 | + if (customHandler.chars) { | ||
243 | + customHandler.chars(node, results); | ||
244 | + } | ||
245 | + | ||
246 | + if (bufArray.length === 0) { | ||
247 | + results.nodes.push(node); | ||
248 | + } else { | ||
249 | + const parent = bufArray[0]; | ||
250 | + if (parent.nodes === undefined) { | ||
251 | + parent.nodes = []; | ||
252 | + } | ||
253 | + parent.nodes.push(node); | ||
254 | + } | ||
255 | + }, | ||
256 | + }); | ||
257 | + | ||
258 | + return results; | ||
259 | +} | ||
260 | + | ||
261 | +export default html2json; |
components/u-parse/libs/htmlparser.js
0 → 100644
1 | +/** | ||
2 | + * | ||
3 | + * htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser | ||
4 | + * | ||
5 | + * author: Di (微信小程序开发工程师) | ||
6 | + * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | ||
7 | + * 垂直微信小程序开发交流社区 | ||
8 | + * | ||
9 | + * github地址: https://github.com/icindy/wxParse | ||
10 | + * | ||
11 | + * for: 微信小程序富文本解析 | ||
12 | + * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | ||
13 | + */ | ||
14 | +// Regular Expressions for parsing tags and attributes | ||
15 | + | ||
16 | +const startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z0-9_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/; | ||
17 | +const endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/; | ||
18 | +const attr = /([a-zA-Z0-9_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; | ||
19 | + | ||
20 | +function makeMap(str) { | ||
21 | + const obj = {}; | ||
22 | + const items = str.split(','); | ||
23 | + for (let i = 0; i < items.length; i += 1) obj[items[i]] = true; | ||
24 | + return obj; | ||
25 | +} | ||
26 | + | ||
27 | +// Empty Elements - HTML 5 | ||
28 | +const empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); | ||
29 | + | ||
30 | +// Block Elements - HTML 5 | ||
31 | +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'); | ||
32 | + | ||
33 | +// Inline Elements - HTML 5 | ||
34 | +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'); | ||
35 | + | ||
36 | +// Elements that you can, intentionally, leave open | ||
37 | +// (and which close themselves) | ||
38 | +const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); | ||
39 | + | ||
40 | +// Attributes that have their values filled in disabled="disabled" | ||
41 | +const fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); | ||
42 | + | ||
43 | +function HTMLParser(html, handler) { | ||
44 | + let index; | ||
45 | + let chars; | ||
46 | + let match; | ||
47 | + let last = html; | ||
48 | + const stack = []; | ||
49 | + | ||
50 | + stack.last = () => stack[stack.length - 1]; | ||
51 | + | ||
52 | + function parseEndTag(tag, tagName) { | ||
53 | + // If no tag name is provided, clean shop | ||
54 | + let pos; | ||
55 | + if (!tagName) { | ||
56 | + pos = 0; | ||
57 | + } else { | ||
58 | + // Find the closest opened tag of the same type | ||
59 | + tagName = tagName.toLowerCase(); | ||
60 | + for (pos = stack.length - 1; pos >= 0; pos -= 1) { | ||
61 | + if (stack[pos] === tagName) break; | ||
62 | + } | ||
63 | + } | ||
64 | + if (pos >= 0) { | ||
65 | + // Close all the open elements, up the stack | ||
66 | + for (let i = stack.length - 1; i >= pos; i -= 1) { | ||
67 | + if (handler.end) handler.end(stack[i]); | ||
68 | + } | ||
69 | + | ||
70 | + // Remove the open elements from the stack | ||
71 | + stack.length = pos; | ||
72 | + } | ||
73 | + } | ||
74 | + | ||
75 | + function parseStartTag(tag, tagName, rest, unary) { | ||
76 | + tagName = tagName.toLowerCase(); | ||
77 | + | ||
78 | + if (block[tagName]) { | ||
79 | + while (stack.last() && inline[stack.last()]) { | ||
80 | + parseEndTag('', stack.last()); | ||
81 | + } | ||
82 | + } | ||
83 | + | ||
84 | + if (closeSelf[tagName] && stack.last() === tagName) { | ||
85 | + parseEndTag('', tagName); | ||
86 | + } | ||
87 | + | ||
88 | + unary = empty[tagName] || !!unary; | ||
89 | + | ||
90 | + if (!unary) stack.push(tagName); | ||
91 | + | ||
92 | + if (handler.start) { | ||
93 | + const attrs = []; | ||
94 | + | ||
95 | + rest.replace(attr, function genAttr(matches, name) { | ||
96 | + const value = arguments[2] || arguments[3] || arguments[4] || (fillAttrs[name] ? name : ''); | ||
97 | + | ||
98 | + attrs.push({ | ||
99 | + name, | ||
100 | + value, | ||
101 | + escaped: value.replace(/(^|[^\\])"/g, '$1\\"'), // " | ||
102 | + }); | ||
103 | + }); | ||
104 | + | ||
105 | + if (handler.start) { | ||
106 | + handler.start(tagName, attrs, unary); | ||
107 | + } | ||
108 | + } | ||
109 | + } | ||
110 | + | ||
111 | + while (html) { | ||
112 | + chars = true; | ||
113 | + | ||
114 | + if (html.indexOf('</') === 0) { | ||
115 | + match = html.match(endTag); | ||
116 | + | ||
117 | + if (match) { | ||
118 | + html = html.substring(match[0].length); | ||
119 | + match[0].replace(endTag, parseEndTag); | ||
120 | + chars = false; | ||
121 | + } | ||
122 | + | ||
123 | + // start tag | ||
124 | + } else if (html.indexOf('<') === 0) { | ||
125 | + match = html.match(startTag); | ||
126 | + | ||
127 | + if (match) { | ||
128 | + html = html.substring(match[0].length); | ||
129 | + match[0].replace(startTag, parseStartTag); | ||
130 | + chars = false; | ||
131 | + } | ||
132 | + } | ||
133 | + | ||
134 | + if (chars) { | ||
135 | + index = html.indexOf('<'); | ||
136 | + let text = ''; | ||
137 | + while (index === 0) { | ||
138 | + text += '<'; | ||
139 | + html = html.substring(1); | ||
140 | + index = html.indexOf('<'); | ||
141 | + } | ||
142 | + text += index < 0 ? html : html.substring(0, index); | ||
143 | + html = index < 0 ? '' : html.substring(index); | ||
144 | + | ||
145 | + if (handler.chars) handler.chars(text); | ||
146 | + } | ||
147 | + | ||
148 | + if (html === last) throw new Error(`Parse Error: ${html}`); | ||
149 | + last = html; | ||
150 | + } | ||
151 | + | ||
152 | + // Clean up any remaining tags | ||
153 | + parseEndTag(); | ||
154 | +} | ||
155 | + | ||
156 | +export default HTMLParser; |
components/u-parse/libs/wxDiscode.js
0 → 100644
1 | +// HTML 支持的数学符号 | ||
2 | +function strNumDiscode(str) { | ||
3 | + str = str.replace(/∀/g, '∀'); | ||
4 | + str = str.replace(/∂/g, '∂'); | ||
5 | + str = str.replace(/∃/g, '∃'); | ||
6 | + str = str.replace(/∅/g, '∅'); | ||
7 | + str = str.replace(/∇/g, '∇'); | ||
8 | + str = str.replace(/∈/g, '∈'); | ||
9 | + str = str.replace(/∉/g, '∉'); | ||
10 | + str = str.replace(/∋/g, '∋'); | ||
11 | + str = str.replace(/∏/g, '∏'); | ||
12 | + str = str.replace(/∑/g, '∑'); | ||
13 | + str = str.replace(/−/g, '−'); | ||
14 | + str = str.replace(/∗/g, '∗'); | ||
15 | + str = str.replace(/√/g, '√'); | ||
16 | + str = str.replace(/∝/g, '∝'); | ||
17 | + str = str.replace(/∞/g, '∞'); | ||
18 | + str = str.replace(/∠/g, '∠'); | ||
19 | + str = str.replace(/∧/g, '∧'); | ||
20 | + str = str.replace(/∨/g, '∨'); | ||
21 | + str = str.replace(/∩/g, '∩'); | ||
22 | + str = str.replace(/∪/g, '∪'); | ||
23 | + str = str.replace(/∫/g, '∫'); | ||
24 | + str = str.replace(/∴/g, '∴'); | ||
25 | + str = str.replace(/∼/g, '∼'); | ||
26 | + str = str.replace(/≅/g, '≅'); | ||
27 | + str = str.replace(/≈/g, '≈'); | ||
28 | + str = str.replace(/≠/g, '≠'); | ||
29 | + str = str.replace(/≤/g, '≤'); | ||
30 | + str = str.replace(/≥/g, '≥'); | ||
31 | + str = str.replace(/⊂/g, '⊂'); | ||
32 | + str = str.replace(/⊃/g, '⊃'); | ||
33 | + str = str.replace(/⊄/g, '⊄'); | ||
34 | + str = str.replace(/⊆/g, '⊆'); | ||
35 | + str = str.replace(/⊇/g, '⊇'); | ||
36 | + str = str.replace(/⊕/g, '⊕'); | ||
37 | + str = str.replace(/⊗/g, '⊗'); | ||
38 | + str = str.replace(/⊥/g, '⊥'); | ||
39 | + str = str.replace(/⋅/g, '⋅'); | ||
40 | + return str; | ||
41 | +} | ||
42 | + | ||
43 | +// HTML 支持的希腊字母 | ||
44 | +function strGreeceDiscode(str) { | ||
45 | + str = str.replace(/Α/g, 'Α'); | ||
46 | + str = str.replace(/Β/g, 'Β'); | ||
47 | + str = str.replace(/Γ/g, 'Γ'); | ||
48 | + str = str.replace(/Δ/g, 'Δ'); | ||
49 | + str = str.replace(/Ε/g, 'Ε'); | ||
50 | + str = str.replace(/Ζ/g, 'Ζ'); | ||
51 | + str = str.replace(/Η/g, 'Η'); | ||
52 | + str = str.replace(/Θ/g, 'Θ'); | ||
53 | + str = str.replace(/Ι/g, 'Ι'); | ||
54 | + str = str.replace(/Κ/g, 'Κ'); | ||
55 | + str = str.replace(/Λ/g, 'Λ'); | ||
56 | + str = str.replace(/Μ/g, 'Μ'); | ||
57 | + str = str.replace(/Ν/g, 'Ν'); | ||
58 | + str = str.replace(/Ξ/g, 'Ν'); | ||
59 | + str = str.replace(/Ο/g, 'Ο'); | ||
60 | + str = str.replace(/Π/g, 'Π'); | ||
61 | + str = str.replace(/Ρ/g, 'Ρ'); | ||
62 | + str = str.replace(/Σ/g, 'Σ'); | ||
63 | + str = str.replace(/Τ/g, 'Τ'); | ||
64 | + str = str.replace(/Υ/g, 'Υ'); | ||
65 | + str = str.replace(/Φ/g, 'Φ'); | ||
66 | + str = str.replace(/Χ/g, 'Χ'); | ||
67 | + str = str.replace(/Ψ/g, 'Ψ'); | ||
68 | + str = str.replace(/Ω/g, 'Ω'); | ||
69 | + | ||
70 | + str = str.replace(/α/g, 'α'); | ||
71 | + str = str.replace(/β/g, 'β'); | ||
72 | + str = str.replace(/γ/g, 'γ'); | ||
73 | + str = str.replace(/δ/g, 'δ'); | ||
74 | + str = str.replace(/ε/g, 'ε'); | ||
75 | + str = str.replace(/ζ/g, 'ζ'); | ||
76 | + str = str.replace(/η/g, 'η'); | ||
77 | + str = str.replace(/θ/g, 'θ'); | ||
78 | + str = str.replace(/ι/g, 'ι'); | ||
79 | + str = str.replace(/κ/g, 'κ'); | ||
80 | + str = str.replace(/λ/g, 'λ'); | ||
81 | + str = str.replace(/μ/g, 'μ'); | ||
82 | + str = str.replace(/ν/g, 'ν'); | ||
83 | + str = str.replace(/ξ/g, 'ξ'); | ||
84 | + str = str.replace(/ο/g, 'ο'); | ||
85 | + str = str.replace(/π/g, 'π'); | ||
86 | + str = str.replace(/ρ/g, 'ρ'); | ||
87 | + str = str.replace(/ς/g, 'ς'); | ||
88 | + str = str.replace(/σ/g, 'σ'); | ||
89 | + str = str.replace(/τ/g, 'τ'); | ||
90 | + str = str.replace(/υ/g, 'υ'); | ||
91 | + str = str.replace(/φ/g, 'φ'); | ||
92 | + str = str.replace(/χ/g, 'χ'); | ||
93 | + str = str.replace(/ψ/g, 'ψ'); | ||
94 | + str = str.replace(/ω/g, 'ω'); | ||
95 | + str = str.replace(/ϑ/g, 'ϑ'); | ||
96 | + str = str.replace(/ϒ/g, 'ϒ'); | ||
97 | + str = str.replace(/ϖ/g, 'ϖ'); | ||
98 | + str = str.replace(/·/g, '·'); | ||
99 | + return str; | ||
100 | +} | ||
101 | + | ||
102 | +function strcharacterDiscode(str) { | ||
103 | + // 加入常用解析 | ||
104 | + str = str.replace(/ /g, ' '); | ||
105 | + str = str.replace(/ /g, ' '); | ||
106 | + str = str.replace(/ /g, ' '); | ||
107 | + str = str.replace(/"/g, "'"); | ||
108 | + str = str.replace(/&/g, '&'); | ||
109 | + str = str.replace(/</g, '<'); | ||
110 | + str = str.replace(/>/g, '>'); | ||
111 | + str = str.replace(/•/g, '•'); | ||
112 | + | ||
113 | + return str; | ||
114 | +} | ||
115 | + | ||
116 | +// HTML 支持的其他实体 | ||
117 | +function strOtherDiscode(str) { | ||
118 | + str = str.replace(/Œ/g, 'Œ'); | ||
119 | + str = str.replace(/œ/g, 'œ'); | ||
120 | + str = str.replace(/Š/g, 'Š'); | ||
121 | + str = str.replace(/š/g, 'š'); | ||
122 | + str = str.replace(/Ÿ/g, 'Ÿ'); | ||
123 | + str = str.replace(/ƒ/g, 'ƒ'); | ||
124 | + str = str.replace(/ˆ/g, 'ˆ'); | ||
125 | + str = str.replace(/˜/g, '˜'); | ||
126 | + str = str.replace(/ /g, ''); | ||
127 | + str = str.replace(/ /g, ''); | ||
128 | + str = str.replace(/ /g, ''); | ||
129 | + str = str.replace(/‌/g, ''); | ||
130 | + str = str.replace(/‍/g, ''); | ||
131 | + str = str.replace(/‎/g, ''); | ||
132 | + str = str.replace(/‏/g, ''); | ||
133 | + str = str.replace(/–/g, '–'); | ||
134 | + str = str.replace(/—/g, '—'); | ||
135 | + str = str.replace(/‘/g, '‘'); | ||
136 | + str = str.replace(/’/g, '’'); | ||
137 | + str = str.replace(/‚/g, '‚'); | ||
138 | + str = str.replace(/“/g, '“'); | ||
139 | + str = str.replace(/”/g, '”'); | ||
140 | + str = str.replace(/„/g, '„'); | ||
141 | + str = str.replace(/†/g, '†'); | ||
142 | + str = str.replace(/‡/g, '‡'); | ||
143 | + str = str.replace(/•/g, '•'); | ||
144 | + str = str.replace(/…/g, '…'); | ||
145 | + str = str.replace(/‰/g, '‰'); | ||
146 | + str = str.replace(/′/g, '′'); | ||
147 | + str = str.replace(/″/g, '″'); | ||
148 | + str = str.replace(/‹/g, '‹'); | ||
149 | + str = str.replace(/›/g, '›'); | ||
150 | + str = str.replace(/‾/g, '‾'); | ||
151 | + str = str.replace(/€/g, '€'); | ||
152 | + str = str.replace(/™/g, '™'); | ||
153 | + | ||
154 | + str = str.replace(/←/g, '←'); | ||
155 | + str = str.replace(/↑/g, '↑'); | ||
156 | + str = str.replace(/→/g, '→'); | ||
157 | + str = str.replace(/↓/g, '↓'); | ||
158 | + str = str.replace(/↔/g, '↔'); | ||
159 | + str = str.replace(/↵/g, '↵'); | ||
160 | + str = str.replace(/⌈/g, '⌈'); | ||
161 | + str = str.replace(/⌉/g, '⌉'); | ||
162 | + | ||
163 | + str = str.replace(/⌊/g, '⌊'); | ||
164 | + str = str.replace(/⌋/g, '⌋'); | ||
165 | + str = str.replace(/◊/g, '◊'); | ||
166 | + str = str.replace(/♠/g, '♠'); | ||
167 | + str = str.replace(/♣/g, '♣'); | ||
168 | + str = str.replace(/♥/g, '♥'); | ||
169 | + | ||
170 | + str = str.replace(/♦/g, '♦'); | ||
171 | + str = str.replace(/'/g, "'"); | ||
172 | + return str; | ||
173 | +} | ||
174 | + | ||
175 | +function strDiscode(str) { | ||
176 | + str = strNumDiscode(str); | ||
177 | + str = strGreeceDiscode(str); | ||
178 | + str = strcharacterDiscode(str); | ||
179 | + str = strOtherDiscode(str); | ||
180 | + return str; | ||
181 | +} | ||
182 | + | ||
183 | +function urlToHttpUrl(url, domain) { | ||
184 | + if (/^\/\//.test(url)) { | ||
185 | + return `https:${url}`; | ||
186 | + } else if (/^\//.test(url)) { | ||
187 | + return `https://${domain}${url}`; | ||
188 | + } | ||
189 | + return url; | ||
190 | +} | ||
191 | + | ||
192 | +export default { | ||
193 | + strDiscode, | ||
194 | + urlToHttpUrl, | ||
195 | +}; |
components/u-parse/readme.md
0 → 100644
1 | +## uParse 适用于 uni-app/mpvue 的富文本解析组件 | ||
2 | + | ||
3 | +> 支持 Html、Markdown 解析,Fork自: [mpvue-wxParse](https://github.com/F-loat/mpvue-wxParse) | ||
4 | + | ||
5 | + | ||
6 | +## 属性 | ||
7 | + | ||
8 | +| 名称 | 类型 | 默认值 | 描述 | | ||
9 | +| -----------------|--------------- | ------------- | ---------------- | | ||
10 | +| loading | Boolean | false | 数据加载状态 | | ||
11 | +| className | String | — | 自定义 class 名称 | | ||
12 | +| content | String | — | 渲染内容 | | ||
13 | +| noData | String | 数据不能为空 | 空数据时的渲染展示 | | ||
14 | +| startHandler | Function | 见源码 | 自定义 parser 函数 | | ||
15 | +| endHandler | Function | null | 自定义 parser 函数 | | ||
16 | +| charsHandler | Function | null | 自定义 parser 函数 | | ||
17 | +| imageProp | Object | 见下文 | 图片相关参数 | | ||
18 | + | ||
19 | +### 自定义 parser 函数具体介绍 | ||
20 | + | ||
21 | +* 传入的参数为当前节点 `node` 对象及解析结果 `results` 对象,例如 `startHandler(node, results)` | ||
22 | +* 无需返回值,通过对传入的参数直接操作来完成需要的改动 | ||
23 | +* 自定义函数会在原解析函数处理之后执行 | ||
24 | + | ||
25 | +### imageProp 对象具体属性 | ||
26 | + | ||
27 | +| 名称 | 类型 | 默认值 | 描述 | | ||
28 | +| -----------------|--------------- | ------------- | ------------------ | | ||
29 | +| mode | String | 'aspectFit' | 图片裁剪、缩放的模式 | | ||
30 | +| padding | Number | 0 | 图片内边距 | | ||
31 | +| lazyLoad | Boolean | false | 图片懒加载 | | ||
32 | +| domain | String | '' | 图片服务域名 | | ||
33 | + | ||
34 | +## 事件 | ||
35 | + | ||
36 | +| 名称 | 参数 | 描述 | | ||
37 | +| -----------------|----------------- | ---------------- | | ||
38 | +| preview | 图片地址,原始事件 | 预览图片时触发 | | ||
39 | +| navigate | 链接地址,原始事件 | 点击链接时触发 | | ||
40 | + | ||
41 | +## 基本使用方法 | ||
42 | + | ||
43 | + | ||
44 | +``` vue | ||
45 | +<template> | ||
46 | + <div> | ||
47 | + <u-parse :content="article" @preview="preview" @navigate="navigate" /> | ||
48 | + </div> | ||
49 | +</template> | ||
50 | + | ||
51 | +<script> | ||
52 | +import uParse from '@/components/u-parse/u-parse.vue' | ||
53 | + | ||
54 | +export default { | ||
55 | + components: { | ||
56 | + uParse | ||
57 | + }, | ||
58 | + data () { | ||
59 | + return { | ||
60 | + article: '<div>我是HTML代码</div>' | ||
61 | + } | ||
62 | + }, | ||
63 | + methods: { | ||
64 | + preview(src, e) { | ||
65 | + // do something | ||
66 | + }, | ||
67 | + navigate(href, e) { | ||
68 | + // do something | ||
69 | + } | ||
70 | + } | ||
71 | +} | ||
72 | +</script> | ||
73 | + | ||
74 | +<style> | ||
75 | +@import url("@/components/u-parse/u-parse.css"); | ||
76 | +</style> | ||
77 | +``` | ||
78 | + | ||
79 | + | ||
80 | +## 渲染 Markdown | ||
81 | + | ||
82 | +> 先将 markdown 转换为 html 即可 | ||
83 | + | ||
84 | +``` | ||
85 | +npm install marked | ||
86 | +``` | ||
87 | + | ||
88 | +``` js | ||
89 | +import marked from 'marked' | ||
90 | +import uParse from '@/components/u-parse/u-parse.vue' | ||
91 | + | ||
92 | +export default { | ||
93 | + components: { | ||
94 | + uParse | ||
95 | + }, | ||
96 | + data () { | ||
97 | + return { | ||
98 | + article: marked(`#hello, markdown!`) | ||
99 | + } | ||
100 | + } | ||
101 | +} | ||
102 | +``` |
components/u-parse/u-parse.css
0 → 100644
1 | +/** | ||
2 | + * author: Di (微信小程序开发工程师) | ||
3 | + * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) | ||
4 | + * 垂直微信小程序开发交流社区 | ||
5 | + * | ||
6 | + * github地址: https://github.com/icindy/wxParse | ||
7 | + * | ||
8 | + * for: 微信小程序富文本解析 | ||
9 | + * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 | ||
10 | + */ | ||
11 | + | ||
12 | +.wxParse { | ||
13 | + width: 100%; | ||
14 | + font-family: Helvetica, sans-serif; | ||
15 | + font-size: 30upx; | ||
16 | + color: #666; | ||
17 | + line-height: 1.8; | ||
18 | +} | ||
19 | + | ||
20 | +.wxParse view { | ||
21 | + word-break: hyphenate; | ||
22 | +} | ||
23 | + | ||
24 | +.wxParse .inline { | ||
25 | + display: inline; | ||
26 | + margin: 0; | ||
27 | + padding: 0; | ||
28 | +} | ||
29 | + | ||
30 | +.wxParse .div { | ||
31 | + margin: 0; | ||
32 | + padding: 0; | ||
33 | +} | ||
34 | + | ||
35 | +.wxParse .h1 .text { | ||
36 | + font-size: 2em; | ||
37 | + margin: 0.67em 0; | ||
38 | +} | ||
39 | +.wxParse .h2 .text { | ||
40 | + font-size: 1.5em; | ||
41 | + margin: 0.83em 0; | ||
42 | +} | ||
43 | +.wxParse .h3 .text { | ||
44 | + font-size: 1.17em; | ||
45 | + margin: 1em 0; | ||
46 | +} | ||
47 | +.wxParse .h4 .text { | ||
48 | + margin: 1.33em 0; | ||
49 | +} | ||
50 | +.wxParse .h5 .text { | ||
51 | + font-size: 0.83em; | ||
52 | + margin: 1.67em 0; | ||
53 | +} | ||
54 | +.wxParse .h6 .text { | ||
55 | + font-size: 0.67em; | ||
56 | + margin: 2.33em 0; | ||
57 | +} | ||
58 | + | ||
59 | +.wxParse .h1 .text, | ||
60 | +.wxParse .h2 .text, | ||
61 | +.wxParse .h3 .text, | ||
62 | +.wxParse .h4 .text, | ||
63 | +.wxParse .h5 .text, | ||
64 | +.wxParse .h6 .text, | ||
65 | +.wxParse .b, | ||
66 | +.wxParse .strong { | ||
67 | + font-weight: bolder; | ||
68 | +} | ||
69 | + | ||
70 | + | ||
71 | +.wxParse .p { | ||
72 | + margin: 1em 0; | ||
73 | +} | ||
74 | + | ||
75 | +.wxParse .i, | ||
76 | +.wxParse .cite, | ||
77 | +.wxParse .em, | ||
78 | +.wxParse .var, | ||
79 | +.wxParse .address { | ||
80 | + font-style: italic; | ||
81 | +} | ||
82 | + | ||
83 | +.wxParse .pre, | ||
84 | +.wxParse .tt, | ||
85 | +.wxParse .code, | ||
86 | +.wxParse .kbd, | ||
87 | +.wxParse .samp { | ||
88 | + font-family: monospace; | ||
89 | +} | ||
90 | +.wxParse .pre { | ||
91 | + overflow: auto; | ||
92 | + background: #f5f5f5; | ||
93 | + padding: 16upx; | ||
94 | + white-space: pre; | ||
95 | + margin: 1em 0upx; | ||
96 | +} | ||
97 | +.wxParse .code { | ||
98 | + display: inline; | ||
99 | + background: #f5f5f5; | ||
100 | +} | ||
101 | + | ||
102 | +.wxParse .big { | ||
103 | + font-size: 1.17em; | ||
104 | +} | ||
105 | + | ||
106 | +.wxParse .small, | ||
107 | +.wxParse .sub, | ||
108 | +.wxParse .sup { | ||
109 | + font-size: 0.83em; | ||
110 | +} | ||
111 | + | ||
112 | +.wxParse .sub { | ||
113 | + vertical-align: sub; | ||
114 | +} | ||
115 | +.wxParse .sup { | ||
116 | + vertical-align: super; | ||
117 | +} | ||
118 | + | ||
119 | +.wxParse .s, | ||
120 | +.wxParse .strike, | ||
121 | +.wxParse .del { | ||
122 | + text-decoration: line-through; | ||
123 | +} | ||
124 | + | ||
125 | +.wxParse .strong, | ||
126 | +.wxParse .s { | ||
127 | + display: inline; | ||
128 | +} | ||
129 | + | ||
130 | +.wxParse .a { | ||
131 | + color: deepskyblue; | ||
132 | +} | ||
133 | + | ||
134 | +.wxParse .video { | ||
135 | + text-align: center; | ||
136 | + margin: 22upx 0; | ||
137 | +} | ||
138 | + | ||
139 | +.wxParse .video-video { | ||
140 | + width: 100%; | ||
141 | +} | ||
142 | + | ||
143 | +.wxParse .img { | ||
144 | + display: inline-block; | ||
145 | + width: 0; | ||
146 | + height: 0; | ||
147 | + max-width: 100%; | ||
148 | + overflow: hidden; | ||
149 | +} | ||
150 | + | ||
151 | +.wxParse .blockquote { | ||
152 | + margin: 10upx 0; | ||
153 | + padding: 22upx 0 22upx 22upx; | ||
154 | + font-family: Courier, Calibri, "宋体"; | ||
155 | + background: #f5f5f5; | ||
156 | + border-left: 6upx solid #dbdbdb; | ||
157 | +} | ||
158 | +.wxParse .blockquote .p { | ||
159 | + margin: 0; | ||
160 | +} | ||
161 | + | ||
162 | +.wxParse .ul, .wxParse .ol { | ||
163 | + display: block; | ||
164 | + margin: 1em 0; | ||
165 | + padding-left: 33upx; | ||
166 | +} | ||
167 | +.wxParse .ol { | ||
168 | + list-style-type: disc; | ||
169 | +} | ||
170 | +.wxParse .ol { | ||
171 | + list-style-type: decimal; | ||
172 | +} | ||
173 | +.wxParse .ol>weixin-parse-template,.wxParse .ul>weixin-parse-template { | ||
174 | + display: list-item; | ||
175 | + align-items: baseline; | ||
176 | + text-align: match-parent; | ||
177 | +} | ||
178 | + | ||
179 | +.wxParse .ol>.li,.wxParse .ul>.li { | ||
180 | + display: list-item; | ||
181 | + align-items: baseline; | ||
182 | + text-align: match-parent; | ||
183 | +} | ||
184 | +.wxParse .ul .ul, .wxParse .ol .ul { | ||
185 | + list-style-type: circle; | ||
186 | +} | ||
187 | +.wxParse .ol .ol .ul, .wxParse .ol .ul .ul, .wxParse .ul .ol .ul, .wxParse .ul .ul .ul { | ||
188 | + list-style-type: square; | ||
189 | +} | ||
190 | + | ||
191 | +.wxParse .u { | ||
192 | + text-decoration: underline; | ||
193 | +} | ||
194 | +.wxParse .hide { | ||
195 | + display: none; | ||
196 | +} | ||
197 | +.wxParse .del { | ||
198 | + display: inline; | ||
199 | +} | ||
200 | +.wxParse .figure { | ||
201 | + overflow: hidden; | ||
202 | +} | ||
203 | + | ||
204 | +.wxParse .table { | ||
205 | + width: 100%; | ||
206 | +} | ||
207 | +.wxParse .thead, .wxParse .tfoot, .wxParse .tr { | ||
208 | + display: flex; | ||
209 | + flex-direction: row; | ||
210 | +} | ||
211 | +.wxParse .tr { | ||
212 | + width:100%; | ||
213 | + display: flex; | ||
214 | + border-right: 2upx solid #e0e0e0; | ||
215 | + border-bottom: 2upx solid #e0e0e0; | ||
216 | +} | ||
217 | +.wxParse .th, | ||
218 | +.wxParse .td { | ||
219 | + display: flex; | ||
220 | + width: 1276upx; | ||
221 | + overflow: auto; | ||
222 | + flex: 1; | ||
223 | + padding: 11upx; | ||
224 | + border-left: 2upx solid #e0e0e0; | ||
225 | +} | ||
226 | +.wxParse .td:last { | ||
227 | + border-top: 2upx solid #e0e0e0; | ||
228 | +} | ||
229 | +.wxParse .th { | ||
230 | + background: #f0f0f0; | ||
231 | + border-top: 2upx solid #e0e0e0; | ||
232 | +} |
components/u-parse/u-parse.vue
0 → 100644
1 | +<!--** | ||
2 | + * forked from:https://github.com/F-loat/mpvue-wxParse | ||
3 | + * | ||
4 | + * github地址: https://github.com/dcloudio/uParse | ||
5 | + * | ||
6 | + * for: uni-app框架下 富文本解析 | ||
7 | + */--> | ||
8 | + | ||
9 | +<template> | ||
10 | +<!--基础元素--> | ||
11 | +<div class="wxParse" :class="className" v-if="!loading"> | ||
12 | + <block v-for="(node,index) of nodes" :key="index"> | ||
13 | + <wxParseTemplate :node="node" /> | ||
14 | + </block> | ||
15 | +</div> | ||
16 | +</template> | ||
17 | + | ||
18 | +<script> | ||
19 | +import HtmlToJson from './libs/html2json'; | ||
20 | +import wxParseTemplate from './components/wxParseTemplate0'; | ||
21 | + | ||
22 | +export default { | ||
23 | + name: 'wxParse', | ||
24 | + props: { | ||
25 | + loading: { | ||
26 | + type: Boolean, | ||
27 | + default: false, | ||
28 | + }, | ||
29 | + className: { | ||
30 | + type: String, | ||
31 | + default: '', | ||
32 | + }, | ||
33 | + content: { | ||
34 | + type: String, | ||
35 | + default: '', | ||
36 | + }, | ||
37 | + noData: { | ||
38 | + type: String, | ||
39 | + default: '<div style="color: red;">数据不能为空</div>', | ||
40 | + }, | ||
41 | + startHandler: { | ||
42 | + type: Function, | ||
43 | + default() { | ||
44 | + return (node) => { | ||
45 | + node.attr.class = null; | ||
46 | + node.attr.style = null; | ||
47 | + }; | ||
48 | + }, | ||
49 | + }, | ||
50 | + endHandler: { | ||
51 | + type: Function, | ||
52 | + default: null, | ||
53 | + }, | ||
54 | + charsHandler: { | ||
55 | + type: Function, | ||
56 | + default: null, | ||
57 | + }, | ||
58 | + imageProp: { | ||
59 | + type: Object, | ||
60 | + default() { | ||
61 | + return { | ||
62 | + mode: 'aspectFit', | ||
63 | + padding: 0, | ||
64 | + lazyLoad: false, | ||
65 | + domain: '', | ||
66 | + }; | ||
67 | + }, | ||
68 | + }, | ||
69 | + }, | ||
70 | + components: { | ||
71 | + wxParseTemplate, | ||
72 | + }, | ||
73 | + data() { | ||
74 | + return { | ||
75 | + imageUrls: [], | ||
76 | + }; | ||
77 | + }, | ||
78 | + computed: { | ||
79 | + nodes() { | ||
80 | + const { | ||
81 | + content, | ||
82 | + noData, | ||
83 | + imageProp, | ||
84 | + startHandler, | ||
85 | + endHandler, | ||
86 | + charsHandler, | ||
87 | + } = this; | ||
88 | + const parseData = content || noData; | ||
89 | + const customHandler = { | ||
90 | + start: startHandler, | ||
91 | + end: endHandler, | ||
92 | + chars: charsHandler, | ||
93 | + }; | ||
94 | + const results = HtmlToJson(parseData, customHandler, imageProp, this); | ||
95 | + this.imageUrls = results.imageUrls; | ||
96 | + console.log(results) | ||
97 | + return results.nodes; | ||
98 | + }, | ||
99 | + }, | ||
100 | + methods: { | ||
101 | + navigate(href, $event) { | ||
102 | + this.$emit('navigate', href, $event); | ||
103 | + }, | ||
104 | + preview(src, $event) { | ||
105 | + if (!this.imageUrls.length) return; | ||
106 | + wx.previewImage({ | ||
107 | + current: src, | ||
108 | + urls: this.imageUrls, | ||
109 | + }); | ||
110 | + this.$emit('preview', src, $event); | ||
111 | + }, | ||
112 | + removeImageUrl(src) { | ||
113 | + const { imageUrls } = this; | ||
114 | + imageUrls.splice(imageUrls.indexOf(src), 1); | ||
115 | + }, | ||
116 | + }, | ||
117 | +}; | ||
118 | +</script> |
main.js
0 → 100644
manifest.json
0 → 100644
1 | +{ | ||
2 | + "name" : "card", | ||
3 | + "appid" : "__UNI__C5AC020", | ||
4 | + "description" : "", | ||
5 | + "versionName" : "1.0.0", | ||
6 | + "versionCode" : "100", | ||
7 | + "transformPx" : false, | ||
8 | + /* 5+App特有相关 */ | ||
9 | + "app-plus" : { | ||
10 | + "usingComponents" : true, | ||
11 | + "nvueCompiler" : "uni-app", | ||
12 | + "splashscreen" : { | ||
13 | + "alwaysShowBeforeRender" : true, | ||
14 | + "waiting" : true, | ||
15 | + "autoclose" : true, | ||
16 | + "delay" : 0 | ||
17 | + }, | ||
18 | + /* 模块配置 */ | ||
19 | + "modules" : {}, | ||
20 | + /* 应用发布信息 */ | ||
21 | + "distribute" : { | ||
22 | + /* android打包配置 */ | ||
23 | + "android" : { | ||
24 | + "permissions" : [ | ||
25 | + "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>", | ||
26 | + "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>", | ||
27 | + "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>", | ||
28 | + "<uses-permission android:name=\"android.permission.VIBRATE\"/>", | ||
29 | + "<uses-permission android:name=\"android.permission.READ_LOGS\"/>", | ||
30 | + "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>", | ||
31 | + "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>", | ||
32 | + "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>", | ||
33 | + "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>", | ||
34 | + "<uses-permission android:name=\"android.permission.CAMERA\"/>", | ||
35 | + "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>", | ||
36 | + "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>", | ||
37 | + "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>", | ||
38 | + "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>", | ||
39 | + "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>", | ||
40 | + "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>", | ||
41 | + "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>", | ||
42 | + "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>", | ||
43 | + "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>", | ||
44 | + "<uses-feature android:name=\"android.hardware.camera\"/>", | ||
45 | + "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>", | ||
46 | + "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>" | ||
47 | + ] | ||
48 | + }, | ||
49 | + /* ios打包配置 */ | ||
50 | + "ios" : {}, | ||
51 | + /* SDK配置 */ | ||
52 | + "sdkConfigs" : {} | ||
53 | + } | ||
54 | + }, | ||
55 | + /* 快应用特有相关 */ | ||
56 | + "quickapp" : {}, | ||
57 | + /* 小程序特有相关 */ | ||
58 | + "mp-weixin" : { | ||
59 | + "appid" : "wx5282e7febc772e8c", | ||
60 | + "setting" : { | ||
61 | + "urlCheck" : false | ||
62 | + }, | ||
63 | + "usingComponents" : true | ||
64 | + }, | ||
65 | + "mp-alipay" : { | ||
66 | + "usingComponents" : true | ||
67 | + }, | ||
68 | + "mp-baidu" : { | ||
69 | + "usingComponents" : true | ||
70 | + }, | ||
71 | + "mp-toutiao" : { | ||
72 | + "usingComponents" : true | ||
73 | + } | ||
74 | +} |
pages.json
0 → 100644
1 | +{ | ||
2 | + "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages | ||
3 | + // 首页 | ||
4 | + { | ||
5 | + "path": "pages/index/index", | ||
6 | + "style": { | ||
7 | + "navigationBarTitleText": "轴承名片网", | ||
8 | + "navigationBarBackgroundColor": "#fff", | ||
9 | + "navigationBarTextStyle": "black" | ||
10 | + } | ||
11 | + }, | ||
12 | + // 名片列表 | ||
13 | + { | ||
14 | + "path": "pages/index/cardList", | ||
15 | + "style": { | ||
16 | + "navigationBarTitleText": "名片列表", | ||
17 | + "navigationBarBackgroundColor": "#fff", | ||
18 | + "navigationBarTextStyle": "black" | ||
19 | + } | ||
20 | + }, | ||
21 | + // 搜索结果 | ||
22 | + { | ||
23 | + "path": "pages/index/search", | ||
24 | + "style": { | ||
25 | + "navigationBarTitleText": "搜索", | ||
26 | + "navigationBarBackgroundColor": "#fff", | ||
27 | + "navigationBarTextStyle": "black" | ||
28 | + } | ||
29 | + }, | ||
30 | + // 名片详情 | ||
31 | + { | ||
32 | + "path": "pages/index/cardDetail", | ||
33 | + "style": { | ||
34 | + "navigationBarTitleText": "轴承名片网", | ||
35 | + "navigationBarBackgroundColor": "#fff", | ||
36 | + "navigationBarTextStyle": "black" | ||
37 | + } | ||
38 | + }, | ||
39 | + // 我的名片 | ||
40 | + { | ||
41 | + "path": "pages/card/card", | ||
42 | + "style": { | ||
43 | + "navigationBarTitleText": "轴承名片网", | ||
44 | + "navigationBarBackgroundColor": "#fff", | ||
45 | + "navigationBarTextStyle": "black" | ||
46 | + } | ||
47 | + }, | ||
48 | + // 添加名片 | ||
49 | + { | ||
50 | + "path": "pages/card/addCard", | ||
51 | + "style": { | ||
52 | + "navigationBarTitleText": "发布名片", | ||
53 | + "navigationBarBackgroundColor": "#fff", | ||
54 | + "navigationBarTextStyle": "black" | ||
55 | + } | ||
56 | + }, | ||
57 | + // 编辑名片 | ||
58 | + { | ||
59 | + "path": "pages/card/editorCard", | ||
60 | + "style": { | ||
61 | + "navigationBarTitleText": "编辑名片", | ||
62 | + "navigationBarBackgroundColor": "#fff", | ||
63 | + "navigationBarTextStyle": "black" | ||
64 | + } | ||
65 | + }, | ||
66 | + // 我的收藏 | ||
67 | + { | ||
68 | + "path": "pages/collect/collect", | ||
69 | + "style": { | ||
70 | + "navigationBarTitleText": "名片收藏", | ||
71 | + "navigationBarBackgroundColor": "#fff", | ||
72 | + "navigationBarTextStyle": "black" | ||
73 | + } | ||
74 | + }, | ||
75 | + // 会员中心 | ||
76 | + { | ||
77 | + "path": "pages/vip/vip", | ||
78 | + "style": { | ||
79 | + "navigationBarTitleText": "会员中心", | ||
80 | + "navigationBarBackgroundColor": "#fff", | ||
81 | + "navigationBarTextStyle": "black" | ||
82 | + } | ||
83 | + }, | ||
84 | + // 我的会员 | ||
85 | + { | ||
86 | + "path": "pages/vip/myVip", | ||
87 | + "style": { | ||
88 | + "navigationBarTitleText": "我的会员", | ||
89 | + "navigationBarBackgroundColor": "#fff", | ||
90 | + "navigationBarTextStyle": "black" | ||
91 | + } | ||
92 | + }, | ||
93 | + // 我的充值 | ||
94 | + { | ||
95 | + "path": "pages/vip/recharge", | ||
96 | + "style": { | ||
97 | + "navigationBarTitleText": "我的充值", | ||
98 | + "navigationBarBackgroundColor": "#fff", | ||
99 | + "navigationBarTextStyle": "black" | ||
100 | + } | ||
101 | + }, | ||
102 | + // 联系客服 | ||
103 | + { | ||
104 | + "path": "pages/vip/contactService", | ||
105 | + "style": { | ||
106 | + "navigationBarTitleText": "联系客服", | ||
107 | + "navigationBarBackgroundColor": "#fff", | ||
108 | + "navigationBarTextStyle": "black" | ||
109 | + } | ||
110 | + }, | ||
111 | + // 关于我们 | ||
112 | + { | ||
113 | + "path": "pages/vip/aboutUs", | ||
114 | + "style": { | ||
115 | + "navigationBarTitleText": "关于我们", | ||
116 | + "navigationBarBackgroundColor": "#fff", | ||
117 | + "navigationBarTextStyle": "black" | ||
118 | + } | ||
119 | + }, | ||
120 | + // 授权登录 | ||
121 | + { | ||
122 | + "path": "pages/start/start", | ||
123 | + "style": { | ||
124 | + "navigationBarTitleText": "", | ||
125 | + "navigationBarBackgroundColor": "#fff", | ||
126 | + "navigationBarTextStyle": "black" | ||
127 | + } | ||
128 | + } | ||
129 | + ], | ||
130 | + "globalStyle": { | ||
131 | + "navigationBarTextStyle": "black", | ||
132 | + "navigationBarTitleText": "uni-app", | ||
133 | + "navigationBarBackgroundColor": "#F8F8F8", | ||
134 | + "backgroundColor": "#F8F8F8" | ||
135 | + }, | ||
136 | + "tabBar": { | ||
137 | + "color": "#8C9198", | ||
138 | + "selectedColor": "#0083FB", | ||
139 | + "borderStyle": "black", | ||
140 | + "backgroundColor": "#ffffff", | ||
141 | + "list": [{ | ||
142 | + "pagePath": "pages/index/index", | ||
143 | + "iconPath": "static/noindex1.png", | ||
144 | + "selectedIconPath": "static/index1.png", | ||
145 | + "text": "首页" | ||
146 | + }, { | ||
147 | + "pagePath": "pages/card/card", | ||
148 | + "iconPath": "static/nocard1.png", | ||
149 | + "selectedIconPath": "static/card1.png", | ||
150 | + "text": "我的名片" | ||
151 | + },{ | ||
152 | + "pagePath": "pages/collect/collect", | ||
153 | + "iconPath": "static/nocollect1.png", | ||
154 | + "selectedIconPath": "static/collect1.png", | ||
155 | + "text": "我的收藏" | ||
156 | + }, { | ||
157 | + "pagePath": "pages/vip/vip", | ||
158 | + "iconPath": "static/novip1.png", | ||
159 | + "selectedIconPath": "static/vip1.png", | ||
160 | + "text": "会员中心" | ||
161 | + }] | ||
162 | + } | ||
163 | +} |
pages/card/addCard.vue
0 → 100644
1 | +<template> | ||
2 | + <view class="add_card" :class="{ over_hide: isHide }"> | ||
3 | + <!-- 名片信息 --> | ||
4 | + <view class="add_card_top"> | ||
5 | + <!-- 正反面 --> | ||
6 | + <view class="add_card_single"> | ||
7 | + <view class="card_front flex_center" @click="uploadPositive()"> | ||
8 | + <view class="show_img" v-if="front_image"><image :src="front_image" mode="aspectFill"></image></view> | ||
9 | + <view class="flex_center" v-else> | ||
10 | + <view class="card_upload"><image src="../../static/add.png" mode=""></image></view> | ||
11 | + <view class="card_tips">上传名片正面图片</view> | ||
12 | + </view> | ||
13 | + </view> | ||
14 | + <view class="card_front flex_center" @click="uploadSide()"> | ||
15 | + <view class="show_img" v-if="reverse_image"><image :src="reverse_image" mode="aspectFill"></image></view> | ||
16 | + <view class="flex_center" v-else> | ||
17 | + <view class="card_upload"><image src="../../static/add.png" mode=""></image></view> | ||
18 | + <view class="card_tips">上传名片背面图片</view> | ||
19 | + </view> | ||
20 | + </view> | ||
21 | + <view class="upload_tips">建议名片尺寸为360*210像素 </view> | ||
22 | + <view class="msg_single layer_between"> | ||
23 | + <view class="single_l">公司名称:</view> | ||
24 | + <input class="single_r" type="text" v-model="company_name" placeholder="请输入公司名称" /> | ||
25 | + </view> | ||
26 | + </view> | ||
27 | + <!-- 公司简介 --> | ||
28 | + | ||
29 | + <view class="add_card_single"> | ||
30 | + <view class="msg_single"> | ||
31 | + <view class="single_l">公司简介:</view> | ||
32 | + <textarea v-model="brief" placeholder="请输入公司简介" maxlength="2000"/> | ||
33 | + <view class="layer_nostar flex_wrap_no"> | ||
34 | + <view class="wx_code" v-for="(item, index) in brief_images" :key="index"> | ||
35 | + <image :src="item" mode=""></image> | ||
36 | + <image @click="deleteCompany(index)" class="cancle_icon" src="../../static/del_icon@2x.png" mode=""></image> | ||
37 | + </view> | ||
38 | + <view class="wx_code" @click="uploadCompay()"><image src="../../static/add_wx.png" mode=""></image></view> | ||
39 | + </view> | ||
40 | + </view> | ||
41 | + </view> | ||
42 | + <!-- 经营范围 --> | ||
43 | + <view class="add_card_single"> | ||
44 | + <view class="msg_single"> | ||
45 | + <view class="single_l">经营范围:</view> | ||
46 | + <textarea v-model="scope" placeholder="请输入经营范围" maxlength="2000"/> | ||
47 | + <view class="layer_nostar flex_wrap_no"> | ||
48 | + <view class="wx_code" v-for="(item, index) in scope_images" :key="index"> | ||
49 | + <image :src="item" mode=""></image> | ||
50 | + <image @click="deleteScope(index)" class="cancle_icon" src="../../static/del_icon@2x.png" mode=""></image> | ||
51 | + </view> | ||
52 | + <view class="wx_code" @click="uploadBusiness()"><image src="../../static/add_wx.png" mode=""></image></view> | ||
53 | + </view> | ||
54 | + </view> | ||
55 | + </view> | ||
56 | + <!-- 各种联系方式 --> | ||
57 | + <view class="add_card_single"> | ||
58 | + <view class="msg_single layer_between"> | ||
59 | + <view class="single_l">联系人:</view> | ||
60 | + <input class="single_r" type="text" v-model="name" placeholder="请输入联系人" /> | ||
61 | + </view> | ||
62 | + </view> | ||
63 | + <view class="add_card_single"> | ||
64 | + <view class="msg_single layer_between"> | ||
65 | + <view class="single_l">地址:</view> | ||
66 | + <input class="single_r" type="text" v-model="site" placeholder="请输入地址" /> | ||
67 | + </view> | ||
68 | + </view> | ||
69 | + <view class="add_card_single"> | ||
70 | + <view class="msg_single layer_between"> | ||
71 | + <view class="single_l">电话:</view> | ||
72 | + <input class="single_r" type="text" v-model="phone" placeholder="请输入电话" /> | ||
73 | + </view> | ||
74 | + </view> | ||
75 | + <view class="add_card_single"> | ||
76 | + <view class="msg_single layer_between"> | ||
77 | + <view class="single_l">传真:</view> | ||
78 | + <input class="single_r" type="text" v-model="fax" placeholder="请输入传真" /> | ||
79 | + </view> | ||
80 | + </view> | ||
81 | + <view class="add_card_single"> | ||
82 | + <view class="msg_single layer_between"> | ||
83 | + <view class="single_l">手机号:</view> | ||
84 | + <input class="single_r" maxlength="11" type="text" v-model="mobile" placeholder="请输入手机号" /> | ||
85 | + </view> | ||
86 | + </view> | ||
87 | + <view class="add_card_single"> | ||
88 | + <view class="msg_single layer_between"> | ||
89 | + <view class="single_l">QQ:</view> | ||
90 | + <input class="single_r" type="text" v-model="qq" placeholder="请输入QQ号" /> | ||
91 | + </view> | ||
92 | + </view> | ||
93 | + <view class="add_card_single"> | ||
94 | + <view class="msg_single layer_between"> | ||
95 | + <view class="single_l">微信:</view> | ||
96 | + <input class="single_r" type="text" v-model="wechat" placeholder="请输入微信" /> | ||
97 | + </view> | ||
98 | + </view> | ||
99 | + <view class="add_card_single"> | ||
100 | + <view class="msg_single"> | ||
101 | + <view class="single_l">微信二维码:</view> | ||
102 | + <view class="layer_nostar" @click="uploadCode()"> | ||
103 | + <view class="wx_img" v-if="weichat_image"><image :src="weichat_image" mode=""></image></view> | ||
104 | + <view class="wx_code" v-else><image src="../../static/add_wx.png" mode=""></image></view> | ||
105 | + </view> | ||
106 | + </view> | ||
107 | + </view> | ||
108 | + </view> | ||
109 | + <!-- 名片分类 --> | ||
110 | + | ||
111 | + <view class="add_card_classify"> | ||
112 | + <view class="classify_title"> | ||
113 | + 名片分类: | ||
114 | + <text>(可选择{{ category_num }}个名片分类)</text> | ||
115 | + </view> | ||
116 | + <view class="classify_tips">想要增加更多分类,请提交名片升级成VIP后到会员中心增加</view> | ||
117 | + <!-- 轴承列表 --> | ||
118 | + <view class="bearing_classify layer_nostar"> | ||
119 | + <!-- 左侧类目 --> | ||
120 | + <view class="bearing_l"> | ||
121 | + <view class="bear_l_box flex_column_center"> | ||
122 | + <view | ||
123 | + class="bear_l_single flex_warp" | ||
124 | + :class="{ bear_l_active: isLeft == item.id }" | ||
125 | + v-for="(item, index) in leftList" | ||
126 | + :key="index" | ||
127 | + @click="changeLeft(item, index)" | ||
128 | + > | ||
129 | + <view class="bear_l_child">{{ item.name }}</view> | ||
130 | + </view> | ||
131 | + </view> | ||
132 | + </view> | ||
133 | + <!-- 右侧具体分类 --> | ||
134 | + <view class="bearing_r"> | ||
135 | + <view class="bear_r_box"> | ||
136 | + <view class="bear_r_single" :class="{ bear_r_active: item.isChoice }" v-for="(item, index) in rightList" :key="index" @click="changeRight(item, index)"> | ||
137 | + {{ item.name }} | ||
138 | + </view> | ||
139 | + </view> | ||
140 | + </view> | ||
141 | + </view> | ||
142 | + </view> | ||
143 | + <!-- 提交名片 --> | ||
144 | + <view class="submit_btn" @click="submitCard()">提交名片</view> | ||
145 | + <!-- 提交弹窗 --> | ||
146 | + <view class="tx_mask" v-if="isHide" @click="closeDialog()"></view> | ||
147 | + <view class="mask_content" v-if="isHide"> | ||
148 | + <view class="mask_top">成为VIP会员,其他用户可以搜索到您的名片</view> | ||
149 | + <view class="mask_bottom" @click="getNow()">立即获取</view> | ||
150 | + </view> | ||
151 | + </view> | ||
152 | +</template> | ||
153 | + | ||
154 | +<script> | ||
155 | +import App from '../../App.vue'; | ||
156 | +export default { | ||
157 | + data() { | ||
158 | + return { | ||
159 | + front_image: '', //正面图片 | ||
160 | + reverse_image: '', //反面图片 | ||
161 | + company_name: '', //公司名称 | ||
162 | + brief: '', //公司简介 | ||
163 | + brief_images: [], //公司简介图片 | ||
164 | + scope: '', //经营范围 | ||
165 | + scope_images: [], //经营范围图片 | ||
166 | + name: '', //联系人 | ||
167 | + phone: '', //电话 | ||
168 | + site: '', //地址 | ||
169 | + mobile: '', //手机号 | ||
170 | + fax: '', //传真 | ||
171 | + qq: '', // QQ | ||
172 | + wechat: '', //微信 | ||
173 | + weichat_image: '', //微信二维码 | ||
174 | + category_ids: [], //分类ID | ||
175 | + category_num: '', //可选分类个数 | ||
176 | + // 轴承列表 | ||
177 | + // 左侧 | ||
178 | + leftList: [], | ||
179 | + isLeft: 0, | ||
180 | + // 右侧 | ||
181 | + rightList: [], | ||
182 | + isRight: 0, | ||
183 | + // 弹窗 | ||
184 | + isHide: false, | ||
185 | + // 是否为vip 1:是 2:否 | ||
186 | + isVip: '', | ||
187 | + // 防连点 | ||
188 | + isClick:false, | ||
189 | + imgBrief: [], //公司简介上传数量 | ||
190 | + imgScope: [] | ||
191 | + }; | ||
192 | + }, | ||
193 | + methods: { | ||
194 | + // 上传正面图片 | ||
195 | + uploadPositive() { | ||
196 | + let t = this; | ||
197 | + uni.chooseImage({ | ||
198 | + count: 1, //默认9 | ||
199 | + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 | ||
200 | + sourceType: ['album'], //从相册选择 | ||
201 | + success: chooseImageRes => { | ||
202 | + const tempFilePaths = chooseImageRes.tempFilePaths; | ||
203 | + App.upload(tempFilePaths[0]).then(res => { | ||
204 | + this.front_image = res.url; | ||
205 | + }); | ||
206 | + } | ||
207 | + }); | ||
208 | + }, | ||
209 | + // 上传反面图片 | ||
210 | + uploadSide() { | ||
211 | + let t = this; | ||
212 | + uni.chooseImage({ | ||
213 | + count: 1, //默认9 | ||
214 | + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 | ||
215 | + sourceType: ['album'], //从相册选择 | ||
216 | + success: chooseImageRes => { | ||
217 | + const tempFilePaths = chooseImageRes.tempFilePaths; | ||
218 | + App.upload(tempFilePaths[0]).then(res => { | ||
219 | + this.reverse_image = res.url; | ||
220 | + }); | ||
221 | + } | ||
222 | + }); | ||
223 | + }, | ||
224 | + // 上传公司简介图片 | ||
225 | + uploadCompay() { | ||
226 | + let t = this; | ||
227 | + uni.chooseImage({ | ||
228 | + count: 3, //默认9 | ||
229 | + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 | ||
230 | + sourceType: ['album'], //从相册选择 | ||
231 | + success: chooseImageRes => { | ||
232 | + const tempFilePaths = chooseImageRes.tempFilePaths; | ||
233 | + t.imgBrief = [...t.imgBrief,...tempFilePaths] | ||
234 | + if(t.imgBrief.length>3){ | ||
235 | + uni.showToast({ | ||
236 | + title: '图片总数超过3张', | ||
237 | + icon: 'none' | ||
238 | + }); | ||
239 | + return false; | ||
240 | + } | ||
241 | + tempFilePaths.forEach(el => { | ||
242 | + App.upload(el).then(res => { | ||
243 | + t.brief_images.push(res.url); | ||
244 | + }); | ||
245 | + }); | ||
246 | + } | ||
247 | + }); | ||
248 | + }, | ||
249 | + // 上传经营范围图片 | ||
250 | + uploadBusiness() { | ||
251 | + let t = this; | ||
252 | + uni.chooseImage({ | ||
253 | + count: 3, //默认9 | ||
254 | + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 | ||
255 | + sourceType: ['album'], //从相册选择 | ||
256 | + success: chooseImageRes => { | ||
257 | + const tempFilePaths = chooseImageRes.tempFilePaths; | ||
258 | + t.imgScope = [...t.imgScope, ...tempFilePaths]; | ||
259 | + if (t.imgScope.length > 3) { | ||
260 | + uni.showToast({ | ||
261 | + title: '图片总数超过3张', | ||
262 | + icon: 'none' | ||
263 | + }); | ||
264 | + return false; | ||
265 | + } | ||
266 | + tempFilePaths.forEach(el => { | ||
267 | + App.upload(el).then(res => { | ||
268 | + t.scope_images.push(res.url); | ||
269 | + }); | ||
270 | + }); | ||
271 | + } | ||
272 | + }); | ||
273 | + }, | ||
274 | + // 删除公司简介图片 | ||
275 | + deleteCompany(index){ | ||
276 | + this.imgBrief.splice(index, 1); | ||
277 | + this.brief_images.splice(index,1) | ||
278 | + }, | ||
279 | + // 删除经营范围图片 | ||
280 | + deleteScope(index){ | ||
281 | + this.imgBrief.splice(index, 1); | ||
282 | + this.scope_images.splice(index,1) | ||
283 | + }, | ||
284 | + // 上传二维码 | ||
285 | + uploadCode() { | ||
286 | + let t = this; | ||
287 | + uni.chooseImage({ | ||
288 | + count: 1, //默认9 | ||
289 | + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 | ||
290 | + sourceType: ['album'], //从相册选择 | ||
291 | + success: chooseImageRes => { | ||
292 | + const tempFilePaths = chooseImageRes.tempFilePaths; | ||
293 | + App.upload(tempFilePaths[0]).then(res => { | ||
294 | + t.weichat_image = res.url; | ||
295 | + }); | ||
296 | + } | ||
297 | + }); | ||
298 | + }, | ||
299 | + // 首页分类数据 左侧一级分类 | ||
300 | + getType() { | ||
301 | + let t = this; | ||
302 | + t.leftList = []; | ||
303 | + t.rightList = []; | ||
304 | + let url = '/api/category/get_category_one'; | ||
305 | + App.post(url).then(res => { | ||
306 | + t.leftList = res; | ||
307 | + t.rightList = res[0].children; | ||
308 | + t.isLeft = res[0].id; | ||
309 | + t.rightList.forEach(el => { | ||
310 | + el.isChoice = false; | ||
311 | + }); | ||
312 | + }); | ||
313 | + }, | ||
314 | + // 左侧列表选中 | ||
315 | + changeLeft(item, index) { | ||
316 | + this.isLeft = item.id; | ||
317 | + this.rightList = item.children; | ||
318 | + }, | ||
319 | + // 右侧列表选中 | ||
320 | + changeRight(item, index) { | ||
321 | + let arr = []; | ||
322 | + item.isChoice = !item.isChoice; | ||
323 | + this.leftList.forEach(lel=>{ | ||
324 | + // 找出已选择的二级分类 | ||
325 | + lel.children.forEach(rel=>{ | ||
326 | + if(rel.isChoice == true){ | ||
327 | + arr.push(rel); | ||
328 | + } | ||
329 | + }) | ||
330 | + }) | ||
331 | + // 根据后台返回的可选择类型数量选择 | ||
332 | + if (arr.length > this.category_num) { | ||
333 | + // 删除超出可选数量的最后一位 | ||
334 | + let end = arr.pop(); | ||
335 | + end.isChoice = false; | ||
336 | + uni.showToast({ | ||
337 | + title:"已超出可选分类数量", | ||
338 | + icon:"none" | ||
339 | + }) | ||
340 | + return false | ||
341 | + } | ||
342 | + arr.forEach(el => { | ||
343 | + this.category_ids.push(el.id); | ||
344 | + }); | ||
345 | + // 去重 | ||
346 | + this.category_ids = [...new Set(this.category_ids)]; | ||
347 | + // 回显选中的分类 | ||
348 | + this.$forceUpdate(); | ||
349 | + }, | ||
350 | + // 提交名片 | ||
351 | + submitCard() { | ||
352 | + if(!this.isClick){ | ||
353 | + let t = this; | ||
354 | + t.isClick = true | ||
355 | + let url = '/api/goods/publish_card'; | ||
356 | + let params = { | ||
357 | + front_image: t.front_image, | ||
358 | + reverse_image: t.reverse_image, | ||
359 | + company_name: t.company_name, | ||
360 | + brief: t.brief, | ||
361 | + brief_images: t.brief_images.toString(), | ||
362 | + scope: t.scope, | ||
363 | + scope_images: t.scope_images.toString(), | ||
364 | + name: t.name, | ||
365 | + phone: t.phone, | ||
366 | + site: t.site, | ||
367 | + mobile: t.mobile, | ||
368 | + fax: t.fax, | ||
369 | + qq: t.qq, | ||
370 | + wechat: t.wechat, | ||
371 | + wechat_image: t.weichat_image, | ||
372 | + category_ids: t.category_ids.toString() | ||
373 | + }; | ||
374 | + if (t.front_image) { | ||
375 | + if (t.company_name) { | ||
376 | + if (t.brief) { | ||
377 | + if (t.scope) { | ||
378 | + if (t.name) { | ||
379 | + App.post(url, params).then(res => { | ||
380 | + uni.showToast({ | ||
381 | + title: '发布成功', | ||
382 | + icon: 'success', | ||
383 | + duration: 1000 | ||
384 | + }); | ||
385 | + setTimeout(function() { | ||
386 | + if(t.isVip == 2){ | ||
387 | + t.isHide = true; | ||
388 | + }else{ | ||
389 | + uni.navigateBack({ | ||
390 | + delta: 1 | ||
391 | + }); | ||
392 | + } | ||
393 | + t.isClick = false | ||
394 | + }, 1000); | ||
395 | + }); | ||
396 | + } else { | ||
397 | + uni.showToast({ | ||
398 | + title: '请输入联系人姓名', | ||
399 | + icon: 'none' | ||
400 | + }); | ||
401 | + t.isClick = false | ||
402 | + } | ||
403 | + } else { | ||
404 | + uni.showToast({ | ||
405 | + title: '请输入经营范围', | ||
406 | + icon: 'none' | ||
407 | + }); | ||
408 | + t.isClick = false | ||
409 | + } | ||
410 | + } else { | ||
411 | + uni.showToast({ | ||
412 | + title: '请输入公司简介', | ||
413 | + icon: 'none' | ||
414 | + }); | ||
415 | + t.isClick = false | ||
416 | + } | ||
417 | + } else { | ||
418 | + uni.showToast({ | ||
419 | + title: '请填写公司名称', | ||
420 | + icon: 'none' | ||
421 | + }); | ||
422 | + t.isClick = false | ||
423 | + } | ||
424 | + } else { | ||
425 | + uni.showToast({ | ||
426 | + title: '请上传正面图片', | ||
427 | + icon: 'none' | ||
428 | + }); | ||
429 | + t.isClick = false | ||
430 | + } | ||
431 | + } | ||
432 | + | ||
433 | + }, | ||
434 | + // 关闭弹窗 | ||
435 | + closeDialog() { | ||
436 | + uni.navigateBack({ | ||
437 | + delta: 1 | ||
438 | + }); | ||
439 | + }, | ||
440 | + // 立即获取vip | ||
441 | + getNow() { | ||
442 | + uni.redirectTo({ | ||
443 | + url: '/pages/vip/myVip' | ||
444 | + }); | ||
445 | + } | ||
446 | + }, | ||
447 | + onLoad() { | ||
448 | + this.category_num = uni.getStorageSync('category_num'); | ||
449 | + this.isVip = uni.getStorageSync("is_vip"); | ||
450 | + this.getType(); | ||
451 | + | ||
452 | + } | ||
453 | +}; | ||
454 | +</script> | ||
455 | + | ||
456 | +<style> | ||
457 | +@import url('../../style/addCard'); | ||
458 | +</style> |
pages/card/card.vue
0 → 100644
1 | +<template> | ||
2 | + <view class="card_wrap"> | ||
3 | + <!-- 无名片 --> | ||
4 | + <view class="layer_center no_card" v-if="!isHave"> | ||
5 | + <view class="no_card_pic"> | ||
6 | + <image src="../../static/no_card.png" mode=""></image> | ||
7 | + </view> | ||
8 | + <view class="add_card"> | ||
9 | + <view class="add_card_btn" @click="addCard()"> | ||
10 | + 发布我的名片 | ||
11 | + </view> | ||
12 | + </view> | ||
13 | + </view> | ||
14 | + <!-- 有名片 --> | ||
15 | + <view class="content" v-else> | ||
16 | + <view class="detail_top"> | ||
17 | + <!-- 公司名称 --> | ||
18 | + <view class="company_name">{{cardDetail.company_name}}</view> | ||
19 | + <!-- 名片正反面 --> | ||
20 | + <view> | ||
21 | + <image class="card_pic" :src="cardDetail.front_image" mode=""></image> | ||
22 | + <view class="card_tips">名片正面</view> | ||
23 | + </view> | ||
24 | + <view> | ||
25 | + <image class="card_pic" :src="cardDetail.reverse_image" mode=""></image> | ||
26 | + <view class="card_tips">名片反面</view> | ||
27 | + </view> | ||
28 | + </view> | ||
29 | + <!-- 公司简介 --> | ||
30 | + <view class="company_intro"> | ||
31 | + <view class="company_title_wrap"><view class="company_title">公司简介</view></view> | ||
32 | + <view class="company_detail"> | ||
33 | + <view class="company_detail_box"> | ||
34 | + <view class=""> | ||
35 | + {{cardDetail.brief}} | ||
36 | + </view> | ||
37 | + <view class="company_pic_wrap flex_wrap_no"> | ||
38 | + <view class="company_pic_single" @click="showImg(item)" v-for="(item, index) in cardDetail.brief_images" :key="index"><image :src="item" mode=""></image></view> | ||
39 | + </view> | ||
40 | + </view> | ||
41 | + </view> | ||
42 | + </view> | ||
43 | + <!-- 经营范围 --> | ||
44 | + <view class="company_intro"> | ||
45 | + <view class="company_title_wrap"><view class="company_title">经营范围</view></view> | ||
46 | + <view class="company_detail"> | ||
47 | + <view class="company_detail_box"> | ||
48 | + <view class=""> | ||
49 | + {{cardDetail.scope}} | ||
50 | + </view> | ||
51 | + <view class="company_pic_wrap flex_wrap_no"> | ||
52 | + <view class="company_pic_single" @click="showImg(item)" v-for="(item, index) in cardDetail.scope_images" :key="index"><image :src="item" mode=""></image></view> | ||
53 | + </view> | ||
54 | + <!-- 刷新名片 --> | ||
55 | + <view class="refresh_card flex_column_nojustify" @click="refreshCard()"> | ||
56 | + <image class="refresh_icon" src="../../static/refresh.png" mode=""></image> | ||
57 | + <view class="refresh_tips">刷新名片</view> | ||
58 | + </view> | ||
59 | + </view> | ||
60 | + </view> | ||
61 | + </view> | ||
62 | + <!-- 联系方式 --> | ||
63 | + <view class="company_intro"> | ||
64 | + <view class="company_title_wrap"><view class="company_title">联系方式</view></view> | ||
65 | + <!-- 地址 --> | ||
66 | + <view class="contact_code"> | ||
67 | + <view class="layer_nobetween"> | ||
68 | + <!-- 二维码 --> | ||
69 | + <view class="qr_code" @click="showImg(cardDetail.wechat_image)"><image :src="cardDetail.wechat_image" mode=""></image></view> | ||
70 | + <!-- 姓名 地址 --> | ||
71 | + <view class="contact_r flex_star_between"> | ||
72 | + <view class="">联系人:{{cardDetail.name}}</view> | ||
73 | + <view class="" @click="callPhone()" v-if="cardDetail.phone">电话:{{cardDetail.phone}}</view> | ||
74 | + <view class="" v-if="cardDetail.site">地址:{{cardDetail.site}}</view> | ||
75 | + </view> | ||
76 | + </view> | ||
77 | + </view> | ||
78 | + <!-- 各种联系方式 --> | ||
79 | + <view class="contact_single layer_between" v-if="cardDetail.fax"> | ||
80 | + <view class="layer_between"> | ||
81 | + <image class="contact_icon" src="../../static/phone.png" mode=""></image> | ||
82 | + 传真 | ||
83 | + </view> | ||
84 | + <view class="" @click="copyEmail()">{{cardDetail.fax}}</view> | ||
85 | + </view> | ||
86 | + <view class="contact_single layer_between" v-if="cardDetail.mobile"> | ||
87 | + <view class="layer_between"> | ||
88 | + <image class="contact_icon" src="../../static/tel.png" mode=""></image> | ||
89 | + 手机号 | ||
90 | + </view> | ||
91 | + <view class="" @click="callTel()">{{cardDetail.mobile}}</view> | ||
92 | + </view> | ||
93 | + <view class="contact_single layer_between" v-if="cardDetail.qq"> | ||
94 | + <view class="layer_between"> | ||
95 | + <image class="contact_icon" src="../../static/qq.png" mode=""></image> | ||
96 | |||
97 | + </view> | ||
98 | + <view class="" @click="copyQQ()">{{cardDetail.qq}}</view> | ||
99 | + </view> | ||
100 | + <view class="contact_single no_bottom layer_between" v-if="cardDetail.wechat"> | ||
101 | + <view class="layer_between"> | ||
102 | + <image class="contact_icon" src="../../static/weixin.png" mode=""></image> | ||
103 | + 微信 | ||
104 | + </view> | ||
105 | + <view class="" @click="copyWx()">{{cardDetail.wechat}}</view> | ||
106 | + </view> | ||
107 | + </view> | ||
108 | + <!-- 图片放大 --> | ||
109 | + <view class="tx_mask" v-if="isShowImg" @click="closDialog()"></view> | ||
110 | + <view class="mask_content" v-if="isShowImg" @click="closDialog()" @longpress="saveImg()"> | ||
111 | + <image :src="img" mode="widthFix"></image> | ||
112 | + </view> | ||
113 | + <!-- 编辑名片 --> | ||
114 | + <view class="layer_between editor_btn"> | ||
115 | + <view class="refresh_time"> | ||
116 | + 上次刷新时间:{{cardDetail.refresh_time}} | ||
117 | + </view> | ||
118 | + <view class="editor_card" @click="toEditor()">编辑我的名片</view> | ||
119 | + </view> | ||
120 | + </view> | ||
121 | + </view> | ||
122 | +</template> | ||
123 | + | ||
124 | +<script> | ||
125 | + import App from "../../App.vue"; | ||
126 | + export default { | ||
127 | + data() { | ||
128 | + return { | ||
129 | + // 是否有名片 | ||
130 | + isHave:false, | ||
131 | + // 我的名片详情 | ||
132 | + cardDetail:"", | ||
133 | + token:"", | ||
134 | + // 图片放大 | ||
135 | + isShowImg:false, | ||
136 | + img:"", | ||
137 | + } | ||
138 | + }, | ||
139 | + methods: { | ||
140 | + // 图片放大 | ||
141 | + showImg(img){ | ||
142 | + console.log(111) | ||
143 | + this.isShowImg = true | ||
144 | + this.img = img | ||
145 | + }, | ||
146 | + closDialog(){ | ||
147 | + this.isShowImg = false | ||
148 | + }, | ||
149 | + saveImg(){ | ||
150 | + let t = this ; | ||
151 | + uni.downloadFile({ | ||
152 | + url: t.img, | ||
153 | + success: function(res) { | ||
154 | + uni.saveImageToPhotosAlbum({ | ||
155 | + filePath: res.tempFilePath, | ||
156 | + success: function() { | ||
157 | + uni.showToast({ | ||
158 | + title: '保存成功', | ||
159 | + icon: 'none', | ||
160 | + duration: 1500 | ||
161 | + }); | ||
162 | + t.isShowImg = false | ||
163 | + }, | ||
164 | + fail: function(err) { | ||
165 | + if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg === | ||
166 | + "saveImageToPhotosAlbum:fail:auth denied") { | ||
167 | + uni.showToast({ | ||
168 | + title: '需要您授权保存相册', | ||
169 | + icon:none, | ||
170 | + duration: 1500, | ||
171 | + success: modalSuccess => { | ||
172 | + uni.openSetting({ | ||
173 | + success(settingdata) { | ||
174 | + if (settingdata.authSetting['scope.writePhotosAlbum']) { | ||
175 | + uni.showToast({ | ||
176 | + title: '获取权限成功', | ||
177 | + icon: 'none', | ||
178 | + duration: 1500 | ||
179 | + }); | ||
180 | + } else { | ||
181 | + uni.showToast({ | ||
182 | + title: '获取权限失败', | ||
183 | + icon: 'none', | ||
184 | + duration: 1500 | ||
185 | + }); | ||
186 | + } | ||
187 | + }, | ||
188 | + fail(failData) { | ||
189 | + console.log("failData", failData) | ||
190 | + }, | ||
191 | + complete(finishData) { | ||
192 | + console.log("finishData", finishData) | ||
193 | + } | ||
194 | + }) | ||
195 | + } | ||
196 | + }) | ||
197 | + } | ||
198 | + }, | ||
199 | + }); | ||
200 | + } | ||
201 | + }); | ||
202 | + }, | ||
203 | + // 刷新名片 | ||
204 | + refreshCard(){ | ||
205 | + let url = "/api/goods/refresh"; | ||
206 | + App.post(url) | ||
207 | + .then(res=>{ | ||
208 | + this.getMyCard() | ||
209 | + }) | ||
210 | + }, | ||
211 | + // 发布我的名片 | ||
212 | + addCard() { | ||
213 | + if(this.token){ | ||
214 | + uni.navigateTo({ | ||
215 | + url:"/pages/card/addCard" | ||
216 | + }) | ||
217 | + }else{ | ||
218 | + uni.navigateTo({ | ||
219 | + url:"/pages/start/start" | ||
220 | + }) | ||
221 | + } | ||
222 | + }, | ||
223 | + // 获取我的名片详情 | ||
224 | + getMyCard(){ | ||
225 | + let url = "/api/goods/my_goods"; | ||
226 | + App.post(url) | ||
227 | + .then(res=>{ | ||
228 | + this.cardDetail = res; | ||
229 | + if(this.cardDetail){ | ||
230 | + this.isHave = true | ||
231 | + } | ||
232 | + }) | ||
233 | + }, | ||
234 | + // 去编辑页 | ||
235 | + toEditor(){ | ||
236 | + uni.navigateTo({ | ||
237 | + url:"/pages/card/editorCard" | ||
238 | + }) | ||
239 | + }, | ||
240 | + // 拨打电话 | ||
241 | + callPhone(){ | ||
242 | + uni.makePhoneCall({ | ||
243 | + phoneNumber:this.cardDetail.mobile | ||
244 | + }) | ||
245 | + }, | ||
246 | + // 拨打手机号 | ||
247 | + callTel(){ | ||
248 | + uni.makePhoneCall({ | ||
249 | + phoneNumber:this.cardDetail.mobile | ||
250 | + }) | ||
251 | + }, | ||
252 | + // 复制传真号 | ||
253 | + copyEmail(){ | ||
254 | + uni.setClipboardData({ | ||
255 | + data: this.cardDetail.fax, | ||
256 | + success: function () { | ||
257 | + uni.showToast({ | ||
258 | + title:"复制成功", | ||
259 | + icon:'success' | ||
260 | + }) | ||
261 | + } | ||
262 | + }); | ||
263 | + }, | ||
264 | + // 复制qq号 | ||
265 | + copyQQ(){ | ||
266 | + uni.setClipboardData({ | ||
267 | + data: this.cardDetail.qq, | ||
268 | + success: function () { | ||
269 | + uni.showToast({ | ||
270 | + title:"复制成功", | ||
271 | + icon:'success' | ||
272 | + }) | ||
273 | + } | ||
274 | + }); | ||
275 | + }, | ||
276 | + // 复制微信号 | ||
277 | + copyWx(){ | ||
278 | + uni.setClipboardData({ | ||
279 | + data: this.cardDetail.wechat, | ||
280 | + success: function () { | ||
281 | + uni.showToast({ | ||
282 | + title:"复制成功", | ||
283 | + icon:'success' | ||
284 | + }) | ||
285 | + } | ||
286 | + }); | ||
287 | + }, | ||
288 | + }, | ||
289 | + onShow() { | ||
290 | + this.token = uni.getStorageSync("token"); | ||
291 | + // 获取我的名片详情 | ||
292 | + if(this.token){ | ||
293 | + this.getMyCard(); | ||
294 | + } | ||
295 | + }, | ||
296 | + onLoad() { | ||
297 | + | ||
298 | + }, | ||
299 | + onShareAppMessage: function (res) { | ||
300 | + var that = this; | ||
301 | + | ||
302 | + | ||
303 | + // 来自页面内转发按钮 | ||
304 | + return { | ||
305 | + title: '分享', | ||
306 | + path: "/pages/card/card" | ||
307 | + | ||
308 | + } | ||
309 | + | ||
310 | + } | ||
311 | + } | ||
312 | +</script> | ||
313 | + | ||
314 | +<style> | ||
315 | + @import url("../../style/card"); | ||
316 | + @import url('../../style/cardDetail'); | ||
317 | +</style> |
pages/card/editorCard.vue
0 → 100644
1 | +<template> | ||
2 | + <view class="add_card" :class="{ over_hide: isHide }"> | ||
3 | + <!-- 名片信息 --> | ||
4 | + <view class="add_card_top"> | ||
5 | + <!-- 正反面 --> | ||
6 | + <view class="add_card_single"> | ||
7 | + <view class="card_front flex_center" @click="uploadPositive()"> | ||
8 | + <view class="show_img" v-if="front_image"><image :src="front_image" mode="aspectFill"></image></view> | ||
9 | + <view class="flex_center" v-else> | ||
10 | + <view class="card_upload"><image src="../../static/add.png" mode=""></image></view> | ||
11 | + <view class="card_tips">上传名片正面图片</view> | ||
12 | + </view> | ||
13 | + </view> | ||
14 | + <view class="card_front flex_center" @click="uploadSide()"> | ||
15 | + <view class="show_img" v-if="reverse_image"><image :src="reverse_image" mode="aspectFill"></image></view> | ||
16 | + <view class="flex_center" v-else> | ||
17 | + <view class="card_upload"><image src="../../static/add.png" mode=""></image></view> | ||
18 | + <view class="card_tips">上传名片背面图片</view> | ||
19 | + </view> | ||
20 | + </view> | ||
21 | + <view class="upload_tips">建议名片尺寸为360*210像素 </view> | ||
22 | + <view class="msg_single layer_between"> | ||
23 | + <view class="single_l">公司名称:</view> | ||
24 | + <input class="single_r" type="text" v-model="company_name" placeholder="请输入公司名称" /> | ||
25 | + </view> | ||
26 | + </view> | ||
27 | + <!-- 公司简介 --> | ||
28 | + <view class="add_card_single"> | ||
29 | + <view class="msg_single"> | ||
30 | + <view class="single_l">公司简介:</view> | ||
31 | + <textarea v-model="brief" placeholder="请输入公司简介" /> | ||
32 | + <view class="layer_nostar flex_wrap_no"> | ||
33 | + <view class="wx_code" v-for="(item, index) in brief_images" :key="index"> | ||
34 | + <image :src="item" mode=""></image> | ||
35 | + <image @click="deleteCompany(index)" class="cancle_icon" src="../../static/del_icon@2x.png" mode=""></image> | ||
36 | + </view> | ||
37 | + <view class="wx_code" @click="uploadCompay()"><image src="../../static/add_wx.png" mode=""></image></view> | ||
38 | + </view> | ||
39 | + </view> | ||
40 | + </view> | ||
41 | + <!-- 经营范围 --> | ||
42 | + <view class="add_card_single"> | ||
43 | + <view class="msg_single"> | ||
44 | + <view class="single_l">经营范围:</view> | ||
45 | + <textarea v-model="scope" placeholder="请输入经营范围" /> | ||
46 | + <view class="layer_nostar flex_wrap_no"> | ||
47 | + <view class="wx_code" v-for="(item, index) in scope_images" :key="index"> | ||
48 | + <image :src="item" mode=""></image> | ||
49 | + <image @click="deleteScope(index)" class="cancle_icon" src="../../static/del_icon@2x.png" mode=""></image> | ||
50 | + </view> | ||
51 | + <view class="wx_code" @click="uploadBusiness()"><image src="../../static/add_wx.png" mode=""></image></view> | ||
52 | + </view> | ||
53 | + </view> | ||
54 | + </view> | ||
55 | + <!-- 各种联系方式 --> | ||
56 | + <view class="add_card_single"> | ||
57 | + <view class="msg_single layer_between"> | ||
58 | + <view class="single_l">联系人:</view> | ||
59 | + <input class="single_r" type="text" v-model="name" placeholder="请输入联系人" /> | ||
60 | + </view> | ||
61 | + </view> | ||
62 | + <view class="add_card_single"> | ||
63 | + <view class="msg_single layer_between"> | ||
64 | + <view class="single_l">地址:</view> | ||
65 | + <input class="single_r" type="text" v-model="site" placeholder="请输入地址" /> | ||
66 | + </view> | ||
67 | + </view> | ||
68 | + <view class="add_card_single"> | ||
69 | + <view class="msg_single layer_between"> | ||
70 | + <view class="single_l">电话:</view> | ||
71 | + <input class="single_r" type="text" v-model="phone" placeholder="请输入电话" /> | ||
72 | + </view> | ||
73 | + </view> | ||
74 | + <view class="add_card_single"> | ||
75 | + <view class="msg_single layer_between"> | ||
76 | + <view class="single_l">传真:</view> | ||
77 | + <input class="single_r" type="text" v-model="fax" placeholder="请输入传真" /> | ||
78 | + </view> | ||
79 | + </view> | ||
80 | + <view class="add_card_single"> | ||
81 | + <view class="msg_single layer_between"> | ||
82 | + <view class="single_l">手机号:</view> | ||
83 | + <input class="single_r" maxlength="11" type="text" v-model="mobile" placeholder="请输入手机号" /> | ||
84 | + </view> | ||
85 | + </view> | ||
86 | + <view class="add_card_single"> | ||
87 | + <view class="msg_single layer_between"> | ||
88 | + <view class="single_l">QQ:</view> | ||
89 | + <input class="single_r" type="text" v-model="qq" placeholder="请输入QQ号" /> | ||
90 | + </view> | ||
91 | + </view> | ||
92 | + <view class="add_card_single"> | ||
93 | + <view class="msg_single layer_between"> | ||
94 | + <view class="single_l">微信:</view> | ||
95 | + <input class="single_r" type="text" v-model="wechat" placeholder="请输入微信" /> | ||
96 | + </view> | ||
97 | + </view> | ||
98 | + <view class="add_card_single"> | ||
99 | + <view class="msg_single"> | ||
100 | + <view class="single_l">微信二维码:</view> | ||
101 | + <view class="layer_nostar" @click="uploadCode()"> | ||
102 | + <view class="wx_img" v-if="weichat_image"><image :src="weichat_image" mode=""></image></view> | ||
103 | + <view class="wx_code" v-else><image src="../../static/add_wx.png" mode=""></image></view> | ||
104 | + </view> | ||
105 | + </view> | ||
106 | + </view> | ||
107 | + </view> | ||
108 | + <!-- 名片分类 --> | ||
109 | + <view class="add_card_classify"> | ||
110 | + <view class="classify_title"> | ||
111 | + 名片分类: | ||
112 | + <text>(可选择{{ category_num }}个名片分类)</text> | ||
113 | + </view> | ||
114 | + <view class="classify_tips">想要增加更多分类,请提交名片升级成VIP后到会员中心增加</view> | ||
115 | + <!-- 轴承列表 --> | ||
116 | + <view class="bearing_classify layer_nostar"> | ||
117 | + <!-- 左侧类目 --> | ||
118 | + <view class="bearing_l"> | ||
119 | + <view class="bear_l_box flex_column_center"> | ||
120 | + <view | ||
121 | + class="bear_l_single flex_warp" | ||
122 | + :class="{ bear_l_active: isLeft == item.id }" | ||
123 | + v-for="(item, index) in leftList" | ||
124 | + :key="index" | ||
125 | + @click="changeLeft(item, index)" | ||
126 | + > | ||
127 | + <view class="bear_l_child">{{ item.name }}</view> | ||
128 | + </view> | ||
129 | + </view> | ||
130 | + </view> | ||
131 | + <!-- 右侧具体分类 --> | ||
132 | + <view class="bearing_r"> | ||
133 | + <view class="bear_r_box"> | ||
134 | + <view class="bear_r_single" :class="{ bear_r_active: item.isChoice }" v-for="(item, index) in rightList" :key="index" @click="changeRight(item, index)"> | ||
135 | + {{ item.name }} | ||
136 | + </view> | ||
137 | + </view> | ||
138 | + </view> | ||
139 | + </view> | ||
140 | + </view> | ||
141 | + <!-- 提交名片 --> | ||
142 | + <view class="submit_btn" @click="submitCard()">提交名片</view> | ||
143 | + <!-- 提交弹窗 --> | ||
144 | + <view class="tx_mask" v-if="isHide" @click="closeDialog()"></view> | ||
145 | + <view class="mask_content" v-if="isHide"> | ||
146 | + <view class="mask_top">成为VIP会员,其他用户可以搜索到您的名片</view> | ||
147 | + <view class="mask_bottom" @click="getNow()">立即获取</view> | ||
148 | + </view> | ||
149 | + </view> | ||
150 | +</template> | ||
151 | + | ||
152 | +<script> | ||
153 | +import App from '../../App.vue'; | ||
154 | +export default { | ||
155 | + data() { | ||
156 | + return { | ||
157 | + front_image: '', //正面图片 | ||
158 | + reverse_image: '', //反面图片 | ||
159 | + company_name: '', //公司名称 | ||
160 | + brief: '', //公司简介 | ||
161 | + brief_images: [], //公司简介图片 | ||
162 | + scope: '', //经营范围 | ||
163 | + scope_images: [], //经营范围图片 | ||
164 | + name: '', //联系人 | ||
165 | + phone: '', //电话 | ||
166 | + site: '', //地址 | ||
167 | + mobile: '', //手机号 | ||
168 | + fax: '', //传真 | ||
169 | + qq: '', // QQ | ||
170 | + wechat: '', //微信 | ||
171 | + weichat_image: '', //微信二维码 | ||
172 | + category_ids: [], //分类ID | ||
173 | + category_num: '', //可选分类个数 | ||
174 | + // 轴承列表 | ||
175 | + // 左侧 | ||
176 | + leftList: [], | ||
177 | + isLeft: 0, | ||
178 | + // 右侧 | ||
179 | + rightList: [], | ||
180 | + isRight: 0, | ||
181 | + // 弹窗 | ||
182 | + isHide: false, | ||
183 | + // 是否为vip 1:是 2:否 | ||
184 | + isVip: '', | ||
185 | + file: '', | ||
186 | + // 防连点 | ||
187 | + isClick: false, | ||
188 | + imgBrief: [], //公司简介上传数量 | ||
189 | + imgScope: [] | ||
190 | + }; | ||
191 | + }, | ||
192 | + methods: { | ||
193 | + // 上传正面图片 | ||
194 | + uploadPositive() { | ||
195 | + let t = this; | ||
196 | + uni.chooseImage({ | ||
197 | + count: 1, //默认9 | ||
198 | + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 | ||
199 | + sourceType: ['album'], //从相册选择 | ||
200 | + success: chooseImageRes => { | ||
201 | + const tempFilePaths = chooseImageRes.tempFilePaths; | ||
202 | + App.upload(tempFilePaths[0]).then(res => { | ||
203 | + this.front_image = res.url; | ||
204 | + }); | ||
205 | + } | ||
206 | + }); | ||
207 | + }, | ||
208 | + // 上传反面图片 | ||
209 | + uploadSide() { | ||
210 | + let t = this; | ||
211 | + uni.chooseImage({ | ||
212 | + count: 1, //默认9 | ||
213 | + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 | ||
214 | + sourceType: ['album'], //从相册选择 | ||
215 | + success: chooseImageRes => { | ||
216 | + const tempFilePaths = chooseImageRes.tempFilePaths; | ||
217 | + t.file = tempFilePaths; | ||
218 | + App.upload(tempFilePaths[0]).then(res => { | ||
219 | + this.reverse_image = res.url; | ||
220 | + }); | ||
221 | + } | ||
222 | + }); | ||
223 | + }, | ||
224 | + // 上传公司简介图片 | ||
225 | + uploadCompay() { | ||
226 | + let t = this; | ||
227 | + uni.chooseImage({ | ||
228 | + count: 3, //默认9 | ||
229 | + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 | ||
230 | + sourceType: ['album'], //从相册选择 | ||
231 | + success: chooseImageRes => { | ||
232 | + const tempFilePaths = chooseImageRes.tempFilePaths; | ||
233 | + t.imgBrief = [...t.imgBrief,...tempFilePaths] | ||
234 | + if(t.imgBrief.length>3){ | ||
235 | + uni.showToast({ | ||
236 | + title: '图片总数超过3张', | ||
237 | + icon: 'none' | ||
238 | + }); | ||
239 | + tempFilePaths.forEach(el=>{ | ||
240 | + t.imgBrief.forEach((ele,i)=>{ | ||
241 | + if(el == ele){ | ||
242 | + t.imgBrief.splice(i,1) | ||
243 | + } | ||
244 | + }) | ||
245 | + }) | ||
246 | + return false; | ||
247 | + } | ||
248 | + tempFilePaths.forEach(el => { | ||
249 | + App.upload(el).then(res => { | ||
250 | + t.brief_images.push(res.url); | ||
251 | + }); | ||
252 | + }); | ||
253 | + } | ||
254 | + }); | ||
255 | + }, | ||
256 | + | ||
257 | + // 上传经营范围图片 | ||
258 | + uploadBusiness() { | ||
259 | + let t = this; | ||
260 | + uni.chooseImage({ | ||
261 | + count: 3, //默认9 | ||
262 | + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 | ||
263 | + sourceType: ['album'], //从相册选择 | ||
264 | + success: chooseImageRes => { | ||
265 | + const tempFilePaths = chooseImageRes.tempFilePaths; | ||
266 | + t.imgScope = [...t.imgScope, ...tempFilePaths]; | ||
267 | + if (t.imgScope.length > 3) { | ||
268 | + uni.showToast({ | ||
269 | + title: '图片总数超过3张', | ||
270 | + icon: 'none' | ||
271 | + }); | ||
272 | + tempFilePaths.forEach(el=>{ | ||
273 | + t.imgScope.forEach((ele,i)=>{ | ||
274 | + if(el == ele){ | ||
275 | + t.imgScope.splice(i,1) | ||
276 | + } | ||
277 | + }) | ||
278 | + }) | ||
279 | + return false; | ||
280 | + } | ||
281 | + | ||
282 | + tempFilePaths.forEach(el => { | ||
283 | + App.upload(el).then(res => { | ||
284 | + t.scope_images.push(res.url); | ||
285 | + }); | ||
286 | + }); | ||
287 | + } | ||
288 | + }); | ||
289 | + }, | ||
290 | + // 删除公司简介图片 | ||
291 | + deleteCompany(index) { | ||
292 | + | ||
293 | + this.imgBrief.splice(index, 1); | ||
294 | + this.brief_images.splice(index, 1); | ||
295 | + console.log(this.imgBrief,this.brief_images) | ||
296 | + }, | ||
297 | + // 删除经营范围图片 | ||
298 | + deleteScope(index) { | ||
299 | + this.imgScope.splice(index, 1); | ||
300 | + this.scope_images.splice(index, 1); | ||
301 | + }, | ||
302 | + // 上传二维码 | ||
303 | + uploadCode() { | ||
304 | + let t = this; | ||
305 | + uni.chooseImage({ | ||
306 | + count: 1, //默认9 | ||
307 | + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 | ||
308 | + sourceType: ['album'], //从相册选择 | ||
309 | + success: chooseImageRes => { | ||
310 | + const tempFilePaths = chooseImageRes.tempFilePaths; | ||
311 | + App.upload(tempFilePaths[0]).then(res => { | ||
312 | + this.weichat_image = res.url; | ||
313 | + }); | ||
314 | + } | ||
315 | + }); | ||
316 | + }, | ||
317 | + // 首页分类数据 左侧一级分类 | ||
318 | + getType() { | ||
319 | + let t = this; | ||
320 | + t.leftList = []; | ||
321 | + t.rightList = []; | ||
322 | + let url = '/api/category/get_category_one'; | ||
323 | + App.post(url).then(res => { | ||
324 | + t.leftList = res; | ||
325 | + t.rightList.forEach(el => { | ||
326 | + el.isChoice = false; | ||
327 | + }); | ||
328 | + res.forEach(el => { | ||
329 | + // 找出已选择的二级分类 | ||
330 | + el.children.forEach(ele => { | ||
331 | + t.category_ids.forEach(eleId => { | ||
332 | + // 根据后台返回的分类id找到对应的分类 | ||
333 | + if (eleId == ele.id) { | ||
334 | + ele.isChoice = true; | ||
335 | + // 一级分类 | ||
336 | + t.isLeft = el.id; | ||
337 | + // 二级分类 | ||
338 | + t.rightList = el.children; | ||
339 | + } | ||
340 | + }); | ||
341 | + }); | ||
342 | + }); | ||
343 | + }); | ||
344 | + }, | ||
345 | + // 左侧列表选中 | ||
346 | + changeLeft(item, index) { | ||
347 | + this.isLeft = item.id; | ||
348 | + this.rightList = item.children; | ||
349 | + }, | ||
350 | + // 右侧列表选中 | ||
351 | + changeRight(item, index) { | ||
352 | + this.category_ids = []; | ||
353 | + let arr = []; | ||
354 | + item.isChoice = !item.isChoice; | ||
355 | + this.leftList.forEach(lel => { | ||
356 | + // 找出已选择的二级分类 | ||
357 | + lel.children.forEach(rel => { | ||
358 | + if (rel.isChoice == true) { | ||
359 | + arr.push(rel); | ||
360 | + } | ||
361 | + }); | ||
362 | + }); | ||
363 | + // 根据后台返回的可选择类型数量选择 | ||
364 | + if (arr.length > this.category_num) { | ||
365 | + // 删除超出可选数量的最后一位 | ||
366 | + let end = arr.pop(); | ||
367 | + end.isChoice = false; | ||
368 | + uni.showToast({ | ||
369 | + title: '已超出可选分类数量', | ||
370 | + icon: 'none' | ||
371 | + }); | ||
372 | + return false; | ||
373 | + } | ||
374 | + arr.forEach(el => { | ||
375 | + this.category_ids.push(el.id); | ||
376 | + }); | ||
377 | + // 去重 | ||
378 | + this.category_ids = [...new Set(this.category_ids)]; | ||
379 | + // 回显选中的分类 | ||
380 | + this.$forceUpdate(); | ||
381 | + }, | ||
382 | + // 提交名片 | ||
383 | + submitCard() { | ||
384 | + if (!this.isClick) { | ||
385 | + let t = this; | ||
386 | + | ||
387 | + t.isClick = true; | ||
388 | + let url = '/api/goods/publish_card'; | ||
389 | + let briefArr = ''; | ||
390 | + if (t.brief_images) { | ||
391 | + briefArr = t.brief_images.toString(); | ||
392 | + } | ||
393 | + let scopeArr = ''; | ||
394 | + if (t.scope_images) { | ||
395 | + scopeArr = t.scope_images.toString(); | ||
396 | + } | ||
397 | + let cateArr = ''; | ||
398 | + if (t.category_ids) { | ||
399 | + cateArr = t.category_ids.toString(); | ||
400 | + } | ||
401 | + let params = { | ||
402 | + front_image: t.front_image, | ||
403 | + reverse_image: t.reverse_image, | ||
404 | + company_name: t.company_name, | ||
405 | + brief: t.brief, | ||
406 | + brief_images: briefArr, | ||
407 | + scope: t.scope, | ||
408 | + scope_images: scopeArr, | ||
409 | + name: t.name, | ||
410 | + phone: t.phone, | ||
411 | + site: t.site, | ||
412 | + mobile: t.mobile, | ||
413 | + fax: t.fax, | ||
414 | + qq: t.qq, | ||
415 | + wechat: t.wechat, | ||
416 | + wechat_image: t.weichat_image, | ||
417 | + category_ids: cateArr | ||
418 | + }; | ||
419 | + if (t.front_image) { | ||
420 | + if (t.company_name) { | ||
421 | + if (t.brief) { | ||
422 | + if (t.scope) { | ||
423 | + if (t.name) { | ||
424 | + App.post(url, params).then(res => { | ||
425 | + uni.showToast({ | ||
426 | + title: '编辑成功', | ||
427 | + icon: 'success', | ||
428 | + duration: 1000 | ||
429 | + }); | ||
430 | + setTimeout(function() { | ||
431 | + if (t.isVip == 2) { | ||
432 | + t.isHide = true; | ||
433 | + } else { | ||
434 | + uni.navigateBack({ | ||
435 | + delta: 1 | ||
436 | + }); | ||
437 | + } | ||
438 | + t.isClick = false; | ||
439 | + }, 1000); | ||
440 | + }); | ||
441 | + } else { | ||
442 | + uni.showToast({ | ||
443 | + title: '请输入联系人姓名', | ||
444 | + icon: 'none' | ||
445 | + }); | ||
446 | + t.isClick = false; | ||
447 | + } | ||
448 | + } else { | ||
449 | + uni.showToast({ | ||
450 | + title: '请输入经营范围', | ||
451 | + icon: 'none' | ||
452 | + }); | ||
453 | + t.isClick = false; | ||
454 | + } | ||
455 | + } else { | ||
456 | + uni.showToast({ | ||
457 | + title: '请输入公司简介', | ||
458 | + icon: 'none' | ||
459 | + }); | ||
460 | + t.isClick = false; | ||
461 | + } | ||
462 | + } else { | ||
463 | + uni.showToast({ | ||
464 | + title: '请填写公司名称', | ||
465 | + icon: 'none' | ||
466 | + }); | ||
467 | + t.isClick = false; | ||
468 | + } | ||
469 | + } else { | ||
470 | + uni.showToast({ | ||
471 | + title: '请上传正面图片', | ||
472 | + icon: 'none' | ||
473 | + }); | ||
474 | + t.isClick = false; | ||
475 | + } | ||
476 | + } | ||
477 | + }, | ||
478 | + // 关闭弹窗 | ||
479 | + closeDialog() { | ||
480 | + uni.navigateBack({ | ||
481 | + delta: 1 | ||
482 | + }); | ||
483 | + }, | ||
484 | + // 立即获取vip | ||
485 | + getNow() { | ||
486 | + uni.redirectTo({ | ||
487 | + url: '/pages/vip/myVip' | ||
488 | + }); | ||
489 | + }, | ||
490 | + // 获取我的名片详情 | ||
491 | + getMyCard() { | ||
492 | + let t = this; | ||
493 | + let url = '/api/goods/my_goods'; | ||
494 | + App.post(url).then(res => { | ||
495 | + t.getType(); | ||
496 | + t.front_image = res.front_image; | ||
497 | + t.reverse_image = res.reverse_image; | ||
498 | + t.company_name = res.company_name; | ||
499 | + t.brief = res.brief; | ||
500 | + if (res.brief_images) { | ||
501 | + t.imgBrief = res.brief_images; | ||
502 | + t.brief_images = res.brief_images; | ||
503 | + } | ||
504 | + t.scope = res.scope; | ||
505 | + if (res.scope_images) { | ||
506 | + t.imgScope = res.scope_images; | ||
507 | + t.scope_images = res.scope_images; | ||
508 | + } | ||
509 | + t.name = res.name; | ||
510 | + t.phone = res.phone; | ||
511 | + t.site = res.site; | ||
512 | + t.mobile = res.mobile; | ||
513 | + t.fax = res.fax; | ||
514 | + t.qq = res.qq; | ||
515 | + t.wechat = res.wechat; | ||
516 | + t.weichat_image = res.wechat_image; | ||
517 | + res.category_ids.forEach(el => { | ||
518 | + if (el) { | ||
519 | + t.category_ids.push(el); | ||
520 | + } | ||
521 | + }); | ||
522 | + }); | ||
523 | + } | ||
524 | + }, | ||
525 | + onLoad() { | ||
526 | + | ||
527 | + // 获取我的名片详情 | ||
528 | + this.getMyCard(); | ||
529 | + }, | ||
530 | + onShow() { | ||
531 | + this.category_num = uni.getStorageSync('category_num'); | ||
532 | + | ||
533 | + } | ||
534 | +}; | ||
535 | +</script> | ||
536 | + | ||
537 | +<style> | ||
538 | +@import url('../../style/addCard'); | ||
539 | +</style> |
pages/collect/collect.vue
0 → 100644
1 | +<template> | ||
2 | + <view class="content"> | ||
3 | + <!-- 轴承列表 --> | ||
4 | + <view class="bearing_classify layer_nostar"> | ||
5 | + <!-- 左侧类目 --> | ||
6 | + <view class="bearing_l"> | ||
7 | + <view class="bear_l_box flex_column_center"> | ||
8 | + <view class="bear_l_single flex_warp" :class="{ bear_l_active: isLeft == item.id }" v-for="(item, index) in leftList" :key="index" @click="changeLeft(item,index)"> | ||
9 | + <view class="bear_l_child">{{ item.name }}</view> | ||
10 | + </view> | ||
11 | + </view> | ||
12 | + </view> | ||
13 | + <!-- 右侧具体分类 --> | ||
14 | + <view class="bearing_r"> | ||
15 | + <view class="bear_r_box"> | ||
16 | + <view class="bear_r_single" :class="{bear_r_active:isRight == item.id}" v-for="(item, index) in rightList" :key="index" @click="changeRight(item,index)">{{ item.name }}</view> | ||
17 | + </view> | ||
18 | + </view> | ||
19 | + </view> | ||
20 | + <!-- 收藏名片 --> | ||
21 | + <view class="hot_search"> | ||
22 | + <!-- 名片列表 --> | ||
23 | + <view class="hot_card_wrap flex_wrap_between" v-if="cardList.length>0"> | ||
24 | + <view class="card_single" v-for="(item,index) in cardList" :key="index" @click="toDetail(item)"> | ||
25 | + <image :src="item.front_image" mode=""></image> | ||
26 | + </view> | ||
27 | + </view> | ||
28 | + <!-- 暂无名片 --> | ||
29 | + <view class="hot_card_wrap" v-else>暂无收藏</view> | ||
30 | + <!-- 分页 --> | ||
31 | + <view class="card_pagation layer_between"> | ||
32 | + <view class="prev_page" :class="{next_page:pageNum>1}" @click="prevPage()">上一页</view> | ||
33 | + <view class="layer_between jump_page"> | ||
34 | + 跳转到 | ||
35 | + <input type="text" @confirm="jumpPage()" v-model="pageNum" /> | ||
36 | + 页 | ||
37 | + </view> | ||
38 | + <view class="next_page" :class="{prev:pageNum >= totalPage}" @click="nextPage()">下一页</view> | ||
39 | + <view class="total_page">共{{totalPage}}页</view> | ||
40 | + </view> | ||
41 | + </view> | ||
42 | + </view> | ||
43 | +</template> | ||
44 | + | ||
45 | +<script> | ||
46 | + import App from "../../App.vue"; | ||
47 | +export default { | ||
48 | + data() { | ||
49 | + return { | ||
50 | + // 搜索 | ||
51 | + keyword:"", | ||
52 | + // 轮播图 | ||
53 | + swiperList:[], | ||
54 | + // 轴承列表 | ||
55 | + // 左侧 | ||
56 | + leftList: [], | ||
57 | + isLeft: 0, | ||
58 | + // 右侧 | ||
59 | + rightList: [], | ||
60 | + isRight: "", | ||
61 | + // 名片列表 | ||
62 | + cardList:[], | ||
63 | + // 分页 | ||
64 | + pageNum:1, | ||
65 | + // 总页数 | ||
66 | + totalPage:"", | ||
67 | + }; | ||
68 | + }, | ||
69 | + | ||
70 | + methods: { | ||
71 | + // 轮播图 | ||
72 | + getSwiper(){ | ||
73 | + let t = this; | ||
74 | + let url = "/api/slide/get_slide"; | ||
75 | + App.post(url) | ||
76 | + .then(res=>{ | ||
77 | + this.swiperList = res.data; | ||
78 | + }) | ||
79 | + }, | ||
80 | + // 首页分类数据 左侧一级分类 | ||
81 | + getType(){ | ||
82 | + let t = this; | ||
83 | + t.leftList = []; | ||
84 | + t.rightList = []; | ||
85 | + let url = "/api/collect/get_category_one"; | ||
86 | + App.post(url) | ||
87 | + .then(res=>{ | ||
88 | + t.leftList = res; | ||
89 | + t.rightList = res[0].children; | ||
90 | + t.isLeft = res[0].id; | ||
91 | + }) | ||
92 | + }, | ||
93 | + // 左侧列表选中 | ||
94 | + changeLeft(item,index) { | ||
95 | + this.isLeft = item.id; | ||
96 | + this.rightList = item.children; | ||
97 | + | ||
98 | + }, | ||
99 | + // 右侧列表选中 | ||
100 | + changeRight(item,index){ | ||
101 | + this.isRight = item.id; | ||
102 | + this.getCardList(); | ||
103 | + }, | ||
104 | + // 获取收藏列表 | ||
105 | + getCardList(){ | ||
106 | + let t = this; | ||
107 | + let url = "/api/collect/collect_list"; | ||
108 | + let params = { | ||
109 | + category_id:t.isRight, | ||
110 | + page:t.pageNum | ||
111 | + }; | ||
112 | + App.post(url,params) | ||
113 | + .then(res=>{ | ||
114 | + t.totalPage = res.page_sum; | ||
115 | + t.cardList = res.list; | ||
116 | + }) | ||
117 | + }, | ||
118 | + // 名片详情 | ||
119 | + toDetail(item){ | ||
120 | + uni.navigateTo({ | ||
121 | + url:"/pages/index/cardDetail?id="+item.id | ||
122 | + }) | ||
123 | + }, | ||
124 | + // 搜索 去名片列表 | ||
125 | + toSearch(){ | ||
126 | + uni.navigateTo({ | ||
127 | + url:"/pages/index/search?keyword="+this.keyword | ||
128 | + }) | ||
129 | + }, | ||
130 | + // 上一页 | ||
131 | + prevPage(){ | ||
132 | + if(this.pageNum <=1 ) | ||
133 | + return false; | ||
134 | + this.pageNum --; | ||
135 | + this.getCardList() | ||
136 | + }, | ||
137 | + // 下一页 | ||
138 | + nextPage(){ | ||
139 | + if(this.pageNum == this.totalPage){ | ||
140 | + return false | ||
141 | + } | ||
142 | + this.pageNum ++; | ||
143 | + this.getCardList() | ||
144 | + }, | ||
145 | + // 跳转到某一页 | ||
146 | + jumpPage(){ | ||
147 | + if(this.pageNum>this.totalPage) | ||
148 | + this.pageNum = this.totalPage; | ||
149 | + this.getCardList() | ||
150 | + }, | ||
151 | + }, | ||
152 | + onLoad() { | ||
153 | + | ||
154 | + }, | ||
155 | + onShow() { | ||
156 | + // 首页分类数据 | ||
157 | + this.getType(); | ||
158 | + // 名片列表数据 | ||
159 | + this.getCardList(); | ||
160 | + }, | ||
161 | + | ||
162 | +}; | ||
163 | +</script> | ||
164 | + | ||
165 | +<style> | ||
166 | +@import url('../../style/index'); | ||
167 | +.hot_card_wrap{ | ||
168 | + border-top: none; | ||
169 | + text-align: center; | ||
170 | +} | ||
171 | +.bearing_classify{ | ||
172 | + border-top: 1upx solid #eee; | ||
173 | +} | ||
174 | +</style> |
pages/index/cardDetail.vue
0 → 100644
1 | +<template> | ||
2 | + <view class="content"> | ||
3 | + <view class="detail_top"> | ||
4 | + <!-- 公司名称 --> | ||
5 | + <view class="company_name">{{ cardDetail.company_name }}</view> | ||
6 | + <!-- 名片正反面 --> | ||
7 | + <view> | ||
8 | + <image class="card_pic" :src="cardDetail.front_image" mode=""></image> | ||
9 | + <view class="card_tips">名片正面</view> | ||
10 | + </view> | ||
11 | + <view> | ||
12 | + <image class="card_pic" :src="cardDetail.reverse_image" mode=""></image> | ||
13 | + <view class="card_tips">名片反面</view> | ||
14 | + </view> | ||
15 | + </view> | ||
16 | + <!-- 公司简介 --> | ||
17 | + <view class="company_intro"> | ||
18 | + <view class="company_title_wrap"><view class="company_title">公司简介</view></view> | ||
19 | + <view class="company_detail"> | ||
20 | + <view class="company_detail_box"> | ||
21 | + <view class="">{{ cardDetail.brief }}</view> | ||
22 | + <view class="company_pic_wrap flex_wrap_no"> | ||
23 | + <view class="company_pic_single" @click="showImg(item)" v-for="(item, index) in cardDetail.brief_images" :key="index"><image :src="item" mode=""></image></view> | ||
24 | + </view> | ||
25 | + </view> | ||
26 | + </view> | ||
27 | + </view> | ||
28 | + <!-- 经营范围 --> | ||
29 | + <view class="company_intro"> | ||
30 | + <view class="company_title_wrap"><view class="company_title">经营范围</view></view> | ||
31 | + <view class="company_detail"> | ||
32 | + <view class="company_detail_box"> | ||
33 | + <view class="">{{ cardDetail.scope }}</view> | ||
34 | + <view class="company_pic_wrap flex_wrap_no"> | ||
35 | + <view class="company_pic_single" @click="showImg(item)" v-for="(item, index) in cardDetail.scope_images" :key="index"><image :src="item" mode=""></image></view> | ||
36 | + </view> | ||
37 | + </view> | ||
38 | + </view> | ||
39 | + </view> | ||
40 | + <!-- 联系方式 --> | ||
41 | + <view class="company_intro"> | ||
42 | + <view class="company_title_wrap"><view class="company_title">联系方式</view></view> | ||
43 | + <!-- 地址 --> | ||
44 | + <view class="contact_code"> | ||
45 | + <view class="layer_nobetween"> | ||
46 | + <!-- 二维码 --> | ||
47 | + <view class="qr_code" @click="showImg(cardDetail.wechat_image)"><image :src="cardDetail.wechat_image" mode=""></image></view> | ||
48 | + <!-- 姓名 地址 --> | ||
49 | + <view class="contact_r flex_star_between"> | ||
50 | + <view class="">联系人:{{ cardDetail.name }}</view> | ||
51 | + <view class="" v-if="cardDetail.phone">电话:{{ cardDetail.phone }}</view> | ||
52 | + <view class="" v-if="cardDetail.site">地址:{{ cardDetail.site }}</view> | ||
53 | + </view> | ||
54 | + </view> | ||
55 | + </view> | ||
56 | + <!-- 各种联系方式 --> | ||
57 | + <view class="contact_single layer_between" v-if="cardDetail.fax"> | ||
58 | + <view class="layer_between"> | ||
59 | + <image class="contact_icon" src="../../static/phone.png" mode=""></image> | ||
60 | + 传真 | ||
61 | + </view> | ||
62 | + <view class="" @click="copyFax()">{{ cardDetail.fax }}</view> | ||
63 | + </view> | ||
64 | + <view class="contact_single layer_between" v-if="cardDetail.mobile"> | ||
65 | + <view class="layer_between"> | ||
66 | + <image class="contact_icon" src="../../static/tel.png" mode=""></image> | ||
67 | + 手机号 | ||
68 | + </view> | ||
69 | + <view class="" @click="callUp()">{{ cardDetail.mobile }}</view> | ||
70 | + </view> | ||
71 | + <view class="contact_single layer_between" v-if="cardDetail.qq"> | ||
72 | + <view class="layer_between"> | ||
73 | + <image class="contact_icon" src="../../static/qq.png" mode=""></image> | ||
74 | |||
75 | + </view> | ||
76 | + <view class="" @click="copyQQ()">{{ cardDetail.qq }}</view> | ||
77 | + </view> | ||
78 | + <view class="contact_single no_bottom layer_between" v-if="cardDetail.wechat"> | ||
79 | + <view class="layer_between"> | ||
80 | + <image class="contact_icon" src="../../static/weixin.png" mode=""></image> | ||
81 | + 微信 | ||
82 | + </view> | ||
83 | + <view class="" @click="copyWx()">{{ cardDetail.wechat }}</view> | ||
84 | + </view> | ||
85 | + </view> | ||
86 | + <!-- 图片放大 --> | ||
87 | + <view class="tx_mask" v-if="isShowImg" @click="closDialog()"></view> | ||
88 | + <view class="mask_content" v-if="isShowImg" @click="closDialog()" @longpress="saveImg()"> | ||
89 | + <image :src="img" mode="widthFix"></image> | ||
90 | + </view> | ||
91 | + <!-- 收藏按钮 --> | ||
92 | + <view class="collect_btn" @click="collectCard()">{{cardDetail.is_collect == 1?"取消收藏":"收藏名片"}}</view> | ||
93 | + </view> | ||
94 | +</template> | ||
95 | + | ||
96 | +<script> | ||
97 | +import App from '../../App.vue'; | ||
98 | +export default { | ||
99 | + data() { | ||
100 | + return { | ||
101 | + id: '', | ||
102 | + imgList: [], | ||
103 | + cardDetail: '', | ||
104 | + token: '', | ||
105 | + // 图片放大 | ||
106 | + isShowImg:false, | ||
107 | + img:"", | ||
108 | + }; | ||
109 | + }, | ||
110 | + methods: { | ||
111 | + // 图片放大 | ||
112 | + showImg(img){ | ||
113 | + | ||
114 | + this.isShowImg = true | ||
115 | + this.img = img; | ||
116 | + | ||
117 | + }, | ||
118 | + saveImg(){ | ||
119 | + let t = this ; | ||
120 | + uni.downloadFile({ | ||
121 | + url: t.img, | ||
122 | + success: function(res) { | ||
123 | + uni.saveImageToPhotosAlbum({ | ||
124 | + filePath: res.tempFilePath, | ||
125 | + success: function() { | ||
126 | + uni.showToast({ | ||
127 | + title: '保存成功', | ||
128 | + icon: 'none', | ||
129 | + duration: 1500 | ||
130 | + }); | ||
131 | + t.isShowImg = false | ||
132 | + }, | ||
133 | + fail: function(err) { | ||
134 | + if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg === | ||
135 | + "saveImageToPhotosAlbum:fail:auth denied") { | ||
136 | + uni.showToast({ | ||
137 | + title: '需要您授权保存相册', | ||
138 | + icon:none, | ||
139 | + duration: 1500, | ||
140 | + success: modalSuccess => { | ||
141 | + uni.openSetting({ | ||
142 | + success(settingdata) { | ||
143 | + if (settingdata.authSetting['scope.writePhotosAlbum']) { | ||
144 | + uni.showToast({ | ||
145 | + title: '获取权限成功', | ||
146 | + icon: 'none', | ||
147 | + duration: 1500 | ||
148 | + }); | ||
149 | + } else { | ||
150 | + uni.showToast({ | ||
151 | + title: '获取权限失败', | ||
152 | + icon: 'none', | ||
153 | + duration: 1500 | ||
154 | + }); | ||
155 | + } | ||
156 | + }, | ||
157 | + fail(failData) { | ||
158 | + console.log("failData", failData) | ||
159 | + }, | ||
160 | + complete(finishData) { | ||
161 | + console.log("finishData", finishData) | ||
162 | + } | ||
163 | + }) | ||
164 | + } | ||
165 | + }) | ||
166 | + } | ||
167 | + }, | ||
168 | + }); | ||
169 | + } | ||
170 | + }); | ||
171 | + }, | ||
172 | + closDialog(){ | ||
173 | + this.isShowImg = false | ||
174 | + }, | ||
175 | + // 名片详情 | ||
176 | + getCarDetail() { | ||
177 | + let t = this; | ||
178 | + let url = '/api/goods/goods_detail'; | ||
179 | + let params = { | ||
180 | + goods_id: this.id | ||
181 | + }; | ||
182 | + App.post(url, params).then(res => { | ||
183 | + this.cardDetail = res; | ||
184 | + }); | ||
185 | + }, | ||
186 | + // 复制传真 | ||
187 | + copyFax() { | ||
188 | + uni.setClipboardData({ | ||
189 | + data: this.cardDetail.fax, | ||
190 | + success: function() { | ||
191 | + uni.showToast({ | ||
192 | + title: '复制成功', | ||
193 | + icon: 'success' | ||
194 | + }); | ||
195 | + } | ||
196 | + }); | ||
197 | + }, | ||
198 | + // 复制qq | ||
199 | + copyQQ() { | ||
200 | + uni.setClipboardData({ | ||
201 | + data: this.cardDetail.qq, | ||
202 | + success: function() { | ||
203 | + uni.showToast({ | ||
204 | + title: '复制成功', | ||
205 | + icon: 'success' | ||
206 | + }); | ||
207 | + } | ||
208 | + }); | ||
209 | + }, | ||
210 | + // 复制微信 | ||
211 | + copyWx() { | ||
212 | + uni.setClipboardData({ | ||
213 | + data: this.cardDetail.wechat, | ||
214 | + success: function() { | ||
215 | + uni.showToast({ | ||
216 | + title: '复制成功', | ||
217 | + icon: 'success' | ||
218 | + }); | ||
219 | + } | ||
220 | + }); | ||
221 | + }, | ||
222 | + // 拨打电话 | ||
223 | + callUp() { | ||
224 | + uni.makePhoneCall({ | ||
225 | + phoneNumber: this.cardDetail.mobile | ||
226 | + }); | ||
227 | + }, | ||
228 | + // 收藏名片 | ||
229 | + collectCard() { | ||
230 | + if (this.token) { | ||
231 | + let url = '/api/collect/collect'; | ||
232 | + let params = { | ||
233 | + goods_id:this.id | ||
234 | + }; | ||
235 | + App.post(url,params) | ||
236 | + .then(res=>{ | ||
237 | + uni.showToast({ | ||
238 | + title:'操作成功', | ||
239 | + icon:'success', | ||
240 | + duration:1500 | ||
241 | + }) | ||
242 | + setTimeout(function(){ | ||
243 | + uni.navigateBack({ | ||
244 | + delta:1 | ||
245 | + }) | ||
246 | + },1500) | ||
247 | + | ||
248 | + }) | ||
249 | + } else { | ||
250 | + uni.navigateTo({ | ||
251 | + url: '/pages/start/start' | ||
252 | + }); | ||
253 | + } | ||
254 | + } | ||
255 | + }, | ||
256 | + onLoad(option) { | ||
257 | + this.token = uni.getStorageSync('token'); | ||
258 | + this.id = option.id; | ||
259 | + // 获取名片详情 | ||
260 | + this.getCarDetail(); | ||
261 | + }, | ||
262 | + | ||
263 | + onShareAppMessage: function (res) { | ||
264 | + var that = this; | ||
265 | + | ||
266 | + | ||
267 | + // 来自页面内转发按钮 | ||
268 | + return { | ||
269 | + title: '分享', | ||
270 | + path: "/pages/index/cardDetail?id="+that.id | ||
271 | + | ||
272 | + } | ||
273 | + | ||
274 | + } | ||
275 | + | ||
276 | +}; | ||
277 | +</script> | ||
278 | + | ||
279 | +<style> | ||
280 | +@import url('../../style/cardDetail'); | ||
281 | +</style> |
pages/index/cardList.vue
0 → 100644
1 | +<template> | ||
2 | + <view class="content"> | ||
3 | + <!-- 顶部搜索 --> | ||
4 | + <view class="search_wrap layer_between"> | ||
5 | + <view class="search_input"> | ||
6 | + <input type="text" @confirm="toSearch()" v-model="keyword" placeholder="请输入名称、型号、品牌、厂家搜索" /> | ||
7 | + <image class="search_icon" src="../../static/search.png" mode=""></image> | ||
8 | + </view> | ||
9 | + <view class="search_word" @click="toSearch()">搜索</view> | ||
10 | + </view> | ||
11 | + <!-- 轴承列表 --> | ||
12 | + <view class="bearing_classify layer_nostar"> | ||
13 | + <!-- 左侧类目 --> | ||
14 | + <view class="bearing_l"> | ||
15 | + <view class="bear_l_box flex_column_center"> | ||
16 | + <view class="bear_l_single flex_warp" :class="{ bear_l_active: isLeft == item.id }" v-for="(item, index) in leftList" :key="index" @click="changeLeft(item,index)"> | ||
17 | + <view class="bear_l_child">{{ item.name }}</view> | ||
18 | + </view> | ||
19 | + </view> | ||
20 | + </view> | ||
21 | + <!-- 右侧具体分类 --> | ||
22 | + <view class="bearing_r"> | ||
23 | + <view class="bear_r_box"> | ||
24 | + <view class="bear_r_single" :class="{bear_r_active:isRight == item.id}" v-for="(item, index) in rightList" :key="index" @click="changeRight(item,index)">{{ item.name }}</view> | ||
25 | + </view> | ||
26 | + </view> | ||
27 | + </view> | ||
28 | + <!-- 热搜名片 --> | ||
29 | + <view class="hot_search"> | ||
30 | + <!-- 名片 --> | ||
31 | + <view class="hot_card_wrap flex_wrap_between"> | ||
32 | + <view class="card_single" v-for="(item,index) in cardList" :key="index" @click="toDetail(item)"> | ||
33 | + <image :src="item.front_image" mode=""></image> | ||
34 | + </view> | ||
35 | + </view> | ||
36 | + <!-- 分页 --> | ||
37 | + <view class="card_pagation layer_between"> | ||
38 | + <view class="prev_page" :class="{next_page:pageNum>1}" @click="prevPage()">上一页</view> | ||
39 | + <view class="layer_between jump_page"> | ||
40 | + 跳转到 | ||
41 | + <input type="text" @confirm="jumpPage()" v-model="pageNum" /> | ||
42 | + 页 | ||
43 | + </view> | ||
44 | + <view class="next_page" :class="{prev:pageNum >= totalPage}" @click="nextPage()">下一页</view> | ||
45 | + <view class="total_page">共{{totalPage/1}}页</view> | ||
46 | + </view> | ||
47 | + </view> | ||
48 | + </view> | ||
49 | +</template> | ||
50 | + | ||
51 | +<script> | ||
52 | + import App from "../../App.vue"; | ||
53 | +export default { | ||
54 | + data() { | ||
55 | + return { | ||
56 | + // 搜索 | ||
57 | + keyword:"", | ||
58 | + // 轴承列表 | ||
59 | + // 左侧 | ||
60 | + leftList: [], | ||
61 | + isLeft: 0, | ||
62 | + // 右侧 | ||
63 | + rightList: [], | ||
64 | + isRight: -1, | ||
65 | + // 名片列表 | ||
66 | + cardList:[], | ||
67 | + // 分页 | ||
68 | + pageNum:1, | ||
69 | + // 总页数 | ||
70 | + totalPage:"", | ||
71 | + }; | ||
72 | + }, | ||
73 | + methods: { | ||
74 | + // 首页分类数据 左侧一级分类 | ||
75 | + getType(){ | ||
76 | + let t = this; | ||
77 | + t.leftList = []; | ||
78 | + t.rightList = []; | ||
79 | + let url = "/api/category/get_category_one"; | ||
80 | + App.post(url) | ||
81 | + .then(res=>{ | ||
82 | + t.leftList = res; | ||
83 | + // 数据回显 | ||
84 | + t.leftList.forEach(el=>{ | ||
85 | + if(el.id == t.isLeft){ | ||
86 | + t.rightList = el.children; | ||
87 | + } | ||
88 | + }) | ||
89 | + }) | ||
90 | + }, | ||
91 | + // 左侧列表选中 | ||
92 | + changeLeft(item,index) { | ||
93 | + this.isLeft = item.id; | ||
94 | + this.rightList = item.children; | ||
95 | + }, | ||
96 | + // 右侧列表选中 | ||
97 | + changeRight(item,index){ | ||
98 | + this.isRight = item.id; | ||
99 | + this.getCardList(); | ||
100 | + }, | ||
101 | + // 获取名片列表 | ||
102 | + getCardList(){ | ||
103 | + let t = this; | ||
104 | + let url = "/api/goods/goods_list"; | ||
105 | + let params = { | ||
106 | + category_id:t.isRight, | ||
107 | + page:t.pageNum | ||
108 | + }; | ||
109 | + App.post(url,params) | ||
110 | + .then(res=>{ | ||
111 | + t.totalPage = res.page_sum; | ||
112 | + t.cardList = res.list; | ||
113 | + }) | ||
114 | + }, | ||
115 | + // 名片详情 | ||
116 | + toDetail(item){ | ||
117 | + uni.navigateTo({ | ||
118 | + url:"/pages/index/cardDetail?id="+item.id | ||
119 | + }) | ||
120 | + }, | ||
121 | + // 搜索 去名片列表 | ||
122 | + toSearch(){ | ||
123 | + uni.navigateTo({ | ||
124 | + url:"/pages/index/search?keyword="+this.keyword | ||
125 | + }) | ||
126 | + }, | ||
127 | + // 上一页 | ||
128 | + prevPage(){ | ||
129 | + if(this.pageNum <=1 ) | ||
130 | + return false; | ||
131 | + this.pageNum --; | ||
132 | + this.getCardList() | ||
133 | + }, | ||
134 | + // 下一页 | ||
135 | + nextPage(){ | ||
136 | + if(this.pageNum == this.totalPage){ | ||
137 | + return false | ||
138 | + } | ||
139 | + this.pageNum ++; | ||
140 | + this.getCardList() | ||
141 | + }, | ||
142 | + // 跳转到某一页 | ||
143 | + jumpPage(){ | ||
144 | + if(this.pageNum>this.totalPage) | ||
145 | + this.pageNum = this.totalPage; | ||
146 | + this.getCardList() | ||
147 | + }, | ||
148 | + }, | ||
149 | + onLoad(options) { | ||
150 | + this.isLeft = options.pid; | ||
151 | + this.isRight = options.id; | ||
152 | + // 首页分类数据 | ||
153 | + this.getType(); | ||
154 | + // 名片列表数据 | ||
155 | + this.getCardList(); | ||
156 | + }, | ||
157 | +}; | ||
158 | +</script> | ||
159 | + | ||
160 | +<style> | ||
161 | +@import url('../../style/index'); | ||
162 | + | ||
163 | +</style> |
-
请 注册 或 登录 后发表评论