├── App.vue
├── README.md
├── index.html
├── main.js
├── manifest.json
├── pages.json
├── pages
├── bindCarnumber
│ └── bindCarnumber.vue
├── codeList
│ └── codeList.vue
├── experienceCode
│ └── experienceCode.vue
├── index
│ └── index.vue
├── me
│ └── me.vue
├── noticeCarowner
│ └── noticeCarowner.vue
├── orderConfirm
│ └── orderConfirm.vue
├── orderList
│ └── orderList.vue
├── problemList
│ └── problemList.vue
└── reciveWay
│ └── reciveWay.vue
├── polyfill
├── README.md
├── base64Binary.js
├── mixins.js
└── polyfill.js
├── sitemap.json
├── static
└── pages
│ └── images
│ ├── 7bb5fad244cb931399549aec9faffeca.png
│ ├── address.png
│ ├── bg0.png
│ ├── bg1.png
│ ├── bg3.png
│ ├── bg4.png
│ ├── bg5.png
│ ├── bg6.png
│ ├── bg7.png
│ ├── bg9.png
│ ├── btn1.png
│ ├── btn2.png
│ ├── icon-arrow.png
│ ├── icon-arrow1.png
│ ├── icon-arrow2.png
│ ├── icon-arrow3.png
│ ├── icon-close.png
│ ├── icon-delete.png
│ ├── icon-gou.png
│ ├── icon-kefu.png
│ ├── icon-mony.png
│ ├── icon-nuochema.png
│ ├── icon-order.png
│ ├── icon-weixin-pay.jpg
│ ├── icon-wenti.png
│ ├── icon-yaoqing.png
│ ├── img0.png
│ ├── img1.png
│ ├── nav-index-active.png
│ ├── nav-index.png
│ ├── nav-me-active.png
│ ├── nav-me.png
│ ├── nav-shangjin-active.png
│ ├── nav-shangjin.png
│ └── qrcode.png
├── transform.log
├── uni.scss
├── uni_modules
└── mp-html
│ ├── README.md
│ ├── changelog.md
│ ├── components
│ └── mp-html
│ │ ├── mp-html.vue
│ │ ├── node
│ │ └── node.vue
│ │ └── parser.js
│ ├── package.json
│ └── static
│ └── app-plus
│ └── mp-html
│ ├── js
│ ├── handler.js
│ └── uni.webview.min.js
│ └── local.html
└── utils
├── common.js
├── md5.js
└── util.js
/App.vue:
--------------------------------------------------------------------------------
1 |
38 |
128 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 插件介绍
2 | 匿名通知用户挪车,保护用户和车主隐私,前端小程序采用uniapp开发,后端采用php+mysql
3 | # 功能特性
4 |
1、用户可以通过扫描小程序码联系到车主
5 | 2、采用匿名通话的方式,用户只能在有效期内拨打车主电话,过期失效,从而保护车主和用户隐私。
6 | 3、后台可对用户订单,绑定用户,挪车码等进行管理
7 | 4、小程序ui采用简洁的设计理念,让主要信息本身作为核心被凸显出来。
8 | 5、提供多种隐私电话通知方式供用户选择。
9 | 6、支持微信公众号消息通知,将用户引流到微信公众号,增加公众号粉丝。
10 | 后台暂不开源,有需要后台的朋友可以联系微信:tunan6666666
11 | 体验小程序微信小程序搜索:挪帮帮
12 | 
13 | 如需接受微信通知,请先关注公众号:钰龙商贸
14 | 
15 | [后台网址](https://tn.rdtxgj.com/MNQYRauFiC.php/index/login "体验网址")
16 | 账号:test 密码:testtest
17 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | import App from './App';
2 |
3 | // Api函数polyfill(目前为实验版本,如不需要,可删除!)';
4 | import Polyfill from './polyfill/polyfill';
5 | Polyfill.init();
6 |
7 | // 全局mixins,用于实现setData等功能,请勿删除!';
8 | import Mixin from './polyfill/mixins';
9 |
10 | // #ifndef VUE3
11 | import Vue from 'vue';
12 |
13 | Vue.mixin(Mixin);
14 | Vue.config.productionTip = false;
15 | App.mpType = 'app';
16 | const app = new Vue({
17 | ...App
18 | });
19 | app.$mount();
20 | // #endif
21 |
22 | // #ifdef VUE3
23 | import { createSSRApp } from 'vue';
24 | export function createApp() {
25 | const app = createSSRApp(App);
26 | app.mixin(Mixin);
27 | return {
28 | app
29 | };
30 | }
31 | // #endif
32 |
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "",
3 | "appid" : "",
4 | "description" : "",
5 | "versionName" : "1.0.0",
6 | "versionCode" : "100",
7 | "transformPx" : false,
8 | "app-plus" : {
9 | "usingComponents" : true,
10 | "nvueStyleCompiler" : "uni-app",
11 | "compilerVersion" : 3,
12 | "splashscreen" : {
13 | "alwaysShowBeforeRender" : true,
14 | "waiting" : true,
15 | "autoclose" : true,
16 | "delay" : 0
17 | },
18 | "modules" : {},
19 | "distribute" : {
20 | "android" : {
21 | "permissions" : [
22 | "",
23 | "",
24 | "",
25 | "",
26 | "",
27 | "",
28 | "",
29 | "",
30 | "",
31 | "",
32 | "",
33 | "",
34 | "",
35 | "",
36 | ""
37 | ]
38 | },
39 | "ios" : {},
40 | "sdkConfigs" : {}
41 | }
42 | },
43 | "quickapp" : {},
44 | "mp-weixin" : {
45 | "appid" : "",
46 | "setting" : {
47 | "urlCheck" : false
48 | },
49 | "usingComponents" : true,
50 | "permission" : {
51 | "scope.userLocation" : {
52 | "desc" : "你的位置信息将用于小程序位置接口的效果展示"
53 | }
54 | },
55 | "plugins" : {}
56 | },
57 | "mp-alipay" : {
58 | "usingComponents" : true
59 | },
60 | "mp-baidu" : {
61 | "usingComponents" : true
62 | },
63 | "mp-toutiao" : {
64 | "usingComponents" : true
65 | },
66 | "uniStatistics" : {
67 | "enable" : false
68 | },
69 | "vueVersion" : "2"
70 | }
71 |
--------------------------------------------------------------------------------
/pages.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [
3 | {
4 | "path": "pages/index/index",
5 | "style": {}
6 | },
7 | {
8 | "path": "pages/bindCarnumber/bindCarnumber",
9 | "style": {
10 | "navigationBarTitleText": "绑定车牌号"
11 | }
12 | },
13 | {
14 | "path": "pages/experienceCode/experienceCode",
15 | "style": {
16 | "navigationBarTitleText": "挪车码"
17 | }
18 | },
19 | {
20 | "path": "pages/noticeCarowner/noticeCarowner",
21 | "style": {
22 | "navigationBarTitleText": "通知车主"
23 | }
24 | },
25 | {
26 | "path": "pages/codeList/codeList",
27 | "style": {
28 | "navigationBarTitleText": "我的挪车码"
29 | }
30 | },
31 | {
32 | "path": "pages/reciveWay/reciveWay",
33 | "style": {}
34 | },
35 | {
36 | "path": "pages/problemList/problemList",
37 | "style": {
38 | "navigationBarTitleText": "常见问题"
39 | }
40 | },
41 | {
42 | "path": "pages/orderList/orderList",
43 | "style": {
44 | "navigationBarTitleText": "我的订单"
45 | }
46 | },
47 | {
48 | "path": "pages/me/me",
49 | "style": {
50 | "navigationBarTitleText": "我的"
51 | }
52 | },
53 | {
54 | "path": "pages/orderConfirm/orderConfirm",
55 | "style": {}
56 | }
57 | ],
58 | "tabBar": {
59 | "color": "#999",
60 | "selectedColor": "#3f270b",
61 | "backgroundColor": "#fff",
62 | "borderStyle": "white",
63 | "list": [
64 | {
65 | "selectedIconPath": "static/pages/images/nav-index-active.png",
66 | "iconPath": "static/pages/images/nav-index.png",
67 | "pagePath": "pages/index/index",
68 | "text": "挪车码"
69 | },
70 | {
71 | "selectedIconPath": "static/pages/images/nav-me-active.png",
72 | "iconPath": "static/pages/images/nav-me.png",
73 | "pagePath": "pages/me/me",
74 | "text": "我的"
75 | }
76 | ]
77 | },
78 | "debug": true,
79 | "sitemapLocation": "sitemap.json",
80 | "requiredPrivateInfos": [
81 | "chooseAddress"
82 | ],
83 | "globalStyle": {
84 | "backgroundTextStyle": "light",
85 | "navigationBarBackgroundColor": "#ffd700",
86 | "navigationBarTextStyle": "black"
87 | },
88 | "subPackages": []
89 | }
--------------------------------------------------------------------------------
/pages/bindCarnumber/bindCarnumber.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ province }}
8 |
9 |
10 | 手机号
11 |
12 |
13 |
14 |
15 |
21 |
22 |
23 |
24 |
25 | 确认生成
26 | 激活挪车码
27 |
28 |
29 | 保存
30 |
31 |
32 |
33 |
34 |
35 | {{ item }}
36 |
37 | 隐藏
38 |
39 |
40 |
41 |
42 |
43 |
80 |
248 |
--------------------------------------------------------------------------------
/pages/codeList/codeList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{ item.car_number }}
9 | 体验码
10 | 正式码
11 | 未激活码
12 |
13 | 绑定手机: {{ item.phone_number }}
14 |
15 |
16 |
17 |
18 | 您还没有挪车码!
19 |
20 |
21 |
22 |
43 |
116 |
--------------------------------------------------------------------------------
/pages/experienceCode/experienceCode.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 注:此挪车码仅作为体验使用
5 | 注:此挪车码码未激活
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | 申请邮寄
15 |
16 |
17 |
18 |
19 |
20 | 删除体验码
21 |
22 |
23 |
24 | {{ licenseplate }}
25 | {{ mobile }}
26 |
27 |
28 |
29 |
30 | 注:开启免打扰模式后,您将收不到电话和短信通知
31 |
32 |
33 |
34 | 修改信息
35 |
36 |
37 |
38 |
39 |
40 |
41 | 保存到手机
42 |
43 |
44 |
45 |
46 |
75 |
166 |
--------------------------------------------------------------------------------
/pages/index/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ content }}
8 |
9 |
10 |
11 | 线上体验
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
58 |
127 |
--------------------------------------------------------------------------------
/pages/me/me.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
70 |
188 |
--------------------------------------------------------------------------------
/pages/noticeCarowner/noticeCarowner.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ licenseplate }}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | 匿名电话通知
18 |
19 |
23 |
24 | 微信通知
25 | 微信通知
26 |
27 |
28 |
29 | 您的挪车码还未激活
30 |
31 |
32 |
33 |
34 | 我也要挪车码
35 |
36 |
37 |
40 |
41 |
42 |
43 |
75 |
155 |
--------------------------------------------------------------------------------
/pages/orderConfirm/orderConfirm.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ user_name }}{{ phone }}
8 | {{ sheng }}{{ shi }}{{ qu }}{{ address }}
9 |
10 |
11 |
12 |
13 | 订单号
14 |
15 | {{ ordernum }}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | 商品价格
25 | {{ price }}元
26 |
27 |
28 |
29 |
30 |
31 | 数量
32 | {{ num }}
33 |
34 |
35 |
36 |
37 |
38 | 邮费
39 | {{ shipping }}元(下单后三天内发货)
40 |
41 |
42 |
43 |
44 |
48 |
49 |
56 |
57 |
58 |
59 |
120 |
278 |
--------------------------------------------------------------------------------
/pages/orderList/orderList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 | 订单编号
14 | {{ item.order_num }}
15 |
16 |
17 | 订单金额
18 | {{ item.sum_price }}元
19 |
20 |
21 | 购买数量
22 | {{ item.num }}套
23 |
24 |
25 | 客户姓名
26 | {{ item.uname }}
27 |
28 |
29 | 联系电话
30 | {{ item.phone }}
31 |
32 |
33 | 邮寄地址
34 | {{ item.sheng }}{{ item.shi }}{{ item.qu }}{{ item.address }}
35 |
36 |
37 | 快递公司
38 | {{ item.logistics }}
39 |
40 |
41 | 快递单号
42 | {{ item.tracknumber }}
43 |
44 |
45 |
46 |
47 |
48 | 您还没有订单!
49 |
50 |
51 |
52 |
70 |
145 |
--------------------------------------------------------------------------------
/pages/problemList/problemList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 不是,在线体验生成的码仅限于线上体验和打印使用,寄出的码是全新的空码,到手之后需要使用微信重新扫码绑定
6 |
7 |
8 |
9 |
10 | 工作日申请后第二天发货,周未及节假日申请后在下一个工作日发出。
11 |
12 |
13 |
14 |
15 | 发货之后,可以在 我的 》》我的订单 中查询购买快递单号及快递公司相关信息
16 |
17 |
18 |
19 |
20 | 物流信息由委托第三方物流公司寄送,如出现物流问题请致电物流客服询问,如没有回应可以联系客服。
21 |
22 |
23 |
24 |
25 | 您将收到精美挪车贴一张,收货后需要使用车主本人微信扫描绑定联络手机号和车牌号,绑定后挪车贴可贴在挡风玻璃四角或后方玻璃内的使用
26 |
27 |
28 |
29 |
30 | 车贴在粘贴后可揭下重复粘贴使用,不会残留胶水印记。
31 |
32 |
33 |
34 |
35 | 挪车码在使用过程中没有额外费用,仅会在拨叫过程中产生拨叫人本人通话资费标准的市话费。
36 |
37 |
38 |
39 |
40 |
50 |
74 |
--------------------------------------------------------------------------------
/pages/reciveWay/reciveWay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ title }}
8 | {{ content }}
9 | 原价:¥{{ old_price }}
10 | 现价:¥{{ price }}
11 |
12 |
13 |
25 |
26 |
27 |
28 |
29 |
30 | 配送方式
31 | 快递运输
32 |
33 |
34 |
35 |
36 | 请选择邮寄地址
37 |
38 |
39 | {{ userName }}
40 | {{ telNumber }}
41 |
42 | {{ address }}
43 |
44 |
45 |
46 |
47 |
48 |
49 | 支付方式
50 |
51 |
52 | 微信支付
53 |
54 |
55 |
56 |
57 |
58 |
59 | 推荐人
60 |
61 | {{ pphone }}
62 |
63 |
64 |
65 |
66 |
67 |
71 |
72 |
79 |
80 |
81 |
82 |
118 |
293 |
--------------------------------------------------------------------------------
/polyfill/README.md:
--------------------------------------------------------------------------------
1 | # 关于polyfill目录
2 |
3 | 用于抹平各平台差异化,使小程序转换uniapp项目后,能尽可能的少报错,尽可能的先运行起来。
4 |
5 | ## 文件结构
6 |
7 | ### base64Binary.js
8 |
9 | 用于 base64ToArrayBuffer, arrayBufferToBase64 两个函数的polyfill,因为这两函数仅app与微信小程序支持,特意制作此polyfill。
10 |
11 | 主要用于polyfill.js文件。
12 |
13 | ### mixins.js
14 |
15 | 有两个用途:
16 | 一是在使用富文本时,可以将后台传入的富文本字符串里面的转义符转换为普通字符,与mp-html插件配合使用。
17 | 二是this.setData()函数的polyfill,使转换后的uniapp项目,可以直接使用setData函数。
18 |
19 | ### polyfill.js
20 |
21 | 此文件,对大量api进行判断,如果在当前平台,不支持此函数,将会创建一个空函数,并输出一条提示,提示开发者,这个api需针对性的进行兼容处理。
22 |
23 | 如果不处理的话,会直接进行报错,并影响流程的运行,对转换者的心理有一定的影响。
24 |
25 | 因此制作此polyfill,让项目能先运行起来~
26 |
27 |
28 | ## 注意
29 |
30 | 如果觉得这些文件不需要想删除它,请一定要先阅读关于每个文件的说明,明白它的作用,再进行删除,以免项目运行报错,感谢合作~
31 |
32 | 如有不明白的地方,请联系作者(375890534@qq.com)或qq群(780359397、361784059、603659851)进行交流~
33 |
34 | zhangdaren 2021-07-21
35 |
36 |
--------------------------------------------------------------------------------
/polyfill/base64Binary.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: zhang peng
3 | * @Date: 2021-08-03 10:57:51
4 | * @LastEditTime: 2021-08-16 17:25:43
5 | * @LastEditors: zhang peng
6 | * @Description:
7 | * @FilePath: \miniprogram-to-uniapp2\src\project\template\polyfill\base64Binary.js
8 | *
9 | * 借鉴自:https://github.com/dankogai/js-base64/blob/main/base64.js
10 | * 因uniapp没有window,也无法使用Buffer,因此直接使用polyfill
11 | *
12 | */
13 | const b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
14 | const b64chs = [...b64ch]
15 | const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/
16 | const b64tab = ((a) => {
17 | let tab = {}
18 | a.forEach((c, i) => tab[c] = i)
19 | return tab
20 | })(b64chs)
21 | const _fromCC = String.fromCharCode.bind(String)
22 |
23 | /**
24 | * polyfill version of `btoa`
25 | */
26 | const btoaPolyfill = (bin) => {
27 | // console.log('polyfilled');
28 | let u32, c0, c1, c2, asc = ''
29 | const pad = bin.length % 3
30 | for (let i = 0;i < bin.length;) {
31 | if ((c0 = bin.charCodeAt(i++)) > 255 ||
32 | (c1 = bin.charCodeAt(i++)) > 255 ||
33 | (c2 = bin.charCodeAt(i++)) > 255)
34 | throw new TypeError('invalid character found')
35 | u32 = (c0 << 16) | (c1 << 8) | c2
36 | asc += b64chs[u32 >> 18 & 63]
37 | + b64chs[u32 >> 12 & 63]
38 | + b64chs[u32 >> 6 & 63]
39 | + b64chs[u32 & 63]
40 | }
41 | return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc
42 | }
43 |
44 | /**
45 | * polyfill version of `atob`
46 | */
47 | const atobPolyfill = (asc) => {
48 | // console.log('polyfilled');
49 | asc = asc.replace(/\s+/g, '')
50 | if (!b64re.test(asc))
51 | throw new TypeError('malformed base64.')
52 | asc += '=='.slice(2 - (asc.length & 3))
53 | let u24, bin = '', r1, r2
54 | for (let i = 0;i < asc.length;) {
55 | u24 = b64tab[asc.charAt(i++)] << 18
56 | | b64tab[asc.charAt(i++)] << 12
57 | | (r1 = b64tab[asc.charAt(i++)]) << 6
58 | | (r2 = b64tab[asc.charAt(i++)])
59 | bin += r1 === 64 ? _fromCC(u24 >> 16 & 255)
60 | : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255)
61 | : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255)
62 | }
63 | return bin
64 | }
65 |
66 | /**
67 | * base64转ArrayBuffer
68 | */
69 | function base64ToArrayBuffer (base64) {
70 | const binaryStr = atobPolyfill(base64)
71 | const byteLength = binaryStr.length
72 | const bytes = new Uint8Array(byteLength)
73 | for (let i = 0;i < byteLength;i++) {
74 | bytes[i] = binary.charCodeAt(i)
75 | }
76 | return bytes.buffer
77 | }
78 |
79 | /**
80 | * ArrayBuffer转base64
81 | */
82 | function arrayBufferToBase64 (buffer) {
83 | let binaryStr = ""
84 | const bytes = new Uint8Array(buffer)
85 | var len = bytes.byteLength
86 | for (let i = 0;i < len;i++) {
87 | binaryStr += String.fromCharCode(bytes[i])
88 | }
89 | return btoaPolyfill(binaryStr)
90 | }
91 |
92 | module.exports = {
93 | base64ToArrayBuffer,
94 | arrayBufferToBase64,
95 | }
96 |
--------------------------------------------------------------------------------
/polyfill/mixins.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: zhang peng
3 | * @Date: 2021-08-03 10:57:51
4 | * @LastEditTime: 2022-05-04 21:24:16
5 | * @LastEditors: zhang peng
6 | * @Description:
7 | * @FilePath: /miniprogram-to-uniapp2/src/project/template/polyfill/mixins.js
8 | *
9 | * 如果你想删除本文件,请先确认它使用的范围,感谢合作~
10 | * 如有疑问,请直接联系: 375890534@qq.com
11 | */
12 | export default {
13 | methods: {
14 | /**
15 | * 转义符换成普通字符
16 | * @param {*} str
17 | * @returns
18 | */
19 | escape2Html (str) {
20 | if (!str) return str
21 | var arrEntities = {
22 | 'lt': '<',
23 | 'gt': '>',
24 | 'nbsp': ' ',
25 | 'amp': '&',
26 | 'quot': '"'
27 | }
28 | return str.replace(/&(lt|gt|nbsp|amp|quot);/ig, function (all, t) {
29 | return arrEntities[t]
30 | })
31 | },
32 | /**
33 | * 普通字符转换成转义符
34 | * @param {*} sHtml
35 | * @returns
36 | */
37 | html2Escape (sHtml) {
38 | if (!sHtml) return sHtml
39 | return sHtml.replace(/[<>&"]/g, function (c) {
40 | return {
41 | '<': '<',
42 | '>': '>',
43 | '&': '&',
44 | '"': '"'
45 | }[c]
46 | })
47 | },
48 | /**
49 | * setData polyfill 勿删!!!
50 | * 用于转换后的uniapp的项目能直接使用this.setData()函数
51 | * @param {*} obj
52 | * @param {*} callback
53 | */
54 | setData: function (obj, callback) {
55 | let that = this
56 | const handleData = (tepData, tepKey, afterKey) => {
57 | var tepData2 = tepData
58 | tepKey = tepKey.split('.')
59 | tepKey.forEach(item => {
60 | if (tepData[item] === null || tepData[item] === undefined) {
61 | let reg = /^[0-9]+$/
62 | tepData[item] = reg.test(afterKey) ? [] : {}
63 | tepData2 = tepData[item]
64 | } else {
65 | tepData2 = tepData[item]
66 | }
67 | })
68 | return tepData2
69 | }
70 | const isFn = function (value) {
71 | return typeof value == 'function' || false
72 | }
73 | Object.keys(obj).forEach(function (key) {
74 | let val = obj[key]
75 | key = key.replace(/\]/g, '').replace(/\[/g, '.')
76 | let front, after
77 | let index_after = key.lastIndexOf('.')
78 | if (index_after != -1) {
79 | after = key.slice(index_after + 1)
80 | front = handleData(that, key.slice(0, index_after), after)
81 | } else {
82 | after = key
83 | front = that
84 | }
85 | if (front.$data && front.$data[after] === undefined) {
86 | Object.defineProperty(front, after, {
87 | get () {
88 | return front.$data[after]
89 | },
90 | set (newValue) {
91 | front.$data[after] = newValue
92 | that.hasOwnProperty("$forceUpdate") && that.$forceUpdate()
93 | },
94 | enumerable: true,
95 | configurable: true
96 | })
97 | front[after] = val
98 | } else {
99 | that.$set(front, after, val)
100 | }
101 | })
102 | // this.$forceUpdate();
103 | isFn(callback) && this.$nextTick(callback)
104 | },
105 | /**
106 | * 解析事件里的动态函数名,这种没有()的函数名,在uniapp不被执行
107 | * 比如:立即
108 | * @param {*} exp
109 | */
110 | parseEventDynamicCode (e, exp) {
111 | if (typeof (this[exp]) === 'function') {
112 | this[exp](e)
113 | }
114 | },
115 | /**
116 | * 用于处理对props进行赋值的情况
117 | * //简单处理一下就行了
118 | *
119 | * @param {*} target
120 | * @returns
121 | */
122 | deepClone (target) {
123 | return JSON.parse(JSON.stringify(target))
124 | },
125 | /**
126 | * 用于处理dataset
127 | * 自定义组件的事件里,是获取不到e.currentTarget.dataset的
128 | * 因此收集data-参数,手动传进去
129 | *
130 | * @param {*} event
131 | * @param {*} dataSet
132 | * @returns
133 | */
134 | datasetHandle (event, dataSet = {}) {
135 | if (event && !event.currentTarget) {
136 | if (dataSet.tagId) {
137 | event.currentTarget = {
138 | id: dataSet.tagId
139 | }
140 | } else {
141 | event.currentTarget = {
142 | dataset: dataSet
143 | }
144 | }
145 | }
146 | }
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/polyfill/polyfill.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: zhang peng
3 | * @Date: 2021-08-03 10:57:51
4 | * @LastEditTime: 2022-05-13 19:02:23
5 | * @LastEditors: zhang peng
6 | * @Description:
7 | * @FilePath: \miniprogram-to-uniapp\src\project\template\polyfill\polyfill.js
8 | *
9 | * Api polyfill
10 | * 2021-03-06
11 | * 因小程序转换到uniapp,再运行到各平台时,总有这样那样的api,没法支持,
12 | * 现根据uniapp文档对各平台的支持度,或实现,或调用success来抹平各平台的差异,
13 | * 让代码能正常运行,下一步再解决这些api的兼容问题。
14 | *
15 | * Author: 375890534@qq.com
16 | */
17 | const base64Binary = require("./base64Binary")
18 |
19 | /**
20 | * 获取guid
21 | */
22 | function guid () {
23 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
24 | var r = Math.random() * 16 | 0,
25 | v = c == 'x' ? r : (r & 0x3 | 0x8)
26 | return v.toString(16)
27 | })
28 | }
29 |
30 | /**
31 | * 检查api是否未实现,没实现返回true
32 | * @param {Object} api
33 | */
34 | function isApiNotImplemented (api) {
35 | return uni[api] === undefined || [api] && uni[api].toString().indexOf("is not yet implemented") > -1
36 | }
37 |
38 | /**
39 | * 条件编译
40 | */
41 | function platformPolyfill () {
42 | // #ifdef APP-PLUS
43 | uni.showNavigationBarLoading = function () {
44 | console.warn("api: uni.showNavigationBarLoading 在App平台会在屏幕中间悬浮loading,不如直接去掉")
45 | }
46 | // #endif
47 | }
48 |
49 |
50 | /**
51 | * 登录相关api polyfill
52 | */
53 | function loginPolyfill () {
54 | if (isApiNotImplemented("login")) {
55 | uni.login = function (options) {
56 | console.warn("api: uni.login 登录 在当前平台不支持,【关键流程函数】 回调成功")
57 | options.success && options.success({
58 | code: guid(),
59 | errMsg: "login:ok"
60 | })
61 | }
62 | }
63 |
64 | if (isApiNotImplemented("checkSession")) {
65 | uni.checkSession = function (options) {
66 | console.warn("api: uni.checkSession 检查登录状态是否过期 在当前平台不支持,【关键流程函数】 回调成功")
67 | options.success && options.success()
68 | }
69 | }
70 |
71 | if (isApiNotImplemented("getUserInfo")) {
72 | uni.getUserInfo = function (options) {
73 | console.warn("api: uni.getUserInfo 获取用户信息 在当前平台不支持,【关键流程函数】回调成功")
74 | options.success && options.success({
75 | userInfo: ""
76 | })
77 | }
78 | }
79 | if (isApiNotImplemented("getUserProfile")) {
80 | uni.getUserProfile = function (options) {
81 | console.warn("api: uni.getUserProfile 获取用户授权信息 在当前平台不支持,【关键流程函数】回调成功")
82 | options.success && options.success({
83 | userInfo: ""
84 | })
85 | }
86 | }
87 | }
88 |
89 | /**
90 | * 地图相关
91 | */
92 | function mapPolyfill () {
93 | if (isApiNotImplemented("chooseLocation")) {
94 | uni.chooseLocation = function (options) {
95 | console.warn("api: uni.chooseLocation 打开地图选择位置 在当前平台不支持,回调失败")
96 | options.fail && options.fail()
97 | }
98 | }
99 |
100 | if (isApiNotImplemented("openLocation")) {
101 | uni.openLocation = function (object) {
102 | console.warn("api: uni.openLocation 使用应用内置地图查看位置 在当前平台不支持,回调失败")
103 | options.fail && options.fail()
104 | }
105 | }
106 |
107 | if (isApiNotImplemented("createMapContext")) {
108 | uni.createMapContext = function (mapId) {
109 | console.warn("api: uni.createMapContext 创建并返回 map 上下文 mapContext 对象 在当前平台不支持,返回空")
110 | return {
111 | $getAppMap: null,
112 | getCenterLocation: function (options) {
113 | options.fail && options.fail()
114 | },
115 | moveToLocation: function (options) {
116 | options.fail && options.fail()
117 | },
118 | translateMarker: function (options) {
119 | options.fail && options.fail()
120 | },
121 | includePoints: function (options) { },
122 | getRegion: function (options) {
123 | options.fail && options.fail()
124 | },
125 | getScale: function (options) {
126 | options.fail && options.fail()
127 | },
128 | }
129 | }
130 | }
131 | }
132 |
133 | /**
134 | * 字符编码
135 | */
136 | function base64Polyfill () {
137 | //将 Base64 字符串转成 ArrayBuffer 对象
138 | if (isApiNotImplemented("base64ToArrayBuffer")) {
139 | uni.base64ToArrayBuffer = function (base64) {
140 | return base64Binary.base64ToArrayBuffer(base64)
141 | }
142 | }
143 |
144 | //将 ArrayBuffer 对象转成 Base64 字符串
145 | if (isApiNotImplemented("arrayBufferToBase64")) {
146 | uni.arrayBufferToBase64 = function (buffer) {
147 | return base64Binary.arrayBufferToBase64(buffer)
148 | }
149 | }
150 | }
151 |
152 |
153 | /**
154 | * 媒体相关
155 | */
156 | function mediaPolyfill () {
157 | if (isApiNotImplemented("saveImageToPhotosAlbum")) {
158 | uni.saveImageToPhotosAlbum = function (options) {
159 | console.warn("api: uni.saveImageToPhotosAlbum 保存图片到系统相册 在当前平台不支持,回调失败")
160 | options.fail && options.fail()
161 | }
162 | }
163 |
164 | if (isApiNotImplemented("compressImage")) {
165 | uni.compressImage = function (object) {
166 | console.warn("api: uni.compressImage 压缩图片接口 在当前平台不支持,回调失败")
167 | options.fail && options.fail()
168 | }
169 | }
170 |
171 | if (isApiNotImplemented("chooseMessageFile")) {
172 | //从微信聊天会话中选择文件。
173 | uni.chooseMessageFile = function (object) {
174 | console.warn("api: uni.chooseMessageFile 从微信聊天会话中选择文件。 在当前平台不支持,回调失败")
175 | options.fail && options.fail()
176 | }
177 | }
178 |
179 | if (isApiNotImplemented("getRecorderManager")) {
180 | //获取全局唯一的录音管理器 recorderManager
181 | uni.getRecorderManager = function (object) {
182 | console.warn("api: uni.getRecorderManager 获取全局唯一的录音管理器 在当前平台不支持")
183 | }
184 | }
185 |
186 | if (isApiNotImplemented("getBackgroundAudioManager")) {
187 | //获取全局唯一的背景音频管理器 backgroundAudioManager
188 | uni.getBackgroundAudioManager = function (object) {
189 | console.warn("api: uni.getBackgroundAudioManager 获取全局唯一的背景音频管理器 在当前平台不支持")
190 | }
191 | }
192 |
193 | if (isApiNotImplemented("chooseMedia")) {
194 | // 拍摄或从手机相册中选择图片或视频
195 | uni.chooseMedia = function (object) {
196 | console.warn("api: uni.chooseMedia 拍摄或从手机相册中选择图片或视频 在当前平台不支持,回调失败")
197 | options.fail && options.fail()
198 | }
199 | }
200 | if (isApiNotImplemented("saveVideoToPhotosAlbum")) {
201 | // 保存视频到系统相册
202 | uni.saveVideoToPhotosAlbum = function (object) {
203 | console.warn("api: uni.saveVideoToPhotosAlbum 保存视频到系统相册 在当前平台不支持,回调失败")
204 | options.fail && options.fail()
205 | }
206 | }
207 |
208 | if (isApiNotImplemented("getVideoInfo")) {
209 | // 获取视频详细信息
210 | uni.getVideoInfo = function (object) {
211 | console.warn("api: uni.getVideoInfo 获取视频详细信息 在当前平台不支持,回调失败")
212 | options.fail && options.fail()
213 | }
214 | }
215 |
216 | if (isApiNotImplemented("compressVideo")) {
217 | // 压缩视频接口
218 | uni.compressVideo = function (object) {
219 | console.warn("api: uni.compressVideo 压缩视频接口 在当前平台不支持,回调失败")
220 | options.fail && options.fail()
221 | }
222 | }
223 |
224 |
225 | if (isApiNotImplemented("openVideoEditor")) {
226 | // 打开视频编辑器
227 | uni.openVideoEditor = function (object) {
228 | console.warn("api: uni.openVideoEditor 打开视频编辑器 在当前平台不支持,回调失败")
229 | options.fail && options.fail()
230 | }
231 | }
232 | }
233 |
234 | /**
235 | * 设备
236 | */
237 | function devicePolyfill () {
238 | if (isApiNotImplemented("canIUse")) {
239 | // 判断应用的 API,回调,参数,组件等是否在当前版本可用。
240 | // h5时,恒返回true
241 | uni.canIUse = function (object) {
242 | console.warn("api: uni.canIUse 判断API在当前平台是否可用 返回true")
243 | return true
244 | }
245 | }
246 |
247 | //微信小程序
248 | if (isApiNotImplemented("startDeviceMotionListening")) {
249 | // 开始监听设备方向的变化
250 | uni.startDeviceMotionListening = function (options) {
251 | console.warn("api: uni.startDeviceMotionListening 开始监听设备方向的变化 在当前平台不支持")
252 | options.success && options.success()
253 | }
254 | }
255 |
256 | if (isApiNotImplemented("onMemoryWarning")) {
257 | // 监听内存不足告警事件。
258 | uni.onMemoryWarning = function (callback) {
259 | console.warn("监听内存不足告警事件,仅支持微信小程序、支付宝小程序、百度小程序、QQ小程序,当前平台不支持,已注释")
260 | }
261 | }
262 |
263 | if (isApiNotImplemented("offNetworkStatusChange")) {
264 | // 取消监听网络状态变化
265 | uni.offNetworkStatusChange = function (callback) { }
266 | }
267 | if (isApiNotImplemented("offAccelerometerChange")) {
268 | // 取消监听加速度数据。
269 | uni.offAccelerometerChange = function (callback) { }
270 | }
271 | if (isApiNotImplemented("startAccelerometer")) {
272 | // 开始监听加速度数据。
273 | uni.startAccelerometer = function (callback) {
274 | console.warn("api: uni.startAccelerometer 开始监听加速度数据 在当前平台不支持")
275 | }
276 | }
277 |
278 | if (isApiNotImplemented("offCompassChange")) {
279 | // 取消监听罗盘数据
280 | uni.offCompassChange = function (callback) {
281 | console.warn("api: uni.offCompassChange 取消监听罗盘数据 在当前平台不支持")
282 | }
283 | }
284 |
285 | if (isApiNotImplemented("startCompass")) {
286 | // 开始监听罗盘数据
287 | uni.startCompass = function (callback) {
288 | console.warn("api: uni.startCompass 开始监听罗盘数据 在当前平台不支持")
289 | }
290 | }
291 |
292 |
293 | if (isApiNotImplemented("onGyroscopeChange")) {
294 | // 监听陀螺仪数据变化事件
295 | uni.onGyroscopeChange = function (callback) {
296 | console.warn("api: uni.onGyroscopeChange 监听陀螺仪数据变化事件 在当前平台不支持")
297 | }
298 | }
299 |
300 | if (isApiNotImplemented("startGyroscope")) {
301 | // 开始监听陀螺仪数据
302 | uni.startGyroscope = function (callback) {
303 | console.warn("api: uni.startGyroscope 监听陀螺仪数据变化事件 在当前平台不支持")
304 | }
305 | }
306 | if (isApiNotImplemented("stopGyroscope")) {
307 | // 停止监听陀螺仪数据
308 | uni.stopGyroscope = function (callback) {
309 | console.warn("api: uni.stopGyroscope 停止监听陀螺仪数据 在当前平台不支持")
310 | }
311 | }
312 | if (isApiNotImplemented("scanCode")) {
313 | // 调起客户端扫码界面,扫码成功后返回对应的结果
314 | uni.scanCode = function (callback) {
315 | console.warn("api: uni.scanCode 扫描二维码 在当前平台不支持")
316 | }
317 | }
318 |
319 | if (isApiNotImplemented("setClipboardData")) {
320 | // 设置系统剪贴板的内容
321 | uni.setClipboardData = function (callback) {
322 | console.warn("api: uni.setClipboardData 设置系统剪贴板的内容 在当前平台不支持")
323 | }
324 | }
325 | if (isApiNotImplemented("getClipboardData")) {
326 | // 获取系统剪贴板内容
327 | uni.getClipboardData = function (callback) {
328 | console.warn("api: uni.getClipboardData 获取系统剪贴板内容 在当前平台不支持")
329 | }
330 | }
331 | if (isApiNotImplemented("setScreenBrightness")) {
332 | // 设置屏幕亮度
333 | uni.setScreenBrightness = function (callback) {
334 | console.warn("api: uni.setScreenBrightness 设置屏幕亮度 在当前平台不支持")
335 | }
336 | }
337 | if (isApiNotImplemented("getScreenBrightness")) {
338 | // 获取屏幕亮度
339 | uni.getScreenBrightness = function (callback) {
340 | console.warn("api: uni.getScreenBrightness 获取屏幕亮度 在当前平台不支持")
341 | }
342 | }
343 |
344 | if (isApiNotImplemented("setKeepScreenOn")) {
345 | // 设置是否保持常亮状态
346 | uni.setKeepScreenOn = function (callback) {
347 | console.warn("api: uni.setKeepScreenOn 设置是否保持常亮状态 在当前平台不支持")
348 | }
349 | }
350 | if (isApiNotImplemented("onUserCaptureScreen")) {
351 | // 监听用户主动截屏事件
352 | uni.onUserCaptureScreen = function (callback) {
353 | console.warn("api: uni.onUserCaptureScreen 监听用户主动截屏事件 在当前平台不支持")
354 | }
355 | }
356 | if (isApiNotImplemented("addPhoneContact")) {
357 | // 添加联系人
358 | uni.addPhoneContact = function (callback) {
359 | console.warn("api: uni.addPhoneContact 添加联系人 在当前平台不支持")
360 | }
361 | }
362 | }
363 |
364 | /**
365 | * 界面相关
366 | */
367 | function uiPolyfill () {
368 | if (isApiNotImplemented("hideNavigationBarLoading")) {
369 | // 在当前页面隐藏导航条加载动画
370 | uni.hideNavigationBarLoading = function (options) {
371 | console.warn("api: uni.hideNavigationBarLoading 在当前页面隐藏导航条加载动画 在当前平台不支持,回调成功")
372 | options.success && options.success()
373 | }
374 | }
375 | if (isApiNotImplemented("hideHomeButton")) {
376 | // 隐藏返回首页按钮
377 | uni.hideHomeButton = function (options) {
378 | console.warn("api: uni.hideHomeButton 隐藏返回首页按钮 在当前平台不支持,回调成功")
379 | options.success && options.success()
380 | }
381 | }
382 |
383 | if (isApiNotImplemented("setTabBarItem")) {
384 | // 动态设置 tabBar 某一项的内容
385 | uni.setTabBarItem = function (options) {
386 | console.warn("api: uni.setTabBarItem 动态设置 tabBar 某一项的内容 在当前平台不支持,执行失败")
387 | options.fail && options.fail()
388 | }
389 | }
390 |
391 | if (isApiNotImplemented("setTabBarStyle")) {
392 | // 动态设置 tabBar 的整体样式
393 | uni.setTabBarStyle = function (options) {
394 | console.warn("api: uni.setTabBarStyle 动态设置 tabBar 的整体样式 在当前平台不支持,回调成功")
395 | options.success && options.success()
396 | }
397 | }
398 |
399 | if (isApiNotImplemented("hideTabBar")) {
400 | // 隐藏 tabBar
401 | uni.hideTabBar = function (options) {
402 | console.warn("api: uni.hideTabBar 隐藏 tabBar 在当前平台不支持,执行失败")
403 | options.fail && options.fail()
404 | }
405 | }
406 |
407 |
408 | if (isApiNotImplemented("showTabBar")) {
409 | // 显示 tabBar
410 | uni.showTabBar = function (options) {
411 | console.warn("api: uni.showTabBar 显示 tabBar 在当前平台不支持,执行失败")
412 | options.fail && options.fail()
413 | }
414 | }
415 | if (isApiNotImplemented("setTabBarBadge")) {
416 | // 为 tabBar 某一项的右上角添加文本
417 | uni.setTabBarBadge = function (options) {
418 | console.warn("api: uni.setTabBarBadge 为 tabBar 某一项的右上角添加文本 在当前平台不支持,执行失败")
419 | options.fail && options.fail()
420 | }
421 | }
422 | if (isApiNotImplemented("removeTabBarBadge")) {
423 | // 移除 tabBar 某一项右上角的文本
424 | uni.removeTabBarBadge = function (options) {
425 | console.warn("api: uni.removeTabBarBadge 移除 tabBar 某一项右上角的文本 在当前平台不支持,执行失败")
426 | options.fail && options.fail()
427 | }
428 | }
429 | if (isApiNotImplemented("showTabBarRedDot")) {
430 | // 显示 tabBar 某一项的右上角的红点
431 | uni.showTabBarRedDot = function (options) {
432 | console.warn("api: uni.showTabBarRedDot 显示 tabBar 某一项的右上角的红点 在当前平台不支持,执行失败")
433 | options.fail && options.fail()
434 | }
435 | }
436 | if (isApiNotImplemented("hideTabBarRedDot")) {
437 | // 隐藏 tabBar 某一项的右上角的红点
438 | uni.hideTabBarRedDot = function (options) {
439 | console.warn("api: uni.hideTabBarRedDot 隐藏 tabBar 某一项的右上角的红点 在当前平台不支持,执行失败")
440 | options.fail && options.fail()
441 | }
442 | }
443 | ///////////////////////////////
444 | if (isApiNotImplemented("setBackgroundColor")) {
445 | // 动态设置窗口的背景色
446 | uni.setBackgroundColor = function (options) {
447 | console.warn("api: uni.setBackgroundColor 动态设置窗口的背景色 在当前平台不支持,执行失败")
448 | options.fail && options.fail()
449 | }
450 | }
451 | if (isApiNotImplemented("setBackgroundTextStyle")) {
452 | // 动态设置下拉背景字体、loading 图的样式
453 | uni.setBackgroundTextStyle = function (options) {
454 | console.warn("api: uni.setBackgroundTextStyle 动态设置下拉背景字体、loading 图的样式 在当前平台不支持,执行失败")
455 | options.fail && options.fail()
456 | }
457 | }
458 | if (isApiNotImplemented("onWindowResize")) {
459 | // 监听窗口尺寸变化事件
460 | uni.onWindowResize = function (callback) {
461 | console.warn("api: uni.onWindowResize 监听窗口尺寸变化事件 在当前平台不支持,执行失败")
462 | callback && callback()
463 | }
464 | }
465 | if (isApiNotImplemented("offWindowResize")) {
466 | // 取消监听窗口尺寸变化事件
467 | uni.offWindowResize = function (callback) {
468 | console.warn("api: uni.offWindowResize 取消监听窗口尺寸变化事件 在当前平台不支持,执行失败")
469 | callback && callback()
470 | }
471 | }
472 | if (isApiNotImplemented("loadFontFace")) {
473 | // 动态加载网络字体
474 | uni.loadFontFace = function (options) {
475 | console.warn("api: uni.loadFontFace 动态加载网络字体 在当前平台不支持,执行失败")
476 | options.fail && options.fail()
477 | }
478 | }
479 | if (isApiNotImplemented("getMenuButtonBoundingClientRect")) {
480 | // 微信胶囊按钮布局信息
481 | uni.getMenuButtonBoundingClientRect = function () {
482 | console.warn("api: uni.getMenuButtonBoundingClientRect 微信胶囊按钮布局信息 在当前平台不支持,执行失败")
483 | }
484 | }
485 | }
486 | /**
487 | * file
488 | */
489 | function filePolyfill () {
490 | if (isApiNotImplemented("saveFile")) {
491 | // 保存文件到本地
492 | uni.saveFile = function (options) {
493 | console.warn("api: uni.saveFile 保存文件到本地 在当前平台不支持,执行失败")
494 | options.fail && options.fail()
495 | }
496 | }
497 | if (isApiNotImplemented("getSavedFileList")) {
498 | // 获取本地已保存的文件列表
499 | uni.getSavedFileList = function (options) {
500 | console.warn("api: uni.getSavedFileList 获取本地已保存的文件列表 在当前平台不支持,执行失败")
501 | options.fail && options.fail()
502 | }
503 | }
504 | if (isApiNotImplemented("getSavedFileInfo")) {
505 | // 获取本地文件的文件信息
506 | uni.getSavedFileInfo = function (options) {
507 | console.warn("api: uni.getSavedFileInfo 获取本地文件的文件信息 在当前平台不支持,执行失败")
508 | options.fail && options.fail()
509 | }
510 | }
511 | if (isApiNotImplemented("removeSavedFile")) {
512 | // 删除本地存储的文件
513 | uni.removeSavedFile = function (options) {
514 | console.warn("api: uni.removeSavedFile 删除本地存储的文件 在当前平台不支持,执行失败")
515 | options.fail && options.fail()
516 | }
517 | }
518 | if (isApiNotImplemented("getFileInfo")) {
519 | // 获取文件信息
520 | uni.getFileInfo = function (options) {
521 | console.warn("api: uni.getFileInfo 获取文件信息 在当前平台不支持,执行失败")
522 | options.fail && options.fail()
523 | }
524 | }
525 | if (isApiNotImplemented("openDocument")) {
526 | // 新开页面打开文档
527 | uni.openDocument = function (options) {
528 | console.warn("api: uni.openDocument 新开页面打开文档 在当前平台不支持,执行失败")
529 | options.fail && options.fail()
530 | }
531 | }
532 | if (isApiNotImplemented("getFileSystemManager")) {
533 | // 获取全局唯一的文件管理器
534 | uni.getFileSystemManager = function () {
535 | console.warn("api: uni.getFileSystemManager 获取全局唯一的文件管理器 在当前平台不支持,执行失败")
536 | }
537 | }
538 | }
539 |
540 | /**
541 | * canvas
542 | */
543 | function canvasPolyfill () {
544 | if (isApiNotImplemented("createOffscreenCanvas")) {
545 | // 创建离屏 canvas 实例
546 | uni.createOffscreenCanvas = function () {
547 | console.warn("api: uni.createOffscreenCanvas 创建离屏 canvas 实例 在当前平台不支持,执行失败")
548 | }
549 | }
550 |
551 | if (isApiNotImplemented("canvasToTempFilePath")) {
552 | // 把当前画布指定区域的内容导出生成指定大小的图片
553 | uni.canvasToTempFilePath = function () {
554 | console.warn("api: uni.canvasToTempFilePath 把当前画布指定区域的内容导出生成指定大小的图片 在当前平台不支持,执行失败")
555 | }
556 | }
557 | }
558 |
559 | /**
560 | * Ad广告
561 | */
562 | function adPolyfill () {
563 | if (isApiNotImplemented("createRewardedVideoAd")) {
564 | // 激励视频广告
565 | uni.createRewardedVideoAd = function () {
566 | console.warn("api: uni.createRewardedVideoAd 激励视频广告 在当前平台不支持,执行失败")
567 | return {
568 | show () { },
569 | onLoad () { },
570 | offLoad () { },
571 | load () { },
572 | onError () { },
573 | offError () { },
574 | onClose () { },
575 | offClose () { },
576 | }
577 | }
578 | }
579 | if (isApiNotImplemented("createInterstitialAd")) {
580 | // 插屏广告组件
581 | uni.createInterstitialAd = function () {
582 | console.warn("api: uni.createInterstitialAd 插屏广告组件 在当前平台不支持,执行失败")
583 | }
584 | }
585 | }
586 |
587 | /**
588 | * 第三方
589 | */
590 | function pluginsPolyfill () {
591 | if (isApiNotImplemented("getProvider")) {
592 | // 获取服务供应商
593 | uni.getProvider = function (options) {
594 | console.warn("api: uni.getProvider 获取服务供应商 在当前平台不支持,执行失败")
595 | options && options.fail && options.fail()
596 | }
597 | }
598 |
599 | if (isApiNotImplemented("showShareMenu")) {
600 | // 小程序的原生菜单中显示分享按钮
601 | uni.showShareMenu = function (options) {
602 | console.warn("api: uni.showShareMenu 小程序的原生菜单中显示分享按钮 在当前平台不支持,执行失败")
603 | options && options.fail && options.fail()
604 | }
605 | }
606 | if (isApiNotImplemented("hideShareMenu")) {
607 | // 小程序的原生菜单中显示分享按钮
608 | uni.hideShareMenu = function (options) {
609 | console.warn("api: uni.hideShareMenu 小程序的原生菜单中隐藏分享按钮 在当前平台不支持,执行失败")
610 | options && options.fail && options.fail()
611 | }
612 | }
613 | if (isApiNotImplemented("requestPayment")) {
614 | // 支付
615 | uni.requestPayment = function (options) {
616 | console.error("api: uni.requestPayment 支付 在当前平台不支持(需自行参考文档封装),执行失败")
617 | options && options.fail && options.fail()
618 | }
619 | }
620 | if (isApiNotImplemented("createWorker")) {
621 | // 创建一个 Worker 线程
622 | uni.createWorker = function () {
623 | console.error("api: uni.createWorker 创建一个 Worker 线程 在当前平台不支持,执行失败")
624 | }
625 | }
626 | }
627 |
628 | /**
629 | * 其他
630 | */
631 | function otherPolyfill () {
632 | if (isApiNotImplemented("authorize")) {
633 | // 提前向用户发起授权请求
634 | uni.authorize = function (options) {
635 | console.warn("api: uni.authorize 提前向用户发起授权请求 在当前平台不支持,执行失败")
636 | options.fail && options.fail()
637 | }
638 | }
639 |
640 | if (isApiNotImplemented("openSetting")) {
641 | // 调起客户端小程序设置界面
642 | uni.openSetting = function (options) {
643 | console.warn("api: uni.openSetting 调起客户端小程序设置界面 在当前平台不支持,执行失败")
644 | options.fail && options.fail()
645 | }
646 | }
647 |
648 | if (isApiNotImplemented("getSetting")) {
649 | // 获取用户的当前设置
650 | uni.getSetting = function (options) {
651 | console.warn("api: uni.getSetting 获取用户的当前设置 在当前平台不支持,【关键流程函数】回调成功")
652 | options.success && options.success({
653 | authSetting: {
654 | scope: {
655 | userInfo: false
656 | }
657 | }
658 | })
659 | }
660 | }
661 |
662 | if (isApiNotImplemented("chooseAddress")) {
663 | // 获取用户收货地址
664 | uni.chooseAddress = function (options) {
665 | console.warn("api: uni.chooseAddress 获取用户收货地址 在当前平台不支持,执行失败")
666 | options.fail && options.fail()
667 | }
668 | }
669 | if (isApiNotImplemented("chooseInvoiceTitle")) {
670 | // 选择用户的发票抬头
671 | uni.chooseInvoiceTitle = function (options) {
672 | console.warn("api: uni.chooseInvoiceTitle 选择用户的发票抬头 在当前平台不支持,执行失败")
673 | options.fail && options.fail()
674 | }
675 | }
676 | if (isApiNotImplemented("navigateToMiniProgram")) {
677 | // 打开另一个小程序
678 | uni.navigateToMiniProgram = function (options) {
679 | console.warn("api: uni.navigateToMiniProgram 打开另一个小程序 在当前平台不支持,执行失败")
680 | options.fail && options.fail()
681 | }
682 | }
683 | if (isApiNotImplemented("navigateBackMiniProgram")) {
684 | // 跳转回上一个小程序
685 | uni.navigateBackMiniProgram = function (options) {
686 | console.warn("api: uni.navigateBackMiniProgram 跳转回上一个小程序 在当前平台不支持,执行失败")
687 | options.fail && options.fail()
688 | }
689 | }
690 | if (isApiNotImplemented("getAccountInfoSync")) {
691 | // 获取当前帐号信息
692 | uni.getAccountInfoSync = function (options) {
693 | console.warn("api: uni.getAccountInfoSync 获取当前帐号信息 在当前平台不支持,执行失败")
694 | options.fail && options.fail()
695 | }
696 | }
697 |
698 | if (isApiNotImplemented("requestSubscribeMessage")) {
699 | // 订阅消息
700 | uni.requestSubscribeMessage = function (options) {
701 | console.warn("api: uni.requestSubscribeMessage 订阅消息 在当前平台不支持,执行失败")
702 | options.fail && options.fail()
703 | }
704 | }
705 | if (isApiNotImplemented("getUpdateManager")) {
706 | // 管理小程序更新
707 | uni.getUpdateManager = function (options) {
708 | console.error("api: uni.getUpdateManager 管理小程序更新 在当前平台不支持,执行失败")
709 | }
710 | }
711 | if (isApiNotImplemented("setEnableDebug")) {
712 | // 设置是否打开调试开关
713 | uni.setEnableDebug = function (options) {
714 | console.error("api: uni.setEnableDebug 设置是否打开调试开关 在当前平台不支持,执行失败")
715 | }
716 | }
717 | if (isApiNotImplemented("getExtConfig")) {
718 | // 获取第三方平台自定义的数据字段
719 | uni.getExtConfig = function (options) {
720 | console.error("api: uni.getExtConfig 获取第三方平台自定义的数据字段 在当前平台不支持,执行失败")
721 | }
722 | }
723 | if (isApiNotImplemented("getExtConfigSync")) {
724 | // uni.getExtConfig 的同步版本
725 | uni.getExtConfigSync = function (options) {
726 | console.error("api: uni.getExtConfigSync uni.getExtConfig 的同步版本 在当前平台不支持,执行失败")
727 | }
728 | }
729 | }
730 |
731 | /**
732 | * 认证
733 | */
734 | function soterAuthPolyfill () {
735 | if (isApiNotImplemented("startSoterAuthentication")) {
736 | // 开始 SOTER 生物认证
737 | uni.startSoterAuthentication = function (options) {
738 | console.warn("api: uni.startSoterAuthentication 开始 SOTER 生物认证 在当前平台不支持")
739 | options.success && options.success()
740 | }
741 | }
742 | if (isApiNotImplemented("checkIsSupportSoterAuthentication")) {
743 | // 获取本机支持的 SOTER 生物认证方式
744 | uni.checkIsSupportSoterAuthentication = function (options) {
745 | console.warn("api: uni.checkIsSupportSoterAuthentication 开获取本机支持的 SOTER 生物认证方式 在当前平台不支持")
746 | options.success && options.success()
747 | }
748 | }
749 | if (isApiNotImplemented("checkIsSoterEnrolledInDevice")) {
750 | // 获取设备内是否录入如指纹等生物信息的接口
751 | uni.checkIsSoterEnrolledInDevice = function (options) {
752 | console.warn("api: uni.checkIsSoterEnrolledInDevice 获取设备内是否录入如指纹等生物信息的接口 在当前平台不支持")
753 | options.success && options.success()
754 | }
755 | }
756 | }
757 |
758 | /**
759 | * nfc
760 | */
761 | function nfcPolyfill () {
762 | //微信小程序
763 | if (isApiNotImplemented("startHCE")) {
764 | // 初始化 NFC 模块
765 | uni.startHCE = function (options) {
766 | console.warn("api: uni.startHCE 初始化 NFC 模块 在当前平台不支持")
767 | options.success && options.success()
768 | }
769 | }
770 | }
771 |
772 | /**
773 | * 电量
774 | */
775 | function batteryPolyfill () {
776 | //微信小程序
777 | if (isApiNotImplemented("getBatteryInfo")) {
778 | // 获取设备电量
779 | uni.getBatteryInfo = function (options) {
780 | console.warn("api: uni.getBatteryInfo 获取设备电量 在当前平台不支持")
781 | options.success && options.success()
782 | }
783 | }
784 | //微信小程序
785 | if (isApiNotImplemented("getBatteryInfoSync")) {
786 | // 同步获取设备电量
787 | uni.getBatteryInfoSync = function (options) {
788 | console.warn("api: uni.getBatteryInfoSync 同步获取设备电量 在当前平台不支持")
789 | }
790 | }
791 | }
792 |
793 | /**
794 | * wifi
795 | */
796 | function wifiPolyfill () {
797 | //微信小程序
798 | if (isApiNotImplemented("startWifi")) {
799 | // 初始化 Wi-Fi 模块
800 | uni.startWifi = function (options) {
801 | console.warn("api: uni.startWifi 初始化 Wi-Fi 模块 在当前平台不支持")
802 | options.success && options.success()
803 | }
804 | }
805 | //字节跳动
806 | if (isApiNotImplemented("getConnectedWifi")) {
807 | // 获取设备当前所连的 WiFi 信息
808 | uni.getConnectedWifi = function (options) {
809 | console.warn("api: uni.getConnectedWifi 初获取设备当前所连的 WiFi 信息 在当前平台不支持")
810 | options.success && options.success()
811 | }
812 | }
813 | }
814 |
815 | /**
816 | * 蓝牙
817 | */
818 | function bluetoothPolyfill () {
819 | //蓝牙
820 | if (isApiNotImplemented("openBluetoothAdapter")) {
821 | // 初始化蓝牙模块
822 | uni.openBluetoothAdapter = function (object) {
823 | console.warn("api: uni.openBluetoothAdapter 初始化蓝牙模块 在当前平台不支持")
824 | }
825 | }
826 | if (isApiNotImplemented("startBluetoothDevicesDiscovery")) {
827 | // 开始搜寻附近的蓝牙外围设备
828 | uni.startBluetoothDevicesDiscovery = function (callback) {
829 | console.warn("api: uni.startBluetoothDevicesDiscovery 开始搜寻附近的蓝牙外围设备 在当前平台不支持")
830 | }
831 | }
832 | if (isApiNotImplemented("onBluetoothDeviceFound")) {
833 | // 监听寻找到新设备的事件
834 | uni.onBluetoothDeviceFound = function (callback) {
835 | console.warn("api: uni.onBluetoothDeviceFound 监听寻找到新设备的事件 在当前平台不支持")
836 | }
837 | }
838 | if (isApiNotImplemented("stopBluetoothDevicesDiscovery")) {
839 | // 停止搜寻附近的蓝牙外围设备
840 | uni.stopBluetoothDevicesDiscovery = function (callback) {
841 | console.warn("api: uni.stopBluetoothDevicesDiscovery 停止搜寻附近的蓝牙外围设备 在当前平台不支持")
842 | }
843 | }
844 | if (isApiNotImplemented("onBluetoothAdapterStateChange")) {
845 | // 监听蓝牙适配器状态变化事件
846 | uni.onBluetoothAdapterStateChange = function (callback) {
847 | console.warn("api: uni.onBluetoothAdapterStateChange 监听蓝牙适配器状态变化事件 在当前平台不支持")
848 | }
849 | }
850 | if (isApiNotImplemented("getConnectedBluetoothDevices")) {
851 | // 根据 uuid 获取处于已连接状态的设备
852 | uni.getConnectedBluetoothDevices = function (callback) {
853 | console.warn("api: uni.getConnectedBluetoothDevices 根据 uuid 获取处于已连接状态的设备 在当前平台不支持")
854 | }
855 | }
856 | if (isApiNotImplemented("getBluetoothDevices")) {
857 | // 获取在蓝牙模块生效期间所有已发现的蓝牙设备
858 | uni.getBluetoothDevices = function (callback) {
859 | console.warn("api: uni.getBluetoothDevices 获取在蓝牙模块生效期间所有已发现的蓝牙设备 在当前平台不支持")
860 | }
861 | }
862 | if (isApiNotImplemented("getBluetoothAdapterState")) {
863 | // 获取本机蓝牙适配器状态
864 | uni.getBluetoothAdapterState = function (callback) {
865 | console.warn("api: uni.getBluetoothAdapterState 获取本机蓝牙适配器状态 在当前平台不支持")
866 | }
867 | }
868 | if (isApiNotImplemented("closeBluetoothAdapter")) {
869 | // 关闭蓝牙模块
870 | uni.closeBluetoothAdapter = function (callback) {
871 | console.warn("api: uni.closeBluetoothAdapter 关闭蓝牙模块 在当前平台不支持")
872 | }
873 | }
874 | }
875 |
876 | /**
877 | * 低功耗蓝牙
878 | */
879 | function blePolyfill () {
880 | if (isApiNotImplemented("setBLEMTU")) {
881 | // 设置蓝牙最大传输单元
882 | uni.setBLEMTU = function (callback) {
883 | console.warn("api: uni.setBLEMTU 设置蓝牙最大传输单元 在当前平台不支持")
884 | }
885 | }
886 | if (isApiNotImplemented("readBLECharacteristicValue")) {
887 | // 读取低功耗蓝牙设备的特征值的二进制数据值
888 | uni.readBLECharacteristicValue = function (callback) {
889 | console.warn("api: uni.readBLECharacteristicValue 读取低功耗蓝牙设备的特征值的二进制数据值 在当前平台不支持")
890 | }
891 | }
892 | if (isApiNotImplemented("onBLEConnectionStateChange")) {
893 | // 关闭蓝牙模块
894 | uni.onBLEConnectionStateChange = function (callback) {
895 | console.warn("api: uni.onBLEConnectionStateChange 监听低功耗蓝牙连接状态的改变事件 在当前平台不支持")
896 | }
897 | }
898 | if (isApiNotImplemented("notifyBLECharacteristicValueChange")) {
899 | // 启用低功耗蓝牙设备特征值变化时的 notify 功能
900 | uni.notifyBLECharacteristicValueChange = function (callback) {
901 | console.warn("api: uni.notifyBLECharacteristicValueChange 启用低功耗蓝牙设备特征值变化时的 notify 功能 在当前平台不支持")
902 | }
903 | }
904 | if (isApiNotImplemented("getBLEDeviceServices")) {
905 | // 获取蓝牙设备所有服务
906 | uni.getBLEDeviceServices = function (callback) {
907 | console.warn("api: uni.getBLEDeviceServices 获取蓝牙设备所有服务 在当前平台不支持")
908 | }
909 | }
910 | if (isApiNotImplemented("getBLEDeviceRSSI")) {
911 | // 获取蓝牙设备的信号强度
912 | uni.getBLEDeviceRSSI = function (callback) {
913 | console.warn("api: uni.getBLEDeviceRSSI 获取蓝牙设备的信号强度 在当前平台不支持")
914 | }
915 | }
916 | if (isApiNotImplemented("createBLEConnection")) {
917 | // 连接低功耗蓝牙设备
918 | uni.createBLEConnection = function (callback) {
919 | console.warn("api: uni.createBLEConnection 连接低功耗蓝牙设备 在当前平台不支持")
920 | }
921 | }
922 | if (isApiNotImplemented("closeBLEConnection")) {
923 | // 断开与低功耗蓝牙设备的连接
924 | uni.closeBLEConnection = function (callback) {
925 | console.warn("api: uni.closeBLEConnection 断开与低功耗蓝牙设备的连接 在当前平台不支持")
926 | }
927 | }
928 | }
929 |
930 | /**
931 | * iBeacon
932 | */
933 | function iBeaconPolyfill () {
934 | if (isApiNotImplemented("onBeaconServiceChange")) {
935 | // 监听 iBeacon 服务状态变化事件
936 | uni.onBeaconServiceChange = function (callback) {
937 | console.warn("api: uni.onBeaconServiceChange 监听 iBeacon 服务状态变化事件 在当前平台不支持")
938 | }
939 | }
940 | if (isApiNotImplemented("onBeaconUpdate")) {
941 | // 监听 iBeacon 设备更新事件
942 | uni.onBeaconUpdate = function (callback) {
943 | console.warn("api: uni.onBeaconUpdate 监听 iBeacon 设备更新事件 在当前平台不支持")
944 | }
945 | }
946 | if (isApiNotImplemented("getBeacons")) {
947 | // 获取所有已搜索到的 iBeacon 设备
948 | uni.getBeacons = function (callback) {
949 | console.warn("api: uni.getBeacons 获取所有已搜索到的 iBeacon 设备 在当前平台不支持")
950 | }
951 | }
952 | if (isApiNotImplemented("startBeaconDiscovery")) {
953 | // 开始搜索附近的 iBeacon 设备
954 | uni.startBeaconDiscovery = function (callback) {
955 | console.warn("api: uni.startBeaconDiscovery 开始搜索附近的 iBeacon 设备 在当前平台不支持")
956 | }
957 | }
958 | if (isApiNotImplemented("stopBeaconDiscovery")) {
959 | // 停止搜索附近的 iBeacon 设备
960 | uni.stopBeaconDiscovery = function (callback) {
961 | console.warn("api: uni.stopBeaconDiscovery 停止搜索附近的 iBeacon 设备 在当前平台不支持")
962 | }
963 | }
964 | }
965 |
966 | /**
967 | * uni.navigateTo 和 uni.redirectTo 不能直接跳转tabbar里面的页面,拦截fail,并当它为tabbar页面时,直接调用uni.switchTab()
968 | */
969 | function routerPolyfill () {
970 | var routerApiFailEventHandle = function (res, options) {
971 | if (res.errMsg.indexOf('tabbar page') > -1) {
972 | console.error('res.errMsg: ' + res.errMsg)
973 | var apiName = res.errMsg.match(/not\s(\w+)\sa/)[1]
974 | console.log(apiName)
975 | var url = options.url
976 | if (url) {
977 | var queryString = url.split('?')[1]
978 | if (queryString) {
979 | console.error(apiName + " 的参数将被忽略:" + queryString)
980 | }
981 | uni.switchTab({
982 | url: url
983 | })
984 | }
985 | }
986 | }
987 |
988 | var routerApiHandle = function (oriLogFunc) {
989 | return function (options) {
990 | try {
991 | if (options.fail) {
992 | options.fail = (function fail (failFun) {
993 | return function (res) {
994 | routerApiFailEventHandle(res, options)
995 | failFun(res)
996 | }
997 | })(options.fail)
998 | } else {
999 | options.fail = function (res) {
1000 | routerApiFailEventHandle(res, options)
1001 | }
1002 | }
1003 | oriLogFunc.call(oriLogFunc, options)
1004 | } catch (e) {
1005 | console.error('uni.navigateTo or uni.redirectTo error', e)
1006 | }
1007 | }
1008 | }
1009 |
1010 | uni.navigateTo = routerApiHandle(uni.navigateTo)
1011 | uni.redirectTo = routerApiHandle(uni.redirectTo)
1012 | }
1013 |
1014 | var isInit = false
1015 | /**
1016 | * polyfill 入口
1017 | */
1018 | function init () {
1019 | if (isInit) return
1020 | isInit = true
1021 |
1022 | console.log("Api polyfill start")
1023 | //条件编译
1024 | platformPolyfill()
1025 | //登录
1026 | loginPolyfill()
1027 | //base64
1028 | base64Polyfill()
1029 | //地图
1030 | mapPolyfill()
1031 | //设备
1032 | devicePolyfill()
1033 |
1034 | //媒体相关
1035 | mediaPolyfill()
1036 |
1037 | //蓝牙
1038 | bluetoothPolyfill()
1039 | //低功耗蓝牙
1040 | blePolyfill()
1041 | //iBeacon
1042 | iBeaconPolyfill()
1043 | //wifi
1044 | wifiPolyfill()
1045 | //电量信息
1046 | batteryPolyfill()
1047 | //nfc
1048 | nfcPolyfill()
1049 | //auth
1050 | soterAuthPolyfill()
1051 |
1052 | //ui
1053 | uiPolyfill()
1054 | //file
1055 | filePolyfill()
1056 | //canvas
1057 | canvasPolyfill()
1058 | //ad
1059 | adPolyfill()
1060 | //plugins
1061 | pluginsPolyfill()
1062 | //other
1063 | otherPolyfill()
1064 |
1065 | //router
1066 | routerPolyfill()
1067 | }
1068 |
1069 |
1070 | module.exports = {
1071 | init,
1072 | guid
1073 | }
1074 |
--------------------------------------------------------------------------------
/sitemap.json:
--------------------------------------------------------------------------------
1 | {
2 | "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
3 | "rules": [{
4 | "action": "allow",
5 | "page": "*"
6 | }]
7 | }
--------------------------------------------------------------------------------
/static/pages/images/7bb5fad244cb931399549aec9faffeca.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/7bb5fad244cb931399549aec9faffeca.png
--------------------------------------------------------------------------------
/static/pages/images/address.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/address.png
--------------------------------------------------------------------------------
/static/pages/images/bg0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/bg0.png
--------------------------------------------------------------------------------
/static/pages/images/bg1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/bg1.png
--------------------------------------------------------------------------------
/static/pages/images/bg3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/bg3.png
--------------------------------------------------------------------------------
/static/pages/images/bg4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/bg4.png
--------------------------------------------------------------------------------
/static/pages/images/bg5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/bg5.png
--------------------------------------------------------------------------------
/static/pages/images/bg6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/bg6.png
--------------------------------------------------------------------------------
/static/pages/images/bg7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/bg7.png
--------------------------------------------------------------------------------
/static/pages/images/bg9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/bg9.png
--------------------------------------------------------------------------------
/static/pages/images/btn1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/btn1.png
--------------------------------------------------------------------------------
/static/pages/images/btn2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/btn2.png
--------------------------------------------------------------------------------
/static/pages/images/icon-arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-arrow.png
--------------------------------------------------------------------------------
/static/pages/images/icon-arrow1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-arrow1.png
--------------------------------------------------------------------------------
/static/pages/images/icon-arrow2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-arrow2.png
--------------------------------------------------------------------------------
/static/pages/images/icon-arrow3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-arrow3.png
--------------------------------------------------------------------------------
/static/pages/images/icon-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-close.png
--------------------------------------------------------------------------------
/static/pages/images/icon-delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-delete.png
--------------------------------------------------------------------------------
/static/pages/images/icon-gou.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-gou.png
--------------------------------------------------------------------------------
/static/pages/images/icon-kefu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-kefu.png
--------------------------------------------------------------------------------
/static/pages/images/icon-mony.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-mony.png
--------------------------------------------------------------------------------
/static/pages/images/icon-nuochema.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-nuochema.png
--------------------------------------------------------------------------------
/static/pages/images/icon-order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-order.png
--------------------------------------------------------------------------------
/static/pages/images/icon-weixin-pay.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-weixin-pay.jpg
--------------------------------------------------------------------------------
/static/pages/images/icon-wenti.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-wenti.png
--------------------------------------------------------------------------------
/static/pages/images/icon-yaoqing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/icon-yaoqing.png
--------------------------------------------------------------------------------
/static/pages/images/img0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/img0.png
--------------------------------------------------------------------------------
/static/pages/images/img1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/img1.png
--------------------------------------------------------------------------------
/static/pages/images/nav-index-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/nav-index-active.png
--------------------------------------------------------------------------------
/static/pages/images/nav-index.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/nav-index.png
--------------------------------------------------------------------------------
/static/pages/images/nav-me-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/nav-me-active.png
--------------------------------------------------------------------------------
/static/pages/images/nav-me.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/nav-me.png
--------------------------------------------------------------------------------
/static/pages/images/nav-shangjin-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/nav-shangjin-active.png
--------------------------------------------------------------------------------
/static/pages/images/nav-shangjin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/nav-shangjin.png
--------------------------------------------------------------------------------
/static/pages/images/qrcode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/static/pages/images/qrcode.png
--------------------------------------------------------------------------------
/transform.log:
--------------------------------------------------------------------------------
1 | !!! NULL docs activeTextEditor return null
2 | buffer sync supports: []
3 | event: [{"range":{"end":{"character":19,"line":106},"start":{"character":27,"line":69}},"rangeLength":850,"rangeOffset":2768,"text":""}]
4 | buffer sync supports: [{"fileName":"e:/mywww/miniprograms_uni/pages/bindCarnumber/bindCarnumber.vue","textChanges":[{"newText":"","start":{"line":70,"offset":28},"end":{"line":107,"offset":20}}]}]
5 | cancel last request:0
6 | cancel last request:0
7 | sendEvent willSaveTextDocument
8 | buffer sync supports: []
9 | diagnostics.$changeMany
10 | buffer sync supports: []
11 | diagnostics.$changeMany
12 | buffer sync supports: []
13 | diagnostics.$changeMany
14 | buffer sync supports: []
15 | diagnostics.$changeMany
16 | buffer sync supports: []
17 | diagnostics.$changeMany
18 | buffer sync supports: []
19 | diagnostics.$changeMany
20 | buffer sync supports: []
21 | diagnostics.$changeMany
22 | buffer sync supports: []
23 | diagnostics.$changeMany
24 | buffer sync supports: []
25 | cancel last request:0
26 | event: [{"range":{"end":{"character":10,"line":33},"start":{"character":15,"line":29}},"rangeLength":190,"rangeOffset":1531,"text":""}]
27 | buffer sync supports: [{"fileName":"e:/mywww/miniprograms_uni/pages/bindCarnumber/bindCarnumber.vue","textChanges":[{"newText":"","start":{"line":30,"offset":16},"end":{"line":34,"offset":11}}]}]
28 | sendEvent willSaveTextDocument
29 | cancel last request:0
30 | cancel last request:0
31 | cancel last request:0
32 | cancel last request:0
33 |
--------------------------------------------------------------------------------
/uni.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * 这里是uni-app内置的常用样式变量
3 | *
4 | * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
5 | * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
6 | *
7 | */
8 |
9 | /**
10 | * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
11 | *
12 | * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
13 | */
14 |
15 | /* 颜色变量 */
16 |
17 | /* 行为相关颜色 */
18 | $uni-color-primary: #007aff;
19 | $uni-color-success: #4cd964;
20 | $uni-color-warning: #f0ad4e;
21 | $uni-color-error: #dd524d;
22 |
23 | /* 文字基本颜色 */
24 | $uni-text-color:#333;//基本色
25 | $uni-text-color-inverse:#fff;//反色
26 | $uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
27 | $uni-text-color-placeholder: #808080;
28 | $uni-text-color-disable:#c0c0c0;
29 |
30 | /* 背景颜色 */
31 | $uni-bg-color:#ffffff;
32 | $uni-bg-color-grey:#f8f8f8;
33 | $uni-bg-color-hover:#f1f1f1;//点击状态颜色
34 | $uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
35 |
36 | /* 边框颜色 */
37 | $uni-border-color:#c8c7cc;
38 |
39 | /* 尺寸变量 */
40 |
41 | /* 文字尺寸 */
42 | $uni-font-size-sm:12px;
43 | $uni-font-size-base:14px;
44 | $uni-font-size-lg:16;
45 |
46 | /* 图片尺寸 */
47 | $uni-img-size-sm:20px;
48 | $uni-img-size-base:26px;
49 | $uni-img-size-lg:40px;
50 |
51 | /* Border Radius */
52 | $uni-border-radius-sm: 2px;
53 | $uni-border-radius-base: 3px;
54 | $uni-border-radius-lg: 6px;
55 | $uni-border-radius-circle: 50%;
56 |
57 | /* 水平间距 */
58 | $uni-spacing-row-sm: 5px;
59 | $uni-spacing-row-base: 10px;
60 | $uni-spacing-row-lg: 15px;
61 |
62 | /* 垂直间距 */
63 | $uni-spacing-col-sm: 4px;
64 | $uni-spacing-col-base: 8px;
65 | $uni-spacing-col-lg: 12px;
66 |
67 | /* 透明度 */
68 | $uni-opacity-disabled: 0.3; // 组件禁用态的透明度
69 |
70 | /* 文章场景相关 */
71 | $uni-color-title: #2C405A; // 文章标题颜色
72 | $uni-font-size-title:20px;
73 | $uni-color-subtitle: #555555; // 二级标题颜色
74 | $uni-font-size-subtitle:26px;
75 | $uni-color-paragraph: #3F536E; // 文章段落颜色
76 | $uni-font-size-paragraph:15px;
77 |
--------------------------------------------------------------------------------
/uni_modules/mp-html/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/uni_modules/mp-html/README.md
--------------------------------------------------------------------------------
/uni_modules/mp-html/changelog.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsanproject/uniappnc/ad6e03fc5b4c77a73d090580860c3075ad851550/uni_modules/mp-html/changelog.md
--------------------------------------------------------------------------------
/uni_modules/mp-html/components/mp-html/mp-html.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
446 |
447 |
463 |
--------------------------------------------------------------------------------
/uni_modules/mp-html/components/mp-html/node/node.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | {{n.text}}
20 |
21 | \n
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
101 |
372 |
--------------------------------------------------------------------------------
/uni_modules/mp-html/components/mp-html/parser.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @fileoverview html 解析器
3 | */
4 |
5 | // 配置
6 | const config = {
7 | // 信任的标签(保持标签名不变)
8 | trustTags: makeMap('a,abbr,ad,audio,b,blockquote,br,code,col,colgroup,dd,del,dl,dt,div,em,fieldset,h1,h2,h3,h4,h5,h6,hr,i,img,ins,label,legend,li,ol,p,q,ruby,rt,source,span,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,title,ul,video'),
9 |
10 | // 块级标签(转为 div,其他的非信任标签转为 span)
11 | blockTags: makeMap('address,article,aside,body,caption,center,cite,footer,header,html,nav,pre,section'),
12 |
13 | // #ifdef (MP-WEIXIN || MP-QQ || APP-PLUS || MP-360) && VUE3
14 | // 行内标签
15 | inlineTags: makeMap('abbr,b,big,code,del,em,i,ins,label,q,small,span,strong,sub,sup'),
16 | // #endif
17 |
18 | // 要移除的标签
19 | ignoreTags: makeMap('area,base,canvas,embed,frame,head,iframe,input,link,map,meta,param,rp,script,source,style,textarea,title,track,wbr'),
20 |
21 | // 自闭合的标签
22 | voidTags: makeMap('area,base,br,col,circle,ellipse,embed,frame,hr,img,input,line,link,meta,param,path,polygon,rect,source,track,use,wbr'),
23 |
24 | // html 实体
25 | entities: {
26 | lt: '<',
27 | gt: '>',
28 | quot: '"',
29 | apos: "'",
30 | ensp: '\u2002',
31 | emsp: '\u2003',
32 | nbsp: '\xA0',
33 | semi: ';',
34 | ndash: '–',
35 | mdash: '—',
36 | middot: '·',
37 | lsquo: '‘',
38 | rsquo: '’',
39 | ldquo: '“',
40 | rdquo: '”',
41 | bull: '•',
42 | hellip: '…',
43 | larr: '←',
44 | uarr: '↑',
45 | rarr: '→',
46 | darr: '↓'
47 | },
48 |
49 | // 默认的标签样式
50 | tagStyle: {
51 | // #ifndef APP-PLUS-NVUE
52 | address: 'font-style:italic',
53 | big: 'display:inline;font-size:1.2em',
54 | caption: 'display:table-caption;text-align:center',
55 | center: 'text-align:center',
56 | cite: 'font-style:italic',
57 | dd: 'margin-left:40px',
58 | mark: 'background-color:yellow',
59 | pre: 'font-family:monospace;white-space:pre',
60 | s: 'text-decoration:line-through',
61 | small: 'display:inline;font-size:0.8em',
62 | strike: 'text-decoration:line-through',
63 | u: 'text-decoration:underline'
64 | // #endif
65 | },
66 |
67 | // svg 大小写对照表
68 | svgDict: {
69 | animatetransform: 'animateTransform',
70 | lineargradient: 'linearGradient',
71 | viewbox: 'viewBox',
72 | attributename: 'attributeName',
73 | repeatcount: 'repeatCount',
74 | repeatdur: 'repeatDur'
75 | }
76 | }
77 | const tagSelector={}
78 | const {
79 | windowWidth,
80 | // #ifdef MP-WEIXIN
81 | system
82 | // #endif
83 | } = uni.getSystemInfoSync()
84 | const blankChar = makeMap(' ,\r,\n,\t,\f')
85 | let idIndex = 0
86 |
87 | // #ifdef H5 || APP-PLUS
88 | config.ignoreTags.iframe = undefined
89 | config.trustTags.iframe = true
90 | config.ignoreTags.embed = undefined
91 | config.trustTags.embed = true
92 | // #endif
93 | // #ifdef APP-PLUS-NVUE
94 | config.ignoreTags.source = undefined
95 | config.ignoreTags.style = undefined
96 | // #endif
97 |
98 | /**
99 | * @description 创建 map
100 | * @param {String} str 逗号分隔
101 | */
102 | function makeMap (str) {
103 | const map = Object.create(null)
104 | const list = str.split(',')
105 | for (let i = list.length; i--;) {
106 | map[list[i]] = true
107 | }
108 | return map
109 | }
110 |
111 | /**
112 | * @description 解码 html 实体
113 | * @param {String} str 要解码的字符串
114 | * @param {Boolean} amp 要不要解码 &
115 | * @returns {String} 解码后的字符串
116 | */
117 | function decodeEntity (str, amp) {
118 | let i = str.indexOf('&')
119 | while (i !== -1) {
120 | const j = str.indexOf(';', i + 3)
121 | let code
122 | if (j === -1) break
123 | if (str[i + 1] === '#') {
124 | // { 形式的实体
125 | code = parseInt((str[i + 2] === 'x' ? '0' : '') + str.substring(i + 2, j))
126 | if (!isNaN(code)) {
127 | str = str.substr(0, i) + String.fromCharCode(code) + str.substr(j + 1)
128 | }
129 | } else {
130 | // 形式的实体
131 | code = str.substring(i + 1, j)
132 | if (config.entities[code] || (code === 'amp' && amp)) {
133 | str = str.substr(0, i) + (config.entities[code] || '&') + str.substr(j + 1)
134 | }
135 | }
136 | i = str.indexOf('&', i + 1)
137 | }
138 | return str
139 | }
140 |
141 | /**
142 | * @description html 解析器
143 | * @param {Object} vm 组件实例
144 | */
145 | function Parser (vm) {
146 | this.options = vm || {}
147 | this.tagStyle = Object.assign({}, config.tagStyle, this.options.tagStyle)
148 | this.imgList = vm.imgList || []
149 | this.plugins = vm.plugins || []
150 | this.attrs = Object.create(null)
151 | this.stack = []
152 | this.nodes = []
153 | this.pre = (this.options.containerStyle || '').includes('white-space') && this.options.containerStyle.includes('pre') ? 2 : 0
154 | }
155 |
156 | /**
157 | * @description 执行解析
158 | * @param {String} content 要解析的文本
159 | */
160 | Parser.prototype.parse = function (content) {
161 | // 插件处理
162 | for (let i = this.plugins.length; i--;) {
163 | if (this.plugins[i].onUpdate) {
164 | content = this.plugins[i].onUpdate(content, config) || content
165 | }
166 | }
167 |
168 | new Lexer(this).parse(content)
169 | // 出栈未闭合的标签
170 | while (this.stack.length) {
171 | this.popNode()
172 | }
173 | return this.nodes
174 | }
175 |
176 | /**
177 | * @description 将标签暴露出来(不被 rich-text 包含)
178 | */
179 | Parser.prototype.expose = function () {
180 | // #ifndef APP-PLUS-NVUE
181 | for (let i = this.stack.length; i--;) {
182 | const item = this.stack[i]
183 | if (item.c || item.name === 'a' || item.name === 'video' || item.name === 'audio') return
184 | item.c = 1
185 | }
186 | // #endif
187 | }
188 |
189 | /**
190 | * @description 处理插件
191 | * @param {Object} node 要处理的标签
192 | * @returns {Boolean} 是否要移除此标签
193 | */
194 | Parser.prototype.hook = function (node) {
195 | for (let i = this.plugins.length; i--;) {
196 | if (this.plugins[i].onParse && this.plugins[i].onParse(node, this) === false) {
197 | return false
198 | }
199 | }
200 | return true
201 | }
202 |
203 | /**
204 | * @description 将链接拼接上主域名
205 | * @param {String} url 需要拼接的链接
206 | * @returns {String} 拼接后的链接
207 | */
208 | Parser.prototype.getUrl = function (url) {
209 | const domain = this.options.domain
210 | if (url[0] === '/') {
211 | if (url[1] === '/') {
212 | // // 开头的补充协议名
213 | url = (domain ? domain.split('://')[0] : 'http') + ':' + url
214 | } else if (domain) {
215 | // 否则补充整个域名
216 | url = domain + url
217 | } /* #ifdef APP-PLUS */ else {
218 | url = plus.io.convertLocalFileSystemURL(url)
219 | } /* #endif */
220 | } else if (!url.includes('data:') && !url.includes('://')) {
221 | if (domain) {
222 | url = domain + '/' + url
223 | } /* #ifdef APP-PLUS */ else {
224 | url = plus.io.convertLocalFileSystemURL(url)
225 | } /* #endif */
226 | }
227 | return url
228 | }
229 |
230 | /**
231 | * @description 解析样式表
232 | * @param {Object} node 标签
233 | * @returns {Object}
234 | */
235 | Parser.prototype.parseStyle = function (node) {
236 | const attrs = node.attrs
237 | const list = (this.tagStyle[node.name] || '').split(';').concat((attrs.style || '').split(';'))
238 | const styleObj = {}
239 | let tmp = ''
240 |
241 | if (attrs.id && !this.xml) {
242 | // 暴露锚点
243 | if (this.options.useAnchor) {
244 | this.expose()
245 | } else if (node.name !== 'img' && node.name !== 'a' && node.name !== 'video' && node.name !== 'audio') {
246 | attrs.id = undefined
247 | }
248 | }
249 |
250 | // 转换 width 和 height 属性
251 | if (attrs.width) {
252 | styleObj.width = parseFloat(attrs.width) + (attrs.width.includes('%') ? '%' : 'px')
253 | attrs.width = undefined
254 | }
255 | if (attrs.height) {
256 | styleObj.height = parseFloat(attrs.height) + (attrs.height.includes('%') ? '%' : 'px')
257 | attrs.height = undefined
258 | }
259 |
260 | for (let i = 0, len = list.length; i < len; i++) {
261 | const info = list[i].split(':')
262 | if (info.length < 2) continue
263 | const key = info.shift().trim().toLowerCase()
264 | let value = info.join(':').trim()
265 | if ((value[0] === '-' && value.lastIndexOf('-') > 0) || value.includes('safe')) {
266 | // 兼容性的 css 不压缩
267 | tmp += `;${key}:${value}`
268 | } else if (!styleObj[key] || value.includes('import') || !styleObj[key].includes('import')) {
269 | // 重复的样式进行覆盖
270 | if (value.includes('url')) {
271 | // 填充链接
272 | let j = value.indexOf('(') + 1
273 | if (j) {
274 | while (value[j] === '"' || value[j] === "'" || blankChar[value[j]]) {
275 | j++
276 | }
277 | value = value.substr(0, j) + this.getUrl(value.substr(j))
278 | }
279 | } else if (value.includes('rpx')) {
280 | // 转换 rpx(rich-text 内部不支持 rpx)
281 | value = value.replace(/[0-9.]+\s*rpx/g, $ => parseFloat($) * windowWidth / 750 + 'px')
282 | }
283 | styleObj[key] = value
284 | }
285 | }
286 |
287 | node.attrs.style = tmp
288 | return styleObj
289 | }
290 |
291 | /**
292 | * @description 解析到标签名
293 | * @param {String} name 标签名
294 | * @private
295 | */
296 | Parser.prototype.onTagName = function (name) {
297 | this.tagName = this.xml ? name : name.toLowerCase()
298 | if (this.tagName === 'svg') {
299 | this.xml = (this.xml || 0) + 1 // svg 标签内大小写敏感
300 | }
301 | }
302 |
303 | /**
304 | * @description 解析到属性名
305 | * @param {String} name 属性名
306 | * @private
307 | */
308 | Parser.prototype.onAttrName = function (name) {
309 | name = this.xml ? name : name.toLowerCase()
310 | if (name.substr(0, 5) === 'data-') {
311 | if (name === 'data-src' && !this.attrs.src) {
312 | // data-src 自动转为 src
313 | this.attrName = 'src'
314 | } else if (this.tagName === 'img' || this.tagName === 'a') {
315 | // a 和 img 标签保留 data- 的属性,可以在 imgtap 和 linktap 事件中使用
316 | this.attrName = name
317 | } else {
318 | // 剩余的移除以减小大小
319 | this.attrName = undefined
320 | }
321 | } else {
322 | this.attrName = name
323 | this.attrs[name] = 'T' // boolean 型属性缺省设置
324 | }
325 | }
326 |
327 | /**
328 | * @description 解析到属性值
329 | * @param {String} val 属性值
330 | * @private
331 | */
332 | Parser.prototype.onAttrVal = function (val) {
333 | const name = this.attrName || ''
334 | if (name === 'style' || name === 'href') {
335 | // 部分属性进行实体解码
336 | this.attrs[name] = decodeEntity(val, true)
337 | } else if (name.includes('src')) {
338 | // 拼接主域名
339 | this.attrs[name] = this.getUrl(decodeEntity(val, true))
340 | } else if (name) {
341 | this.attrs[name] = val
342 | }
343 | }
344 |
345 | /**
346 | * @description 解析到标签开始
347 | * @param {Boolean} selfClose 是否有自闭合标识 />
348 | * @private
349 | */
350 | Parser.prototype.onOpenTag = function (selfClose) {
351 | // 拼装 node
352 | const node = Object.create(null)
353 | node.name = this.tagName
354 | node.attrs = this.attrs
355 | // 避免因为自动 diff 使得 type 被设置为 null 导致部分内容不显示
356 | if (this.options.nodes.length) {
357 | node.type = 'node'
358 | }
359 | this.attrs = Object.create(null)
360 |
361 | const attrs = node.attrs
362 | const parent = this.stack[this.stack.length - 1]
363 | const siblings = parent ? parent.children : this.nodes
364 | const close = this.xml ? selfClose : config.voidTags[node.name]
365 |
366 | // 替换标签名选择器
367 | if (tagSelector[node.name]) {
368 | attrs.class = tagSelector[node.name] + (attrs.class ? ' ' + attrs.class : '')
369 | }
370 |
371 | // 转换 embed 标签
372 | if (node.name === 'embed') {
373 | // #ifndef H5 || APP-PLUS
374 | const src = attrs.src || ''
375 | // 按照后缀名和 type 将 embed 转为 video 或 audio
376 | if (src.includes('.mp4') || src.includes('.3gp') || src.includes('.m3u8') || (attrs.type || '').includes('video')) {
377 | node.name = 'video'
378 | } else if (src.includes('.mp3') || src.includes('.wav') || src.includes('.aac') || src.includes('.m4a') || (attrs.type || '').includes('audio')) {
379 | node.name = 'audio'
380 | }
381 | if (attrs.autostart) {
382 | attrs.autoplay = 'T'
383 | }
384 | attrs.controls = 'T'
385 | // #endif
386 | // #ifdef H5 || APP-PLUS
387 | this.expose()
388 | // #endif
389 | }
390 |
391 | // #ifndef APP-PLUS-NVUE
392 | // 处理音视频
393 | if (node.name === 'video' || node.name === 'audio') {
394 | // 设置 id 以便获取 context
395 | if (node.name === 'video' && !attrs.id) {
396 | attrs.id = 'v' + idIndex++
397 | }
398 | // 没有设置 controls 也没有设置 autoplay 的自动设置 controls
399 | if (!attrs.controls && !attrs.autoplay) {
400 | attrs.controls = 'T'
401 | }
402 | // 用数组存储所有可用的 source
403 | node.src = []
404 | if (attrs.src) {
405 | node.src.push(attrs.src)
406 | attrs.src = undefined
407 | }
408 | this.expose()
409 | }
410 | // #endif
411 |
412 | // 处理自闭合标签
413 | if (close) {
414 | if (!this.hook(node) || config.ignoreTags[node.name]) {
415 | // 通过 base 标签设置主域名
416 | if (node.name === 'base' && !this.options.domain) {
417 | this.options.domain = attrs.href
418 | } /* #ifndef APP-PLUS-NVUE */ else if (node.name === 'source' && parent && (parent.name === 'video' || parent.name === 'audio') && attrs.src) {
419 | // 设置 source 标签(仅父节点为 video 或 audio 时有效)
420 | parent.src.push(attrs.src)
421 | } /* #endif */
422 | return
423 | }
424 |
425 | // 解析 style
426 | const styleObj = this.parseStyle(node)
427 |
428 | // 处理图片
429 | if (node.name === 'img') {
430 | if (attrs.src) {
431 | // 标记 webp
432 | if (attrs.src.includes('webp')) {
433 | node.webp = 'T'
434 | }
435 | // data url 图片如果没有设置 original-src 默认为不可预览的小图片
436 | if (attrs.src.includes('data:') && !attrs['original-src']) {
437 | attrs.ignore = 'T'
438 | }
439 | if (!attrs.ignore || node.webp || attrs.src.includes('cloud://')) {
440 | for (let i = this.stack.length; i--;) {
441 | const item = this.stack[i]
442 | if (item.name === 'a') {
443 | node.a = item.attrs
444 | break
445 | }
446 | // #ifndef H5 || APP-PLUS
447 | const style = item.attrs.style || ''
448 | if (style.includes('flex:') && !style.includes('flex:0') && !style.includes('flex: 0') && (!styleObj.width || !styleObj.width.includes('%'))) {
449 | styleObj.width = '100% !important'
450 | styleObj.height = ''
451 | for (let j = i + 1; j < this.stack.length; j++) {
452 | this.stack[j].attrs.style = (this.stack[j].attrs.style || '').replace('inline-', '')
453 | }
454 | } else if (style.includes('flex') && styleObj.width === '100%') {
455 | for (let j = i + 1; j < this.stack.length; j++) {
456 | const style = this.stack[j].attrs.style || ''
457 | if (!style.includes(';width') && !style.includes(' width') && style.indexOf('width') !== 0) {
458 | styleObj.width = ''
459 | break
460 | }
461 | }
462 | } else if (style.includes('inline-block')) {
463 | if (styleObj.width && styleObj.width[styleObj.width.length - 1] === '%') {
464 | item.attrs.style += ';max-width:' + styleObj.width
465 | styleObj.width = ''
466 | } else {
467 | item.attrs.style += ';max-width:100%'
468 | }
469 | }
470 | // #endif
471 | item.c = 1
472 | }
473 | attrs.i = this.imgList.length.toString()
474 | let src = attrs['original-src'] || attrs.src
475 | // #ifndef H5 || MP-ALIPAY || APP-PLUS || MP-360
476 | if (this.imgList.includes(src)) {
477 | // 如果有重复的链接则对域名进行随机大小写变换避免预览时错位
478 | let i = src.indexOf('://')
479 | if (i !== -1) {
480 | i += 3
481 | let newSrc = src.substr(0, i)
482 | for (; i < src.length; i++) {
483 | if (src[i] === '/') break
484 | newSrc += Math.random() > 0.5 ? src[i].toUpperCase() : src[i]
485 | }
486 | newSrc += src.substr(i)
487 | src = newSrc
488 | }
489 | }
490 | // #endif
491 | this.imgList.push(src)
492 | // #ifdef H5 || APP-PLUS
493 | if (this.options.lazyLoad) {
494 | attrs['data-src'] = attrs.src
495 | attrs.src = undefined
496 | }
497 | // #endif
498 | }
499 | }
500 | if (styleObj.display === 'inline') {
501 | styleObj.display = ''
502 | }
503 | // #ifndef APP-PLUS-NVUE
504 | if (attrs.ignore) {
505 | styleObj['max-width'] = styleObj['max-width'] || '100%'
506 | attrs.style += ';-webkit-touch-callout:none'
507 | }
508 | // #endif
509 | // 设置的宽度超出屏幕,为避免变形,高度转为自动
510 | if (parseInt(styleObj.width) > windowWidth) {
511 | styleObj.height = undefined
512 | }
513 | // 记录是否设置了宽高
514 | if (!isNaN(parseInt(styleObj.width))) {
515 | node.w = 'T'
516 | }
517 | if (!isNaN(parseInt(styleObj.height)) && (!styleObj.height.includes('%') || (parent && (parent.attrs.style || '').includes('height')))) {
518 | node.h = 'T'
519 | }
520 | } else if (node.name === 'svg') {
521 | siblings.push(node)
522 | this.stack.push(node)
523 | this.popNode()
524 | return
525 | }
526 | for (const key in styleObj) {
527 | if (styleObj[key]) {
528 | attrs.style += `;${key}:${styleObj[key].replace(' !important', '')}`
529 | }
530 | }
531 | attrs.style = attrs.style.substr(1) || undefined
532 | // #ifdef (MP-WEIXIN || MP-QQ) && VUE3
533 | if (!attrs.style) {
534 | delete attrs.style
535 | }
536 | // #endif
537 | } else {
538 | if ((node.name === 'pre' || ((attrs.style || '').includes('white-space') && attrs.style.includes('pre'))) && this.pre !== 2) {
539 | this.pre = node.pre = 1
540 | }
541 | node.children = []
542 | this.stack.push(node)
543 | }
544 |
545 | // 加入节点树
546 | siblings.push(node)
547 | }
548 |
549 | /**
550 | * @description 解析到标签结束
551 | * @param {String} name 标签名
552 | * @private
553 | */
554 | Parser.prototype.onCloseTag = function (name) {
555 | // 依次出栈到匹配为止
556 | name = this.xml ? name : name.toLowerCase()
557 | let i
558 | for (i = this.stack.length; i--;) {
559 | if (this.stack[i].name === name) break
560 | }
561 | if (i !== -1) {
562 | while (this.stack.length > i) {
563 | this.popNode()
564 | }
565 | } else if (name === 'p' || name === 'br') {
566 | const siblings = this.stack.length ? this.stack[this.stack.length - 1].children : this.nodes
567 | siblings.push({
568 | name,
569 | attrs: {
570 | class: tagSelector[name] || '',
571 | style: this.tagStyle[name] || ''
572 | }
573 | })
574 | }
575 | }
576 |
577 | /**
578 | * @description 处理标签出栈
579 | * @private
580 | */
581 | Parser.prototype.popNode = function () {
582 | const node = this.stack.pop()
583 | let attrs = node.attrs
584 | const children = node.children
585 | const parent = this.stack[this.stack.length - 1]
586 | const siblings = parent ? parent.children : this.nodes
587 |
588 | if (!this.hook(node) || config.ignoreTags[node.name]) {
589 | // 获取标题
590 | if (node.name === 'title' && children.length && children[0].type === 'text' && this.options.setTitle) {
591 | uni.setNavigationBarTitle({
592 | title: children[0].text
593 | })
594 | }
595 | siblings.pop()
596 | return
597 | }
598 |
599 | if (node.pre && this.pre !== 2) {
600 | // 是否合并空白符标识
601 | this.pre = node.pre = undefined
602 | for (let i = this.stack.length; i--;) {
603 | if (this.stack[i].pre) {
604 | this.pre = 1
605 | }
606 | }
607 | }
608 |
609 | const styleObj = {}
610 |
611 | // 转换 svg
612 | if (node.name === 'svg') {
613 | if (this.xml > 1) {
614 | // 多层 svg 嵌套
615 | this.xml--
616 | return
617 | }
618 | // #ifdef APP-PLUS-NVUE
619 | (function traversal (node) {
620 | if (node.name) {
621 | // 调整 svg 的大小写
622 | node.name = config.svgDict[node.name] || node.name
623 | for (const item in node.attrs) {
624 | if (config.svgDict[item]) {
625 | node.attrs[config.svgDict[item]] = node.attrs[item]
626 | node.attrs[item] = undefined
627 | }
628 | }
629 | for (let i = 0; i < (node.children || []).length; i++) {
630 | traversal(node.children[i])
631 | }
632 | }
633 | })(node)
634 | // #endif
635 | // #ifndef APP-PLUS-NVUE
636 | let src = ''
637 | const style = attrs.style
638 | attrs.style = ''
639 | attrs.xmlns = 'http://www.w3.org/2000/svg';
640 | (function traversal (node) {
641 | if (node.type === 'text') {
642 | src += node.text
643 | return
644 | }
645 | const name = config.svgDict[node.name] || node.name
646 | src += '<' + name
647 | for (const item in node.attrs) {
648 | const val = node.attrs[item]
649 | if (val) {
650 | src += ` ${config.svgDict[item] || item}="${val}"`
651 | }
652 | }
653 | if (!node.children) {
654 | src += '/>'
655 | } else {
656 | src += '>'
657 | for (let i = 0; i < node.children.length; i++) {
658 | traversal(node.children[i])
659 | }
660 | src += '' + name + '>'
661 | }
662 | })(node)
663 | node.name = 'img'
664 | node.attrs = {
665 | src: 'data:image/svg+xml;utf8,' + src.replace(/#/g, '%23'),
666 | style,
667 | ignore: 'T'
668 | }
669 | node.children = undefined
670 | // #endif
671 | this.xml = false
672 | return
673 | }
674 |
675 | // #ifndef APP-PLUS-NVUE
676 | // 转换 align 属性
677 | if (attrs.align) {
678 | if (node.name === 'table') {
679 | if (attrs.align === 'center') {
680 | styleObj['margin-inline-start'] = styleObj['margin-inline-end'] = 'auto'
681 | } else {
682 | styleObj.float = attrs.align
683 | }
684 | } else {
685 | styleObj['text-align'] = attrs.align
686 | }
687 | attrs.align = undefined
688 | }
689 |
690 | // 转换 dir 属性
691 | if (attrs.dir) {
692 | styleObj.direction = attrs.dir
693 | attrs.dir = undefined
694 | }
695 |
696 | // 转换 font 标签的属性
697 | if (node.name === 'font') {
698 | if (attrs.color) {
699 | styleObj.color = attrs.color
700 | attrs.color = undefined
701 | }
702 | if (attrs.face) {
703 | styleObj['font-family'] = attrs.face
704 | attrs.face = undefined
705 | }
706 | if (attrs.size) {
707 | let size = parseInt(attrs.size)
708 | if (!isNaN(size)) {
709 | if (size < 1) {
710 | size = 1
711 | } else if (size > 7) {
712 | size = 7
713 | }
714 | styleObj['font-size'] = ['x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', 'xxx-large'][size - 1]
715 | }
716 | attrs.size = undefined
717 | }
718 | }
719 | // #endif
720 |
721 | // 一些编辑器的自带 class
722 | if ((attrs.class || '').includes('align-center')) {
723 | styleObj['text-align'] = 'center'
724 | }
725 |
726 | Object.assign(styleObj, this.parseStyle(node))
727 |
728 | if (node.name !== 'table' && parseInt(styleObj.width) > windowWidth) {
729 | styleObj['max-width'] = '100%'
730 | styleObj['box-sizing'] = 'border-box'
731 | }
732 |
733 | // #ifndef APP-PLUS-NVUE
734 | if (config.blockTags[node.name]) {
735 | node.name = 'div'
736 | } else if (!config.trustTags[node.name] && !this.xml) {
737 | // 未知标签转为 span,避免无法显示
738 | node.name = 'span'
739 | }
740 |
741 | if (node.name === 'a' || node.name === 'ad'
742 | // #ifdef H5 || APP-PLUS
743 | || node.name === 'iframe' // eslint-disable-line
744 | // #endif
745 | ) {
746 | this.expose()
747 | } else if (node.name === 'video') {
748 | if ((styleObj.height || '').includes('auto')) {
749 | styleObj.height = undefined
750 | }
751 | /* #ifdef APP-PLUS */
752 | let str = ''
766 | node.html = str
767 | /* #endif */
768 | } else if ((node.name === 'ul' || node.name === 'ol') && node.c) {
769 | // 列表处理
770 | const types = {
771 | a: 'lower-alpha',
772 | A: 'upper-alpha',
773 | i: 'lower-roman',
774 | I: 'upper-roman'
775 | }
776 | if (types[attrs.type]) {
777 | attrs.style += ';list-style-type:' + types[attrs.type]
778 | attrs.type = undefined
779 | }
780 | for (let i = children.length; i--;) {
781 | if (children[i].name === 'li') {
782 | children[i].c = 1
783 | }
784 | }
785 | } else if (node.name === 'table') {
786 | // 表格处理
787 | // cellpadding、cellspacing、border 这几个常用表格属性需要通过转换实现
788 | let padding = parseFloat(attrs.cellpadding)
789 | let spacing = parseFloat(attrs.cellspacing)
790 | const border = parseFloat(attrs.border)
791 | if (node.c) {
792 | // padding 和 spacing 默认 2
793 | if (isNaN(padding)) {
794 | padding = 2
795 | }
796 | if (isNaN(spacing)) {
797 | spacing = 2
798 | }
799 | }
800 | if (border) {
801 | attrs.style += ';border:' + border + 'px solid gray'
802 | }
803 | if (node.flag && node.c) {
804 | // 有 colspan 或 rowspan 且含有链接的表格通过 grid 布局实现
805 | styleObj.display = 'grid'
806 | if (spacing) {
807 | styleObj['grid-gap'] = spacing + 'px'
808 | styleObj.padding = spacing + 'px'
809 | } else if (border) {
810 | // 无间隔的情况下避免边框重叠
811 | attrs.style += ';border-left:0;border-top:0'
812 | }
813 |
814 | const width = [] // 表格的列宽
815 | const trList = [] // tr 列表
816 | const cells = [] // 保存新的单元格
817 | const map = {}; // 被合并单元格占用的格子
818 |
819 | (function traversal (nodes) {
820 | for (let i = 0; i < nodes.length; i++) {
821 | if (nodes[i].name === 'tr') {
822 | trList.push(nodes[i])
823 | } else {
824 | traversal(nodes[i].children || [])
825 | }
826 | }
827 | })(children)
828 |
829 | for (let row = 1; row <= trList.length; row++) {
830 | let col = 1
831 | for (let j = 0; j < trList[row - 1].children.length; j++) {
832 | const td = trList[row - 1].children[j]
833 | if (td.name === 'td' || td.name === 'th') {
834 | // 这个格子被上面的单元格占用,则列号++
835 | while (map[row + '.' + col]) {
836 | col++
837 | }
838 | let style = td.attrs.style || ''
839 | const start = style.indexOf('width') ? style.indexOf(';width') : 0
840 | // 提取出 td 的宽度
841 | if (start !== -1) {
842 | let end = style.indexOf(';', start + 6)
843 | if (end === -1) {
844 | end = style.length
845 | }
846 | if (!td.attrs.colspan) {
847 | width[col] = style.substring(start ? start + 7 : 6, end)
848 | }
849 | style = style.substr(0, start) + style.substr(end)
850 | }
851 | style += (border ? `;border:${border}px solid gray` + (spacing ? '' : ';border-right:0;border-bottom:0') : '') + (padding ? `;padding:${padding}px` : '')
852 | // 处理列合并
853 | if (td.attrs.colspan) {
854 | style += `;grid-column-start:${col};grid-column-end:${col + parseInt(td.attrs.colspan)}`
855 | if (!td.attrs.rowspan) {
856 | style += `;grid-row-start:${row};grid-row-end:${row + 1}`
857 | }
858 | col += parseInt(td.attrs.colspan) - 1
859 | }
860 | // 处理行合并
861 | if (td.attrs.rowspan) {
862 | style += `;grid-row-start:${row};grid-row-end:${row + parseInt(td.attrs.rowspan)}`
863 | if (!td.attrs.colspan) {
864 | style += `;grid-column-start:${col};grid-column-end:${col + 1}`
865 | }
866 | // 记录下方单元格被占用
867 | for (let rowspan = 1; rowspan < td.attrs.rowspan; rowspan++) {
868 | for (let colspan = 0; colspan < (td.attrs.colspan || 1); colspan++) {
869 | map[(row + rowspan) + '.' + (col - colspan)] = 1
870 | }
871 | }
872 | }
873 | if (style) {
874 | td.attrs.style = style
875 | }
876 | cells.push(td)
877 | col++
878 | }
879 | }
880 | if (row === 1) {
881 | let temp = ''
882 | for (let i = 1; i < col; i++) {
883 | temp += (width[i] ? width[i] : 'auto') + ' '
884 | }
885 | styleObj['grid-template-columns'] = temp
886 | }
887 | }
888 | node.children = cells
889 | } else {
890 | // 没有使用合并单元格的表格通过 table 布局实现
891 | if (node.c) {
892 | styleObj.display = 'table'
893 | }
894 | if (!isNaN(spacing)) {
895 | styleObj['border-spacing'] = spacing + 'px'
896 | }
897 | if (border || padding) {
898 | // 遍历
899 | (function traversal (nodes) {
900 | for (let i = 0; i < nodes.length; i++) {
901 | const td = nodes[i]
902 | if (td.name === 'th' || td.name === 'td') {
903 | if (border) {
904 | td.attrs.style = `border:${border}px solid gray;${td.attrs.style || ''}`
905 | }
906 | if (padding) {
907 | td.attrs.style = `padding:${padding}px;${td.attrs.style || ''}`
908 | }
909 | } else if (td.children) {
910 | traversal(td.children)
911 | }
912 | }
913 | })(children)
914 | }
915 | }
916 | // 给表格添加一个单独的横向滚动层
917 | if (this.options.scrollTable && !(attrs.style || '').includes('inline')) {
918 | const table = Object.assign({}, node)
919 | node.name = 'div'
920 | node.attrs = {
921 | style: 'overflow:auto'
922 | }
923 | node.children = [table]
924 | attrs = table.attrs
925 | }
926 | } else if ((node.name === 'td' || node.name === 'th') && (attrs.colspan || attrs.rowspan)) {
927 | for (let i = this.stack.length; i--;) {
928 | if (this.stack[i].name === 'table') {
929 | this.stack[i].flag = 1 // 指示含有合并单元格
930 | break
931 | }
932 | }
933 | } else if (node.name === 'ruby') {
934 | // 转换 ruby
935 | node.name = 'span'
936 | for (let i = 0; i < children.length - 1; i++) {
937 | if (children[i].type === 'text' && children[i + 1].name === 'rt') {
938 | children[i] = {
939 | name: 'div',
940 | attrs: {
941 | style: 'display:inline-block;text-align:center'
942 | },
943 | children: [{
944 | name: 'div',
945 | attrs: {
946 | style: 'font-size:50%;' + (children[i + 1].attrs.style || '')
947 | },
948 | children: children[i + 1].children
949 | }, children[i]]
950 | }
951 | children.splice(i + 1, 1)
952 | }
953 | }
954 | } else if (node.c) {
955 | (function traversal (node) {
956 | node.c = 2
957 | for (let i = node.children.length; i--;) {
958 | const child = node.children[i]
959 | // #ifdef (MP-WEIXIN || MP-QQ || APP-PLUS || MP-360) && VUE3
960 | if (child.name && (config.inlineTags[child.name] || (child.attrs.style || '').includes('inline')) && !child.c) {
961 | traversal(child)
962 | }
963 | // #endif
964 | if (!child.c || child.name === 'table') {
965 | node.c = 1
966 | }
967 | }
968 | })(node)
969 | }
970 |
971 | if ((styleObj.display || '').includes('flex') && !node.c) {
972 | for (let i = children.length; i--;) {
973 | const item = children[i]
974 | if (item.f) {
975 | item.attrs.style = (item.attrs.style || '') + item.f
976 | item.f = undefined
977 | }
978 | }
979 | }
980 | // flex 布局时部分样式需要提取到 rich-text 外层
981 | const flex = parent && ((parent.attrs.style || '').includes('flex') || (parent.attrs.style || '').includes('grid'))
982 | // #ifdef MP-WEIXIN
983 | // 检查基础库版本 virtualHost 是否可用
984 | && !(node.c && wx.getNFCAdapter) // eslint-disable-line
985 | // #endif
986 | // #ifndef MP-WEIXIN || MP-QQ || MP-BAIDU || MP-TOUTIAO
987 | && !node.c // eslint-disable-line
988 | // #endif
989 | if (flex) {
990 | node.f = ';max-width:100%'
991 | }
992 |
993 | // 优化长内容加载速度
994 | if (children.length >= 50 && node.c && !(styleObj.display || '').includes('flex')) {
995 | let i = children.length - 1
996 | for (let j = i; j >= -1; j--) {
997 | // 合并多个块级标签
998 | if (j === -1 || children[j].c || !children[j].name || (children[j].name !== 'div' && children[j].name !== 'p' && children[j].name[0] !== 'h') || (children[j].attrs.style || '').includes('inline')) {
999 | if (i - j >= 5) {
1000 | children.splice(j + 1, i - j, {
1001 | name: 'div',
1002 | attrs: {},
1003 | children: node.children.slice(j + 1, i + 1)
1004 | })
1005 | }
1006 | i = j - 1
1007 | }
1008 | }
1009 | }
1010 | // #endif
1011 |
1012 | for (const key in styleObj) {
1013 | if (styleObj[key]) {
1014 | const val = `;${key}:${styleObj[key].replace(' !important', '')}`
1015 | /* #ifndef APP-PLUS-NVUE */
1016 | if (flex && ((key.includes('flex') && key !== 'flex-direction') || key === 'align-self' || key.includes('grid') || styleObj[key][0] === '-' || (key.includes('width') && val.includes('%')))) {
1017 | node.f += val
1018 | if (key === 'width') {
1019 | attrs.style += ';width:100%'
1020 | }
1021 | } else /* #endif */ {
1022 | attrs.style += val
1023 | }
1024 | }
1025 | }
1026 | attrs.style = attrs.style.substr(1) || undefined
1027 | // #ifdef (MP-WEIXIN || MP-QQ) && VUE3
1028 | for (const key in attrs) {
1029 | if (!attrs[key]) {
1030 | delete attrs[key]
1031 | }
1032 | }
1033 | // #endif
1034 | }
1035 |
1036 | /**
1037 | * @description 解析到文本
1038 | * @param {String} text 文本内容
1039 | */
1040 | Parser.prototype.onText = function (text) {
1041 | if (!this.pre) {
1042 | // 合并空白符
1043 | let trim = ''
1044 | let flag
1045 | for (let i = 0, len = text.length; i < len; i++) {
1046 | if (!blankChar[text[i]]) {
1047 | trim += text[i]
1048 | } else {
1049 | if (trim[trim.length - 1] !== ' ') {
1050 | trim += ' '
1051 | }
1052 | if (text[i] === '\n' && !flag) {
1053 | flag = true
1054 | }
1055 | }
1056 | }
1057 | // 去除含有换行符的空串
1058 | if (trim === ' ' && flag) return
1059 | text = trim
1060 | }
1061 | const node = Object.create(null)
1062 | node.type = 'text'
1063 | // #ifdef (MP-BAIDU || MP-ALIPAY || MP-TOUTIAO) && VUE3
1064 | node.attrs = {}
1065 | // #endif
1066 | node.text = decodeEntity(text)
1067 | if (this.hook(node)) {
1068 | // #ifdef MP-WEIXIN
1069 | if (this.options.selectable === 'force' && system.includes('iOS') && !uni.canIUse('rich-text.user-select')) {
1070 | this.expose()
1071 | }
1072 | // #endif
1073 | const siblings = this.stack.length ? this.stack[this.stack.length - 1].children : this.nodes
1074 | siblings.push(node)
1075 | }
1076 | }
1077 |
1078 | /**
1079 | * @description html 词法分析器
1080 | * @param {Object} handler 高层处理器
1081 | */
1082 | function Lexer (handler) {
1083 | this.handler = handler
1084 | }
1085 |
1086 | /**
1087 | * @description 执行解析
1088 | * @param {String} content 要解析的文本
1089 | */
1090 | Lexer.prototype.parse = function (content) {
1091 | this.content = content || ''
1092 | this.i = 0 // 标记解析位置
1093 | this.start = 0 // 标记一个单词的开始位置
1094 | this.state = this.text // 当前状态
1095 | for (let len = this.content.length; this.i !== -1 && this.i < len;) {
1096 | this.state()
1097 | }
1098 | }
1099 |
1100 | /**
1101 | * @description 检查标签是否闭合
1102 | * @param {String} method 如果闭合要进行的操作
1103 | * @returns {Boolean} 是否闭合
1104 | * @private
1105 | */
1106 | Lexer.prototype.checkClose = function (method) {
1107 | const selfClose = this.content[this.i] === '/'
1108 | if (this.content[this.i] === '>' || (selfClose && this.content[this.i + 1] === '>')) {
1109 | if (method) {
1110 | this.handler[method](this.content.substring(this.start, this.i))
1111 | }
1112 | this.i += selfClose ? 2 : 1
1113 | this.start = this.i
1114 | this.handler.onOpenTag(selfClose)
1115 | if (this.handler.tagName === 'script') {
1116 | this.i = this.content.indexOf('', this.i)
1117 | if (this.i !== -1) {
1118 | this.i += 2
1119 | this.start = this.i
1120 | }
1121 | this.state = this.endTag
1122 | } else {
1123 | this.state = this.text
1124 | }
1125 | return true
1126 | }
1127 | return false
1128 | }
1129 |
1130 | /**
1131 | * @description 文本状态
1132 | * @private
1133 | */
1134 | Lexer.prototype.text = function () {
1135 | this.i = this.content.indexOf('<', this.i) // 查找最近的标签
1136 | if (this.i === -1) {
1137 | // 没有标签了
1138 | if (this.start < this.content.length) {
1139 | this.handler.onText(this.content.substring(this.start, this.content.length))
1140 | }
1141 | return
1142 | }
1143 | const c = this.content[this.i + 1]
1144 | if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
1145 | // 标签开头
1146 | if (this.start !== this.i) {
1147 | this.handler.onText(this.content.substring(this.start, this.i))
1148 | }
1149 | this.start = ++this.i
1150 | this.state = this.tagName
1151 | } else if (c === '/' || c === '!' || c === '?') {
1152 | if (this.start !== this.i) {
1153 | this.handler.onText(this.content.substring(this.start, this.i))
1154 | }
1155 | const next = this.content[this.i + 2]
1156 | if (c === '/' && ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z'))) {
1157 | // 标签结尾
1158 | this.i += 2
1159 | this.start = this.i
1160 | this.state = this.endTag
1161 | return
1162 | }
1163 | // 处理注释
1164 | let end = '-->'
1165 | if (c !== '!' || this.content[this.i + 2] !== '-' || this.content[this.i + 3] !== '-') {
1166 | end = '>'
1167 | }
1168 | this.i = this.content.indexOf(end, this.i)
1169 | if (this.i !== -1) {
1170 | this.i += end.length
1171 | this.start = this.i
1172 | }
1173 | } else {
1174 | this.i++
1175 | }
1176 | }
1177 |
1178 | /**
1179 | * @description 标签名状态
1180 | * @private
1181 | */
1182 | Lexer.prototype.tagName = function () {
1183 | if (blankChar[this.content[this.i]]) {
1184 | // 解析到标签名
1185 | this.handler.onTagName(this.content.substring(this.start, this.i))
1186 | while (blankChar[this.content[++this.i]]);
1187 | if (this.i < this.content.length && !this.checkClose()) {
1188 | this.start = this.i
1189 | this.state = this.attrName
1190 | }
1191 | } else if (!this.checkClose('onTagName')) {
1192 | this.i++
1193 | }
1194 | }
1195 |
1196 | /**
1197 | * @description 属性名状态
1198 | * @private
1199 | */
1200 | Lexer.prototype.attrName = function () {
1201 | let c = this.content[this.i]
1202 | if (blankChar[c] || c === '=') {
1203 | // 解析到属性名
1204 | this.handler.onAttrName(this.content.substring(this.start, this.i))
1205 | let needVal = c === '='
1206 | const len = this.content.length
1207 | while (++this.i < len) {
1208 | c = this.content[this.i]
1209 | if (!blankChar[c]) {
1210 | if (this.checkClose()) return
1211 | if (needVal) {
1212 | // 等号后遇到第一个非空字符
1213 | this.start = this.i
1214 | this.state = this.attrVal
1215 | return
1216 | }
1217 | if (this.content[this.i] === '=') {
1218 | needVal = true
1219 | } else {
1220 | this.start = this.i
1221 | this.state = this.attrName
1222 | return
1223 | }
1224 | }
1225 | }
1226 | } else if (!this.checkClose('onAttrName')) {
1227 | this.i++
1228 | }
1229 | }
1230 |
1231 | /**
1232 | * @description 属性值状态
1233 | * @private
1234 | */
1235 | Lexer.prototype.attrVal = function () {
1236 | const c = this.content[this.i]
1237 | const len = this.content.length
1238 | if (c === '"' || c === "'") {
1239 | // 有冒号的属性
1240 | this.start = ++this.i
1241 | this.i = this.content.indexOf(c, this.i)
1242 | if (this.i === -1) return
1243 | this.handler.onAttrVal(this.content.substring(this.start, this.i))
1244 | } else {
1245 | // 没有冒号的属性
1246 | for (; this.i < len; this.i++) {
1247 | if (blankChar[this.content[this.i]]) {
1248 | this.handler.onAttrVal(this.content.substring(this.start, this.i))
1249 | break
1250 | } else if (this.checkClose('onAttrVal')) return
1251 | }
1252 | }
1253 | while (blankChar[this.content[++this.i]]);
1254 | if (this.i < len && !this.checkClose()) {
1255 | this.start = this.i
1256 | this.state = this.attrName
1257 | }
1258 | }
1259 |
1260 | /**
1261 | * @description 结束标签状态
1262 | * @returns {String} 结束的标签名
1263 | * @private
1264 | */
1265 | Lexer.prototype.endTag = function () {
1266 | const c = this.content[this.i]
1267 | if (blankChar[c] || c === '>' || c === '/') {
1268 | this.handler.onCloseTag(this.content.substring(this.start, this.i))
1269 | if (c !== '>') {
1270 | this.i = this.content.indexOf('>', this.i)
1271 | if (this.i === -1) return
1272 | }
1273 | this.start = ++this.i
1274 | this.state = this.text
1275 | } else {
1276 | this.i++
1277 | }
1278 | }
1279 |
1280 | export default Parser
1281 |
--------------------------------------------------------------------------------
/uni_modules/mp-html/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "mp-html",
3 | "displayName": "mp-html 富文本组件【全端支持,可编辑】",
4 | "version": "v2.3.1",
5 | "description": "一个强大的富文本组件,高效轻量,功能丰富",
6 | "keywords": [
7 | "富文本",
8 | "编辑器",
9 | "html",
10 | "rich-text",
11 | "editor"
12 | ],
13 | "repository": "https://github.com/jin-yufeng/mp-html",
14 | "dcloudext": {
15 | "category": [
16 | "前端组件",
17 | "通用组件"
18 | ],
19 | "sale": {
20 | "regular": {
21 | "price": "0.00"
22 | },
23 | "sourcecode": {
24 | "price": "0.00"
25 | }
26 | },
27 | "contact": {
28 | "qq": ""
29 | },
30 | "declaration": {
31 | "ads": "无",
32 | "data": "无",
33 | "permissions": "无"
34 | },
35 | "npmurl": "https://www.npmjs.com/package/mp-html"
36 | },
37 | "uni_modules": {
38 | "platforms": {
39 | "cloud": {
40 | "tcb": "y",
41 | "aliyun": "y"
42 | },
43 | "client": {
44 | "App": {
45 | "app-vue": "y",
46 | "app-nvue": "y"
47 | },
48 | "H5-mobile": {
49 | "Safari": "y",
50 | "Android Browser": "y",
51 | "微信浏览器(Android)": "y",
52 | "QQ浏览器(Android)": "y"
53 | },
54 | "H5-pc": {
55 | "Chrome": "y",
56 | "IE": "u",
57 | "Edge": "y",
58 | "Firefox": "y",
59 | "Safari": "y"
60 | },
61 | "小程序": {
62 | "微信": "y",
63 | "阿里": "y",
64 | "百度": "y",
65 | "字节跳动": "y",
66 | "QQ": "y"
67 | },
68 | "快应用": {
69 | "华为": "y",
70 | "联盟": "y"
71 | },
72 | "Vue": {
73 | "vue2": "y",
74 | "vue3": "y"
75 | }
76 | }
77 | }
78 | }
79 | }
--------------------------------------------------------------------------------
/uni_modules/mp-html/static/app-plus/mp-html/js/handler.js:
--------------------------------------------------------------------------------
1 | "use strict";function t(t){for(var e=Object.create(null),n=t.attributes.length;n--;)e[t.attributes[n].name]=t.attributes[n].value;return e}function e(){o[1]&&(this.src=o[1],this.onerror=null),this.onclick=null,this.ontouchstart=null,uni.postMessage({data:{action:"onError",source:"img",attrs:t(this)}})}function n(r,i,s){for(var c=0;c0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;a("navigateTo",{url:encodeURI(n)})},navigateBack:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.delta;a("navigateBack",{delta:parseInt(n)||1})},switchTab:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;a("switchTab",{url:encodeURI(n)})},reLaunch:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;a("reLaunch",{url:encodeURI(n)})},redirectTo:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;a("redirectTo",{url:encodeURI(n)})},getEnv:function(e){window.plus?e({plus:!0}):e({h5:!0})},postMessage:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};a("postMessage",e.data||{})}},r=/uni-app/i.test(navigator.userAgent),d=/Html5Plus/i.test(navigator.userAgent),s=/complete|loaded|interactive/;var w=window.my&&navigator.userAgent.indexOf("AlipayClient")>-1;var u=window.swan&&window.swan.webView&&/swan/i.test(navigator.userAgent);var c=window.qq&&window.qq.miniProgram&&/QQ/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var g=window.tt&&window.tt.miniProgram&&/toutiaomicroapp/i.test(navigator.userAgent);var v=window.wx&&window.wx.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var p=window.qa&&/quickapp/i.test(navigator.userAgent);for(var l,_=function(){window.UniAppJSBridge=!0,document.dispatchEvent(new CustomEvent("UniAppJSBridgeReady",{bubbles:!0,cancelable:!0}))},f=[function(e){if(r||d)return window.__dcloud_weex_postMessage||window.__dcloud_weex_?document.addEventListener("DOMContentLoaded",e):window.plus&&s.test(document.readyState)?setTimeout(e,0):document.addEventListener("plusready",e),o},function(e){if(v)return window.WeixinJSBridge&&window.WeixinJSBridge.invoke?setTimeout(e,0):document.addEventListener("WeixinJSBridgeReady",e),window.wx.miniProgram},function(e){if(c)return window.QQJSBridge&&window.QQJSBridge.invoke?setTimeout(e,0):document.addEventListener("QQJSBridgeReady",e),window.qq.miniProgram},function(e){if(w){document.addEventListener("DOMContentLoaded",e);var n=window.my;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){if(u)return document.addEventListener("DOMContentLoaded",e),window.swan.webView},function(e){if(g)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){if(p){window.QaJSBridge&&window.QaJSBridge.invoke?setTimeout(e,0):document.addEventListener("QaJSBridgeReady",e);var n=window.qa;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){return document.addEventListener("DOMContentLoaded",e),o}],m=0;m
--------------------------------------------------------------------------------
/utils/common.js:
--------------------------------------------------------------------------------
1 | function common() {
2 | let time = new Date().getTime() / 1000;
3 | let request_time = time.toString().replace(/\.\d{0,}/g, '');
4 | let uid = uni.getStorageSync('userid');
5 | this.apiurl = ''; //接口域名地址 域名+/addons/mycar 例如 https://www.xxxxxxx.com/addons/mycar
6 |
7 | this.app_token = ''; //需要与插件后台自定义接口密钥配置一致
8 |
9 | this.data = {
10 | url: '',
11 | request_time: request_time
12 | };
13 | this.userinfo = {
14 | uid: uid
15 | };
16 |
17 | this.ajax = function (param, success, fail, complete, type = 'POST') {
18 | let that = this;
19 | uni.request({
20 | url: param.url,
21 | data: param,
22 | method: type,
23 | header: {
24 | 'content-type': 'application/x-www-form-urlencoded'
25 | },
26 | success: function (result) {
27 | if (result.statusCode == 200 && result.data.code == 3003) {
28 | that.authorization();
29 | return false;
30 | }
31 |
32 | success(result);
33 | },
34 | fail: function () {
35 | fail();
36 | },
37 | complete: function () {
38 | complete();
39 | uni.navloading('close');
40 | }
41 | });
42 | }; //封装登陆方法
43 |
44 | this.checklogin = function () {
45 | const that = this;
46 | let uid = uni.getStorageSync('userid');
47 | let contenttext = uni.getStorageSync('contenttext');
48 | console.log(contenttext);
49 | uni.request({
50 | url: that.apiurl + '?action=car.check_sessionkey',
51 | data: {
52 | uid: uid
53 | },
54 | method: 'POST',
55 | header: {
56 | 'content-type': 'application/x-www-form-urlencoded'
57 | },
58 | success: function (result) {
59 | let datainfo = result.data;
60 |
61 | if (datainfo.error.errorCode == 0) {
62 | } else {
63 | //session已经过期
64 | uni.loading();
65 | uni.login({
66 | success: function (res) {
67 | if (res.code) {
68 | uni.request({
69 | url: that.apiurl + '?action=car.get_auth_info',
70 | data: {
71 | js_code: res.code
72 | },
73 | method: 'POST',
74 | header: {
75 | 'content-type': 'application/x-www-form-urlencoded'
76 | },
77 | success: function (result) {
78 | let datainfo = result.data;
79 |
80 | if (datainfo.error.errorCode == 0) {
81 | uni.setStorageSync('userid', datainfo.data.uid);
82 | }
83 | },
84 | complete: function () {
85 | uni.loading('close');
86 | }
87 | });
88 | }
89 | }
90 | });
91 | }
92 | },
93 | complete: function () {
94 | uni.loading('close');
95 | }
96 | });
97 | }; //封装登陆方法
98 |
99 | this.newchecklogin = function () {
100 | const that = this;
101 | uni.login({
102 | success: function (res) {
103 | if (res.code) {
104 | uni.request({
105 | url: that.apiurl + '?action=car.get_auth_info',
106 | data: {
107 | js_code: res.code
108 | },
109 | method: 'POST',
110 | header: {
111 | 'content-type': 'application/x-www-form-urlencoded'
112 | },
113 | success: function (result) {
114 | let datainfo = result.data;
115 |
116 | if (datainfo.error.errorCode == 0) {
117 | uni.setStorageSync('userid', datainfo.data.uid);
118 | } else {
119 | }
120 | },
121 | complete: function () {}
122 | });
123 | }
124 | }
125 | });
126 | };
127 | }
128 |
129 | module.exports = common;
130 |
--------------------------------------------------------------------------------
/utils/md5.js:
--------------------------------------------------------------------------------
1 | /*
2 | * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
3 | * Digest Algorithm, as defined in RFC 1321.
4 | * Version 1.1 Copyright (C) Paul Johnston 1999 - 2002.
5 | * Code also contributed by Greg Holt
6 | * See http://pajhome.org.uk/site/legal.html for details.
7 | */
8 |
9 | /*
10 | * Add integers, wrapping at 2^32. This uses 16-bit operations internally
11 | * to work around bugs in some JS interpreters.
12 | */
13 | function safe_add(x, y) {
14 | var lsw = (x & 0xFFFF) + (y & 0xFFFF);
15 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
16 | return msw << 16 | lsw & 0xFFFF;
17 | }
18 | /*
19 | * Bitwise rotate a 32-bit number to the left.
20 | */
21 |
22 |
23 | function rol(num, cnt) {
24 | return num << cnt | num >>> 32 - cnt;
25 | }
26 | /*
27 | * These functions implement the four basic operations the algorithm uses.
28 | */
29 |
30 |
31 | function cmn(q, a, b, x, s, t) {
32 | return safe_add(rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
33 | }
34 |
35 | function ff(a, b, c, d, x, s, t) {
36 | return cmn(b & c | ~b & d, a, b, x, s, t);
37 | }
38 |
39 | function gg(a, b, c, d, x, s, t) {
40 | return cmn(b & d | c & ~d, a, b, x, s, t);
41 | }
42 |
43 | function hh(a, b, c, d, x, s, t) {
44 | return cmn(b ^ c ^ d, a, b, x, s, t);
45 | }
46 |
47 | function ii(a, b, c, d, x, s, t) {
48 | return cmn(c ^ (b | ~d), a, b, x, s, t);
49 | }
50 | /*
51 | * Calculate the MD5 of an array of little-endian words, producing an array
52 | * of little-endian words.
53 | */
54 |
55 |
56 | function coreMD5(x) {
57 | var a = 1732584193;
58 | var b = -271733879;
59 | var c = -1732584194;
60 | var d = 271733878;
61 |
62 | for (var i = 0; i < x.length; i += 16) {
63 | var olda = a;
64 | var oldb = b;
65 | var oldc = c;
66 | var oldd = d;
67 | a = ff(a, b, c, d, x[i + 0], 7, -680876936);
68 | d = ff(d, a, b, c, x[i + 1], 12, -389564586);
69 | c = ff(c, d, a, b, x[i + 2], 17, 606105819);
70 | b = ff(b, c, d, a, x[i + 3], 22, -1044525330);
71 | a = ff(a, b, c, d, x[i + 4], 7, -176418897);
72 | d = ff(d, a, b, c, x[i + 5], 12, 1200080426);
73 | c = ff(c, d, a, b, x[i + 6], 17, -1473231341);
74 | b = ff(b, c, d, a, x[i + 7], 22, -45705983);
75 | a = ff(a, b, c, d, x[i + 8], 7, 1770035416);
76 | d = ff(d, a, b, c, x[i + 9], 12, -1958414417);
77 | c = ff(c, d, a, b, x[i + 10], 17, -42063);
78 | b = ff(b, c, d, a, x[i + 11], 22, -1990404162);
79 | a = ff(a, b, c, d, x[i + 12], 7, 1804603682);
80 | d = ff(d, a, b, c, x[i + 13], 12, -40341101);
81 | c = ff(c, d, a, b, x[i + 14], 17, -1502002290);
82 | b = ff(b, c, d, a, x[i + 15], 22, 1236535329);
83 | a = gg(a, b, c, d, x[i + 1], 5, -165796510);
84 | d = gg(d, a, b, c, x[i + 6], 9, -1069501632);
85 | c = gg(c, d, a, b, x[i + 11], 14, 643717713);
86 | b = gg(b, c, d, a, x[i + 0], 20, -373897302);
87 | a = gg(a, b, c, d, x[i + 5], 5, -701558691);
88 | d = gg(d, a, b, c, x[i + 10], 9, 38016083);
89 | c = gg(c, d, a, b, x[i + 15], 14, -660478335);
90 | b = gg(b, c, d, a, x[i + 4], 20, -405537848);
91 | a = gg(a, b, c, d, x[i + 9], 5, 568446438);
92 | d = gg(d, a, b, c, x[i + 14], 9, -1019803690);
93 | c = gg(c, d, a, b, x[i + 3], 14, -187363961);
94 | b = gg(b, c, d, a, x[i + 8], 20, 1163531501);
95 | a = gg(a, b, c, d, x[i + 13], 5, -1444681467);
96 | d = gg(d, a, b, c, x[i + 2], 9, -51403784);
97 | c = gg(c, d, a, b, x[i + 7], 14, 1735328473);
98 | b = gg(b, c, d, a, x[i + 12], 20, -1926607734);
99 | a = hh(a, b, c, d, x[i + 5], 4, -378558);
100 | d = hh(d, a, b, c, x[i + 8], 11, -2022574463);
101 | c = hh(c, d, a, b, x[i + 11], 16, 1839030562);
102 | b = hh(b, c, d, a, x[i + 14], 23, -35309556);
103 | a = hh(a, b, c, d, x[i + 1], 4, -1530992060);
104 | d = hh(d, a, b, c, x[i + 4], 11, 1272893353);
105 | c = hh(c, d, a, b, x[i + 7], 16, -155497632);
106 | b = hh(b, c, d, a, x[i + 10], 23, -1094730640);
107 | a = hh(a, b, c, d, x[i + 13], 4, 681279174);
108 | d = hh(d, a, b, c, x[i + 0], 11, -358537222);
109 | c = hh(c, d, a, b, x[i + 3], 16, -722521979);
110 | b = hh(b, c, d, a, x[i + 6], 23, 76029189);
111 | a = hh(a, b, c, d, x[i + 9], 4, -640364487);
112 | d = hh(d, a, b, c, x[i + 12], 11, -421815835);
113 | c = hh(c, d, a, b, x[i + 15], 16, 530742520);
114 | b = hh(b, c, d, a, x[i + 2], 23, -995338651);
115 | a = ii(a, b, c, d, x[i + 0], 6, -198630844);
116 | d = ii(d, a, b, c, x[i + 7], 10, 1126891415);
117 | c = ii(c, d, a, b, x[i + 14], 15, -1416354905);
118 | b = ii(b, c, d, a, x[i + 5], 21, -57434055);
119 | a = ii(a, b, c, d, x[i + 12], 6, 1700485571);
120 | d = ii(d, a, b, c, x[i + 3], 10, -1894986606);
121 | c = ii(c, d, a, b, x[i + 10], 15, -1051523);
122 | b = ii(b, c, d, a, x[i + 1], 21, -2054922799);
123 | a = ii(a, b, c, d, x[i + 8], 6, 1873313359);
124 | d = ii(d, a, b, c, x[i + 15], 10, -30611744);
125 | c = ii(c, d, a, b, x[i + 6], 15, -1560198380);
126 | b = ii(b, c, d, a, x[i + 13], 21, 1309151649);
127 | a = ii(a, b, c, d, x[i + 4], 6, -145523070);
128 | d = ii(d, a, b, c, x[i + 11], 10, -1120210379);
129 | c = ii(c, d, a, b, x[i + 2], 15, 718787259);
130 | b = ii(b, c, d, a, x[i + 9], 21, -343485551);
131 | a = safe_add(a, olda);
132 | b = safe_add(b, oldb);
133 | c = safe_add(c, oldc);
134 | d = safe_add(d, oldd);
135 | }
136 |
137 | return [a, b, c, d];
138 | }
139 | /*
140 | * Convert an array of little-endian words to a hex string.
141 | */
142 |
143 |
144 | function binl2hex(binarray) {
145 | var hex_tab = "0123456789abcdef";
146 | var str = "";
147 |
148 | for (var i = 0; i < binarray.length * 4; i++) {
149 | str += hex_tab.charAt(binarray[i >> 2] >> i % 4 * 8 + 4 & 0xF) + hex_tab.charAt(binarray[i >> 2] >> i % 4 * 8 & 0xF);
150 | }
151 |
152 | return str;
153 | }
154 | /*
155 | * Convert an array of little-endian words to a base64 encoded string.
156 | */
157 |
158 |
159 | function binl2b64(binarray) {
160 | var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
161 | var str = "";
162 |
163 | for (var i = 0; i < binarray.length * 32; i += 6) {
164 | str += tab.charAt(binarray[i >> 5] << i % 32 & 0x3F | binarray[i >> 5 + 1] >> 32 - i % 32 & 0x3F);
165 | }
166 |
167 | return str;
168 | }
169 | /*
170 | * Convert an 8-bit character string to a sequence of 16-word blocks, stored
171 | * as an array, and append appropriate padding for MD4/5 calculation.
172 | * If any of the characters are >255, the high byte is silently ignored.
173 | */
174 |
175 |
176 | function str2binl(str) {
177 | var nblk = (str.length + 8 >> 6) + 1; // number of 16-word blocks
178 |
179 | var blks = new Array(nblk * 16);
180 |
181 | for (var i = 0; i < nblk * 16; i++) blks[i] = 0;
182 |
183 | for (var i = 0; i < str.length; i++) blks[i >> 2] |= (str.charCodeAt(i) & 0xFF) << i % 4 * 8;
184 |
185 | blks[i >> 2] |= 0x80 << i % 4 * 8;
186 | blks[nblk * 16 - 2] = str.length * 8;
187 | return blks;
188 | }
189 | /*
190 | * Convert a wide-character string to a sequence of 16-word blocks, stored as
191 | * an array, and append appropriate padding for MD4/5 calculation.
192 | */
193 |
194 |
195 | function strw2binl(str) {
196 | var nblk = (str.length + 4 >> 5) + 1; // number of 16-word blocks
197 |
198 | var blks = new Array(nblk * 16);
199 |
200 | for (var i = 0; i < nblk * 16; i++) blks[i] = 0;
201 |
202 | for (var i = 0; i < str.length; i++) blks[i >> 1] |= str.charCodeAt(i) << i % 2 * 16;
203 |
204 | blks[i >> 1] |= 0x80 << i % 2 * 16;
205 | blks[nblk * 16 - 2] = str.length * 16;
206 | return blks;
207 | }
208 | /*
209 | * External interface
210 | */
211 |
212 |
213 | function hexMD5(str) {
214 | return binl2hex(coreMD5(str2binl(str)));
215 | }
216 |
217 | function hexMD5w(str) {
218 | return binl2hex(coreMD5(strw2binl(str)));
219 | }
220 |
221 | function b64MD5(str) {
222 | return binl2b64(coreMD5(str2binl(str)));
223 | }
224 |
225 | function b64MD5w(str) {
226 | return binl2b64(coreMD5(strw2binl(str)));
227 | }
228 | /* Backward compatibility */
229 |
230 |
231 | function calcMD5(str) {
232 | return binl2hex(coreMD5(str2binl(str)));
233 | }
234 |
235 | module.exports = {
236 | hexMD5: hexMD5
237 | };
--------------------------------------------------------------------------------
/utils/util.js:
--------------------------------------------------------------------------------
1 | const formatTime = (date) => {
2 | const year = date.getFullYear();
3 | const month = date.getMonth() + 1;
4 | const day = date.getDate();
5 | const hour = date.getHours();
6 | const minute = date.getMinutes();
7 | const second = date.getSeconds();
8 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':');
9 | };
10 |
11 | const formatNumber = (n) => {
12 | n = n.toString();
13 | return n[1] ? n : '0' + n;
14 | };
15 |
16 | module.exports = {
17 | formatTime: formatTime
18 | };
19 |
--------------------------------------------------------------------------------