diff --git a/App.vue b/App.vue index 55be1b2..1361438 100644 --- a/App.vue +++ b/App.vue @@ -33,4 +33,5 @@ diff --git a/components/gaoyia-parse/components/wxParseAudio.vue b/components/gaoyia-parse/components/wxParseAudio.vue new file mode 100644 index 0000000..b277717 --- /dev/null +++ b/components/gaoyia-parse/components/wxParseAudio.vue @@ -0,0 +1,28 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseImg.vue b/components/gaoyia-parse/components/wxParseImg.vue new file mode 100644 index 0000000..de9978b --- /dev/null +++ b/components/gaoyia-parse/components/wxParseImg.vue @@ -0,0 +1,94 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseTable.vue b/components/gaoyia-parse/components/wxParseTable.vue new file mode 100644 index 0000000..e1e25bf --- /dev/null +++ b/components/gaoyia-parse/components/wxParseTable.vue @@ -0,0 +1,55 @@ + + + \ No newline at end of file diff --git a/components/gaoyia-parse/components/wxParseTemplate0.vue b/components/gaoyia-parse/components/wxParseTemplate0.vue new file mode 100644 index 0000000..01bf8e1 --- /dev/null +++ b/components/gaoyia-parse/components/wxParseTemplate0.vue @@ -0,0 +1,98 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseTemplate1.vue b/components/gaoyia-parse/components/wxParseTemplate1.vue new file mode 100644 index 0000000..7054e35 --- /dev/null +++ b/components/gaoyia-parse/components/wxParseTemplate1.vue @@ -0,0 +1,88 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseTemplate10.vue b/components/gaoyia-parse/components/wxParseTemplate10.vue new file mode 100644 index 0000000..11c252c --- /dev/null +++ b/components/gaoyia-parse/components/wxParseTemplate10.vue @@ -0,0 +1,88 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseTemplate11.vue b/components/gaoyia-parse/components/wxParseTemplate11.vue new file mode 100644 index 0000000..0d04e53 --- /dev/null +++ b/components/gaoyia-parse/components/wxParseTemplate11.vue @@ -0,0 +1,86 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseTemplate2.vue b/components/gaoyia-parse/components/wxParseTemplate2.vue new file mode 100644 index 0000000..f06782a --- /dev/null +++ b/components/gaoyia-parse/components/wxParseTemplate2.vue @@ -0,0 +1,88 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseTemplate3.vue b/components/gaoyia-parse/components/wxParseTemplate3.vue new file mode 100644 index 0000000..b0943f8 --- /dev/null +++ b/components/gaoyia-parse/components/wxParseTemplate3.vue @@ -0,0 +1,88 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseTemplate4.vue b/components/gaoyia-parse/components/wxParseTemplate4.vue new file mode 100644 index 0000000..8a43756 --- /dev/null +++ b/components/gaoyia-parse/components/wxParseTemplate4.vue @@ -0,0 +1,88 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseTemplate5.vue b/components/gaoyia-parse/components/wxParseTemplate5.vue new file mode 100644 index 0000000..0c0993e --- /dev/null +++ b/components/gaoyia-parse/components/wxParseTemplate5.vue @@ -0,0 +1,88 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseTemplate6.vue b/components/gaoyia-parse/components/wxParseTemplate6.vue new file mode 100644 index 0000000..0dca28a --- /dev/null +++ b/components/gaoyia-parse/components/wxParseTemplate6.vue @@ -0,0 +1,88 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseTemplate7.vue b/components/gaoyia-parse/components/wxParseTemplate7.vue new file mode 100644 index 0000000..b62acaf --- /dev/null +++ b/components/gaoyia-parse/components/wxParseTemplate7.vue @@ -0,0 +1,88 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseTemplate8.vue b/components/gaoyia-parse/components/wxParseTemplate8.vue new file mode 100644 index 0000000..f6fa037 --- /dev/null +++ b/components/gaoyia-parse/components/wxParseTemplate8.vue @@ -0,0 +1,88 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseTemplate9.vue b/components/gaoyia-parse/components/wxParseTemplate9.vue new file mode 100644 index 0000000..47ac81a --- /dev/null +++ b/components/gaoyia-parse/components/wxParseTemplate9.vue @@ -0,0 +1,88 @@ + + + diff --git a/components/gaoyia-parse/components/wxParseVideo.vue b/components/gaoyia-parse/components/wxParseVideo.vue new file mode 100644 index 0000000..7d05285 --- /dev/null +++ b/components/gaoyia-parse/components/wxParseVideo.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/gaoyia-parse/libs/html2json.js b/components/gaoyia-parse/libs/html2json.js new file mode 100644 index 0000000..0927382 --- /dev/null +++ b/components/gaoyia-parse/libs/html2json.js @@ -0,0 +1,261 @@ +/** + * html2Json 改造来自: https://github.com/Jxck/html2json + * + * + * author: Di (微信小程序开发工程师) + * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) + * 垂直微信小程序开发交流社区 + * + * github地址: https://github.com/icindy/wxParse + * + * for: 微信小程序富文本解析 + * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 + */ + +import wxDiscode from './wxDiscode'; +import HTMLParser from './htmlparser'; + +function makeMap(str) { + const obj = {}; + const items = str.split(','); + for (let i = 0; i < items.length; i += 1) obj[items[i]] = true; + return obj; +} + +// Block Elements - HTML 5 +const block = makeMap('br,code,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); + +// Inline Elements - HTML 5 +const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); + +// Elements that you can, intentionally, leave open +// (and which close themselves) +const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); + +function removeDOCTYPE(html) { + const isDocument = /([^]*)<\/body>/.test(html); + return isDocument ? RegExp.$1 : html; +} + +function trimHtml(html) { + return html + .replace(//gi, '') + .replace(/\/\*.*?\*\//gi, '') + .replace(/[ ]+/gi, '') + .replace(//gi, ''); +} + +function getScreenInfo() { + const screen = {}; + wx.getSystemInfo({ + success: (res) => { + screen.width = res.windowWidth; + screen.height = res.windowHeight; + }, + }); + return screen; +} + +function html2json(html, customHandler, imageProp, host) { + // 处理字符串 + html = removeDOCTYPE(html); + html = trimHtml(html); + html = wxDiscode.strDiscode(html); + // 生成node节点 + const bufArray = []; + const results = { + nodes: [], + imageUrls: [], + }; + + const screen = getScreenInfo(); + function Node(tag) { + this.node = 'element'; + this.tag = tag; + + this.$screen = screen; + } + + HTMLParser(html, { + start(tag, attrs, unary) { + // node for this element + const node = new Node(tag); + + if (bufArray.length !== 0) { + const parent = bufArray[0]; + if (parent.nodes === undefined) { + parent.nodes = []; + } + } + + if (block[tag]) { + node.tagType = 'block'; + } else if (inline[tag]) { + node.tagType = 'inline'; + } else if (closeSelf[tag]) { + node.tagType = 'closeSelf'; + } + + node.attr = attrs.reduce((pre, attr) => { + const { name } = attr; + let { value } = attr; + if (name === 'class') { + node.classStr = value; + } + // has multi attibutes + // make it array of attribute + if (name === 'style') { + node.styleStr = value; + } + if (value.match(/ /)) { + value = value.split(' '); + } + + // if attr already exists + // merge it + if (pre[name]) { + if (Array.isArray(pre[name])) { + // already array, push to last + pre[name].push(value); + } else { + // single value, make it array + pre[name] = [pre[name], value]; + } + } else { + // not exist, put it + pre[name] = value; + } + + return pre; + }, {}); + + // 优化样式相关属性 + if (node.classStr) { + node.classStr += ` ${node.tag}`; + } else { + node.classStr = node.tag; + } + if (node.tagType === 'inline') { + node.classStr += ' inline'; + } + + // 对img添加额外数据 + if (node.tag === 'img') { + let imgUrl = node.attr.src; + imgUrl = wxDiscode.urlToHttpUrl(imgUrl, imageProp.domain); + Object.assign(node.attr, imageProp, { + src: imgUrl || '', + }); + if (imgUrl) { + results.imageUrls.push(imgUrl); + } + } + + // 处理a标签属性 + if (node.tag === 'a') { + node.attr.href = node.attr.href || ''; + } + + // 处理font标签样式属性 + if (node.tag === 'font') { + const fontSize = [ + 'x-small', + 'small', + 'medium', + 'large', + 'x-large', + 'xx-large', + '-webkit-xxx-large', + ]; + const styleAttrs = { + color: 'color', + face: 'font-family', + size: 'font-size', + }; + if (!node.styleStr) node.styleStr = ''; + Object.keys(styleAttrs).forEach((key) => { + if (node.attr[key]) { + const value = key === 'size' ? fontSize[node.attr[key] - 1] : node.attr[key]; + node.styleStr += `${styleAttrs[key]}: ${value};`; + } + }); + } + + // 临时记录source资源 + if (node.tag === 'source') { + results.source = node.attr.src; + } + + if (customHandler.start) { + customHandler.start(node, results); + } + + if (unary) { + // if this tag doesn't have end tag + // like + // add to parents + const parent = bufArray[0] || results; + if (parent.nodes === undefined) { + parent.nodes = []; + } + parent.nodes.push(node); + } else { + bufArray.unshift(node); + } + }, + end(tag) { + // merge into parent tag + const node = bufArray.shift(); + if (node.tag !== tag) { + console.error('invalid state: mismatch end tag'); + } + + // 当有缓存source资源时于于video补上src资源 + if (node.tag === 'video' && results.source) { + node.attr.src = results.source; + delete results.source; + } + + if (customHandler.end) { + customHandler.end(node, results); + } + + if (bufArray.length === 0) { + results.nodes.push(node); + } else { + const parent = bufArray[0]; + if (!parent.nodes) { + parent.nodes = []; + } + parent.nodes.push(node); + } + }, + chars(text) { + if (!text.trim()) return; + + const node = { + node: 'text', + text, + }; + + if (customHandler.chars) { + customHandler.chars(node, results); + } + + if (bufArray.length === 0) { + results.nodes.push(node); + } else { + const parent = bufArray[0]; + if (parent.nodes === undefined) { + parent.nodes = []; + } + parent.nodes.push(node); + } + }, + }); + + return results; +} + +export default html2json; diff --git a/components/gaoyia-parse/libs/htmlparser.js b/components/gaoyia-parse/libs/htmlparser.js new file mode 100644 index 0000000..2939da3 --- /dev/null +++ b/components/gaoyia-parse/libs/htmlparser.js @@ -0,0 +1,156 @@ +/** + * + * htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser + * + * author: Di (微信小程序开发工程师) + * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) + * 垂直微信小程序开发交流社区 + * + * github地址: https://github.com/icindy/wxParse + * + * for: 微信小程序富文本解析 + * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 + */ +// Regular Expressions for parsing tags and attributes + +const startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z0-9_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/; +const endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/; +const attr = /([a-zA-Z0-9_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; + +function makeMap(str) { + const obj = {}; + const items = str.split(','); + for (let i = 0; i < items.length; i += 1) obj[items[i]] = true; + return obj; +} + +// Empty Elements - HTML 5 +const empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); + +// Block Elements - HTML 5 +const block = makeMap('address,code,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); + +// Inline Elements - HTML 5 +const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); + +// Elements that you can, intentionally, leave open +// (and which close themselves) +const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); + +// Attributes that have their values filled in disabled="disabled" +const fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); + +function HTMLParser(html, handler) { + let index; + let chars; + let match; + let last = html; + const stack = []; + + stack.last = () => stack[stack.length - 1]; + + function parseEndTag(tag, tagName) { + // If no tag name is provided, clean shop + let pos; + if (!tagName) { + pos = 0; + } else { + // Find the closest opened tag of the same type + tagName = tagName.toLowerCase(); + for (pos = stack.length - 1; pos >= 0; pos -= 1) { + if (stack[pos] === tagName) break; + } + } + if (pos >= 0) { + // Close all the open elements, up the stack + for (let i = stack.length - 1; i >= pos; i -= 1) { + if (handler.end) handler.end(stack[i]); + } + + // Remove the open elements from the stack + stack.length = pos; + } + } + + function parseStartTag(tag, tagName, rest, unary) { + tagName = tagName.toLowerCase(); + + if (block[tagName]) { + while (stack.last() && inline[stack.last()]) { + parseEndTag('', stack.last()); + } + } + + if (closeSelf[tagName] && stack.last() === tagName) { + parseEndTag('', tagName); + } + + unary = empty[tagName] || !!unary; + + if (!unary) stack.push(tagName); + + if (handler.start) { + const attrs = []; + + rest.replace(attr, function genAttr(matches, name) { + const value = arguments[2] || arguments[3] || arguments[4] || (fillAttrs[name] ? name : ''); + + attrs.push({ + name, + value, + escaped: value.replace(/(^|[^\\])"/g, '$1\\"'), // " + }); + }); + + if (handler.start) { + handler.start(tagName, attrs, unary); + } + } + } + + while (html) { + chars = true; + + if (html.indexOf(' '); +// str = str.replace(/ | | /g, ' '); +// str = str.replace(/"|"|"/g, "\""); +// str = str.replace(/'|'|'/g, "'"); +// str = str.replace(/´|´|´/g, "´"); +// str = str.replace(/×|×|×/g, "×"); +// str = str.replace(/÷|÷|÷/g, "÷"); +// str = str.replace(/&|&|&/g, '&'); +// str = str.replace(/<|<|</g, '<'); +// str = str.replace(/>|>|>/g, '>'); + + + + +str = str.replace(/ | | /g, " "); +str = str.replace(/ | | /g, ''); +str = str.replace(/ | /g, ' '); +str = str.replace(/ | | /g, ''); +str = str.replace(/"|"|"/g, "\""); +str = str.replace(/"|'|'/g, "'"); +str = str.replace(/´|´|´/g, "´"); +str = str.replace(/×|×|×/g, "×"); +str = str.replace(/÷|÷|÷/g, "÷"); +str = str.replace(/&|&|&/g, '&'); +str = str.replace(/<|<|</g, '<'); +str = str.replace(/>|>|>/g, '>'); +return str; +} + +// HTML 支持的其他实体 +function strOtherDiscode(str) { +str = str.replace(/Œ|Œ|Œ/g, 'Œ'); +str = str.replace(/œ|œ|œ/g, 'œ'); +str = str.replace(/Š|Š|Š/g, 'Š'); +str = str.replace(/š|š|š/g, 'š'); +str = str.replace(/Ÿ|Ÿ|Ÿ/g, 'Ÿ'); +str = str.replace(/ƒ|ƒ|ƒ/g, 'ƒ'); +str = str.replace(/ˆ|ˆ|ˆ/g, 'ˆ'); +str = str.replace(/˜|˜|˜/g, '˜'); +str = str.replace(/ |$#8201;| /g, ''); +str = str.replace(/‌|‌|‌/g, ''); +str = str.replace(/‍|$#8205;|‍/g, ''); +str = str.replace(/‎|$#8206;|‎/g, ''); +str = str.replace(/‏|‏|‏/g, ''); +str = str.replace(/–|–|–/g, '–'); +str = str.replace(/—|—|—/g, '—'); +str = str.replace(/‘|‘|‘/g, '‘'); +str = str.replace(/’|’|’/g, '’'); +str = str.replace(/‚|‚|‚/g, '‚'); +str = str.replace(/“|“|“/g, '“'); +str = str.replace(/”|”|”/g, '”'); +str = str.replace(/„|„|„/g, '„'); +str = str.replace(/†|†|†/g, '†'); +str = str.replace(/‡|‡|‡/g, '‡'); +str = str.replace(/•|•|•/g, '•'); +str = str.replace(/…|…|…/g, '…'); +str = str.replace(/‰|‰|‰/g, '‰'); +str = str.replace(/′|′|′/g, '′'); +str = str.replace(/″|″|″/g, '″'); +str = str.replace(/‹|‹|‹/g, '‹'); +str = str.replace(/›|›|›/g, '›'); +str = str.replace(/‾|‾|‾/g, '‾'); +str = str.replace(/€|€|€/g, '€'); +str = str.replace(/™|™|™/g, '™'); +str = str.replace(/←|←|←/g, '←'); +str = str.replace(/↑|↑|↑/g, '↑'); +str = str.replace(/→|→|→/g, '→'); +str = str.replace(/↓|↓|↓/g, '↓'); +str = str.replace(/↔|↔|↔/g, '↔'); +str = str.replace(/↵|↵|↵/g, '↵'); +str = str.replace(/⌈|⌈|⌈/g, '⌈'); +str = str.replace(/⌉|⌉|⌉/g, '⌉'); +str = str.replace(/⌊|⌊|⌊/g, '⌊'); +str = str.replace(/⌋|⌋|⌋/g, '⌋'); +str = str.replace(/◊|◊|◊/g, '◊'); +str = str.replace(/♠|♠|♠/g, '♠'); +str = str.replace(/♣|♣|♣/g, '♣'); +str = str.replace(/♥|♥|♥/g, '♥'); +str = str.replace(/♦|♦|♦/g, '♦'); +return str; +} + +function strDiscode(str) { + str = strNumDiscode(str); + str = strGreeceDiscode(str); + str = strcharacterDiscode(str); + str = strOtherDiscode(str); + return str; +} + +function urlToHttpUrl(url, domain) { + if (/^\/\//.test(url)) { + return `https:${url}`; + } else if (/^\//.test(url)) { + return `https://${domain}${url}`; + } + return url; +} + +export default { + strDiscode, + urlToHttpUrl, +}; diff --git a/components/gaoyia-parse/parse.css b/components/gaoyia-parse/parse.css new file mode 100644 index 0000000..e7adce1 --- /dev/null +++ b/components/gaoyia-parse/parse.css @@ -0,0 +1,258 @@ +/** + * author: Di (微信小程序开发工程师) + * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) + * 垂直微信小程序开发交流社区 + * + * github地址: https://github.com/icindy/wxParse + * + * for: 微信小程序富文本解析 + * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 + */ +/** + * 请在全局下引入该文件,@import '/static/wxParse.css'; + */ +.wxParse { + user-select:none; + width: 100%; + font-family: Helvetica, "PingFangSC", 'Microsoft Yahei', '微软雅黑', Arial, sans-serif; + color: #333; + line-height: 1.5; + font-size: 1em; + text-align:justify;/* //左右两端对齐 */ +} +.wxParse view ,.wxParse uni-view{ + word-break: break-word; +} +.wxParse .p { + padding-bottom: 0.5em; + clear: both; + /* letter-spacing: 0;//字间距 */ +} +.wxParse .inline { + display: inline; + margin: 0; + padding: 0; +} + +.wxParse .div { + margin: 0; + padding: 0; + display: block; +} + +.wxParse .h1{ + font-size: 2em; + line-height: 1.2em; + margin: 0.67em 0; +} +.wxParse .h2{ + font-size: 1.5em; + margin: 0.83em 0; +} +.wxParse .h3{ + font-size: 1.17em; + margin: 1em 0; +} +.wxParse .h4{ + margin: 1.33em 0; +} +.wxParse .h5{ + font-size: 0.83em; + margin: 1.67em 0; +} +.wxParse .h6{ + font-size: 0.83em; + margin: 1.67em 0; +} + +.wxParse .h1, +.wxParse .h2, +.wxParse .h3, +.wxParse .h4, +.wxParse .h5, +.wxParse .h6, +.wxParse .b, +.wxParse .strong{ + font-weight: bolder; +} + +.wxParse .i, +.wxParse .cite, +.wxParse .em, +.wxParse .var, +.wxParse .address { + font-style: italic; +} +.wxParse .spaceshow{ + white-space: pre; +} +.wxParse .pre, +.wxParse .tt, +.wxParse .code, +.wxParse .kbd, +.wxParse .samp { + font-family: monospace; +} +.wxParse .pre { + overflow: auto; + background: #f5f5f5; + padding: 16upx; + white-space: pre; + margin: 1em 0upx; + font-size: 24upx; +} +.wxParse .code { + overflow: auto; + padding: 16upx; + white-space: pre; + margin: 1em 0upx; + background: #f5f5f5; + font-size: 24upx; +} + +.wxParse .big { + font-size: 1.17em; +} + +.wxParse .small, +.wxParse .sub, +.wxParse .sup { + font-size: 0.83em; +} + +.wxParse .sub { + vertical-align: sub; +} +.wxParse .sup { + vertical-align: super; +} + +.wxParse .s, +.wxParse .strike, +.wxParse .del { + text-decoration: line-through; +} + +.wxParse .strong, +.wxParse .text, +.wxParse .span, +.wxParse .s { + display: inline; +} + +.wxParse .a { + color: deepskyblue; +} + +.wxParse .video { + text-align: center; + margin: 22upx 0; +} + +.wxParse .video-video { + width: 100%; +} +.wxParse .uni-image{ + max-width: 100%; +} +.wxParse .img { + display: block; + max-width: 100%; + margin-bottom: 0em;/* //与p标签底部padding同时修改 */ + overflow: hidden; +} + +.wxParse .blockquote { + margin: 10upx 0; + padding: 22upx 0 22upx 22upx; + font-family: Courier, Calibri, "宋体"; + background: #f5f5f5; + border-left: 6upx solid #dbdbdb; +} +.wxParse .blockquote .p { + margin: 0; +} +.wxParse .ul, .wxParse .ol { + display: block; + margin: 1em 0; + padding-left: 2em; +} +.wxParse .ol { + list-style-type: disc; +} +.wxParse .ol { + list-style-type: decimal; +} +.wxParse .ol>weixin-parse-template,.wxParse .ul>weixin-parse-template { + display: list-item; + align-items: baseline; + text-align: match-parent; +} + +.wxParse .ol>.li,.wxParse .ul>.li { + display: list-item; + align-items: baseline; + text-align: match-parent; +} +.wxParse .ul .ul, .wxParse .ol .ul { + list-style-type: circle; +} +.wxParse .ol .ol .ul, .wxParse .ol .ul .ul, .wxParse .ul .ol .ul, .wxParse .ul .ul .ul { + list-style-type: square; +} + +.wxParse .u { + text-decoration: underline; +} +.wxParse .hide { + display: none; +} +.wxParse .del { + display: inline; +} +.wxParse .figure { + overflow: hidden; +} +.wxParse .tablebox{ + overflow: auto; + background-color: #f5f5f5; + background: #f5f5f5; + font-size: 13px; + padding: 8px; +} +.wxParse .table .table,.wxParse .table{ + border-collapse:collapse; + box-sizing: border-box; + /* 内边框 */ + /* width: 100%; */ + overflow: auto; + white-space: pre; +} +.wxParse .tbody{ + border-collapse:collapse; + box-sizing: border-box; + /* 内边框 */ + border: 1px solid #dadada; +} +.wxParse .table .thead, .wxParse .table .tfoot, .wxParse .table .th{ + border-collapse:collapse; + box-sizing: border-box; + background: #ececec; + font-weight: 40; +} +.wxParse .table .tr { + border-collapse:collapse; + box-sizing: border-box; + /* border: 2px solid #F0AD4E; */ + overflow:auto; +} +.wxParse .table .th, +.wxParse .table .td{ + border-collapse:collapse; + box-sizing: border-box; + border: 2upx solid #dadada; + overflow:auto; +} +.wxParse .audio, .wxParse .uni-audio-default{ + display: block; +} \ No newline at end of file diff --git a/components/gaoyia-parse/parse.vue b/components/gaoyia-parse/parse.vue new file mode 100644 index 0000000..f255166 --- /dev/null +++ b/components/gaoyia-parse/parse.vue @@ -0,0 +1,228 @@ + + + + + diff --git a/order/editCourse/editCourse.vue b/order/editCourse/editCourse.vue index df8cdb1..e717109 100644 --- a/order/editCourse/editCourse.vue +++ b/order/editCourse/editCourse.vue @@ -190,6 +190,8 @@ }, // 使用期限转换以及计算剩余天数 calcDate(row, fromData) { + console.log('row=>',row) + console.log('fromData=>',fromData) clearTimeout(this.timer) this.timer = setTimeout(() => { const { periodOfUse, options } = row diff --git a/order/orderDetail/orderDetail.vue b/order/orderDetail/orderDetail.vue index d1d8314..8414a25 100644 --- a/order/orderDetail/orderDetail.vue +++ b/order/orderDetail/orderDetail.vue @@ -260,7 +260,9 @@ this.form = order.order this.courses = order.orderOther this.handleProduct(order.orderOther) - this.calcTotal() + if(!this.orderId) { + this.calcTotal() + } uni.hideLoading() }).catch(e => { uni.hideLoading() @@ -398,7 +400,7 @@ this.handleErr('orderType') const { form } = this const isTrial = form.orderType === 2 // 是否试用 - let total = 0 + let total = 0 const list = this.courses let purchase = 0 // 总采购成本 let profit = 0 // 总利润 @@ -413,6 +415,7 @@ 总成本和总利润为单个产品的采购成本价和利润的和 */ + console.log('list=>',list) list.map(e => { // out=1 && 试用,则把结算价等重置为0 if (out && isTrial) { @@ -422,6 +425,9 @@ e.finalValue = 0 e.discountRate = '0%' } else { + this.calcDiscount(e) + this.dealSettlePrice(e) + this.calcFinalPrice(e) const curPurchase = +e.settlementPrice + +e.serviceFee purchase += curPurchase profit += +e.finalPrice - curPurchase @@ -431,6 +437,66 @@ form.profit = profit form.orderAmount = (+form.purchaseCost + +form.profit).toFixed(2) }, + calcDiscount(row) { + const price = row.authority ? row.finalPrice : row.finalValue + const { marketValue } = row + // (原价-现价)÷原价 x100% + if (price) row.discountRate = marketValue != 0 ? ((marketValue - price) / marketValue * 100).toFixed(2) + '%' : '0%' + }, + // 计算结算价及平台服务费 + dealSettlePrice(row) { + // 如果是试用,结算价和平台服务费都是0 + if (this.form.orderType == 2) { + row.settlementPrice = 0 + row.serviceFee = 0 + } else { + const unit = row.options // 使用期限单位 + const useUnit = row.periodOfUse // 使用期限 + let sPrice = '' + if (row.settlementMethod == 0) { + // 结算单价。计算规则:结算单价(**元/年)*购买时长(单位年)*数量(课程为1,数据为账号数量) + const priceUnit = row.settlementPriceUnit + sPrice = ((!unit ? + priceUnit / 365 * useUnit : + unit === 1 ? + priceUnit / 12 * useUnit : + priceUnit * useUnit) * (row.authority ? + 1 : + row.accountNum)).toFixed((2)) + } else { + // 比例分成。计算规则:成交价*商务分成比例 + sPrice = (row.finalPrice * row.businessProportion / 100).toFixed((2)) + } + row.settlementPrice = this.$util.handleNaN(sPrice) + // 平台服务费(结算价*10%) + if (row.settlementPrice) { + row.serviceFee = (row.finalPrice * (this.rate / 100)).toFixed(2) + } + } + }, + // 计算成交价。计算规则:成交单价*账号数*时间(成交单价为元/账号/年,所以时间要换算成年的单位去计算) + calcFinalPrice(row) { + clearTimeout(this.timer) + this.timer = setTimeout(() => { + const { finalValue, accountNum, periodOfUse, finalPrice } = row + if (periodOfUse) { + if (accountNum) { + // 有成交单价,则成交价=成交单价*账号数*时间 + if (finalValue) { + row.finalPrice = Math.round(finalValue * periodOfUse * accountNum) + } else if (!finalValue && finalPrice) { + // 有成交价,没有成交单价,则成交单价=成交价/账号数/时间 + row.finalValue = (finalPrice / periodOfUse / accountNum).toFixed(2) + this.calcDiscount(row) + } + } else if (finalValue && finalPrice && !row.authority) { + // 有成交价、成交单价,没有数量,则数量=成交价/时间/成交单价 + row.accountNum = Math.floor(finalPrice / periodOfUse / finalValue) + } + } + this.dealSettlePrice(row) + }, 500) + }, // 处理错误提示 handleErr(val) { if (val === this.err) this.err = '' diff --git a/team/article/article.vue b/team/article/article.vue index 4d25b21..ca5336e 100644 --- a/team/article/article.vue +++ b/team/article/article.vue @@ -17,7 +17,10 @@ - + + + + @@ -31,6 +34,7 @@