├── .editorconfig
├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── babel.config.js
├── package.json
├── postcss.config.js
├── public
└── index.html
├── screenshot
├── app-plus-apps.jpg
├── app-plus-donate.jpg
├── app-plus-index.jpg
├── electron.png
├── h5.png
├── mp-alipay.png
├── mp-toutiao.png
├── mp-weixin.png
└── 运行环境截图.md
├── src-builds
├── config.ts
├── electron.ts
└── utils.ts
├── src
├── App.vue
├── assets
│ └── css
│ │ ├── aiplat.css
│ │ ├── cmreset.css
│ │ └── cmstyle.css
├── components
│ ├── ani-copyright.vue
│ ├── ani-header1.vue
│ ├── ani-image.vue
│ ├── ani-jifenqi-table.vue
│ ├── ani-list01.vue
│ ├── ani-no-data.vue
│ ├── ani-pop-confirm.vue
│ └── ani-pop-win.vue
├── electron
│ ├── main.js
│ ├── package.json
│ ├── preload.js
│ └── utils.js
├── lib.d.ts
├── main.ts
├── pages
│ ├── aiplat
│ │ ├── apps.vue
│ │ ├── donate.vue
│ │ └── index.vue
│ ├── common
│ │ ├── about.vue
│ │ ├── find.vue
│ │ ├── h5.vue
│ │ ├── mine.vue
│ │ └── userAgent.vue
│ └── index.vue
├── plugins.d.ts
├── plugins
│ ├── cmapp.class.ts
│ ├── index.ts
│ ├── lib
│ │ ├── axios.ts
│ │ ├── canvas2Image.ts
│ │ ├── loadFiles.ts
│ │ ├── qrcode.ts
│ │ └── setFileObject.ts
│ └── uniAjax.ts
├── projects
│ └── aiplat
│ │ ├── builds
│ │ └── selfConfig.ts
│ │ ├── manifest
│ │ ├── pro
│ │ │ └── manifest.json
│ │ ├── uat
│ │ │ └── manifest.json
│ │ └── ver
│ │ │ └── manifest.json
│ │ ├── selfConfig.ts
│ │ └── selfPages.json
├── service
│ ├── api.ts
│ ├── apis
│ │ └── sign.ts
│ ├── config.ts
│ └── config
│ │ └── map.ts
├── sfc.d.ts
├── static
│ ├── aiplat
│ │ ├── 72x72.png
│ │ ├── cm_back.png
│ │ ├── cm_close.png
│ │ ├── cm_loading.gif
│ │ ├── cm_right.png
│ │ ├── donate_WX.png
│ │ ├── donate_ZFB.png
│ │ ├── icon.png
│ │ ├── icon1024.png
│ │ ├── icon2.png
│ │ └── metro_icon.png
│ ├── cmDemo1
│ │ ├── 1.jpg
│ │ ├── 2.jpg
│ │ └── 3.jpg
│ ├── img
│ │ ├── sy_01.png
│ │ ├── sy_01on.png
│ │ ├── sy_01on_zfb.png
│ │ ├── sy_02.png
│ │ ├── sy_02on.png
│ │ ├── sy_02on_zfb.png
│ │ ├── sy_03.png
│ │ ├── sy_03on.png
│ │ ├── sy_03on_zfb.png
│ │ ├── sy_04.png
│ │ ├── sy_04on.png
│ │ └── sy_04on_zfb.png
│ └── logo.png
└── vuex
│ ├── commonModule
│ └── index.ts
│ ├── donateModule
│ └── index.ts
│ └── store.ts
├── tsconfig.json
├── unpackage
└── res
│ └── icons
│ ├── 120x120.png
│ ├── 144x144.png
│ ├── 152x152.png
│ ├── 167x167.png
│ ├── 180x180.png
│ ├── 192x192.png
│ ├── 20x20.png
│ ├── 29x29.png
│ ├── 40x40.png
│ ├── 48x48.png
│ ├── 58x58.png
│ ├── 60x60.png
│ ├── 72x72.png
│ ├── 76x76.png
│ ├── 80x80.png
│ ├── 87x87.png
│ └── 96x96.png
└── vue.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # *.ts linguist-language=TypeScript+Vue
2 | # *.vue linguist-language=TypeScript+Vue
3 | # *.js linguist-language=TypeScript+Vue
4 | # *.css linguist-language=TypeScript+Vue
5 | # *.less linguist-language=TypeScript+Vue
6 | # *.scss linguist-language=TypeScript+Vue
7 | # *.html linguist-language=TypeScript+Vue
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
3 | test/
4 | .idea/
5 | .vs/
6 | .vscode/
7 | nbproject/
8 | .history/
9 | /src/builds
10 | /src/manifest.json
11 | /src/pages.json
12 | .DS_Store
13 |
14 | # local env files
15 | .env.local
16 | .env.*.local
17 |
18 | # Log files
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
23 | # Editor directories and files
24 | .project
25 | .idea
26 | .vscode
27 | *.suo
28 | *.ntvs*
29 | *.njsproj
30 | *.sln
31 | *.sw*
32 |
33 | yarn.lock
34 | package-lock.json
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # uniapp vue-cli4 typescript版本
2 |
3 | - vue-cli4 + vuex + cmui + html5 + css3 + typescript + electron
4 | - 一次开发,同时打包成Android版app、iOS版app、H5版、微信小程序版、支付宝小程序版、头条小程序、PC安装包平台这几个平台,界面统一,功能一致。
5 | - 新引入electron用于支持打包PC端(Windows、Mac、Linux)安装包, 后续也关注鸿蒙系统
6 | - cmui仓库为https://github.com/aiplat/cmui.git
7 | - 代码示例为 https://aiplat.com 的版本 http://uniapp.aiplat.com
8 | - 基于 https://uniapp.dcloud.io/ 的uni-app
9 | - 基于本仓库所开发的‘娱乐计分器’已经成功上线微信、头条、支付宝三大程序,暂不开源。各框架在升级中。
10 |
11 | ---
12 |
13 | # 代码目录结构
14 | - dist ------打包目录
15 | - public
16 | index.html ------入口公共html
17 | - screenshot ------运行环境截图
18 | - src
19 | - assets ------静态css文件目录
20 | - builds ------运行构建时目录(git已忽略,不可手动修改)
21 | - components ------公共组件目录
22 | - electron ------electron目录, 用于支持打包PC安装包
23 | - pages ------视图目录
24 | - aiplat ------aiplat项目视图目录
25 | - common ------公共页面目录
26 | - *** ------若有多个项目,请在这新增不同目录区分
27 | - plugins ------公共函数或插件目录
28 | - lib ------第三方库目录
29 | - cmapp.class.ts ------公共$cmapp配置
30 | - uniAjax.ts ------公共$uniAjax配置
31 | - projects ------多个小程序各配置目录
32 | - aiplat ------aiplat配置信息目录
33 | - *** ------若有多个项目,请在这新增不同目录区分
34 | - service ------配置目录
35 | - apis ------api扩展配置目录
36 | - config ------config扩展配置目录
37 | - api.ts ------公共$api配置
38 | - config.ts ------公共$config配置
39 | - static ------静态资源目录
40 | - vuex ------vuex目录
41 | - App.vue ------vue应用承载文件
42 | - lib.d.ts ------typescript声明文件
43 | - main.ts ------vue应用入口文件
44 | - manifest.json ------应用配置文件(运行构建时生成,git已忽略,不可手动修改)
45 | - pages.json ------页面配置文件(运行构建时生成,git已忽略,不可手动修改)
46 | - plugins.d.ts ------typescript声明文件
47 | - sfc.d.ts ------typescript声明文件
48 | - src-builds ------框架运行构建时修改配置目录
49 | - config.ts ------修改配置文件
50 | - electron.ts ------electron相关执行文件
51 | - utils.ts ------公共工具类
52 |
53 | ---
54 |
55 | # clone
56 | - $ git clone https://github.com/aiplat/uniapp.git
57 |
58 | # 安装依赖
59 | - $ cd uniapp
60 | - $ npm install
61 |
62 | # 开发模式
63 | - $ npm run dev (默认h5开发) h5运行默认打开 http://localhost:2016/#/
64 | - $ npm run dev:mp-weixin (微信小程序开发)
65 | - 打开微信开发者工具->小程序->导入项目->选择dist/dev/mp-weixin
66 | - 若有多个项目同一个仓库,$ npm run dev --env=uat --type=** 区分
67 |
68 |
69 | # 打包项目
70 | - $ npm run build (默认构建h5)
71 | - $ npm run build:mp-weixin (微信小程序构建)
72 | - 单个项目(默认aiplat)代码打包到了dist/build/mp-weixin
73 | - 若有多个项目同一个仓库,$ npm run build --env=uat --type=** 区分
74 |
75 | ---
76 |
77 | # 注意
78 | - 开发工具为任意,不一定要HbuilderX.如果也要同时打包成app,再导入项目到HbuilderX打包。
79 | - 开发或构建成其他平台命令:
80 | - dev为开发模式,build为构建模式
81 | - 参数--env=uat为环境参数,默认uat。
82 | - 参数--type=aiplat为项目名,默认aiplat。
83 | - 例如:
84 | - $ npm run dev:mp-weixin --env=uat --type=** 为微信小程序平台->uat环境(测试环境)->开发模式
85 | - $ npm run dev:mp-weixin --env=ver --type=** 为微信小程序平台->ver环境(预生产环境)->开发模式
86 | - $ npm run dev:mp-weixin --env=pro --type=** 为微信小程序平台->pro环境(生产环境)->开发模式
87 | - $ npm run build:mp-weixin --env=uat --type=** 为微信小程序平台->uat环境(测试环境)->构建模式
88 | - $ npm run build:mp-weixin --env=ver --type=** 为微信小程序平台->ver环境(预生产环境)->构建模式
89 | - $ npm run build:mp-weixin --env=pro --type=** 为微信小程序平台->pro环境(生产环境)->构建模式
90 |
91 | #### 运行环境截图,screenshot目录,示例为aiplat项目
92 | #### 平台标识: 后面主要适配这几个平台, 如果也能适配到鸿蒙系统是最好
93 | - app-plus: android、ios
94 | - electron: PC安装包平台
95 | - h5: h5(pc web、mobile web)
96 | - mp-alipay: 支付宝小程序
97 | - mp-toutiao: 头条小程序
98 | - mp-weixin: 微信小程序
99 | - 注意:百度小程序、QQ小程序、快应用、360小程序这4个平台uni-app也是支持的,本示例没有运行与构建这4个平台论证。
100 |
101 | ---
102 |
103 | # projects -- 多个小程序各配置目录
104 | ## 默认aiplat,文件结构
105 | - manifest目录下还有uat/ver/pro(三个环境目录)
106 | - manifest.json -- uni-app应用的配置文件,用于指定应用的名称、图标、权限等。运行微信和头条小程序时请先将其中的appid改为自己可用的。
107 | - selfConfig.ts -- aiplat配置信息
108 | - selfPages.json -- 用于对 uni-app 进行全局配置,决定页面文件的路径、窗口表现、设置多 tab 等
109 | - 运行构建APP前先执行一次dev或build命令,使src目录里有以上对应的三个文件。
110 |
111 | ## 当有其他项目时如jifenqi(娱乐计分器,后续开源):
112 | - 开发命令为npm run dev --env=uat --type=jifenqi
113 | - 构建命令为npm run build --env=uat --type=jifenqi
114 |
115 | ---
116 |
117 | # 关于electron运行、构建、打包
118 |
119 | #### h5运行默认http://localhost:2016/#/
120 | ## 运行:首先运行h5版本,再运行electron
121 | #### 运行h5,单独git bash窗口1
122 | - $ npm run dev:h5 --env=uat --type=aiplat
123 | #### 运行h5之后,单独git bash窗口2
124 | - $ npm run dev:electron --env=uat --type=aiplat
125 | - 此时h5运行时项目运行到electron环境
126 |
127 | ## 构建:首先构建h5版本,再构建electron,再打包(待添加完善)
128 | #### 构建h5
129 | - $ npm run build:h5 --env=uat --type=aiplat
130 | #### 构建h5之后继续执行
131 | - $ npm run build:electron --env=uat --type=aiplat
132 | - 此时h5构建时项目运行到electron环境
133 |
134 | #### 打包PC安装包(待添加完善)
135 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | const plugins = []
2 |
3 | if (process.env.UNI_OPT_TREESHAKINGNG) {
4 | plugins.push(require('@dcloudio/vue-cli-plugin-uni-optimize/packages/babel-plugin-uni-api/index.js'))
5 | }
6 |
7 | if (
8 | (
9 | process.env.UNI_PLATFORM === 'app-plus' &&
10 | process.env.UNI_USING_V8
11 | ) ||
12 | (
13 | process.env.UNI_PLATFORM === 'h5' &&
14 | process.env.UNI_H5_BROWSER === 'builtin'
15 | )
16 | ) {
17 | const path = require('path')
18 |
19 | const isWin = /^win/.test(process.platform)
20 |
21 | const normalizePath = path => (isWin ? path.replace(/\\/g, '/') :path)
22 |
23 | const input = normalizePath(process.env.UNI_INPUT_DIR)
24 | try {
25 | plugins.push([
26 | require('@dcloudio/vue-cli-plugin-hbuilderx/packages/babel-plugin-console'),
27 | {
28 | file (file) {
29 | file = normalizePath(file)
30 | if (file.indexOf(input) === 0) {
31 | return path.relative(input, file)
32 | }
33 | return false
34 | }
35 | }
36 | ])
37 | } catch (e) {}
38 | }
39 |
40 | process.UNI_LIBRARIES = process.UNI_LIBRARIES || ['@dcloudio/uni-ui']
41 | process.UNI_LIBRARIES.forEach(libraryName => {
42 | plugins.push([
43 | 'import',
44 | {
45 | 'libraryName':libraryName,
46 | 'customName':(name) => {
47 | return `${libraryName}/lib/${name}/${name}`
48 | }
49 | }
50 | ])
51 | })
52 | module.exports = {
53 | presets:[
54 | [
55 | '@vue/app',
56 | {
57 | modules:'commonjs',
58 | useBuiltIns:process.env.UNI_PLATFORM === 'h5' ? 'usage' :'entry'
59 | }
60 | ]
61 | ],
62 | plugins
63 | }
64 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "aiplat.com-miniprogram",
3 | "version": "2.0.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "npm run build:h5",
7 | "build:app-plus": "ts-node src-builds/config.ts && cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
8 | "build:custom": "ts-node src-builds/config.ts && cross-env NODE_ENV=production uniapp-cli custom",
9 | "build:h5": "ts-node src-builds/config.ts && cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
10 | "build:mp-360": "ts-node src-builds/config.ts && cross-env NODE_ENV=production UNI_PLATFORM=mp-360 vue-cli-service uni-build",
11 | "build:mp-alipay": "ts-node src-builds/config.ts && cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build",
12 | "build:mp-baidu": "ts-node src-builds/config.ts && cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build",
13 | "build:mp-qq": "ts-node src-builds/config.ts && cross-env NODE_ENV=production UNI_PLATFORM=mp-qq vue-cli-service uni-build",
14 | "build:mp-toutiao": "ts-node src-builds/config.ts && cross-env NODE_ENV=production UNI_PLATFORM=mp-toutiao vue-cli-service uni-build",
15 | "build:mp-weixin": "ts-node src-builds/config.ts && cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",
16 | "build:quickapp-native": "ts-node src-builds/config.ts && cross-env NODE_ENV=production UNI_PLATFORM=quickapp-native vue-cli-service uni-build",
17 | "build:quickapp-webview": "ts-node src-builds/config.ts && cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview vue-cli-service uni-build",
18 | "build:quickapp-webview-huawei": "ts-node src-builds/config.ts && cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build",
19 | "build:quickapp-webview-union": "ts-node src-builds/config.ts && cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build",
20 | "build:electron": "ts-node src-builds/electron.ts && electron dist/build/h5/main.js",
21 | "dev": "npm run dev:h5",
22 | "dev:app-plus": "ts-node src-builds/config.ts && cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch",
23 | "dev:custom": "ts-node src-builds/config.ts && cross-env NODE_ENV=development uniapp-cli custom",
24 | "dev:h5": "ts-node src-builds/config.ts && cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
25 | "dev:mp-360": "ts-node src-builds/config.ts && cross-env NODE_ENV=development UNI_PLATFORM=mp-360 vue-cli-service uni-build --watch",
26 | "dev:mp-alipay": "ts-node src-builds/config.ts && cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
27 | "dev:mp-baidu": "ts-node src-builds/config.ts && cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",
28 | "dev:mp-qq": "ts-node src-builds/config.ts && cross-env NODE_ENV=development UNI_PLATFORM=mp-qq vue-cli-service uni-build --watch",
29 | "dev:mp-toutiao": "ts-node src-builds/config.ts && cross-env NODE_ENV=development UNI_PLATFORM=mp-toutiao vue-cli-service uni-build --watch",
30 | "dev:mp-weixin": "ts-node src-builds/config.ts && cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch",
31 | "dev:quickapp-native": "ts-node src-builds/config.ts && cross-env NODE_ENV=development UNI_PLATFORM=quickapp-native vue-cli-service uni-build --watch",
32 | "dev:quickapp-webview": "ts-node src-builds/config.ts && cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview vue-cli-service uni-build --watch",
33 | "dev:quickapp-webview-huawei": "ts-node src-builds/config.ts && cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build --watch",
34 | "dev:quickapp-webview-union": "ts-node src-builds/config.ts && cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build --watch",
35 | "dev:electron": "electron src/electron/main.js",
36 | "info": "node node_modules/@dcloudio/vue-cli-plugin-uni/commands/info.js",
37 | "serve:quickapp-native": "node node_modules/@dcloudio/uni-quickapp-native/bin/serve.js",
38 | "test:android": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=android jest -i",
39 | "test:h5": "cross-env UNI_PLATFORM=h5 jest -i",
40 | "test:ios": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=ios jest -i",
41 | "test:mp-baidu": "cross-env UNI_PLATFORM=mp-baidu jest -i",
42 | "test:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin jest -i"
43 | },
44 | "dependencies": {
45 | "@dcloudio/uni-app-plus": "^2.0.0-31920210709003",
46 | "@dcloudio/uni-h5": "^2.0.0-31920210709003",
47 | "@dcloudio/uni-helper-json": "*",
48 | "@dcloudio/uni-i18n": "^2.0.0-31920210709003",
49 | "@dcloudio/uni-mp-360": "^2.0.0-31920210709003",
50 | "@dcloudio/uni-mp-alipay": "^2.0.0-31920210709003",
51 | "@dcloudio/uni-mp-baidu": "^2.0.0-31920210709003",
52 | "@dcloudio/uni-mp-kuaishou": "^2.0.0-31920210709003",
53 | "@dcloudio/uni-mp-qq": "^2.0.0-31920210709003",
54 | "@dcloudio/uni-mp-toutiao": "^2.0.0-31920210709003",
55 | "@dcloudio/uni-mp-vue": "^2.0.0-31920210709003",
56 | "@dcloudio/uni-mp-weixin": "^2.0.0-31920210709003",
57 | "@dcloudio/uni-quickapp-native": "^2.0.0-31920210709003",
58 | "@dcloudio/uni-quickapp-webview": "^2.0.0-31920210709003",
59 | "@dcloudio/uni-stat": "^2.0.0-31920210709003",
60 | "@vue/shared": "^3.0.0",
61 | "core-js": "^3.6.5",
62 | "html2canvas": "^1.0.0-rc.5",
63 | "regenerator-runtime": "^0.12.1",
64 | "vue": "^2.6.11",
65 | "vue-class-component": "^6.3.2",
66 | "vue-property-decorator": "^8.5.1",
67 | "vuex": "^3.2.0",
68 | "weixin-js-sdk": "^1.6.0"
69 | },
70 | "devDependencies": {
71 | "@babel/plugin-syntax-typescript": "^7.2.0",
72 | "@babel/runtime": "~7.12.0",
73 | "@dcloudio/types": "*",
74 | "@dcloudio/uni-automator": "^2.0.0-31920210709003",
75 | "@dcloudio/uni-cli-shared": "^2.0.0-31920210709003",
76 | "@dcloudio/uni-migration": "^2.0.0-31920210709003",
77 | "@dcloudio/uni-template-compiler": "^2.0.0-31920210709003",
78 | "@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.0-31920210709003",
79 | "@dcloudio/vue-cli-plugin-uni": "^2.0.0-31920210709003",
80 | "@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.0-31920210709003",
81 | "@dcloudio/webpack-uni-mp-loader": "^2.0.0-31920210709003",
82 | "@dcloudio/webpack-uni-pages-loader": "^2.0.0-31920210709003",
83 | "@vue/cli-plugin-babel": "~4.5.0",
84 | "@vue/cli-plugin-typescript": "*",
85 | "@vue/cli-service": "~4.5.0",
86 | "axios": "^0.21.1",
87 | "babel-plugin-import": "^1.11.0",
88 | "compression-webpack-plugin": "^3.1.0",
89 | "cross-env": "^7.0.2",
90 | "crypto-js": "^3.1.9-1",
91 | "css-minimizer-webpack-plugin": "^1.2.0",
92 | "jest": "^25.4.0",
93 | "less": "^3.12.2",
94 | "less-loader": "^6.2.0",
95 | "mini-css-extract-plugin": "^2.1.0",
96 | "mini-types": "*",
97 | "miniprogram-api-typings": "*",
98 | "postcss-comment": "^2.0.0",
99 | "qrcode": "^1.4.4",
100 | "shelljs": "^0.8.3",
101 | "ts-node": "^8.10.2",
102 | "typescript": "^3.0.0",
103 | "vue-class-component": "^6.3.2",
104 | "vue-template-compiler": "^2.6.11",
105 | "vuex-class": "^0.3.2",
106 | "webpack-bundle-analyzer": "^4.4.2"
107 | },
108 | "browserslist": [
109 | "Android >= 4",
110 | "ios >= 8"
111 | ],
112 | "uni-app": {
113 | "scripts": {}
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | module.exports = {
3 | parser:require('postcss-comment'),
4 | plugins:[
5 | require('postcss-import')({
6 | resolve (id) {
7 | if (id.startsWith('~@/')) {
8 | return path.resolve(process.env.UNI_INPUT_DIR, id.substr(3))
9 | } else if (id.startsWith('@/')) {
10 | return path.resolve(process.env.UNI_INPUT_DIR, id.substr(2))
11 | } else if (id.startsWith('/') && !id.startsWith('//')) {
12 | return path.resolve(process.env.UNI_INPUT_DIR, id.substr(1))
13 | }
14 | return id
15 | }
16 | }),
17 | require('autoprefixer')({
18 | remove:process.env.UNI_PLATFORM !== 'h5'
19 | }),
20 | require('@dcloudio/vue-cli-plugin-uni/packages/postcss')
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | <%= htmlWebpackPlugin.options.title %>
7 |
8 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
40 |
41 |
42 |
43 |
44 |
45 | Please enable JavaScript to continue.
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/screenshot/app-plus-apps.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/screenshot/app-plus-apps.jpg
--------------------------------------------------------------------------------
/screenshot/app-plus-donate.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/screenshot/app-plus-donate.jpg
--------------------------------------------------------------------------------
/screenshot/app-plus-index.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/screenshot/app-plus-index.jpg
--------------------------------------------------------------------------------
/screenshot/electron.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/screenshot/electron.png
--------------------------------------------------------------------------------
/screenshot/h5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/screenshot/h5.png
--------------------------------------------------------------------------------
/screenshot/mp-alipay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/screenshot/mp-alipay.png
--------------------------------------------------------------------------------
/screenshot/mp-toutiao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/screenshot/mp-toutiao.png
--------------------------------------------------------------------------------
/screenshot/mp-weixin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/screenshot/mp-weixin.png
--------------------------------------------------------------------------------
/screenshot/运行环境截图.md:
--------------------------------------------------------------------------------
1 | # 运行环境截图,示例为aiplat项目
2 | ## 后面主要适配这几个平台
3 | - app-plus: android、ios
4 | - electron: PC安装包平台
5 | - h5: h5(pc web、mobile web)
6 | - mp-alipay: 支付宝小程序
7 | - mp-toutiao: 头条小程序
8 | - mp-weixin: 微信小程序
--------------------------------------------------------------------------------
/src-builds/config.ts:
--------------------------------------------------------------------------------
1 | class configClass{
2 | public utils = require('./utils');
3 | constructor() {
4 | }
5 | async initStart() {
6 | const utilsClass = new this.utils();
7 | const utilsParams = utilsClass.getParams();
8 |
9 | let appTypeName:any = utilsParams.buildType.split(':');
10 | appTypeName = appTypeName && appTypeName.length > 1 ? appTypeName[1] : 'h5';
11 |
12 | const runDir = utilsParams.buildType.includes('build') ? 'build' :'dev';
13 | utilsParams.shell.rm('-rf', `${utilsParams.currentDir}/dist/${runDir}/${appTypeName}`);
14 | utilsParams.shell.rm('-rf', `${utilsParams.currentDir}/dist/${runDir}/.automator/${appTypeName}`);
15 | utilsParams.shell.rm('-rf', `${utilsParams.currentDir}/dist/${runDir}/.sourcemap/${appTypeName}`);
16 |
17 | const buildsDir = `${utilsParams.currentDir}/src/builds`;
18 | utilsParams.shell.rm('-rf', buildsDir);
19 | utilsParams.shell.mkdir('-p', buildsDir);
20 |
21 | appTypeName = utilsClass.getAppTypeName(appTypeName);
22 |
23 | console.log('');
24 | const isDevTxt = utilsParams.buildType.includes('build') ? '构建' :'开发';
25 | console.log(`------${appTypeName}平台-${utilsParams.envTxt[utilsParams.envType]}环境-${isDevTxt}-${utilsParams.type}------`);
26 | console.log('');
27 |
28 | await utilsClass.writeFile({
29 | file:`${utilsParams.currentDir}/src/builds/envType.ts`,
30 | content:`const envType:string = '${utilsParams.envType}';export default envType;`,
31 | });
32 |
33 | utilsClass.buildFile({
34 | oldFile:`${utilsParams.currentDir}/src/projects/${utilsParams.type}/selfPages.json`,
35 | newFile:`${utilsParams.currentDir}/src/pages.json`,
36 | });
37 | utilsClass.buildFile({
38 | oldFile:`${utilsParams.currentDir}/src/projects/${utilsParams.type}/manifest/${utilsParams.envType}/manifest.json`,
39 | newFile:`${utilsParams.currentDir}/src/manifest.json`,
40 | });
41 | utilsClass.buildFile({
42 | oldFile:`${utilsParams.currentDir}/src/projects/${utilsParams.type}/builds/selfConfig.ts`,
43 | newFile:`${utilsParams.currentDir}/src/builds/selfConfig.ts`,
44 | });
45 | console.log('');
46 | console.log('------Building now------');
47 | console.log('');
48 | }
49 | }
50 |
51 | const configClassTarget = new configClass();
52 | configClassTarget.initStart();
53 |
--------------------------------------------------------------------------------
/src-builds/electron.ts:
--------------------------------------------------------------------------------
1 | class electronClass{
2 | public utils = require('./utils');
3 | constructor() {
4 | }
5 | async initStart() {
6 | const utilsClass = new this.utils();
7 | const utilsParams = utilsClass.getParams();
8 |
9 | utilsClass.buildFile({
10 | oldFile:`${utilsParams.currentDir}/src/electron/main.js`,
11 | newFile:`${utilsParams.currentDir}/dist/build/h5/main.js`,
12 | });
13 | utilsClass.buildFile({
14 | oldFile:`${utilsParams.currentDir}/src/electron/package.json`,
15 | newFile:`${utilsParams.currentDir}/dist/build/h5/package.json`,
16 | });
17 | utilsClass.buildFile({
18 | oldFile:`${utilsParams.currentDir}/src/electron/preload.js`,
19 | newFile:`${utilsParams.currentDir}/dist/build/h5/preload.js`,
20 | });
21 | utilsClass.buildFile({
22 | oldFile:`${utilsParams.currentDir}/src/electron/utils.js`,
23 | newFile:`${utilsParams.currentDir}/dist/build/h5/utils.js`,
24 | });
25 | console.log('');
26 | console.log('------electron build ok------');
27 | console.log('');
28 | }
29 | }
30 |
31 | const electronClassTarget = new electronClass();
32 | electronClassTarget.initStart();
33 |
--------------------------------------------------------------------------------
/src-builds/utils.ts:
--------------------------------------------------------------------------------
1 | interface fileData{
2 | file:string,
3 | content:string,
4 | }
5 |
6 | interface buildFileData{
7 | oldFile:string,
8 | newFile:string,
9 | }
10 |
11 | interface envData{
12 | runId:number,
13 | envType:string,
14 | type:string,
15 | buildType:string,
16 | }
17 |
18 | class utilsClass{
19 | public fs = require('fs');
20 | public shell = require('shelljs');
21 | public currentDir = '.';
22 | public buildInfo:envData;
23 | public envTxt:any = {
24 | sit:'SIT',
25 | uat:'UAT',
26 | ver:'VER',
27 | pro:'生产',
28 | };
29 | constructor() {
30 | this.buildInfo = {
31 | runId:0,
32 | buildType:'dev',
33 | envType:'uat',
34 | type:'aiplat',
35 | };
36 | this.getEnv();
37 | }
38 | writeFile(fileData:fileData) {
39 | return new Promise((resolve) => {
40 | this.fs.writeFile(fileData.file, fileData.content, (err:any) => {
41 | if (err) {
42 | console.error(err);
43 | } else {
44 | console.log(`------Build ./${fileData.file}------`);
45 | }
46 | resolve(true);
47 | });
48 | });
49 | }
50 | readFile(fileData:fileData) {
51 | return new Promise((resolve) => {
52 | this.fs.readFile(fileData.file, 'utf8', (err:any, data:string) => {
53 | if (err) {
54 | console.error(err);
55 | }
56 | resolve(data);
57 | });
58 | });
59 | }
60 | isIn(value:string, key:string, defaultValue:string) {
61 | value = value.includes(key) ? `${value.split(key)[1]}` :defaultValue;
62 | return value;
63 | }
64 | buildFile(data:buildFileData) {
65 | this.shell.cp('-R', data.oldFile, data.newFile);
66 | console.log(`------Build ${data.newFile}------`);
67 | }
68 | getEnv() {
69 | return new Promise((resolve) => {
70 | let argv = process.env.npm_config_argv;
71 | if (!argv) {
72 | resolve(false);
73 | return false;
74 | }
75 | argv = JSON.parse(argv);
76 |
77 | let runId = argv.original.indexOf('run');
78 | const buildType = argv.original[runId + 1];
79 | let envType = argv.original[runId + 2];
80 | envType = envType ? this.isIn(envType, 'env=', 'uat') :'uat';
81 | let type = argv.original[runId + 3];
82 | type = type ? this.isIn(type, 'type=', 'aiplat') :'aiplat';
83 | this.buildInfo = {
84 | runId,
85 | buildType,
86 | envType,
87 | type,
88 | }
89 | resolve(true);
90 | });
91 | }
92 | getAppTypeName(type = 'h5') {
93 | const appType:any = {
94 | 'app-plus':'APP',
95 | 'h5':'H5',
96 | 'custom':'custom',
97 | 'mp-360':'360小程序',
98 | 'mp-alipay':'支付宝小程序',
99 | 'mp-baidu':'百度小程序',
100 | 'mp-qq':'QQ小程序',
101 | 'mp-toutiao':'今日头条小程序',
102 | 'mp-weixin':'微信小程序',
103 | };
104 | return appType[type];
105 | }
106 | getParams() {
107 | return {
108 | fs: this.fs,
109 | shell: this.shell,
110 | currentDir: this.currentDir,
111 | envTxt: this.envTxt,
112 | ...this.buildInfo
113 | }
114 | }
115 | }
116 |
117 | module.exports = utilsClass
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
21 |
22 |
27 |
--------------------------------------------------------------------------------
/src/assets/css/aiplat.css:
--------------------------------------------------------------------------------
1 | /*
2 | -----------------------------------------------------------------
3 | *文 件 名:aiplat.css
4 | *修 改 人:梁超明 womendi@qq.com
5 | *最近修改:2019.01.24
6 | -----------------------------------------------------------------
7 | */
8 | .cm_c1b{background:#FD1414!important;}
9 | .cm_c1c{color:#FD1414!important;}/*c1*/
10 | .cm_c2b{background:rgb(0,0,0)!important;}
11 | .cm_c2c{color:rgb(0,0,0)!important;}/*c2*/
12 | .cm_c3b{background:rgb(105,104,103)!important;}
13 | .cm_c3c{color:rgb(105,104,103)!important;}/*c3*/
14 | .cm_c4b{background:rgb(155,155,155)!important;}
15 | .cm_c4c{color:rgb(155,155,155)!important;}/*c4*/
16 | .cm_c5b{background:rgb(223,221,218)!important;}
17 | .cm_c5c{color:rgb(223,221,218)!important;}/*c5*/
18 | .cm_c6b{background:rgb(239,239,238)!important;}
19 | .cm_c6c{color:rgb(239,239,238)!important;}/*c6*/
20 | .cm_c7b{background:rgb(255,255,255)!important;}
21 | .cm_c7c{color:rgb(255,255,255)!important;}/*c7*/
22 | .cm_c8b{background:#22BF22!important;}
23 | .cm_c8c{color:#22BF22!important;}/*c8*/
24 | .cm_c9b{background:#1890FF!important;}
25 | .cm_c9c{color:#1890FF!important;}/*c9*/
26 |
27 | .ulMain{
28 | width: 100vw;
29 | min-height: 100vh;
30 | }
31 | .jifenView{
32 | width: 100vw;
33 | height: 100vh;
34 | }
35 | .jifenTitle{
36 | border:1px solid #FD1414;
37 | color:#FD1414;
38 | }
39 | .jifenTitleAli{
40 | border:1px solid #1890FF;
41 | color:#1890FF;
42 | }
43 |
--------------------------------------------------------------------------------
/src/assets/css/cmreset.css:
--------------------------------------------------------------------------------
1 | /*
2 | -----------------------------------------------------------------
3 | *文 件 名:cmreset.css
4 | *修 改 人:梁超明 womendi@qq.com
5 | *最近修改:2019.01.24
6 | -----------------------------------------------------------------
7 | */
8 | html {
9 | margin: 0;
10 | padding: 0;
11 | border: 0;
12 | font-size:1em!important;
13 | }
14 | body,
15 | div,
16 | span,
17 | object,
18 | iframe,
19 | h1,
20 | h2,
21 | h3,
22 | h4,
23 | h5,
24 | h6,
25 | p,
26 | blockquote,
27 | pre,
28 | a,
29 | abbr,
30 | acronym,
31 | address,
32 | code,
33 | del,
34 | dfn,
35 | em,
36 | q,
37 | dl,
38 | dt,
39 | dd,
40 | ol,
41 | ul,
42 | li,
43 | fieldset,
44 | form,
45 | legend,
46 | caption,
47 | tbody,
48 | tfoot,
49 | thead,
50 | article,
51 | aside,
52 | dialog,
53 | figure,
54 | footer,
55 | header,
56 | hgroup,
57 | nav,
58 | section,
59 | button,
60 | input,
61 | optgroup,
62 | select,
63 | textarea,
64 | view,
65 | image{
66 | margin: 0;
67 | padding: 0;
68 | border: 0;
69 | font: inherit;
70 | vertical-align: baseline;
71 | -webkit-box-sizing: border-box;
72 | -moz-box-sizing: border-box;
73 | box-sizing: border-box;
74 | -webkit-appearance: none!important;
75 | }
76 | body {
77 | font-size: 1em!important;
78 | background: #fff;
79 | font-family: 'Microsoft YaHei';
80 | word-break: break-all;
81 | word-wrap: break-word;
82 | }
83 | article,
84 | aside,
85 | details,
86 | figcaption,
87 | figure,
88 | footer,
89 | header,
90 | hgroup,
91 | main,
92 | nav,
93 | section,
94 | summary {
95 | display: block;
96 | }
97 | audio,
98 | canvas,
99 | progress,
100 | video {
101 | display: inline-block;
102 | vertical-align: baseline;
103 | }
104 | ul,
105 | ol,
106 | li{
107 | list-style: none;
108 | }
109 |
--------------------------------------------------------------------------------
/src/components/ani-copyright.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 | {{ copyrightData.copyright }} {{ copyrightData.name }}
9 | {{ copyrightData.site }}
11 |
12 |
13 |
14 |
37 |
--------------------------------------------------------------------------------
/src/components/ani-header1.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
{{ title }}
8 |
9 |
10 |
11 |
22 |
--------------------------------------------------------------------------------
/src/components/ani-image.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
18 |
--------------------------------------------------------------------------------
/src/components/ani-jifenqi-table.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
19 | {{ item1 }}
20 |
21 |
22 |
28 |
34 | {{ item3 }}
35 |
36 |
37 |
38 |
39 |
55 |
62 |
--------------------------------------------------------------------------------
/src/components/ani-list01.vue:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
34 |
--------------------------------------------------------------------------------
/src/components/ani-no-data.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ message.title }}
5 |
6 |
7 |
8 |
23 |
--------------------------------------------------------------------------------
/src/components/ani-pop-confirm.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{ confirmData.title }}
9 |
10 |
11 | {{ confirmData.content }}
12 |
13 |
14 |
15 |
16 |
20 | {{ confirmData.leftBtn }}
21 |
22 |
23 |
24 |
25 |
26 |
30 | {{ confirmData.rightBtn }}
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
62 |
--------------------------------------------------------------------------------
/src/components/ani-pop-win.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{ popData.title }}
9 |
10 |
11 | {{ popData.content }}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
35 |
--------------------------------------------------------------------------------
/src/electron/main.js:
--------------------------------------------------------------------------------
1 | const { app, BrowserWindow } = require('electron')
2 | const path = require('path')
3 | const utils = require('./utils.js');
4 |
5 | async function createWindow() {
6 | const win = new BrowserWindow({
7 | width: 1024,
8 | height: 800,
9 | webPreferences: {
10 | preload: path.join(__dirname, 'preload.js')
11 | }
12 | })
13 | const buildInfo = await utils.getBuildInfo();
14 | if (buildInfo && buildInfo.buildType.includes('build')) {
15 | win.loadFile('index.html') // build模式
16 | } else {
17 | win.loadURL('http://localhost:2016/#/') // dev模式
18 | }
19 | }
20 |
21 | app.whenReady().then(() => {
22 | createWindow()
23 |
24 | app.on('activate', () => {
25 | if (BrowserWindow.getAllWindows().length === 0) {
26 | createWindow()
27 | }
28 | })
29 | })
30 |
31 | app.on('window-all-closed', () => {
32 | if (process.platform !== 'darwin') {
33 | app.quit()
34 | }
35 | })
--------------------------------------------------------------------------------
/src/electron/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "aiplat.com-electron",
3 | "version": "0.0.1",
4 | "author": "aiplat.com",
5 | "description": "electron app",
6 | "scripts": {
7 | "build:electron": "electron ./main.js"
8 | }
9 | }
--------------------------------------------------------------------------------
/src/electron/preload.js:
--------------------------------------------------------------------------------
1 | window.addEventListener('DOMContentLoaded', () => {
2 | const replaceText = (selector, text) => {
3 | const element = document.getElementById(selector)
4 | if (element) element.innerText = text
5 | }
6 |
7 | for (const type of ['chrome', 'node', 'electron']) {
8 | replaceText(`${type}-version`, process.versions[type])
9 | }
10 | })
--------------------------------------------------------------------------------
/src/electron/utils.js:
--------------------------------------------------------------------------------
1 | const utils = function () {
2 | this.isIn = function(value, key, defaultValue) {
3 | value = value.includes(key) ? `${value.split(key)[1]}` : defaultValue;
4 | return value;
5 | }
6 | this.getBuildInfo = function () {
7 | return new Promise((resolve) => {
8 | let argv = process.env.npm_config_argv;
9 | if (!argv) {
10 | resolve(null);
11 | return false;
12 | }
13 | argv = JSON.parse(argv);
14 |
15 | let runId = argv.original.indexOf('run');
16 | const buildType = argv.original[runId + 1];
17 | let envType = argv.original[runId + 2];
18 | envType = envType ? this.isIn(envType, 'env=', 'uat') : 'uat';
19 | let type = argv.original[runId + 3];
20 | type = type ? this.isIn(type, 'type=', 'aiplat') : 'aiplat';
21 | resolve({
22 | runId,
23 | buildType,
24 | envType,
25 | type,
26 | });
27 | });
28 | }
29 | return this;
30 | }
31 |
32 | module.exports = utils();
--------------------------------------------------------------------------------
/src/lib.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'crypto-js/hmac-sha256';
2 | // #ifdef H5
3 | declare module 'weixin-js-sdk';
4 | declare var window: Window & typeof globalThis;
5 | declare module 'qrcode';
6 | // #endif
7 | declare var plus; // h5+
8 | declare var uni; // uni
9 | declare var getCurrentPages; // uni
10 | declare var require; // nodejs
11 | declare var process; // nodejs
12 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from '@/App.vue';
3 | import plugins from '@/plugins/index';
4 |
5 | Vue.config.productionTip = false;
6 | Vue.use(plugins);
7 |
8 | new App().$mount();
9 |
--------------------------------------------------------------------------------
/src/pages/aiplat/apps.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
14 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
141 |
143 |
--------------------------------------------------------------------------------
/src/pages/aiplat/donate.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 | {{ indexData.desc }}
12 |
13 |
14 |
24 |
{{ item1.name }}
25 |
30 | {{ item2.name }}
31 |
32 |
33 |
34 |
39 |
44 |
45 |
46 | {{ indexData.about }}
47 |
48 |
49 |
50 |
51 |
52 |
53 |
100 |
102 |
--------------------------------------------------------------------------------
/src/pages/aiplat/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
66 |
67 |
150 |
152 |
--------------------------------------------------------------------------------
/src/pages/common/about.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | {{description}}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
49 |
51 |
--------------------------------------------------------------------------------
/src/pages/common/find.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
18 |
19 | {{ item1.market + "-" + item1.name }}
20 |
21 |
22 | {{ index1 + 1 }}、{{ item1.name }}
23 |
24 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
85 |
--------------------------------------------------------------------------------
/src/pages/common/h5.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 | 正在拼命加载中..
10 |
11 |
12 |
44 |
--------------------------------------------------------------------------------
/src/pages/common/mine.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
16 |
17 |
{{ userInfo.nickName }}
18 |
19 | {{ userInfo.city || userInfo.province || userInfo.country }}
20 |
21 |
22 |
23 |
28 |
29 |
30 |
36 |
37 | {{ appName }}
38 |
39 |
40 | {{ message }}
41 |
42 |
50 | 去授权
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
110 |
115 |
--------------------------------------------------------------------------------
/src/pages/common/userAgent.vue:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
48 |
50 |
--------------------------------------------------------------------------------
/src/pages/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
15 |
16 |
17 | {{ title }}
18 |
19 |
20 | 请确认以下授权信息
21 |
22 |
23 | •
25 | {{
26 | project
27 | }}旗下应用将获得您的公开信息(昵称、头像、签名等)
29 |
30 |
31 |
35 | 授权
36 |
37 |
38 |
39 |
45 | 授权
46 |
47 |
48 |
49 |
56 | 授权
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
189 |
--------------------------------------------------------------------------------
/src/plugins.d.ts:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import api from '@/service/api';
3 | import conf from '@/service/config';
4 | import cmappClass from '@/plugins/cmapp.class';
5 | import uniAjax from '@/plugins/uniAjax';
6 |
7 | const cmapp = new cmappClass();
8 | declare module 'vue/types/vue' {
9 | interface Vue {
10 | $api: api,
11 | $config: conf,
12 | $cmapp: cmapp,
13 | $uniAjax: uniAjax,
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/plugins/cmapp.class.ts:
--------------------------------------------------------------------------------
1 | /*
2 | -----------------------------------------------------------------
3 | // Copyright (C) 2016 https://aiplat.com 版权所有。
4 | // cmapp.ts
5 | // 创 建 人:aiplat.com
6 | // 修改日期:2019.01.23
7 | // 描述:小程序专用
8 | -----------------------------------------------------------------
9 | */
10 |
11 | class cmappClass {
12 | public authCallBack:any; // 对应 以下参数 func,当类型function时授权之后返回到上一页执行一次func
13 | public authType:number; // 对应authTypeObj
14 | public authTypeObj:Array; // 微信授权
15 | public environmentInfo: any = {
16 | userAgent: null,
17 | isMiniprogram: !window, // 是否为小程序环境
18 | isElectron: 0, // 是否为electron环境
19 | isWeixin: 0, // 微信环境
20 | isWechat: 0, // 公众号环境
21 | isWxwork: 0, // 企业微信环境
22 | isDevtools: 0, // 微信开发者工具环境
23 | isApp: 0, // app环境
24 | isHvoi: 0, // 特定手机或系统
25 | isWebview: 0, // 是否为内嵌的webview
26 | appType: 0
27 | }; // 环境详情参数
28 | public innerAudioContext: any;
29 | constructor() {
30 | this.authType = 0;
31 | this.authTypeObj = [
32 | {
33 | type: 'scope.userLocation',
34 | title: '温馨提示',
35 | content: '需要获取您的位置信息',
36 | ts: '未授权微信获取位置',
37 | },
38 | {
39 | type: 'scope.werun',
40 | title: '温馨提示',
41 | content: '需要获取您的运动信息',
42 | ts: '未授权微信获取步数',
43 | },
44 | {
45 | type: 'scope.camera',
46 | title: '温馨提示',
47 | content: '需要获取您的系统相机',
48 | ts: '未授权微信获取相机',
49 | },
50 | ];
51 | }
52 | getUniApi(uniApi: any, config = {}) {
53 | let isSuccess = 0;
54 | return new Promise((resolve: any, reject: any) => {
55 | const callback = {
56 | ...config,
57 | success(res: any) {
58 | isSuccess = 1;
59 | resolve({
60 | isSuccess,
61 | res,
62 | });
63 | },
64 | fail(res: any) {
65 | reject({
66 | isSuccess,
67 | res,
68 | });
69 | },
70 | }
71 | uniApi(callback);
72 | });
73 | }
74 | isApp() {
75 | return window && window.plus || false;
76 | }
77 | setStorage(key: string, value: any, type = 'uni') {
78 | if (type === 'plus') {
79 | this.isApp() && window.plus.storage.setItem(key, value) || window.localStorage.setItem(key, value);
80 | return;
81 | }
82 | uni.setStorageSync(key, value);
83 | }
84 | getStorage(key: string, type = 'uni') {
85 | if (type === 'plus') {
86 | return this.isApp() && window.plus.storage.getItem(key) || window.localStorage.getItem(key) || '';
87 | }
88 | return uni.getStorageSync(key) || '';
89 | }
90 | removeStorage(key: string, type = 'uni') {
91 | if (key) {
92 | if (type === 'plus') {
93 | this.isApp() && window.plus.storage.removeItem(key) || window.localStorage.removeItem(key);
94 | return;
95 | }
96 | uni.removeStorageSync(key);
97 | } else {
98 | window && window.localStorage.clear();
99 | uni.clearStorageSync();
100 | }
101 | }
102 | updateLS(k:string, timeKey:string, s:number, func:any) { // k值的timeKey超过s分钟为过期,过期(id=0)则清除k值
103 | const cmapp:any = this;
104 | const nd:any = new Date().valueOf();
105 | const kid:any = cmapp.getStorage(k);
106 | const time:any = cmapp.getStorage(timeKey);
107 | let id:number = 1;
108 | if (kid && time && nd - time >= 1000 * 60 * s) {
109 | cmapp.removeStorage(k);
110 | id = 0;
111 | }
112 | if (typeof func === 'function') {
113 | func(id);
114 | }
115 | }
116 | getSearchValue(name: string, path = '') {
117 | let reg: any = new RegExp(name + '=([^&]*)(&|$)', 'i');
118 | const params = path || (!this.environmentInfo.isMiniprogram && window.location.href || '');
119 |
120 | reg = params.substr(1).match(reg);
121 | const value = reg != null ? reg[1] : null;
122 | return value;
123 | }
124 | getQuery($vue: any, key: string) {
125 | const route = '_route';
126 | let query = $vue.$mp && $vue.$mp.query || null;
127 | const query2 = $vue[route] && $vue[route].query || null;
128 | const query3 = $vue.__page__ && $vue.__page__.options || null;
129 | query = query || query2 || query3;
130 | if (key === 'query') {
131 | return query || '';
132 | }
133 | const value2 = !this.environmentInfo.isMiniprogram && window.location.href.includes(`${key}=`) && this.getSearchValue(key) || '';
134 | return query && query[key] || value2 || '';
135 | }
136 | getSelectorInfo(selector: string) {
137 | return new Promise((resolve: any) => {
138 | const query: any = uni.createSelectorQuery();
139 | query.select(selector).boundingClientRect();
140 | query.selectViewport().scrollOffset();
141 | query.exec((res: any) => {
142 | resolve(res);
143 | });
144 | });
145 | }
146 | getDivMatrix(m:any) { // 获取旋转对象div的matrix转换为角度
147 | const d1:number = 180;
148 | const d2:number = 360;
149 | const aa:any = Math.round(d1 * Math.asin(m[0]) / Math.PI);
150 | const bb:any = Math.round(d1 * Math.acos(m[1]) / Math.PI);
151 | const cc:any = Math.round(d1 * Math.asin(m[2]) / Math.PI);
152 | const dd:any = Math.round(d1 * Math.acos(m[3]) / Math.PI);
153 | let deg:any = 0;
154 | if (aa === bb || -aa === bb) {
155 | deg = dd;
156 | } else if (-aa + bb === d1) {
157 | deg = d1 + cc;
158 | } else if (aa + bb === d1) {
159 | deg = d2 - cc || d2 - dd;
160 | }
161 | return deg >= d2 ? 0 : deg;
162 | }
163 | /**
164 | * 获取旋转对象div的matrix
165 | * @param selector
166 | */
167 | getDivDeg(selector: string) {
168 | const $cmapp: any = this;
169 | return new Promise((resolve: any, reject: any) => {
170 | uni.createSelectorQuery().select(selector).fields({
171 | dataset: true,
172 | size: true,
173 | scrollOffset: true,
174 | properties: ['scrollX', 'scrollY'],
175 | computedStyle: ['animation', 'transform'],
176 | context: true,
177 | }, async function (res: any) {
178 | if (res.transform) {
179 | const transform: any = res.transform;
180 | const matrix: any = transform.split(',');
181 | if (matrix && matrix.length > 0) {
182 | matrix[0] = matrix[0].split('(').pop();
183 | const deg: any = await $cmapp.getDivMatrix(matrix);
184 | resolve(deg);
185 | } else {
186 | reject(0);
187 | }
188 | } else {
189 | reject(0);
190 | }
191 | }).exec();
192 | });
193 | }
194 | update() {// 升级
195 | const cmapp:any = this;
196 | const updateManager:any = uni.getUpdateManager();
197 |
198 | updateManager.onCheckForUpdate((res:any) => {
199 | // 请求完新版本信息的回调
200 | console.log(res.hasUpdate);
201 | });
202 |
203 | updateManager.onUpdateReady(function () {
204 | cmapp.removeStorage('');
205 | const a:object = {
206 | title: '新版本更新中..',
207 | icon: 'none',
208 | };
209 | uni.showToast(a);
210 | updateManager.applyUpdate();
211 | });
212 |
213 | updateManager.onUpdateFailed(() => {
214 | // 新版本下载失败
215 | });
216 | }
217 | /**
218 | * 打开页面 只用于 cmapp.isToAuth 中转(所有点击都必须经过cmapp.isToAuth)
219 | * @param url 路由
220 | * @param navigateType 类型 switchTab、reLaunch、navigateTo、redirectTo、navigateBack
221 | */
222 | jumpTo(url:string, navigateType:string, isAuth = 'no') {
223 | if (!url && navigateType !== 'navigateBack') {
224 | console.log(isAuth);
225 | return;
226 | }
227 | switch (navigateType) {
228 | case 'switchTab': uni.switchTab({ url: url }); break;
229 | case 'reLaunch': uni.reLaunch({ url: url }); break;
230 | case 'navigateBack': uni.navigateBack(); break;
231 | case 'navigateTo': uni.navigateTo({ url: url }); break;
232 | case 'redirectTo': uni.redirectTo({ url: url }); break;
233 | case 'yes': uni.redirectTo({ url: url }); break;// 同redirectTo
234 | default: uni.navigateTo({ url: url }); break;
235 | }
236 | }
237 | /**
238 | * 统一点击方法 cmapp.isToAuth
239 | // 对应 以下参数 func,当类型function时授权之后返回到上一页执行一次func
240 | */
241 | isToAuth(page:any, navigateType:any, func:any) {
242 | const cmapp:any = this;
243 | const wxinfo = cmapp.getStorage('userInfo');
244 | const nb = 'navigateBack';
245 | let nt = navigateType;
246 | if (wxinfo && wxinfo.openid) {
247 | if (nt === nb && typeof func === 'function') {
248 | func();
249 | return;
250 | }
251 | cmapp.jumpTo(page, navigateType);
252 | } else {
253 | if (nt === nb && typeof func === 'function') {
254 | cmapp.authCallBack = func;
255 | }
256 | if (!nt) {
257 | nt = 'redirectTo';
258 | }
259 | const shareUrl = encodeURIComponent(page);
260 | const authUrl = `/pages/index?shareUrl=${shareUrl}&navigateType=${nt}`;
261 | cmapp.jumpTo(authUrl, 'navigateTo');
262 | }
263 | }
264 | /**
265 | * 执行cmapp.isToAuth中参数func的方法
266 | * 需要在执行了cmapp.isToAuth方法时的页面onShow中加 this.$cmapp.getAuthCallBack();
267 | */
268 | getAuthCallBack() {
269 | const cmapp:any = this;
270 | const isCallBack:any = cmapp.getStorage('isCallBack');
271 | if (typeof cmapp.authCallBack === 'function' && isCallBack && isCallBack === 'yes') {
272 | cmapp.authCallBack();
273 | cmapp.authCallBack = '';
274 | cmapp.removeStorage('isCallBack');
275 | } else if (isCallBack === 'yes') {
276 | cmapp.authCallBack = '';
277 | cmapp.removeStorage('isCallBack');
278 | }
279 | }
280 | /**
281 | 小程序登录获取code
282 | */
283 | getCode() {
284 | let code:any = null;
285 | return new Promise((resolve, reject) => {
286 | uni.login({
287 | success: async (res:any) => {
288 | if (res.code) {
289 | code = res.code;
290 | }
291 | resolve(code);
292 | },
293 | fail: async () => {
294 | reject(code);
295 | },
296 | });
297 | });
298 | }
299 | /**
300 | * 检测是否授权
301 | * @param key 是否存在的Stroage的key
302 | * @param func1
303 | * @param func2
304 | * @returns {Promise}
305 | */
306 | async checkLogin(key:any, func1:any, func2:any) {
307 | const cmapp:any = this;
308 | const storageValue = cmapp.getStorage(key);
309 | if (storageValue) {
310 | await func1();
311 | } else {
312 | await func2();
313 | }
314 | }
315 | /**
316 | * 获取openid
317 | * @param t
318 | * @param code
319 | * @param func
320 | * @returns {Promise}
321 | */
322 | async getOpenid($vue:any, code:any) {
323 | const cmapp:any = this;
324 | return new Promise(async (resolve) => {
325 | const responseData = await $vue.$uniAjax.http($vue.$api.sign.getUserId, {
326 | apptype: $vue.$config.project.type,
327 | plat: $vue.$config.platform,
328 | code: code,
329 | }, {
330 | method: 'POST',
331 | });
332 | const openid = responseData.isSuccess && responseData.data && responseData.data.list && responseData.data.list.openid || null;
333 | openid && cmapp.setStorage('openid', openid);
334 | !openid && cmapp.removeStorage('openid');
335 | resolve(openid);
336 | });
337 | }
338 | /**
339 | * 保存用户信息
340 | * @param t
341 | * @param info
342 | * @param func
343 | * @returns {Promise}
344 | */
345 | saveUserInfo(t:any, info:any, func:any) {
346 | const cmapp:any = this;
347 | info.platform = t.$config.platform;
348 | info.apptype = t.$config.project.type;
349 | info.openid = info.openid ? info.openid : t.$cmapp.getStorage('openid');
350 | t.$uniAjax.http(t.$api.sign.saveUserInfo, info, {
351 | method: 'POST',
352 | }, (isSuc:number, res:any) => {
353 | t.$store.dispatch('setUserInfo', info);
354 | cmapp.setStorage('userInfo', info);
355 | let d:any = null;
356 | if (isSuc) {
357 | d = res.data;
358 | }
359 | if (typeof func === 'function') {
360 | func(d);
361 | }
362 | }, 'no');
363 | }
364 | /**
365 | * 已授权 直接到对应的shareUrl页面
366 | * @param t
367 | * @param isTs
368 | */
369 | authToPage(t:any, isTs = 'no', time:any) {
370 | const cmapp:any = this;
371 | let url = `/pages/${t.$config.project.type}/index`;
372 | const shareUrl = cmapp.getStorage('shareUrl');
373 | if (shareUrl) {
374 | url = decodeURIComponent(shareUrl);
375 | }
376 | if (t.navigateType === 'navigateBack') {
377 | cmapp.setStorage('isCallBack', 'yes');
378 | }
379 | if (isTs === 'no') {
380 | cmapp.jumpTo(url, t.navigateType);
381 | return;
382 | }
383 | let timeOut = 2000;
384 | if (time) {
385 | timeOut = time;
386 | }
387 | setTimeout(() => {
388 | cmapp.jumpTo(url, t.navigateType);
389 | }, timeOut);
390 | }
391 | /**
392 | * 获取分享路由所带的参数
393 | * @param query
394 | * @param k
395 | * @returns {Promise}
396 | */
397 | getUrlParams(t:any, query:any, k:any) {
398 | const cmapp:any = this;
399 | if (query && query[k]) {
400 | cmapp.setStorage(k, decodeURIComponent(query[k]));
401 | } else {
402 | cmapp.removeStorage(k);
403 | }
404 | }
405 | /**
406 | * 入口页面
407 | * @param t
408 | * @param isAuth 有tabs并且当前页面是tabs中一页时必为yes
409 | * @param query
410 | * @param func
411 | * @returns {Promise}
412 | */
413 | async noAuthIndex(t:any, isAuth = 'no', query:any, func:any) {
414 | const cmapp:any = this;
415 | uni.showLoading({ title: '数据加载中..' });
416 | await cmapp.getUrlParams(t, query, 'scene');
417 | await cmapp.getUrlParams(t, query, 'shareId');
418 | await cmapp.getUrlParams(t, query, 'shareUrl');
419 | await cmapp.getUrlParams(t, query, 'returnUrl');
420 | if (query && query.navigateType) {
421 | t.navigateType = query.navigateType;
422 | }
423 | const d = async () => {
424 | uni.hideLoading();
425 | t.isLoadEnd = 1;
426 | let shareUrl:any = cmapp.getStorage('shareUrl');
427 | const userInfo:any = cmapp.getStorage('userInfo');
428 | if (userInfo) {
429 | t.$store.dispatch('setUserInfo', userInfo);
430 | await t.$cmapp.saveUserInfo(t, userInfo);
431 | }
432 | if (isAuth === 'yes') {
433 | if (userInfo && shareUrl) {
434 | cmapp.authToPage(t, 'no');
435 | return;
436 | }
437 | if (typeof func === 'function') {
438 | func();
439 | }
440 | return;
441 | }
442 | if (shareUrl) {
443 | shareUrl = decodeURIComponent(shareUrl);
444 | cmapp.jumpTo(shareUrl, query.navigateType || '');
445 | }
446 | if (typeof func === 'function') {
447 | func();
448 | }
449 | };
450 | cmapp.checkLogin('openid', () => {
451 | d();
452 | }, async () => {
453 | cmapp.getCode().then((code:any) => {
454 | cmapp.getOpenid(t, code).then(() => {
455 | d();
456 | });
457 | });
458 | });
459 | }
460 | /**
461 | * PopWin.vue关闭窗口
462 | */
463 | closePop(t:any, time = 1, func:any) {
464 | setTimeout(() => {
465 | t.popIsShow = 'no';
466 | if (typeof func === 'function') {
467 | func();
468 | }
469 | }, time * 1000);
470 | }
471 | /**
472 | * 设置分享信息
473 | * @param t
474 | * @param d d参数如下4个:
475 | * @param sharePage 已授权后打开的路由
476 | * @param shareIndex 未授权时打开的页面,默认/pages/${t.$config.project.dir}/index
477 | * @param shareTitle 分享标题
478 | * @param shareUrl 打开sharePage或shareIndex之后再打开的shareUrl,默认不打开
479 | * @returns {{path: (*|string), title: (string|*)}}
480 | */
481 | setShareMessage(t:any, d:any) {
482 | const cmapp:any = this;
483 | let path = d.sharePage;
484 | const userInfo = cmapp.getStorage('userInfo');
485 | if (!userInfo) {
486 | path = d.shareIndex ? `${d.shareIndex}` : `/pages/${t.$config.project.dir}/index`;
487 | }
488 | path += path.includes('?') ? '&' : '?';
489 | path += `shareId=${cmapp.getStorage('openid') ? cmapp.getStorage('openid') : ''}`;
490 | path += `&scene=${cmapp.getStorage('scene') ? cmapp.getStorage('scene') : ''}`;
491 | if (d.shareUrl) {
492 | path += `&shareUrl=${encodeURIComponent(d.shareUrl)}`;
493 | }
494 | const title = d.shareTitle ? `${d.shareTitle}` : t.$config.project.name;
495 | return {
496 | title: title,
497 | path: path,
498 | };
499 | }
500 | /**
501 | * 支付宝 设置主题颜色
502 | */
503 | setNavigationBarColor() {
504 | // #ifdef MP-ALIPAY
505 | const bgColor = '#1890FF';
506 | const txtColor = '#FFFFFF';
507 | uni.setNavigationBarColor({
508 | frontColor: txtColor,
509 | backgroundColor: bgColor,
510 | animation: {
511 | duration: 400,
512 | timingFunc: 'easeIn',
513 | },
514 | });
515 | // #endif
516 | }
517 | notFound() { // 页面不存在时自动到首页
518 | // @ts-ignore
519 | uni.onPageNotFound((res:any) => {
520 | uni.showToast({
521 | title: '页面出错,自动到首页',
522 | icon: 'none',
523 | });
524 | let q:any = '';
525 | if (res.query && res.query.scene) {
526 | const scene = decodeURIComponent(res.query.scene);
527 | q = `?scene=${scene}`;
528 | }
529 | setTimeout(() => {
530 | uni.redirectTo({ url: `/pages/index${q}` });
531 | }, 2000);
532 | });
533 | }
534 | /**
535 | * 结合h5跳转路由
536 | * @param path
537 | * @param url
538 | * @param type
539 | */
540 | goToWindow(url:any, type:any) {
541 | // #ifdef APP-PLUS
542 | this.setStorage('h5url', url);
543 | this.jumpTo('/pages/common/h5', '', '');
544 | // #endif
545 | // #ifndef APP-PLUS
546 | // #ifdef H5
547 | const w:any = window;
548 | if (type === 'email') {
549 | w.location = `mailto:${url}`;
550 | return;
551 | }
552 | w.location = url;
553 | // #endif
554 | // #ifndef H5
555 | uni.showToast({
556 | title: '请打开aiplat.com查看',
557 | icon: 'none',
558 | });
559 | // #endif
560 | // #endif
561 | }
562 | tsCity(cityName:string) { // 删除市、区、县 三字
563 | const lastStr:any = cityName.substr(cityName.length - 1);
564 | const filterWords:Array = ['市', '区', '县'];
565 | if (filterWords.includes(lastStr) && cityName.length > 2) {
566 | cityName = cityName.slice(0, -1);
567 | }
568 | return cityName;
569 | }
570 | lessThan10(num: any) { // 0~9前加0
571 | return num < 10 ? `0${num}` : num;
572 | }
573 | /*
574 | * 1,当前日期时间戮 cmapp.nowTime(0,0);
575 | * 2,日期转时间戮 cmapp.nowTime(0,'2017-01-01');
576 | * 3,时间戮转日期 cmapp.nowTime(1,'1500002222',f);//f为格式
577 | * */
578 | nowTime(type: any, dateTime: any, format: any, isMillisecond: any) {
579 | let nowTime: any = null;
580 | let value: any = null;
581 | if (dateTime) {
582 | nowTime = new Date(dateTime);
583 | } else {
584 | nowTime = new Date();
585 | }
586 | if (type === 0) { // 日期转时间戮
587 | const v: any = nowTime.valueOf() / 1000;
588 | if (isMillisecond) {
589 | return nowTime.valueOf();
590 | }
591 | value = parseInt(v, 10);
592 | } else { // 时间戮转日期
593 | const y: any = nowTime.getFullYear();
594 | const m: any = this.lessThan10(nowTime.getMonth() + 1);
595 | const d: any = this.lessThan10(nowTime.getDate());
596 | const h: any = this.lessThan10(nowTime.getHours());
597 | const m2: any = this.lessThan10(nowTime.getMinutes());
598 | const s: any = this.lessThan10(nowTime.getSeconds());
599 | switch (format) {
600 | case 1:
601 | value = `${y}-${m}-${d} ${h}:${m2}:${s}`;
602 | break;
603 | case 2:
604 | value = `${y}/${m}/${d} ${h}:${m2}:${s}`;
605 | break;
606 | case 3:
607 | value = `${y}/${m}/${d}`;
608 | break;
609 | case 4:
610 | value = `${y}/${m}`;
611 | break;
612 | case 5:
613 | value = `${m}/${d}`;
614 | break;
615 | case 6:
616 | value = `${y}-${m}-${d}`;
617 | break;
618 | case 7:
619 | value = `${y}-${m}`;
620 | break;
621 | case 8:
622 | value = `${m}-${d}`;
623 | break;
624 | case 9:
625 | value = `${h}:${m2}:${s}`;
626 | break;
627 | case 10:
628 | value = `${y}年${m}月${d}日`;
629 | break;
630 | case 11:
631 | value = `${y}-${m}-${d} ${h}:${m2}`;
632 | break;
633 | case 12:
634 | value = `${y}/${m}/${d} ${h}:${m2}`;
635 | break;
636 | case 13:
637 | value = `${y}年${m}月${d}日 ${h}:${m2}`;
638 | break;
639 | default:
640 | value = `${y}-${m}-${d}`;
641 | break;
642 | }
643 | }
644 | return value;
645 | }
646 | /**
647 | * 倒计时(进度条显示的时间)
648 | */
649 | countDownTime(time: any, type: any, isFan: any) {
650 | let nowTime: any = new Date().valueOf();
651 | let jdt: any = 0;
652 | const arr: Array = [3600, 24, 60, 10];
653 | let time2: any = time;
654 | if (isFan) {
655 | const a: any = nowTime;
656 | nowTime = time2;
657 | time2 = a;
658 | }
659 | if (time2 && time2 > nowTime) {
660 | const v1: any = (time2 - nowTime) / (arr[3] * arr[3] * arr[3]);
661 | const n: number = parseInt(v1, arr[3]);
662 | const v2: any = n / (arr[0] * arr[1]);
663 | const day: number = parseInt(v2, arr[3]);
664 | const v3: any = ((n - day * arr[0] * arr[1]) / arr[0]);
665 | const hour: number = parseInt(v3, arr[3]);
666 | const v4: any = ((n - day * arr[0] * arr[1] - hour * arr[0]) / arr[2]);
667 | const minutes: number = parseInt(v4, arr[3]);
668 | const seconds: any = n - day * arr[0] * arr[1] - hour * arr[0] - minutes * arr[2];
669 | jdt = `${day}天${hour}时${minutes}分${seconds}秒`;
670 | if (day <= 0) {
671 | if (type === 1) {
672 | jdt = `${hour}时${minutes}分${seconds}秒`;
673 | }
674 | if (hour <= 0 && type === 2) {
675 | jdt = `${minutes}分${seconds}秒`;
676 | }
677 | }
678 | if (type === 3) {
679 | jdt = {
680 | day: day, hour: hour, minutes: minutes, seconds: seconds,
681 | };
682 | }
683 | }
684 | return jdt;
685 | }
686 | checkMobile(value: any) {
687 | let reg: string = '^[1][3,4,5,6,7,8,9][0-9]{9}$';
688 | const regExp: any = new RegExp(reg);
689 | return regExp.test(value);
690 | }
691 | isIllegalMobile(value: any, txt = '手机号码') {
692 | let message = [`${txt}正确`, `请输入11位${txt}`, `${txt}必须为11位数字`, `${txt}格式为1(3~9)开头`];
693 | let illegalId = 0;
694 | if (!value || value.length !== 11) {
695 | illegalId = 1;
696 | } else if (!this.checkWord(value, 1)) {
697 | illegalId = 2;
698 | } else if (!this.checkMobile(value)) {
699 | illegalId = 3;
700 | }
701 | return {
702 | illegalId,
703 | message: message[illegalId],
704 | };
705 | }
706 | /**
707 | * 默认type=0:只限中文、英文
708 | * type=1:只限数字
709 | * type=2:只限数字和小数点
710 | * type=3:只限中文
711 | * type=4:只限英文
712 | * type=5:只限大写英文
713 | * type=6:只限小写英文
714 | * type=7:只限中文、英文、数字和小数点
715 | * @param v
716 | * @param type
717 | * @returns {*}
718 | */
719 | checkWord(value: any, type: any) {
720 | let reg: string = '^[A-Za-z\u4e00-\u9fa5]+$';
721 |
722 | switch (type) {
723 | case 1:
724 | reg = '^[0-9]+$';
725 | break;
726 | case 2:
727 | reg = '^[0-9.]+$';
728 | break;
729 | case 3:
730 | reg = '^[\u4e00-\u9fa5]+$';
731 | break;
732 | case 4:
733 | reg = '^[A-Za-z]+$';
734 | break;
735 | case 5:
736 | reg = '^[A-Z]+$';
737 | break;
738 | case 6:
739 | reg = '^[a-z]+$';
740 | break;
741 | case 7:
742 | reg = '^[A-Za-z0-9.\u4e00-\u9fa5]+$';
743 | case 8:
744 | reg = '^[0-9-]+$';
745 | break;
746 | default:
747 | break;
748 | }
749 | const regExp: any = new RegExp(reg);
750 | return regExp.test(value);
751 | }
752 | openWxSetting(func:any, func2:any) {// 打开设置
753 | const cmapp:any = this;
754 | const a:any = {
755 | success() {
756 | cmapp.openWxAuth(0, func, func2);
757 | },
758 | fail() {
759 | func2(func);
760 | },
761 | };
762 | uni.openSetting(a);
763 | }
764 | openWxAuth(type:any, func:any, func2:any) {// 提示授权的操作
765 | const cmapp:any = this;
766 | uni.authorize({
767 | scope: cmapp.authTypeObj[cmapp.authType].type,
768 | success(res:any) {
769 | // data: {scope.userInfo: "ok"} // res.data[cmapp.authTypeObj[cmapp.authType].type] === 'ok'
770 | // #ifdef MP-TOUTIAO
771 | if (res.data[cmapp.authTypeObj[cmapp.authType].type] === 'ok') {
772 | func(0, func);
773 | } else {
774 | func2(func);
775 | }
776 | // #endif
777 | // #ifndef MP-TOUTIAO
778 | func2(func);
779 | // #endif
780 | },
781 | fail() {
782 | if (type === 1) {
783 | uni.hideLoading();
784 | uni.showModal({
785 | title: cmapp.authTypeObj[cmapp.authType].title,
786 | content: cmapp.authTypeObj[cmapp.authType].content,
787 | success(res:any) {
788 | if (res.confirm) {
789 | cmapp.openWxSetting(func, func2);
790 | } else if (res.cancel) {
791 | if (typeof func === 'function') {
792 | func(1);
793 | }
794 | }
795 | },
796 | });
797 | } else {
798 | func2(func);
799 | }
800 | },
801 | });
802 | }
803 | /**
804 | *是否授权过
805 | * @param func 如(id, authData) => {} , id=0已授权,id=1取消授权
806 | * @param func2
807 | */
808 | checkWxUserAuth(func:any, func2:any) {
809 | const cmapp:any = this;
810 | uni.getSetting({
811 | success(res:any) {
812 | const a = res.authSetting[cmapp.authTypeObj[cmapp.authType].type] !== undefined && res.authSetting[cmapp.authTypeObj[cmapp.authType].type] !== true;
813 | const b = res.authSetting[cmapp.authTypeObj[cmapp.authType].type] === undefined;
814 | const c = JSON.stringify(res.authSetting) === '{}';
815 | let aa = a;
816 | // #ifdef MP-TOUTIAO
817 | aa = aa || c;
818 | // #endif
819 | if (aa) {
820 | cmapp.openWxAuth(1, func, func2);
821 | } else if (b) {
822 | func2(func);
823 | } else {
824 | func(0, func);
825 | }
826 | },
827 | });
828 | }
829 | getWebGeo(t:any, localGeo:any, func:any) {// 经纬度转为地址信息
830 | const cmapp:any = this;
831 | const keyId:any = Math.round(Math.random() * (t.$config.map.keys.length - 1));
832 | const d:object = {
833 | location: `${localGeo.latitude},${localGeo.longitude}`,
834 | ak: t.$config.map.keys[keyId],
835 | output: 'json',
836 | coordtype: 'gcj02ll',
837 | latest_admin: 1,
838 | };
839 | uni.request({
840 | url: t.$config.map.host + t.$config.map.apis.geocoder,
841 | data: d,
842 | method: 'GET',
843 | header: {
844 | 'content-type': 'application/json', // 默认值
845 | },
846 | success: async function (res:any) {
847 | if (res.data && res.data.status === 0) {
848 | const result:any = { ...res.data.result };
849 | const lg:any = result.addressComponent;
850 | lg.cityName = cmapp.tsCity(lg.city);
851 | lg.lng = localGeo.longitude;
852 | lg.lat = localGeo.latitude;
853 | cmapp.setStorage('localGeo', lg);
854 | }
855 | if (typeof func === 'function') {
856 | func();
857 | }
858 | },
859 | fail: async () => {
860 | if (typeof func === 'function') {
861 | func();
862 | }
863 | },
864 | });
865 | }
866 | // 获取微信经纬度
867 | getLocation(func:any) {
868 | uni.getLocation({
869 | type: 'wgs84',
870 | success(res:any) {
871 | const localGeo:any = {
872 | longitude: res.longitude,
873 | latitude: res.latitude,
874 | };
875 | if (typeof func === 'function') {
876 | func(2, localGeo);
877 | }
878 | },
879 | fail() {
880 | if (typeof func === 'function') {
881 | func(1);
882 | }
883 | },
884 | });
885 | }
886 | // 判断是否要显示loading showLoad 为 yes 或者 no
887 | showLoad(t:any, type:any) {
888 | if (!t.showLoad || t.showLoad !== 'no') {
889 | if (type === 1) {
890 | uni.showLoading({
891 | title: '数据加载中..',
892 | });
893 | return;
894 | }
895 | if (type === 0) {
896 | uni.hideLoading();
897 | }
898 | }
899 | }
900 | // 需要授权地理位置的页面
901 | // const t = this;
902 | // cmapp.authType = 0;
903 | // cmapp.checkLocalGeo(t, () => {
904 | // 授权或取消后页面执行的方法
905 | // });
906 | checkLocalGeo(t:any, func3:any) {
907 | const cmapp:any = this;
908 | cmapp.showLoad(t, 1);
909 | cmapp.authType = 0;
910 | cmapp.checkWxUserAuth(function (id:any, authData:any) {
911 | if (id === 1) {
912 | cmapp.showLoad(t, 0);
913 | func3();
914 | } else if (id === 2) {
915 | cmapp.getWebGeo(t, authData, () => {
916 | cmapp.showLoad(t, 0);
917 | func3();
918 | });
919 | } else {
920 | const localGeo:any = cmapp.getStorage('localGeo');
921 | if (!localGeo || (localGeo && !localGeo.lng)) {
922 | cmapp.getLocation(authData);
923 | } else {
924 | cmapp.showLoad(t, 0);
925 | func3();
926 | }
927 | }
928 | }, cmapp.getLocation);
929 | }
930 | /**
931 | * 重置动画
932 | * @param $vue
933 | */
934 | animationReset($vue: any) {
935 | const animation: any = uni.createAnimation({
936 | duration: 100,
937 | });
938 | animation.rotate(0).step();
939 | $vue.animationData = animation.export();
940 | }
941 | /**
942 | * 指定div或图左右摇摆的动画
943 | * @param $vue
944 | * @param animationAngle 摇摆角度
945 | * @param maxRun 摇摆次数
946 | * @param duration 每次摇摆的时间
947 | * @param callback
948 | * div中必有 :animation='animationData'
949 | * data中必有 animationData = {}字段
950 | */
951 | animationShake($vue: any, animationAngle = -10, maxRun = 6, duration = 500, callback: any) {
952 | const $cmapp: any = this;
953 | const animationRun: any = uni.createAnimation({
954 | duration: duration,
955 | timingFunction: 'ease',
956 | });
957 | animationRun.rotate(animationAngle).step();
958 | $vue.animationData = animationRun.export();
959 | let num: number = 0;
960 | const thisShake = setInterval(() => {
961 | num += 1;
962 | if (num > maxRun || $vue.animationEnd) {
963 | $vue.animationEnd = false;
964 | $cmapp.animationReset($vue);
965 | clearInterval(thisShake);
966 | if (typeof callback === 'function') {
967 | callback();
968 | }
969 | return;
970 | }
971 | animationAngle = -animationAngle;
972 | animationRun.rotate(animationAngle).step();
973 | $vue.animationData = animationRun.export();
974 | }, duration + 5);
975 | }
976 | /**
977 | * showToast方法封装
978 | * @param title 内容
979 | * @param icon 图标
980 | * @param duration 持续时间
981 | */
982 | showToast(title = '网络出错了', icon = 'none', duration = 2000, position = 'center') {
983 | return new Promise((resolve: any) => {
984 | const params: any = {
985 | title,
986 | icon,
987 | duration,
988 | position,
989 | mask: true,
990 | complete: (res:any) => {
991 | setTimeout(() => {
992 | resolve(res);
993 | }, duration);
994 | }
995 | }
996 | uni.showToast(params);
997 | });
998 | }
999 | /**
1000 | * 内部 audio 音乐播放
1001 | * @param audioUrl
1002 | * @param autoplay
1003 | */
1004 | toPlayAudio(audioUrl: string, autoplay = true) {
1005 | const $cmapp: any = this;
1006 | return new Promise((resolve, reject) => {
1007 | if (this.innerAudioContext) {
1008 | this.innerAudioContext.destroy();
1009 | }
1010 | this.innerAudioContext = uni.createInnerAudioContext();
1011 | this.innerAudioContext.autoplay = autoplay;
1012 | this.innerAudioContext.src = audioUrl;
1013 | this.innerAudioContext.play();
1014 | this.innerAudioContext.onPlay(() => {
1015 | this.showToast('播放成功');
1016 | resolve({
1017 | isSuccess: 1,
1018 | message: '播放成功',
1019 | errCode: 0,
1020 | innerAudioContext: $cmapp.innerAudioContext
1021 | });
1022 | });
1023 | this.innerAudioContext.onError((responseData: any) => {
1024 | this.showToast('播放失败');
1025 | reject({
1026 | isSuccess: 0,
1027 | message: responseData,
1028 | errCode: 0,
1029 | innerAudioContext: this.innerAudioContext
1030 | });
1031 | });
1032 | this.innerAudioContext.onEnded(() => {
1033 | this.innerAudioContext.destroy();
1034 | this.showToast('播放已结束');
1035 | });
1036 | this.innerAudioContext.onStop((responseData: any) => {
1037 | this.showToast('播放已停止');
1038 | });
1039 | });
1040 | }
1041 | /**
1042 | * 保存图片到手机
1043 | * @param isCanvas yes为从canvas保存过去,no为普通保存
1044 | * @param id isCanvas=yes时必填
1045 | * @param filePath isCanvas=no时必填
1046 | * @param callback
1047 | */
1048 | saveImageToPhotosAlbum(isCanvas = 'no', id: any, filePath: any, callback: any) {
1049 | const $cmapp: any = this;
1050 | uni.showLoading({ title: '保存中..' });
1051 | let toast: string = '保存失败';
1052 | const save: any = (path: string) => {
1053 | uni.saveImageToPhotosAlbum({
1054 | filePath: path,
1055 | success() {
1056 | uni.hideLoading();
1057 | toast = '保存成功';
1058 | $cmapp.showToast(toast);
1059 | setTimeout(() => {
1060 | if (typeof callback === 'function') {
1061 | callback();
1062 | }
1063 | }, 2000);
1064 | },
1065 | fail() {
1066 | uni.hideLoading();
1067 | $cmapp.showToast(toast);
1068 | },
1069 | });
1070 | };
1071 | if (isCanvas === 'no') {
1072 | save(filePath);
1073 | return;
1074 | }
1075 | uni.canvasToTempFilePath({
1076 | canvasId: id,
1077 | success(responseData: any) {
1078 | save(responseData.tempFilePath);
1079 | },
1080 | fail() {
1081 | uni.hideLoading();
1082 | $cmapp.showToast(toast);
1083 | },
1084 | });
1085 | }
1086 | /**
1087 | * canvas内文本自动换行
1088 | * @param ctx getContext('2d') 对象
1089 | * @param lineheight 行高
1090 | * @param bytelength 每行字数
1091 | * @param text 文本
1092 | * @param startleft 开始x坐标
1093 | * @param starttop 开始y坐标
1094 | */
1095 | canvasTextAutoLine(ctx: any, lineheight: any, bytelength: any, text: any, startleft: any, starttop: any) {
1096 | const getTrueLength: any = (str: any) => {
1097 | const length: any = str.length;
1098 | let truelen: any = 0;
1099 | for (let x: any = 0; x < length; x++) {
1100 | if (str.charCodeAt(x) > 128) {
1101 | truelen += 2;
1102 | } else {
1103 | truelen += 1;
1104 | }
1105 | }
1106 | return truelen;
1107 | };
1108 | const cutString: any = (str: any, leng: any) => {
1109 | const len: any = str.length;
1110 | let tlen: any = len;
1111 | let nlen: any = 0;
1112 | for (let x: any = 0; x < len; x++) {
1113 | if (str.charCodeAt(x) > 128) {
1114 | if (nlen + 2 < leng) {
1115 | nlen += 2;
1116 | } else {
1117 | tlen = x;
1118 | break;
1119 | }
1120 | } else {
1121 | console.log();
1122 | if (nlen + 1 < leng) {
1123 | nlen += 1;
1124 | } else {
1125 | tlen = x;
1126 | break;
1127 | }
1128 | }
1129 | }
1130 | return tlen;
1131 | };
1132 | for (let i: any = 1; getTrueLength(text) > 0; i++) {
1133 | const tl: any = cutString(text, bytelength);
1134 | ctx.fillText(text.substr(0, tl).replace(/^\s+|\s+$/, ''), startleft, (i - 1) * lineheight + starttop);
1135 | text = text.substr(tl);
1136 | }
1137 | }
1138 | /**
1139 | * 返回到已打开的某个页面
1140 | * @param url 为要返回到的那个页面的路由地址,如pages/aiplat/index
1141 | * @param url2 如果是要返回到某个页面时并要打开在这个页面才有的入口页面,返回到url时要再进入url2
1142 | * @param callback
1143 | */
1144 | backTo(url: string, url2: string) {
1145 | const currentPages: any = getCurrentPages();
1146 | const isCurrentPage: any = currentPages.filter((x: { route: string; }) => x.route === url);
1147 | return new Promise((resolve: any) => {
1148 | if (isCurrentPage && isCurrentPage.length > 0) {
1149 | const page: any = currentPages.length - currentPages.indexOf(isCurrentPage[0]) - 1;
1150 | uni.navigateBack({
1151 | delta: page,
1152 | });
1153 | if (url2) {
1154 | setTimeout(() => {
1155 | uni.navigateTo({
1156 | url: url2,
1157 | });
1158 | }, 100);
1159 | }
1160 | }
1161 | resolve();
1162 | });
1163 | }
1164 | openLocation(latitude: any, longitude: any, name: string, address: string) {
1165 | latitude = parseFloat(latitude);
1166 | longitude = parseFloat(longitude);
1167 | this.getUniApi(uni.openLocation, {
1168 | latitude,
1169 | longitude,
1170 | scale: 18,
1171 | name,
1172 | address,
1173 | }).then((responseData:any) => {
1174 | console.log(responseData);
1175 | }).catch((responseData:any) => {
1176 | console.log(responseData);
1177 | });
1178 | }
1179 | onAccelerometerChange($vue: any, url:string) {
1180 | this.getUniApi(uni.getSystemInfo).then(() => {
1181 | uni.onAccelerometerChange((e: any) => {
1182 | const pages: any = getCurrentPages();
1183 | const currentPage: any = pages[pages.length - 1];
1184 | if (currentPage.route === url) {
1185 | currentPage.$vm.onAccelerometerChange(e);
1186 | }
1187 | });
1188 | }).catch((responseData:any) => {
1189 | console.log(responseData);
1190 | });
1191 | }
1192 | scrollTo(scrollTop: number, duration: number, selector: string) {
1193 | return new Promise((resolve) => {
1194 | const params: object = {
1195 | scrollTop: scrollTop || 0,
1196 | duration: duration || 999,
1197 | selector: selector || '',
1198 | complete: () => {
1199 | resolve();
1200 | }
1201 | };
1202 | uni.pageScrollTo(params);
1203 | });
1204 | }
1205 | eventListener(type: string, eventName: any, func: any) {
1206 | if (!eventName) {
1207 | return;
1208 | }
1209 | if (type === 'dispatchEvent') {
1210 | const event: any = new Event(eventName);
1211 | event && window.dispatchEvent(event);
1212 | return;
1213 | }
1214 | window.addEventListener(eventName, func);
1215 | }
1216 | showInfo(title:any,content:any, showCancel:any, cancelText:any, confirmText:any, confirmColor:any, completeFunction:any) {
1217 | if (!content) {
1218 | return;
1219 | }
1220 | uni.showModal({
1221 | title: title || '温馨提示',
1222 | content: content,
1223 | showCancel: showCancel || false,
1224 | cancelText: cancelText || '取消',
1225 | confirmText: confirmText || '确定',
1226 | confirmColor: confirmColor || '#ff8b15',
1227 | complete: (res:any)=>{
1228 | completeFunction && completeFunction(res);
1229 | }
1230 | });
1231 | }
1232 | getAppType() {
1233 | if (!window) {
1234 | return 'miniprogram';
1235 | }
1236 | const userAgent = window.navigator.userAgent.toLowerCase();
1237 | if (userAgent && /(android)/i.test(userAgent)) {
1238 | return 'android';
1239 | } else if (userAgent && /(iphone|ipad|ipod|ios)/i.test(userAgent)) {
1240 | return 'ios';
1241 | } else if (userAgent && /(mobile|micromessenger)/i.test(userAgent)) {
1242 | return 'mobile';
1243 | }
1244 | return 'pc'; // pc
1245 | }
1246 | async setEnvironmentInfo($vue: any) {
1247 | this.environmentInfo.isMiniprogram = !window;
1248 | this.environmentInfo.isWebview = this.getQuery($vue, 'isWebview') ? 1 : 0;
1249 | this.environmentInfo.appType = this.getAppType();
1250 | // #ifdef APP-PLUS
1251 | this.environmentInfo.isApp = 1;
1252 | // #endif
1253 | const weixinType = this.getQuery($vue, 'weixinType') || this.getStorage('weixinType');
1254 | if (weixinType) {
1255 | this.setStorage('weixinType', weixinType);
1256 | }
1257 | // #ifdef H5
1258 | this.environmentInfo.userAgent = window.navigator.userAgent.toLowerCase();
1259 | this.environmentInfo.isElectron = this.environmentInfo.userAgent.includes('electron') ? 1 : 0;
1260 | this.environmentInfo.isWeixin = this.environmentInfo.userAgent.includes('micromessenger') ? 1 : 0;
1261 | this.environmentInfo.isWxwork = this.environmentInfo.userAgent.includes('wxwork') ? 1 : 0;
1262 | this.environmentInfo.isWechat = (this.environmentInfo.isWeixin && !this.environmentInfo.isWxwork) || this.environmentInfo.userAgent.includes('wechat') ? 1 : 0;
1263 | this.environmentInfo.isDevtools = this.environmentInfo.userAgent.includes('wechatdevtools') ? 1 : 0;
1264 | this.environmentInfo.isApp = this.environmentInfo.userAgent.includes('html5plus') ? 1 : 0;
1265 | const hvoi = this.environmentInfo.userAgent.includes('huawei') || this.environmentInfo.userAgent.includes('vivo') || this.environmentInfo.userAgent.includes('oppo') || this.environmentInfo.userAgent.includes('iphone');
1266 | this.environmentInfo.isHvoi = hvoi ? 1 : 0;
1267 | // #endif
1268 | if (weixinType === 'wechat') {
1269 | this.environmentInfo.isWechat = 1;
1270 | this.environmentInfo.isWxwork = 0;
1271 | }
1272 | if (weixinType === 'wxwork') {
1273 | this.environmentInfo.isWechat = 0;
1274 | this.environmentInfo.isWxwork = 1;
1275 | }
1276 | $vue.$forceUpdate();
1277 | }
1278 | }
1279 |
1280 | export default cmappClass;
1281 |
--------------------------------------------------------------------------------
/src/plugins/index.ts:
--------------------------------------------------------------------------------
1 |
2 | import store from '@/vuex/store';
3 | import api from '@/service/api';
4 | import config from '@/service/config';
5 | import cmappClass from '@/plugins/cmapp.class';
6 | import uniAjax from '@/plugins/uniAjax';
7 |
8 | const plugins:any = {};
9 |
10 | plugins.install = function (Vue:any) {
11 | Vue.prototype.$store = store;
12 | Vue.prototype.$api = api;
13 | Vue.prototype.$config = config;
14 | Vue.prototype.$cmapp = new cmappClass();
15 | Vue.prototype.$uniAjax = uniAjax;
16 | }
17 |
18 | export default plugins;
19 |
--------------------------------------------------------------------------------
/src/plugins/lib/axios.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @FilePath: \src\plugins\lib\axios.ts
3 | * @Description: 用于请求第三方接口:比如地图api,公司接口都使用src/plugins/uniAjax.class.ts
4 | * @Author: aiplat.com
5 | * @Date: 2020-08-26 20:37:04
6 | * @LastEditTime: 2020-08-26 20:41:33
7 | */
8 | import axios from 'axios';
9 |
10 | axios.defaults.adapter = function (config: any) {
11 | return new Promise((resolve, reject) => {
12 | const settle: any = require('axios/lib/core/settle');
13 | const buildURL: any = require('axios/lib/helpers/buildURL');
14 | uni.request({
15 | method: config.method.toUpperCase(),
16 | url: buildURL(config.url, config.params, config.paramsSerializer),
17 | header: config.headers,
18 | data: config.data,
19 | dataType: config.dataType,
20 | responseType: config.responseType,
21 | sslVerify: config.sslVerify,
22 | complete: function complete(response: any) {
23 | response = {
24 | data: response.data,
25 | status: response.statusCode,
26 | errMsg: response.errMsg,
27 | header: response.header,
28 | config: config
29 | };
30 | settle(resolve, reject, response);
31 | }
32 | });
33 | });
34 | };
35 | export default axios;
--------------------------------------------------------------------------------
/src/plugins/lib/canvas2Image.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @FilePath: \src\plugins\lib\canvas2Image.ts
3 | * @Description: canvas生成image
4 | * @Author: aiplat.com
5 | * @Date: 2020-06-28 09:42:24
6 | * @LastEditTime: 2020-07-30 20:40:50
7 | */
8 | import html2canvas from 'html2canvas';
9 |
10 | const Canvas2Image = () => {
11 | const win:any = window;
12 | const downloadMime = 'image/octet-stream';
13 |
14 | function scaleCanvas(canvas:any, width:any, height:any) {
15 | const w = canvas.width;
16 | const h = canvas.height;
17 | if (width === undefined) {
18 | width = w;
19 | }
20 | if (height === undefined) {
21 | height = h;
22 | }
23 |
24 | const retCanvas = win.document.createElement('canvas');
25 | const retCtx:any = retCanvas.getContext('2d');
26 | retCanvas.width = width;
27 | retCanvas.height = height;
28 | retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
29 | return retCanvas;
30 | }
31 |
32 | function getDataURL(canvas:any, type:any, width:any, height:any) {
33 | canvas = scaleCanvas(canvas, width, height);
34 | return canvas.toDataURL(type);
35 | }
36 |
37 | function saveFile(strData:any, filename:any) {
38 | // const a = win.document.createElement('a');
39 | // a.href = strData;
40 | // a.download = filename;
41 | // const event = new MouseEvent('click', { bubbles: false, cancelable: false });
42 | // a.dispatchEvent(event);
43 | const saveLink:any = win.document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
44 | saveLink.href = strData;
45 | saveLink.download = filename;
46 |
47 | const event = win.document.createEvent('MouseEvents');
48 | event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
49 | saveLink.dispatchEvent(event);
50 | }
51 |
52 | function genImage(strData:any) {
53 | return strData;
54 | }
55 |
56 | function fixType(type:any) {
57 | type = type.toLowerCase().replace(/jpg/i, 'jpeg');
58 | const r = type.match(/png|jpeg|bmp|gif/)[0];
59 | return `image/${r}`;
60 | }
61 |
62 | function encodeData(data:any) {
63 | if (!window.btoa) {
64 | return 'btoa undefined';
65 | }
66 | let str = '';
67 | if (typeof data === 'string') {
68 | str = data;
69 | } else {
70 | for (let i2 = 0; i2 < data.length; i2 += 1) {
71 | str += String.fromCharCode(data[i2]);
72 | }
73 | }
74 |
75 | return btoa(str);
76 | }
77 |
78 | function getImageData(canvas:any) {
79 | const w = canvas.width;
80 | const h = canvas.height;
81 | return canvas.getContext('2d').getImageData(0, 0, w, h);
82 | }
83 |
84 | function makeURI(strData:any, type:any) {
85 | return `data: ${type};base64,${strData}`;
86 | }
87 |
88 |
89 | /**
90 | * create bitmap image
91 | * 按照规则生成图片响应头和响应体
92 | */
93 | const genBitmapImage = (oData:any) => {
94 | //
95 | // BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
96 | // BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
97 | //
98 |
99 | const biWidth = oData.width;
100 | const biHeight = oData.height;
101 | const biSizeImage = biWidth * biHeight * 3;
102 | const bfSize = biSizeImage + 54; // total header size = 54 bytes
103 | const BITMAPFILEHEADER = [
104 | // WORD bfType -- The file type signature; must be "BM"
105 | 0x42, 0x4D,
106 | // DWORD bfSize -- The size, in bytes, of the bitmap file
107 | bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
108 | // WORD bfReserved1 -- Reserved; must be zero
109 | 0, 0,
110 | // WORD bfReserved2 -- Reserved; must be zero
111 | 0, 0,
112 | // DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
113 | 54, 0, 0, 0,
114 | ];
115 | const BITMAPINFOHEADER = [
116 | // DWORD biSize -- The number of bytes required by the structure
117 | 40, 0, 0, 0,
118 | // LONG biWidth -- The width of the bitmap, in pixels
119 | biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
120 | // LONG biHeight -- The height of the bitmap, in pixels
121 | biHeight & 0xff, biHeight >> 8 & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
122 | // WORD biPlanes -- The number of planes for the target device. This value must be set to 1
123 | 1, 0,
124 | // WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
125 | // has a maximum of 2^24 colors (16777216, Truecolor)
126 | 24, 0,
127 | // DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
128 | 0, 0, 0, 0,
129 | // DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
130 | biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
131 | // LONG biXPelsPerMeter, unused
132 | 0, 0, 0, 0,
133 | // LONG biYPelsPerMeter, unused
134 | 0, 0, 0, 0,
135 | // DWORD biClrUsed, the number of color indexes of palette, unused
136 | 0, 0, 0, 0,
137 | // DWORD biClrImportant, unused
138 | 0, 0, 0, 0,
139 | ];
140 |
141 | const iPadding = (4 - ((biWidth * 3) % 4)) % 4;
142 |
143 | const aImgData = oData.data;
144 |
145 | let strPixelData = '';
146 | const biWidth4 = biWidth << 2;
147 | let y = biHeight;
148 | y -= 1;
149 | do {
150 | const iOffsetY = biWidth4 * (y - 1);
151 | let strPixelRow = '';
152 | for (let x = 0; x < biWidth; x += 1) {
153 | const iOffsetX = x << 2;
154 | strPixelRow += String.fromCharCode(aImgData[iOffsetY + iOffsetX + 2]) +
155 | String.fromCharCode(aImgData[iOffsetY + iOffsetX + 1]) +
156 | String.fromCharCode(aImgData[iOffsetY + iOffsetX]);
157 | }
158 | for (let c = 0; c < iPadding; c += 1) {
159 | strPixelRow += String.fromCharCode(0);
160 | }
161 | strPixelData += strPixelRow;
162 | y -= 1;
163 | } while (y);
164 |
165 | const strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);
166 |
167 | return strEncoded;
168 | };
169 |
170 |
171 | /**
172 | * [saveAsImage]
173 | * @param {[obj]} canvas [canvasElement]
174 | * @param {[Number]} width [optional] png width
175 | * @param {[Number]} height [optional] png height
176 | * @param {[String]} type [image type]
177 | * @param {[String]} filename [image filename]
178 | * @return {[type]} [description]
179 | */
180 | const saveAsImage = (canvas:any, width:any, height:any, type:any, filename:any) => {
181 | if (typeof canvas === 'string') {
182 | canvas = win.document.getElementById(canvas);
183 | }
184 | if (type === undefined) {
185 | type = 'png';
186 | }
187 | filename = filename === undefined || filename.length === 0 ? `${Date.now()}.${type}` : `${filename}.${type}`;
188 | type = fixType(type);
189 |
190 | if (/bmp/.test(type)) {
191 | const data = getImageData(scaleCanvas(canvas, width, height));
192 | const strData = genBitmapImage(data);
193 | saveFile(makeURI(strData, downloadMime), filename);
194 | } else {
195 | const strData = getDataURL(canvas, type, width, height);
196 | saveFile(strData.replace(type, downloadMime), filename);
197 | }
198 | };
199 |
200 | const convertToImage = (canvas:any, width:any, height:any, type:any) => {
201 | if (typeof canvas === 'string') {
202 | canvas = win.document.getElementById(canvas);
203 | }
204 | if (type === undefined) {
205 | type = 'png';
206 | }
207 | type = fixType(type);
208 |
209 | if (/bmp/.test(type)) {
210 | const data = getImageData(scaleCanvas(canvas, width, height));
211 | const strData = genBitmapImage(data);
212 | return genImage(makeURI(strData, 'image/bmp'));
213 | }
214 | const strData = getDataURL(canvas, type, width, height);
215 | return genImage(strData);
216 | };
217 |
218 | const getPixelRatio = (context:any) => {
219 | const backingStore = context.backingStorePixelRatio ||
220 | context.webkitBackingStorePixelRatio ||
221 | context.mozBackingStorePixelRatio ||
222 | context.msBackingStorePixelRatio ||
223 | context.oBackingStorePixelRatio ||
224 | context.backingStorePixelRatio || 1;
225 | return (window.devicePixelRatio || 1) / backingStore;
226 | };
227 | const getHighPixels = (data:any, width:any, height:any) => {
228 | width = parseInt(width, 10);
229 | height = parseInt(height, 10);
230 | const canvas:any = win.document.querySelector('canvas');
231 | const ctx = canvas.getContext('2d');
232 | const ratio = getPixelRatio(ctx);
233 | width *= ratio;
234 | height *= ratio;
235 | return {
236 | data: data,
237 | width: width,
238 | height: height,
239 | ratio: ratio,
240 | };
241 | };
242 | const getCanvasImg = (selector1:any, selector2:any, imgType:string) => {
243 | /* #ifdef H5 */
244 | const canvasHtml1:any = win.document.querySelector(selector1);
245 | const canvasHtml2:any = win.document.querySelector(selector2);
246 | return new Promise((resolve:any) => {
247 | win.document.body.style.overflow = 'auto';
248 | html2canvas(canvasHtml1, {
249 | scale: 2,
250 | allowTaint: true,
251 | logging: false,
252 | useCORS: true,
253 | removeContainer: true,
254 | }).then((canvas:any) => {
255 | canvasHtml2.appendChild(canvas);
256 | const width = canvas.style.width.substr(0, canvas.style.width.length - 2);
257 | const height = canvas.style.height.substr(0, canvas.style.height.length - 2);
258 | const canvasData:any = getHighPixels(canvas, width, height);
259 | const base64Data = convertToImage(canvasData.data, canvasData.width, canvasData.height, imgType);
260 | win.document.body.style.overflow = 'hidden';
261 | resolve(base64Data);
262 | });
263 | });
264 | /* #endif */
265 | };
266 | return {
267 | getHighPixels: getHighPixels,
268 | saveAsImage: saveAsImage,
269 | convertToImage: convertToImage,
270 | getCanvasImg: getCanvasImg,
271 | };
272 | };
273 |
274 | export default Canvas2Image;
275 |
--------------------------------------------------------------------------------
/src/plugins/lib/loadFiles.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @FilePath: \src\plugins\lib\loadFiles.ts
3 | * @Description: 加载指定url, 待支持h5端
4 | * @Author: aiplat.com
5 | * @Date: 2020-06-28 09:42:24
6 | * @LastEditTime: 2020-12-14 15:50:38
7 | */
8 | export default function remoteLoad(url:any, isCallback:any) {
9 | const win:any = window;
10 | const file:any = { createScript: null, removeScript: null };
11 | file.createScript = (url2:any) => {
12 | const scriptElement = win.document.createElement('script');
13 | win.document.body.appendChild(scriptElement);
14 | const promise = new Promise((resolve, reject) => {
15 | scriptElement.addEventListener('load', (e:any) => {
16 | file.removeScript(scriptElement);
17 | if (!isCallback) {
18 | resolve(e);
19 | }
20 | }, false);
21 | scriptElement.addEventListener('error', (e:any) => {
22 | file.removeScript(scriptElement);
23 | reject(e);
24 | }, false);
25 | if (isCallback) {
26 | win.callback = (result:any) => {
27 | resolve(result);
28 | win.callback = null;
29 | };
30 | }
31 | });
32 | if (isCallback) {
33 | url2 += !url2.includes('?') ? '?' : '&';
34 | url2 += 'callback=callback';
35 | }
36 | scriptElement.src = url2;
37 | return promise;
38 | };
39 | file.removeScript = (scriptElement:any) => {
40 | win.document.body.removeChild(scriptElement);
41 | };
42 | return file.createScript(url);
43 | }
44 |
--------------------------------------------------------------------------------
/src/plugins/lib/setFileObject.ts:
--------------------------------------------------------------------------------
1 | /*
2 | 作者:aiplat.com(womendi@qq.com)
3 | 创建时间:2020.05.27
4 | */
5 | export default (fileList:any, fileObject:any) => {
6 | const isArray = fileObject instanceof Array;
7 | fileList.keys().forEach(async (fileName: any) => {
8 | const fileConfig = fileList(fileName);
9 | const name = fileName.split('/')[1].split('.')[0];
10 | if (isArray) {
11 | fileObject.push(fileConfig.default);
12 | } else {
13 | fileObject[name] = fileConfig.default;
14 | }
15 | });
16 | return fileObject;
17 | };
18 |
--------------------------------------------------------------------------------
/src/plugins/uniAjax.ts:
--------------------------------------------------------------------------------
1 | /**
2 | -----------------------------------------------------------------
3 | // Copyright (C) 2016 https://aiplat.com 版权所有。
4 | // uniAjax.ts
5 | // 创 建 人:aiplat.com
6 | // 修改日期:2019.05.23
7 | // 描述: * 基于Promise对象与uni.request 统一请求ajax
8 | -----------------------------------------------------------------
9 | */
10 | import api from '@/service/api';
11 |
12 | export default {
13 | baseURL: api.server,
14 | config: {
15 | url: '',
16 | header: {
17 | 'Content-Type': 'application/json;charset=UTF-8',
18 | },
19 | method: 'GET',
20 | data: {},
21 | dataType: 'json',
22 | // responseType: 'text',
23 | success: () => {},
24 | fail: () => {},
25 | complete: () => {},
26 | },
27 | isLoading: true,
28 | http(url:string, data:any, options:any, func:any, isLoading:any, isError:any) {
29 | if (!options) {
30 | options = {};
31 | }
32 | options.baseURL = options.baseURL || this.baseURL;
33 | options.url = options.baseURL + url;
34 | if ((options.method === 'POST' || options.method === 'post') && (options.header === undefined || !options.header)) {
35 | options.header = {
36 | 'Content-Type': 'application/x-www-form-urlencoded',
37 | };
38 | }
39 | options.header = options.header || this.config.header;
40 | options.method = options.method || this.config.method;
41 | options.data = data || {};
42 | options.dataType = options.dataType || this.config.dataType;
43 | // options.responseType = options.responseType || t.config.responseType;
44 | // #ifndef MP-WEIXIN
45 | // delete options.responseType; // (h5+和支付宝)不支持并且会报错
46 | // #endif
47 | const loadingTitle:any = isLoading && isLoading !== 'no' ? isLoading : '数据加载中..';
48 | if (isLoading !== 'no') {
49 | uni.showLoading({ title: loadingTitle });
50 | }
51 | return new Promise((resolve:any) => {
52 | let requestConfig:any = null;
53 | options.complete = (responseData:any) => {
54 | if (isLoading !== 'no') {
55 | uni.hideLoading();
56 | }
57 | const isSuccess = responseData.statusCode === 200 && responseData.data && responseData.data.res === 0;
58 | if (responseData.statusCode !== 200 || !isSuccess) {
59 | if (isError) {
60 | const errorTxt:any = {
61 | title: '网络出错了',
62 | icon: 'none',
63 | duration: 3000,
64 | };
65 | if (isError !== 'yes') {
66 | errorTxt.title = isError;
67 | }
68 | uni.showToast(errorTxt);
69 | }
70 | }
71 | resolve({
72 | isSuccess,
73 | ...responseData,
74 | });
75 | };
76 | requestConfig = Object.assign({}, this.config, options);
77 | uni.request(requestConfig);
78 | });
79 | },
80 | };
81 |
--------------------------------------------------------------------------------
/src/projects/aiplat/builds/selfConfig.ts:
--------------------------------------------------------------------------------
1 | import conf from '@/projects/aiplat/selfConfig';
2 | export default conf;
--------------------------------------------------------------------------------
/src/projects/aiplat/manifest/pro/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "AI智能空间",
3 | "appid": "__UNI__17D8E7A",
4 | "description": "https://aiplat.com",
5 | "versionName": "1.1.1",
6 | "versionCode": "100",
7 | "transformPx": true,
8 | "app-plus": {
9 | /* 5+App特有相关 */
10 | "modules": {},
11 | /* 模块配置 */
12 | "distribute": {
13 | /* 应用发布信息 */
14 | "android": {
15 | /* android打包配置 */
16 | "permissions": [
17 | "",
18 | "",
19 | "",
20 | "",
21 | "",
22 | "",
23 | "",
24 | "",
25 | "",
26 | "",
27 | "",
28 | "",
29 | "",
30 | "",
31 | "",
32 | "",
33 | "",
34 | "",
35 | "",
36 | "",
37 | "",
38 | ""
39 | ]
40 | },
41 | "ios": {},
42 | /* ios打包配置 */
43 | "sdkConfigs": {},
44 | "icons": {
45 | "ios": {
46 | "appstore": "src/static/aiplat/icon1024.png",
47 | "ipad": {
48 | "app": "unpackage/res/icons/76x76.png",
49 | "app@2x": "unpackage/res/icons/152x152.png",
50 | "notification": "unpackage/res/icons/20x20.png",
51 | "notification@2x": "unpackage/res/icons/40x40.png",
52 | "proapp@2x": "unpackage/res/icons/167x167.png",
53 | "settings": "unpackage/res/icons/29x29.png",
54 | "settings@2x": "unpackage/res/icons/58x58.png",
55 | "spotlight": "unpackage/res/icons/40x40.png",
56 | "spotlight@2x": "unpackage/res/icons/80x80.png"
57 | },
58 | "iphone": {
59 | "app@2x": "unpackage/res/icons/120x120.png",
60 | "app@3x": "unpackage/res/icons/180x180.png",
61 | "notification@2x": "unpackage/res/icons/40x40.png",
62 | "notification@3x": "unpackage/res/icons/60x60.png",
63 | "settings@2x": "unpackage/res/icons/58x58.png",
64 | "settings@3x": "unpackage/res/icons/87x87.png",
65 | "spotlight@2x": "unpackage/res/icons/80x80.png",
66 | "spotlight@3x": "unpackage/res/icons/120x120.png"
67 | }
68 | },
69 | "android": {
70 | "hdpi": "unpackage/res/icons/72x72.png",
71 | "ldpi": "unpackage/res/icons/48x48.png",
72 | "mdpi": "unpackage/res/icons/48x48.png",
73 | "xhdpi": "unpackage/res/icons/96x96.png",
74 | "xxhdpi": "unpackage/res/icons/144x144.png",
75 | "xxxhdpi": "unpackage/res/icons/192x192.png"
76 | }
77 | }
78 | },
79 | "usingComponents": true
80 | },
81 | /* SDK配置 */
82 | "quickapp": {},
83 | /* 快应用特有相关 */
84 | "mp-weixin": {
85 | /* 小程序特有相关 */
86 | "appid": "touristappid",
87 | "setting": {
88 | "urlCheck": true
89 | },
90 | "permission": {
91 | "scope.userLocation": {
92 | "desc": "获取您的位置信息"
93 | }
94 | },
95 | "usingComponents": true
96 | },
97 | "mp-alipay": {
98 | "usingComponents": true
99 | },
100 | "mp-baidu": {
101 | "usingComponents": true
102 | },
103 | "mp-toutiao": {
104 | "appid": "touristappid",
105 | "usingComponents": true
106 | },
107 | "h5": {
108 | "title": "AI智能空间",
109 | "domain": "https://aiplat.com",
110 | "router": {
111 | "mode": "hash",
112 | "base": "./"
113 | },
114 | "template": "index.html"
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/projects/aiplat/manifest/uat/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "AI智能空间",
3 | "appid": "__UNI__17D8E7A",
4 | "description": "https://aiplat.com",
5 | "versionName": "1.1.1",
6 | "versionCode": "100",
7 | "transformPx": true,
8 | "app-plus": {
9 | /* 5+App特有相关 */
10 | "modules": {},
11 | /* 模块配置 */
12 | "distribute": {
13 | /* 应用发布信息 */
14 | "android": {
15 | /* android打包配置 */
16 | "permissions": [
17 | "",
18 | "",
19 | "",
20 | "",
21 | "",
22 | "",
23 | "",
24 | "",
25 | "",
26 | "",
27 | "",
28 | "",
29 | "",
30 | "",
31 | "",
32 | "",
33 | "",
34 | "",
35 | "",
36 | "",
37 | "",
38 | ""
39 | ]
40 | },
41 | "ios": {},
42 | /* ios打包配置 */
43 | "sdkConfigs": {},
44 | "icons": {
45 | "ios": {
46 | "appstore": "src/static/aiplat/icon1024.png",
47 | "ipad": {
48 | "app": "unpackage/res/icons/76x76.png",
49 | "app@2x": "unpackage/res/icons/152x152.png",
50 | "notification": "unpackage/res/icons/20x20.png",
51 | "notification@2x": "unpackage/res/icons/40x40.png",
52 | "proapp@2x": "unpackage/res/icons/167x167.png",
53 | "settings": "unpackage/res/icons/29x29.png",
54 | "settings@2x": "unpackage/res/icons/58x58.png",
55 | "spotlight": "unpackage/res/icons/40x40.png",
56 | "spotlight@2x": "unpackage/res/icons/80x80.png"
57 | },
58 | "iphone": {
59 | "app@2x": "unpackage/res/icons/120x120.png",
60 | "app@3x": "unpackage/res/icons/180x180.png",
61 | "notification@2x": "unpackage/res/icons/40x40.png",
62 | "notification@3x": "unpackage/res/icons/60x60.png",
63 | "settings@2x": "unpackage/res/icons/58x58.png",
64 | "settings@3x": "unpackage/res/icons/87x87.png",
65 | "spotlight@2x": "unpackage/res/icons/80x80.png",
66 | "spotlight@3x": "unpackage/res/icons/120x120.png"
67 | }
68 | },
69 | "android": {
70 | "hdpi": "unpackage/res/icons/72x72.png",
71 | "ldpi": "unpackage/res/icons/48x48.png",
72 | "mdpi": "unpackage/res/icons/48x48.png",
73 | "xhdpi": "unpackage/res/icons/96x96.png",
74 | "xxhdpi": "unpackage/res/icons/144x144.png",
75 | "xxxhdpi": "unpackage/res/icons/192x192.png"
76 | }
77 | }
78 | },
79 | "usingComponents": true
80 | },
81 | /* SDK配置 */
82 | "quickapp": {},
83 | /* 快应用特有相关 */
84 | "mp-weixin": {
85 | /* 小程序特有相关 */
86 | "appid": "touristappid",
87 | "setting": {
88 | "urlCheck": true
89 | },
90 | "permission": {
91 | "scope.userLocation": {
92 | "desc": "获取您的位置信息"
93 | }
94 | },
95 | "usingComponents": true
96 | },
97 | "mp-alipay": {
98 | "usingComponents": true
99 | },
100 | "mp-baidu": {
101 | "usingComponents": true
102 | },
103 | "mp-toutiao": {
104 | "appid": "touristappid",
105 | "usingComponents": true
106 | },
107 | "h5": {
108 | "title": "AI智能空间",
109 | "domain": "https://aiplat.com",
110 | "router": {
111 | "mode": "hash",
112 | "base": "./"
113 | },
114 | "template": "index.html"
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/projects/aiplat/manifest/ver/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "AI智能空间",
3 | "appid": "__UNI__17D8E7A",
4 | "description": "https://aiplat.com",
5 | "versionName": "1.1.1",
6 | "versionCode": "100",
7 | "transformPx": true,
8 | "app-plus": {
9 | /* 5+App特有相关 */
10 | "modules": {},
11 | /* 模块配置 */
12 | "distribute": {
13 | /* 应用发布信息 */
14 | "android": {
15 | /* android打包配置 */
16 | "permissions": [
17 | "",
18 | "",
19 | "",
20 | "",
21 | "",
22 | "",
23 | "",
24 | "",
25 | "",
26 | "",
27 | "",
28 | "",
29 | "",
30 | "",
31 | "",
32 | "",
33 | "",
34 | "",
35 | "",
36 | "",
37 | "",
38 | ""
39 | ]
40 | },
41 | "ios": {},
42 | /* ios打包配置 */
43 | "sdkConfigs": {},
44 | "icons": {
45 | "ios": {
46 | "appstore": "src/static/aiplat/icon1024.png",
47 | "ipad": {
48 | "app": "unpackage/res/icons/76x76.png",
49 | "app@2x": "unpackage/res/icons/152x152.png",
50 | "notification": "unpackage/res/icons/20x20.png",
51 | "notification@2x": "unpackage/res/icons/40x40.png",
52 | "proapp@2x": "unpackage/res/icons/167x167.png",
53 | "settings": "unpackage/res/icons/29x29.png",
54 | "settings@2x": "unpackage/res/icons/58x58.png",
55 | "spotlight": "unpackage/res/icons/40x40.png",
56 | "spotlight@2x": "unpackage/res/icons/80x80.png"
57 | },
58 | "iphone": {
59 | "app@2x": "unpackage/res/icons/120x120.png",
60 | "app@3x": "unpackage/res/icons/180x180.png",
61 | "notification@2x": "unpackage/res/icons/40x40.png",
62 | "notification@3x": "unpackage/res/icons/60x60.png",
63 | "settings@2x": "unpackage/res/icons/58x58.png",
64 | "settings@3x": "unpackage/res/icons/87x87.png",
65 | "spotlight@2x": "unpackage/res/icons/80x80.png",
66 | "spotlight@3x": "unpackage/res/icons/120x120.png"
67 | }
68 | },
69 | "android": {
70 | "hdpi": "unpackage/res/icons/72x72.png",
71 | "ldpi": "unpackage/res/icons/48x48.png",
72 | "mdpi": "unpackage/res/icons/48x48.png",
73 | "xhdpi": "unpackage/res/icons/96x96.png",
74 | "xxhdpi": "unpackage/res/icons/144x144.png",
75 | "xxxhdpi": "unpackage/res/icons/192x192.png"
76 | }
77 | }
78 | },
79 | "usingComponents": true
80 | },
81 | /* SDK配置 */
82 | "quickapp": {},
83 | /* 快应用特有相关 */
84 | "mp-weixin": {
85 | /* 小程序特有相关 */
86 | "appid": "touristappid",
87 | "setting": {
88 | "urlCheck": true
89 | },
90 | "permission": {
91 | "scope.userLocation": {
92 | "desc": "获取您的位置信息"
93 | }
94 | },
95 | "usingComponents": true
96 | },
97 | "mp-alipay": {
98 | "usingComponents": true
99 | },
100 | "mp-baidu": {
101 | "usingComponents": true
102 | },
103 | "mp-toutiao": {
104 | "appid": "touristappid",
105 | "usingComponents": true
106 | },
107 | "h5": {
108 | "title": "AI智能空间",
109 | "domain": "https://aiplat.com",
110 | "router": {
111 | "mode": "hash",
112 | "base": "./"
113 | },
114 | "template": "index.html"
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/projects/aiplat/selfConfig.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * AI智能空间配置
3 | */
4 |
5 | export default {
6 | name: 'AI智能空间',
7 | type: 'aiplat',
8 | version: '1.1.1',
9 | logo: 'static/logo.png',
10 | site: 'aiplat.com',
11 | url: 'https://aiplat.com',
12 | description: 'AI智能空间,拥抱人工智能,明天会更好。个人项目:跨平台app~《亲信地铁》、已上线微信头条支付宝三大小程序~《娱乐计分器》。技术研究潜心使用各种框架开发h5app:同时兼容wap、web、微信浏览器、微信百度支付宝头条小程序、android和ios,各个平台界面统一,功能一致。详见应用展示。',
13 | copyright: '©2016',
14 | email: 'womendi@qq.com',
15 | server: {
16 | uat: 'https://aiplat.com', // 测试环境接口域名
17 | ver: 'https://aiplat.com', // 预生产环境接口域名
18 | pro: 'https://aiplat.com', // 生产环境接口域名
19 | },
20 | };
21 |
--------------------------------------------------------------------------------
/src/projects/aiplat/selfPages.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [
3 | {
4 | "path": "pages/aiplat/index",
5 | "style": {
6 | "navigationBarTitleText": "首页",
7 | "h5": {
8 | "titleNView": false
9 | }
10 | }
11 | },
12 | {
13 | "path": "pages/aiplat/apps",
14 | "style": {
15 | "navigationBarTitleText": "应用展示",
16 | "h5": {
17 | "titleNView": false
18 | }
19 | }
20 | },
21 | {
22 | "path": "pages/aiplat/donate",
23 | "style": {
24 | "navigationBarTitleText": "捐赠我们",
25 | "h5": {
26 | "titleNView": false
27 | }
28 | }
29 | },
30 | {
31 | "path": "pages/common/userAgent",
32 | "style": {
33 | "navigationBarTitleText": "userAgent",
34 | "h5": {
35 | "titleNView": false
36 | }
37 | }
38 | },
39 | {
40 | "path": "pages/common/h5",
41 | "style": {
42 | "navigationBarTitleText": "h5站点",
43 | "h5": {
44 | "titleNView": false
45 | }
46 | }
47 | }
48 | ],
49 | "tabBar": {
50 | "color": "#9b9b9b",
51 | "selectedColor": "#FD1414",
52 | "backgroundColor": "#EAEAEA",
53 | "list": [
54 | {
55 | "pagePath": "pages/aiplat/index",
56 | "text": "首页",
57 | "iconPath": "static/img/sy_01.png",
58 | "selectedIconPath": "static/img/sy_01on.png"
59 | },
60 | {
61 | "pagePath": "pages/aiplat/apps",
62 | "text": "应用展示",
63 | "iconPath": "static/img/sy_03.png",
64 | "selectedIconPath": "static/img/sy_03on.png"
65 | },
66 | {
67 | "pagePath": "pages/aiplat/donate",
68 | "text": "捐赠我们",
69 | "iconPath": "static/img/sy_04.png",
70 | "selectedIconPath": "static/img/sy_04on.png"
71 | }
72 | ]
73 | },
74 | "globalStyle": {
75 | "navigationBarTextStyle": "white",
76 | "navigationBarBackgroundColor": "#000000",
77 | "backgroundColor": "#FFFFFF"
78 | },
79 | "easycom": {
80 | "autoscan": true,
81 | "custom": {
82 | "(.*)": "@/components/$1.vue"
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/service/api.ts:
--------------------------------------------------------------------------------
1 | import setFileObject from '@/plugins/lib/setFileObject';
2 | import envType from '@/builds/envType';
3 | import selfConfig from '@/builds/selfConfig';
4 |
5 | const fileList = require.context(
6 | '@/service/apis',
7 | true,
8 | /.ts$/,
9 | );
10 |
11 | const config:any = selfConfig;
12 |
13 | // 接口域名
14 | let server:string = 'https://aiplat.com';
15 | if (config && config.server && config.server[envType]) {
16 | server = config.server[envType];
17 | }
18 | const api:any = {
19 | server: server,
20 | ...setFileObject(fileList, {}),
21 | };
22 |
23 | export default api;
24 |
--------------------------------------------------------------------------------
/src/service/apis/sign.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 用户接口
3 | */
4 | export default {
5 | getUserId: '/test',
6 | saveUserInfo: '/test',
7 | };
8 |
--------------------------------------------------------------------------------
/src/service/config.ts:
--------------------------------------------------------------------------------
1 | import envType from '@/builds/envType';
2 | import selfConfig from '@/builds/selfConfig';
3 |
4 | import setFileObject from '@/plugins/lib/setFileObject';
5 | const fileList = require.context(
6 | '@/service/config',
7 | true,
8 | /.ts$/,
9 | );
10 | const otherConf = setFileObject(fileList, {});
11 |
12 | export default {
13 | name: 'AI智能空间',
14 | description: 'AI智能空间,拥抱人工智能,明天会更好。个人项目:跨平台app~《亲信地铁》、已上线微信头条支付宝三大小程序~《娱乐计分器》。技术研究潜心使用各种框架开发h5app:同时兼容wap、web、微信浏览器、微信百度支付宝头条小程序、android和ios,各个平台界面统一,功能一致。详见应用展示。',
15 | site: 'aiplat.com',
16 | github: 'github.com/aiplat',
17 | version: new Date().valueOf(),
18 | project: selfConfig,
19 | platform: process.env.VUE_APP_PLATFORM,
20 | envType: envType,
21 | screenWidth: 750,
22 | ...otherConf,
23 | };
24 |
--------------------------------------------------------------------------------
/src/service/config/map.ts:
--------------------------------------------------------------------------------
1 | const mapConf:any = {
2 | pf: 'baidu',
3 | keys: ['这里写百度真实key'],
4 | host: 'https://api.map.baidu.com',
5 | apis: {
6 | geocoder: '/geocoder/v2/',
7 | geoconv: '/geoconv/v1/',
8 | },
9 | };
10 | export default mapConf;
11 |
--------------------------------------------------------------------------------
/src/sfc.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import Vue from 'vue';
3 | export default Vue;
4 | }
5 |
--------------------------------------------------------------------------------
/src/static/aiplat/72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/aiplat/72x72.png
--------------------------------------------------------------------------------
/src/static/aiplat/cm_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/aiplat/cm_back.png
--------------------------------------------------------------------------------
/src/static/aiplat/cm_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/aiplat/cm_close.png
--------------------------------------------------------------------------------
/src/static/aiplat/cm_loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/aiplat/cm_loading.gif
--------------------------------------------------------------------------------
/src/static/aiplat/cm_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/aiplat/cm_right.png
--------------------------------------------------------------------------------
/src/static/aiplat/donate_WX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/aiplat/donate_WX.png
--------------------------------------------------------------------------------
/src/static/aiplat/donate_ZFB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/aiplat/donate_ZFB.png
--------------------------------------------------------------------------------
/src/static/aiplat/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/aiplat/icon.png
--------------------------------------------------------------------------------
/src/static/aiplat/icon1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/aiplat/icon1024.png
--------------------------------------------------------------------------------
/src/static/aiplat/icon2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/aiplat/icon2.png
--------------------------------------------------------------------------------
/src/static/aiplat/metro_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/aiplat/metro_icon.png
--------------------------------------------------------------------------------
/src/static/cmDemo1/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/cmDemo1/1.jpg
--------------------------------------------------------------------------------
/src/static/cmDemo1/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/cmDemo1/2.jpg
--------------------------------------------------------------------------------
/src/static/cmDemo1/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/cmDemo1/3.jpg
--------------------------------------------------------------------------------
/src/static/img/sy_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/img/sy_01.png
--------------------------------------------------------------------------------
/src/static/img/sy_01on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/img/sy_01on.png
--------------------------------------------------------------------------------
/src/static/img/sy_01on_zfb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/img/sy_01on_zfb.png
--------------------------------------------------------------------------------
/src/static/img/sy_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/img/sy_02.png
--------------------------------------------------------------------------------
/src/static/img/sy_02on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/img/sy_02on.png
--------------------------------------------------------------------------------
/src/static/img/sy_02on_zfb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/img/sy_02on_zfb.png
--------------------------------------------------------------------------------
/src/static/img/sy_03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/img/sy_03.png
--------------------------------------------------------------------------------
/src/static/img/sy_03on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/img/sy_03on.png
--------------------------------------------------------------------------------
/src/static/img/sy_03on_zfb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/img/sy_03on_zfb.png
--------------------------------------------------------------------------------
/src/static/img/sy_04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/img/sy_04.png
--------------------------------------------------------------------------------
/src/static/img/sy_04on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/img/sy_04on.png
--------------------------------------------------------------------------------
/src/static/img/sy_04on_zfb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/img/sy_04on_zfb.png
--------------------------------------------------------------------------------
/src/static/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/src/static/logo.png
--------------------------------------------------------------------------------
/src/vuex/commonModule/index.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | state: {
3 | userInfo: null, // 用户信息
4 | systemInfo: null, //
5 | },
6 | mutations: {
7 | SETUSERINFO (store:any, data:any) {
8 | store.userInfo = data
9 | },
10 | },
11 | getters: {
12 | getUserInfo (status:any) {
13 | return status.userInfo
14 | },
15 | },
16 | actions: {
17 | setUserInfo ({ commit }:any, data:any) {
18 | commit('SETUSERINFO', data);
19 | },
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/vuex/donateModule/index.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | state: {
3 | donateId: 0
4 | },
5 | mutations: {
6 | SETDONATEID (store:any, data:any) {
7 | store.donateId = data
8 | },
9 | },
10 | getters: {
11 | getDonateId (status:any) {
12 | return status.donateId
13 | },
14 | },
15 | actions: {
16 | setDonateId ({ commit }:any, data:any) {
17 | commit('SETDONATEID', data);
18 | },
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/vuex/store.ts:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 |
4 | const modules:any = {};
5 | const fileList = require.context(
6 | '@/vuex',
7 | true,
8 | /index.ts$/,
9 | );
10 |
11 | fileList.keys()
12 | .map((key:any) => {
13 | const namespace = key.replace(/(\.\/)|(\.ts)/g, '')
14 | const module = fileList(key).default
15 | modules[namespace] = {
16 | namespaced: true,
17 | ...module
18 | }
19 | })
20 | Vue.use(Vuex);
21 | export default new Vuex.Store({
22 | modules
23 | });
24 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions":{
3 | "target":"esnext",
4 | "module":"esnext",
5 | "strict":true,
6 | "jsx":"preserve",
7 | "importHelpers":true,
8 | "moduleResolution":"node",
9 | "esModuleInterop":true,
10 | "allowSyntheticDefaultImports":true,
11 | "experimentalDecorators":true,
12 | "sourceMap":true,
13 | "skipLibCheck":true,
14 | "baseUrl":".",
15 | "types":[
16 | "webpack-env",
17 | "@dcloudio/types",
18 | "miniprogram-api-typings",
19 | "mini-types"
20 | ],
21 | "paths":{
22 | "@/*":[
23 | "./src/*"
24 | ]
25 | },
26 | "lib":[
27 | "esnext",
28 | "dom",
29 | "dom.iterable",
30 | "scripthost"
31 | ]
32 | },
33 | "exclude":[
34 | "node_modules",
35 | "unpackage",
36 | "src/**/*.nvue"
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/unpackage/res/icons/120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/120x120.png
--------------------------------------------------------------------------------
/unpackage/res/icons/144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/144x144.png
--------------------------------------------------------------------------------
/unpackage/res/icons/152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/152x152.png
--------------------------------------------------------------------------------
/unpackage/res/icons/167x167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/167x167.png
--------------------------------------------------------------------------------
/unpackage/res/icons/180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/180x180.png
--------------------------------------------------------------------------------
/unpackage/res/icons/192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/192x192.png
--------------------------------------------------------------------------------
/unpackage/res/icons/20x20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/20x20.png
--------------------------------------------------------------------------------
/unpackage/res/icons/29x29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/29x29.png
--------------------------------------------------------------------------------
/unpackage/res/icons/40x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/40x40.png
--------------------------------------------------------------------------------
/unpackage/res/icons/48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/48x48.png
--------------------------------------------------------------------------------
/unpackage/res/icons/58x58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/58x58.png
--------------------------------------------------------------------------------
/unpackage/res/icons/60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/60x60.png
--------------------------------------------------------------------------------
/unpackage/res/icons/72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/72x72.png
--------------------------------------------------------------------------------
/unpackage/res/icons/76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/76x76.png
--------------------------------------------------------------------------------
/unpackage/res/icons/80x80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/80x80.png
--------------------------------------------------------------------------------
/unpackage/res/icons/87x87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/87x87.png
--------------------------------------------------------------------------------
/unpackage/res/icons/96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiplat/uniapp/acc88661224ddf8e81a77dc98132226563dfd39b/unpackage/res/icons/96x96.png
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const devMode = process.env.NODE_ENV !== 'production';
3 | const compressionWebpackPlugin = require('compression-webpack-plugin');
4 | const cssMinimizerPlugin = require('css-minimizer-webpack-plugin');
5 | const miniCssExtractPlugin = require('mini-css-extract-plugin');
6 |
7 | function resolve(dir) {
8 | return path.resolve(__dirname, dir)
9 | }
10 |
11 | module.exports = {
12 | filenameHashing:true,
13 | lintOnSave:false,
14 | css:{
15 | requireModuleExtension:true,
16 | },
17 | productionSourceMap:false,
18 | devServer:{
19 | compress:true,
20 | port:2016,
21 | disableHostCheck:true,
22 | hot:true,
23 | open:true,
24 | },
25 | parallel:require('os').cpus().length > 1,
26 | configureWebpack:cfg => {
27 | if (process.env.VUE_APP_PLATFORM === 'h5') {
28 | cfg.performance = {
29 | hints:'warning',
30 | maxEntrypointSize:20480000,
31 | maxAssetSize:20480000,
32 | assetFilter:function (assetFilename) {
33 | return assetFilename.endsWith('.js');
34 | }
35 | };
36 | cfg.plugins.push(new compressionWebpackPlugin({
37 | algorithm:'gzip',
38 | test:new RegExp('\\.(' + ['ts', 'js', 'css'].join('|') + ')$'),
39 | threshold:10240,
40 | minRatio:0.8
41 | }));
42 | cfg.optimization = {
43 | moduleIds: 'size',
44 | minimize: true,
45 | minimizer: [
46 | new cssMinimizerPlugin(),
47 | ],
48 | splitChunks: {
49 | chunks: 'async',
50 | minSize: 20000,
51 | maxSize: 0,
52 | minChunks: 1,
53 | maxAsyncRequests: 5,
54 | maxInitialRequests: Infinity,
55 | automaticNameDelimiter: '~',
56 | name: true,
57 | cacheGroups: {
58 | vendor: {
59 | test: /[\\/]node_modules[\\/]/,
60 | name(module) {
61 | const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
62 | return `npm.${packageName.replace('@', '')}`;
63 | },
64 | priority: 9,
65 | minChunks: 1,
66 | reuseExistingChunk: true,
67 | enforce: true,
68 | // chunks: 'all',
69 | },
70 | commons: {
71 | name: 'commons',
72 | priority: 8,
73 | minChunks: 2,
74 | reuseExistingChunk: true,
75 | enforce: true,
76 | chunks: 'all',
77 | },
78 | default: {
79 | minChunks: 2,
80 | priority: 7,
81 | }
82 | }
83 | }
84 | };
85 | }
86 | cfg.resolve.extensions = ['.ts', '.js', '.vue', '.json'];
87 | cfg.resolve.alias = {
88 | ...cfg.resolve.alias,
89 | '@':resolve('src'),
90 | 'assets':resolve('src/assets'),
91 | 'builds':resolve('src/builds'),
92 | 'components':resolve('src/components'),
93 | 'mixins':resolve('src/mixins'),
94 | 'pages':resolve('src/pages'),
95 | 'plugins':resolve('src/plugins'),
96 | 'projects':resolve('src/projects'),
97 | 'service':resolve('src/service'),
98 | 'static':resolve('src/static'),
99 | 'utils':resolve('src/utils'),
100 | };
101 | },
102 | chainWebpack: cfg => {
103 | cfg.plugins.delete('prefetch');
104 | if (process.env.VUE_APP_PLATFORM === 'h5' && !devMode) {
105 | cfg.module.loaders = [
106 | {
107 | test: /.s?css$/,
108 | use: [miniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
109 | }
110 | ];
111 | }
112 | if (process.env.npm_config_report && !devMode) {
113 | cfg.plugin('webpack-bundle-analyzer')
114 | .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
115 | .end();
116 | }
117 | }
118 | };
119 |
--------------------------------------------------------------------------------