fe75cffbf3bae6777aa2794fd89fa5dc37f5df8d..d1448cb0ef10f358bb7bddb4e1ec268515e0b787
3 天以前 gaoluyang
项目初始化
d1448c 对比 | 目录
3 天以前 gaoluyang
项目初始化
18f6b7 对比 | 目录
已重命名16个文件
已删除575个文件
已修改6个文件
已添加436个文件
153681 ■■■■■ 文件已修改
.gitignore 85 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.vscode/launch.json 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
App.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LICENSE 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md 346 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/captcha.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/center/log.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/login.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/user.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/work/notice.js 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/work/userManage.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/button/FloatButton.vue 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/gap/Gap.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/navbar/Navbar.vue 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/navbar/props.js 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/qian-tree/qian-tree.vue 425 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/qian-tree/style.css 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/tabs/Tabs.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
config/environment.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
config/http.interceptor.js 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
config/request.js 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/image/index.png 补丁 | 查看 | 原始文档 | blame | 历史
doc/image/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
doc/image/mallMenu.png 补丁 | 查看 | 原始文档 | blame | 历史
doc/image/template1.png 补丁 | 查看 | 原始文档 | blame | 历史
doc/image/template2.png 补丁 | 查看 | 原始文档 | blame | 历史
index.html 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manifest.json 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json 13028 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 114 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages.json 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/center/index.vue 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/center/log.vue 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/center/password.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/center/profile.vue 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/index/index.vue 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/login/index.scss 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/login/index.vue 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/work/index.vue 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/work/notice/detail.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/work/notice/edit.vue 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/work/notice/list.vue 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/work/notice/manage.vue 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/work/notice/record.vue 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/work/user/edit.vue 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/work/user/list.vue 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pnpm-lock.yaml 9075 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/App.vue 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/login.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/oauth.js 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system/dict/data.js 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system/dict/type.js 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system/user.js 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/geek-xd/components/geek-certificate/geek-certificate.vue 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/geek-xd/components/geek-color-picker/geek-color-picker.vue 747 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/geek-xd/components/geek-commodity/geek-commodity.vue 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/geek-xd/components/geek-menu/geek-menu.vue 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/geek-xd/components/geek-order/geek-order.vue 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/geek-xd/components/geek-qrcode/README.md 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/geek-xd/components/geek-qrcode/geek-qrcode.vue 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/geek-xd/components/geek-qrcode/qrcode.js 1206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/geek-xd/components/geek-statistic/geek-statistic.vue 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/geek-xd/types/index.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/qiun-data-charts/changelog.md 320 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue 1614 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/qiun-data-charts/js_sdk/u-charts/config-ucharts.js 606 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/qiun-data-charts/js_sdk/u-charts/u-charts.js 7706 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/qiun-data-charts/js_sdk/u-charts/u-charts.min.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/qiun-data-charts/package.json 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/qiun-data-charts/readme.md 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/ruoyi/DictTag/index.vue 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/u-city-select/area.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/u-city-select/city.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/u-city-select/province.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/u-city-select/u-city-select.vue 265 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/uni-section/uni-section.vue 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/config.js 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/directive/common/copyText.ts 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/directive/common/focus.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/directive/common/full.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/directive/index.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/directive/permission/hasPermi.ts 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/directive/permission/hasRole.ts 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/env.d.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/manifest.json 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages.json 280 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/common/textview/index.vue 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/common/webview/index.vue 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/index.vue 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/login.vue 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/mine.vue 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/template.config.js 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/template.vue 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/work.vue 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_geek/pages/code/index.vue 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_geek/pages/index/index.vue 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_mine/pages/about/index.vue 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_mine/pages/avatar/index.vue 642 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_mine/pages/help/index.vue 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_mine/pages/info/edit.vue 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_mine/pages/info/index.vue 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_mine/pages/pwd/index.vue 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_mine/pages/setting/index.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/card-swiper/card-swiper.vue 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/data-center/user-healthy.vue 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/data-center/user-operate.vue 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/data-center/user-server.vue 385 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/data-center/wechat.vue 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/data-progress/data-progress.vue 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/data-table/senior-table.vue 1117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/drop-down/drop-down.vue 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/progress-bar/progress-bar.vue 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/ranking-list/ranking-list.vue 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/text-block/text-block.vue 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/uni-calendar/calendar.js 600 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/uni-calendar/uni-calendar-item.vue 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/uni-calendar/uni-calendar.vue 512 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/uni-calendar/util.js 357 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/components/wuc-tab/wuc-tab.vue 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/pages/finance/index.vue 585 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/pages/main/index.vue 348 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/pages/school/index.vue 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/pages/sport/index.vue 762 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/js/common.js 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/js/config.js 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/finance/1.json 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/finance/2.json 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/school/1.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/school/2.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/school/3.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/school/4.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/sport/1.json 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/sport/2.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/sport/3.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/sport/4.json 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-healthy/1.json 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-healthy/2.json 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-healthy/3.json 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-healthy/4.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-healthy/5.json 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-healthy/6.json 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-healthy/7.json 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-operate/1.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-operate/2.json 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-operate/3.json 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-operate/4.json 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-operate/6.json 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-operate/7.json 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-operate/8.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-operate/9.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-server/1.json 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-server/2.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-server/3.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-server/4.json 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/user-server/5.json 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/wechat/1.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/wechat/2.json 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/wechat/3.json 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/wechat/4.json 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/wechat/5.json 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/json/wechat/6.json 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/table/characterToPinyin.js 901 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/table/iconfont.wxss 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/table/loader.wxss 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_qiun/static/table/objEqual.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/common/api.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/common/classify.data.js 1087 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/common/config.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/common/demo.scss 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/common/locales/en.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/common/locales/zh.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/common/mixin.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/common/props.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/address/addSite.vue 444 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/address/index.ts 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/address/index.vue 262 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/citySelect/index.vue 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/comment/index.vue 265 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/comment/reply.vue 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/coupon/index.vue 413 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/keyboardPay/index.vue 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/login/code.vue 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/login/index1.vue 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/login/index2.vue 662 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/mallMenu/index1.vue 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/mallMenu/index2.vue 313 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/order/OrderItem.vue 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/order/index.vue 250 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/submitBar/index.vue 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/wxCenter/index.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/plugins/auth.ts 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/plugins/bus.ts 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/plugins/index.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/plugins/modal.ts 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/plugins/mqttclient.ts 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/plugins/socketclient.ts 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/plugins/tab.ts 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/shime-uni.d.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
src/static/font/iconfont.css 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/font/iconfont.ttf 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/banner/banner01.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/banner/banner02.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/banner/banner03.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/dialogue.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/knowledge.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/message.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/phone.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/rocket.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/profile.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/tabbar/work.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/tabbar/work_.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/index.html 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/scss/colorui.css 3912 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/scss/global.scss 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/scss/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/common/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/common/gray-logo.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/common/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/actionSheet.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/address.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/album.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/alert.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/avatar.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/backTop.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/badge.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/button.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/calendar.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/cell.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/checkbox.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/citySelect.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/code.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/collapse.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/color.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/comment.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/countDown.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/countTo.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/coupon.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/datetimePicker.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/divider.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/empty.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/field.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/form.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/gap.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/grid.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/icon.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/image.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/indexList (1).png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/indexList.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/keyboard.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/keyboardPay.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/layout.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/line.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/link.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/list.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/loading-page.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/loading.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/loadmore.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/login.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/mall_menu_1.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/mall_menu_2.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/mask.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/messageInput.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/modal.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/navbar.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/noNetwork.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/noticeBar.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/notify.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/numberBox.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/order.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/parse.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/picker.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/popup.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/progress.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/radio.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/rate.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/readMore.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/scrollList.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/search.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/skeleton.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/slider.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/steps.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/sticky.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/submitBar.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/subsection.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/swipeAction.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/swiper.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/switch.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/tabbar.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/tabs.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/tag.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/text.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/textarea.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/toast.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/tooltip.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/transition.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/upload.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/demo/wxCenter.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/example/component.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/example/component_select.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/example/js.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/example/js_bak.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/example/js_select.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/example/template.png 补丁 | 查看 | 原始文档 | blame | 历史
src/static/uview/example/template_select.png 补丁 | 查看 | 原始文档 | blame | 历史
src/store/index.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/dict.ts 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/user.ts 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/types/request.ts 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni.scss 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-badge/changelog.md 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-badge/components/uni-badge/uni-badge.vue 268 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-badge/package.json 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-badge/readme.md 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-breadcrumb/changelog.md 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-breadcrumb/components/uni-breadcrumb-item/uni-breadcrumb-item.vue 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-breadcrumb/components/uni-breadcrumb/uni-breadcrumb.vue 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-breadcrumb/package.json 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-breadcrumb/readme.md 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-calendar/changelog.md 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-calendar/components/uni-calendar/calendar.js 546 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-calendar/components/uni-calendar/i18n/en.json 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-calendar/components/uni-calendar/i18n/index.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue 562 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-calendar/components/uni-calendar/util.js 350 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-calendar/package.json 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-calendar/readme.md 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-card/changelog.md 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-card/components/uni-card/uni-card.vue 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-card/package.json 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-card/readme.md 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-collapse/changelog.md 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue 402 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-collapse/package.json 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-collapse/readme.md 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-combox/changelog.md 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-combox/components/uni-combox/uni-combox.vue 275 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-combox/package.json 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-combox/readme.md 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-countdown/changelog.md 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-countdown/components/uni-countdown/i18n/en.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-countdown/components/uni-countdown/i18n/index.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hans.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hant.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue 271 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-countdown/package.json 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-countdown/readme.md 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-checkbox/changelog.md 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue 821 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-checkbox/package.json 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-checkbox/readme.md 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-picker/changelog.md 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue 547 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js 622 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue 321 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-picker/package.json 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-picker/readme.md 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-select/changelog.md 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue 440 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-select/package.json 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-data-select/readme.md 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-dateformat/changelog.md 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-dateformat/components/uni-dateformat/date-format.js 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-dateformat/package.json 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-dateformat/readme.md 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-datetime-picker/changelog.md 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue 924 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue 946 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue 1015 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js 410 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-datetime-picker/package.json 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-datetime-picker/readme.md 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-drawer/changelog.md 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-drawer/components/uni-drawer/keypress.js 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-drawer/package.json 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-drawer/readme.md 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-easyinput/changelog.md 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-easyinput/components/uni-easyinput/common.js 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue 679 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-easyinput/package.json 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-easyinput/readme.md 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-fab/changelog.md 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-fab/components/uni-fab/uni-fab.vue 490 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-fab/package.json 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-fab/readme.md 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-fav/changelog.md 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-fav/components/uni-fav/i18n/en.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-fav/components/uni-fav/i18n/index.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-fav/components/uni-fav/uni-fav.vue 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-fav/package.json 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-fav/readme.md 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-file-picker/changelog.md 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue 656 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue 325 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue 292 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-file-picker/components/uni-file-picker/utils.js 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-file-picker/package.json 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-file-picker/readme.md 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-forms/changelog.md 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue 631 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-forms/components/uni-forms/uni-forms.vue 397 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-forms/components/uni-forms/utils.js 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-forms/components/uni-forms/validate.js 486 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-forms/package.json 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-forms/readme.md 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-goods-nav/changelog.md 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/en.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/index.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hans.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hant.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-goods-nav/components/uni-goods-nav/uni-goods-nav.vue 229 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-goods-nav/package.json 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-goods-nav/readme.md 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-grid/changelog.md 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-grid/components/uni-grid-item/uni-grid-item.vue 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-grid/components/uni-grid/uni-grid.vue 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-grid/package.json 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-grid/readme.md 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-group/changelog.md 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-group/components/uni-group/uni-group.vue 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-group/package.json 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-group/readme.md 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-icons/changelog.md 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-icons/components/uni-icons/icons.js 1169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-icons/components/uni-icons/uni-icons.vue 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-icons/components/uni-icons/uniicons.css 663 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-icons/components/uni-icons/uniicons.ttf 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-icons/package.json 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-icons/readme.md 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-indexed-list/changelog.md 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list-item.vue 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list.vue 367 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-indexed-list/package.json 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-indexed-list/readme.md 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-link/changelog.md 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-link/components/uni-link/uni-link.vue 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-link/package.json 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-link/readme.md 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-list/changelog.md 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-list/components/uni-list-ad/uni-list-ad.vue 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.scss 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue 538 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-list/components/uni-list-item/uni-list-item.vue 454 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-list/components/uni-list/uni-list.vue 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-list/components/uni-list/uni-refresh.vue 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-list/components/uni-list/uni-refresh.wxs 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-list/package.json 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-list/readme.md 346 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-load-more/changelog.md 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-load-more/components/uni-load-more/i18n/en.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-load-more/components/uni-load-more/i18n/index.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue 399 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-load-more/package.json 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-load-more/readme.md 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-nav-bar/changelog.md 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue 357 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-nav-bar/package.json 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-nav-bar/readme.md 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-notice-bar/changelog.md 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue 426 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-notice-bar/package.json 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-notice-bar/readme.md 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-number-box/changelog.md 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-number-box/package.json 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-number-box/readme.md 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-pagination/changelog.md 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-pagination/components/uni-pagination/i18n/en.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-pagination/components/uni-pagination/i18n/es.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-pagination/components/uni-pagination/i18n/fr.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-pagination/components/uni-pagination/i18n/index.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hans.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hant.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-pagination/components/uni-pagination/uni-pagination.vue 465 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-pagination/package.json 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-pagination/readme.md 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/changelog.md 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue 275 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/components/uni-popup/i18n/en.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/components/uni-popup/i18n/index.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/components/uni-popup/keypress.js 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/components/uni-popup/popup.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/components/uni-popup/uni-popup.vue 474 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/package.json 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-popup/readme.md 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-rate/changelog.md 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-rate/components/uni-rate/uni-rate.vue 361 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-rate/package.json 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-rate/readme.md 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-row/changelog.md 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-row/components/uni-col/uni-col.vue 317 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-row/components/uni-row/uni-row.vue 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-row/package.json 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-row/readme.md 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/changelog.md 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/package.json 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/readme.md 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/styles/index.scss 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/styles/setting/_border.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/styles/setting/_color.scss 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/styles/setting/_radius.scss 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/styles/setting/_space.scss 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/styles/setting/_styles.scss 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/styles/setting/_text.scss 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/styles/setting/_variables.scss 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/styles/tools/functions.scss 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/theme.scss 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-scss/variables.scss 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-search-bar/changelog.md 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-search-bar/components/uni-search-bar/i18n/en.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-search-bar/components/uni-search-bar/i18n/index.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hans.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hant.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-search-bar/components/uni-search-bar/uni-search-bar.vue 298 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-search-bar/package.json 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-search-bar/readme.md 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-segmented-control/changelog.md 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-segmented-control/components/uni-segmented-control/uni-segmented-control.vue 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-segmented-control/package.json 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-segmented-control/readme.md 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-steps/changelog.md 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-steps/components/uni-steps/uni-steps.vue 269 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-steps/package.json 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-steps/readme.md 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swipe-action/changelog.md 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/bindingx.js 302 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue 347 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs 341 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swipe-action/package.json 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swipe-action/readme.md 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swiper-dot/changelog.md 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swiper-dot/package.json 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-swiper-dot/readme.md 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/changelog.md 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/components/uni-table/uni-table.vue 455 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/components/uni-td/uni-td.vue 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/components/uni-th/filter-dropdown.vue 503 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/components/uni-th/uni-th.vue 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/components/uni-thead/uni-thead.vue 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/components/uni-tr/table-checkbox.vue 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/components/uni-tr/uni-tr.vue 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/i18n/en.json 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/i18n/es.json 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/i18n/fr.json 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/i18n/index.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/i18n/zh-Hans.json 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/i18n/zh-Hant.json 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/package.json 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-table/readme.md 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-tag/changelog.md 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-tag/components/uni-tag/uni-tag.vue 252 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-tag/package.json 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-tag/readme.md 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-title/changelog.md 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-title/components/uni-title/uni-title.vue 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-title/package.json 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-title/readme.md 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-tooltip/changelog.md 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-tooltip/package.json 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-tooltip/readme.md 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-transition/changelog.md 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-transition/components/uni-transition/createAnimation.js 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-transition/components/uni-transition/uni-transition.vue 277 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-transition/package.json 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/uni_modules/uni-transition/readme.md 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/auth.ts 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/common.ts 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/constant.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/dict.ts 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/errorCode.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/geek.ts 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/permission.ts 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request.ts 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/ruoyi.js 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/storage.ts 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/upload.ts 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/img/avatar.png 补丁 | 查看 | 原始文档 | blame | 历史
static/img/b-1.png 补丁 | 查看 | 原始文档 | blame | 历史
static/img/b-2.png 补丁 | 查看 | 原始文档 | blame | 历史
static/img/tabbar/center.png 补丁 | 查看 | 原始文档 | blame | 历史
static/img/tabbar/center_art.png 补丁 | 查看 | 原始文档 | blame | 历史
static/img/tabbar/home.png 补丁 | 查看 | 原始文档 | blame | 历史
static/img/tabbar/home_art.png 补丁 | 查看 | 原始文档 | blame | 历史
static/img/tabbar/user.png 补丁 | 查看 | 原始文档 | blame | 历史
static/img/tabbar/user_art.png 补丁 | 查看 | 原始文档 | blame | 历史
static/preview/ali_pay.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/preview/index.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/preview/login.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/preview/logs.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/preview/my.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/preview/notice-e.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/preview/notice-m.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/preview/prefile.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/preview/pwd-reset.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/preview/wechat_pay.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/preview/work.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/style.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
store/index.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
store/modules/system.js 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
store/modules/user.js 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
store/mutation-types.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
template.h5.html 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tsconfig.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni.scss 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/changelog.md 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue 1607 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/components/qiun-error/qiun-error.vue 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/components/qiun-loading/loading1.vue 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/components/qiun-loading/loading2.vue 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/components/qiun-loading/loading3.vue 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/components/qiun-loading/loading4.vue 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/components/qiun-loading/loading5.vue 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/components/qiun-loading/qiun-loading.vue 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/js_sdk/u-charts/config-echarts.js 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/js_sdk/u-charts/config-ucharts.js 601 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/js_sdk/u-charts/readme.md 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.js 7297 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.min.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/license.md 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/package.json 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/readme.md 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/static/app-plus/echarts.min.js 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/qiun-data-charts/static/h5/echarts.min.js 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/LICENSE 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/README.md 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/changelog.md 326 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u--form/u--form.vue 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u--image/u--image.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u--input/u--input.vue 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u--text/u--text.vue 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u--textarea/u--textarea.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-action-sheet/props.js 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-album/props.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-album/u-album.vue 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-alert/props.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-alert/u-alert.vue 243 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-avatar-group/props.js 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-avatar/props.js 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-avatar/u-avatar.vue 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-back-top/props.js 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-back-top/u-back-top.vue 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-badge/props.js 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-badge/u-badge.vue 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-button/nvue.scss 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-button/props.js 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-button/u-button.vue 490 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-button/vue.scss 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-calendar/header.vue 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-calendar/month.vue 579 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-calendar/props.js 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-calendar/u-calendar.vue 383 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-calendar/util.js 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-car-keyboard/props.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue 311 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-cell-group/props.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-cell/props.js 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-cell/u-cell.vue 229 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-checkbox-group/props.js 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-checkbox/props.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue 344 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-circle-progress/props.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-code-input/props.js 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-code-input/u-code-input.vue 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-code/props.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-code/u-code.vue 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-col/props.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-col/u-col.vue 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-collapse-item/props.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-collapse/props.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-collapse/u-collapse.vue 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-column-notice/props.js 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-count-down/props.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-count-down/u-count-down.vue 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-count-down/utils.js 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-count-to/props.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-count-to/u-count-to.vue 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-datetime-picker/props.js 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue 360 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-divider/props.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-divider/u-divider.vue 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-dropdown-item/props.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-dropdown/props.js 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-empty/props.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-empty/u-empty.vue 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-form-item/props.js 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-form-item/u-form-item.vue 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-form/props.js 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-form/u-form.vue 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-gap/props.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-gap/u-gap.vue 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-grid-item/props.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue 209 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-grid/props.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-grid/u-grid.vue 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-icon/icons.js 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-icon/props.js 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-icon/u-icon.vue 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-image/props.js 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-image/u-image.vue 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-index-anchor/props.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-index-item/props.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-index-item/u-index-item.vue 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-index-list/props.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-index-list/u-index-list.vue 440 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-input/props.js 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-input/u-input.vue 353 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-keyboard/props.js 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-line-progress/props.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-line/props.js 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-line/u-line.vue 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-link/props.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-link/u-link.vue 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-list-item/props.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-list-item/u-list-item.vue 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-list/props.js 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-list/u-list.vue 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-loading-icon/props.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue 343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-loading-page/props.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-loadmore/props.js 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-modal/props.js 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-modal/u-modal.vue 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-navbar/props.js 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-navbar/u-navbar.vue 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-no-network/props.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-no-network/u-no-network.vue 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-notice-bar/props.js 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-notify/props.js 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-notify/u-notify.vue 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-number-box/props.js 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-number-box/u-number-box.vue 416 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-number-keyboard/props.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-overlay/props.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-overlay/u-overlay.vue 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-parse/node/node.vue 499 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-parse/parser.js 1075 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-parse/props.js 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-parse/u-parse.vue 366 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-picker-column/props.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-picker-column/u-picker-column.vue 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-picker/props.js 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-picker/u-picker.vue 284 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-popup/props.js 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-popup/u-popup.vue 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-radio-group/props.js 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-radio-group/u-radio-group.vue 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-radio/props.js 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-radio/u-radio.vue 337 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-rate/props.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-rate/u-rate.vue 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-read-more/props.js 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-read-more/u-read-more.vue 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-row-notice/props.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-row-notice/u-row-notice.vue 306 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-row/props.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-row/u-row.vue 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-safe-bottom/props.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-safe-bottom/u-safe-bottom.vue 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-scroll-list/nvue.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-scroll-list/other.js 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-scroll-list/props.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-scroll-list/scrollWxs.wxs 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-scroll-list/u-scroll-list.vue 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-search/props.js 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-search/u-search.vue 303 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-skeleton/props.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-skeleton/u-skeleton.vue 244 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-slider/mpother.js 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-slider/mpwxs.js 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-slider/mpwxs.wxs 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-slider/nvue - 副本.js 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-slider/nvue.js 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-slider/props.js 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-slider/u-slider.vue 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-status-bar/props.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-status-bar/u-status-bar.vue 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-steps-item/props.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-steps-item/u-steps-item.vue 316 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-steps/props.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-steps/u-steps.vue 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-sticky/props.js 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-sticky/u-sticky.vue 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-subsection/props.js 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-subsection/u-subsection.vue 299 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-swipe-action-item/index - backup.wxs 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-swipe-action-item/index.wxs 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-swipe-action-item/nvue - backup.js 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-swipe-action-item/nvue.js 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-swipe-action-item/props.js 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-swipe-action-item/u-swipe-action-item.vue 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-swipe-action-item/wxs.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-swipe-action/props.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-swipe-action/u-swipe-action.vue 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-swiper-indicator/props.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-swiper-indicator/u-swiper-indicator.vue 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-swiper/props.js 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-swiper/u-swiper.vue 255 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-switch/props.js 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-switch/u-switch.vue 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tabbar-item/props.js 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tabbar-item/u-tabbar-item.vue 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tabbar/props.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tabbar/u-tabbar.vue 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-table/props.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-table/u-table.vue 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tabs-item/props.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tabs-item/u-tabs-item.vue 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tabs/props.js 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tabs/u-tabs.vue 354 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tag/props.js 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tag/u-tag.vue 358 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-td/props.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-td/u-td.vue 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-text/props.js 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-text/u-text.vue 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-text/value.js 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-textarea/props.js 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-textarea/u-textarea.vue 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-toast/u-toast.vue 291 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-toolbar/props.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-toolbar/u-toolbar.vue 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tooltip/clipboard.min.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tooltip/props.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tooltip/u-tooltip.vue 365 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tr/props.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-tr/u-tr.vue 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-transition/nvue.ani-map.js 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-transition/props.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-transition/transition.js 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-transition/u-transition.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-transition/vue.ani-style.scss 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-upload/mixin.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-upload/props.js 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-upload/u-upload.vue 558 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/u-upload/utils.js 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/components/uview-ui/uview-ui.vue 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/index.js 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/index.scss 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/color.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/config.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props.js 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/actionSheet.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/album.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/alert.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/avatar.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/avatarGroup.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/backtop.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/badge.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/button.js 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/calendar.js 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/carKeyboard.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/cell.js 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/cellGroup.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/checkbox.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/checkboxGroup.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/circleProgress.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/code.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/codeInput.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/col.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/collapse.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/collapseItem.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/columnNotice.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/countDown.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/countTo.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/datetimePicker.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/divider.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/empty.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/form.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/formItem.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/gap.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/grid.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/gridItem.js 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/icon.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/image.js 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/indexAnchor.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/indexList.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/input.js 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/keyboard.js 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/line.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/lineProgress.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/link.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/list.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/listItem.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/loadingIcon.js 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/loadingPage.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/loadmore.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/modal.js 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/navbar.js 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/noNetwork.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/noticeBar.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/notify.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/numberBox.js 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/numberKeyboard.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/overlay.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/parse.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/picker.js 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/popup.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/radio.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/radioGroup.js 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/rate.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/readMore.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/row.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/rowNotice.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/scrollList.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/search.js 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/section.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/skeleton.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/slider.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/statusBar.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/steps.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/stepsItem.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/sticky.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/subsection.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/swipeAction.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/swipeActionItem.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/swiper.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/swipterIndicator.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/switch.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/tabbar.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/tabbarItem.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/tabs.js 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/tag.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/text.js 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/textarea.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/toast.js 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/toolbar.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/tooltip.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/transition.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/props/upload.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/config/zIndex.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/css/color.scss 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/css/common.scss 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/css/components.scss 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/css/flex.scss 257 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/css/h5.scss 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/css/mixin.scss 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/css/mp.scss 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/css/nvue.scss 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/css/vue.scss 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/function/colorGradient.js 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/function/debounce.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/function/digit.js 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/function/index.js 705 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/function/platform.js 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/function/test.js 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/function/throttle.js 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/adapters/index.js 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/core/InterceptorManager.js 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/core/Request.js 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/core/buildFullPath.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/core/defaults.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/core/dispatchRequest.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/core/mergeConfig.js 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/core/settle.js 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/helpers/buildURL.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/helpers/combineURLs.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/helpers/isAbsoluteURL.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/index.d.ts 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/index.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/utils.js 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/luch-request/utils/clone.js 264 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/mixin/button.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/mixin/mixin.js 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/mixin/mpMixin.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/mixin/mpShare.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/mixin/openType.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/mixin/style.js 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/mixin/touch.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/util/async-validator.js 1343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/util/calendar.js 546 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/util/dayjs.js 308 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/util/emitter.js 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/libs/util/route.js 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/package.json 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
uni_modules/uview-ui/theme.scss 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/storage.js 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/verify.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vite.config.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vue.config.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yarn.lock 5080 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -1,48 +1,51 @@
# å¿½ç•¥ç”Ÿæˆçš„æ–‡ä»¶
build/
dist/
unpackage/
*.class
*.jar
*.war
*.ear
######################################################################
# Build Tools
# å¿½ç•¥ç¼–辑器/IDE生成的文件和目录
.idea/
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
### hbuilder ###
unpackage
.hbuilderx
*.swp
*.swo
*~
# å¿½ç•¥ä¾èµ–管理工具生成的目录
node_modules/
bower_components/
vendor/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
# å¿½ç•¥æ“ä½œç³»ç»Ÿæ–‡ä»¶
.DS_Store
Thumbs.db
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
# å¿½ç•¥æ—¥å¿—文件
### JRebel ###
rebel.xml
### NetBeans ###
nbproject/private/
build/*
nbbuild/
dist/
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
*.swp
# å¿½ç•¥æ•æ„Ÿæˆ–包含个人信息的文件(根据需要添加更多)
credentials.json
config.ini
secrets.txt
# å¿½ç•¥å…¶ä»–自定义的文件或目录
/custom_directory/
# æŽ’除特定扩展名的文件(根据需要添加更多)
*.bak
*.tmp
# æŽ’除特定文件名(根据需要添加更多)
debug.log
# ä¸æŽ’除下列扩展名的文件
!*.allowed_extension
# ä¸æŽ’除下列文件名
!important_file.txt
!*/build/*.java
!*/build/*.html
!*/build/*.xml
.vscode/launch.json
ÎļþÒÑɾ³ý
App.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
<script>
  export default {
    onLaunch () {
      // åŠ è½½ç³»ç»Ÿä¿¡æ¯
      this.$store.dispatch('SystemInfo')
    },
    onShow () {
    },
    onHide () {
    }
  }
</script>
<style lang="scss">
@import "@/uni_modules/uview-ui/index.scss";
@import "@/static/style.scss";
</style>
LICENSE
@@ -1,21 +1,201 @@
MIT License
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/
Copyright (c) 2023 å“¦NO
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
   1. Definitions.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.
      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.
      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.
      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.
      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.
      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).
      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.
      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."
      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.
   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.
   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.
   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:
      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and
      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and
      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and
      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.
      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.
   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.
   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.
   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.
   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.
   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.
   END OF TERMS AND CONDITIONS
   APPENDIX: How to apply the Apache License to your work.
      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.
   Copyright [yyyy] [name of copyright owner]
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
       http://www.apache.org/licenses/LICENSE-2.0
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
README.md
@@ -1,269 +1,121 @@
# RuoYi-App-Geek
# ç§»åŠ¨ç«¯åŽå°ç®¡ç†ç³»ç»Ÿ RuoYi-Mobile
主页:<a href="http://fastbuild.run" target="_blank">http://fastbuild.run</a>
<p align="center">
    <span>
        <img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
    </span>
    <span>+</span>
    <span>
        <img alt="logo" src="./doc/image/logo.png">
    </span>
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi-Geek v3.8.7.3.2</h1>
<h4 align="center">基于SpringBoot3+Vue3前后端分离的Java快速开发框架</h4>
<p align="center">
    <img src="https://img.shields.io/github/license/mashape/apistatus.svg">
</p>
[![gitee star](https://gitee.com/yinm/RuoYi-Mobile/badge/star.svg?theme=dark)]('https://gitee.com/yinm/RuoYi-Mobile/stargazers')
[![gitee fork](https://gitee.com/yinm/RuoYi-Mobile/badge/fork.svg?theme=dark)]('https://gitee.com/yinm/RuoYi-Mobile/members')
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
# å¼•言
### :peach: é¡¹ç›®ç®€ä»‹
企事业单位信息化加速,移动端办工逐渐成为趋势,H5或小程序比起APP来说更简单方便。因此一款好的移动端基础平台十分有必要。<br>
项目采用当下流行的UniApp + uView2 æ¡†æž¶å¼€å‘,完成常见的日常工作功能与移动端特有功能组件。
<br><br>
RuoYi-Vue ä¸Ž RuoYi-App æ˜¯åŸºäºŽ SpringBoot2+Vue2 æ‰“造的企业级开发框架,得到了广大开发者的喜爱和积极反馈。随着技术的迭代进步,SpringBoot3 ä¸Ž Vue3 é€æ¸è¿›å…¥å¼€å‘者的视野。为了满足开发者对于新技术的追求,RuoYi å®˜æ–¹æ–‡æ¡£æä¾›äº† SpringBoot2 è‡³ SpringBoot3 çš„升级方法。与此同时,社区也涌现出了 RuoYi-Vue3、RuoYi-App-Vue3 çš„版本,展现了开发者社区对于技术升级的热情与努力。
然而,在升级的过程中,官方的方法为了兼顾 Java1.8 çš„特性与一些老旧的方法,未完全拥抱**SpringBoot3 ä¸Ž Java17**的全部特性。而社区的 RuoYi-Vue3、RuoYi-App-Vue3 ç‰ˆæœ¬ç”±äºŽå‡ºè‡ªä¸åŒçš„团队之手,**兼容性及整合性**上存在些许**不足**。更为关键的是,尽管这些版本**支持 TypeScript**,但**缺乏与之相匹配的 tsconfig.json é…ç½®æ–‡ä»¶**,这使得在主流编辑器如 VSCode ä¸­ï¼ŒTypeScript çš„语法提示环境并未达到最佳状态。
鉴于此,**RuoYi-Geek ç”Ÿæ€**应运而生。它旨在为广大开发者提供一个既保留原版本核心特性,又整合社区版优点的全新解决方案。在**RuoYi-Geek**中,我们深入调研了企业开发中常用的 RuoYi æ‰©å±•,并直接在框架中集成,确保开发者能够快速上手,高效开发。同时,我们采用了最新的**SpringBoot3+Vue3**技术栈,彻底移除了为了兼容 Java1.8 è€Œä¿ç•™çš„老旧方法。更为重要的是,我们为 TypeScript å¼€å‘环境加入了常用的 tsconfig.json é…ç½®ï¼Œä½¿å¾—开发者在 VSCode ç­‰ç¼–辑器中能够获得更为舒适、便捷的语法提示体验。
**RuoYi-Geek**不仅仅是一个简单的升级版本,更是对于 RuoYi ç”Ÿæ€çš„一次全面优化与整合。我们相信,通过**RuoYi-Geek ç”Ÿæ€**,开发者将能够更为高效、愉悦地开发出优秀的企业级应用。
本项目为**RuoYi-Geek ç”Ÿæ€**的 RuoYi-App éƒ¨åˆ†ã€‚
**注意:**
本人的其他两个推荐搭配的项目
1. [Ruoyi-SpringBoot3-Geek: è¿™æ˜¯è‹¥ä¾æžå®¢ç”Ÿæ€çš„后端 Springboot3 ç‰ˆæœ¬ (gitee.com)](https://gitee.com/geek-xd/ruoyi-spring-boot3-geek)
2. [RuoYi-Vue3-Geek: è¿™æ˜¯è‹¥ä¾æžå®¢ç”Ÿæ€çš„ Vue3 ç‰ˆæœ¬ (gitee.com)](https://gitee.com/geek-xd/ruo-yi-vue3-geek)
**与 Ruoyi-App ç›¸æ¯”较**
1. ä½¿ç”¨ UniApp+Vue3 çš„æœ€æ–°æ¡†æž¶
2. æ”¯æŒ TS、SCSS、LESS ç­‰å¯¹ js å’Œ css çš„æ‰©å……语言
3. ä½¿ç”¨ Pinia ä»£æ›¿ Vuex,更加轻巧简单
4. ä½¿ç”¨ uView-Plus(好看的 ui) ä»£æ›¿ uView-ui çš„ ui ç»„件库
5. ä½¿ç”¨ uCharts(方便的图表)画图工具
6. å·²ç»å®Œæˆäº†åˆ†åŒ…操作
7. æä¾›äº†é¢œè‰²é€‰æ‹©å™¨ã€äºŒç»´ç ç­‰å¸¸ç”¨ç»„ä»¶
8. å°†åŽŸæœ‰å†…ç½®å·¥å…·è¿›è¡Œç±»åž‹æ ‡å®š
9. åˆ†åˆ«æä¾›äº† uview-plus å’Œ ucharts çš„æ¨¡æ¿ï¼ˆå¯ä»¥ç›´æŽ¥ä½¿ç”¨æˆ–者用于学习)
# å¿«é€Ÿå¼€å§‹
**注意:** node ç‰ˆæœ¬éœ€è¦ 16+
## è¿ç§»åˆ°Hbuilder(不依赖Hbuilder的项目不需要迁移)
1. src路径作为项目根路径
2. å°†index.html、package.json、vite.config.js、tsconfig.json、.gitignore粘贴到src目录下
3. åœ¨src目录下运行npm install
4. ä¿®æ”¹index.html中的./src/main.js为./main.js
5. åœ¨HBuilderX中运行时注意观察是否使用的是Vue3的编译器(若不是请自行查找方法解决,本人对HbuilderX使用不多)
### :pear: åŽç«¯ä¸‹è½½
下载地址:<a href="http://fastbuild.run" target="_blank">传送门</a><br>
***注:目前移动端支持若依管理平台全系列(单应用、微服务、MySQL版、Oracle版、SqlServer版、Antd版等),需要适配其他版本的请到上面地址下载移动端源码。***
<br><br>
## å®‰è£…
###  :watermelon:  æŠ€æœ¯æ ˆ
| ç»„ä»¶       | ç‰ˆæœ¬     |
|----------|--------|
| uview-ui | 2.0.31 |
| qiun-data-charts | 2.4.3-20220505 |
一下三种方式均可,感觉速度 pnpm > yarn > cnpm > npm
<br><br>
**_Vue3/Vite ç‰ˆè¦æ±‚ node ç‰ˆæœ¬^14.18.0 || >=16.0.0_**
###   :tw-1f348:   ç³»ç»Ÿé…ç½®
1. åŽç«¯è¯·æ±‚地址配置:
```shell
npm install
cnpm install
yarn
pnpm install
```
# é…ç½®æ–‡ä»¶è·¯å¾„:/config/environment.js
# ä¿®æ”¹baseURL属性
const environment = {
    // å¼€å‘环境配置
    development: {
        // æœ¬åœ°éƒ¨ç½²çš„后端
        baseURL: 'http://localhost:8080',
        // ç›´æŽ¥ä½¿ç”¨çº¿ä¸ŠåŽç«¯
        // baseURL: 'http://vue.ruoyi.vip/prod-api'
    },
    // ç”Ÿäº§çŽ¯å¢ƒé…ç½®
    production: {
        baseURL: 'http://vue.ruoyi.vip/prod-api' // å‘布时需要修改为后端实际地址
    }
}
module.exports = {
  environment: environment[process.env.NODE_ENV]
}
```
2. H5启动端口配置:
***注意:不要在manifest.json中配置h5启动信息,可能会引发后端接口访问异常***
```
# é…ç½®æ–‡ä»¶è·¯å¾„:/vue.config.js
# ä¿®æ”¹port属性
const { environment } = require('./config/environment.js')
module.exports = {
  devServer: {
    port: 9001,
    proxy: {
      '/': {
        target: environment.baseURL,
        ws: true,
        changeOrigin: true,
        pathRewrite: {
          '^/': ''
        }
      }
    },
  }
}
```
# å¯åЍ
1. å°†é¡¹ç›®ä¸‹è½½åˆ°æœ¬åœ°
2. åˆå§‹åŒ–项目---进入项目根路径运行指令初始化项目
   `npm install`
3. è¿è¡Œé¡¹ç›®---进入项目根路径运行指令(在 package.json èƒ½æ‰¾åˆ°æ‰€æœ‰æŒ‡ä»¤ï¼‰ï¼š
   ä»¥å¾®ä¿¡å°ç¨‹åºä¸ºä¾‹ï¼š`npm run dev:mp-weixin`
   ä»¥ H5 ä¸ºä¾‹ ` npm run dev:h5`
4. æŸ¥çœ‹é¡¹ç›® ä»¥å¾®ä¿¡å°ç¨‹åºä¸ºä¾‹ï¼š
   æ‰“开微信开发者工具,导入项目路径 dist\dev\mp-weixin
   ä»¥ H5 ä¸ºä¾‹ï¼šæ‰“开浏览器,输入控制台输出的地址
   æ³¨ï¼šå…¬ä¼—号属于 H5,以微信公众号为例,打开微信开发者工具,输入控制台输出的地址
5. æ‰“包项目---进入项目根路径运行指令(在 package.json èƒ½æ‰¾åˆ°æ‰€æœ‰æŒ‡ä»¤ï¼‰ï¼š
   ä»¥å¾®ä¿¡å°ç¨‹åºä¸ºä¾‹ï¼š`npm run build:mp-weixin`
   ä»¥ H5 ä¸ºä¾‹ï¼š `npm run build:h5`
### ä»£ç åŽ‹ç¼©
默认是启动代码压缩的,
如果需要关闭代码压缩,可以将 vite.config.js ä¸­çš„ build.minify èµ‹å€¼ä¸º false。
如果需要打开代码压缩,可以将 vite.config.js ä¸­çš„ build.minify èµ‹å€¼ä¸º true。
# å†…置组件(geek-xd)
1. é¢œè‰²é€‰æ‹©å™¨ç»„ä»¶
2. äºŒç»´ç ç»„ä»¶
3. åœ†å½¢èœå•组件
4. å¸¸ç”¨çš„订单组件
5. ä¿¡æ¯å±•示组件
# æ’件的使用
#### tab - é¡µé¢æ’ä»¶
可以通过设置参数中的 config.data æ¥å®žçŽ°é¡µé¢ä¼ å‚
| æ–¹æ³•         | ä½œç”¨                                             | å‚æ•°        |
| ------------ | ------------------------------------------------ | ----------- |
| getData      | å¯ä»¥æ‹¿åˆ°ä¸Šä¸ªé¡µé¢é€šè¿‡ tab ä¼ é€’的参数              | æ—           |
| reLaunch     | å…³é—­æ‰€æœ‰é¡µé¢ï¼Œæ‰“开到应用内的某个页面             | url、config |
| switchTab    | è·³è½¬åˆ° tabBar é¡µé¢ï¼Œå¹¶å…³é—­å…¶ä»–所有非 tabBar é¡µé¢ | url、config |
| redirectTo   | å…³é—­å½“前页面,跳转到应用内的某个页面             | url、config |
| navigateTo   | ä¿ç•™å½“前页面,跳转到应用内的某个页面             | url、config |
| navigateBack | å…³é—­å½“前页面,返回上一页面或多级页面             | config      |
#### auth - é‰´æƒæ’ä»¶
下面所有方法返回值都是布尔值,permission ä»£è¡¨æƒé™å­—符串,role ä»£è¡¨è§’色字符串,复数形式代表数组。
| æ–¹æ³•        | ä½œç”¨                                       | å‚æ•°        |
| ----------- | ------------------------------------------ | ----------- |
| hasPermi    | éªŒè¯ç”¨æˆ·æ˜¯å¦å…·å¤‡æŸæƒé™                     | permission  |
| hasPermiOr  | éªŒè¯ç”¨æˆ·æ˜¯å¦å«æœ‰æŒ‡å®šæƒé™ï¼Œåªéœ€åŒ…含其中一个 | permissions |
| hasPermiAnd | éªŒè¯ç”¨æˆ·æ˜¯å¦å«æœ‰æŒ‡å®šæƒé™ï¼Œå¿…须全部拥有     | permissions |
| hasRole     | éªŒè¯ç”¨æˆ·æ˜¯å¦å…·å¤‡æŸè§’色                     | role        |
| hasRoleOr   | éªŒè¯ç”¨æˆ·æ˜¯å¦å«æœ‰æŒ‡å®šè§’色,只需包含其中一个 | roles       |
| hasRoleAnd  | roles                                      | roles       |
#### modal - å¼¹çª—插件
content æ˜¯æ¶ˆæ¯å†…容,option æ˜¯è¯¦ç»†é…ç½®ã€‚
| æ–¹æ³•         | ä½œç”¨                           | å‚æ•°    |
| ------------ | ------------------------------ | ------- |
| msg          | æ¶ˆæ¯æç¤º                       | content |
| msgError     | é”™è¯¯æ¶ˆæ¯                       | content |
| msgSuccess   | æˆåŠŸæ¶ˆæ¯                       | content |
| hideMsg      | éšè—æ¶ˆæ¯                       | æ—       |
| alert        | å¼¹å‡ºæç¤º                       | content |
| confirm      | ç¡®è®¤çª—体                       | content |
| showToast    | æç¤ºä¿¡æ¯                       | option  |
| loading      | æ‰“开遮罩层,需要手动关闭遮罩层 | content |
| closeLoading | å…³é—­é®ç½©å±‚                     | æ—       |
#### bus - äº‹ä»¶æ’ä»¶
eventName æ˜¯äº‹ä»¶åç§°ï¼ŒeventFun æ˜¯äº‹ä»¶å¤„理函数,请尽量避免事件插件的使用,请在组件销毁是解绑素有该组件有关的事件,避免产生 bug。
| æ–¹æ³•  | ä½œç”¨         | å‚æ•°                |
| ----- | ------------ | ------------------- |
| $on   | ç»‘定一个事件 | eventName、eventFun |
| $off  | è§£ç»‘一个事件 | eventName           |
| $emit | è§¦å‘一个事件 | eventName、...args  |
#### socket
设置项 enableUUID,是否启用基于 uuid çš„æ¶ˆæ¯å¤„理机制,要求当发送的消息携带 uuid å­—段时,返回的消息也要携带 uuid å­—段。
设置项 enableEvent,是否启用基于事件的消息处理机制,要求当希望被事件处理函数处理的消息需要携带 event å­—段。
| æ–¹æ³•      | ä½œç”¨                                                                                                                    | å‚æ•°                                                                                                                                    |
| --------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| connect   | è¿žæŽ¥ websocke,当连接成功后触发回调函数                                                                                 | æœ€ç®€å•的用法就是传入{url:"ws://demo"}                                                                                                   |
| send      | å‘送信息,当 uuid ä¸ä¸ºç©ºä¸”不为 false æ—¶ï¼Œå½“收到携带相同 uuid çš„æ¶ˆæ¯æ—¶è§¦å‘回调函数,只触发一次。否则由默认处理函数处理。 | msg æ¶ˆæ¯å†…容,会被处理成 json å­—符串 uuid å”¯ä¸€æ ‡è¯†ç¬¦ï¼Œå¯ä»¥æ‰‹åŠ¨ä¼ å…¥ï¼Œä¹Ÿå¯ä»¥è®¾ç½®ä¸º true å½“为 true æ—¶ä¼šè‡ªåŠ¨ç”Ÿæˆä¸€ä¸ª uuid å¹¶æ·»åŠ åˆ° msg ä¸­ã€‚ |
| close     | å…³é—­è¿žæŽ¥ï¼Œä¼šè§¦å‘回调函数的内容,不会触发默认关闭事件的处理函数,也不会修改默认关闭事件的处理函数。                      | æ—                                                                                                                                       |
| on        | ç›‘听事件,当收到携带 event çš„æ¶ˆæ¯æ—¶ä¼šè°ƒç”¨å›žè°ƒå‡½æ•°ã€‚                                                                     | event äº‹ä»¶çš„名称                                                                                                                        |
| off       | å–消监听事件                                                                                                            |                                                                                                                                         |
| onMessage | å®šä¹‰é»˜è®¤ç›‘听事件                                                                                                        | callback é»˜è®¤ç›‘听事件的处理函数                                                                                                         |
| onError   | å®šä¹‰å¼‚常事件                                                                                                            | callback é»˜è®¤å¼‚常事件的处理函数                                                                                                         |
| onClose   | å®šä¹‰å…³é—­äº‹ä»¶                                                                                                            | callback é»˜è®¤å…³é—­äº‹ä»¶çš„处理函数                                                                                                         |
# ä½œè€…建议
### å¯¹äºŽé€‰é¡¹å¼
```js
this.$tab; // å»ºè®®ä½¿ç”¨this.$tab进行页面跳转,理由:便于在跳转前处理其他事务
this.$auth; // å»ºè®®ä½¿ç”¨this.$auth进行鉴权操作
this.$modal; // å»ºè®®ä½¿ç”¨this.$modal打开弹窗,理由:便于以后想要使用自定义弹窗
```
### å¯¹äºŽç»„合式
```js
import tab from "@/plugins/tab"; // å»ºè®®ä½¿ç”¨tab进行页面跳转,理由:便于在跳转前处理其他事务
import auth from "@/plugins/auth"; // å»ºè®®ä½¿ç”¨auth进行鉴权操作
import modal from "@/plugins/modal"; // å»ºè®®ä½¿ç”¨modal打开弹窗,理由:便于以后想要使用自定义弹窗
// ä¹Ÿå¯ä»¥ä½¿ç”¨ä¸‹é¢çš„æ–¹å¼
import { tab, auth, modal } from "@/plugins";
```
### å¯¹äºŽ ucharts
建议即便暂时不使用图表也不要删除它,以后可能会用到。
# åŽ‹ç¼©å†…å­˜
(主包最低 809kb å·¦å³)
### åˆ é™¤ geek ç»„ä»¶
1. åˆ é™¤ pages_geek å’Œ components/geek-xd æ–‡ä»¶å¤¹
2. åˆ é™¤ pages.json ä¸­ subPackages çš„ root å€¼ä¸ºâ€œpages_geek/pages”的配置
3. åˆ é™¤ pages/template.config.js ä¸­ geek ç»„ä»¶
### åŽ»é™¤æ¨¡æ¿
(占用主包 582kb å·¦å³ï¼‰
1. åˆ é™¤ pages_template、pages_qiun ä¸¤ä¸ªæ–‡ä»¶å¤¹
2. åˆ é™¤ pages.json ä¸­ subPackages çš„ root å€¼ä¸ºâ€œpages_qiun/pages”、“pages_template/pages”的两个配置
3. åˆ é™¤ pages/template.config.js å’Œ pages/template.vue
4. åˆ é™¤ pages.json ä¸­ subPackages çš„“tabBar”中的模板一项和“pages”中模板的一项
5. åˆ é™¤ static ä¸­çš„ uview,里面都是示例图片。
6. åˆ é™¤ plugins ä¸­çš„ config.js å’Œ common.js,并在 plugins/index.js ä¸­åˆ é™¤ç›¸å…³é…ç½®
### åˆ é™¤ uchart
(占用主包 175kb å·¦å³ï¼Œä¸å»ºè®®åˆ é™¤ï¼Œä»¥é˜²ä»¥åŽä¼šç”¨ï¼‰
1. åˆ é™¤ components/qiun-data-charts æ–‡ä»¶å¤¹
2. åˆ é™¤ pages.json ä¸­çš„ easycom ä¸‹çš„ custom ä¸­çš„"qiun-(.\*)"的那一行
3. åˆ é™¤ pages/index ä¸­ä½¿ç”¨ â€œqiun-data-charts” çš„部分
### åˆ é™¤ uview
(按需引入,没必要删除)
1. main.js æˆ–者 main.ts ä¸­åˆ é™¤
```js
import uviewPlus from "uview-plus";
// ......
app.use(uviewPlus);
```
2. uni.scss ä¸­åˆ é™¤ @import 'uview-plus/theme.scss';
3. App.vue ä¸­åˆ é™¤ @import '@/static/scss/index.scss';
4. package.json ä¸­åˆ é™¤ "clipboard": "^2.0.11","dayjs": "^1.11.9","uview-plus": "^3.1.36",
# åŠŸèƒ½æ¼”ç¤º
###    :lemon:   ç³»ç»Ÿæˆªå›¾
<table>
    <tr>
        <td><img src="./doc/image/template1.png" /></td>
        <td><img src="./doc/image/template2.png"  /></td>
        <td valign="top"><img src="https://gitee.com/yinm/RuoYi-Mobile/raw/master/static/preview/login.jpg"/></td>
        <td valign="top"><img src="https://gitee.com/yinm/RuoYi-Mobile/raw/master/static/preview/index.jpg"/></td>
        <td valign="top"><img src="https://gitee.com/yinm/RuoYi-Mobile/raw/master/static/preview/work.jpg"/></td>
        <td valign="top"><img src="https://gitee.com/yinm/RuoYi-Mobile/raw/master/static/preview/my.jpg"/></td>
    </tr>
    <tr>
        <td><img src="./doc/image/index.png"  /></td>
        <td><img src="./doc/image/mallMenu.png"/></td>
        <td valign="top"><img src="https://gitee.com/yinm/RuoYi-Mobile/raw/master/static/preview/notice-m.jpg"/></td>
        <td valign="top"><img src="https://gitee.com/yinm/RuoYi-Mobile/raw/master/static/preview/notice-e.jpg"/></td>
        <td valign="top"><img src="https://gitee.com/yinm/RuoYi-Mobile/raw/master/static/preview/prefile.jpg"/></td>
        <td valign="top"><img src="https://gitee.com/yinm/RuoYi-Mobile/raw/master/static/preview/pwd-reset.jpg"/></td>
    </tr>
</table>
<br><br>
# é™„录
###  :lollipop: æŠ€æœ¯äº¤æµ
QQ群:860974500
[Vue3 å®˜ç½‘](https://cn.vuejs.org/);
[uniapp å®˜ç½‘](https://uniapp.dcloud.net.cn/);
[uView-plus å®˜ç½‘](https://uiadmin.net/uview-plus/);
[uCharts å®˜ç½‘](https://www.ucharts.cn/v2/#/);
[RuoYi å®˜ç½‘](http://ruoyi.vip/);
<br><br>
#### å¦‚果觉得项目还不错,一定记得 :star: ä¸€ä¸‹
#### å¦‚果觉得项目还不错,一定记得 :star: ä¸€ä¸‹
#### å¦‚果觉得项目还不错,一定记得 :star: ä¸€ä¸‹
<br><br>
# è”系我们:
QQ äº¤æµç¾¤ï¼š744785891
###  :poultry_leg:  ç»™ä½œè€…加个鸡腿
如果对您的工作或学习产生些许帮助,可以给作者的午餐加一个鸡腿 :poultry_leg:  :poultry_leg:  :poultry_leg: ï¼~~
<table>
    <tr>
        <td valign="top" width="180"><img src="https://gitee.com/yinm/RuoYi-Mobile/raw/master/static/preview/wechat_pay.jpg"/></td>
        <td valign="top" width="180"><img src="https://gitee.com/yinm/RuoYi-Mobile/raw/master/static/preview/ali_pay.jpg"/></td>
    </tr>
    <tr>
        <td valign="top" align="center">微信捐助</td>
        <td valign="top" align="center">支付宝捐助</td>
    </tr>
</table>
api/captcha.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,4 @@
import request from '@/config/request.js';
// èŽ·å–éªŒè¯ç 
export const image = () => request.get('/captchaImage', null, { custom: { auth: false, loading: false } })
api/center/log.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,4 @@
import request from '@/config/request.js';
// èŽ·å–æ“ä½œæ—¥å¿—
export const operLog = (params) => request.get('/monitor/operlog/list', params)
api/login.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
import request from '@/config/request.js';
// ç”¨æˆ·ç™»å½•(账号+密码+验证码)
export const login = (params) => request.post('/login', params, { custom: { auth: false } })
// ç”¨æˆ·é€€å‡º
export const logout = () => request.get('/logout')
api/user.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,4 @@
import request from '@/config/request.js';
// èŽ·å–ç”¨æˆ·ä¿¡æ¯
export const getInfo = () => request.get('/getInfo')
api/work/notice.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
import request from '@/config/request.js';
// èŽ·å–é€šçŸ¥å…¬å‘Šåˆ—è¡¨
export const noticeList = (params) => request.get('/system/notice/list', params)
// èŽ·å–é€šçŸ¥å…¬å‘Šè¯¦æƒ…ä¿¡æ¯
export const noticeById = (id) => request.get('/system/notice/' + id)
// æ–°å¢žé€šçŸ¥å…¬å‘Šè¯¦æƒ…信息
export const noticeAdd = (params) => request.post('/system/notice', params)
// ä¿®æ”¹é€šçŸ¥å…¬å‘Šè¯¦æƒ…信息
export const noticeModify = (params) => request.put('/system/notice', params)
// åˆ é™¤é€šçŸ¥å…¬å‘Šè¯¦æƒ…信息
export const noticeDelete = (id) => request.delete('/system/notice/' + id)
api/work/userManage.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
import request from '@/config/request.js';
// èŽ·å–ç”¨æˆ·åˆ—è¡¨
export const userList = (params) => request.get('/system/user/list', params)
// èŽ·å–ç”¨æˆ·ä¿¡æ¯
export const userById = (id) => request.get('/system/user/' + id)
components/button/FloatButton.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
<template>
  <view class="float-button">
    <u-button :type="type" :icon="icon" :shape="shape" :disabled="disabled" :size="size" @click="$emit('click')"></u-button>
  </view>
</template>
<script>
export default {
  props: {
    // æŒ‰é’®çš„预置样式,info,primary,error,warning,success
    type: {
      type: String,
      default: uni.$u.props.button.type
    },
    // å›¾æ ‡
    icon: {
      type: String
    },
    // æŒ‰é’®å°ºå¯¸ï¼Œlarge,normal,small,mini
    size: {
      type: String,
      default: 'large'
    },
    // æŒ‰é’®å½¢çŠ¶ï¼Œcircle(两边为半圆),square(带圆角)
    shape: {
      type: String,
      default: 'circle'
    },
    // æŒ‰é’®æ˜¯å¦é•‚空
    plain: {
      type: Boolean,
      default: uni.$u.props.button.plain
    },
    // æ˜¯å¦ç¦æ­¢çŠ¶æ€
    disabled: {
      type: Boolean,
      default: uni.$u.props.button.disabled
    },
  }
}
</script>
<style lang="scss" scoped>
.float-button {
  bottom: 100px;
  right: 20px;
  width: 52px;
  height: 52px;
  position: fixed;
  z-index: 10;
}
</style>
components/gap/Gap.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
<template>
  <u-gap :height="height" :bgColor="bgColor"></u-gap>
</template>
<script>
export default {
  props: {
    height: {
      type: [String, Number],
      default: 16
    },
    bgColor: {
      type: String,
      default: '#f4f4f5'
    }
  }
}
</script>
components/navbar/Navbar.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,117 @@
<template>
  <block v-if="isShow()">
    <view v-if="hideBtn" class="u-navbar" :style="{ backgroundColor: bgColor, textAlign: 'center' }">
      <view
        class="u-navbar__placeholder"
        v-if="fixed"
        :style="{
          height: $u.addUnit($u.getPx(height) + $u.sys().statusBarHeight,'px'),
        }"
      ></view>
      <view :class="[fixed && 'u-navbar--fixed']">
        <u-status-bar v-if="safeAreaInsetTop" :bgColor="bgColor"></u-status-bar>
        <view class="u-navbar__content" :class="[border && 'u-border-bottom']" :style="{ height: contentHeight, backgroundColor: bgColor }">
          <view class="u-navbar__content__left" hover-class="u-navbar__content__left--hover" hover-start-time="150" style="position: relative;">
            <text class="u-line-1 u-navbar__content__title" :style="[{ height: contentHeight, lineHeight: contentHeight, margin: '0 auto' }, $u.addStyle(titleStyle)]">
              {{ title }}
            </text>
          </view>
        </view>
      </view>
    </view>
    <u-navbar v-else :title="title" :autoBack="true" :placeholder="true" :bgColor="bgColor"></u-navbar>
  </block>
</template>
<script>
import props from './props.js';
/**
 * Navbar è‡ªå®šä¹‰å¯¼èˆªæ 
 * @property {Boolean}            h5Show                æ˜¯å¦åœ¨h5模式下显示 ï¼ˆé»˜è®¤ false ï¼‰
 * @property {Boolean}            hideBtn                æ˜¯å¦éšè—è¿”回按钮 ï¼ˆé»˜è®¤ false ï¼‰
 */
export default {
  mixins: [props],
  props: {
    h5Show: Boolean,
    hideBtn: Boolean,
    back: Boolean,
    home: Boolean
  },
  data () {
    return {
      systemInfo : this.$store.getters.getSystemInfo,
      statusBarHeight: uni.$u.addUnit(uni.$u.getPx(this.height) + uni.$u.sys().statusBarHeight, 'px'),
      contentHeight: uni.$u.addUnit(this.height)
    }
  },
  methods: {
    isShow () {
      if (this.systemInfo.uniPlatform == 'web') {
        return this.h5Show
      }
      return true;
    }
  }
}
</script>
<style lang="scss" scoped>
    .u-navbar {
        &--fixed {
            position: fixed;
            left: 0;
            right: 0;
            top: 0;
            z-index: 11;
        }
        &__content {
            @include flex(row);
            align-items: center;
            height: 44px;
            background-color: #9acafc;
            position: relative;
            justify-content: center;
            &__left,
            &__right {
                padding: 0 13px;
                position: absolute;
                top: 0;
                bottom: 0;
                @include flex(row);
                align-items: center;
            }
            &__left {
                left: 0;
                &--hover {
                    opacity: 0.7;
                }
                &__text {
                    font-size: 15px;
                    margin-left: 3px;
                }
            }
            &__title {
                text-align: center;
                font-size: 16px;
                color: $u-main-color;
            }
            &__right {
                right: 0;
                &__text {
                    font-size: 15px;
                    margin-left: 3px;
                }
            }
        }
    }
</style>
components/navbar/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,84 @@
export default {
    props: {
        // æ˜¯å¦å¼€å¯é¡¶éƒ¨å®‰å…¨åŒºé€‚配
        safeAreaInsetTop: {
            type: Boolean,
            default: uni.$u.props.navbar.safeAreaInsetTop
        },
        // å›ºå®šåœ¨é¡¶éƒ¨æ—¶ï¼Œæ˜¯å¦ç”Ÿæˆä¸€ä¸ªç­‰é«˜å…ƒç´ ï¼Œä»¥é˜²æ­¢å¡Œé™·
        placeholder: {
            type: Boolean,
            default: uni.$u.props.navbar.placeholder
        },
        // æ˜¯å¦å›ºå®šåœ¨é¡¶éƒ¨
        fixed: {
            type: Boolean,
            default: uni.$u.props.navbar.fixed
        },
        // æ˜¯å¦æ˜¾ç¤ºä¸‹è¾¹æ¡†
        border: {
            type: Boolean,
            default: uni.$u.props.navbar.border
        },
        // å·¦è¾¹çš„图标
        leftIcon: {
            type: String,
            default: uni.$u.props.navbar.leftIcon
        },
        // å·¦è¾¹çš„æç¤ºæ–‡å­—
        leftText: {
            type: String,
            default: uni.$u.props.navbar.leftText
        },
        // å·¦å³çš„æç¤ºæ–‡å­—
        rightText: {
            type: String,
            default: uni.$u.props.navbar.rightText
        },
        // å³è¾¹çš„图标
        rightIcon: {
            type: String,
            default: uni.$u.props.navbar.rightIcon
        },
        // æ ‡é¢˜
        title: {
            type: [String, Number],
            default: uni.$u.props.navbar.title
        },
        // èƒŒæ™¯é¢œè‰²
        bgColor: {
            type: String,
            default: uni.$u.props.navbar.bgColor
        },
        // æ ‡é¢˜çš„宽度
        titleWidth: {
            type: [String, Number],
            default: uni.$u.props.navbar.titleWidth
        },
        // å¯¼èˆªæ é«˜åº¦
        height: {
            type: [String, Number],
            default: uni.$u.props.navbar.height
        },
        // å·¦ä¾§è¿”回图标的大小
        leftIconSize: {
            type: [String, Number],
            default: uni.$u.props.navbar.leftIconSize
        },
        // å·¦ä¾§è¿”回图标的颜色
        leftIconColor: {
            type: String,
            default: uni.$u.props.navbar.leftIconColor
        },
        // ç‚¹å‡»å·¦ä¾§åŒºåŸŸ(返回图标),是否自动返回上一页
        autoBack: {
            type: Boolean,
            default: uni.$u.props.navbar.autoBack
        },
        // æ ‡é¢˜çš„æ ·å¼ï¼Œå¯¹è±¡æˆ–字符串
        titleStyle: {
            type: [String, Object],
            default: uni.$u.props.navbar.titleStyle
        }
    }
}
components/qian-tree/qian-tree.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,425 @@
<template xlang="wxml">
    <view class="tki-tree">
        <view class="tki-tree-mask" :class="{'show':showTree}" @tap="_cancel"></view>
        <view class="tki-tree-cnt" :class="{'show':showTree}">
            <view class="tki-tree-bar">
                <view class="tki-tree-bar-cancel" :style="{'color':cancelColor}" hover-class="hover-c" @tap="_cancel">取消</view>
                <view class="tki-tree-bar-title" :style="{'color':titleColor}">{{title}}</view>
                <view class="tki-tree-bar-confirm" :style="{'color':confirmColor}" hover-class="hover-c" @tap="_confirm">确定</view>
            </view>
            <view class="tki-tree-view">
                <scroll-view class="tki-tree-view-sc" :scroll-y="true">
                    <block v-for="(item, index) in treeList" :key="index">
                        <view class="tki-tree-item" :style="[{
                            paddingLeft: item.rank*15 + 'px',
                            zIndex: item.rank*-1 +50
                        }]"
                         :class="{
                            border: border === true,
                            show: item.show,
                            last: item.lastRank,
                            showchild: item.showChild,
                            open: item.open,
                        }">
                            <view class="tki-tree-label" @tap.stop="_treeItemTap(item, index)">
                                <image class="tki-tree-icon" :src="item.lastRank ? lastIcon : item.showChild ? currentIcon : defaultIcon"></image>
                                {{item.name}}
                            </view>
                            <view class="tki-tree-check" @tap.stop="_treeItemSelect(item, index)" v-if="selectParent?true:item.lastRank">
                                <view class="tki-tree-check-yes" v-if="item.checked" :class="{'radio':!multiple}" :style="{'border-color':confirmColor}">
                                    <view class="tki-tree-check-yes-b" :style="{'background-color':confirmColor}"></view>
                                </view>
                                <view class="tki-tree-check-no" v-else :class="{'radio':!multiple}" :style="{'border-color':confirmColor}"></view>
                            </view>
                        </view>
                    </block>
                </scroll-view>
            </view>
        </view>
    </view>
</template>
<script>
    export default {
        name: "tki-tree",
        props: {
            lazy: {
                type: Boolean,
                default: false
            },
            range: {
                type: Array,
                default: function() {
                    return []
                }
            },
            idKey: {
                type: String,
                default: 'id'
            },
            rangeKey: {
                type: String,
                default: 'label'
            },
            title: {
                type: String,
                default: ''
            },
            multiple: { // æ˜¯å¦å¯ä»¥å¤šé€‰
                type: Boolean,
                default: false
                // default: true
            },
            selectParent: { //是否可以选父级
                type: Boolean,
                default: false
            },
            foldAll: { //折叠时关闭所有已经打开的子集,再次打开时需要一级一级打开
                type: Boolean,
                default: false
            },
            confirmColor: { // ç¡®å®šæŒ‰é’®é¢œè‰²
                type: String,
                default: '' // #07bb07
            },
            cancelColor: { // å–消按钮颜色
                type: String,
                default: '' // #757575
            },
            titleColor: { // æ ‡é¢˜é¢œè‰²
                type: String,
                default: '' // #757575
            },
            currentIcon: { // å±•开时候的ic
                type: String,
                default: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAABRCAYAAACqj0o2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MEQ0QTM0MzQ1Q0RBMTFFOUE0MjY4NzI1Njc1RjI1ODIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MEQ0QTM0MzU1Q0RBMTFFOUE0MjY4NzI1Njc1RjI1ODIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowRDRBMzQzMjVDREExMUU5QTQyNjg3MjU2NzVGMjU4MiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowRDRBMzQzMzVDREExMUU5QTQyNjg3MjU2NzVGMjU4MiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PidwepsAAAK0SURBVHja7JxbTsJAFIYHww7ciStgCeoGvGxAiOsgURegoL5720AXYLiIr0aJviq3Zx3PhIEnKG3ndtr+f3KixrSUj/ZjzjClIqUUiFm2gAAQAREQEUAEREAERAQQAREQAREBREAEREBEEqa67h9RFDWllDv0awWYlqlQHmu1WjMRRMoV1QFttA12y3xRtdNczq8EsE4/f8FumX2q77ROvNXk8UGMEKdUz6tYJHljaZAbuyUH+UR1to5BEohTuqwPCeS4pAA/qY6o/kyHOAMCeRK3owJnj+rH1jjxhqpVsstaebCz6TmnHWyXyY+xHjSBWBY/bvSgadtXBj9u9KCN3rnIfkzkQVsTEEX0Y2IP2oKo/HhMICcFAThUcwVZNGU6FdbX/XURzkbVF4+ybGhjPrFdgP66QdXNurGtSdk6Xdb9nAJ8oDo3OQlsQZzkdPw41ONBo6vI5scDefRjZg+6gpg3Pxp50CXEvPjR2IOuIXL3oxUPuobI3Y9WPOgDIlc/WvOgL4iL/vqFCcD7LH0xB4hj7cfQ/fWH9qCT+FhG0tN+DBk1PzjOM0SVllixcsBT1AvYc/kAPhc0hRg/3uvxoCgKRN9+dOrBUBB9+9GpB0NC9OVH5x4MDdG1H714kANEV3705kEOEBf9dcPi/lQnsuvLg1wgSu3Ha0v7Uh4MMgUXeuG71H407a+VBy9CPQkOdw+MtB+nGbd/D+FBbhBNxo9SjwcngJjNj0E9yBFiFj8G9SBXiGn8GNyDnCEm8SMLD3KHGOdHNh7kDjHOj2w8mAeIi/5arX+c6b/fxHz9oADEdGdjR/fXCw/OOB5oVfCOgnepz8IB14PMw03jCmTE+QBx5z0gAmKSqK9OUF+hcAeIhu/QYr4Qie8rjW83hhMBERARQAREQAREBBABERCLnH8BBgA+TQI7U4t53AAAAABJRU5ErkJggg=='
            },
            defaultIcon: { // æŠ˜å æ—¶å€™çš„ic
                type: String,
                default: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAABRCAYAAACqj0o2AAACE0lEQVR4Xu3c200DMRCF4XEltJAOkEugA+ggpUAHoQMqiFMCdEAJUMEiS4mEELlIO7bPOeN9i6K1rG/952myyea1WiCtXmEuYBPR4RBMxInoIOCwhOtJLKVszWyXc/5y2BvNEq6I+/3+kFK6M7OHnPM7jcLKjbZAvD/uaZtzflm5P4rbWyJWgDcze1LPuzVihfxUz7sH4ilJ2bx7Isrm3RtRMu8RiHJ5j0SUyXs0okTeCIj0eSMh0uaNhkiZNyIiXd7IiDR5oyNS5M2ACJ83EyJs3myIkHkzIsLlzYwIkzc7IkTeCojD81ZCHJa3GuKQvBURu+etjNgtb3XELnlHQGyedyTEZnlHQ2ySd0RE97wjI7rlHR3RJe+JeIrbLOecD6ePpZQ6W1kn2epo4MUrPOKyLN8ppYq1+y1VStncOjIdGnFZlo+U0uOtWOeOY2TE12Ouq//pEA7xXL7XfvcufR8K0Svfv6CREN3yDYfYIt9QiK3yjYTYLF95xB75SiP2ylcZsVu+cogj8pVCHJWvEuKwfOkREfKlRkTJlxkRJl86RMR8qRBR82VChM0XHpEhX2hElnyREWnyhUNkzBcKkTVfJETafIcjKuQ7FFEl35GIMvl2R1TMtyuiar49EWXzbY5oZpv/hibXTF2h3+s60FRKeT6+3TjMS3nrA3ZFRD8xrfY3ER1kJ+JEdBBwWGKeRAfEH1wS5WFZSDB/AAAAAElFTkSuQmCC'
            },
            lastIcon: { // æ²¡æœ‰å­é›†çš„ic
                type: String,
                default: ''
            },
            border: { // æ˜¯å¦æœ‰åˆ†å‰²çº¿
                type: Boolean,
                default: false
            },
        },
        data() {
            return {
                showTree: false,
                treeList: [],
                selectIndex: -1,
                returnedItem: [] ,//定义一个空数组
                pids: [],
                ancestorsIds: [],
                childNums: [],
            }
        },
        computed: {},
        methods: {
            _show() {
                this.showTree = true
            },
            _hide() {
                this.showTree = false
            },
            _cancel() {
                this._hide()
                this.$emit("cancel", '');
            },
            _confirm() {
                // å¤„理所选数据
                let rt = [],
                    obj = {};
                this.treeList.forEach((v, i) => {
                    if (this.treeList[i].checked) {
                        rt.push(this.treeList[i].id)
                    }
                })
                this._hide()
                this.$emit("confirm", rt);
            },
            //扁平化树结构
            _renderTreeList(list = [], rank = 0, parentId = [], parents = []) {
                list.forEach(item => {
                    this.treeList.push({
                        id: item[this.idKey],
                        name: item[this.rangeKey],
                        source: item,
                        parentId, // çˆ¶çº§id数组
                        parents, // çˆ¶çº§id数组
                        rank, // å±‚级
                        showChild: false, //子级是否显示
                        open: false, //是否打开
                        show: rank === 0, // è‡ªèº«æ˜¯å¦æ˜¾ç¤º
                        hideArr: [],
                        orChecked: item.checked ? item.checked : false,
                        checked: item.checked ? item.checked : false,
                        childNum: 0
                    })
                    if (Array.isArray(item.children) && item.children.length > 0) {
                        // console.log(item)
                        let parentid = [...parentId],
                            parentArr = [...parents];
                        delete parentArr.children
                        parentid.push(item[this.idKey]);
                        parentArr.push({
                            [this.idKey]: item[this.idKey],
                            [this.rangeKey]: item[this.rangeKey]
                        })
                        // lazy
                        if(!this.lazy) {
                            this._renderTreeList(item.children, rank + 1, parentid, parentArr)
                        }
                    } else {
                        this.treeList[this.treeList.length - 1].lastRank = true;
                    }
                })
            },
            // å¤„理默认选择
            _defaultSelect() {
                this.treeList.forEach((v, i) => {
                    if (v.checked) {
                        this.treeList.forEach((v2, i2) => {
                            if (v.parentId.toString().indexOf(v2.parentId.toString()) >= 0) {
                                v2.show = true
                                if (v.parentId.includes(v2.id)) {
                                    v2.showChild = true;
                                    v2.open = true;
                                }
                            }
                        })
                    }
                })
            },
            getOwn(id, arr){
              //利用foreach循环遍历
              arr.forEach((item) => {
                //判断递归结束条件
                if(item[this.idKey] == id)
                {
                  // å­˜å‚¨æ•°æ®åˆ°ç©ºæ•°ç»„
                  this.returnedItem = item
                }
                  else if(item.children != null) //判断chlidren是否有数据
                {
                  //递归调用
                  this.getOwn(id, item.children);
                }
              })
              return this.returnedItem
            },
            setShow (id, arr, isShow) {
                arr.forEach((item, index) => {
                    if(item.parentId.includes(id)) {
                        this.treeList[index].showChild = isShow
                        this.treeList[index].show = isShow
                    } else if (item.children !== undefined) {
                        this.setShow(id, item.children, isShow)
                    }
                })
            },
            // ç‚¹å‡»
            _treeItemTap(item, index) {
                // console.log(item)
                if (item.lastRank === true) {
                    //点击最后一级时触发事件
                    this.treeList[index].checked = !this.treeList[index].checked
                    this._fixMultiple(index)
                    return;
                }
                let id = item.id;
                item.showChild = !item.showChild;
                // qingqian
                if(item.showChild) {
                    const range = this.range
                    const parentIdArr = item.parentId
                    // æ‰¾åˆ°å½“前元素
                    const own = this.getOwn(id, range)
                    const checkedChildren = own.children
                    // å­å…ƒç´ æ’入的索引位置
                    const nextIndex = this.treeList.findIndex(itemT => itemT.id === item.id)
                    console.log(checkedChildren);
                    if(checkedChildren === undefined || checkedChildren.length < 1) {
                        return
                    }
                    // å­èŠ‚ç‚¹æ•°é‡
                    this.treeList[index].childNum = checkedChildren.length
                    const newRank = item.rank + 1
                    checkedChildren.forEach(itemC => {
                        const childObj = {
                            id: itemC[this.idKey],
                            name: itemC[this.rangeKey],
                            source: {},
                            parentId: [item.id], // çˆ¶çº§id数组
                            parents: [item], // çˆ¶çº§id数组
                            rank: newRank, // å±‚级
                            showChild: false, //子级是否显示
                            open: false, //是否打开
                            show: 1, // è‡ªèº«æ˜¯å¦æ˜¾ç¤º
                            hideArr: [],
                            orChecked:  this.treeList[index].checked,
                            checked:  this.treeList[index].checked,
                        }
                        if(!this.treeList.some(itemT => itemT.id === itemC[this.idKey])) {
                            this.treeList.splice(nextIndex+1,0,childObj)
                        }
                    })
                }
                // å±•å¼€/隐藏子级/孙级
                let list = this.treeList
                item.open = item.showChild ? true : !item.open;
                list.forEach((childItem, i) => {
                    if (item.showChild === false) {
                        //隐藏所有子级
                        if (!childItem.parentId.includes(id)) {
                            return;
                        }
                        //TODO: ä¿®æ”¹
                        if (!this.foldAll) {
                            if (childItem.lastRank !== true && !childItem.open) {
                                childItem.showChild = false;
                                this.setShow(childItem.id, this.treeList, false)
                            }
                            // ä¸ºéšè—çš„内容添加一个标记
                            if (childItem.show) {
                                childItem.hideArr[item.rank] = id
                            }
                        } else {
                            if (childItem.lastRank !== true) {
                                childItem.showChild = false;
                                // ç»§ç»­éšè—å­çº§çš„的子级
                                this.setShow(childItem.id, this.treeList, false)
                            }
                        }
                        if(childItem.children !== undefined) {
                            childItem.children.forEach((childItem1, i1) => {
                                if(!childItem1.parentId.includes(childItem.id)) {
                                    return
                                }
                                childItem.children[i1].showChild = false
                                childItem.children[i1].show = false
                            })
                        }
                        childItem.show = false;
                    } else {
                        // æ‰“开子集
                        if (childItem.parentId[childItem.parentId.length - 1] === id) {
                            childItem.show = true;
                        }
                        // æ‰“开被隐藏的子集
                        if (childItem.parentId.includes(id) && !this.foldAll) {
                            // console.log(childItem.hideArr)
                            if (childItem.hideArr[item.rank] === id) {
                                childItem.show = true;
                                if (childItem.open && childItem.showChild) {
                                    childItem.showChild = true
                                } else {
                                    childItem.showChild = false
                                }
                                childItem.hideArr[item.rank] = null
                            }
                        }
                    }
                })
            },
            // é€šè¿‡çˆ¶id处理子级
            syncChecked (trees, pid, checked) {
                trees.forEach((item,index) => {
                    if(item.parentId.includes(pid)) {
                        this.treeList[index].checked = checked
                        this.syncChecked(trees, item.id, checked)
                    } else if(item.children !== undefined) {
                        this.syncChecked(item.children, pid, checked)
                    }
                })
            },
            // èŽ·å–çˆ¶çº§å¾€ä¸Šæ‰€æœ‰å±‚çº§çš„id å¹¶åŒæ­¥çŠ¶æ€
            setAncestors (pids, checked) {
                this.treeList.forEach((item,index) => {
                    if(pids.includes(item.id)) {
                        if(checked && this.childNums[item.id] !== undefined && item.childNum === this.childNums[item.id]) {
                        // å­çº§å…¨éƒ¨é€‰ä¸­, çˆ¶çº§æ‰é€‰ä¸­
                            this.treeList[index].checked = true
                        } else {
                            this.treeList[index].checked = false
                        }
                        this.setAncestors(item.parentId, checked)
                    }
                })
            },
            _treeItemSelect(item, index) {
                this.treeList[index].checked = !this.treeList[index].checked
                // é€‰çˆ¶çº§, å­çº§è‡ªåЍ免选
                this.syncChecked(this.treeList, item.id, this.treeList[index].checked)
                if(item.rank > 0) {
                    item.parentId.forEach((pid, indexP) => {
                        const parent = this.treeList.filter(i => i.id === pid)
                        const childNum = parent.length > 0 ? parent[0].childNum : 0
                        if(this.childNums[pid] === undefined) {
                            this.childNums[pid] = 1
                        } else if(this.childNums[pid] < childNum) {
                            this.childNums[pid]++
                        }
                    })
                    //子级选择/选满/取消选择, çˆ¶çº§å¾€ä¸ŠåŒæ­¥çŠ¶æ€
                    this.setAncestors(item.parentId, this.treeList[index].checked)
                }
                this._fixMultiple(index)
            },
            // å¤„理单选多选
            _fixMultiple(index) {
                if (!this.multiple) {
                    // å¦‚果是单选
                    this.treeList.forEach((v, i) => {
                        if (i != index) {
                            this.treeList[i].checked = false
                        } else {
                            this.treeList[i].checked = true
                        }
                    })
                }
            },
            // é‡ç½®æ•°æ®
            _reTreeList() {
                this.treeList.forEach((v, i) => {
                    this.treeList[i].checked = v.orChecked
                })
            },
            _initTree(range = this.range){
                this.treeList = [];
                this._renderTreeList(range);
                this.$nextTick(() => {
                    this._defaultSelect(range)
                })
            }
        },
        watch: {
            range(list) {
                this._initTree(list);
            },
            multiple() {
                if (this.range.length) {
                    this._reTreeList();
                }
            },
            selectParent() {
                if (this.range.length) {
                    this._reTreeList();
                }
            },
        },
        mounted() {
            this._initTree();
        }
    }
</script>
<style scoped>
    @import "./style.css";
</style>
components/qian-tree/style.css
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,151 @@
.tki-tree-mask {
  position: fixed;
  top: 0rpx;
  right: 0rpx;
  bottom: 0rpx;
  left: 0rpx;
  z-index: 9998;
  background-color: rgba(0, 0, 0, 0.6);
  opacity: 0;
  transition: all 0.3s ease;
  visibility: hidden;
}
.tki-tree-mask.show {
  visibility: visible;
  opacity: 1;
}
.tki-tree-cnt {
  position: fixed;
  top: 0rpx;
  right: 0rpx;
  bottom: 0rpx;
  left: 0rpx;
  z-index: 9999;
  top: 160rpx;
  transition: all 0.3s ease;
  transform: translateY(100%);
}
.tki-tree-cnt.show {
  transform: translateY(0);
}
.tki-tree-bar {
  background-color: #fff;
  height: 72rpx;
  padding-left: 20rpx;
  padding-right: 20rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-sizing: border-box;
  border-bottom-width: 1rpx !important;
  border-bottom-style: solid;
  border-bottom-color: #f5f5f5;
  font-size: 32rpx;
  color: #757575;
  line-height: 1;
}
.tki-tree-bar-confirm {
  color: #07bb07;
}
.tki-tree-view {
  position: absolute;
  top: 0rpx;
  right: 0rpx;
  bottom: 0rpx;
  left: 0rpx;
  top: 72rpx;
  background-color: #fff;
  padding-top: 20rpx;
  padding-right: 20rpx;
  padding-bottom: 20rpx;
  padding-left: 20rpx;
}
.tki-tree-view-sc {
  height: 100%;
  overflow: hidden;
}
.tki-tree-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 26rpx;
  color: #757575;
  line-height: 1;
  height: 0;
  opacity: 0;
  transition: 0.2s;
  position: relative;
  overflow: hidden;
}
.tki-tree-item.show {
  height: 80rpx;
  opacity: 1;
}
.tki-tree-item.showchild:before {
  transform: rotate(90deg);
}
.tki-tree-item.last:before {
  opacity: 0;
}
.tki-tree-icon {
  width: 26rpx;
  height: 26rpx;
  margin-right: 8rpx;
}
.tki-tree-label {
  flex: 1;
  display: flex;
  align-items: center;
  height: 100%;
  line-height: 1.2;
}
.tki-tree-check {
  width: 40px;
  height: 40px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.tki-tree-check-yes,
.tki-tree-check-no {
  width: 20px;
  height: 20px;
  border-top-left-radius: 20%;
  border-top-right-radius: 20%;
  border-bottom-right-radius: 20%;
  border-bottom-left-radius: 20%;
  border-top-width: 1rpx;
  border-left-width: 1rpx;
  border-bottom-width: 1rpx;
  border-right-width: 1rpx;
  border-style: solid;
  border-color: #07bb07;
  display: flex;
  justify-content: center;
  align-items: center;
  box-sizing: border-box;
}
.tki-tree-check-yes-b {
  width: 12px;
  height: 12px;
  border-top-left-radius: 20%;
  border-top-right-radius: 20%;
  border-bottom-right-radius: 20%;
  border-bottom-left-radius: 20%;
  background-color: #07bb07;
}
.tki-tree-check .radio {
  border-top-left-radius: 50%;
  border-top-right-radius: 50%;
  border-bottom-right-radius: 50%;
  border-bottom-left-radius: 50%;
}
.tki-tree-check .radio .tki-tree-check-yes-b {
  border-top-left-radius: 50%;
  border-top-right-radius: 50%;
  border-bottom-right-radius: 50%;
  border-bottom-left-radius: 50%;
}
.hover-c {
  opacity: 0.6;
}
components/tabs/Tabs.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
<template>
  <u-tabs :activeStyle="activeStyle" :list="tabs" @change="(tab) => $emit('change', tab)"></u-tabs>
</template>
<script>
export default {
  props: {
    tabs: Array
  },
  data () {
    return {
      activeStyle: {
        color: '#303133',
        fontSize: '20px',
        fontWeight: 'bold',
        transform: 'scale(1.05)'
      }
    }
  }
}
</script>
config/environment.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
const environment = {
    // å¼€å‘环境配置
    development: {
        // æœ¬åœ°éƒ¨ç½²çš„后端
        // baseURL: 'http://localhost:8080',
        // ç›´æŽ¥ä½¿ç”¨çº¿ä¸ŠåŽç«¯
        baseURL: 'http://vue.ruoyi.vip/prod-api'
    },
    // ç”Ÿäº§çŽ¯å¢ƒé…ç½®
    production: {
        baseURL: 'http://vue.ruoyi.vip/prod-api' // å‘布时需要修改为后端实际地址
    }
}
module.exports = {
  environment: environment[process.env.NODE_ENV]
}
config/http.interceptor.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
const { environment } = require('./environment.js')
import { ACCESS_TOKEN } from '@/store/mutation-types'
import storage from '@/utils/storage';
// æ­¤vm参数为页面的实例,可以通过它引用vuex中的变量
module.exports = (vm) => {
  // åˆå§‹åŒ–请求配置
  uni.$u.http.setConfig((config) => {
    /* config ä¸ºé»˜è®¤å…¨å±€é…ç½®ï¼Œè¯·æ±‚地址判断*/
      /* #ifdef H5 */
      if (process.env.NODE_ENV === 'production') {
          config.baseURL = environment.baseURL; /* æ ¹åŸŸå */
      } else {
      // å¼€å‘模式则使用代理方式,见vue.config.js配置
          config.baseURL = '/'; /* æ ¹åŸŸå */
      }
      /* #endif */
      /* #ifndef H5 */
      config.baseURL = environment.baseURL; /* æ ¹åŸŸå */
      /* #endif */
    return config
  })
  // è¯·æ±‚拦截
  uni.$u.http.interceptors.request.use((config) => { // å¯ä½¿ç”¨async await åšå¼‚步操作
    // åˆå§‹åŒ–请求拦截器时,会执行此方法,此时data为undefined,赋予默认{}
    config.data = config.data || {}
    // æ ¹æ®custom参数中配置的是否需要token,添加对应的请求头
    if(config?.custom?.auth) {
      // å¯ä»¥åœ¨æ­¤é€šè¿‡vm引用vuex中的变量,具体值在vm.$store.state中
      config.header.Authorization = 'Bearer ' + storage.get(ACCESS_TOKEN)
    }
    // æ ¹æ®custom参数中配置的是否需要显示loading
    if (config?.custom?.loading) {
      uni.showLoading({
        title: '加载中...',
        mask: true
      })
    }
    return config
  }, config => { // å¯ä½¿ç”¨async await åšå¼‚步操作
    return Promise.reject(config)
  })
    // å“åº”拦截
  uni.$u.http.interceptors.response.use((response) => { /* å¯¹å“åº”成功做点什么 å¯ä½¿ç”¨async await åšå¼‚步操作*/
    const data = response.data
    // å…³é—­loading
    uni.hideLoading();
    // è‡ªå®šä¹‰å‚æ•°
    const custom = response.config?.custom
    if (data.code !== 200) {
      // å¦‚果没有显式定义custom的toast参数为false的话,默认对报错进行toast弹出提示
      if (custom.toast !== false) {
        uni.$u.toast(data.msg)
      }
      // åˆ¤æ–­çŠ¶æ€ç 
      switch (data.code) {
        case 401: {
          uni.reLaunch({ url: '/' })
          return;
        }
      }
      // å¦‚果需要catch返回,则进行reject
      if (custom?.catch) {
        return Promise.reject(data)
      } else {
        // å¦åˆ™è¿”回一个pending中的promise,请求不会进入catch中
        return new Promise(() => { })
      }
    }
    return data === undefined ? {} : data
  }, (response) => {
    // å¯¹å“åº”错误做点什么 ï¼ˆstatusCode !== 200)
    return Promise.reject(response)
  })
}
config/request.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
const http = uni.$u.http;
/**
 * æ··å…¥é»˜è®¤ä¸ªæ€§åŒ–配置
 * @param {*} config
 * @returns
 */
function mixinCustom (config) {
  config.custom = Object.assign({
    auth: true,
    toast: true,
    catch: true,
    loading: true
  }, config.custom || {});
  return config;
}
/**
 * æ ¼å¼åŒ–get请求url参数,将对象解析为字符串
 * @param {*} url
 * @param {*} params
 * @returns
 */
function urlFormater (url, params) {
  if (params) {
    let paramList = [];
    for (let key in params) {
      paramList.push(key + '=' + params[key])
    }
    return url.indexOf('?') > -1 ? (url + '&' + paramList.join('&')) : (url + '?' + paramList.join('&'))
  }
  return url;
}
const request = {
  // post提交
  post (url, params, config = {}) {
    config = mixinCustom(config)
    return http.post(url, params, config);
  },
  // get提交
  get (url, params, config = {}) {
    config = mixinCustom(config)
    let path = urlFormater(url, params)
    return http.get(path, config);
  },
  // put提交
  put (url, params, config = {}) {
    config = mixinCustom(config)
    return http.put(url, params, config);
  },
  // delete提交
  delete (url, params, config = {}) {
    config = mixinCustom(config)
    return http.delete(url, params, config);
  },
};
export default request;
doc/image/index.png
Binary files differ
doc/image/logo.png
Binary files differ
doc/image/mallMenu.png
Binary files differ
doc/image/template1.png
Binary files differ
doc/image/template2.png
Binary files differ
index.html
@@ -1,8 +1,7 @@
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Ruoyi-App-Geek</title>
    <meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="UTF-8" />
    <script>
      var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
        CSS.supports('top: constant(a)'))
@@ -16,6 +15,6 @@
  </head>
  <body>
    <div id="app"><!--app-html--></div>
    <script type="module" src="./src/main.js"></script>
    <script type="module" src="/main.js"></script>
  </body>
</html>
main.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
import App from './App'
import Vue from 'vue'
import uView from 'uni_modules/uview-ui'
Vue.use(uView)
Vue.config.productionTip = false
App.mpType = 'app'
import store from '@/store';
const app = new Vue({
  store,
  ...App
})
// å¼•入请求封装,将app参数传递到配置中
require('@/config/http.interceptor.js')(app)
app.$mount()
manifest.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,76 @@
{
    "name" : "若依权限管理系统",
    "appid" : "__UNI__3D0DC28",
    "description" : "",
    "versionName" : "1.0.1",
    "versionCode" : "100",
    "transformPx" : false,
    /* 5+App特有相关 */
    "app-plus" : {
        "usingComponents" : true,
        "nvueStyleCompiler" : "uni-app",
        "compilerVersion" : 3,
        "splashscreen" : {
            "alwaysShowBeforeRender" : true,
            "waiting" : true,
            "autoclose" : true,
            "delay" : 0
        },
        /* æ¨¡å—配置 */
        "modules" : {},
        /* åº”用发布信息 */
        "distribute" : {
            /* android打包配置 */
            "android" : {
                "permissions" : [
                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                    "<uses-feature android:name=\"android.hardware.camera\"/>",
                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
                ]
            },
            /* ios打包配置 */
            "ios" : {},
            /* SDK配置 */
            "sdkConfigs" : {}
        }
    },
    /* å¿«åº”用特有相关 */
    "quickapp" : {},
    /* å°ç¨‹åºç‰¹æœ‰ç›¸å…³ */
    "mp-weixin" : {
        "appid" : "",
        "setting" : {
            "urlCheck" : false
        },
        "usingComponents" : true
    },
    "mp-alipay" : {
        "usingComponents" : true
    },
    "mp-baidu" : {
        "usingComponents" : true
    },
    "mp-toutiao" : {
        "usingComponents" : true
    },
    "uniStatistics" : {
        "enable" : false
    },
    "vueVersion" : "2",
    /* h5不能配置devServer属性,需要配置可修改vue.config.js文件 */
    "h5" : {
        "template" : "template.h5.html"
    }
}
package-lock.json
ÎļþÌ«´ó
package.json
@@ -1,99 +1,17 @@
{
  "name": "ruoyi-geek-app",
  "version": "1.0.0",
  "description": "若依Geek管理系统",
  "author": "Geek-XD",
  "license": "MIT",
  "homepage": "https://gitee.com/geek-xd",
  "repository": {
    "type": "git",
    "url": "https://gitee.com/geek-xd/ruoyi-geek-app.git"
  },
  "engines": {
    "node": "^18.0.0 || >=20.0.0"
  },
  "scripts": {
    "dev:app": "uni -p app",
    "dev:app-android": "uni -p app-android",
    "dev:app-ios": "uni -p app-ios",
    "dev:custom": "uni -p",
    "dev:h5": "uni",
    "dev:h5:ssr": "uni --ssr",
    "dev:mp-alipay": "uni -p mp-alipay",
    "dev:mp-baidu": "uni -p mp-baidu",
    "dev:mp-jd": "uni -p mp-jd",
    "dev:mp-kuaishou": "uni -p mp-kuaishou",
    "dev:mp-lark": "uni -p mp-lark",
    "dev:mp-qq": "uni -p mp-qq",
    "dev:mp-toutiao": "uni -p mp-toutiao",
    "dev:mp-weixin": "uni -p mp-weixin",
    "dev:quickapp-webview": "uni -p quickapp-webview",
    "dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
    "dev:quickapp-webview-union": "uni -p quickapp-webview-union",
    "build:app": "uni build -p app",
    "build:app-android": "uni build -p app-android",
    "build:app-ios": "uni build -p app-ios",
    "build:custom": "uni build -p",
    "build:h5": "uni build",
    "build:h5:ssr": "uni build --ssr",
    "build:mp-alipay": "uni build -p mp-alipay",
    "build:mp-baidu": "uni build -p mp-baidu",
    "build:mp-jd": "uni build -p mp-jd",
    "build:mp-kuaishou": "uni build -p mp-kuaishou",
    "build:mp-lark": "uni build -p mp-lark",
    "build:mp-qq": "uni build -p mp-qq",
    "build:mp-toutiao": "uni build -p mp-toutiao",
    "build:mp-weixin": "uni build -p mp-weixin",
    "build:quickapp-webview": "uni build -p quickapp-webview",
    "build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
    "build:quickapp-webview-union": "uni build -p quickapp-webview-union",
    "type-check": "vue-tsc --noEmit",
    "clean:linux": "rm -rf dist || rm -rf node_modules",
    "clean:windows": "rd /s /q dist || rd /s /q node_modules"
  },
  "dependencies": {
    "@dcloudio/uni-app": "3.0.0-4060420250429001",
    "@dcloudio/uni-app-harmony": "3.0.0-4060420250429001",
    "@dcloudio/uni-app-plus": "3.0.0-4060420250429001",
    "@dcloudio/uni-components": "3.0.0-4060420250429001",
    "@dcloudio/uni-h5": "3.0.0-4060420250429001",
    "@dcloudio/uni-mp-alipay": "3.0.0-4060420250429001",
    "@dcloudio/uni-mp-baidu": "3.0.0-4060420250429001",
    "@dcloudio/uni-mp-harmony": "3.0.0-4060420250429001",
    "@dcloudio/uni-mp-jd": "3.0.0-4060420250429001",
    "@dcloudio/uni-mp-kuaishou": "3.0.0-4060420250429001",
    "@dcloudio/uni-mp-lark": "3.0.0-4060420250429001",
    "@dcloudio/uni-mp-qq": "3.0.0-4060420250429001",
    "@dcloudio/uni-mp-toutiao": "3.0.0-4060420250429001",
    "@dcloudio/uni-mp-weixin": "3.0.0-4060420250429001",
    "@dcloudio/uni-mp-xhs": "3.0.0-4060420250429001",
    "@dcloudio/uni-quickapp-webview": "3.0.0-4060420250429001",
    "@dcloudio/uvm": "^0.3.1",
    "@jridgewell/sourcemap-codec": "^1.5.0",
    "@qiun/wx-ucharts": "2.5.0-20230101",
    "@uview-plus/types": "^3.2.5",
    "clipboard": "^2.0.11",
    "dayjs": "^1.11.13",
    "mqtt": "4.1.0",
    "pinia": "2.2.2",
    "tslib": "^2.7.0",
    "uview-plus": "^3.3.32",
    "vue": "3.4.21",
    "vue-i18n": "^9.14.2"
  },
  "devDependencies": {
    "@dcloudio/types": "^3.4.14",
    "@dcloudio/uni-automator": "3.0.0-4060420250429001",
    "@dcloudio/uni-cli-shared": "3.0.0-4060420250429001",
    "@dcloudio/uni-stacktracey": "3.0.0-4060420250429001",
    "@dcloudio/vite-plugin-uni": "3.0.0-4060420250429001",
    "@vue/runtime-core": "^3.5.12",
    "@vue/tsconfig": "^0.5.1",
    "less": "^4.2.0",
    "sass": "^1.78.0",
    "sass-loader": "^16.0.1",
    "typescript": "^5.6.2",
    "vite": "5.2.8",
    "vue-tsc": "2.1.6"
  }
}
    "id": "qian-tree",
    "name": "树形选择器增强版,支持多选、单选、父级选中子级自动选中、懒加载",
    "version": "1.0.1",
    "description": "树形选择器增强版,支持多选、单选、父级选择、父子级选中/取消联动、懒加载.",
    "keywords": [
        "tree",
        "树",
        "多选"
    ],
    "dcloudext": {
        "category": [
            "前端组件",
            "通用组件"
        ]
    }
}
pages.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,122 @@
{
    "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
        {
            "path": "pages/login/index",
            "style": {
                "navigationBarTitleText": "登录",
                "navigationStyle": "custom"
            }
        },
        {
            "path": "pages/index/index",
            "style": {
                "navigationBarTitleText": "首页",
                "navigationStyle": "custom"
            }
        },
        {
            "path": "pages/work/index",
            "style": {
                "navigationBarTitleText": "工作台",
                "navigationStyle": "custom"
            }
        },
        {
            "path": "pages/work/user/list",
            "style": {
                "navigationBarTitleText": "用户管理",
                "navigationStyle": "custom"
            }
        },
        {
            "path": "pages/work/user/edit",
            "style": {
                "navigationBarTitleText": "用户详情",
                "navigationStyle": "custom"
            }
        },
        {
            "path": "pages/work/notice/list",
            "style": {
                "navigationBarTitleText": "通知公告",
                "navigationStyle": "custom"
            }
        },
        {
            "path": "pages/work/notice/manage",
            "style": {
                "navigationBarTitleText": "公告管理",
                "navigationStyle": "custom"
            }
        },
        {
            "path": "pages/work/notice/detail",
            "style": {
                "navigationBarTitleText": "公告详情",
                "navigationStyle": "custom"
            }
        },
        {
            "path": "pages/work/notice/edit",
            "style": {
                "navigationBarTitleText": "公告详情",
                "navigationStyle": "custom"
            }
        },
        {
            "path": "pages/center/index",
            "style": {
                "navigationBarTitleText": "我的",
                "navigationStyle": "custom"
            }
        },
        {
            "path": "pages/center/profile",
            "style": {
                "navigationBarTitleText": "个人资料",
                "navigationStyle": "custom"
            }
        },
        {
            "path": "pages/center/log",
            "style": {
                "navigationBarTitleText": "操作日志",
                "navigationStyle": "custom"
            }
        }
    ],
    "tabBar": {
        "color": "#909399",
        "selectedColor": "#000000",
        "borderStyle": "black",
        "backgroundColor": "#ffffff",
        "list": [{
            "pagePath": "pages/index/index",
            "iconPath": "static/img/tabbar/home.png",
            "selectedIconPath": "static/img/tabbar/home_art.png",
            "text": "首页"
        }, {
            "pagePath": "pages/work/index",
            "iconPath": "static/img/tabbar/center.png",
            "selectedIconPath": "static/img/tabbar/center_art.png",
            "text": "工作台"
        }, {
            "pagePath": "pages/center/index",
            "iconPath": "static/img/tabbar/user.png",
            "selectedIconPath": "static/img/tabbar/user_art.png",
            "text": "我的"
        }]
    },
    "globalStyle": {
        "navigationBarTextStyle": "black",
        "navigationBarTitleText": "uni-app",
        "navigationBarBackgroundColor": "#F8F8F8",
        "backgroundColor": "#F8F8F8",
    "app-plus": {
      "softinputMode": "adjustResize"
    }
    },
    "easycom": {
        "^u-(.*)": "@/uni_modules/uview-ui/components/u-$1/u-$1.vue"
    }
}
pages/center/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,137 @@
<template>
    <view>
    <Navbar :hideBtn="true" bgColor="#f3f4f6"></Navbar>
    <view class="profile-top">
      <view class="user-info">
        <view>
          <view class="user-info--name">{{ user.nickName }}</view>
          <text class="user-info--account">{{ user.email || user.phonenumber || user.userName }}</text>
        </view>
        <view>
          <u-avatar src="/static/img/avatar.png" size="120rpx"></u-avatar>
        </view>
      </view>
      <view style="padding: 40rpx 40rpx 0 40rpx;">
        <view class="profile-rule">
          <u-row>
            <u-col span="8">
              <view style="color: white; font-size: 20px;">{{ user.dept ? user.dept.deptName : '未知部门' }}</view>
            </u-col>
            <u-col span="4">
              <u-button icon="question-circle" text="问题反馈" style="height: 36px;"></u-button>
            </u-col>
          </u-row>
        </view>
      </view>
    </view>
    <view style="padding: 40rpx; background-color: #fff;">
      <u-grid>
        <u-grid-item @click="navigateTo('/pages/center/profile')">
          <u-icon name="account-fill" color="#2979ff" size="60rpx"></u-icon>
          <text class="btn-text">个人资料</text>
        </u-grid-item>
        <u-grid-item @click="resetPassword = true">
          <u-icon name="lock-fill" color="#2979ff" size="60rpx"></u-icon>
          <text class="btn-text">修改密码</text>
        </u-grid-item>
        <u-grid-item @click="navigateTo('/pages/center/log')">
          <u-icon name="coupon-fill" color="#2979ff" size="60rpx"></u-icon>
          <text class="btn-text">操作日志</text>
        </u-grid-item>
      </u-grid>
    </view>
    <view style="padding: 40rpx; margin-top: 300rpx;">
      <u-row gutter="32">
        <u-col span="6">
          <u-button icon="phone" text="联系我们" plain></u-button>
        </u-col>
        <u-col span="6">
              <u-button icon="reload" text="退出" type="error" @click="logout"></u-button>
        </u-col>
      </u-row>
    </view>
    <Password :show="resetPassword" @close="resetPassword = false"></Password>
    </view>
</template>
<script>
import Navbar from '@/components/navbar/Navbar'
import Password from './password.vue'
export default {
  components: {
    Navbar,
    Password,
  },
  data () {
    return {
      user: {},
      resetPassword: false
    }
  },
  created () {
    this.getInfo()
  },
  methods: {
    getInfo () {
      const app = this
      app.$store.dispatch('Info').then(res => {
        app.user = res.user
      })
    },
    navigateTo (url) {
      uni.navigateTo({ url: url })
    },
    logout () {
      const app = this
      app.$store.dispatch('Logout').then(res => {
        uni.reLaunch({
          url: '/pages/login/index'
        })
      })
    }
  }
}
</script>
<style lang="scss">
.profile-top {
  background-color: #f3f4f6;
  padding-top: 50rpx;
}
.profile-rule {
  height: 140rpx;
  line-height: 140rpx;
  padding: 0px 40rpx;
  background-color: $u-main-color;
  border-radius: 16px 16px 0 0;
  box-shadow: 0px 16px 26px rgba(0, 0, 0, .8);
}
.btn-text {
  font-size: 28rpx;
  color: #606266;
}
.user-info {
  display: flex;
  justify-content: space-between;
  padding: 40rpx;
  max-width: 100%;
  color: #303133;
  &--name {
    font-size: 56rpx;
    font-weight: bold;
    width: 100%
  }
  &--account {
    font-size: 26rpx;
    color: #909399;
  }
}
</style>
pages/center/log.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
<template>
  <view style="padding: 40rpx;">
    <view>
      <u-search placeholder="请输入查询内容" v-model="params.title" height="60rpx" @search="searchData" @custom="searchData"></u-search>
    </view>
    <view>
      <u-list v-if="logList.length > 0" @scrolltolower="scrolltolower">
        <u-list-item v-for="(item, index) in logList" :key="index" class="log-item">
          <view><text style="color: #606266;">操作内容:</text><text>{{item.title}}</text></view>
          <view><text style="color: #606266;">请求地址:</text><text>{{item.operUrl}}</text></view>
          <view><text style="color: #606266;">操作地址:</text><text>{{item.operLocation}}</text></view>
          <view><text style="color: #606266;">操作时间:</text><text>{{item.operTime}}</text></view>
        </u-list-item>
      </u-list>
      <u-empty v-else></u-empty>
    </view>
  </view>
</template>
<script>
import * as LogApi from '@/api/center/log'
export default {
  data () {
    return {
      params: {
        pageNum: 0,
        pageSize: 10,
        title: ''
      },
      logList: []
    }
  },
  created () {
    this.loadData();
  },
  methods: {
    // åŠ è½½æ—¥å¿—åˆ—è¡¨æ•°æ®
    loadData () {
      const app = this
      // é¦–先获取当前登录账号信息
      app.$store.dispatch('Info').then(res => {
        app.params.pageNum += 1
        if (res.user) {
          // åªæŸ¥è¯¢å½“前用户的操作日志
          app.params.operName = res.user.userName
        }
        LogApi.operLog(app.params).then(res => {
          app.logList = app.logList.concat(res.rows);
        })
      })
    },
    // æŸ¥è¯¢æŒ‰é’®åŠ¨ä½œ
    searchData () {
      this.params.pageNum = 0
      this.logList = []
      this.loadData();
    },
    // æ»šåŠ¨åˆ†é¡µåŠ è½½æ•°æ®
    scrolltolower () {
      this.loadData();
    }
  }
}
</script>
<style lang="scss" scoped>
.log-item {
  padding: 20rpx 0;
  border-bottom: 0.5px solid #ccc;
}
</style>
pages/center/password.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
<template>
  <u-modal :show="show" title="修改密码" showCancelButton @confirm="confirm" @cancel="cancel">
    <view class="slot-content">
      <u--form :model="pwd" ref="uForm" labelWidth="160rpx" labelAlign="left">
        <u-form-item label="原密码" prop="origiPwd" class="u-border-bottom">
          <u--input v-model="pwd.origiPwd" type="password" placeholder="请输入原密码" border="none"></u--input>
        </u-form-item>
        <u-form-item label="新密码" prop="newPwd" class="u-border-bottom">
          <u--input v-model="pwd.newPwd" type="password" placeholder="请输入新密码" border="none"></u--input>
        </u-form-item>
        <u-form-item label="确认密码" prop="confirmPwd" class="u-border-bottom">
          <u--input v-model="pwd.confirmPwd" type="password" placeholder="请输入确认密码" border="none"></u--input>
        </u-form-item>
      </u--form>
    </view>
  </u-modal>
</template>
<script>
export default {
  props: {
    show: Boolean
  },
  data () {
    return {
      pwd: {
        origiPwd: '',
        newPwd: '',
        confirmPwd: ''
      }
    }
  },
  methods: {
    confirm () {
      this.$emit('close')
    },
    cancel () {
      this.$emit('close')
    }
  }
}
</script>
<style lang="scss" scoped>
</style>
pages/center/profile.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,80 @@
<template>
  <view>
    <Navbar :hideBtn="false" bgColor="#f3f4f6"></Navbar>
    <view style="background-color: #2b85e4; padding: 40rpx;">
      <view style="width: 140rpx; height: 140rpx; border: 1px solid #fff; border-radius: 50%; margin: 0 auto;">
        <u-avatar src="/static/img/avatar.png" size="120rpx" style="margin: 10rpx;"></u-avatar>
      </view>
    </view>
    <view style="padding: 40rpx;">
      <u--form :model="userInfo" ref="uForm" labelWidth="160rpx" labelAlign="left">
        <u-form-item label="姓名" prop="nickName" class="u-border-bottom">
          <u--input
            placeholder="请输入内容"
            border="none"
            v-model="userInfo.nickName"
          ></u--input>
        </u-form-item>
        <u-form-item label="性别" prop="sex" class="u-border-bottom">
          <u-radio-group v-model="userInfo.sex" size="36rpx">
            <u-radio shape="circle" label="男" name="1" labelSize="32rpx"></u-radio>
            <u-radio shape="circle" label="女" name="2" labelSize="32rpx" style="margin-left: 36rpx;"></u-radio>
          </u-radio-group>
        </u-form-item>
        <u-form-item label="手机号码" prop="phonenumber" class="u-border-bottom">
          <u--input
            placeholder="请输入内容"
            border="none"
            v-model="userInfo.phonenumber"
          ></u--input>
        </u-form-item>
        <u-form-item label="邮箱" prop="email" class="u-border-bottom">
          <u--input
            placeholder="请输入内容"
            border="none"
            v-model="userInfo.email"
          ></u--input>
        </u-form-item>
      </u--form>
    </view>
    <view style="padding: 40rpx;">
      <u-row gutter="32">
        <u-col span="6">
          <u-button icon="arrow-left" text="返回" plain @click="goBack()"></u-button>
        </u-col>
        <u-col span="6">
              <u-button icon="checkmark-circle" text="保存" type="primary"></u-button>
        </u-col>
      </u-row>
    </view>
  </view>
</template>
<script>
import Navbar from '@/components/navbar/Navbar'
export default {
  components: {
    Navbar,
  },
  data () {
    return {
      userInfo: {
        nickName: '若依',
        sex: '1',
        email: 'fastbuild@163.com',
        phonenumber: '18888888888'
      }
    }
  },
  methods: {
    goBack () {
      uni.navigateBack({ delta: 1});
    }
  }
}
</script>
<style lang="sass" scoped>
</style>
pages/index/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,202 @@
<template>
    <view class="index-content">
    <Navbar :hideBtn="true" title="首页" bgColor="#fff" :h5Show="false" :fixed="false"></Navbar>
        <view class="index-block">
      <view class="index-block-title">运行统计</view>
      <u-row gutter="16">
        <u-col span="4">
          <view class="item-tj item-tj-frist">
            <view style="padding: 16rpx; height: 100%; position: relative;">
              <view style="display: flex; color: white;">
                <u-icon name="photo" color="#fff"></u-icon>
                <text>在线人数</text>
              </view>
              <view style="position: absolute; bottom: 48rpx; right: 16rpx;">
                <u-count-to :startVal="0" :endVal="149" :duration="1500" color="#fff" separator=","></u-count-to>
              </view>
            </view>
          </view>
        </u-col>
        <u-col span="4">
          <view class="item-tj item-tj-second">
            <view style="padding: 16rpx; height: 100%; position: relative;">
              <view style="display: flex; color: white;">
                <u-icon name="photo" color="#fff"></u-icon>
                <text>今日新增</text>
              </view>
              <view style="position: absolute; bottom: 48rpx; right: 16rpx;">
                <u-count-to :startVal="1" :endVal="2349" :duration="1500" color="#fff" separator=","></u-count-to>
              </view>
            </view>
          </view>
        </u-col>
        <u-col span="4">
          <view class="item-tj item-tj-thrid">
            <view style="padding: 16rpx; height: 100%; position: relative;">
              <view style="display: flex; color: white;">
                <u-icon name="photo" color="#fff"></u-icon>
                <text>总人数</text>
              </view>
              <view style="position: absolute; bottom: 48rpx; right: 16rpx;">
                <u-count-to :startVal="1" :endVal="1249350" :duration="1500" color="#fff" separator=","></u-count-to>
              </view>
            </view>
          </view>
        </u-col>
      </u-row>
    </view>
    <view class="index-block">
      <view class="index-block-title">近7天访问量统计</view>
      <view>
        <qiun-data-charts type="line" canvasId="finance_a" :canvas2d="isCanvas2d" :resshow="delayload"
                        :opts="{xAxis:{itemCount:12,disableGrid:true},yAxis:{disableGrid:true,data:[{disabled:true}]}}"
                        :chartData="historyData" />
      </view>
      <view class="index-block-title">访问量统计</view>
      <view>
        <qiun-data-charts type="bar" canvasId="finance_b" :canvas2d="isCanvas2d" :resshow="delayload"
                        :opts="{xAxis:{disabled: true,disableGrid:true},extra:{bar:{barBorderCircle:true,width:20}},legend:{show:false}}"
                        :chartData="historyData" />
      </view>
    </view>
    <view class="index-block">
      <view class="index-block-title">数据总览</view>
      <view class="detail_list">
        <view v-for="(item,index) in detail_list" :key="index" class="detail_item">
          <view>
            <view class="font-middle">{{item.date}}</view>
            <view class="font-small">{{item.time}}</view>
          </view>
          <view class="icon"><li :class="['iconfont',item.type == 'income'?'icon-income':'icon-expend']"></li></view>
          <view class="right_content">
            <view class="money">{{item.type == 'income'?'+':'-'}}{{item.money}}</view>
            <view class="text-gray font-middle">{{item.desc}}</view>
          </view>
        </view>
      </view>
    </view>
    </view>
</template>
<script>
import Navbar from '@/components/navbar/Navbar'
let _now = new Date();
let now_time = {};
now_time.year = _now.getFullYear()
now_time.month = _now.getMonth() + 1
now_time.day = _now.getDay()
export default {
  components: {
    Navbar,
  },
  data () {
    return {
      isCanvas2d: true,
      delayload: false,
      historyData: {
        "categories": [
          "1月",
          "2月",
          "2月",
          "4月",
          "5月"
        ],
        "series": [
          {
            "name": "收入情况",
            "data": [1601,1840.5,1900,1760,1500.85],
            "type": "line",
            "style": "curve",
            "color": "#4ECDB6",
            "unit":""
          }
        ],
        "yAxis":[
          {"calibration":true,"position":"left","title":"单位/元","titleFontSize":12,"unit":"","tofix":0,"min":0,"disableGrid":true}
        ]
      },
      detail_list:[
        {date:now_time.month + "-01",time:"11:01","type":"extend",money:"10.00",desc:"银行卡转出"},
        {date:now_time.month + "-01",time:"13:45","type":"income",money:"18.00",desc:"银行卡收入"},
        {date:now_time.month + "-02",time:"06:21","type":"extend",money:"123.45",desc:"信用卡转出"},
        {date:now_time.month + "-03",time:"07:38","type":"income",money:"23.00",desc:"银行卡收入"},
        {date:now_time.month + "-08",time:"16:28","type":"extend",money:"23.56",desc:"信用卡转出"},
        {date:now_time.month + "-09",time:"15:25","type":"income",money:"850.12",desc:"银行卡收入"},
        {date:now_time.month + "-09",time:"18:52","type":"income",money:"1.88",desc:"银行卡收入"},
        {date:now_time.month + "-11",time:"21:12","type":"extend",money:"220.21",desc:"银行卡转出"},
        {date:now_time.month + "-12",time:"13:08","type":"income",money:"32.28",desc:"银行卡收入"},
        {date:now_time.month + "-12",time:"12:41","type":"extend",money:"122.12",desc:"信用卡转出"},
        {date:now_time.month + "-13",time:"17:21","type":"income",money:"10.00",desc:"银行卡收入"},
      ]
    }
  }
}
</script>
<style lang="scss">
.index-content {
  background-color: #f3f4f6;
  min-height: 100vh;
}
.index-block {
  padding: 40rpx;
  background-color: #fff;
}
.index-block-title {
  font-size: 40rpx;
  font-weight: bold;
  padding: 0 0 40rpx 0;
}
.item-tj {
  width: 100%;
  height: 160rpx;
  border-radius: 16rpx;
  &-frist {
    background-color: rgba($color: #2979ff, $alpha: 0.8);
    // background-image: url('/static/img/bg/qb.png');
  }
  &-second {
    background-color: rgba($color: #303133, $alpha: 0.8);
    // background-image: url('/static/img/bg/qb.png');
  }
  &-thrid {
    background-color: rgba($color: #19be6b, $alpha: 0.8);
    // background-image: url('/static/img/bg/qb.png');
  }
}
.detail_list{
  height: 700rpx;
  overflow: auto;
  color: #9E9E9E;
  .detail_item{
    display: flex;
    margin: 20rpx 0;
    align-items: center;
    .icon{
      width: 30%;
      text-align: center;
      li{
        font-size: 80rpx;
      }
    }
    .right_content{
      width: 50%;
      text-align: center;
    }
    .icon-income{
      color:#4AABF9;
    }
    .icon-expend{
      color: #E45521;
    }
    .money{
      color: #000;
    }
  }
}
</style>
pages/login/index.scss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
.t-login {
    width: 650rpx;
    margin: 0 auto;
    font-size: 28rpx;
    color: #000;
}
/deep/ .login-form-item .u-input {
  padding: 0 10px 0 62px;
    height: 32px;
    line-height: 32px;
    margin-bottom: 26px;
    background: #f8f7fc;
    border: 1px solid #e9e9e9;
    font-size: 14px;
    border-radius: 26px;
}
.t-captcha {
    display: flex;
  flex-wrap: wrap;
  justify-content: space-evenly;
}
.t-captcha-img {
  margin-left: 16px;
    width: 102px;
    height: 44px;
}
.img-a {
    position: absolute;
    width: 100%;
    top: -150rpx;
    right: 0;
    z-index: -999;
}
.img-b {
    position: absolute;
    width: 50%;
    bottom: 0;
    left: -50rpx;
    z-index: -999;
}
.t-login button {
    font-size: 28rpx;
    background: #5677fc;
    color: #fff;
    height: 90rpx;
    line-height: 90rpx;
    border-radius: 50rpx;
    box-shadow: 0 5px 7px 0 rgba(86, 119, 252, 0.2);
}
.t-login .t-b {
    text-align: left;
    font-size: 56rpx;
    color: #000;
    padding: 300rpx 0 20rpx 0;
    font-weight: bold;
}
.t-login .t-b2 {
    text-align: left;
    font-size: 32rpx;
    color: #aaaaaa;
    padding: 0rpx 0 60rpx 0;
}
.t-login .uni-input-placeholder {
    color: #000 !important;
}
pages/login/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,115 @@
<!-- è“è‰²ç®€æ´ç™»å½•页面 -->
<template>
    <view class="t-login">
        <!-- é¡µé¢è£…饰图片 -->
        <image class="img-a" src="/static/img/b-1.png"></image>
        <image class="img-b" src="/static/img/b-2.png"></image>
        <!-- æ ‡é¢˜ -->
        <view class="t-b">{{ title }}</view>
        <view class="t-b2">{{ subTitle }}</view>
        <form class="cl">
            <!-- ç™»å½•账号 -->
            <view class="login-form-item">
                <u-input v-model="username" placeholder="请输入登录用户名" maxlength="30">
                    <u-icon slot="prefix" name="account" size="35px"></u-icon>
                </u-input>
            </view>
            <!-- ç™»å½•密码 -->
            <view class="login-form-item">
                <u-input v-model="password" type="password" placeholder="请输入登录密码" maxlength="16">
                    <u-icon slot="prefix" name="lock" size="35px"></u-icon>
                </u-input>
            </view>
            <!-- å›¾å½¢éªŒè¯ç  -->
            <view class="login-form-item t-captcha">
                <u-input v-model="captchaCode" type="number" placeholder="请输入验证码" maxlength="4">
                    <u-icon slot="prefix" name="fingerprint" size="35px"></u-icon>
                </u-input>
                <image :src="captcha" @click="getCaptcha" class="t-captcha-img"></image>
            </view>
            <button @tap="login()">登 å½•</button>
        </form>
    </view>
</template>
<script>
import * as CaptchaApi from '@/api/captcha'
import { isEmpty } from '@/utils/verify.js'
export default {
    data() {
        return {
            title: '若依权限管理系统',
            subTitle: '欢迎回来,开始工作吧!',
            // å›¾å½¢éªŒè¯ç ä¿¡æ¯
            captcha: null,
            // ç™»å½•账号
            username: 'admin',
            // å¯†ç 
            password: 'admin123',
            // å›¾å½¢éªŒè¯ç 
            captchaCode: '',
            uuid: ''
        };
    },
    created() {
      // èŽ·å–å›¾å½¢éªŒè¯ç 
      this.getCaptcha()
    },
    methods: {
        // èŽ·å–å›¾å½¢éªŒè¯ç 
        getCaptcha() {
            const app = this
            CaptchaApi.image().then(result => {
                app.captcha = 'data:image/gif;base64,' + result.img
                app.uuid = result.uuid
            })
        },
        // éªŒè¯è¡¨å•内容
        validItem() {
            const app = this
            if (isEmpty(app.username)) {
                uni.$u.toast('请输入登录用户名')
                return false
            }
            if (isEmpty(app.password)) {
                uni.$u.toast('请输入登录密码')
                return false
            }
            if (isEmpty(app.captchaCode)) {
                uni.$u.toast('请输入验证码')
                return false
            }
            return true
        },
        // ç¡®è®¤ç™»å½•
        login() {
      const app = this
            let valid = app.validItem();
            if (valid) {
                app.isLoading = true
                app.$store.dispatch('Login', {
                  username: app.username,
                  password: app.password,
                  code: app.captchaCode,
                  uuid: app.uuid
                }).then(result => {
                    uni.switchTab({
                        url: '/pages/index/index',
                        fail(err) {
                            console.log(err)
                        }
                    })
                })
                .catch(err => {
                    app.captchaCode = ''
                    app.getCaptcha()
                })
                .finally(() => app.isLoading = false)
            }
        },
    }
};
</script>
<style lang="scss" scoped>
@import 'index.scss';
</style>
pages/work/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,133 @@
<template>
    <view>
    <Navbar title="工作台" bgColor="#fff" :hideBtn="true" :h5Show="false"></Navbar>
    <view class="mobile-item-container">
      <view style="font-size: 40rpx; font-weight: bold; padding: 0 0 40rpx 0;">待处理</view>
      <u-grid col="3">
        <u-grid-item @click="navigateTo('/pages/work/notice/list')">
          <view style="position: relative;">
            <u-icon name="chat" color="#2979ff" size="60rpx"></u-icon>
            <u-badge style="position: absolute; top: -5rpx; right: -10rpx;" type="error" numberType="overflow" max="99" v-model="todo.notice"></u-badge>
          </view>
          <text class="btn-text">通知公告</text>
        </u-grid-item>
        <u-grid-item>
          <view style="position: relative;">
            <u-icon name="list-dot" color="#2979ff" size="60rpx"></u-icon>
            <u-badge style="position: absolute; top: -5rpx; right: -10rpx;" type="error" numberType="overflow" max="99" v-model="todo.task"></u-badge>
          </view>
          <text class="btn-text">待办任务</text>
        </u-grid-item>
        <u-grid-item>
          <view style="position: relative;">
            <u-icon name="warning" color="#2979ff" size="60rpx"></u-icon>
            <u-badge style="position: absolute; top: -5rpx; right: -10rpx;" type="error" numberType="overflow" max="99" v-model="todo.error"></u-badge>
          </view>
          <text class="btn-text">异常信息</text>
        </u-grid-item>
      </u-grid>
    </view>
    <Gap />
    <view class="mobile-item-container">
      <view style="font-size: 40rpx; font-weight: bold; padding: 0 0 40rpx 0;">统计报表</view>
      <u-grid col="3">
        <u-grid-item>
          <u-icon name="star" color="#2979ff" size="60rpx"></u-icon>
          <text class="btn-text">访问量统计</text>
        </u-grid-item>
        <u-grid-item>
          <u-icon name="share-square" color="#2979ff" size="60rpx"></u-icon>
          <text class="btn-text">分享统计</text>
        </u-grid-item>
      </u-grid>
    </view>
    <Gap />
    <view style="padding: 40rpx; background-color: #fff; margin-top: 40rpx; min-height: 600rpx;">
      <u-tabs
        :activeStyle="{
          color: '#303133',
          fontSize: '40rpx',
          fontWeight: 'bold',
          transform: 'scale(1.05)'
        }"
        :inactiveStyle="{
          color: '#606266',
          fontSize: '36rpx',
          transform: 'scale(1)'
        }"
        :list="tabs"
        @change="tabChange">
      </u-tabs>
      <view v-if="activeKey == 'work'" style="padding: 40rpx 0;">
        <u-grid col="3">
          <u-grid-item @click="navigateTo('/pages/work/notice/manage')">
            <u-icon name="edit-pen" color="#2979ff" size="60rpx"></u-icon>
            <text class="btn-text">公告管理</text>
          </u-grid-item>
          <u-grid-item @click="navigateTo('/pages/work/user/list')">
            <u-icon name="plus-people-fill" color="#2979ff" size="60rpx"></u-icon>
            <text class="btn-text">用户管理</text>
          </u-grid-item>
          <u-grid-item>
            <u-icon name="tags" color="#2979ff" size="60rpx"></u-icon>
            <text class="btn-text">部门管理</text>
          </u-grid-item>
        </u-grid>
        <u-grid col="3" style="margin-top: 40rpx;">
          <u-grid-item>
            <u-icon name="bookmark" color="#2979ff" size="60rpx"></u-icon>
            <text class="btn-text">岗位管理</text>
          </u-grid-item>
        </u-grid>
      </view>
      <view v-if="activeKey == 'plugin'" style="padding: 40rpx 0;">
        <u-grid col="3">
          <u-grid-item>
            <u-icon name="order" color="#2979ff" size="60rpx"></u-icon>
            <text class="btn-text">表单样例</text>
          </u-grid-item>
        </u-grid>
      </view>
    </view>
    </view>
</template>
<script>
import Navbar from '@/components/navbar/Navbar'
import Gap from '@/components/gap/Gap'
export default {
  components: {
    Gap,
    Navbar,
  },
  data () {
    return {
      activeKey: 'work',
      tabs: [{
        name: '日常工作',
        key: 'work'
      }, {
        name: '插件',
        key: 'plugin'
      }],
      todo: {
        notice: 2,
        task: 5,
        error: 1
      }
    }
  },
  methods: {
    tabChange (item) {
      this.activeKey = item.key;
    },
    navigateTo (url) {
      uni.navigateTo({ url: url })
    }
  }
}
</script>
<style lang="scss">
</style>
pages/work/notice/detail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
<template>
  <view class="mobile-item-container">
    <Navbar title="公告详情" bgColor="#fff" :h5Show="false"></Navbar>
    <view style="font-size: 40rpx; font-weight: bold;">{{notice.noticeTitle}}</view>
    <view style="display: flex; font-size: 12px; color: #909399;">
      <u-icon name="clock" size="12"></u-icon>
      <text>{{notice.createTime}}</text>
      <u-icon name="account" size="12"></u-icon>
      <text>{{notice.remark}}</text>
    </view>
    <view style="margin-top: 40rpx;">
      <u-parse :content="notice.noticeContent"></u-parse>
    </view>
  </view>
</template>
<script>
import * as NoticeApi from '@/api/work/notice'
import Navbar from '@/components/navbar/Navbar'
export default {
  components: {
    Navbar,
  },
  data () {
    return {
      noticeId: undefined,
      notice: {}
    }
  },
  onLoad (params) {
    this.noticeId = params.id
    this.loadData()
  },
  methods: {
    loadData () {
      const app = this
      NoticeApi.noticeById(this.noticeId).then(res => {
        app.notice = res.data
      })
    }
  }
}
</script>
<style lang="scss" scoped>
</style>
pages/work/notice/edit.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,110 @@
<template>
  <view class="mobile-item-container">
    <Navbar :title="noticeId ? '修改公告' : '新增公告'" bgColor="#fff" :h5Show="false"></Navbar>
    <u--form ref="noticeForm" :model="notice" :rules="rules" labelPosition="left">
      <u-form-item label="标题" prop="noticeTitle" borderBottom>
        <u--textarea v-model="notice.noticeTitle" placeholder="请输入标题" :count="false" :maxlength="30" :autoHeight="true" confirmType="done"></u--textarea>
      </u-form-item>
      <u-form-item label="类型" prop="noticeType" borderBottom @click="actionShow = true;">
        <u--input v-model="noticeTypeName" disabled disabledColor="#ffffff" placeholder="请选择类型" border="none"></u--input>
                <u-icon slot="right" name="arrow-right"></u-icon>
      </u-form-item>
      <u-form-item label="状态" prop="status" borderBottom>
        <u-radio-group v-model="notice.status">
          <u-radio shape="circle" label="正常" name="0" checked></u-radio>
          <u-radio shape="circle" label="关闭" name="1"></u-radio>
        </u-radio-group>
      </u-form-item>
      <u-form-item label="正文" prop="noticeContent">
        <u--textarea v-model="notice.noticeContent" placeholder="请输入标题" :count="true" :maxlength="600" confirmType="done"></u--textarea>
      </u-form-item>
    </u--form>
    <u-action-sheet :actions="actions" :title="actionTitle" :show="actionShow" @close="actionShow = false" @select="actionSelect"></u-action-sheet>
    <u-row :gutter="16" style="margin-top: 36px;">
      <u-col :span="6">
        <u-button v-if="noticeId" type="error" text="删除" @click="del"></u-button>
        <u-button v-else icon="arrow-left" text="返回" plain @click="goBack()"></u-button>
      </u-col>
      <u-col :span="6">
        <u-button type="primary" text="提交" @click="submit"></u-button>
      </u-col>
    </u-row>
  </view>
</template>
<script>
import * as NoticeApi from '@/api/work/notice'
import Navbar from '@/components/navbar/Navbar'
export default {
  components: {
    Navbar,
  },
  data () {
    return {
      noticeId: undefined,
      notice: {
        noticeTitle: '',
        status: '0',
        noticeContent: ''
      },
      actionShow: false,
      actions: [{
        name: '通知',
        value: '1'
      }, {
        name: '公告',
        value: '2'
      }],
      actionTitle: '',
      noticeTypeName: null,
      rules: {
        noticeTitle: [ { required: true, message: '请输入公告标题', trigger: ['blur', 'change'] } ],
        noticeType: [ { required: true, message: '请选择公告类型', trigger: ['blur', 'change'] } ],
        status: [ { required: true, message: '请选择公告状态', trigger: ['blur', 'change'] } ],
        noticeContent: [ { required: true, message: '请输入公告正文', trigger: ['blur', 'change'] } ],
      }
    }
  },
  onLoad (params) {
    this.noticeId = params.id
    this.loadData()
  },
  methods: {
    loadData () {
      if (this.noticeId) {
        const app = this
        NoticeApi.noticeById(this.noticeId).then(res => {
          app.notice = res.data
        })
      }
    },
    del () {
      NoticeApi.noticeDelete(this.noticeId).then(res => {
        uni.showToast({ title: '保存成功!' })
      })
    },
    submit () {
      this.$refs.noticeForm.validate().then(res => {
        if (this.noticeId) {
          NoticeApi.noticeModify(this.notice).then(res => {
            uni.showToast({ title: '提交成功!' })
          })
        } else {
          NoticeApi.noticeAdd(this.notice).then(res => {
            uni.showToast({ title: '提交成功!' })
          })
        }
      });
    },
    actionSelect (item) {
      this.noticeTypeName = item.name;
      this.notice.noticeType = item.value;
      this.$refs.noticeForm.validateField('noticeType');
    },
    goBack () {
      uni.navigateBack({ delta: 1});
    }
  }
}
</script>
pages/work/notice/list.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,112 @@
<template>
  <view class="mobile-item-container">
    <Navbar title="通知公告" bgColor="#fff" :h5Show="false"></Navbar>
    <u-tabs :activeStyle="activeStyle" :list="tabs" @change="tabChange"></u-tabs>
    <!-- æœªè¯» -->
    <view v-if="activeKey == 'unread'">
      <view style="padding: 16px 0 10px;">
        <view class="notice-item-tips">
          <text>通知</text>
          <u-tag text="1" size="mini" type="primary" style="margin: 0 8px;"></u-tag>
          <text>条,公告</text>
          <u-tag text="1" size="mini" type="success" style="margin: 0 8px;"></u-tag>
          <text>条,共 2 æ¡ã€‚</text>
        </view>
      </view>
      <Record :list="list" @click="toDetail"></Record>
    </view>
    <!-- å·²è¯» -->
    <view v-if="activeKey == 'read'">
      <view style="padding: 16px 0 10px;">
        <u-search :show-action="true" actionText="搜索" :animation="true" shape="square" height="40px"></u-search>
      </view>
      <Record :list="[]" @click="toDetail"></Record>
    </view>
    <!-- å…¨éƒ¨ -->
    <view v-if="activeKey == 'all'">
      <view style="padding: 16px 0 10px;">
        <u-search :show-action="true" actionText="搜索" :animation="true" shape="square" height="40px"></u-search>
      </view>
      <Record :list="list" @click="toDetail"></Record>
    </view>
  </view>
</template>
<script>
import * as NoticeApi from '@/api/work/notice'
import Navbar from '@/components/navbar/Navbar'
import Record from './record'
export default {
  components: {
    Navbar,
    Record,
  },
  data () {
    return {
      activeKey: 'unread',
      tabs: [{
        name: '未读',
        key: 'unread',
        badge: {
          value: 2,
        }
      }, {
        name: '已读',
        key: 'read'
      }, {
        name: '全部',
        key: 'all'
      }],
      params: {
        pageNum: 0,
        pageSize: 10
      },
      list: [],
      activeStyle: {
        color: '#303133',
        fontSize: '20px',
        fontWeight: 'bold',
        transform: 'scale(1.05)'
      }
    }
  },
  created () {
    this.loadData()
  },
  methods: {
    // åŠ è½½é€šçŸ¥å…¬å‘Šæ•°æ®
    loadData () {
      const app = this
      this.params.pageNum += 1;
      NoticeApi.noticeList(this.params).then(res => {
        app.list = res.rows;
      })
    },
    tabChange (item) {
      this.activeKey = item.key;
      this.params.pageNum = 0;
      this.loadData();
    },
    // æ»šåŠ¨åˆ†é¡µåŠ è½½æ•°æ®
    scrolltolower () {
      this.loadData();
    },
    toDetail (notice) {
      uni.navigateTo({ url: '/pages/work/notice/detail?id=' + notice.noticeId })
    }
  }
}
</script>
<style lang="scss" scoped>
.notice-item-tips {
  border-radius: 8px;
  background-color: #f4f4f5;
  padding: 9px 16px;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
}
</style>
pages/work/notice/manage.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,79 @@
<template>
  <view class="mobile-item-container">
    <Navbar title="公告管理" bgColor="#fff" :h5Show="false"></Navbar>
    <Tabs :tabs="tabs" @change="tabChange" style="margin-bottom: 16px;"></Tabs>
    <Record v-if="activeKey == 'draft'" :list="list" @click="navigateTo"></Record>
    <Record v-if="activeKey == 'published'" :list="list" @click="navigateTo"></Record>
    <FloatButton type="primary" icon="plus" @click="navigateTo"></FloatButton>
  </view>
</template>
<script>
import * as NoticeApi from '@/api/work/notice'
import Navbar from '@/components/navbar/Navbar'
import FloatButton from '@/components/button/FloatButton'
import Tabs from '@/components/tabs/Tabs'
import Record from './record'
export default {
  components: {
    Navbar,
    FloatButton,
    Tabs,
    Record,
  },
  data () {
    return {
      activeKey: 'draft',
      tabs: [{
        name: '草稿',
        key: 'draft',
      }, {
        name: '已发布',
        key: 'published'
      }],
      params: {
        pageNum: 0,
        pageSize: 10
      },
      list: []
    }
  },
  created () {
    this.loadData()
  },
  methods: {
    // åŠ è½½é€šçŸ¥å…¬å‘Šæ•°æ®
    loadData () {
      const app = this
      this.params.pageNum += 1;
      NoticeApi.noticeList(this.params).then(res => {
        app.list = res.rows;
      })
    },
    // æ»šåŠ¨åˆ†é¡µåŠ è½½æ•°æ®
    scrolltolower () {
      this.loadData();
    },
    tabChange (tab) {
      this.activeKey = tab.key;
      this.params.pageNum = 0;
      this.loadData();
    },
    navigateTo (notice) {
      if (notice) {
        uni.navigateTo({ url: '/pages/work/notice/edit?id=' + notice.noticeId })
      } else {
        uni.navigateTo({ url: '/pages/work/notice/edit' })
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.list-item {
  padding: 20rpx 0;
  border-bottom: 0.5px solid #ccc;
}
</style>
pages/work/notice/record.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
<template>
  <view v-if="list && list.length > 0">
    <u-cell v-for="(item, index) in list" :key="index" :isLink="true" :border="true" @click="$emit('click', item)">
      <u-avatar slot="icon" :bg-color="item.noticeType == 2 ? '#2979ff' : '#19be6b'" :text="item.noticeType == 2 ? '公' : '通'" shape="square"></u-avatar>
      <view slot="title" class="notice-record-title">{{item.noticeTitle}}</view>
      <view slot="label" class="notice-record-desc">
        <view style="display: flex;">
          <u-icon name="clock" size="12"></u-icon>
          <text>{{item.createTime}}</text>
        </view>
        <view style="display: flex; margin-left: 16px;">
          <u-icon name="account" size="12"></u-icon>
          <text>{{item.remark}}</text>
        </view>
      </view>
    </u-cell>
    <!-- <u-loadmore :status="status" /> -->
  </view>
  <u-empty v-else></u-empty>
</template>
<script>
export default {
  props: {
    list: {
      type: Array,
      default: []
    },
    status: String
  }
}
</script>
<style lang="scss" scoped>
/deep/.u-cell__body {
  padding: 8px 0 !important;
}
.notice-record {
  display: flex;
  padding: 16px 0;
  &-content {
    margin-left: 8px;
  }
  &-title {
    font-size: 18px;
    font-weight: bold;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
  }
  &-title .read {
    color: #ccc;
  }
  &-desc {
    padding: 4px 0;
    font-size: 12px;
    color: #909399;
    display: flex;
  }
}
</style>
pages/work/user/edit.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,114 @@
<template>
  <view class="mobile-item-container">
    <Navbar :title="userId ? '修改用户' : '新增用户'" bgColor="#fff" :h5Show="false"></Navbar>
    <u--form ref="form" :model="userInfo" :rules="rules" labelPosition="left" labelWidth="80">
      <u-form-item label="用户昵称" prop="nickName" borderBottom>
        <u-input v-model="userInfo.nickName" placeholder="请输入用户昵称" :maxlength="30" border="none"></u-input>
      </u-form-item>
      <u-form-item label="归属部门" prop="deptId" borderBottom @click="actionShow = true;">
        <u--input v-model="noticeTypeName" disabled disabledColor="#ffffff" placeholder="请选择类型" border="none"></u--input>
                <u-icon slot="right" name="arrow-right"></u-icon>
      </u-form-item>
      <u-form-item label="状态" prop="status" borderBottom>
        <u-radio-group v-model="userInfo.status">
          <u-radio shape="circle" label="正常" name="0" checked></u-radio>
          <u-radio shape="circle" label="关闭" name="1"></u-radio>
        </u-radio-group>
      </u-form-item>
      <u-form-item label="正文" prop="noticeContent">
        <u--textarea v-model="userInfo.noticeContent" placeholder="请输入标题" :count="true" :maxlength="600" confirmType="done"></u--textarea>
      </u-form-item>
    </u--form>
    <u-action-sheet title="部门选择" :show="actionShow" @close="actionShow = false">
      <qian-tree ref="tkitree" confirmColor="#4e8af7" />
    </u-action-sheet>
    <u-row :gutter="16" style="margin-top: 36px;">
      <u-col :span="6">
        <u-button v-if="userId" type="error" text="删除" @click="del"></u-button>
        <u-button v-else icon="arrow-left" text="返回" plain @click="goBack()"></u-button>
      </u-col>
      <u-col :span="6">
        <u-button type="primary" text="提交" @click="submit"></u-button>
      </u-col>
    </u-row>
  </view>
</template>
<script>
import * as UserManageApi from '@/api/work/userManage'
import Navbar from '@/components/navbar/Navbar'
import qianTree from "@/components/qian-tree/qian-tree.vue"
export default {
  components: {
    Navbar,
    qianTree
  },
  data () {
    return {
      userId: undefined,
      userInfo: {
        noticeTitle: '',
        status: '0',
        noticeContent: ''
      },
      actionShow: false,
      actions: [{
        name: '通知',
        value: '1'
      }, {
        name: '公告',
        value: '2'
      }],
      actionTitle: '',
      noticeTypeName: null,
      rules: {
        noticeTitle: [ { required: true, message: '请输入公告标题', trigger: ['blur', 'change'] } ],
        noticeType: [ { required: true, message: '请选择公告类型', trigger: ['blur', 'change'] } ],
        status: [ { required: true, message: '请选择公告状态', trigger: ['blur', 'change'] } ],
        noticeContent: [ { required: true, message: '请输入公告正文', trigger: ['blur', 'change'] } ],
      }
    }
  },
  onLoad (params) {
    this.userId = params.id
    this.loadData()
  },
  methods: {
    loadData () {
      if (this.userId) {
        const app = this
        UserManageApi.userById(this.userId).then(res => {
          app.userInfo = res.data
        })
      }
    },
    del () {
      NoticeApi.noticeDelete(this.userId).then(res => {
        uni.showToast({ title: '保存成功!' })
      })
    },
    submit () {
      this.$refs.noticeForm.validate().then(res => {
        if (this.userId) {
          NoticeApi.noticeModify(this.notice).then(res => {
            uni.showToast({ title: '提交成功!' })
          })
        } else {
          NoticeApi.noticeAdd(this.notice).then(res => {
            uni.showToast({ title: '提交成功!' })
          })
        }
      });
    },
    actionSelect (item) {
      this.noticeTypeName = item.name;
      this.userInfo.noticeType = item.value;
      this.$refs.noticeForm.validateField('noticeType');
    },
    goBack () {
      uni.navigateBack({ delta: 1});
    }
  }
}
</script>
pages/work/user/list.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
<template>
  <view class="mobile-item-container">
    <Navbar title="用户管理" bgColor="#fff" :h5Show="false"></Navbar>
    <view style="padding: 16px 0 10px;">
      <u-search :show-action="true" actionText="搜索" :animation="true" height="40px"></u-search>
    </view>
    <view v-if="list && list.length > 0">
      <u-cell v-for="(item, index) in list" :key="index" :isLink="true" :border="true" @click="navigateTo(item)">
        <u-avatar slot="icon" v-if="item.avatar" :src="item.avatar"></u-avatar>
        <u-avatar slot="icon" v-else :text="item.remark.substring(0, 1)" randomBgColor></u-avatar>
        <view slot="title">
          <view style="display: flex; padding: 8px 0;">
            <text style="font-size: 18px; font-weight: bold;">{{item.remark}}</text>
            <u-tag :text="item.delFlag == 0 ? '启用' : '停用'" :type="item.delFlag == 0 ? 'primary' : 'error'" shape="circle" size="mini" style="margin-left: 8px;"></u-tag>
          </view>
          <view style="display: flex; justify-content:space-between;">
            <text>部门:{{item.dept.deptName}}</text>
            <text>电话:{{item.phonenumber}}</text>
          </view>
          <view>
            <text>邮件:{{item.email}}</text>
          </view>
        </view>
        <view slot="label">
        </view>
      </u-cell>
      <!-- <u-loadmore :status="status" /> -->
    </view>
    <u-empty v-else></u-empty>
    <FloatButton type="primary" icon="plus" @click="navigateTo"></FloatButton>
  </view>
</template>
<script>
import * as UserManageApi from '@/api/work/userManage'
import Navbar from '@/components/navbar/Navbar'
import FloatButton from '@/components/button/FloatButton'
export default {
  components: {
    Navbar,
    FloatButton
  },
  data () {
    return {
      params: {
        pageNum: 0,
        pageSize: 10
      },
      list: []
    }
  },
  onLoad () {
    this.loadData();
  },
  methods: {
    // åŠ è½½ç”¨æˆ·åˆ—è¡¨æ•°æ®
    loadData () {
      const app = this
      this.params.pageNum += 1;
      UserManageApi.userList(this.params).then(res => {
        app.list = res.rows;
      })
    },
    navigateTo (user) {
      if (user) {
        uni.navigateTo({ url: '/pages/work/user/edit?id=' + user.userId })
      } else {
        uni.navigateTo({ url: '/pages/work/user/edit' })
      }
    }
  }
}
</script>
pnpm-lock.yaml
ÎļþÒÑɾ³ý
src/App.vue
ÎļþÒÑɾ³ý
src/api/login.js
ÎļþÒÑɾ³ý
src/api/oauth.js
ÎļþÒÑɾ³ý
src/api/system/dict/data.js
ÎļþÒÑɾ³ý
src/api/system/dict/type.js
ÎļþÒÑɾ³ý
src/api/system/user.js
ÎļþÒÑɾ³ý
src/components/geek-xd/components/geek-certificate/geek-certificate.vue
ÎļþÒÑɾ³ý
src/components/geek-xd/components/geek-color-picker/geek-color-picker.vue
ÎļþÒÑɾ³ý
src/components/geek-xd/components/geek-commodity/geek-commodity.vue
ÎļþÒÑɾ³ý
src/components/geek-xd/components/geek-menu/geek-menu.vue
ÎļþÒÑɾ³ý
src/components/geek-xd/components/geek-order/geek-order.vue
ÎļþÒÑɾ³ý
src/components/geek-xd/components/geek-qrcode/README.md
ÎļþÒÑɾ³ý
src/components/geek-xd/components/geek-qrcode/geek-qrcode.vue
ÎļþÒÑɾ³ý
src/components/geek-xd/components/geek-qrcode/qrcode.js
ÎļþÒÑɾ³ý
src/components/geek-xd/components/geek-statistic/geek-statistic.vue
ÎļþÒÑɾ³ý
src/components/geek-xd/types/index.ts
ÎļþÒÑɾ³ý
src/components/qiun-data-charts/changelog.md
ÎļþÒÑɾ³ý
src/components/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue
ÎļþÒÑɾ³ý
src/components/qiun-data-charts/js_sdk/u-charts/config-ucharts.js
ÎļþÒÑɾ³ý
src/components/qiun-data-charts/js_sdk/u-charts/u-charts.js
ÎļþÒÑɾ³ý
src/components/qiun-data-charts/js_sdk/u-charts/u-charts.min.js
ÎļþÒÑɾ³ý
src/components/qiun-data-charts/package.json
ÎļþÒÑɾ³ý
src/components/qiun-data-charts/readme.md
ÎļþÒÑɾ³ý
src/components/ruoyi/DictTag/index.vue
ÎļþÒÑɾ³ý
src/components/u-city-select/area.js
ÎļþÒÑɾ³ý
src/components/u-city-select/city.js
ÎļþÒÑɾ³ý
src/components/u-city-select/province.js
ÎļþÒÑɾ³ý
src/components/u-city-select/u-city-select.vue
ÎļþÒÑɾ³ý
src/components/uni-section/uni-section.vue
ÎļþÒÑɾ³ý
src/config.js
ÎļþÒÑɾ³ý
src/directive/common/copyText.ts
ÎļþÒÑɾ³ý
src/directive/common/focus.ts
ÎļþÒÑɾ³ý
src/directive/common/full.ts
ÎļþÒÑɾ³ý
src/directive/index.ts
ÎļþÒÑɾ³ý
src/directive/permission/hasPermi.ts
ÎļþÒÑɾ³ý
src/directive/permission/hasRole.ts
ÎļþÒÑɾ³ý
src/env.d.ts
ÎļþÒÑɾ³ý
src/main.js
ÎļþÒÑɾ³ý
src/manifest.json
ÎļþÒÑɾ³ý
src/pages.json
ÎļþÒÑɾ³ý
src/pages/common/textview/index.vue
ÎļþÒÑɾ³ý
src/pages/common/webview/index.vue
ÎļþÒÑɾ³ý
src/pages/index.vue
ÎļþÒÑɾ³ý
src/pages/login.vue
ÎļþÒÑɾ³ý
src/pages/mine.vue
ÎļþÒÑɾ³ý
src/pages/template.config.js
ÎļþÒÑɾ³ý
src/pages/template.vue
ÎļþÒÑɾ³ý
src/pages/work.vue
ÎļþÒÑɾ³ý
src/pages_geek/pages/code/index.vue
ÎļþÒÑɾ³ý
src/pages_geek/pages/index/index.vue
ÎļþÒÑɾ³ý
src/pages_mine/pages/about/index.vue
ÎļþÒÑɾ³ý
src/pages_mine/pages/avatar/index.vue
ÎļþÒÑɾ³ý
src/pages_mine/pages/help/index.vue
ÎļþÒÑɾ³ý
src/pages_mine/pages/info/edit.vue
ÎļþÒÑɾ³ý
src/pages_mine/pages/info/index.vue
ÎļþÒÑɾ³ý
src/pages_mine/pages/pwd/index.vue
ÎļþÒÑɾ³ý
src/pages_mine/pages/setting/index.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/card-swiper/card-swiper.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/data-center/user-healthy.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/data-center/user-operate.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/data-center/user-server.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/data-center/wechat.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/data-progress/data-progress.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/data-table/senior-table.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/drop-down/drop-down.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/progress-bar/progress-bar.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/ranking-list/ranking-list.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/text-block/text-block.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/uni-calendar/calendar.js
ÎļþÒÑɾ³ý
src/pages_qiun/components/uni-calendar/uni-calendar-item.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/uni-calendar/uni-calendar.vue
ÎļþÒÑɾ³ý
src/pages_qiun/components/uni-calendar/util.js
ÎļþÒÑɾ³ý
src/pages_qiun/components/wuc-tab/wuc-tab.vue
ÎļþÒÑɾ³ý
src/pages_qiun/pages/finance/index.vue
ÎļþÒÑɾ³ý
src/pages_qiun/pages/main/index.vue
ÎļþÒÑɾ³ý
src/pages_qiun/pages/school/index.vue
ÎļþÒÑɾ³ý
src/pages_qiun/pages/sport/index.vue
ÎļþÒÑɾ³ý
src/pages_qiun/static/js/common.js
ÎļþÒÑɾ³ý
src/pages_qiun/static/js/config.js
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/finance/1.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/finance/2.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/school/1.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/school/2.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/school/3.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/school/4.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/sport/1.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/sport/2.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/sport/3.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/sport/4.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-healthy/1.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-healthy/2.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-healthy/3.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-healthy/4.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-healthy/5.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-healthy/6.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-healthy/7.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-operate/1.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-operate/2.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-operate/3.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-operate/4.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-operate/6.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-operate/7.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-operate/8.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-operate/9.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-server/1.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-server/2.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-server/3.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-server/4.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/user-server/5.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/wechat/1.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/wechat/2.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/wechat/3.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/wechat/4.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/wechat/5.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/json/wechat/6.json
ÎļþÒÑɾ³ý
src/pages_qiun/static/table/characterToPinyin.js
ÎļþÒÑɾ³ý
src/pages_qiun/static/table/iconfont.wxss
ÎļþÒÑɾ³ý
src/pages_qiun/static/table/loader.wxss
ÎļþÒÑɾ³ý
src/pages_qiun/static/table/objEqual.js
ÎļþÒÑɾ³ý
src/pages_template/common/api.js
ÎļþÒÑɾ³ý
src/pages_template/common/classify.data.js
ÎļþÒÑɾ³ý
src/pages_template/common/config.js
ÎļþÒÑɾ³ý
src/pages_template/common/demo.scss
ÎļþÒÑɾ³ý
src/pages_template/common/locales/en.js
ÎļþÒÑɾ³ý
src/pages_template/common/locales/zh.js
ÎļþÒÑɾ³ý
src/pages_template/common/mixin.js
ÎļþÒÑɾ³ý
src/pages_template/common/props.js
ÎļþÒÑɾ³ý
src/pages_template/pages/address/addSite.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/address/index.ts
ÎļþÒÑɾ³ý
src/pages_template/pages/address/index.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/citySelect/index.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/comment/index.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/comment/reply.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/coupon/index.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/keyboardPay/index.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/login/code.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/login/index1.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/login/index2.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/mallMenu/index1.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/mallMenu/index2.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/order/OrderItem.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/order/index.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/submitBar/index.vue
ÎļþÒÑɾ³ý
src/pages_template/pages/wxCenter/index.vue
ÎļþÒÑɾ³ý
src/plugins/auth.ts
ÎļþÒÑɾ³ý
src/plugins/bus.ts
ÎļþÒÑɾ³ý
src/plugins/index.ts
ÎļþÒÑɾ³ý
src/plugins/modal.ts
ÎļþÒÑɾ³ý
src/plugins/mqttclient.ts
ÎļþÒÑɾ³ý
src/plugins/socketclient.ts
ÎļþÒÑɾ³ý
src/plugins/tab.ts
ÎļþÒÑɾ³ý
src/shime-uni.d.ts
ÎļþÒÑɾ³ý
src/static/favicon.ico
Binary files differ
src/static/font/iconfont.css
ÎļþÒÑɾ³ý
src/static/font/iconfont.ttf
Binary files differ
src/static/images/banner/banner01.jpg
Binary files differ
src/static/images/banner/banner02.jpg
Binary files differ
src/static/images/banner/banner03.jpg
Binary files differ
src/static/images/icon/dialogue.png
Binary files differ
src/static/images/icon/knowledge.png
Binary files differ
src/static/images/icon/message.png
Binary files differ
src/static/images/icon/phone.png
Binary files differ
src/static/images/icon/rocket.png
Binary files differ
src/static/images/profile.jpg
Binary files differ
src/static/images/tabbar/work.png
Binary files differ
src/static/images/tabbar/work_.png
Binary files differ
src/static/index.html
ÎļþÒÑɾ³ý
src/static/logo.png
Binary files differ
src/static/scss/colorui.css
ÎļþÒÑɾ³ý
src/static/scss/global.scss
ÎļþÒÑɾ³ý
src/static/scss/index.scss
ÎļþÒÑɾ³ý
src/static/uview/common/favicon.ico
Binary files differ
src/static/uview/common/gray-logo.png
Binary files differ
src/static/uview/common/logo.png
Binary files differ
src/static/uview/demo/actionSheet.png
Binary files differ
src/static/uview/demo/address.png
Binary files differ
src/static/uview/demo/album.png
Binary files differ
src/static/uview/demo/alert.png
Binary files differ
src/static/uview/demo/avatar.png
Binary files differ
src/static/uview/demo/backTop.png
Binary files differ
src/static/uview/demo/badge.png
Binary files differ
src/static/uview/demo/button.png
Binary files differ
src/static/uview/demo/calendar.png
Binary files differ
src/static/uview/demo/cell.png
Binary files differ
src/static/uview/demo/checkbox.png
Binary files differ
src/static/uview/demo/citySelect.png
Binary files differ
src/static/uview/demo/code.png
Binary files differ
src/static/uview/demo/collapse.png
Binary files differ
src/static/uview/demo/color.png
Binary files differ
src/static/uview/demo/comment.png
Binary files differ
src/static/uview/demo/countDown.png
Binary files differ
src/static/uview/demo/countTo.png
Binary files differ
src/static/uview/demo/coupon.png
Binary files differ
src/static/uview/demo/datetimePicker.png
Binary files differ
src/static/uview/demo/divider.png
Binary files differ
src/static/uview/demo/empty.png
Binary files differ
src/static/uview/demo/field.png
Binary files differ
src/static/uview/demo/form.png
Binary files differ
src/static/uview/demo/gap.png
Binary files differ
src/static/uview/demo/grid.png
Binary files differ
src/static/uview/demo/icon.png
Binary files differ
src/static/uview/demo/image.png
Binary files differ
src/static/uview/demo/indexList (1).png
Binary files differ
src/static/uview/demo/indexList.png
Binary files differ
src/static/uview/demo/keyboard.png
Binary files differ
src/static/uview/demo/keyboardPay.png
Binary files differ
src/static/uview/demo/layout.png
Binary files differ
src/static/uview/demo/line.png
Binary files differ
src/static/uview/demo/link.png
Binary files differ
src/static/uview/demo/list.png
Binary files differ
src/static/uview/demo/loading-page.png
Binary files differ
src/static/uview/demo/loading.png
Binary files differ
src/static/uview/demo/loadmore.png
Binary files differ
src/static/uview/demo/login.png
Binary files differ
src/static/uview/demo/mall_menu_1.png
Binary files differ
src/static/uview/demo/mall_menu_2.png
Binary files differ
src/static/uview/demo/mask.png
Binary files differ
src/static/uview/demo/messageInput.png
Binary files differ
src/static/uview/demo/modal.png
Binary files differ
src/static/uview/demo/navbar.png
Binary files differ
src/static/uview/demo/noNetwork.png
Binary files differ
src/static/uview/demo/noticeBar.png
Binary files differ
src/static/uview/demo/notify.png
Binary files differ
src/static/uview/demo/numberBox.png
Binary files differ
src/static/uview/demo/order.png
Binary files differ
src/static/uview/demo/parse.png
Binary files differ
src/static/uview/demo/picker.png
Binary files differ
src/static/uview/demo/popup.png
Binary files differ
src/static/uview/demo/progress.png
Binary files differ
src/static/uview/demo/radio.png
Binary files differ
src/static/uview/demo/rate.png
Binary files differ
src/static/uview/demo/readMore.png
Binary files differ
src/static/uview/demo/scrollList.png
Binary files differ
src/static/uview/demo/search.png
Binary files differ
src/static/uview/demo/skeleton.png
Binary files differ
src/static/uview/demo/slider.png
Binary files differ
src/static/uview/demo/steps.png
Binary files differ
src/static/uview/demo/sticky.png
Binary files differ
src/static/uview/demo/submitBar.png
Binary files differ
src/static/uview/demo/subsection.png
Binary files differ
src/static/uview/demo/swipeAction.png
Binary files differ
src/static/uview/demo/swiper.png
Binary files differ
src/static/uview/demo/switch.png
Binary files differ
src/static/uview/demo/tabbar.png
Binary files differ
src/static/uview/demo/tabs.png
Binary files differ
src/static/uview/demo/tag.png
Binary files differ
src/static/uview/demo/text.png
Binary files differ
src/static/uview/demo/textarea.png
Binary files differ
src/static/uview/demo/toast.png
Binary files differ
src/static/uview/demo/tooltip.png
Binary files differ
src/static/uview/demo/transition.png
Binary files differ
src/static/uview/demo/upload.png
Binary files differ
src/static/uview/demo/wxCenter.png
Binary files differ
src/static/uview/example/component.png
Binary files differ
src/static/uview/example/component_select.png
Binary files differ
src/static/uview/example/js.png
Binary files differ
src/static/uview/example/js_bak.png
Binary files differ
src/static/uview/example/js_select.png
Binary files differ
src/static/uview/example/template.png
Binary files differ
src/static/uview/example/template_select.png
Binary files differ
src/store/index.ts
ÎļþÒÑɾ³ý
src/store/modules/dict.ts
ÎļþÒÑɾ³ý
src/store/modules/user.ts
ÎļþÒÑɾ³ý
src/types/request.ts
ÎļþÒÑɾ³ý
src/uni.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-badge/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-badge/components/uni-badge/uni-badge.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-badge/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-badge/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-breadcrumb/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-breadcrumb/components/uni-breadcrumb-item/uni-breadcrumb-item.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-breadcrumb/components/uni-breadcrumb/uni-breadcrumb.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-breadcrumb/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-breadcrumb/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-calendar/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-calendar/components/uni-calendar/calendar.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-calendar/components/uni-calendar/i18n/en.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-calendar/components/uni-calendar/i18n/index.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-calendar/components/uni-calendar/util.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-calendar/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-calendar/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-card/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-card/components/uni-card/uni-card.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-card/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-card/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-collapse/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-collapse/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-collapse/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-combox/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-combox/components/uni-combox/uni-combox.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-combox/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-combox/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-countdown/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-countdown/components/uni-countdown/i18n/en.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-countdown/components/uni-countdown/i18n/index.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hans.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hant.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-countdown/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-countdown/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-checkbox/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-checkbox/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-checkbox/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-picker/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-picker/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-picker/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-select/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-select/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-data-select/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-dateformat/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-dateformat/components/uni-dateformat/date-format.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-dateformat/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-dateformat/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-datetime-picker/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-datetime-picker/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-datetime-picker/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-drawer/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-drawer/components/uni-drawer/keypress.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-drawer/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-drawer/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-easyinput/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-easyinput/components/uni-easyinput/common.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-easyinput/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-easyinput/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-fab/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-fab/components/uni-fab/uni-fab.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-fab/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-fab/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-fav/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-fav/components/uni-fav/i18n/en.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-fav/components/uni-fav/i18n/index.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-fav/components/uni-fav/uni-fav.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-fav/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-fav/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-file-picker/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-file-picker/components/uni-file-picker/utils.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-file-picker/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-file-picker/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-forms/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-forms/components/uni-forms/uni-forms.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-forms/components/uni-forms/utils.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-forms/components/uni-forms/validate.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-forms/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-forms/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-goods-nav/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/en.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/index.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hans.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hant.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-goods-nav/components/uni-goods-nav/uni-goods-nav.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-goods-nav/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-goods-nav/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-grid/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-grid/components/uni-grid-item/uni-grid-item.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-grid/components/uni-grid/uni-grid.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-grid/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-grid/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-group/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-group/components/uni-group/uni-group.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-group/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-group/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-icons/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-icons/components/uni-icons/icons.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-icons/components/uni-icons/uni-icons.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-icons/components/uni-icons/uniicons.css
ÎļþÒÑɾ³ý
src/uni_modules/uni-icons/components/uni-icons/uniicons.ttf
Binary files differ
src/uni_modules/uni-icons/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-icons/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-indexed-list/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list-item.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-indexed-list/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-indexed-list/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-link/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-link/components/uni-link/uni-link.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-link/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-link/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-list/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-list/components/uni-list-ad/uni-list-ad.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-list/components/uni-list-item/uni-list-item.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-list/components/uni-list/uni-list.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-list/components/uni-list/uni-refresh.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-list/components/uni-list/uni-refresh.wxs
ÎļþÒÑɾ³ý
src/uni_modules/uni-list/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-list/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-load-more/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-load-more/components/uni-load-more/i18n/en.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-load-more/components/uni-load-more/i18n/index.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-load-more/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-load-more/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-nav-bar/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-nav-bar/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-nav-bar/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-notice-bar/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-notice-bar/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-notice-bar/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-number-box/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-number-box/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-number-box/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-pagination/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-pagination/components/uni-pagination/i18n/en.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-pagination/components/uni-pagination/i18n/es.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-pagination/components/uni-pagination/i18n/fr.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-pagination/components/uni-pagination/i18n/index.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hans.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hant.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-pagination/components/uni-pagination/uni-pagination.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-pagination/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-pagination/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/components/uni-popup/i18n/en.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/components/uni-popup/i18n/index.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/components/uni-popup/keypress.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/components/uni-popup/popup.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/components/uni-popup/uni-popup.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-popup/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-rate/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-rate/components/uni-rate/uni-rate.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-rate/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-rate/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-row/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-row/components/uni-col/uni-col.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-row/components/uni-row/uni-row.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-row/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-row/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/index.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/styles/index.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/styles/setting/_border.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/styles/setting/_color.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/styles/setting/_radius.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/styles/setting/_space.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/styles/setting/_styles.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/styles/setting/_text.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/styles/setting/_variables.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/styles/tools/functions.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/theme.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-scss/variables.scss
ÎļþÒÑɾ³ý
src/uni_modules/uni-search-bar/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-search-bar/components/uni-search-bar/i18n/en.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-search-bar/components/uni-search-bar/i18n/index.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hans.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hant.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-search-bar/components/uni-search-bar/uni-search-bar.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-search-bar/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-search-bar/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-segmented-control/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-segmented-control/components/uni-segmented-control/uni-segmented-control.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-segmented-control/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-segmented-control/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-steps/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-steps/components/uni-steps/uni-steps.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-steps/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-steps/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-swipe-action/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/bindingx.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs
ÎļþÒÑɾ³ý
src/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-swipe-action/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-swipe-action/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-swiper-dot/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-swiper-dot/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-swiper-dot/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/components/uni-table/uni-table.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/components/uni-td/uni-td.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/components/uni-th/filter-dropdown.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/components/uni-th/uni-th.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/components/uni-thead/uni-thead.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/components/uni-tr/table-checkbox.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/components/uni-tr/uni-tr.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/i18n/en.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/i18n/es.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/i18n/fr.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/i18n/index.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/i18n/zh-Hans.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/i18n/zh-Hant.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-table/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-tag/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-tag/components/uni-tag/uni-tag.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-tag/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-tag/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-title/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-title/components/uni-title/uni-title.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-title/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-title/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-tooltip/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-tooltip/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-tooltip/readme.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-transition/changelog.md
ÎļþÒÑɾ³ý
src/uni_modules/uni-transition/components/uni-transition/createAnimation.js
ÎļþÒÑɾ³ý
src/uni_modules/uni-transition/components/uni-transition/uni-transition.vue
ÎļþÒÑɾ³ý
src/uni_modules/uni-transition/package.json
ÎļþÒÑɾ³ý
src/uni_modules/uni-transition/readme.md
ÎļþÒÑɾ³ý
src/utils/auth.ts
ÎļþÒÑɾ³ý
src/utils/common.ts
ÎļþÒÑɾ³ý
src/utils/constant.ts
ÎļþÒÑɾ³ý
src/utils/dict.ts
ÎļþÒÑɾ³ý
src/utils/errorCode.ts
ÎļþÒÑɾ³ý
src/utils/geek.ts
ÎļþÒÑɾ³ý
src/utils/permission.ts
ÎļþÒÑɾ³ý
src/utils/request.ts
ÎļþÒÑɾ³ý
src/utils/ruoyi.js
ÎļþÒÑɾ³ý
src/utils/storage.ts
ÎļþÒÑɾ³ý
src/utils/upload.ts
ÎļþÒÑɾ³ý
static/img/avatar.png
static/img/b-1.png
static/img/b-2.png
static/img/tabbar/center.png
static/img/tabbar/center_art.png
static/img/tabbar/home.png

static/img/tabbar/home_art.png

static/img/tabbar/user.png

static/img/tabbar/user_art.png

static/preview/ali_pay.jpg
static/preview/index.jpg
static/preview/login.jpg
static/preview/logs.jpg
static/preview/my.jpg
static/preview/notice-e.jpg
static/preview/notice-m.jpg
static/preview/prefile.jpg
static/preview/pwd-reset.jpg
static/preview/wechat_pay.jpg
static/preview/work.jpg
static/style.scss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
/* è‡ªå®šä¹‰æ ·å¼ */
.mobile-item-container {
  padding: 16px;
  background-color: #fff;
}
store/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const files = require.context("./modules", false, /\.js$/);
let modules = {
    state: {},
    mutations: {},
    actions: {},
  getters: {}
};
files.keys().forEach((key) => {
  Object.assign(modules.state, files(key)["state"] || {});
  Object.assign(modules.mutations, files(key)["mutations"] || {});
  Object.assign(modules.actions, files(key)["actions"] || {});
  Object.assign(modules.getters, files(key)["getters"] || {});
});
const store = new Vuex.Store(modules);
export default store;
store/modules/system.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
import storage from '@/utils/storage'
export const state = {
  systemInfo: null
}
export const mutations = {
  SET_SYSTEM_INFO: (state, value) => {
    state.systemInfo = value
  },
}
export const actions = {
  // èŽ·å–ç”¨æˆ·ç»ˆç«¯ç³»ç»Ÿä¿¡æ¯
  SystemInfo ({ commit, state }) {
    return new Promise((resolve, reject) => {
      if (state.info) {
        resolve(res)
      } else {
        uni.getSystemInfo({
          success (res) {
            commit('SET_SYSTEM_INFO', res)
            // ä¿¡æ¯å­˜å…¥ç¼“存(有效期1天)
            storage.set('SYSTEM_INFO', res, 86400);
            resolve(res)
          },
          fail (err) {
            reject(err)
          }
        })
      }
    })
  },
}
export const getters = {
  getSystemInfo (state) {
    if (state.systemInfo) {
      return state.systemInfo
    } else if (storage.get('SYSTEM_INFO')) {
      return JSON.parse(storage.get('SYSTEM_INFO'))
    }
    return {}
  }
}
store/modules/user.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
import { ACCESS_TOKEN } from '@/store/mutation-types'
import storage from '@/utils/storage'
import * as LoginApi from '@/api/login'
import * as UserApi from '@/api/user'
// ç™»é™†æˆåŠŸåŽæ‰§è¡Œ
const loginSuccess = (commit, { token }) => {
  // è¿‡æœŸæ—¶é—´30天
  const expiryTime = 30 * 86400
  // ä¿å­˜tokne和userId到缓存
  storage.set(ACCESS_TOKEN, token, expiryTime)
  // è®°å½•到store全局变量
  commit('SET_TOKEN', token)
}
export const state = {
  // ç”¨æˆ·è®¤è¯token
  token: '',
  // ç”¨æˆ·ä¿¡æ¯
  userInfo: null
}
export const mutations = {
  SET_TOKEN: (state, value) => {
    state.token = value
  },
  SET_USER: (state, value) => {
    state.userInfo = value
  },
}
export const actions = {
  // ç”¨æˆ·ç™»å½•(普通登录: è¾“入账号、密码和验证码)
  Login({ commit }, data) {
    return new Promise((resolve, reject) => {
      LoginApi.login(data, { custom: { catch: true } }).then(response => {
          const result = response;
          loginSuccess(commit, result)
          resolve(response)
        }).catch(reject)
    })
  },
  // ç”¨æˆ·ä¿¡æ¯
  Info({ commit, state }) {
    return new Promise((resolve, reject) => {
      if (state.userInfo) {
        return resolve(state.userInfo)
      }
      UserApi.getInfo().then(response => {
        const result = response;
        commit('SET_USER', result)
        resolve(response)
      }).catch(reject)
    })
  },
  // é€€å‡ºç™»å½•
  Logout({ commit }, data) {
    return new Promise((resolve, reject) => {
      LoginApi.logout(data, { custom: { catch: true } }).then(response => {
        storage.remove(ACCESS_TOKEN)
        commit('SET_TOKEN', '')
        resolve(response)
      }).catch(reject)
    })
  }
}
store/mutation-types.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
export const ACCESS_TOKEN = 'AccessToken'
template.h5.html
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>
            <%= htmlWebpackPlugin.options.title %>
        </title>
        <!-- Open Graph data -->
        <!-- <meta property="og:title" content="Title Here" /> -->
        <!-- <meta property="og:url" content="http://www.example.com/" /> -->
        <!-- <meta property="og:image" content="http://example.com/image.jpg" /> -->
        <!-- <meta property="og:description" content="Description Here" /> -->
        <script>
            var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
            document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')
        </script>
        <link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
    </head>
    <body>
        <noscript>
            <strong>Please enable JavaScript to continue.</strong>
        </noscript>
        <div id="app"></div>
        <!-- built files will be auto injected -->
    <script>
      var _hmt = _hmt || [];
      (function() {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?8ae2d12e41f0fe8b183e2e97b5c8e3df";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
      })();
      </script>
    </body>
</html>
tsconfig.json
ÎļþÒÑɾ³ý
uni.scss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,76 @@
/**
 * è¿™é‡Œæ˜¯uni-app内置的常用样式变量
 *
 * uni-app å®˜æ–¹æ‰©å±•插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
 * å¦‚果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import è¿™ä¸ªæ–‡ä»¶ï¼‰ï¼Œæ–¹ä¾¿ç”¨æˆ·é€šè¿‡æ­ç§¯æœ¨çš„æ–¹å¼å¼€å‘整体风格一致的App
 *
 */
@import '@/uni_modules/uview-ui/theme.scss';
/**
 * å¦‚果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
 *
 * å¦‚果你的项目同样使用了scss预处理,你也可以直接在你的 scss ä»£ç ä¸­ä½¿ç”¨å¦‚下变量,同时无需 import è¿™ä¸ªæ–‡ä»¶
 */
/* é¢œè‰²å˜é‡ */
/* è¡Œä¸ºç›¸å…³é¢œè‰² */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* æ–‡å­—基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* èƒŒæ™¯é¢œè‰² */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
/* è¾¹æ¡†é¢œè‰² */
$uni-border-color:#c8c7cc;
/* å°ºå¯¸å˜é‡ */
/* æ–‡å­—尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16;
/* å›¾ç‰‡å°ºå¯¸ */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/* æ°´å¹³é—´è· */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
/* åž‚直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* é€æ˜Žåº¦ */
$uni-opacity-disabled: 0.3; // ç»„件禁用态的透明度
/* æ–‡ç« åœºæ™¯ç›¸å…³ */
$uni-color-title: #2C405A; // æ–‡ç« æ ‡é¢˜é¢œè‰²
$uni-font-size-title:20px;
$uni-color-subtitle: #555555; // äºŒçº§æ ‡é¢˜é¢œè‰²
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // æ–‡ç« æ®µè½é¢œè‰²
$uni-font-size-paragraph:15px;
uni_modules/qiun-data-charts/changelog.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,246 @@
## 2.4.3-20220505(2022-05-05)
- ç§‹äº‘图表组件 ä¿®å¤å¼€å¯canvas2d后将series赋值为空数组显示加载图标时,再次赋值后画布闪动的bug
- ç§‹äº‘图表组件 ä¿®å¤å‡çº§hbx最新版后ECharts的highlight方法报错的bug
- uCharts.js é›·è¾¾å›¾æ–°å¢žå‚æ•°opts.extra.radar.gridEval,数据点位网格抽希,默认1
- uCharts.js é›·è¾¾å›¾æ–°å¢žå‚æ•°opts.extra.radar.axisLabel,    æ˜¯å¦æ˜¾ç¤ºåˆ»åº¦ç‚¹å€¼ï¼Œé»˜è®¤false
- uCharts.js é›·è¾¾å›¾æ–°å¢žå‚æ•°opts.extra.radar.axisLabelTofix,刻度点值小数位数,默认0
- uCharts.js é›·è¾¾å›¾æ–°å¢žå‚æ•°opts.extra.radar.labelPointShow,是否显示末端刻度圆点,默认false
- uCharts.js é›·è¾¾å›¾æ–°å¢žå‚æ•°opts.extra.radar.labelPointRadius,刻度圆点的半径,默认3
- uCharts.js é›·è¾¾å›¾æ–°å¢žå‚æ•°opts.extra.radar.labelPointColor,刻度圆点的颜色,默认#cccccc
- uCharts.js é›·è¾¾å›¾æ–°å¢žå‚æ•°opts.extra.radar.linearType,渐变色类型,可选值"none"关闭渐变,"custom"开启渐变
- uCharts.js é›·è¾¾å›¾æ–°å¢žå‚æ•°opts.extra.radar.customColor,自定义渐变颜色,数组类型对应series的数组长度以匹配不同series颜色的不同配色方案,例如["#FA7D8D", "#EB88E2"]
- uCharts.js é›·è¾¾å›¾ä¼˜åŒ–支持series.textColor、series.textSize属性
- uCharts.js æŸ±çŠ¶å›¾ä¸­æ¸©åº¦è®¡å¼å›¾æ ‡ï¼Œä¼˜åŒ–æ”¯æŒå…¨åœ†è§’ç±»åž‹ï¼Œä¿®å¤è¾¹æ¡†æœ‰ç¼éš™çš„bug,详见官网【演示】中的温度计图表
- uCharts.js æŸ±çŠ¶å›¾æ–°å¢žå‚æ•°opts.extra.column.activeWidth,当前点击柱状图的背景宽度,默认一个单元格单位
- uCharts.js æ··åˆå›¾å¢žåŠ opts.extra.mix.area.gradient åŒºåŸŸå›¾æ˜¯å¦å¼€å¯æ¸å˜è‰²
- uCharts.js æ··åˆå›¾å¢žåŠ opts.extra.mix.area.opacity åŒºåŸŸå›¾é€æ˜Žåº¦ï¼Œé»˜è®¤0.2
- uCharts.js é¥¼å›¾ã€åœ†çŽ¯å›¾ã€çŽ«ç‘°å›¾ã€æ¼æ–—å›¾ï¼Œå¢žåŠ opts.series[0].data[i].labelText,自定义标签文字,避免formatter格式化的繁琐,详见官网【演示】中的饼图
- uCharts.js é¥¼å›¾ã€åœ†çŽ¯å›¾ã€çŽ«ç‘°å›¾ã€æ¼æ–—å›¾ï¼Œå¢žåŠ opts.series[0].data[i].labelShow,自定义是否显示某一个指示标签,避免因饼图类别太多导致标签重复或者居多导致图形变形的问题,详见官网【演示】中的饼图
- uCharts.js å¢žåŠ opts.series[i].legendText/opts.series[0].data[i].legendText(与series.name同级)自定义图例显示文字的方法
- uCharts.js ä¼˜åŒ–X轴、Yè½´formatter格式化方法增加形参,统一为fromatter:function(value,index,opts){}
- uCharts.js ä¿®å¤æ¨ªå±æ¨¡å¼ä¸‹æ— æ³•使用双指缩放方法的bug
- uCharts.js ä¿®å¤å½“只有一条数据或者多条数据值相等的时候Y轴自动计算的最大值错误的bug
- ã€å®˜ç½‘模板】增加外部自定义图例与图表交互的例子,[点击跳转](https://www.ucharts.cn/v2/#/layout/info?id=2)
## æ³¨æ„ï¼šéžunimodules ç‰ˆæœ¬å¦‚å› æ›´æ–° hbx è‡³ 3.4.7 å¯¼è‡´æŠ¥é”™å¦‚下,请到码云更新非 unimodules ç‰ˆæœ¬ç»„件,[点击跳转](https://gitee.com/uCharts/uCharts/tree/master/uni-app/uCharts-%E7%BB%84%E4%BB%B6)
> Error in callback for immediate watcher "uchartsOpts": "SyntaxError: Unexpected token u in JSON at position 0"
## 2.4.2-20220421(2022-04-21)
- ç§‹äº‘图表组件 ä¿®å¤HBX升级3.4.6.20220420版本后echarts报错的问题
## 2.4.2-20220420(2022-04-20)
## é‡è¦ï¼æ­¤ç‰ˆæœ¬uCharts新增了很多功能,修复了诸多已知问题
- ç§‹äº‘图表组件 æ–°å¢žonzoom开启双指缩放功能(仅uCharts),前提需要直角坐标系类图表类型,并且ontouch为true、opts.enableScroll为true,详见实例项目K线图
- ç§‹äº‘图表组件 æ–°å¢žoptsWatch是否监听opts变化,关闭optsWatch后,动态修改opts不会触发图表重绘
- ç§‹äº‘图表组件 ä¿®å¤å¼€å¯canvas2d功能后,动态更新数据后画布闪动的bug
- ç§‹äº‘图表组件 å޻除directory属性,改为自动获取echarts.min.js路径(升级不受影响)
- ç§‹äº‘图表组件 å¢žåŠ getImage()方法及@getImage事件,通过ref调用getImage()方法获,触发@getImage事件获取当前画布的base64图片文件流。
- ç§‹äº‘图表组件 æ”¯ä»˜å®ã€å­—节跳动、飞书、快手小程序支持开启canvas2d同层渲染设置。
- ç§‹äº‘图表组件 æ–°å¢žåŠ ã€éžuniCloud】版本组件,避免有些不需要uniCloud的使用组件发布至小程序需要提交隐私声明问题,请到码云[【非uniCloud版本】](https://gitee.com/uCharts/uCharts/tree/master/uni-app/uCharts-%E7%BB%84%E4%BB%B6),或npm[【非uniCloud版本】](https://www.npmjs.com/package/@qiun/uni-ucharts)下载使用。
- uCharts.js æ–°å¢ždobuleZoom双指缩放功能
- uCharts.js æ–°å¢žå±±å³°å›¾type="mount",数据格式为饼图类格式,不需要传入categories,具体详见新版官网在线演示
- uCharts.js ä¿®å¤æŠ˜çº¿å›¾å½“数据中存在null时tooltip报错的bug
- uCharts.js ä¿®å¤é¥¼å›¾ç±»å½“画布比较小时自动计算的半径是负数报错的bug
- uCharts.js ç»Ÿä¸€å„图表类型的series.formatter格式化方法的形参为(val, index, series, opts),方便格式化时有更多参数可用
- uCharts.js æ ‡è®°çº¿åŠŸèƒ½å¢žåŠ labelText自定义显示文字,增加labelAlign标签显示位置(左侧或右侧),增加标签显示位置微调labelOffsetX、labelOffsetY
- uCharts.js ä¿®å¤æ¡çŠ¶å›¾å½“æ•°å€¼å¾ˆå°æ—¶å¼€å¯åœ†è§’åŽæ ·å¼é”™è¯¯çš„bug
- uCharts.js ä¿®å¤X轴开启disabled后,X轴仍占用空间的bug
- uCharts.js ä¿®å¤X轴开启滚动条并且开启rotateLabel后,X轴文字与滚动条重叠的bug
- uCharts.js å¢žåŠ Xè½´rotateAngle文字旋转自定义角度,取值范围(-90至90)
- uCharts.js ä¿®å¤åœ°å›¾æ–‡å­—标签层级显示不正确的bug
- uCharts.js ä¿®å¤é¥¼å›¾ã€åœ†çŽ¯å›¾ã€çŽ«ç‘°å›¾å½“æ•°æ®å…¨éƒ¨ä¸º0的时候不显示数据标签的bug
- uCharts.js ä¿®å¤å½“opts.padding上边距为0时,Y轴顶部刻度标签位置不正确的bug
## å¦å¤–我们还开发了各大原生小程序组件,已发布至码云和npm
[https://gitee.com/uCharts/uCharts](https://gitee.com/uCharts/uCharts)
[https://www.npmjs.com/~qiun](https://www.npmjs.com/~qiun)
## å¯¹äºŽåŽŸç”ŸuCharts文档我们已上线新版官方网站,详情点击下面链接进入官网
[https://www.uCharts.cn/v2/](https://www.ucharts.cn/v2/)
## 2.3.7-20220122(2022-01-22)
## é‡è¦ï¼ä½¿ç”¨vue3编译,请使用cli模式并升级至最新依赖,HbuilderX编译需要使用3.3.8以上版本
- uCharts.js ä¿®å¤uni-app平台组件模式使用vue3编译到小程序报错的bug。
## 2.3.7-20220118(2022-01-18)
## æ³¨æ„ï¼Œä½¿ç”¨vue3的前提是需要3.3.8.20220114-alpha版本的HBuilder!
## 2.3.67-20220118(2022-01-18)
- ç§‹äº‘图表组件 ç»„件初步支持vue3,全端编译会有些问题,具体详见下面修改:
1. å°ç¨‹åºç«¯è¿è¡Œæ—¶ï¼Œåœ¨uni_modules文件夹的qiun-data-charts.js中搜索 new uni_modules_qiunDataCharts_js_sdk_uCharts_uCharts.uCharts,将.uCharts去掉。
2. å°ç¨‹åºç«¯å‘行时,在uni_modules文件夹的qiun-data-charts.js中搜索 new e.uCharts,将.uCharts去掉,变为 new e。
3. å¦‚果觉得上述步骤比较麻烦,如果您的项目只编译到小程序端,可以修改u-charts.js最后一行导出方式,将 export default uCharts;变更为 export default { uCharts: uCharts }; è¿™æ ·å˜æ›´åŽï¼ŒH5和App端的renderjs会有问题,请开发者自行选择。(此问题非组件问题,请等待DC官方修复Vue3的小程序端)
## 2.3.6-20220111(2022-01-11)
- ç§‹äº‘图表组件 ä¿®æ”¹ç»„ä»¶ props å±žæ€§ä¸­çš„ background é»˜è®¤å€¼ä¸º rgba(0,0,0,0)
## 2.3.6-20211201(2021-12-01)
- uCharts.js ä¿®å¤bar条状图开启圆角模式时,值很小时圆角渲染错误的bug
## 2.3.5-20211014(2021-10-15)
- uCharts.js å¢žåŠ vue3的编译支持(仅原生uCharts,qiun-data-charts组件后续会支持,请关注更新)
## 2.3.4-20211012(2021-10-12)
- ç§‹äº‘图表组件 ä¿®å¤ mac os x ç³»ç»Ÿ mouseover äº‹ä»¶ä¸¢å¤±çš„ bug
## 2.3.3-20210706(2021-07-06)
- uCharts.js å¢žåŠ é›·è¾¾å›¾å¼€å¯æ•°æ®ç‚¹å€¼ï¼ˆopts.dataLabel)的显示
## 2.3.2-20210627(2021-06-27)
- ç§‹äº‘图表组件 ä¿®å¤tooltipCustom个别情况下传值不正确报错TypeError: Cannot read property 'name' of undefined的bug
## 2.3.1-20210616(2021-06-16)
- uCharts.js ä¿®å¤åœ†è§’柱状图使用4角圆角时,当数值过大时不正确的bug
## 2.3.0-20210612(2021-06-12)
- uCharts.js ã€é‡è¦ã€‘uCharts增加nvue兼容,可在nvue项目中使用gcanvas组件渲染uCharts,[详见码云uCharts-demo-nvue](https://gitee.com/uCharts/uCharts)
- ç§‹äº‘图表组件 å¢žåŠ tapLegend属性,是否开启图例点击交互事件
- ç§‹äº‘图表组件 getIndex事件中增加返回uCharts实例中的opts参数,以便在页面中调用参数
- ç¤ºä¾‹é¡¹ç›® pages/other/other.vue增加app端自定义tooltip的方法,详见showOptsTooltip方法
## 2.2.1-20210603(2021-06-03)
- uCharts.js ä¿®å¤é¥¼å›¾ã€åœ†çŽ¯å›¾ã€çŽ«ç‘°å›¾ï¼Œå½“èµ·å§‹è§’åº¦ä¸ä¸º0时,tooltip位置不准确的bug
- uCharts.js å¢žåŠ æ¸©åº¦è®¡å¼æŸ±çŠ¶å›¾å¼€å¯é¡¶éƒ¨åŠåœ†å½¢çš„é…ç½®
## 2.2.0-20210529(2021-05-29)
- uCharts.js å¢žåŠ æ¡çŠ¶å›¾type="bar"
- ç¤ºä¾‹é¡¹ç›® pages/ucharts/ucharts.vue增加条状图的demo
## 2.1.7-20210524(2021-05-24)
- uCharts.js ä¿®å¤å¤§æ•°æ®é‡æ¨¡å¼ä¸‹æ›²çº¿å›¾ä¸å¹³æ»‘çš„bug
## 2.1.6-20210523(2021-05-23)
- ç§‹äº‘图表组件 ä¿®å¤å°ç¨‹åºç«¯å¼€å¯æ»šåŠ¨æ¡æ›´æ–°æ•°æ®åŽæ»šåŠ¨æ¡ä½ç½®ä¸ç¬¦åˆé¢„æœŸçš„bug
## 2.1.5-2021051702(2021-05-17)
- uCharts.js ä¿®å¤è‡ªå®šä¹‰Yè½´min和max值为0时不能正确显示的bug
## 2.1.5-20210517(2021-05-17)
- uCharts.js ä¿®å¤Y轴自定义min和max时,未按指定的最大值最小值显示坐标轴刻度的bug
## 2.1.4-20210516(2021-05-16)
- ç§‹äº‘图表组件 ä¼˜åŒ–onWindowResize防抖方法
- ç§‹äº‘图表组件 ä¿®å¤APP端uCharts更新数据时,清空series显示loading图标后再显示图表,图表抖动的bug
- uCharts.js ä¿®å¤å¼€å¯canvas2d后,x轴、y轴、series自定义字体大小未按比例缩放的bug
- ç¤ºä¾‹é¡¹ç›® ä¿®å¤format-e.vue拼写错误导致app端使用uCharts渲染图表
## 2.1.3-20210513(2021-05-13)
- ç§‹äº‘图表组件 ä¿®æ”¹uCharts变更chartData数据为updateData方法,支持带滚动条的数据动态打点
- ç§‹äº‘图表组件 å¢žåŠ onWindowResize防抖方法 fix by ã©èª“言,如尘般染指流年づ
- ç§‹äº‘图表组件 H5或者APP变更chartData数据显示loading图表时,原数据闪现的bug
- ç§‹äº‘图表组件 props增加errorReload禁用错误点击重新加载的方法
- uCharts.js å¢žåŠ tooltip显示category(x轴对应点位)标题的功能,opts.extra.tooltip.showCategory,默认为false
- uCharts.js ä¿®å¤mix混合图只有柱状图时,tooltip的分割线显示位置不正确的bug
- uCharts.js ä¿®å¤å¼€å¯æ»šåŠ¨æ¡ï¼Œå›¾è¡¨åœ¨æ‹–åŠ¨ä¸­åŠ¨æ€æ‰“ç‚¹ï¼Œæ»šåŠ¨æ¡ä½ç½®ä¸æ­£ç¡®çš„bug
- uCharts.js ä¿®å¤é¥¼å›¾ç±»æ•°æ®æ ¼å¼ä¸ºecharts数据格式,series为空数组报错的bug
- ç¤ºä¾‹é¡¹ç›® ä¿®æ”¹uCharts.js更新到v2.1.2版本后,@getIndex方法获取索引值变更为e.currentIndex.index
- ç¤ºä¾‹é¡¹ç›® pages/updata/updata.vue增加滚动条拖动更新(数据动态打点)的demo
- ç¤ºä¾‹é¡¹ç›® pages/other/other.vue增加errorReload禁用错误点击重新加载的demo
## 2.1.2-20210509(2021-05-09)
秋云图表组件 ä¿®å¤APP端初始化时就传入chartData或lacaldata不显示图表的bug
## 2.1.1-20210509(2021-05-09)
- ç§‹äº‘图表组件 å˜æ›´ECharts的eopts配置在renderjs内执行,支持在config-echarts.js配置文件内写function配置。
- ç§‹äº‘图表组件 ä¿®å¤APP端报错Prop being mutated: "onmouse"错误的bug。
- ç§‹äº‘图表组件 ä¿®å¤APP端报错Error: Not Found:Page[6][-1,27] at view.umd.min.js:1的bug。
## 2.1.0-20210507(2021-05-07)
- ç§‹äº‘图表组件 ä¿®å¤åˆå§‹åŒ–时就有数据或者数据更新的时候loading加载动画闪动的bug
- uCharts.js ä¿®å¤xè½´format方法categories为字符串类型时返回NaN的bug
- uCharts.js ä¿®å¤series.textColor、legend.fontColor未执行全局默认颜色的bug
## 2.1.0-20210506(2021-05-06)
- ç§‹äº‘图表组件 ä¿®å¤æžä¸ªåˆ«æƒ…况下报错item.properties undefined的bug
- ç§‹äº‘图表组件 ä¿®å¤æžä¸ªåˆ«æƒ…况下关闭加载动画reshow不起作用,无法显示图表的bug
- ç¤ºä¾‹é¡¹ç›® pages/ucharts/ucharts.vue å¢žåŠ æ—¶é—´è½´æŠ˜çº¿å›¾ï¼ˆtype="tline")、时间轴区域图(type="tarea")、散点图(type="scatter")、气泡图demo(type="bubble")、倒三角形漏斗图(opts.extra.funnel.type="triangle")、金字塔形漏斗图(opts.extra.funnel.type="pyramid")
- ç¤ºä¾‹é¡¹ç›® pages/format-u/format-u.vue å¢žåŠ Xè½´format格式化示例
- uCharts.js å‡çº§è‡³v2.1.0版本
- uCharts.js ä¿®å¤ çŽ«ç‘°å›¾é¢ç§¯æ¨¡å¼ç‚¹å‡»tooltip位置不正确的bug
- uCharts.js ä¿®å¤ çŽ«ç‘°å›¾ç‚¹å‡»å›¾ä¾‹ï¼Œåªå‰©ä¸€ä¸ªç±»åˆ«æ˜¾ç¤ºç©ºç™½çš„bug
- uCharts.js ä¿®å¤ é¥¼å›¾ç±»å›¾ç‚¹å‡»å›¾ä¾‹ï¼Œå…¶ä»–图表tooltip位置某些情况下不准的bug
- uCharts.js ä¿®å¤ x轴为矢量轴(时间轴)情况下,点击tooltip位置不正确的bug
- uCharts.js ä¿®å¤ è¯äº‘图获取点击索引偶尔不准的bug
- uCharts.js å¢žåŠ  ç›´è§’坐标系图表Xè½´format格式化方法(原生uCharts.js用法请使用formatter)
- uCharts.js å¢žåŠ  æ¼æ–—图扩展配置,倒三角形(opts.extra.funnel.type="triangle"),金字塔形(opts.extra.funnel.type="pyramid")
- uCharts.js å¢žåŠ  æ•£ç‚¹å›¾ï¼ˆopts.type="scatter")、气泡图(opts.type="bubble")
- åŽæœŸè®¡åˆ’ å®Œå–„散点图、气泡图,增加markPoints标记点,增加横向条状图。
## 2.0.0-20210502(2021-05-02)
- uCharts.js ä¿®å¤è¯äº‘图获取点击索引不正确的bug
## 2.0.0-20210501(2021-05-01)
- ç§‹äº‘图表组件 ä¿®å¤QQ小程序、百度小程序在关闭动画效果情况下,v-for循环使用图表,显示不正确的bug
## 2.0.0-20210426(2021-04-26)
- ç§‹äº‘图表组件 ä¿®å¤QQ小程序不支持canvas2d的bug
- ç§‹äº‘图表组件 ä¿®å¤é’‰é’‰å°ç¨‹åºæŸäº›æƒ…况点击坐标计算错误的bug
- uCharts.js å¢žåŠ  extra.column.categoryGap å‚数,柱状图类每个category点位(X轴点)柱子组之间的间距
- uCharts.js å¢žåŠ  yAxis.data[i].titleOffsetY å‚数,标题纵向偏移距离,负数为向上偏移,正数向下偏移
- uCharts.js å¢žåŠ  yAxis.data[i].titleOffsetX å‚数,标题横向偏移距离,负数为向左偏移,正数向右偏移
- uCharts.js å¢žåŠ  extra.gauge.labelOffset å‚数,仪表盘标签文字径向便宜距离,默认13px
## 2.0.0-20210422-2(2021-04-22)
秋云图表组件 ä¿®å¤ formatterAssign æœªåˆ¤æ–­ args[key] == null çš„æƒ…况导致栈溢出的 bug
## 2.0.0-20210422(2021-04-22)
- ç§‹äº‘图表组件 ä¿®å¤H5、APP、支付宝小程序、微信小程序canvas2d模式下横屏模式的bug
## 2.0.0-20210421(2021-04-21)
- uCharts.js ä¿®å¤å¤šè¡Œå›¾ä¾‹çš„æƒ…况下,图例在上方或者下方时,图例float为左侧或者右侧时,第二行及以后的图例对齐方式不正确的bug
## 2.0.0-20210420(2021-04-20)
- ç§‹äº‘图表组件 ä¿®å¤å¾®ä¿¡å°ç¨‹åºå¼€å¯canvas2d模式后,windows版微信小程序不支持canvas2d模式的bug
- ç§‹äº‘图表组件 ä¿®æ”¹éžuni_modules版本为v2.0版本qiun-data-charts组件
## 2.0.0-20210419(2021-04-19)
## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
## åˆæ¬¡ä½¿ç”¨å¦‚果提示未注册&lt;qiun-data-charts&gt;组件,请重启HBuilderX,如仍不好用,请重启电脑;
## å¦‚果是cli项目,请尝试清理node_modules,重新install,还不行就删除项目,再重新install。
## æ­¤é—®é¢˜å·²äºŽDCloud官方确认,HBuilderX下个版本会修复。
## å…¶ä»–图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn)
## <font color=#FF0000> æ–°æ‰‹è¯·å…ˆå®Œæ•´é˜…读帮助文档及常见问题3遍,右侧蓝色按钮示例项目请看2遍! </font>
## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
- uCharts.js ä¿®å¤æ··åˆå›¾ä¸­æŸ±çŠ¶å›¾å•ç‹¬è®¾ç½®é¢œè‰²ä¸ç”Ÿæ•ˆçš„bug
- uCharts.js ä¿®å¤å¤šY轴单独设置fontSize时,开启canvas2d后,未对应放大字体的bug
## 2.0.0-20210418(2021-04-18)
- ç§‹äº‘图表组件 å¢žåŠ directory配置,修复H5端history模式下如果发布到二级目录无法正确加载echarts.min.js的bug
## 2.0.0-20210416(2021-04-16)
## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
## åˆæ¬¡ä½¿ç”¨å¦‚果提示未注册&lt;qiun-data-charts&gt;组件,请重启HBuilderX,如仍不好用,请重启电脑;
## å¦‚果是cli项目,请尝试清理node_modules,重新install,还不行就删除项目,再重新install。
## æ­¤é—®é¢˜å·²äºŽDCloud官方确认,HBuilderX下个版本会修复。
## å…¶ä»–图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn)
## <font color=#FF0000> æ–°æ‰‹è¯·å…ˆå®Œæ•´é˜…读帮助文档及常见问题3遍,右侧蓝色按钮示例项目请看2遍! </font>
## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
- ç§‹äº‘图表组件 ä¿®å¤APP端某些情况下报错`Not Found Page`的bug,fix by é«˜çº§bug开发技术员
- ç¤ºä¾‹é¡¹ç›® ä¿®å¤APP端v-for循环某些情况下报错`Not Found Page`的bug,fix by é«˜çº§bug开发技术员
- uCharts.js ä¿®å¤éžç›´è§’坐标系tooltip提示窗右侧超出未变换方向显示的bug
## 2.0.0-20210415(2021-04-15)
- ç§‹äº‘图表组件 ä¿®å¤H5端发布到二级目录下echarts无法加载的bug
- ç§‹äº‘图表组件 ä¿®å¤æŸäº›æƒ…况下echarts.off('finished')移除监听事件报错的bug
## 2.0.0-20210414(2021-04-14)
## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
## åˆæ¬¡ä½¿ç”¨å¦‚果提示未注册&lt;qiun-data-charts&gt;组件,请重启HBuilderX,如仍不好用,请重启电脑;
## å¦‚果是cli项目,请尝试清理node_modules,重新install,还不行就删除项目,再重新install。
## æ­¤é—®é¢˜å·²äºŽDCloud官方确认,HBuilderX下个版本会修复。
## å…¶ä»–图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn)
## <font color=#FF0000> æ–°æ‰‹è¯·å…ˆå®Œæ•´é˜…读帮助文档及常见问题3遍,右侧蓝色按钮示例项目请看2遍! </font>
## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
- ç§‹äº‘图表组件 ä¿®å¤H5端在cli项目下ECharts引用地址错误的bug
- ç¤ºä¾‹é¡¹ç›® å¢žåŠ ECharts的formatter用法的示例(详见示例项目format-e.vue)
- uCharts.js å¢žåŠ åœ†çŽ¯å›¾ä¸­å¿ƒèƒŒæ™¯è‰²çš„é…ç½®extra.ring.centerColor
- uCharts.js ä¿®å¤å¾®ä¿¡å°ç¨‹åºå®‰å“端柱状图开启透明色后显示不正确的bug
## 2.0.0-20210413(2021-04-13)
- ç§‹äº‘图表组件 ä¿®å¤ç™¾åº¦å°ç¨‹åºå¤šä¸ªå›¾è¡¨çœŸæœºæœªèƒ½æ­£ç¡®èŽ·å–æ ¹å…ƒç´ dom尺寸的bug
- ç§‹äº‘图表组件 ä¿®å¤ç™¾åº¦å°ç¨‹åºæ¨ªå±æ¨¡å¼æ–¹å‘不正确的bug
- ç§‹äº‘图表组件 ä¿®æ”¹ontouch时,@getTouchStart@getTouchMove@getTouchEnd的触发条件
- uCharts.js ä¿®å¤é¥¼å›¾ç±»æ•°æ®æ ¼å¼series属性不生效的bug
- uCharts.js å¢žåŠ æ—¶åºåŒºåŸŸå›¾ è¯¦è§ç¤ºä¾‹é¡¹ç›®ä¸­ucharts.vue
## 2.0.0-20210412-2(2021-04-12)
## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
## åˆæ¬¡ä½¿ç”¨å¦‚果提示未注册&lt;qiun-data-charts&gt;组件,请重启HBuilderX。如仍不好用,请重启电脑,此问题已于DCloud官方确认,HBuilderX下个版本会修复。
## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
## [图表组件在uniCloudAdmin中的应用 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
- ç§‹äº‘图表组件 ä¿®å¤uCharts在APP端横屏模式下不能正确渲染的bug
- ç¤ºä¾‹é¡¹ç›® å¢žåŠ ECharts柱状图渐变色、圆角柱状图、横向柱状图(条状图)的示例
## 2.0.0-20210412(2021-04-12)
- ç§‹äº‘图表组件 ä¿®å¤created中判断echarts导致APP端无法识别,改回mounted中判断echarts初始化
- uCharts.js ä¿®å¤2d模式下series.textOffset未乘像素比的bug
## 2.0.0-20210411(2021-04-11)
## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
## åˆæ¬¡ä½¿ç”¨å¦‚果提示未注册<qiun-data-charts>组件,请重启HBuilderX,并清空小程序开发者工具缓存。
## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
## [图表组件在uniCloudAdmin中的应用 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
- uCharts.js æŠ˜çº¿å›¾åŒºåŸŸå›¾å¢žåŠ connectNulls断点续连的功能,详见示例项目中ucharts.vue
- ç§‹äº‘图表组件 å˜æ›´åˆå§‹åŒ–方法为created,变更type2d默认值为true,优化2d模式下组件初始化后dom获取不到的bug
- ç§‹äº‘图表组件 ä¿®å¤å·¦å³å¸ƒå±€æ—¶ï¼Œå³ä¾§å›¾è¡¨ç‚¹å‡»åæ ‡é”™è¯¯çš„bug,修复tooltip柱状图自定义颜色显示object的bug
## 2.0.0-20210410(2021-04-10)
- ä¿®å¤å·¦å³å¸ƒå±€æ—¶ï¼Œå³ä¾§å›¾è¡¨ç‚¹å‡»åæ ‡é”™è¯¯çš„bug,修复柱状图自定义颜色tooltip显示object的bug
- å¢žåŠ æ ‡è®°çº¿åŠæŸ±çŠ¶å›¾è‡ªå®šä¹‰é¢œè‰²çš„demo
## 2.0.0-20210409(2021-04-08)
## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧【使用HBuilderX导入插件】即可体验,DEMO演示及在线生成工具(v2.0文档)[https://demo.ucharts.cn](https://demo.ucharts.cn)
## å›¾è¡¨ç»„件在uniCloudAdmin中的应用 [UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
- uCharts.js ä¿®å¤é’‰é’‰å°ç¨‹åºç™¾åº¦å°ç¨‹åºmeasureText不准确的bug,修复2d模式下饼图类activeRadius为按比例放大的bug
- ä¿®å¤ç»„件在支付宝小程序端点击位置不准确的bug
## 2.0.0-20210408(2021-04-07)
- ä¿®å¤ç»„件在支付宝小程序端不能显示的bug(目前支付宝小程不能点击交互,后续修复)
- uCharts.js ä¿®å¤é«˜åˆ†å±ä¸‹æŸ±çŠ¶å›¾ç±»ï¼Œåœ†å¼§è¿›åº¦æ¡ è‡ªå®šä¹‰å®½åº¦ä¸èƒ½æŒ‰æ¯”例放大的bug
## 2.0.0-20210407(2021-04-06)
## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧【使用HBuilderX导入插件】即可体验,DEMO演示及在线生成工具(v2.0文档)[https://demo.ucharts.cn](https://demo.ucharts.cn)
## å¢žåŠ  é€šè¿‡tofix和unit快速格式化y轴的demo add by `howcode`
## å¢žåŠ  å›¾è¡¨ç»„件在uniCloudAdmin中的应用 [UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
## 2.0.0-20210406(2021-04-05)
# ç§‹äº‘图表组件+uCharts v2.0版本同步上线,使用方法详见https://demo.ucharts.cn帮助页
## 2.0.0(2021-04-05)
# ç§‹äº‘图表组件+uCharts v2.0版本同步上线,使用方法详见https://demo.ucharts.cn帮助页
uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1607 @@
<!--
 * qiun-data-charts ç§‹äº‘高性能跨全端图表组件
 * Copyright (c) 2021 QIUN® ç§‹äº‘ https://www.ucharts.cn All rights reserved.
 * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 * å¤åˆ¶ä½¿ç”¨è¯·ä¿ç•™æœ¬æ®µæ³¨é‡Šï¼Œæ„Ÿè°¢æ”¯æŒå¼€æºï¼
 * ä¸ºæ–¹ä¾¿æ›´å¤šå¼€å‘者使用,如有更好的建议请提交码云 Pull Requests ï¼
 *
 * uCharts®官方网站
 * https://www.uCharts.cn
 *
 * å¼€æºåœ°å€:
 * https://gitee.com/uCharts/uCharts
 *
 * uni-app插件市场地址:
 * http://ext.dcloud.net.cn/plugin?id=271
 *
 -->
<template>
  <view class="chartsview" :id="'ChartBoxId'+cid">
    <view v-if="mixinDatacomLoading">
      <!-- è‡ªå®šä¹‰åŠ è½½çŠ¶æ€ï¼Œè¯·æ”¹è¿™é‡Œ -->
      <qiun-loading :loadingType="loadingType" />
    </view>
    <view v-if="mixinDatacomErrorMessage && errorShow" @tap="reloading">
      <!-- è‡ªå®šä¹‰é”™è¯¯æç¤ºï¼Œè¯·æ”¹è¿™é‡Œ -->
      <qiun-error :errorMessage="errorMessage" />
    </view>
    <!-- APP和H5采用renderjs渲染图表 -->
    <!-- #ifdef APP-VUE || H5 -->
    <block v-if="echarts">
      <view
        :style="{ background: background }"
        style="width: 100%;height: 100%;"
        :data-directory="directory"
        :id="'EC'+cid"
        :prop="echartsOpts"
        :change:prop="rdcharts.ecinit"
        :resize="echartsResize"
        :change:resize="rdcharts.ecresize"
        v-show="showchart"
      />
    </block>
    <block v-else>
      <view
        v-on:tap="rdcharts.tap"
        v-on:mousemove="rdcharts.mouseMove"
        v-on:mousedown="rdcharts.mouseDown"
        v-on:mouseup="rdcharts.mouseUp"
        v-on:touchstart="rdcharts.touchStart"
        v-on:touchmove="rdcharts.touchMove"
        v-on:touchend="rdcharts.touchEnd"
        :id="'UC'+cid"
        :prop="uchartsOpts"
        :change:prop="rdcharts.ucinit"
      >
        <canvas
          :id="cid"
          :canvasId="cid"
          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
          :disable-scroll="disableScroll"
          @error="_error"
          v-show="showchart"
        />
      </view>
    </block>
    <!-- #endif -->
    <!-- æ”¯ä»˜å®å°ç¨‹åº -->
    <!-- #ifdef MP-ALIPAY -->
    <block v-if="ontouch">
      <canvas
        :id="cid"
        :canvasId="cid"
        :width="cWidth * pixel"
        :height="cHeight * pixel"
        :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
        :disable-scroll="disScroll"
        @tap="_tap"
        @touchstart="_touchStart"
        @touchmove="_touchMove"
        @touchend="_touchEnd"
        @error="_error"
        v-show="showchart"
      />
    </block>
    <block v-if="!ontouch">
      <canvas
        :id="cid"
        :canvasId="cid"
        :width="cWidth * pixel"
        :height="cHeight * pixel"
        :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
        :disable-scroll="disScroll"
        @tap="_tap"
        @error="_error"
        v-show="showchart"
      />
    </block>
    <!-- #endif -->
    <!-- å…¶ä»–小程序通过vue渲染图表 -->
    <!-- #ifdef MP-360 || MP-BAIDU || MP-QQ || MP-TOUTIAO || MP-WEIXIN || MP-KUAISHOU || MP-LARK || MP-JD -->
    <block v-if="type2d">
      <view v-if="ontouch" @tap="_tap">
        <canvas
          :id="cid"
          :canvasId="cid"
          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
          type="2d"
          :disable-scroll="disScroll"
          @touchstart="_touchStart"
          @touchmove="_touchMove"
          @touchend="_touchEnd"
          @error="_error"
          v-show="showchart"
        />
      </view>
      <view v-if="!ontouch" @tap="_tap">
        <canvas
          :id="cid"
          :canvasId="cid"
          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
          type="2d"
          :disable-scroll="disScroll"
          @error="_error"
          v-show="showchart"
        />
      </view>
    </block>
    <block v-if="!type2d">
      <view v-if="ontouch" @tap="_tap">
        <canvas
          :id="cid"
          :canvasId="cid"
          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
          @touchstart="_touchStart"
          @touchmove="_touchMove"
          @touchend="_touchEnd"
          :disable-scroll="disScroll"
          @error="_error"
          v-if="showchart"
        />
      </view>
      <view v-if="!ontouch" >
        <canvas
          :id="cid"
          :canvasId="cid"
          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
          :disable-scroll="disScroll"
          @tap="_tap"
          @error="_error"
          v-if="showchart"
        />
      </view>
    </block>
    <!-- #endif -->
  </view>
</template>
<script>
import uCharts from '../../js_sdk/u-charts/u-charts.js';
import cfu from '../../js_sdk/u-charts/config-ucharts.js';
// #ifdef APP-VUE || H5
import cfe from '../../js_sdk/u-charts/config-echarts.js';
// #endif
function deepCloneAssign(origin = {}, ...args) {
  for (let i in args) {
    for (let key in args[i]) {
      if (args[i].hasOwnProperty(key)) {
        origin[key] = args[i][key] && typeof args[i][key] === 'object' ? deepCloneAssign(Array.isArray(args[i][key]) ? [] : {}, origin[key], args[i][key]) : args[i][key];
      }
    }
  }
  return origin;
}
function formatterAssign(args,formatter) {
  for (let key in args) {
    if(args.hasOwnProperty(key) && args[key] !== null && typeof args[key] === 'object'){
      formatterAssign(args[key],formatter)
    }else if(key === 'format' && typeof args[key] === 'string'){
      args['formatter'] = formatter[args[key]] ? formatter[args[key]] : undefined;
    }
  }
  return args;
}
// æ—¶é—´è½¬æ¢å‡½æ•°ï¼Œä¸ºäº†åŒ¹é…uniClinetDB读取出的时间与categories不同
function getFormatDate(date) {
    var seperator = "-";
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var strDate = date.getDate();
    if (month >= 1 && month <= 9) {
            month = "0" + month;
    }
    if (strDate >= 0 && strDate <= 9) {
            strDate = "0" + strDate;
    }
    var currentdate = year + seperator + month + seperator + strDate;
    return currentdate;
}
var lastMoveTime = null;
/**
 * é˜²æŠ–
 *
 * @param { Function } fn è¦æ‰§è¡Œçš„æ–¹æ³•
 * @param { Number } wait  é˜²æŠ–多少毫秒
 *
 * åœ¨ vue ä¸­ä½¿ç”¨ï¼ˆæ³¨æ„ï¼šä¸èƒ½ä½¿ç”¨ç®­å¤´å‡½æ•°ï¼Œå¦åˆ™this指向不对,并且不能再次封装如:
 * move(){  // é”™è¯¯è°ƒç”¨æ–¹å¼
 *   debounce(function () {
 *   console.log(this.title);
 * }, 1000)});
 * åº”该直接使用:// æ­£ç¡®è°ƒç”¨æ–¹å¼
 * move: debounce(function () {
 *   console.log(this.title);
 * }, 1000)
 */
function debounce(fn, wait) {
  let timer = false;
  return function() {
    clearTimeout(timer);
    timer && clearTimeout(timer);
    timer = setTimeout(() => {
      timer = false;
      fn.apply(this, arguments); // æŠŠå‚数传进去
    }, wait);
  };
}
export default {
  name: 'qiun-data-charts',
  mixins: [uniCloud.mixinDatacom],
  props: {
    type: {
      type: String,
      default: null
    },
    canvasId: {
      type: String,
      default: 'uchartsid'
    },
    canvas2d: {
      type: Boolean,
      default: false
    },
    background: {
      type: String,
      default: 'rgba(0,0,0,0)'
    },
    animation: {
      type: Boolean,
      default: true
    },
    chartData: {
      type: Object,
      default() {
        return {
          categories: [],
          series: []
        };
      }
    },
    opts: {
      type: Object,
      default() {
        return {};
      }
    },
    eopts: {
      type: Object,
      default() {
        return {};
      }
    },
    loadingType: {
      type: Number,
      default: 2
    },
    errorShow: {
      type: Boolean,
      default: true
    },
    errorReload: {
      type: Boolean,
      default: true
    },
    errorMessage: {
      type: String,
      default: null
    },
    inScrollView: {
      type: Boolean,
      default: false
    },
    reshow: {
      type: Boolean,
      default: false
    },
    reload: {
      type: Boolean,
      default: false
    },
    disableScroll: {
      type: Boolean,
      default: false
    },
    optsWatch: {
      type: Boolean,
      default: true
    },
    onzoom: {
      type: Boolean,
      default: false
    },
    ontap: {
      type: Boolean,
      default: true
    },
    ontouch: {
      type: Boolean,
      default: false
    },
    onmouse: {
      type: Boolean,
      default: true
    },
    onmovetip: {
      type: Boolean,
      default: false
    },
    echartsH5: {
      type: Boolean,
      default: false
    },
    echartsApp: {
      type: Boolean,
      default: false
    },
    tooltipShow: {
      type: Boolean,
      default: true
    },
    tooltipFormat: {
      type: String,
      default: undefined
    },
    tooltipCustom: {
      type: Object,
      default: undefined
    },
    startDate: {
      type: String,
      default: undefined
    },
    endDate: {
      type: String,
      default: undefined
    },
    textEnum: {
      type: Array,
      default () {
        return []
      }
    },
    groupEnum: {
      type: Array,
      default () {
        return []
      }
    },
    pageScrollTop: {
      type: Number,
      default: 0
    },
    directory: {
      type: String,
      default: '/'
    },
    tapLegend: {
      type: Boolean,
      default: true
    },
    menus: {
      type: Array,
      default () {
        return []
      }
    }
  },
  data() {
    return {
      cid: 'uchartsid',
      inWx: false,
      inAli: false,
      inTt: false,
      inBd: false,
      inH5: false,
      inApp: false,
      inWin: false,
      type2d: true,
      disScroll: false,
      openmouse: false,
      pixel: 1,
      cWidth: 375,
      cHeight: 250,
      showchart: false,
      echarts: false,
      echartsResize:false,
      uchartsOpts: {},
      echartsOpts: {},
      drawData:{},
      lastDrawTime:null,
    };
  },
  created(){
    this.cid = this.canvasId
    if (this.canvasId == 'uchartsid' || this.canvasId == '') {
      let t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
      let len = t.length
      let id = ''
      for (let i = 0; i < 32; i++) {
        id += t.charAt(Math.floor(Math.random() * len))
      }
      this.cid = id
    }
    const systemInfo = uni.getSystemInfoSync()
    if(systemInfo.platform === 'windows' || systemInfo.platform === 'mac'){
      this.inWin = true;
    }
    // #ifdef MP-WEIXIN
    this.inWx = true;
    if (this.canvas2d === false || systemInfo.platform === 'windows' || systemInfo.platform === 'mac') {
      this.type2d = false;
    }else{
      this.type2d = true;
      this.pixel = systemInfo.pixelRatio;
    }
    // #endif
    //非微信小程序端强制关闭canvas2d模式
    // #ifndef MP-WEIXIN
    this.type2d = false;
    // #endif
    // #ifdef  MP-TOUTIAO || MP-LARK || MP-ALIPAY
    this.type2d = this.canvas2d;
    // #endif
    // #ifdef MP-ALIPAY
    this.inAli = true;
    this.pixel = systemInfo.pixelRatio;
    // #endif
    // #ifdef MP-BAIDU
    this.inBd = true;
    // #endif
    // #ifdef MP-TOUTIAO
    this.inTt = true;
    // #endif
    this.disScroll = this.disableScroll;
  },
  mounted() {
    // #ifdef APP-VUE
    this.inApp = true;
    if (this.echartsApp === true) {
      this.echarts = true;
      this.openmouse = false;
    }
    // #endif
    // #ifdef APP-NVUE
    this.inApp = true;
    this.mixinDatacomLoading = false
    this.mixinDatacomErrorMessage = "暂不支持NVUE"
    // #endif
    // #ifdef H5
    this.inH5 = true;
    if(this.inWin === true){
      this.openmouse = this.onmouse;
    }
    if (this.echartsH5 === true) {
      this.echarts = true;
    }
    // #endif
    this.$nextTick(()=>{
      this.beforeInit();
    })
    // #ifndef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || APP-VUE
    const time = this.inH5 ? 500 : 200;
    const _this = this;
    uni.onWindowResize(
      debounce(function(res) {
        if (_this.mixinDatacomLoading == true) {
          return;
        }
        let errmsg = _this.mixinDatacomErrorMessage;
        if (errmsg !== null && errmsg !== 'null' && errmsg !== '') {
          return;
        }
        if (_this.echarts) {
          _this.echartsResize = !_this.echartsResize;
        } else {
          _this.resizeHandler();
        }
      }, time)
    );
    // #endif
  },
  destroyed(){
    if(this.echarts === true){
      delete cfe.option[this.cid]
      delete cfe.instance[this.cid]
    }else{
      delete cfu.option[this.cid]
      delete cfu.instance[this.cid]
    }
    // #ifndef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
    uni.offWindowResize(()=>{})
    // #endif
  },
  watch: {
    chartDataProps: {
      handler(val, oldval) {
        if (typeof val === 'object') {
          if (JSON.stringify(val) !== JSON.stringify(oldval)) {
            this._clearChart();
            if (val.series && val.series.length > 0) {
              this.beforeInit();
            }else{
              this.mixinDatacomLoading = true;
              this.showchart = false;
              this.mixinDatacomErrorMessage = null;
            }
          }
        } else {
          this.mixinDatacomLoading = false;
          this._clearChart();
          this.showchart = false;
          this.mixinDatacomErrorMessage = '参数错误:chartData数据类型错误';
        }
      },
      immediate: false,
      deep: true
    },
    localdata:{
      handler(val, oldval) {
        if (JSON.stringify(val) !== JSON.stringify(oldval)) {
          if (val.length > 0) {
            this.beforeInit();
          }else{
            this.mixinDatacomLoading = true;
            this._clearChart();
            this.showchart = false;
            this.mixinDatacomErrorMessage = null;
          }
        }
      },
      immediate: false,
      deep: true
    },
    optsProps: {
      handler(val, oldval) {
        if (typeof val === 'object') {
          if (JSON.stringify(val) !== JSON.stringify(oldval) && this.echarts === false && this.optsWatch == true) {
            this.checkData(this.drawData);
          }
        } else {
          this.mixinDatacomLoading = false;
          this._clearChart();
          this.showchart = false;
          this.mixinDatacomErrorMessage = '参数错误:opts数据类型错误';
        }
      },
      immediate: false,
      deep: true
    },
    eoptsProps: {
      handler(val, oldval) {
        if (typeof val === 'object') {
          if (JSON.stringify(val) !== JSON.stringify(oldval) && this.echarts === true) {
            this.checkData(this.drawData);
          }
        } else {
          this.mixinDatacomLoading = false;
          this.showchart = false;
          this.mixinDatacomErrorMessage = '参数错误:eopts数据类型错误';
        }
      },
      immediate: false,
      deep: true
    },
    reshow(val, oldval) {
      if (val === true && this.mixinDatacomLoading === false) {
        setTimeout(() => {
          this.mixinDatacomErrorMessage = null;
          this.echartsResize = !this.echartsResize;
          this.checkData(this.drawData);
        }, 200);
      }
    },
    reload(val, oldval) {
      if (val === true) {
        this.showchart = false;
        this.mixinDatacomErrorMessage = null;
        this.reloading();
      }
    },
    mixinDatacomErrorMessage(val, oldval) {
      if (val) {
        this.emitMsg({name: 'error', params: {type:"error", errorShow: this.errorShow, msg: val, id: this.cid}});
        if(this.errorShow){
          console.log('[秋云图表组件]' + val);
        }
      }
    },
    errorMessage(val, oldval) {
      if (val && this.errorShow && val !== null && val !== 'null' && val !== '') {
        this.showchart = false;
        this.mixinDatacomLoading = false;
        this.mixinDatacomErrorMessage = val;
      } else {
        this.showchart = false;
        this.mixinDatacomErrorMessage = null;
        this.reloading();
      }
    }
  },
  computed: {
    optsProps() {
      return JSON.parse(JSON.stringify(this.opts));
    },
    eoptsProps() {
      return JSON.parse(JSON.stringify(this.eopts));
    },
    chartDataProps() {
      return JSON.parse(JSON.stringify(this.chartData));
    },
  },
  methods: {
    beforeInit(){
      this.mixinDatacomErrorMessage = null;
      if (typeof this.chartData === 'object' && this.chartData != null && this.chartData.series !== undefined && this.chartData.series.length > 0) {
        //拷贝一下chartData,为了opts变更后统一数据来源
        this.drawData = deepCloneAssign({}, this.chartData);
        this.mixinDatacomLoading = false;
        this.showchart = true;
        this.checkData(this.chartData);
      }else if(this.localdata.length>0){
        this.mixinDatacomLoading = false;
        this.showchart = true;
        this.localdataInit(this.localdata);
      }else if(this.collection !== ''){
        this.mixinDatacomLoading = false;
        this.getCloudData();
      }else{
        this.mixinDatacomLoading = true;
      }
    },
    localdataInit(resdata){
      //替换enum类型为正确的描述
      if(this.groupEnum.length>0){
        for (let i = 0; i < resdata.length; i++) {
          for (let j = 0; j < this.groupEnum.length; j++) {
            if(resdata[i].group === this.groupEnum[j].value){
              resdata[i].group = this.groupEnum[j].text
            }
          }
        }
      }
      if(this.textEnum.length>0){
        for (let i = 0; i < resdata.length; i++) {
          for (let j = 0; j < this.textEnum.length; j++) {
            if(resdata[i].text === this.textEnum[j].value){
              resdata[i].text = this.textEnum[j].text
            }
          }
        }
      }
      let needCategories = false;
      let tmpData = {categories:[], series:[]}
      let tmpcategories = []
      let tmpseries = [];
      //拼接categories
      if(this.echarts === true){
        needCategories = cfe.categories.includes(this.type)
      }else{
        needCategories = cfu.categories.includes(this.type)
      }
      if(needCategories === true){
        //如果props中的chartData带有categories,则优先使用chartData的categories
        if(this.chartData && this.chartData.categories && this.chartData.categories.length>0){
          tmpcategories = this.chartData.categories
        }else{
          //如果是日期类型的数据,不管是本地数据还是云数据,都按起止日期自动拼接categories
          if(this.startDate && this.endDate){
            let idate = new Date(this.startDate)
            let edate = new Date(this.endDate)
            while (idate <= edate) {
                tmpcategories.push(getFormatDate(idate))
                idate = idate.setDate(idate.getDate() + 1)
                idate = new Date(idate)
            }
          //否则从结果中去重并拼接categories
          }else{
            let tempckey = {};
            resdata.map(function(item, index) {
              if (item.text != undefined && !tempckey[item.text]) {
                tmpcategories.push(item.text)
                tempckey[item.text] = true
              }
            });
          }
        }
        tmpData.categories = tmpcategories
      }
      //拼接series
      let tempskey = {};
      resdata.map(function(item, index) {
        if (item.group != undefined && !tempskey[item.group]) {
          tmpseries.push({ name: item.group, data: [] });
          tempskey[item.group] = true;
        }
      });
      //如果没有获取到分组名称(可能是带categories的数据,也可能是不带的饼图类)
      if (tmpseries.length == 0) {
        tmpseries = [{ name: '默认分组', data: [] }];
        //如果是需要categories的图表类型
        if(needCategories === true){
          for (let j = 0; j < tmpcategories.length; j++) {
            let seriesdata = 0;
            for (let i = 0; i < resdata.length; i++) {
              if (resdata[i].text == tmpcategories[j]) {
                seriesdata = resdata[i].value;
              }
            }
            tmpseries[0].data.push(seriesdata);
          }
        //如果是饼图类的图表类型
        }else{
          for (let i = 0; i < resdata.length; i++) {
            tmpseries[0].data.push({"name": resdata[i].text,"value": resdata[i].value});
          }
        }
      //如果有分组名
      } else {
        for (let k = 0; k < tmpseries.length; k++) {
          //如果有categories
          if (tmpcategories.length > 0) {
            for (let j = 0; j < tmpcategories.length; j++) {
              let seriesdata = 0;
              for (let i = 0; i < resdata.length; i++) {
                if (tmpseries[k].name == resdata[i].group && resdata[i].text == tmpcategories[j]) {
                  seriesdata = resdata[i].value;
                }
              }
              tmpseries[k].data.push(seriesdata);
            }
          //如果传了group而没有传text,即没有categories(正常情况下这种数据是不符合数据要求规范的)
          } else {
            for (let i = 0; i < resdata.length; i++) {
              if (tmpseries[k].name == resdata[i].group) {
                tmpseries[k].data.push(resdata[i].value);
              }
            }
          }
        }
      }
      tmpData.series = tmpseries
      //拷贝一下chartData,为了opts变更后统一数据来源
      this.drawData = deepCloneAssign({}, tmpData);
      this.checkData(tmpData)
    },
    reloading() {
      if(this.errorReload === false){
        return;
      }
      this.showchart = false;
      this.mixinDatacomErrorMessage = null;
      if (this.collection !== '') {
        this.mixinDatacomLoading = false;
        this.onMixinDatacomPropsChange(true);
      } else {
        this.beforeInit();
      }
    },
    checkData(anyData) {
      let cid = this.cid
      //复位opts或eopts
      if(this.echarts === true){
        cfe.option[cid] = deepCloneAssign({}, this.eopts);
        cfe.option[cid].id = cid;
        cfe.option[cid].type = this.type;
      }else{
        if (this.type && cfu.type.includes(this.type)) {
          cfu.option[cid] = deepCloneAssign({}, cfu[this.type], this.opts);
          cfu.option[cid].canvasId = cid;
        } else {
          this.mixinDatacomLoading = false;
          this.showchart = false;
          this.mixinDatacomErrorMessage = '参数错误:props参数中type类型不正确';
        }
      }
      //挂载categories和series
      let newData = deepCloneAssign({}, anyData);
      if (newData.series !== undefined && newData.series.length > 0) {
        this.mixinDatacomErrorMessage = null;
        if (this.echarts === true) {
          cfe.option[cid].chartData = newData;
          this.$nextTick(()=>{
            this.init()
          })
        }else{
          cfu.option[cid].categories = newData.categories;
          cfu.option[cid].series = newData.series;
          this.$nextTick(()=>{
            this.init()
          })
        }
      }
    },
    resizeHandler() {
      //渲染防抖
      let currTime = Date.now();
      let lastDrawTime = this.lastDrawTime?this.lastDrawTime:currTime-3000;
      let duration = currTime - lastDrawTime;
      if (duration < 1000) return;
      let chartdom = uni
        .createSelectorQuery()
        // #ifndef MP-ALIPAY
        .in(this)
        // #endif
        .select('#ChartBoxId'+this.cid)
        .boundingClientRect(data => {
          this.showchart = true;
          if (data.width > 0 && data.height > 0) {
            if (data.width !== this.cWidth || data.height !== this.cHeight) {
              this.checkData(this.drawData)
            }
          }
        })
        .exec();
    },
    getCloudData() {
      if (this.mixinDatacomLoading == true) {
        return;
      }
      this.mixinDatacomLoading = true;
      this.mixinDatacomGet()
        .then(res => {
          this.mixinDatacomResData = res.result.data;
          this.localdataInit(this.mixinDatacomResData);
        })
        .catch(err => {
          this.mixinDatacomLoading = false;
          this.showchart = false;
          this.mixinDatacomErrorMessage = '请求错误:' + err;
        });
    },
    onMixinDatacomPropsChange(needReset, changed) {
      if (needReset == true && this.collection !== '') {
        this.showchart = false;
        this.mixinDatacomErrorMessage = null;
        this._clearChart();
        this.getCloudData();
      }
    },
    _clearChart() {
      let cid = this.cid
      if (this.echrts !== true && cfu.option[cid] && cfu.option[cid].context) {
        const ctx = cfu.option[cid].context;
        if(typeof ctx === "object" && !cfu.option[cid].update){
          ctx.clearRect(0, 0, this.cWidth, this.cHeight);
          ctx.draw();
        }
      }
    },
    init() {
      let cid = this.cid
      let chartdom = uni
        .createSelectorQuery()
        // #ifndef MP-ALIPAY
        .in(this)
        // #endif
        .select('#ChartBoxId'+cid)
        .boundingClientRect(data => {
          if (data.width > 0 && data.height > 0) {
            this.mixinDatacomLoading = false;
            this.showchart = true;
            this.lastDrawTime = Date.now();
            this.cWidth = data.width;
            this.cHeight = data.height;
            if(this.echarts !== true){
              cfu.option[cid].background = this.background == 'rgba(0,0,0,0)' ? '#FFFFFF' : this.background;
              cfu.option[cid].canvas2d = this.type2d;
              cfu.option[cid].pixelRatio = this.pixel;
              cfu.option[cid].animation = this.animation;
              cfu.option[cid].width = data.width * this.pixel;
              cfu.option[cid].height = data.height * this.pixel;
              cfu.option[cid].onzoom = this.onzoom;
              cfu.option[cid].ontap = this.ontap;
              cfu.option[cid].ontouch = this.ontouch;
              cfu.option[cid].onmouse = this.openmouse;
              cfu.option[cid].onmovetip = this.onmovetip;
              cfu.option[cid].tooltipShow = this.tooltipShow;
              cfu.option[cid].tooltipFormat = this.tooltipFormat;
              cfu.option[cid].tooltipCustom = this.tooltipCustom;
              cfu.option[cid].inScrollView = this.inScrollView;
              cfu.option[cid].lastDrawTime = this.lastDrawTime;
              cfu.option[cid].tapLegend = this.tapLegend;
            }
            //如果是H5或者App端,采用renderjs渲染图表
            if (this.inH5 || this.inApp) {
              if (this.echarts == true) {
                cfe.option[cid].ontap = this.ontap;
                cfe.option[cid].onmouse = this.openmouse;
                cfe.option[cid].tooltipShow = this.tooltipShow;
                cfe.option[cid].tooltipFormat = this.tooltipFormat;
                cfe.option[cid].tooltipCustom = this.tooltipCustom;
                cfe.option[cid].lastDrawTime = this.lastDrawTime;
                this.echartsOpts = deepCloneAssign({}, cfe.option[cid]);
              } else {
                cfu.option[cid].rotateLock = cfu.option[cid].rotate;
                this.uchartsOpts = deepCloneAssign({}, cfu.option[cid]);
              }
            //如果是小程序端,采用uCharts渲染
            } else {
              cfu.option[cid] = formatterAssign(cfu.option[cid],cfu.formatter)
              this.mixinDatacomErrorMessage = null;
              this.mixinDatacomLoading = false;
              this.showchart = true;
              this.$nextTick(()=>{
                if (this.type2d === true) {
                  const query = uni.createSelectorQuery().in(this)
                  query
                    .select('#' + cid)
                    .fields({ node: true, size: true })
                    .exec(res => {
                      if (res[0]) {
                        const canvas = res[0].node;
                        const ctx = canvas.getContext('2d');
                        cfu.option[cid].context = ctx;
                        cfu.option[cid].rotateLock = cfu.option[cid].rotate;
                        if(cfu.instance[cid] && cfu.option[cid] && cfu.option[cid].update === true){
                          this._updataUChart(cid)
                        }else{
                          canvas.width = data.width * this.pixel;
                          canvas.height = data.height * this.pixel;
                          canvas._width = data.width * this.pixel;
                          canvas._height = data.height * this.pixel;
                          setTimeout(()=>{
                            cfu.option[cid].context.restore();
                            cfu.option[cid].context.save();
                            this._newChart(cid)
                          },100)
                        }
                      } else {
                        this.showchart = false;
                        this.mixinDatacomErrorMessage = '参数错误:开启2d模式后,未获取到dom节点,canvas-id:' + cid;
                      }
                    });
                } else {
                  if(this.inAli){
                    cfu.option[cid].rotateLock = cfu.option[cid].rotate;
                  }
                  cfu.option[cid].context = uni.createCanvasContext(cid, this);
                  if(cfu.instance[cid] && cfu.option[cid] && cfu.option[cid].update === true){
                    this._updataUChart(cid)
                  }else{
                    setTimeout(()=>{
                      cfu.option[cid].context.restore();
                      cfu.option[cid].context.save();
                      this._newChart(cid)
                    },100)
                  }
                }
              })
            }
          } else {
            this.mixinDatacomLoading = false;
            this.showchart = false;
            if (this.reshow == true) {
              this.mixinDatacomErrorMessage = '布局错误:未获取到父元素宽高尺寸!canvas-id:' + cid;
            }
          }
        })
        .exec();
    },
    saveImage(){
        uni.canvasToTempFilePath({
          canvasId: this.cid,
          success: res=>{
            //#ifdef H5
                var a = document.createElement("a");
                a.href = res.tempFilePath;
                a.download = this.cid;
                a.target = '_blank'
                a.click();
            //#endif
            //#ifndef H5
              uni.saveImageToPhotosAlbum({
              filePath: res.tempFilePath,
              success: function () {
                uni.showToast({
                  title: '保存成功',
                  duration: 2000
                });
              }
              });
            //#endif
          }
        },this);
    },
    getImage(){
      if(this.type2d == false){
        uni.canvasToTempFilePath({
          canvasId: this.cid,
          success: res=>{
            this.emitMsg({name: 'getImage', params: {type:"getImage", base64: res.tempFilePath}});
          }
        },this);
      }else{
        const query = uni.createSelectorQuery().in(this)
        query
          .select('#' + this.cid)
          .fields({ node: true, size: true })
          .exec(res => {
            if (res[0]) {
              const canvas = res[0].node;
              this.emitMsg({name: 'getImage', params: {type:"getImage", base64: canvas.toDataURL('image/png')}});
            }
          });
      }
    },
    // #ifndef APP-VUE || H5
    _newChart(cid) {
      if (this.mixinDatacomLoading == true) {
        return;
      }
      this.showchart = true;
      cfu.instance[cid] = new uCharts(cfu.option[cid]);
      cfu.instance[cid].addEventListener('renderComplete', () => {
        this.emitMsg({name: 'complete', params: {type:"complete", complete: true, id: cid}});
        cfu.instance[cid].delEventListener('renderComplete')
      });
      cfu.instance[cid].addEventListener('scrollLeft', () => {
        this.emitMsg({name: 'scrollLeft', params: {type:"scrollLeft", scrollLeft: true, id: cid}});
      });
      cfu.instance[cid].addEventListener('scrollRight', () => {
        this.emitMsg({name: 'scrollRight', params: {type:"scrollRight", scrollRight: true, id: cid}});
      });
    },
    _updataUChart(cid) {
      cfu.instance[cid].updateData(cfu.option[cid])
    },
    _tooltipDefault(item, category, index, opts) {
      if (category) {
        let data = item.data
        if(typeof item.data === "object"){
          data = item.data.value
        }
        return category + ' ' + item.name + ':' + data;
      } else {
        if (item.properties && item.properties.name) {
          return item.properties.name;
        } else {
          return item.name + ':' + item.data;
        }
      }
    },
    _showTooltip(e) {
      let cid = this.cid
      let tc = cfu.option[cid].tooltipCustom
      if (tc && tc !== undefined && tc !== null) {
        let offset = undefined;
        if (tc.x >= 0 && tc.y >= 0) {
          offset = { x: tc.x, y: tc.y + 10 };
        }
        cfu.instance[cid].showToolTip(e, {
          index: tc.index,
          offset: offset,
          textList: tc.textList,
          formatter: (item, category, index, opts) => {
            if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
              return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
            } else {
              return this._tooltipDefault(item, category, index, opts);
            }
          }
        });
      } else {
        cfu.instance[cid].showToolTip(e, {
          formatter: (item, category, index, opts) => {
            if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
              return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
            } else {
              return this._tooltipDefault(item, category, index, opts);
            }
          }
        });
      }
    },
    _tap(e,move) {
      let cid = this.cid
      let currentIndex = null;
      let legendIndex = null;
      if (this.inScrollView === true || this.inAli) {
        let chartdom = uni
          .createSelectorQuery()
          // #ifndef MP-ALIPAY
          .in(this)
          .select('#ChartBoxId'+cid)
          // #endif
          // #ifdef MP-ALIPAY
          .select('#'+this.cid)
          // #endif
          .boundingClientRect(data => {
            e.changedTouches=[];
            if (this.inAli) {
              e.changedTouches.unshift({ x: e.detail.clientX - data.left, y: e.detail.clientY - data.top});
            }else{
              e.changedTouches.unshift({ x: e.detail.x - data.left, y: e.detail.y - data.top - this.pageScrollTop});
            }
            if(move){
              if (this.tooltipShow === true) {
                this._showTooltip(e);
              }
            }else{
              currentIndex = cfu.instance[cid].getCurrentDataIndex(e);
              legendIndex = cfu.instance[cid].getLegendDataIndex(e);
              if(this.tapLegend === true){
                cfu.instance[cid].touchLegend(e);
              }
              if (this.tooltipShow === true) {
                this._showTooltip(e);
              }
              this.emitMsg({name: 'getIndex', params: { type:"getIndex", event:{ x: e.detail.x - data.left, y: e.detail.y - data.top }, currentIndex: currentIndex, legendIndex: legendIndex, id: cid, opts: cfu.instance[cid].opts}});
            }
          })
          .exec();
      } else {
        if(move){
          if (this.tooltipShow === true) {
            this._showTooltip(e);
          }
        }else{
          e.changedTouches=[];
          e.changedTouches.unshift({ x: e.detail.x - e.currentTarget.offsetLeft, y: e.detail.y - e.currentTarget.offsetTop });
          currentIndex = cfu.instance[cid].getCurrentDataIndex(e);
          legendIndex = cfu.instance[cid].getLegendDataIndex(e);
          if(this.tapLegend === true){
            cfu.instance[cid].touchLegend(e);
          }
          if (this.tooltipShow === true) {
            this._showTooltip(e);
          }
          this.emitMsg({name: 'getIndex', params: {type:"getIndex", event:{ x: e.detail.x, y: e.detail.y - e.currentTarget.offsetTop }, currentIndex: currentIndex, legendIndex: legendIndex, id: cid, opts: cfu.instance[cid].opts}});
        }
      }
    },
    _touchStart(e) {
      let cid = this.cid
      lastMoveTime=Date.now();
      if(cfu.option[cid].enableScroll === true && e.touches.length == 1){
        cfu.instance[cid].scrollStart(e);
      }
      this.emitMsg({name:'getTouchStart', params:{type:"touchStart", event:e.changedTouches[0], id:cid}});
    },
    _touchMove(e) {
      let cid = this.cid
      let currMoveTime = Date.now();
      let duration = currMoveTime - lastMoveTime;
      let touchMoveLimit = cfu.option[cid].touchMoveLimit || 24;
      if (duration < Math.floor(1000 / touchMoveLimit)) return;//每秒60帧
      lastMoveTime = currMoveTime;
      if(cfu.option[cid].enableScroll === true && e.changedTouches.length == 1){
        cfu.instance[cid].scroll(e);
      }
      if(this.ontap === true && cfu.option[cid].enableScroll === false && this.onmovetip === true){
        this._tap(e,true)
      }
      if(this.ontouch === true && cfu.option[cid].enableScroll === true && this.onzoom === true && e.changedTouches.length == 2){
        cfu.instance[cid].dobuleZoom(e);
      }
      this.emitMsg({name: 'getTouchMove', params: {type:"touchMove", event:e.changedTouches[0], id: cid}});
    },
    _touchEnd(e) {
      let cid = this.cid
      if(cfu.option[cid].enableScroll === true && e.touches.length == 0){
        cfu.instance[cid].scrollEnd(e);
      }
      this.emitMsg({name:'getTouchEnd', params:{type:"touchEnd", event:e.changedTouches[0], id:cid}});
      if(this.ontap === true && cfu.option[cid].enableScroll === false && this.onmovetip === true){
        this._tap(e,true)
      }
    },
    // #endif
    _error(e) {
      this.mixinDatacomErrorMessage = e.detail.errMsg;
    },
    emitMsg(msg) {
      this.$emit(msg.name, msg.params);
    },
    getRenderType() {
      //防止如果开启echarts且父元素为v-if的情况renderjs监听不到prop变化的问题
      if(this.echarts===true && this.mixinDatacomLoading===false){
        this.beforeInit()
      }
    },
    toJSON(){
      return this
    }
  }
};
</script>
<!-- #ifdef APP-VUE || H5 -->
<script module="rdcharts" lang="renderjs">
import uChartsRD from '../../js_sdk/u-charts/u-charts.js';
import cfu from '../../js_sdk/u-charts/config-ucharts.js';
import cfe from '../../js_sdk/u-charts/config-echarts.js';
var that = {};
var rootdom = null;
function rddeepCloneAssign(origin = {}, ...args) {
  for (let i in args) {
    for (let key in args[i]) {
      if (args[i].hasOwnProperty(key)) {
        origin[key] = args[i][key] && typeof args[i][key] === 'object' ? rddeepCloneAssign(Array.isArray(args[i][key]) ? [] : {}, origin[key], args[i][key]) : args[i][key];
      }
    }
  }
  return origin;
}
function rdformatterAssign(args,formatter) {
  for (let key in args) {
    if(args.hasOwnProperty(key) && args[key] !== null && typeof args[key] === 'object'){
      rdformatterAssign(args[key],formatter)
    }else if(key === 'format' && typeof args[key] === 'string'){
      args['formatter'] = formatter[args[key]] ? formatter[args[key]] : undefined;
    }
  }
  return args;
}
export default {
  data() {
    return {
      rid:null
    }
  },
  mounted() {
    rootdom = {top:0,left:0}
    // #ifdef H5
    let dm = document.querySelectorAll('uni-main')[0]
    if(dm === undefined){
      dm = document.querySelectorAll('uni-page-wrapper')[0]
    }
    rootdom = {top:dm.offsetTop,left:dm.offsetLeft}
    // #endif
    setTimeout(()=>{
      if(this.rid === null){
        this.$ownerInstance && this.$ownerInstance.callMethod('getRenderType')
      }
    },200)
  },
  destroyed(){
    delete cfu.option[this.rid]
    delete cfu.instance[this.rid]
    delete cfe.option[this.rid]
    delete cfe.instance[this.rid]
  },
  methods: {
    //==============以下是ECharts的方法====================
    ecinit(newVal, oldVal, owner, instance){
      let cid = JSON.stringify(newVal.id)
      this.rid = cid
      that[cid] = this.$ownerInstance || instance
      let eopts = JSON.parse(JSON.stringify(newVal))
      let type = eopts.type;
      //载入并覆盖默认配置
      if (type && cfe.type.includes(type)) {
        cfe.option[cid] = rddeepCloneAssign({}, cfe[type], eopts);
      }else{
        cfe.option[cid] = rddeepCloneAssign({}, eopts);
      }
      let newData = eopts.chartData;
      if(newData){
        //挂载categories和series
        if(cfe.option[cid].xAxis && cfe.option[cid].xAxis.type && cfe.option[cid].xAxis.type === 'category'){
          cfe.option[cid].xAxis.data = newData.categories
        }
        if(cfe.option[cid].yAxis && cfe.option[cid].yAxis.type && cfe.option[cid].yAxis.type === 'category'){
          cfe.option[cid].yAxis.data = newData.categories
        }
        cfe.option[cid].series = []
        for (var i = 0; i < newData.series.length; i++) {
          cfe.option[cid].seriesTemplate = cfe.option[cid].seriesTemplate ? cfe.option[cid].seriesTemplate : {}
          let Template = rddeepCloneAssign({},cfe.option[cid].seriesTemplate,newData.series[i])
          cfe.option[cid].series.push(Template)
        }
      }
      if (typeof window.echarts === 'object') {
          this.newEChart()
      }else{
        const script = document.createElement('script')
        // #ifdef APP-VUE
        script.src = './uni_modules/qiun-data-charts/static/app-plus/echarts.min.js'
        // #endif
        // #ifdef H5
        const { origin, pathname } = window.location
        const rooturl = origin + pathname
        script.src = rooturl + 'uni_modules/qiun-data-charts/static/h5/echarts.min.js'
        // #endif
        script.onload = this.newEChart
        document.head.appendChild(script)
      }
    },
    ecresize(newVal, oldVal, owner, instance){
      if(cfe.instance[this.rid]){
        cfe.instance[this.rid].resize()
      }
    },
    newEChart(){
      let cid = this.rid
      if(cfe.instance[cid] === undefined){
        cfe.instance[cid] = echarts.init(that[cid].$el.children[0])
        //ontap开启后才触发click事件
        if(cfe.option[cid].ontap === true){
          cfe.instance[cid].on('click', resdata => {
            let event = JSON.parse(JSON.stringify({
              x:resdata.event.offsetX,y:resdata.event.offsetY
            }))
            that[cid].callMethod('emitMsg',{name:"getIndex", params:{type:"getIndex", event:event, currentIndex:resdata.dataIndex, value:resdata.data, seriesName: resdata.seriesName,id:cid}})
          })
          // å¢žåŠ ECharts的highlight消息,实现按下移动返回索引功能。add by onefish åˆ›å»ºäºŽ 2021-12-11 09:50
          cfe.instance[cid].on('highlight', resdata => {
            that[cid].callMethod('emitMsg',{name:"getHighlight", params:{type:"highlight", res:resdata, id:cid}})
          })
        }
        this.updataEChart(cid,cfe.option[cid])
      }else{
        this.updataEChart(cid,cfe.option[cid])
      }
    },
    updataEChart(cid,option){
      //替换option内format属性为formatter的预定义方法
      option = rdformatterAssign(option,cfe.formatter)
      if(option.tooltip){
        option.tooltip.show = option.tooltipShow?true:false;
        option.tooltip.position = this.tooltipPosition()
        //tooltipFormat方法,替换组件的tooltipFormat为config-echarts.js内对应的方法
        if (typeof option.tooltipFormat === 'string' && cfe.formatter[option.tooltipFormat]) {
          option.tooltip.formatter = option.tooltip.formatter ? option.tooltip.formatter : cfe.formatter[option.tooltipFormat]
        }
      }
      // é¢œè‰²æ¸å˜æ·»åŠ çš„æ–¹æ³•
      if (option.series) {
          for (let i in option.series) {
              let linearGradient = option.series[i].linearGradient
              if (linearGradient) {
                  option.series[i].color = new echarts.graphic.LinearGradient(linearGradient[0],linearGradient[1],linearGradient[2],linearGradient[3],linearGradient[4])
              }
          }
      }
      cfe.instance[cid].setOption(option, option.notMerge)
      cfe.instance[cid].on('finished', function(){
        that[cid].callMethod('emitMsg',{name:"complete",params:{type:"complete",complete:true,id:cid}})
        if(cfe.instance[cid]){
          cfe.instance[cid].off('finished')
        }
      })
    },
    tooltipPosition(){
      return (point, params, dom, rect, size) => {
          let x = point[0]
          let y = point[1]
          let viewWidth = size.viewSize[0]
          let viewHeight = size.viewSize[1]
          let boxWidth = size.contentSize[0]
          let boxHeight = size.contentSize[1]
          let posX = x + 30
          let posY = y + 30
          if (posX + boxWidth > viewWidth) {
              posX = x - boxWidth - 30
          }
          if (posY + boxHeight > viewHeight) {
              posY = y - boxHeight - 30
          }
          return [posX, posY]
      }
    },
    //==============以下是uCharts的方法====================
    ucinit(newVal, oldVal, owner, instance){
      if(JSON.stringify(newVal) == JSON.stringify(oldVal)){
        return;
      }
      if(!newVal.canvasId){
        return;
      }
      let cid = JSON.parse(JSON.stringify(newVal.canvasId))
      this.rid = cid
      that[cid] = this.$ownerInstance || instance
      cfu.option[cid] = JSON.parse(JSON.stringify(newVal))
      cfu.option[cid] = rdformatterAssign(cfu.option[cid],cfu.formatter)
      let canvasdom = document.getElementById(cid)
      if(canvasdom && canvasdom.children[0]){
        cfu.option[cid].context = canvasdom.children[0].getContext("2d")
        if(cfu.instance[cid] && cfu.option[cid] && cfu.option[cid].update === true){
          this.updataUChart()
        }else{
          setTimeout(()=>{
            cfu.option[cid].context.restore();
            cfu.option[cid].context.save();
            this.newUChart()
          },100)
        }
      }
    },
    newUChart() {
      let cid = this.rid
      cfu.instance[cid] = new uChartsRD(cfu.option[cid])
      cfu.instance[cid].addEventListener('renderComplete', () => {
        that[cid].callMethod('emitMsg',{name:"complete",params:{type:"complete",complete:true,id:cid}})
        cfu.instance[cid].delEventListener('renderComplete')
      });
      cfu.instance[cid].addEventListener('scrollLeft', () => {
        that[cid].callMethod('emitMsg',{name:"scrollLeft",params:{type:"scrollLeft",scrollLeft:true,id:cid}})
      });
      cfu.instance[cid].addEventListener('scrollRight', () => {
        that[cid].callMethod('emitMsg',{name:"scrollRight",params:{type:"scrollRight",scrollRight:true,id:cid}})
      });
    },
    updataUChart() {
      let cid = this.rid
      cfu.instance[cid].updateData(cfu.option[cid])
    },
    tooltipDefault(item, category, index, opts) {
      if (category) {
        let data = item.data
        if(typeof item.data === "object"){
          data = item.data.value
        }
        return category + ' ' + item.name + ':' + data;
      } else {
        if (item.properties && item.properties.name) {
          return item.properties.name ;
        } else {
          return item.name + ':' + item.data;
        }
      }
    },
    showTooltip(e,cid) {
      let tc = cfu.option[cid].tooltipCustom
      if (tc && tc !== undefined && tc !== null) {
        let offset = undefined;
        if (tc.x >= 0 && tc.y >= 0) {
          offset = { x: tc.x, y: tc.y + 10 };
        }
        cfu.instance[cid].showToolTip(e, {
          index: tc.index,
          offset: offset,
          textList: tc.textList,
          formatter: (item, category, index, opts) => {
            if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
              return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
            } else {
              return this.tooltipDefault(item, category, index, opts);
            }
          }
        });
      } else {
        cfu.instance[cid].showToolTip(e, {
          formatter: (item, category, index, opts) => {
            if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
              return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
            } else {
              return this.tooltipDefault(item, category, index, opts);
            }
          }
        });
      }
    },
    tap(e) {
      let cid = this.rid
      let ontap = cfu.option[cid].ontap
      let tooltipShow = cfu.option[cid].tooltipShow
      let tapLegend = cfu.option[cid].tapLegend
      if(ontap == false) return;
      let currentIndex=null
      let legendIndex=null
      let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
      let tmpe = {}
      if(e.detail.x){//tap或者click的事件
        tmpe = { x: e.detail.x - rchartdom.left, y:e.detail.y - rchartdom.top + rootdom.top}
      }else{//mouse的事件
        tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
      }
      e.changedTouches = [];
      e.changedTouches.unshift(tmpe)
      currentIndex=cfu.instance[cid].getCurrentDataIndex(e)
      legendIndex=cfu.instance[cid].getLegendDataIndex(e)
      if(tapLegend === true){
        cfu.instance[cid].touchLegend(e);
      }
      if(tooltipShow==true){
        this.showTooltip(e,cid)
      }
      that[cid].callMethod('emitMsg',{name:"getIndex",params:{type:"getIndex",event:tmpe,currentIndex:currentIndex,legendIndex:legendIndex,id:cid, opts: cfu.instance[cid].opts}})
    },
    touchStart(e) {
      let cid = this.rid
      let ontouch = cfu.option[cid].ontouch
      if(ontouch == false) return;
      if(cfu.option[cid].enableScroll === true && e.touches.length == 1){
        cfu.instance[cid].scrollStart(e);
      }
      that[cid].callMethod('emitMsg',{name:"getTouchStart",params:{type:"touchStart",event:e.changedTouches[0],id:cid}})
    },
    touchMove(e) {
      let cid = this.rid
      let ontouch = cfu.option[cid].ontouch
      if(ontouch == false) return;
      if(cfu.option[cid].enableScroll === true && e.changedTouches.length == 1){
        cfu.instance[cid].scroll(e);
      }
      if(cfu.option[cid].ontap === true && cfu.option[cid].enableScroll === false && cfu.option[cid].onmovetip === true){
        let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
        let tmpe = { x: e.changedTouches[0].clientX - rchartdom.left, y:e.changedTouches[0].clientY - rchartdom.top + rootdom.top}
        e.changedTouches.unshift(tmpe)
        if(cfu.option[cid].tooltipShow === true){
          this.showTooltip(e,cid)
        }
      }
      if(ontouch === true && cfu.option[cid].enableScroll === true && cfu.option[cid].onzoom === true && e.changedTouches.length == 2){
        cfu.instance[cid].dobuleZoom(e);
      }
      that[cid].callMethod('emitMsg',{name:"getTouchMove",params:{type:"touchMove",event:e.changedTouches[0],id:cid}})
    },
    touchEnd(e) {
      let cid = this.rid
      let ontouch = cfu.option[cid].ontouch
      if(ontouch == false) return;
      if(cfu.option[cid].enableScroll === true && e.touches.length == 0){
        cfu.instance[cid].scrollEnd(e);
      }
      that[cid].callMethod('emitMsg',{name:"getTouchEnd",params:{type:"touchEnd",event:e.changedTouches[0],id:cid}})
    },
    mouseDown(e) {
      let cid = this.rid
      let onmouse = cfu.option[cid].onmouse
      if(onmouse == false) return;
      let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
      let tmpe = {}
      tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
      e.changedTouches = [];
      e.changedTouches.unshift(tmpe)
      cfu.instance[cid].scrollStart(e)
      cfu.option[cid].mousedown=true;
      that[cid].callMethod('emitMsg',{name:"getTouchStart",params:{type:"mouseDown",event:tmpe,id:cid}})
    },
    mouseMove(e) {
      let cid = this.rid
      let onmouse = cfu.option[cid].onmouse
      let tooltipShow = cfu.option[cid].tooltipShow
      if(onmouse == false) return;
      let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
      let tmpe = {}
      tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
      e.changedTouches = [];
      e.changedTouches.unshift(tmpe)
      if(cfu.option[cid].mousedown){
        cfu.instance[cid].scroll(e)
        that[cid].callMethod('emitMsg',{name:"getTouchMove",params:{type:"mouseMove",event:tmpe,id:cid}})
      }else if(cfu.instance[cid]){
        if(tooltipShow==true){
          this.showTooltip(e,cid)
        }
      }
    },
    mouseUp(e) {
      let cid = this.rid
      let onmouse = cfu.option[cid].onmouse
      if(onmouse == false) return;
      let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
      let tmpe = {}
      tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
      e.changedTouches = [];
      e.changedTouches.unshift(tmpe)
      cfu.instance[cid].scrollEnd(e)
      cfu.option[cid].mousedown=false;
      that[cid].callMethod('emitMsg',{name:"getTouchEnd",params:{type:"mouseUp",event:tmpe,id:cid}})
    },
  }
}
</script>
<!-- #endif -->
<style scoped>
.chartsview {
  width: 100%;
  height: 100%;
  display: flex;
  flex: 1;
  justify-content: center;
  align-items: center;
}
</style>
uni_modules/qiun-data-charts/components/qiun-error/qiun-error.vue
uni_modules/qiun-data-charts/components/qiun-loading/loading1.vue
uni_modules/qiun-data-charts/components/qiun-loading/loading2.vue
uni_modules/qiun-data-charts/components/qiun-loading/loading3.vue
uni_modules/qiun-data-charts/components/qiun-loading/loading4.vue
uni_modules/qiun-data-charts/components/qiun-loading/loading5.vue
uni_modules/qiun-data-charts/components/qiun-loading/qiun-loading.vue
uni_modules/qiun-data-charts/js_sdk/u-charts/config-echarts.js
uni_modules/qiun-data-charts/js_sdk/u-charts/config-ucharts.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,601 @@
/*
 * uCharts®
 * é«˜æ€§èƒ½è·¨å¹³å°å›¾è¡¨åº“,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360)、Vue、Taro等支持canvas的框架平台
 * Copyright (c) 2021 QIUN®秋云 https://www.ucharts.cn All rights reserved.
 * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 * å¤åˆ¶ä½¿ç”¨è¯·ä¿ç•™æœ¬æ®µæ³¨é‡Šï¼Œæ„Ÿè°¢æ”¯æŒå¼€æºï¼
 *
 * uCharts®官方网站
 * https://www.uCharts.cn
 *
 * å¼€æºåœ°å€:
 * https://gitee.com/uCharts/uCharts
 *
 * uni-app插件市场地址:
 * http://ext.dcloud.net.cn/plugin?id=271
 *
 */
// ä¸»é¢˜é¢œè‰²é…ç½®ï¼šå¦‚每个图表类型需要不同主题,请在对应图表类型上更改color属性
const color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'];
//事件转换函数,主要用作格式化x轴为时间轴,根据需求自行修改
const formatDateTime = (timeStamp, returnType)=>{
  var date = new Date();
  date.setTime(timeStamp * 1000);
  var y = date.getFullYear();
  var m = date.getMonth() + 1;
  m = m < 10 ? ('0' + m) : m;
  var d = date.getDate();
  d = d < 10 ? ('0' + d) : d;
  var h = date.getHours();
  h = h < 10 ? ('0' + h) : h;
  var minute = date.getMinutes();
  var second = date.getSeconds();
  minute = minute < 10 ? ('0' + minute) : minute;
  second = second < 10 ? ('0' + second) : second;
  if(returnType == 'full'){return y + '-' + m + '-' + d + ' '+ h +':' + minute + ':' + second;}
  if(returnType == 'y-m-d'){return y + '-' + m + '-' + d;}
  if(returnType == 'h:m'){return  h +':' + minute;}
  if(returnType == 'h:m:s'){return  h +':' + minute +':' + second;}
  return [y, m, d, h, minute, second];
}
const cfu = {
  //demotype为自定义图表类型,一般不需要自定义图表类型,只需要改根节点上对应的类型即可
    "type":["pie","ring","rose","word","funnel","map","arcbar","line","column","mount","bar","area","radar","gauge","candle","mix","tline","tarea","scatter","bubble","demotype"],
    "range":["饼状图","圆环图","玫瑰图","词云图","漏斗图","地图","圆弧进度条","折线图","柱状图","山峰图","条状图","区域图","雷达图","仪表盘","K线图","混合图","时间轴折线","时间轴区域","散点图","气泡图","自定义类型"],
  //增加自定义图表类型,如果需要categories,请在这里加入您的图表类型,例如最后的"demotype"
  //自定义类型时需要注意"tline","tarea","scatter","bubble"等时间轴(矢量x轴)类图表,没有categories,不需要加入categories
    "categories":["line","column","mount","bar","area","radar","gauge","candle","mix","demotype"],
  //instance为实例变量承载属性,不要删除
  "instance":{},
  //option为opts及eopts承载属性,不要删除
  "option":{},
  //下面是自定义format配置,因除H5端外的其他端无法通过props传递函数,只能通过此属性对应下标的方式来替换
  "formatter":{
    "yAxisDemo1":function(val, index, opts){return val+'元'},
    "yAxisDemo2":function(val, index, opts){return val.toFixed(2)},
    "xAxisDemo1":function(val, index, opts){return val+'å¹´';},
    "xAxisDemo2":function(val, index, opts){return formatDateTime(val,'h:m')},
    "seriesDemo1":function(val, index, series, opts){return val+'元'},
    "tooltipDemo1":function(item, category, index, opts){
      if(index==0){
          return '随便用'+item.data+'å¹´'
      }else{
          return '其他我没改'+item.data+'天'
      }
    },
    "pieDemo":function(val, index, series, opts){
      if(index !== undefined){
        return series[index].name+':'+series[index].data+'元'
      }
    },
  },
  //这里演示了自定义您的图表类型的option,可以随意命名,之后在组件上 type="demotype" åŽï¼Œç»„件会调用这个花括号里的option,如果组件上还存在opts参数,会将demotype与opts中option合并后渲染图表。
  "demotype":{
    //我这里把曲线图当做了自定义图表类型,您可以根据需要随意指定类型或配置
    "type": "line",
    "color": color,
    "padding": [15,10,0,15],
    "xAxis": {
      "disableGrid": true,
    },
    "yAxis": {
      "gridType": "dash",
      "dashLength": 2,
    },
    "legend": {
    },
    "extra": {
        "line": {
            "type": "curve",
            "width": 2
        },
    }
  },
  //下面是自定义配置,请添加项目所需的通用配置
    "pie":{
        "type": "pie",
    "color": color,
        "padding": [5,5,5,5],
        "extra": {
            "pie": {
                "activeOpacity": 0.5,
                "activeRadius": 10,
                "offsetAngle": 0,
                "labelWidth": 15,
                "border": true,
                "borderWidth": 3,
                "borderColor": "#FFFFFF"
            },
        }
    },
    "ring":{
        "type": "ring",
    "color": color,
        "padding": [5,5,5,5],
        "rotate": false,
        "dataLabel": true,
        "legend": {
            "show": true,
            "position": "right",
      "lineHeight": 25,
        },
        "title": {
            "name": "收益率",
            "fontSize": 15,
            "color": "#666666"
        },
        "subtitle": {
            "name": "70%",
            "fontSize": 25,
            "color": "#7cb5ec"
        },
        "extra": {
            "ring": {
                "ringWidth":30,
                "activeOpacity": 0.5,
                "activeRadius": 10,
                "offsetAngle": 0,
                "labelWidth": 15,
                "border": true,
                "borderWidth": 3,
                "borderColor": "#FFFFFF"
            },
        },
    },
    "rose":{
        "type": "rose",
    "color": color,
        "padding": [5,5,5,5],
        "legend": {
            "show": true,
            "position": "left",
      "lineHeight": 25,
        },
        "extra": {
            "rose": {
                "type": "area",
                "minRadius": 50,
                "activeOpacity": 0.5,
                "activeRadius": 10,
                "offsetAngle": 0,
                "labelWidth": 15,
                "border": false,
                "borderWidth": 2,
                "borderColor": "#FFFFFF"
            },
        }
    },
    "word":{
        "type": "word",
    "color": color,
        "extra": {
            "word": {
                "type": "normal",
                "autoColors": false
            }
        }
    },
    "funnel":{
        "type": "funnel",
    "color": color,
        "padding": [15,15,0,15],
        "extra": {
            "funnel": {
                "activeOpacity": 0.3,
                "activeWidth": 10,
                "border": true,
                "borderWidth": 2,
                "borderColor": "#FFFFFF",
                "fillOpacity": 1,
                "labelAlign": "right"
            },
        }
    },
    "map":{
        "type": "map",
    "color": color,
        "padding": [0,0,0,0],
    "dataLabel": true,
        "extra": {
            "map": {
                "border": true,
                "borderWidth": 1,
                "borderColor": "#666666",
                "fillOpacity": 0.6,
                "activeBorderColor": "#F04864",
                "activeFillColor": "#FACC14",
                "activeFillOpacity": 1
            },
        }
    },
    "arcbar":{
        "type": "arcbar",
    "color": color,
        "title": {
            "name": "百分比",
            "fontSize": 25,
            "color": "#00FF00"
        },
        "subtitle": {
            "name": "默认标题",
            "fontSize": 15,
            "color": "#666666"
        },
        "extra": {
            "arcbar": {
                "type": "default",
                "width": 12,
                "backgroundColor": "#E9E9E9",
                "startAngle": 0.75,
                "endAngle": 0.25,
                "gap": 2
            }
        }
    },
    "line":{
        "type": "line",
    "color": color,
        "padding": [15,10,0,15],
        "xAxis": {
      "disableGrid": true,
        },
        "yAxis": {
      "gridType": "dash",
      "dashLength": 2,
        },
        "legend": {
        },
        "extra": {
            "line": {
                "type": "straight",
                "width": 2
            },
        }
    },
  "tline":{
      "type": "line",
    "color": color,
      "padding": [15,10,0,15],
      "xAxis": {
      "disableGrid": false,
      "boundaryGap":"justify",
      },
      "yAxis": {
      "gridType": "dash",
      "dashLength": 2,
      "data":[
        {
          "min":0,
          "max":80
        }
      ]
      },
      "legend": {
      },
      "extra": {
          "line": {
              "type": "curve",
              "width": 2
          },
      }
  },
  "tarea":{
      "type": "area",
    "color": color,
      "padding": [15,10,0,15],
      "xAxis": {
      "disableGrid": true,
      "boundaryGap":"justify",
      },
      "yAxis": {
      "gridType": "dash",
      "dashLength": 2,
      "data":[
        {
          "min":0,
          "max":80
        }
      ]
      },
      "legend": {
      },
      "extra": {
          "area": {
              "type": "curve",
              "opacity": 0.2,
              "addLine": true,
              "width": 2,
              "gradient": true
          },
      }
  },
    "column":{
        "type": "column",
    "color": color,
        "padding": [15,15,0,5],
        "xAxis": {
      "disableGrid": true,
        },
        "yAxis": {
      "data":[{"min":0}]
        },
        "legend": {
        },
        "extra": {
            "column": {
                "type": "group",
                "width": 30,
                "activeBgColor": "#000000",
                "activeBgOpacity": 0.08
            },
        }
    },
  "mount":{
      "type": "mount",
    "color": color,
      "padding": [15,15,0,5],
      "xAxis": {
      "disableGrid": true,
      },
      "yAxis": {
      "data":[{"min":0}]
      },
      "legend": {
      },
      "extra": {
          "mount": {
              "type": "mount",
              "widthRatio": 1.5,
          },
      }
  },
  "bar":{
      "type": "bar",
    "color": color,
      "padding": [15,30,0,5],
      "xAxis": {
      "boundaryGap":"justify",
      "disableGrid":false,
      "min":0,
      "axisLine":false
      },
      "yAxis": {
      },
      "legend": {
      },
      "extra": {
          "bar": {
              "type": "group",
              "width": 30,
              "meterBorde": 1,
              "meterFillColor": "#FFFFFF",
              "activeBgColor": "#000000",
              "activeBgOpacity": 0.08
          },
      }
  },
    "area":{
        "type": "area",
        "color": color,
        "padding": [15,15,0,15],
        "xAxis": {
      "disableGrid": true,
        },
        "yAxis": {
      "gridType": "dash",
      "dashLength": 2,
        },
        "legend": {
        },
        "extra": {
            "area": {
                "type": "straight",
                "opacity": 0.2,
                "addLine": true,
                "width": 2,
                "gradient": false
            },
        }
    },
    "radar":{
        "type": "radar",
        "color": color,
        "padding": [5,5,5,5],
    "dataLabel": false,
        "legend": {
            "show": true,
            "position": "right",
      "lineHeight": 25,
        },
        "extra": {
            "radar": {
                "gridType": "radar",
                "gridColor": "#CCCCCC",
                "gridCount": 3,
                "opacity": 0.2,
                "max": 200
            },
        }
    },
    "gauge":{
        "type": "gauge",
        "color": color,
        "title": {
            "name": "66Km/H",
            "fontSize": 25,
            "color": "#2fc25b",
            "offsetY": 50
        },
        "subtitle": {
            "name": "实时速度",
            "fontSize": 15,
            "color": "#1890ff",
            "offsetY": -50
        },
        "extra": {
            "gauge": {
                "type": "default",
                "width": 30,
                "labelColor": "#666666",
                "startAngle": 0.75,
                "endAngle": 0.25,
                "startNumber": 0,
                "endNumber": 100,
                "labelFormat": "",
                "splitLine": {
                    "fixRadius": 0,
                    "splitNumber": 10,
                    "width": 30,
                    "color": "#FFFFFF",
                    "childNumber": 5,
                    "childWidth": 12
                },
                "pointer": {
                    "width": 24,
                    "color": "auto"
                }
            }
        }
    },
    "candle":{
        "type": "candle",
        "color": color,
        "padding": [15,15,0,15],
        "enableScroll": true,
        "enableMarkLine": true,
        "dataLabel": false,
        "xAxis": {
            "labelCount": 4,
            "itemCount": 40,
            "disableGrid": true,
            "gridColor": "#CCCCCC",
            "gridType": "solid",
            "dashLength": 4,
            "scrollShow": true,
            "scrollAlign": "left",
            "scrollColor": "#A6A6A6",
            "scrollBackgroundColor": "#EFEBEF"
        },
        "yAxis": {
        },
        "legend": {
        },
        "extra": {
            "candle": {
                "color": {
                    "upLine": "#f04864",
                    "upFill": "#f04864",
                    "downLine": "#2fc25b",
                    "downFill": "#2fc25b"
                },
                "average": {
                    "show": true,
                    "name": ["MA5","MA10","MA30"],
                    "day": [5,10,20],
                    "color": ["#1890ff","#2fc25b","#facc14"]
                }
            },
            "markLine": {
                "type": "dash",
                "dashLength": 5,
                "data": [
                    {
                        "value": 2150,
                        "lineColor": "#f04864",
                        "showLabel": true
                    },
                    {
                        "value": 2350,
                        "lineColor": "#f04864",
                        "showLabel": true
                    }
                ]
            }
        }
    },
    "mix":{
        "type": "mix",
        "color": color,
        "padding": [15,15,0,15],
        "xAxis": {
      "disableGrid": true,
        },
        "yAxis": {
            "disabled": false,
            "disableGrid": false,
            "splitNumber": 5,
            "gridType": "dash",
            "dashLength": 4,
            "gridColor": "#CCCCCC",
            "padding": 10,
            "showTitle": true,
            "data": []
        },
        "legend": {
        },
        "extra": {
            "mix": {
                "column": {
                    "width": 20
                }
            },
        }
    },
    "scatter":{
        "type": "scatter",
        "color":color,
        "padding":[15,15,0,15],
    "dataLabel":false,
    "xAxis": {
      "disableGrid": false,
      "gridType":"dash",
      "splitNumber":5,
      "boundaryGap":"justify",
      "min":0
    },
    "yAxis": {
      "disableGrid": false,
      "gridType":"dash",
    },
    "legend": {
    },
    "extra": {
        "scatter": {
        },
    }
    },
    "bubble":{
        "type": "bubble",
        "color":color,
        "padding":[15,15,0,15],
    "xAxis": {
      "disableGrid": false,
      "gridType":"dash",
      "splitNumber":5,
      "boundaryGap":"justify",
      "min":0,
      "max":250
    },
    "yAxis": {
      "disableGrid": false,
      "gridType":"dash",
      "data":[{
        "min":0,
        "max":150
      }]
    },
    "legend": {
    },
    "extra": {
        "bubble": {
        "border":2,
        "opacity": 0.5,
        },
    }
    }
}
export default cfu;
uni_modules/qiun-data-charts/js_sdk/u-charts/readme.md
uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.js
¶Ô±ÈÐÂÎļþ
ÎļþÌ«´ó
uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.min.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
/*
 * uCharts (R)
 * é«˜æ€§èƒ½è·¨å¹³å°å›¾è¡¨åº“,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360/快手)、Vue、Taro等支持canvas的框架平台
 * Copyright (C) 2021 QIUN (R) ç§‹äº‘ https://www.ucharts.cn All rights reserved.
 * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 * å¤åˆ¶ä½¿ç”¨è¯·ä¿ç•™æœ¬æ®µæ³¨é‡Šï¼Œæ„Ÿè°¢æ”¯æŒå¼€æºï¼
 *
 * uCharts (R) å®˜æ–¹ç½‘ç«™
 * https://www.uCharts.cn
 *
 * å¼€æºåœ°å€:
 * https://gitee.com/uCharts/uCharts
 *
 * uni-app插件市场地址:
 * http://ext.dcloud.net.cn/plugin?id=271
 *
 */
"use strict";var config={version:"v2.4.3-20220505",yAxisWidth:15,xAxisHeight:22,xAxisTextPadding:3,padding:[10,10,10,10],pixelRatio:1,rotate:false,fontSize:13,fontColor:"#666666",dataPointShape:["circle","circle","circle","circle"],color:["#1890FF","#91CB74","#FAC858","#EE6666","#73C0DE","#3CA272","#FC8452","#9A60B4","#ea7ccc"],linearColor:["#0EE2F8","#2BDCA8","#FA7D8D","#EB88E2","#2AE3A0","#0EE2F8","#EB88E2","#6773E3","#F78A85"],pieChartLinePadding:15,pieChartTextPadding:5,titleFontSize:20,subtitleFontSize:15,toolTipPadding:3,toolTipBackground:"#000000",toolTipOpacity:.7,toolTipLineHeight:20,radarLabelTextMargin:13};var assign=function(e,...t){if(e==null){throw new TypeError("[uCharts] Cannot convert undefined or null to object")}if(!t||t.length<=0){return e}function i(e,a){for(let t in a){e[t]=e[t]&&e[t].toString()==="[object Object]"?i(e[t],a[t]):e[t]=a[t]}return e}t.forEach(t=>{e=i(e,t)});return e};var util={toFixed:function t(e,a){a=a||2;if(this.isFloat(e)){e=e.toFixed(a)}return e},isFloat:function t(e){return e%1!==0},approximatelyEqual:function t(e,a){return Math.abs(e-a)<1e-10},isSameSign:function t(e,a){return Math.abs(e)===e&&Math.abs(a)===a||Math.abs(e)!==e&&Math.abs(a)!==a},isSameXCoordinateArea:function t(e,a){return this.isSameSign(e.x,a.x)},isCollision:function t(e,a){e.end={};e.end.x=e.start.x+e.width;e.end.y=e.start.y-e.height;a.end={};a.end.x=a.start.x+a.width;a.end.y=a.start.y-a.height;var i=a.start.x>e.end.x||a.end.x<e.start.x||a.end.y>e.start.y||a.start.y<e.end.y;return!i}};function getH5Offset(t){t.mp={changedTouches:[]};t.mp.changedTouches.push({x:t.offsetX,y:t.offsetY});return t}function hexToRgb(t,e){var a=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;var i=t.replace(a,function(t,e,a,i){return e+e+a+a+i+i});var r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(i);var o=parseInt(r[1],16);var n=parseInt(r[2],16);var l=parseInt(r[3],16);return"rgba("+o+","+n+","+l+","+e+")"}function findRange(t,e,a){if(isNaN(t)){throw new Error("[uCharts] series数据需为Number格式")}a=a||10;e=e?e:"upper";var i=1;while(a<1){a*=10;i*=10}if(e==="upper"){t=Math.ceil(t*i)}else{t=Math.floor(t*i)}while(t%a!==0){if(e==="upper"){if(t==t+1){break}t++}else{t--}}return t/i}function calCandleMA(o,t,e,n){let a=[];for(let r=0;r<o.length;r++){let i={data:[],name:t[r],color:e[r]};for(let a=0,t=n.length;a<t;a++){if(a<o[r]){i.data.push(null);continue}let e=0;for(let t=0;t<o[r];t++){e+=n[a-t][1]}i.data.push(+(e/o[r]).toFixed(3))}a.push(i)}return a}function calValidDistance(t,e,a,i,r){var o=r.width-r.area[1]-r.area[3];var n=a.eachSpacing*(r.chartData.xAxisData.xAxisPoints.length-1);if(r.type=="mount"&&r.extra&&r.extra.mount&&r.extra.mount.widthRatio&&r.extra.mount.widthRatio>1){if(r.extra.mount.widthRatio>2)r.extra.mount.widthRatio=2;n+=(r.extra.mount.widthRatio-1)*a.eachSpacing}var l=e;if(e>=0){l=0;t.uevent.trigger("scrollLeft");t.scrollOption.position="left";r.xAxis.scrollPosition="left"}else if(Math.abs(e)>=n-o){l=o-n;t.uevent.trigger("scrollRight");t.scrollOption.position="right";r.xAxis.scrollPosition="right"}else{t.scrollOption.position=e;r.xAxis.scrollPosition=e}return l}function isInAngleRange(t,e,a){function i(t){while(t<0){t+=2*Math.PI}while(t>2*Math.PI){t-=2*Math.PI}return t}t=i(t);e=i(e);a=i(a);if(e>a){a+=2*Math.PI;if(t<e){t+=2*Math.PI}}return t>=e&&t<=a}function createCurveControlPoints(t,e){function a(t,e){if(t[e-1]&&t[e+1]){return t[e].y>=Math.max(t[e-1].y,t[e+1].y)||t[e].y<=Math.min(t[e-1].y,t[e+1].y)}else{return false}}function c(t,e){if(t[e-1]&&t[e+1]){return t[e].x>=Math.max(t[e-1].x,t[e+1].x)||t[e].x<=Math.min(t[e-1].x,t[e+1].x)}else{return false}}var i=.2;var r=.2;var o=null;var n=null;var l=null;var s=null;if(e<1){o=t[0].x+(t[1].x-t[0].x)*i;n=t[0].y+(t[1].y-t[0].y)*i}else{o=t[e].x+(t[e+1].x-t[e-1].x)*i;n=t[e].y+(t[e+1].y-t[e-1].y)*i}if(e>t.length-3){var h=t.length-1;l=t[h].x-(t[h].x-t[h-1].x)*r;s=t[h].y-(t[h].y-t[h-1].y)*r}else{l=t[e+1].x-(t[e+2].x-t[e].x)*r;s=t[e+1].y-(t[e+2].y-t[e].y)*r}if(a(t,e+1)){s=t[e+1].y}if(a(t,e)){n=t[e].y}if(c(t,e+1)){l=t[e+1].x}if(c(t,e)){o=t[e].x}if(n>=Math.max(t[e].y,t[e+1].y)||n<=Math.min(t[e].y,t[e+1].y)){n=t[e].y}if(s>=Math.max(t[e].y,t[e+1].y)||s<=Math.min(t[e].y,t[e+1].y)){s=t[e+1].y}if(o>=Math.max(t[e].x,t[e+1].x)||o<=Math.min(t[e].x,t[e+1].x)){o=t[e].x}if(l>=Math.max(t[e].x,t[e+1].x)||l<=Math.min(t[e].x,t[e+1].x)){l=t[e+1].x}return{ctrA:{x:o,y:n},ctrB:{x:l,y:s}}}function convertCoordinateOrigin(t,e,a){return{x:a.x+t,y:a.y-e}}function avoidCollision(t,e){if(e){while(util.isCollision(t,e)){if(t.start.x>0){t.start.y--}else if(t.start.x<0){t.start.y++}else{if(t.start.y>0){t.start.y++}else{t.start.y--}}}}return t}function fixPieSeries(e,a,t){let i=[];if(e.length>0&&e[0].data.constructor.toString().indexOf("Array")>-1){a._pieSeries_=e;let t=e[0].data;for(var r=0;r<t.length;r++){t[r].formatter=e[0].formatter;t[r].data=t[r].value;i.push(t[r])}a.series=i}else{i=e}return i}function fillSeries(e,a,i){var r=0;for(var o=0;o<e.length;o++){let t=e[o];if(!t.color){t.color=i.color[r];r=(r+1)%i.color.length}if(!t.linearIndex){t.linearIndex=o}if(!t.index){t.index=0}if(!t.type){t.type=a.type}if(typeof t.show=="undefined"){t.show=true}if(!t.type){t.type=a.type}if(!t.pointShape){t.pointShape="circle"}if(!t.legendShape){switch(t.type){case"line":t.legendShape="line";break;case"column":case"bar":t.legendShape="rect";break;case"area":case"mount":t.legendShape="triangle";break;default:t.legendShape="circle"}}}return e}function fillCustomColor(t,e,a,i){var r=e||[];if(t=="custom"&&r.length==0){r=i.linearColor}if(t=="custom"&&r.length<a.length){let t=a.length-r.length;for(var o=0;o<t;o++){r.push(i.linearColor[(o+1)%i.linearColor.length])}}return r}function getDataRange(t,e){var a=0;var i=e-t;if(i>=1e4){a=1e3}else if(i>=1e3){a=100}else if(i>=100){a=10}else if(i>=10){a=5}else if(i>=1){a=1}else if(i>=.1){a=.1}else if(i>=.01){a=.01}else if(i>=.001){a=.001}else if(i>=1e-4){a=1e-4}else if(i>=1e-5){a=1e-5}else{a=1e-6}return{minRange:findRange(t,"lower",a),maxRange:findRange(e,"upper",a)}}function measureText(a,t,e){var i=0;a=String(a);e=false;if(e!==false&&e!==undefined&&e.setFontSize&&e.measureText){e.setFontSize(t);return e.measureText(a).width}else{var a=a.split("");for(let e=0;e<a.length;e++){let t=a[e];if(/[a-zA-Z]/.test(t)){i+=7}else if(/[0-9]/.test(t)){i+=5.5}else if(/\./.test(t)){i+=2.7}else if(/-/.test(t)){i+=3.25}else if(/:/.test(t)){i+=2.5}else if(/[\u4e00-\u9fa5]/.test(t)){i+=10}else if(/\(|\)/.test(t)){i+=3.73}else if(/\s/.test(t)){i+=2.5}else if(/%/.test(t)){i+=8}else{i+=10}}return i*t/10}}function dataCombine(t){return t.reduce(function(t,e){return(t.data?t.data:t).concat(e.data)},[])}function dataCombineStack(t,e){var a=new Array(e);for(var i=0;i<a.length;i++){a[i]=0}for(var r=0;r<t.length;r++){for(var i=0;i<a.length;i++){a[i]+=t[r].data[i]}}return t.reduce(function(t,e){return(t.data?t.data:t).concat(e.data).concat(a)},[])}function getTouches(t,e,a){let i,r;if(t.clientX){if(e.rotate){r=e.height-t.clientX*e.pix;i=(t.pageY-a.currentTarget.offsetTop-e.height/e.pix/2*(e.pix-1))*e.pix}else{i=t.clientX*e.pix;r=(t.pageY-a.currentTarget.offsetTop-e.height/e.pix/2*(e.pix-1))*e.pix}}else{if(e.rotate){r=e.height-t.x*e.pix;i=t.y*e.pix}else{i=t.x*e.pix;r=t.y*e.pix}}return{x:i,y:r}}function getSeriesDataItem(e,i,a){var r=[];var o=[];var n=i.constructor.toString().indexOf("Array")>-1;if(n){let t=filterSeries(e);for(var l=0;l<a.length;l++){o.push(t[a[l]])}}else{o=e}for(let t=0;t<o.length;t++){let e=o[t];let a=-1;if(n){a=i[t]}else{a=i}if(e.data[a]!==null&&typeof e.data[a]!=="undefined"&&e.show){let t={};t.color=e.color;t.type=e.type;t.style=e.style;t.pointShape=e.pointShape;t.disableLegend=e.disableLegend;t.name=e.name;t.show=e.show;t.data=e.formatter?e.formatter(e.data[a]):e.data[a];r.push(t)}}return r}function getMaxTextListLength(t,e,a){var i=t.map(function(t){return measureText(t,e,a)});return Math.max.apply(null,i)}function getRadarCoordinateSeries(t){var e=2*Math.PI/t;var a=[];for(var i=0;i<t;i++){a.push(e*i)}return a.map(function(t){return-1*t+Math.PI/2})}function getToolTipData(t,a,i,r,o){var n=arguments.length>5&&arguments[5]!==undefined?arguments[5]:{};var l=a.chartData.calPoints?a.chartData.calPoints:[];let s={};if(r.length>0){let e=[];for(let t=0;t<r.length;t++){e.push(l[r[t]])}s=e[0][i[0]]}else{for(let t=0;t<l.length;t++){if(l[t][i]){s=l[t][i];break}}}var e=t.map(function(t){let e=null;if(a.categories&&a.categories.length>0){e=o[i]}return{text:n.formatter?n.formatter(t,e,i,a):t.name+": "+t.data,color:t.color}});var h={x:Math.round(s.x),y:Math.round(s.y)};return{textList:e,offset:h}}function getMixToolTipData(t,e,a,i){var r=arguments.length>4&&arguments[4]!==undefined?arguments[4]:{};var o=e.chartData.xAxisPoints[a]+e.chartData.eachSpacing/2;var n=t.map(function(t){return{text:r.formatter?r.formatter(t,i[a],a,e):t.name+": "+t.data,color:t.color,disableLegend:t.disableLegend?true:false}});n=n.filter(function(t){if(t.disableLegend!==true){return t}});var l={x:Math.round(o),y:0};return{textList:n,offset:l}}function getCandleToolTipData(o,e,r,n,d,t){var x=arguments.length>6&&arguments[6]!==undefined?arguments[6]:{};var a=r.chartData.calPoints;let l=t.color.upFill;let s=t.color.downFill;let h=[l,l,s,l];var c=[];e.map(function(t){if(n==0){if(t.data[1]-t.data[0]<0){h[1]=s}else{h[1]=l}}else{if(t.data[0]<o[n-1][1]){h[0]=s}if(t.data[1]<t.data[0]){h[1]=s}if(t.data[2]>o[n-1][1]){h[2]=l}if(t.data[3]<o[n-1][1]){h[3]=s}}let e={text:"开盘:"+t.data[0],color:h[0]};let a={text:"收盘:"+t.data[1],color:h[1]};let i={text:"最低:"+t.data[2],color:h[2]};let r={text:"最高:"+t.data[3],color:h[3]};c.push(e,a,i,r)});var i=[];var f={x:0,y:0};for(let e=0;e<a.length;e++){let t=a[e];if(typeof t[n]!=="undefined"&&t[n]!==null){i.push(t[n])}}f.x=Math.round(i[0][0].x);return{textList:c,offset:f}}function filterSeries(e){let a=[];for(let t=0;t<e.length;t++){if(e[t].show==true){a.push(e[t])}}return a}function findCurrentIndex(o,n,e,t){var a=arguments.length>4&&arguments[4]!==undefined?arguments[4]:0;var l={index:-1,group:[]};var i=e.chartData.eachSpacing/2;let r=[];if(n&&n.length>0){if(!e.categories){i=0}else{for(let t=1;t<e.chartData.xAxisPoints.length;t++){r.push(e.chartData.xAxisPoints[t]-i)}if((e.type=="line"||e.type=="area")&&e.xAxis.boundaryGap=="justify"){r=e.chartData.xAxisPoints}}if(isInExactChartArea(o,e,t)){if(!e.categories){let a=Array(n.length);for(let e=0;e<n.length;e++){a[e]=Array(n[e].length);for(let t=0;t<n[e].length;t++){a[e][t]=Math.abs(n[e][t].x-o.x)}}let e=Array(a.length);let i=Array(a.length);for(let t=0;t<a.length;t++){e[t]=Math.min.apply(null,a[t]);i[t]=a[t].indexOf(e[t])}let r=Math.min.apply(null,e);l.index=[];for(let t=0;t<e.length;t++){if(e[t]==r){l.group.push(t);l.index.push(i[t])}}}else{r.forEach(function(t,e){if(o.x+a+i>t){l.index=e}})}}}return l}function findBarChartCurrentIndex(a,t,e,i){var r=arguments.length>4&&arguments[4]!==undefined?arguments[4]:0;var o={index:-1,group:[]};var n=e.chartData.eachSpacing/2;let l=e.chartData.yAxisPoints;if(t&&t.length>0){if(isInExactChartArea(a,e,i)){l.forEach(function(t,e){if(a.y+r+n>t){o.index=e}})}}return o}function findLegendIndex(o,t,e){let n=-1;let l=0;if(isInExactLegendArea(o,t.area)){let i=t.points;let r=-1;for(let t=0,e=i.length;t<e;t++){let a=i[t];for(let e=0;e<a.length;e++){r+=1;let t=a[e]["area"];if(t&&o.x>t[0]-l&&o.x<t[2]+l&&o.y>t[1]-l&&o.y<t[3]+l){n=r;break}}}return n}return n}function isInExactLegendArea(t,e){return t.x>e.start.x&&t.x<e.end.x&&t.y>e.start.y&&t.y<e.end.y}function isInExactChartArea(t,e,a){return t.x<=e.width-e.area[1]+10&&t.x>=e.area[3]-10&&t.y>=e.area[0]&&t.y<=e.height-e.area[2]}function findRadarChartCurrentIndex(t,e,a){var r=2*Math.PI/a;var o=-1;if(isInExactPieChartArea(t,e.center,e.radius)){var n=function t(e){if(e<0){e+=2*Math.PI}if(e>2*Math.PI){e-=2*Math.PI}return e};var l=Math.atan2(e.center.y-t.y,t.x-e.center.x);l=-1*l;if(l<0){l+=2*Math.PI}var i=e.angleList.map(function(t){t=n(-1*t);return t});i.forEach(function(t,e){var a=n(t-r/2);var i=n(t+r/2);if(i<a){i+=2*Math.PI}if(l>=a&&l<=i||l+2*Math.PI>=a&&l+2*Math.PI<=i){o=e}})}return o}function findFunnelChartCurrentIndex(t,e){var a=-1;for(var i=0,r=e.series.length;i<r;i++){var o=e.series[i];if(t.x>o.funnelArea[0]&&t.x<o.funnelArea[2]&&t.y>o.funnelArea[1]&&t.y<o.funnelArea[3]){a=i;break}}return a}function findWordChartCurrentIndex(t,e){var a=-1;for(var i=0,r=e.length;i<r;i++){var o=e[i];if(t.x>o.area[0]&&t.x<o.area[2]&&t.y>o.area[1]&&t.y<o.area[3]){a=i;break}}return a}function findMapChartCurrentIndex(t,e){var a=-1;var i=e.chartData.mapData;var r=e.series;var o=pointToCoordinate(t.y,t.x,i.bounds,i.scale,i.xoffset,i.yoffset);var n=[o.x,o.y];for(var l=0,s=r.length;l<s;l++){var h=r[l].geometry.coordinates;if(isPoiWithinPoly(n,h,e.chartData.mapData.mercator)){a=l;break}}return a}function findRoseChartCurrentIndex(t,e,a){var i=-1;var r=getRoseDataPoints(a._series_,a.extra.rose.type,e.radius,e.radius);if(e&&e.center&&isInExactPieChartArea(t,e.center,e.radius)){var o=Math.atan2(e.center.y-t.y,t.x-e.center.x);o=-o;if(a.extra.rose&&a.extra.rose.offsetAngle){o=o-a.extra.rose.offsetAngle*Math.PI/180}for(var n=0,l=r.length;n<l;n++){if(isInAngleRange(o,r[n]._start_,r[n]._start_+r[n]._rose_proportion_*2*Math.PI)){i=n;break}}}return i}function findPieChartCurrentIndex(t,e,a){var i=-1;var r=getPieDataPoints(e.series);if(e&&e.center&&isInExactPieChartArea(t,e.center,e.radius)){var o=Math.atan2(e.center.y-t.y,t.x-e.center.x);o=-o;if(a.extra.pie&&a.extra.pie.offsetAngle){o=o-a.extra.pie.offsetAngle*Math.PI/180}if(a.extra.ring&&a.extra.ring.offsetAngle){o=o-a.extra.ring.offsetAngle*Math.PI/180}for(var n=0,l=r.length;n<l;n++){if(isInAngleRange(o,r[n]._start_,r[n]._start_+r[n]._proportion_*2*Math.PI)){i=n;break}}}return i}function isInExactPieChartArea(t,e,a){return Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2)<=Math.pow(a,2)}function splitPoints(t,a){var i=[];var r=[];t.forEach(function(t,e){if(a.connectNulls){if(t!==null){r.push(t)}}else{if(t!==null){r.push(t)}else{if(r.length){i.push(r)}r=[]}}});if(r.length){i.push(r)}return i}function calLegendData(l,s,e,t,h){let c={area:{start:{x:0,y:0},end:{x:0,y:0},width:0,height:0,wholeWidth:0,wholeHeight:0},points:[],widthArr:[],heightArr:[]};if(s.legend.show===false){t.legendData=c;return c}let d=s.legend.padding*s.pix;let x=s.legend.margin*s.pix;let f=s.legend.fontSize?s.legend.fontSize*s.pix:e.fontSize;let p=15*s.pix;let u=5*s.pix;let g=Math.max(s.legend.lineHeight*s.pix,f);if(s.legend.position=="top"||s.legend.position=="bottom"){let i=[];let r=0;let o=[];let n=[];for(let a=0;a<l.length;a++){let t=l[a];const y=t.legendText?t.legendText:t.name;let e=p+u+measureText(y||"undefined",f,h)+s.legend.itemGap*s.pix;if(r+e>s.width-s.area[1]-s.area[3]){i.push(n);o.push(r-s.legend.itemGap*s.pix);r=e;n=[t]}else{r+=e;n.push(t)}}if(n.length){i.push(n);o.push(r-s.legend.itemGap*s.pix);c.widthArr=o;let t=Math.max.apply(null,o);switch(s.legend.float){case"left":c.area.start.x=s.area[3];c.area.end.x=s.area[3]+t+2*d;break;case"right":c.area.start.x=s.width-s.area[1]-t-2*d;c.area.end.x=s.width-s.area[1];break;default:c.area.start.x=(s.width-t)/2-d;c.area.end.x=(s.width+t)/2+d}c.area.width=t+2*d;c.area.wholeWidth=t+2*d;c.area.height=i.length*g+2*d;c.area.wholeHeight=i.length*g+2*d+2*x;c.points=i}}else{let t=l.length;let e=s.height-s.area[0]-s.area[2]-2*x-2*d;let a=Math.min(Math.floor(e/g),t);c.area.height=a*g+d*2;c.area.wholeHeight=a*g+d*2;switch(s.legend.float){case"top":c.area.start.y=s.area[0]+x;c.area.end.y=s.area[0]+x+c.area.height;break;case"bottom":c.area.start.y=s.height-s.area[2]-x-c.area.height;c.area.end.y=s.height-s.area[2]-x;break;default:c.area.start.y=(s.height-c.area.height)/2;c.area.end.y=(s.height+c.area.height)/2}let i=t%a===0?t/a:Math.floor(t/a+1);let r=[];for(let e=0;e<i;e++){let t=l.slice(e*a,e*a+a);r.push(t)}c.points=r;if(r.length){for(let t=0;t<r.length;t++){let a=r[t];let i=0;for(let e=0;e<a.length;e++){let t=p+u+measureText(a[e].name||"undefined",f,h)+s.legend.itemGap*s.pix;if(t>i){i=t}}c.widthArr.push(i);c.heightArr.push(a.length*g+d*2)}let e=0;for(let t=0;t<c.widthArr.length;t++){e+=c.widthArr[t]}c.area.width=e-s.legend.itemGap*s.pix+2*d;c.area.wholeWidth=c.area.width+d}}switch(s.legend.position){case"top":c.area.start.y=s.area[0]+x;c.area.end.y=s.area[0]+x+c.area.height;break;case"bottom":c.area.start.y=s.height-s.area[2]-c.area.height-x;c.area.end.y=s.height-s.area[2]-x;break;case"left":c.area.start.x=s.area[3];c.area.end.x=s.area[3]+c.area.width;break;case"right":c.area.start.x=s.width-s.area[1]-c.area.width;c.area.end.x=s.width-s.area[1];break}t.legendData=c;return c}function calCategoriesData(t,i,e,a,r){var o={angle:0,xAxisHeight:e.xAxisHeight};var n=i.xAxis.fontSize*i.pix||e.fontSize;var l=t.map(function(t,e){var a=i.xAxis.formatter?i.xAxis.formatter(t,e,i):t;return measureText(String(a),n,r)});var s=Math.max.apply(this,l);if(i.xAxis.rotateLabel==true){o.angle=i.xAxis.rotateAngle*Math.PI/180;let t=2*e.xAxisTextPadding+Math.abs(s*Math.sin(o.angle));t=t<n+2*e.xAxisTextPadding?t+2*e.xAxisTextPadding:t;if(i.enableScroll==true&&i.xAxis.scrollShow==true){t+=12*i.pix}o.xAxisHeight=t}if(i.xAxis.disabled){o.xAxisHeight=0}return o}function getXAxisTextList(t,e,h,c){var a=arguments.length>4&&arguments[4]!==undefined?arguments[4]:-1;var i;if(c=="stack"){i=dataCombineStack(t,e.categories.length)}else{i=dataCombine(t)}var r=[];i=i.filter(function(t){if(typeof t==="object"&&t!==null){if(t.constructor.toString().indexOf("Array")>-1){return t!==null}else{return t.value!==null}}else{return t!==null}});i.map(function(t){if(typeof t==="object"){if(t.constructor.toString().indexOf("Array")>-1){if(e.type=="candle"){t.map(function(t){r.push(t)})}else{r.push(t[0])}}else{r.push(t.value)}}else{r.push(t)}});var o=0;var n=0;if(r.length>0){o=Math.min.apply(this,r);n=Math.max.apply(this,r)}if(a>-1){if(typeof e.xAxis.data[a].min==="number"){o=Math.min(e.xAxis.data[a].min,o)}if(typeof e.xAxis.data[a].max==="number"){n=Math.max(e.xAxis.data[a].max,n)}}else{if(typeof e.xAxis.min==="number"){o=Math.min(e.xAxis.min,o)}if(typeof e.xAxis.max==="number"){n=Math.max(e.xAxis.max,n)}}if(o===n){var d=n||10;n+=d}var l=o;var x=n;var f=[];var p=(x-l)/e.xAxis.splitNumber;for(var s=0;s<=e.xAxis.splitNumber;s++){f.push(l+p*s)}return f}function calXAxisData(t,e,a,i){var r=assign({},{type:""},e.extra.bar);var o={angle:0,xAxisHeight:a.xAxisHeight};o.ranges=getXAxisTextList(t,e,a,r.type);o.rangesFormat=o.ranges.map(function(t){t=util.toFixed(t,2);return t});var n=o.ranges.map(function(t){t=util.toFixed(t,2);return t});o=Object.assign(o,getXAxisPoints(n,e,a));var l=o.eachSpacing;var s=n.map(function(t){return measureText(t,e.xAxis.fontSize*e.pix||a.fontSize,i)});var h=Math.max.apply(this,s);if(h+2*a.xAxisTextPadding>l){o.angle=45*Math.PI/180;o.xAxisHeight=2*a.xAxisTextPadding+h*Math.sin(o.angle)}if(e.xAxis.disabled===true){o.xAxisHeight=0}return o}function getRadarDataPoints(r,o,n,a,t){var l=arguments.length>5&&arguments[5]!==undefined?arguments[5]:1;var e=t.extra.radar||{};e.max=e.max||0;var s=Math.max(e.max,Math.max.apply(null,dataCombine(a)));var h=[];for(let e=0;e<a.length;e++){let t=a[e];let i={};i.color=t.color;i.legendShape=t.legendShape;i.pointShape=t.pointShape;i.data=[];t.data.forEach(function(t,e){let a={};a.angle=r[e];a.proportion=t/s;a.value=t;a.position=convertCoordinateOrigin(n*a.proportion*l*Math.cos(a.angle),n*a.proportion*l*Math.sin(a.angle),o);i.data.push(a)});h.push(i)}return h}function getPieDataPoints(a,i){var r=arguments.length>2&&arguments[2]!==undefined?arguments[2]:1;var o=0;var n=0;for(let e=0;e<a.length;e++){let t=a[e];t.data=t.data===null?0:t.data;o+=t.data}for(let e=0;e<a.length;e++){let t=a[e];t.data=t.data===null?0:t.data;if(o===0){t._proportion_=1/a.length*r}else{t._proportion_=t.data/o*r}t._radius_=i}for(let e=0;e<a.length;e++){let t=a[e];t._start_=n;n+=2*t._proportion_*Math.PI}return a}function getFunnelDataPoints(e,a,i,r){var o=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;e=e.sort(function(t,e){return parseInt(e.data)-parseInt(t.data)});for(let t=0;t<e.length;t++){if(i=="funnel"){e[t].radius=e[t].data/e[0].data*a*o}else{e[t].radius=r*(e.length-t)/(r*e.length)*a*o}e[t]._proportion_=e[t].data/e[0].data}if(i!=="pyramid"){e.reverse()}return e}function getRoseDataPoints(a,i,r,o){var n=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;var l=0;var s=0;var h=[];for(let e=0;e<a.length;e++){let t=a[e];t.data=t.data===null?0:t.data;l+=t.data;h.push(t.data)}var c=Math.min.apply(null,h);var d=Math.max.apply(null,h);var x=o-r;for(let e=0;e<a.length;e++){let t=a[e];t.data=t.data===null?0:t.data;if(l===0){t._proportion_=1/a.length*n;t._rose_proportion_=1/a.length*n}else{t._proportion_=t.data/l*n;if(i=="area"){t._rose_proportion_=1/a.length*n}else{t._rose_proportion_=t.data/l*n}}t._radius_=r+x*((t.data-c)/(d-c))||o}for(let e=0;e<a.length;e++){let t=a[e];t._start_=s;s+=2*t._rose_proportion_*Math.PI}return a}function getArcbarDataPoints(i,r){var o=arguments.length>2&&arguments[2]!==undefined?arguments[2]:1;if(o==1){o=.999999}for(let a=0;a<i.length;a++){let t=i[a];t.data=t.data===null?0:t.data;let e;if(r.type=="circle"){e=2}else{if(r.endAngle<r.startAngle){e=2+r.endAngle-r.startAngle}else{e=r.startAngle-r.endAngle}}t._proportion_=e*t.data*o+r.startAngle;if(t._proportion_>=2){t._proportion_=t._proportion_%2}}return i}function getGaugeArcbarDataPoints(i,r){var o=arguments.length>2&&arguments[2]!==undefined?arguments[2]:1;if(o==1){o=.999999}for(let a=0;a<i.length;a++){let t=i[a];t.data=t.data===null?0:t.data;let e;if(r.type=="circle"){e=2}else{if(r.endAngle<r.startAngle){e=2+r.endAngle-r.startAngle}else{e=r.startAngle-r.endAngle}}t._proportion_=e*t.data*o+r.startAngle;if(t._proportion_>=2){t._proportion_=t._proportion_%2}}return i}function getGaugeAxisPoints(e,a,t){let i=a-t+1;let r=a;for(let t=0;t<e.length;t++){e[t].value=e[t].value===null?0:e[t].value;e[t]._startAngle_=r;e[t]._endAngle_=i*e[t].value+a;if(e[t]._endAngle_>=2){e[t]._endAngle_=e[t]._endAngle_%2}r=e[t]._endAngle_}return e}function getGaugeDataPoints(i,r,o){let n=arguments.length>3&&arguments[3]!==undefined?arguments[3]:1;for(let a=0;a<i.length;a++){let e=i[a];e.data=e.data===null?0:e.data;if(o.pointer.color=="auto"){for(let t=0;t<r.length;t++){if(e.data<=r[t].value){e.color=r[t].color;break}}}else{e.color=o.pointer.color}let t=o.startAngle-o.endAngle+1;e._endAngle_=t*e.data+o.startAngle;e._oldAngle_=o.oldAngle;if(o.oldAngle<o.endAngle){e._oldAngle_+=2}if(e.data>=o.oldData){e._proportion_=(e._endAngle_-e._oldAngle_)*n+o.oldAngle}else{e._proportion_=e._oldAngle_-(e._oldAngle_-e._endAngle_)*n}if(e._proportion_>=2){e._proportion_=e._proportion_%2}}return i}function getPieTextMaxLength(i,r,o,n){i=getPieDataPoints(i);let l=0;for(let a=0;a<i.length;a++){let t=i[a];let e=t.formatter?t.formatter(+t._proportion_.toFixed(2)):util.toFixed(t._proportion_*100)+"%";l=Math.max(l,measureText(e,t.textSize*n.pix||r.fontSize,o))}return l}function fixColumeData(t,i,r,o,e,n){return t.map(function(t){if(t===null){return null}var e=0;var a=0;if(n.type=="mix"){e=n.extra.mix.column.seriesGap*n.pix||0;a=n.extra.mix.column.categoryGap*n.pix||0}else{e=n.extra.column.seriesGap*n.pix||0;a=n.extra.column.categoryGap*n.pix||0}e=Math.min(e,i/r);a=Math.min(a,i/r);t.width=Math.ceil((i-2*a-e*(r-1))/r);if(n.extra.mix&&n.extra.mix.column.width&&+n.extra.mix.column.width>0){t.width=Math.min(t.width,+n.extra.mix.column.width*n.pix)}if(n.extra.column&&n.extra.column.width&&+n.extra.column.width>0){t.width=Math.min(t.width,+n.extra.column.width*n.pix)}if(t.width<=0){t.width=1}t.x+=(o+.5-r/2)*(t.width+e);return t})}function fixBarData(t,i,r,o,e,n){return t.map(function(t){if(t===null){return null}var e=0;var a=0;e=n.extra.bar.seriesGap*n.pix||0;a=n.extra.bar.categoryGap*n.pix||0;e=Math.min(e,i/r);a=Math.min(a,i/r);t.width=Math.ceil((i-2*a-e*(r-1))/r);if(n.extra.bar&&n.extra.bar.width&&+n.extra.bar.width>0){t.width=Math.min(t.width,+n.extra.bar.width*n.pix)}if(t.width<=0){t.width=1}t.y+=(o+.5-r/2)*(t.width+e);return t})}function fixColumeMeterData(t,e,a,i,r,o,n){var l=o.extra.column.categoryGap*o.pix||0;return t.map(function(t){if(t===null){return null}t.width=e-2*l;if(o.extra.column&&o.extra.column.width&&+o.extra.column.width>0){t.width=Math.min(t.width,+o.extra.column.width*o.pix)}if(i>0){t.width-=n}return t})}function fixColumeStackData(t,a,e,i,r,o,n){var l=o.extra.column.categoryGap*o.pix||0;return t.map(function(t,e){if(t===null){return null}t.width=Math.ceil(a-2*l);if(o.extra.column&&o.extra.column.width&&+o.extra.column.width>0){t.width=Math.min(t.width,+o.extra.column.width*o.pix)}if(t.width<=0){t.width=1}return t})}function fixBarStackData(t,a,e,i,r,o,n){var l=o.extra.bar.categoryGap*o.pix||0;return t.map(function(t,e){if(t===null){return null}t.width=Math.ceil(a-2*l);if(o.extra.bar&&o.extra.bar.width&&+o.extra.bar.width>0){t.width=Math.min(t.width,+o.extra.bar.width*o.pix)}if(t.width<=0){t.width=1}return t})}function getXAxisPoints(t,e,h){var a=e.width-e.area[1]-e.area[3];var i=e.enableScroll?Math.min(e.xAxis.itemCount,t.length):t.length;if((e.type=="line"||e.type=="area"||e.type=="scatter"||e.type=="bubble"||e.type=="bar")&&i>1&&e.xAxis.boundaryGap=="justify"){i-=1}var r=0;if(e.type=="mount"&&e.extra&&e.extra.mount&&e.extra.mount.widthRatio&&e.extra.mount.widthRatio>1){if(e.extra.mount.widthRatio>2)e.extra.mount.widthRatio=2;r=e.extra.mount.widthRatio-1;i+=r}var o=a/i;var n=[];var l=e.area[3];var s=e.width-e.area[1];t.forEach(function(t,e){n.push(l+r/2*o+e*o)});if(e.xAxis.boundaryGap!=="justify"){if(e.enableScroll===true){n.push(l+r*o+t.length*o)}else{n.push(s)}}return{xAxisPoints:n,startX:l,endX:s,eachSpacing:o}}function getCandleDataPoints(t,l,s,h,c,d,a){var x=arguments.length>7&&arguments[7]!==undefined?arguments[7]:1;var e=[];var f=d.height-d.area[0]-d.area[2];t.forEach(function(t,o){if(t===null){e.push(null)}else{var n=[];t.forEach(function(t,e){var a={};a.x=h[o]+Math.round(c/2);var i=t.value||t;var r=f*(i-l)/(s-l);r*=x;a.y=d.height-Math.round(r)-d.area[2];n.push(a)});e.push(n)}});return e}function getDataPoints(t,a,n,l,s,h,e){var c=arguments.length>7&&arguments[7]!==undefined?arguments[7]:1;var d="center";if(h.type=="line"||h.type=="area"||h.type=="scatter"||h.type=="bubble"){d=h.xAxis.boundaryGap}var x=[];var f=h.height-h.area[0]-h.area[2];var p=h.width-h.area[1]-h.area[3];t.forEach(function(i,t){if(i===null){x.push(null)}else{var r={};r.color=i.color;r.x=l[t];var o=i;if(typeof i==="object"&&i!==null){if(i.constructor.toString().indexOf("Array")>-1){let t,e,a;t=[].concat(h.chartData.xAxisData.ranges);e=t.shift();a=t.pop();o=i[1];r.x=h.area[3]+p*(i[0]-e)/(a-e);if(h.type=="bubble"){r.r=i[2];r.t=i[3]}}else{o=i.value}}if(d=="center"){r.x+=s/2}var e=f*(o-a)/(n-a);e*=c;r.y=h.height-e-h.area[2];x.push(r)}});return x}function getMountDataPoints(t,o,n,l,s,h,e){var c=arguments.length>7&&arguments[7]!==undefined?arguments[7]:1;var d=[];var x=h.height-h.area[0]-h.area[2];var a=h.width-h.area[1]-h.area[3];var f=s*e.widthRatio;t.forEach(function(t,e){if(t===null){d.push(null)}else{var a={};a.color=t.color;a.x=l[e];a.x+=s/2;var i=t.data;var r=x*(i-o)/(n-o);r*=c;a.y=h.height-r-h.area[2];a.value=i;a.width=f;d.push(a)}});return d}function getBarDataPoints(t,o,n,l,e,s,a){var h=arguments.length>7&&arguments[7]!==undefined?arguments[7]:1;var c=[];var i=s.height-s.area[0]-s.area[2];var d=s.width-s.area[1]-s.area[3];t.forEach(function(t,e){if(t===null){c.push(null)}else{var a={};a.color=t.color;a.y=l[e];var i=t;if(typeof t==="object"&&t!==null){i=t.value}var r=d*(i-o)/(n-o);r*=h;a.height=r;a.value=i;a.x=r+s.area[3];c.push(a)}});return c}function getStackDataPoints(t,s,h,c,u,d,e,x,y){var f=arguments.length>9&&arguments[9]!==undefined?arguments[9]:1;var p=[];var g=d.height-d.area[0]-d.area[2];t.forEach(function(t,e){if(t===null){p.push(null)}else{var a={};a.color=t.color;a.x=c[e]+Math.round(u/2);if(x>0){var i=0;for(let t=0;t<=x;t++){i+=y[t].data[e]}var r=i-t;var o=g*(i-s)/(h-s);var n=g*(r-s)/(h-s)}else{var i=t;var o=g*(i-s)/(h-s);var n=0}var l=n;o*=f;l*=f;a.y=d.height-Math.round(o)-d.area[2];a.y0=d.height-Math.round(l)-d.area[2];p.push(a)}});return p}function getBarStackDataPoints(t,s,h,c,e,d,a,x,u){var f=arguments.length>9&&arguments[9]!==undefined?arguments[9]:1;var p=[];var g=d.width-d.area[1]-d.area[3];t.forEach(function(t,e){if(t===null){p.push(null)}else{var a={};a.color=t.color;a.y=c[e];if(x>0){var i=0;for(let t=0;t<=x;t++){i+=u[t].data[e]}var r=i-t;var o=g*(i-s)/(h-s);var n=g*(r-s)/(h-s)}else{var i=t;var o=g*(i-s)/(h-s);var n=0}var l=n;o*=f;l*=f;a.height=o-l;a.x=d.area[3]+o;a.x0=d.area[3]+l;p.push(a)}});return p}function getYAxisTextList(t,e,h,c,a){var d=arguments.length>5&&arguments[5]!==undefined?arguments[5]:-1;var i;if(c=="stack"){i=dataCombineStack(t,e.categories.length)}else{i=dataCombine(t)}var r=[];i=i.filter(function(t){if(typeof t==="object"&&t!==null){if(t.constructor.toString().indexOf("Array")>-1){return t!==null}else{return t.value!==null}}else{return t!==null}});i.map(function(t){if(typeof t==="object"){if(t.constructor.toString().indexOf("Array")>-1){if(e.type=="candle"){t.map(function(t){r.push(t)})}else{r.push(t[1])}}else{r.push(t.value)}}else{r.push(t)}});var o=a.min||0;var n=a.max||0;if(r.length>0){o=Math.min.apply(this,r);n=Math.max.apply(this,r)}if(o===n){if(n==0){n=10}else{o=0}}var l=getDataRange(o,n);var x=a.min===undefined||a.min===null?l.minRange:a.min;var f=a.max===undefined||a.max===null?l.maxRange:a.max;var p=[];var g=(f-x)/e.yAxis.splitNumber;for(var s=0;s<=e.yAxis.splitNumber;s++){p.push(x+g*s)}return p.reverse()}function calYAxisData(a,o,e,n){var l=assign({},{type:""},o.extra.column);var t=o.yAxis.data.length;var s=new Array(t);if(t>0){for(let e=0;e<t;e++){s[e]=[];for(let t=0;t<a.length;t++){if(a[t].index==e){s[e].push(a[t])}}}var h=new Array(t);var c=new Array(t);var d=new Array(t);for(let r=0;r<t;r++){let i=o.yAxis.data[r];if(o.yAxis.disabled==true){i.disabled=true}if(i.type==="categories"){if(!i.formatter){i.formatter=(t,e,a)=>{return t+(i.unit||"")}}i.categories=i.categories||o.categories;h[r]=i.categories}else{if(!i.formatter){i.formatter=(t,e,a)=>{return t.toFixed(i.tofix)+(i.unit||"")}}h[r]=getYAxisTextList(s[r],o,e,l.type,i,r)}let a=i.fontSize*o.pix||e.fontSize;d[r]={position:i.position?i.position:"left",width:0};c[r]=h[r].map(function(t,e){t=i.formatter(t,e,o);d[r].width=Math.max(d[r].width,measureText(t,a,n)+5);return t});let t=i.calibration?4*o.pix:0;d[r].width+=t+3*o.pix;if(i.disabled===true){d[r].width=0}}}else{var h=new Array(1);var c=new Array(1);var d=new Array(1);if(o.type==="bar"){h[0]=o.categories;if(!o.yAxis.formatter){o.yAxis.formatter=(t,e,a)=>{return t+(a.yAxis.unit||"")}}}else{if(!o.yAxis.formatter){o.yAxis.formatter=(t,e,a)=>{return t.toFixed(a.yAxis.tofix)+(a.yAxis.unit||"")}}h[0]=getYAxisTextList(a,o,e,l.type,{})}d[0]={position:"left",width:0};var i=o.yAxis.fontSize*o.pix||e.fontSize;c[0]=h[0].map(function(t,e){t=o.yAxis.formatter(t,e,o);d[0].width=Math.max(d[0].width,measureText(t,i,n)+5);return t});d[0].width+=3*o.pix;if(o.yAxis.disabled===true){d[0]={position:"left",width:0};o.yAxis.data[0]={disabled:true}}else{o.yAxis.data[0]={disabled:false,position:"left",max:o.yAxis.max,min:o.yAxis.min,formatter:o.yAxis.formatter};if(o.type==="bar"){o.yAxis.data[0].categories=o.categories;o.yAxis.data[0].type="categories"}}}return{rangesFormat:c,ranges:h,yAxisWidth:d}}function calTooltipYAxisData(r,t,o,e,a){let n=[].concat(o.chartData.yAxisData.ranges);let l=o.height-o.area[0]-o.area[2];let s=o.area[0];let h=[];for(let i=0;i<n.length;i++){let t=n[i].shift();let e=n[i].pop();let a=t-(t-e)*(r-s)/l;a=o.yAxis.data[i].formatter?o.yAxis.data[i].formatter(a):a.toFixed(0);h.push(String(a))}return h}function calMarkLineData(i,r){let o,n;let l=r.height-r.area[0]-r.area[2];for(let a=0;a<i.length;a++){i[a].yAxisIndex=i[a].yAxisIndex?i[a].yAxisIndex:0;let t=[].concat(r.chartData.yAxisData.ranges[i[a].yAxisIndex]);o=t.pop();n=t.shift();let e=l*(i[a].value-o)/(n-o);i[a].y=r.height-Math.round(e)-r.area[2]}return i}function contextRotate(t,e){if(e.rotateLock!==true){t.translate(e.height,0);t.rotate(90*Math.PI/180)}else if(e._rotate_!==true){t.translate(e.height,0);t.rotate(90*Math.PI/180);e._rotate_=true}}function drawPointShape(t,e,a,i,r){i.beginPath();if(r.dataPointShapeType=="hollow"){i.setStrokeStyle(e);i.setFillStyle(r.background);i.setLineWidth(2*r.pix)}else{i.setStrokeStyle("#ffffff");i.setFillStyle(e);i.setLineWidth(1*r.pix)}if(a==="diamond"){t.forEach(function(t,e){if(t!==null){i.moveTo(t.x,t.y-4.5);i.lineTo(t.x-4.5,t.y);i.lineTo(t.x,t.y+4.5);i.lineTo(t.x+4.5,t.y);i.lineTo(t.x,t.y-4.5)}})}else if(a==="circle"){t.forEach(function(t,e){if(t!==null){i.moveTo(t.x+2.5*r.pix,t.y);i.arc(t.x,t.y,3*r.pix,0,2*Math.PI,false)}})}else if(a==="square"){t.forEach(function(t,e){if(t!==null){i.moveTo(t.x-3.5,t.y-3.5);i.rect(t.x-3.5,t.y-3.5,7,7)}})}else if(a==="triangle"){t.forEach(function(t,e){if(t!==null){i.moveTo(t.x,t.y-4.5);i.lineTo(t.x-4.5,t.y+4.5);i.lineTo(t.x+4.5,t.y+4.5);i.lineTo(t.x,t.y-4.5)}})}else if(a==="triangle"){return}i.closePath();i.fill();i.stroke()}function drawRingTitle(t,e,a,i){var r=t.title.fontSize||e.titleFontSize;var o=t.subtitle.fontSize||e.subtitleFontSize;var n=t.title.name||"";var l=t.subtitle.name||"";var c=t.title.color||t.fontColor;var d=t.subtitle.color||t.fontColor;var x=n?r:0;var f=l?o:0;var s=5;if(l){var p=measureText(l,o*t.pix,a);var g=i.x-p/2+(t.subtitle.offsetX||0)*t.pix;var h=i.y+o*t.pix/2+(t.subtitle.offsetY||0)*t.pix;if(n){h+=(x*t.pix+s)/2}a.beginPath();a.setFontSize(o*t.pix);a.setFillStyle(d);a.fillText(l,g,h);a.closePath();a.stroke()}if(n){var u=measureText(n,r*t.pix,a);var y=i.x-u/2+(t.title.offsetX||0);var v=i.y+r*t.pix/2+(t.title.offsetY||0)*t.pix;if(l){v-=(f*t.pix+s)/2}a.beginPath();a.setFontSize(r*t.pix);a.setFillStyle(c);a.fillText(n,y,v);a.closePath();a.stroke()}}function drawPointText(t,o,n,l,s){var h=o.data;var c=o.textOffset?o.textOffset:0;t.forEach(function(t,e){if(t!==null){l.beginPath();var a=o.textSize?o.textSize*s.pix:n.fontSize;l.setFontSize(a);l.setFillStyle(o.textColor||s.fontColor);var i=h[e];if(typeof h[e]==="object"&&h[e]!==null){if(h[e].constructor.toString().indexOf("Array")>-1){i=h[e][1]}else{i=h[e].value}}var r=o.formatter?o.formatter(i,e,o,s):i;l.setTextAlign("center");l.fillText(String(r),t.x,t.y-4+c*s.pix);l.closePath();l.stroke();l.setTextAlign("left")}})}function drawMountPointText(t,o,n,l,s){var e=o.data;var h=o.textOffset?o.textOffset:0;t.forEach(function(t,e){if(t!==null){l.beginPath();var a=o[e].textSize?o[e].textSize*s.pix:n.fontSize;l.setFontSize(a);l.setFillStyle(o[e].textColor||s.fontColor);var i=t.value;var r=o[e].formatter?o[e].formatter(i,e,o,s):i;l.setTextAlign("center");l.fillText(String(r),t.x,t.y-4+h*s.pix);l.closePath();l.stroke();l.setTextAlign("left")}})}function drawBarPointText(t,o,n,l,s){var h=o.data;var e=o.textOffset?o.textOffset:0;t.forEach(function(t,e){if(t!==null){l.beginPath();var a=o.textSize?o.textSize*s.pix:n.fontSize;l.setFontSize(a);l.setFillStyle(o.textColor||s.fontColor);var i=h[e];if(typeof h[e]==="object"&&h[e]!==null){i=h[e].value}var r=o.formatter?o.formatter(i,e,o,s):i;l.setTextAlign("left");l.fillText(String(r),t.x+4*s.pix,t.y+a/2-3);l.closePath();l.stroke()}})}function drawGaugeLabel(e,a,i,r,o,n){a-=e.width/2+e.labelOffset*r.pix;a=a<10?10:a;let t=e.startAngle-e.endAngle+1;let d=t/e.splitLine.splitNumber;let x=e.endNumber-e.startNumber;let f=x/e.splitLine.splitNumber;let l=e.startAngle;let s=e.startNumber;for(let t=0;t<e.splitLine.splitNumber+1;t++){var h={x:a*Math.cos(l*Math.PI),y:a*Math.sin(l*Math.PI)};var c=e.formatter?e.formatter(s,t,r):s;h.x+=i.x-measureText(c,o.fontSize,n)/2;h.y+=i.y;var p=h.x;var g=h.y;n.beginPath();n.setFontSize(o.fontSize);n.setFillStyle(e.labelColor||r.fontColor);n.fillText(c,p,g+o.fontSize/2);n.closePath();n.stroke();l+=d;if(l>=2){l=l%2}s+=f}}function drawRadarLabel(t,s,h,c,d,x){var f=c.extra.radar||{};t.forEach(function(t,e){if(f.labelPointShow===true&&c.categories[e]!==""){var a={x:s*Math.cos(t),y:s*Math.sin(t)};var i=convertCoordinateOrigin(a.x,a.y,h);x.setFillStyle(f.labelPointColor);x.beginPath();x.arc(i.x,i.y,f.labelPointRadius*c.pix,0,2*Math.PI,false);x.closePath();x.fill()}var r={x:(s+d.radarLabelTextMargin*c.pix)*Math.cos(t),y:(s+d.radarLabelTextMargin*c.pix)*Math.sin(t)};var o=convertCoordinateOrigin(r.x,r.y,h);var n=o.x;var l=o.y;if(util.approximatelyEqual(r.x,0)){n-=measureText(c.categories[e]||"",d.fontSize,x)/2}else if(r.x<0){n-=measureText(c.categories[e]||"",d.fontSize,x)}x.beginPath();x.setFontSize(d.fontSize);x.setFillStyle(f.labelColor||c.fontColor);x.fillText(c.categories[e]||"",n,l+d.fontSize/2);x.closePath();x.stroke()})}function drawPieText(n,d,x,f,t,l){var p=x.pieChartLinePadding;var g=[];var u=null;var y=n.map(function(t,e){var a=t.formatter?t.formatter(t,e,n,d):util.toFixed(t._proportion_.toFixed(4)*100)+"%";a=t.labelText?t.labelText:a;var i=2*Math.PI-(t._start_+2*Math.PI*t._proportion_/2);if(t._rose_proportion_){i=2*Math.PI-(t._start_+2*Math.PI*t._rose_proportion_/2)}var r=t.color;var o=t._radius_;return{arc:i,text:a,color:r,radius:o,textColor:t.textColor,textSize:t.textSize,labelShow:t.labelShow}});for(let c=0;c<y.length;c++){let t=y[c];let e=Math.cos(t.arc)*(t.radius+p);let a=Math.sin(t.arc)*(t.radius+p);let i=Math.cos(t.arc)*t.radius;let r=Math.sin(t.arc)*t.radius;let o=e>=0?e+x.pieChartTextPadding:e-x.pieChartTextPadding;let n=a;let l=measureText(t.text,t.textSize*d.pix||x.fontSize,f);let s=n;if(u&&util.isSameXCoordinateArea(u.start,{x:o})){if(o>0){s=Math.min(n,u.start.y)}else if(e<0){s=Math.max(n,u.start.y)}else{if(n>0){s=Math.max(n,u.start.y)}else{s=Math.min(n,u.start.y)}}}if(o<0){o-=l}let h={lineStart:{x:i,y:r},lineEnd:{x:e,y:a},start:{x:o,y:s},width:l,height:x.fontSize,text:t.text,color:t.color,textColor:t.textColor,textSize:t.textSize};u=avoidCollision(h,u);g.push(u)}for(let n=0;n<g.length;n++){if(y[n].labelShow===false){continue}let t=g[n];let e=convertCoordinateOrigin(t.lineStart.x,t.lineStart.y,l);let a=convertCoordinateOrigin(t.lineEnd.x,t.lineEnd.y,l);let i=convertCoordinateOrigin(t.start.x,t.start.y,l);f.setLineWidth(1*d.pix);f.setFontSize(t.textSize*d.pix||x.fontSize);f.beginPath();f.setStrokeStyle(t.color);f.setFillStyle(t.color);f.moveTo(e.x,e.y);let r=t.start.x<0?i.x+t.width:i.x;let o=t.start.x<0?i.x-5:i.x+5;f.quadraticCurveTo(a.x,a.y,r,i.y);f.moveTo(e.x,e.y);f.stroke();f.closePath();f.beginPath();f.moveTo(i.x+t.width,i.y);f.arc(r,i.y,2*d.pix,0,2*Math.PI);f.closePath();f.fill();f.beginPath();f.setFontSize(t.textSize*d.pix||x.fontSize);f.setFillStyle(t.textColor||d.fontColor);f.fillText(t.text,o,i.y+3);f.closePath();f.stroke();f.closePath()}}function drawToolTipSplitLine(r,o,n,l){var s=o.extra.tooltip||{};s.gridType=s.gridType==undefined?"solid":s.gridType;s.dashLength=s.dashLength==undefined?4:s.dashLength;var t=o.area[0];var h=o.height-o.area[2];if(s.gridType=="dash"){l.setLineDash([s.dashLength,s.dashLength])}l.setStrokeStyle(s.gridColor||"#cccccc");l.setLineWidth(1*o.pix);l.beginPath();l.moveTo(r,t);l.lineTo(r,h);l.stroke();l.setLineDash([]);if(s.xAxisLabel){let t=o.categories[o.tooltip.index];l.setFontSize(n.fontSize);let e=measureText(t,n.fontSize,l);let a=r-.5*e;let i=h;l.beginPath();l.setFillStyle(hexToRgb(s.labelBgColor||n.toolTipBackground,s.labelBgOpacity||n.toolTipOpacity));l.setStrokeStyle(s.labelBgColor||n.toolTipBackground);l.setLineWidth(1*o.pix);l.rect(a-n.toolTipPadding,i,e+2*n.toolTipPadding,n.fontSize+2*n.toolTipPadding);l.closePath();l.stroke();l.fill();l.beginPath();l.setFontSize(n.fontSize);l.setFillStyle(s.labelFontColor||o.fontColor);l.fillText(String(t),a,i+n.toolTipPadding+n.fontSize);l.closePath();l.stroke()}}function drawMarkLine(s,h,c){let e=assign({},{type:"solid",dashLength:4,data:[]},s.extra.markLine);let a=s.area[3];let i=s.width-s.area[1];let r=calMarkLineData(e.data,s);for(let t=0;t<r.length;t++){let l=assign({},{lineColor:"#DE4A42",showLabel:false,labelFontColor:"#666666",labelBgColor:"#DFE8FF",labelBgOpacity:.8,labelAlign:"left",labelOffsetX:0,labelOffsetY:0},r[t]);if(e.type=="dash"){c.setLineDash([e.dashLength,e.dashLength])}c.setStrokeStyle(l.lineColor);c.setLineWidth(1*s.pix);c.beginPath();c.moveTo(a,l.y);c.lineTo(i,l.y);c.stroke();c.setLineDash([]);if(l.showLabel){let t=l.labelText?l.labelText:l.value;c.setFontSize(h.fontSize);let e=measureText(t,h.fontSize,c);let a=e+h.toolTipPadding*2;let i=l.labelAlign=="left"?s.area[3]-a:s.width-s.area[1];i+=l.labelOffsetX;let r=l.y-.5*h.fontSize-h.toolTipPadding;r+=l.labelOffsetY;let o=i+h.toolTipPadding;let n=l.y;c.setFillStyle(hexToRgb(l.labelBgColor,l.labelBgOpacity));c.setStrokeStyle(l.labelBgColor);c.setLineWidth(1*s.pix);c.beginPath();c.rect(i,r,a,h.fontSize+2*h.toolTipPadding);c.closePath();c.stroke();c.fill();c.setFontSize(h.fontSize);c.setTextAlign("left");c.setFillStyle(l.labelFontColor);c.fillText(String(t),o,r+h.fontSize+h.toolTipPadding/2);c.stroke();c.setTextAlign("left")}}}function drawToolTipHorizentalLine(d,x,f,t,e){var p=assign({},{gridType:"solid",dashLength:4},d.extra.tooltip);var a=d.area[3];var i=d.width-d.area[1];if(p.gridType=="dash"){f.setLineDash([p.dashLength,p.dashLength])}f.setStrokeStyle(p.gridColor||"#cccccc");f.setLineWidth(1*d.pix);f.beginPath();f.moveTo(a,d.tooltip.offset.y);f.lineTo(i,d.tooltip.offset.y);f.stroke();f.setLineDash([]);if(p.yAxisLabel){let l=calTooltipYAxisData(d.tooltip.offset.y,d.series,d,x,t);let s=d.chartData.yAxisData.yAxisWidth;let h=d.area[3];let c=d.width-d.area[1];for(let n=0;n<l.length;n++){f.setFontSize(x.fontSize);let t=measureText(l[n],x.fontSize,f);let e,a,i;if(s[n].position=="left"){e=h-s[n].width;a=Math.max(e,e+t+x.toolTipPadding*2)}else{e=c;a=Math.max(e+s[n].width,e+t+x.toolTipPadding*2)}i=a-e;let r=e+(i-t)/2;let o=d.tooltip.offset.y;f.beginPath();f.setFillStyle(hexToRgb(p.labelBgColor||x.toolTipBackground,p.labelBgOpacity||x.toolTipOpacity));f.setStrokeStyle(p.labelBgColor||x.toolTipBackground);f.setLineWidth(1*d.pix);f.rect(e,o-.5*x.fontSize-x.toolTipPadding,i,x.fontSize+2*x.toolTipPadding);f.closePath();f.stroke();f.fill();f.beginPath();f.setFontSize(x.fontSize);f.setFillStyle(p.labelFontColor||d.fontColor);f.fillText(l[n],r,o+.5*x.fontSize);f.closePath();f.stroke();if(s[n].position=="left"){h-=s[n].width+d.yAxis.padding*d.pix}else{c+=s[n].width+d.yAxis.padding*d.pix}}}}function drawToolTipSplitArea(t,e,a,i,r){var o=assign({},{activeBgColor:"#000000",activeBgOpacity:.08,activeWidth:r},e.extra.column);o.activeWidth=o.activeWidth>r?r:o.activeWidth;var n=e.area[0];var l=e.height-e.area[2];i.beginPath();i.setFillStyle(hexToRgb(o.activeBgColor,o.activeBgOpacity));i.rect(t-o.activeWidth/2,n,o.activeWidth,l-n);i.closePath();i.fill();i.setFillStyle("#FFFFFF")}function drawBarToolTipSplitArea(t,e,a,i,r){var o=assign({},{activeBgColor:"#000000",activeBgOpacity:.08},e.extra.bar);var n=e.area[3];var l=e.width-e.area[1];i.beginPath();i.setFillStyle(hexToRgb(o.activeBgColor,o.activeBgOpacity));i.rect(n,t-r/2,l-n,r);i.closePath();i.fill();i.setFillStyle("#FFFFFF")}function drawToolTip(t,r,e,o,n,c,d){var l=assign({},{showBox:true,showArrow:true,showCategory:false,bgColor:"#000000",bgOpacity:.7,borderColor:"#000000",borderWidth:0,borderRadius:0,borderOpacity:.7,fontColor:"#FFFFFF",splitLine:true},e.extra.tooltip);if(l.showCategory==true&&e.categories){t.unshift({text:e.categories[e.tooltip.index],color:null})}var x=4*e.pix;var f=5*e.pix;var s=l.showArrow?8*e.pix:0;var p=false;if(e.type=="line"||e.type=="mount"||e.type=="area"||e.type=="candle"||e.type=="mix"){if(l.splitLine==true){drawToolTipSplitLine(e.tooltip.offset.x,e,o,n)}}r=assign({x:0,y:0},r);r.y-=8*e.pix;var g=t.map(function(t){return measureText(t.text,o.fontSize,n)});var h=x+f+4*o.toolTipPadding+Math.max.apply(null,g);var a=2*o.toolTipPadding+t.length*o.toolTipLineHeight;if(l.showBox==false){return}if(r.x-Math.abs(e._scrollDistance_||0)+s+h>e.width){p=true}if(a+r.y>e.height){r.y=e.height-a}n.beginPath();n.setFillStyle(hexToRgb(l.bgColor||o.toolTipBackground,l.bgOpacity||o.toolTipOpacity));n.setLineWidth(l.borderWidth*e.pix);n.setStrokeStyle(hexToRgb(l.borderColor,l.borderOpacity));var i=l.borderRadius;if(p){if(l.showArrow){n.moveTo(r.x,r.y+10*e.pix);n.lineTo(r.x-s,r.y+10*e.pix+5*e.pix)}n.arc(r.x-s-i,r.y+a-i,i,0,Math.PI/2,false);n.arc(r.x-s-Math.round(h)+i,r.y+a-i,i,Math.PI/2,Math.PI,false);n.arc(r.x-s-Math.round(h)+i,r.y+i,i,-Math.PI,-Math.PI/2,false);n.arc(r.x-s-i,r.y+i,i,-Math.PI/2,0,false);if(l.showArrow){n.lineTo(r.x-s,r.y+10*e.pix-5*e.pix);n.lineTo(r.x,r.y+10*e.pix)}}else{if(l.showArrow){n.moveTo(r.x,r.y+10*e.pix);n.lineTo(r.x+s,r.y+10*e.pix-5*e.pix)}n.arc(r.x+s+i,r.y+i,i,-Math.PI,-Math.PI/2,false);n.arc(r.x+s+Math.round(h)-i,r.y+i,i,-Math.PI/2,0,false);n.arc(r.x+s+Math.round(h)-i,r.y+a-i,i,0,Math.PI/2,false);n.arc(r.x+s+i,r.y+a-i,i,Math.PI/2,Math.PI,false);if(l.showArrow){n.lineTo(r.x+s,r.y+10*e.pix+5*e.pix);n.lineTo(r.x,r.y+10*e.pix)}}n.closePath();n.fill();if(l.borderWidth>0){n.stroke()}t.forEach(function(t,e){if(t.color!==null){n.beginPath();n.setFillStyle(t.color);var a=r.x+s+2*o.toolTipPadding;var i=r.y+(o.toolTipLineHeight-o.fontSize)/2+o.toolTipLineHeight*e+o.toolTipPadding+1;if(p){a=r.x-h-s+2*o.toolTipPadding}n.fillRect(a,i,x,o.fontSize);n.closePath()}});t.forEach(function(t,e){var a=r.x+s+2*o.toolTipPadding+x+f;if(p){a=r.x-h-s+2*o.toolTipPadding+ +x+f}var i=r.y+(o.toolTipLineHeight-o.fontSize)/2+o.toolTipLineHeight*e+o.toolTipPadding;n.beginPath();n.setFontSize(o.fontSize);n.setFillStyle(l.fontColor);n.fillText(t.text,a,i+o.fontSize);n.closePath();n.stroke()})}function drawColumnDataPoints(y,v,m,T){let b=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;let t=v.chartData.xAxisData,P=t.xAxisPoints,w=t.eachSpacing;let S=assign({},{type:"group",width:w/2,meterBorder:4,meterFillColor:"#FFFFFF",barBorderCircle:false,barBorderRadius:[],seriesGap:2,linearType:"none",linearOpacity:1,customColor:[],colorStop:0},v.extra.column);let A=[];T.save();let C=-2;let D=P.length+2;if(v._scrollDistance_&&v._scrollDistance_!==0&&v.enableScroll===true){T.translate(v._scrollDistance_,0);C=Math.floor(-v._scrollDistance_/w)-2;D=C+v.xAxis.itemCount+4}if(v.tooltip&&v.tooltip.textList&&v.tooltip.textList.length&&b===1){drawToolTipSplitArea(v.tooltip.offset.x,v,m,T,w)}S.customColor=fillCustomColor(S.linearType,S.customColor,y,m);y.forEach(function(a,i){let t,o,x;t=[].concat(v.chartData.yAxisData.ranges[a.index]);o=t.pop();x=t.shift();var f=a.data;switch(S.type){case"group":var r=getDataPoints(f,o,x,P,w,v,m,b);var p=getStackDataPoints(f,o,x,P,w,v,m,i,y,b);A.push(p);r=fixColumeData(r,w,y.length,i,m,v);for(let t=0;t<r.length;t++){let o=r[t];if(o!==null&&t>C&&t<D){var n=o.x-o.width/2;var l=v.height-o.y-v.area[2];T.beginPath();var s=o.color||a.color;var g=o.color||a.color;if(S.linearType!=="none"){var e=T.createLinearGradient(n,o.y,n,v.height-v.area[2]);if(S.linearType=="opacity"){e.addColorStop(0,hexToRgb(s,S.linearOpacity));e.addColorStop(1,hexToRgb(s,1))}else{e.addColorStop(0,hexToRgb(S.customColor[a.linearIndex],S.linearOpacity));e.addColorStop(S.colorStop,hexToRgb(S.customColor[a.linearIndex],S.linearOpacity));e.addColorStop(1,hexToRgb(s,1))}s=e}if(S.barBorderRadius&&S.barBorderRadius.length===4||S.barBorderCircle===true){const h=n;const c=o.y;const d=o.width;const l=v.height-v.area[2]-o.y;if(S.barBorderCircle){S.barBorderRadius=[d/2,d/2,0,0]}let[t,e,a,i]=S.barBorderRadius;let r=Math.min(d/2,l/2);t=t>r?r:t;e=e>r?r:e;a=a>r?r:a;i=i>r?r:i;t=t<0?0:t;e=e<0?0:e;a=a<0?0:a;i=i<0?0:i;T.arc(h+t,c+t,t,-Math.PI,-Math.PI/2);T.arc(h+d-e,c+e,e,-Math.PI/2,0);T.arc(h+d-a,c+l-a,a,0,Math.PI/2);T.arc(h+i,c+l-i,i,Math.PI/2,Math.PI)}else{T.moveTo(n,o.y);T.lineTo(n+o.width,o.y);T.lineTo(n+o.width,v.height-v.area[2]);T.lineTo(n,v.height-v.area[2]);T.lineTo(n,o.y);T.setLineWidth(1);T.setStrokeStyle(g)}T.setFillStyle(s);T.closePath();T.fill()}};break;case"stack":var r=getStackDataPoints(f,o,x,P,w,v,m,i,y,b);A.push(r);r=fixColumeStackData(r,w,y.length,i,m,v,y);for(let e=0;e<r.length;e++){let t=r[e];if(t!==null&&e>C&&e<D){T.beginPath();var s=t.color||a.color;var n=t.x-t.width/2+1;var l=v.height-t.y-v.area[2];var u=v.height-t.y0-v.area[2];if(i>0){l-=u}T.setFillStyle(s);T.moveTo(n,t.y);T.fillRect(n,t.y,t.width,l);T.closePath();T.fill()}};break;case"meter":var r=getDataPoints(f,o,x,P,w,v,m,b);A.push(r);r=fixColumeMeterData(r,w,y.length,i,m,v,S.meterBorder);for(let t=0;t<r.length;t++){let o=r[t];if(o!==null&&t>C&&t<D){T.beginPath();if(i==0&&S.meterBorder>0){T.setStrokeStyle(a.color);T.setLineWidth(S.meterBorder*v.pix)}if(i==0){T.setFillStyle(S.meterFillColor)}else{T.setFillStyle(o.color||a.color)}var n=o.x-o.width/2;var l=v.height-o.y-v.area[2];if(S.barBorderRadius&&S.barBorderRadius.length===4||S.barBorderCircle===true){const h=n;const c=o.y;const d=o.width;const l=v.height-v.area[2]-o.y;if(S.barBorderCircle){S.barBorderRadius=[d/2,d/2,0,0]}let[t,e,a,i]=S.barBorderRadius;let r=Math.min(d/2,l/2);t=t>r?r:t;e=e>r?r:e;a=a>r?r:a;i=i>r?r:i;t=t<0?0:t;e=e<0?0:e;a=a<0?0:a;i=i<0?0:i;T.arc(h+t,c+t,t,-Math.PI,-Math.PI/2);T.arc(h+d-e,c+e,e,-Math.PI/2,0);T.arc(h+d-a,c+l-a,a,0,Math.PI/2);T.arc(h+i,c+l-i,i,Math.PI/2,Math.PI);T.fill()}else{T.moveTo(n,o.y);T.lineTo(n+o.width,o.y);T.lineTo(n+o.width,v.height-v.area[2]);T.lineTo(n,v.height-v.area[2]);T.lineTo(n,o.y);T.fill()}if(i==0&&S.meterBorder>0){T.closePath();T.stroke()}}}break}});if(v.dataLabel!==false&&b===1){y.forEach(function(t,e){let a,i,r;a=[].concat(v.chartData.yAxisData.ranges[t.index]);i=a.pop();r=a.shift();var o=t.data;switch(S.type){case"group":var n=getDataPoints(o,i,r,P,w,v,m,b);n=fixColumeData(n,w,y.length,e,m,v);drawPointText(n,t,m,T,v);break;case"stack":var n=getStackDataPoints(o,i,r,P,w,v,m,e,y,b);drawPointText(n,t,m,T,v);break;case"meter":var n=getDataPoints(o,i,r,P,w,v,m,b);drawPointText(n,t,m,T,v);break}})}T.restore();return{xAxisPoints:P,calPoints:A,eachSpacing:w}}function drawMountDataPoints(i,n,o,l){let f=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;let t=n.chartData.xAxisData,p=t.xAxisPoints,r=t.eachSpacing;let s=assign({},{type:"mount",widthRatio:1,borderWidth:1,barBorderCircle:false,barBorderRadius:[],linearType:"none",linearOpacity:1,customColor:[],colorStop:0},n.extra.mount);s.widthRatio=s.widthRatio<=0?0:s.widthRatio;s.widthRatio=s.widthRatio>=2?2:s.widthRatio;let e=[];l.save();let a=-2;let g=p.length+2;if(n._scrollDistance_&&n._scrollDistance_!==0&&n.enableScroll===true){l.translate(n._scrollDistance_,0);a=Math.floor(-n._scrollDistance_/r)-2;g=a+n.xAxis.itemCount+4}s.customColor=fillCustomColor(s.linearType,s.customColor,i,o);let u,y,v;u=[].concat(n.chartData.yAxisData.ranges[0]);y=u.pop();v=u.shift();var h=getMountDataPoints(i,y,v,p,r,n,s,f);switch(s.type){case"bar":for(let t=0;t<h.length;t++){let o=h[t];if(o!==null&&t>a&&t<g){var c=o.x-r*s.widthRatio/2;var m=n.height-o.y-n.area[2];l.beginPath();var d=o.color||i[t].color;var T=o.color||i[t].color;if(s.linearType!=="none"){var x=l.createLinearGradient(c,o.y,c,n.height-n.area[2]);if(s.linearType=="opacity"){x.addColorStop(0,hexToRgb(d,s.linearOpacity));x.addColorStop(1,hexToRgb(d,1))}else{x.addColorStop(0,hexToRgb(s.customColor[i[t].linearIndex],s.linearOpacity));x.addColorStop(s.colorStop,hexToRgb(s.customColor[i[t].linearIndex],s.linearOpacity));x.addColorStop(1,hexToRgb(d,1))}d=x}if(s.barBorderRadius&&s.barBorderRadius.length===4||s.barBorderCircle===true){const b=c;const P=o.y;const w=o.width;const m=n.height-n.area[2]-o.y-s.borderWidth*n.pix/2;if(s.barBorderCircle){s.barBorderRadius=[w/2,w/2,0,0]}let[t,e,a,i]=s.barBorderRadius;let r=Math.min(w/2,m/2);t=t>r?r:t;e=e>r?r:e;a=a>r?r:a;i=i>r?r:i;t=t<0?0:t;e=e<0?0:e;a=a<0?0:a;i=i<0?0:i;l.arc(b+t,P+t,t,-Math.PI,-Math.PI/2);l.arc(b+w-e,P+e,e,-Math.PI/2,0);l.arc(b+w-a,P+m-a,a,0,Math.PI/2);l.arc(b+i,P+m-i,i,Math.PI/2,Math.PI)}else{l.moveTo(c,o.y);l.lineTo(c+o.width,o.y);l.lineTo(c+o.width,n.height-n.area[2]);l.lineTo(c,n.height-n.area[2]);l.lineTo(c,o.y)}l.setStrokeStyle(T);l.setFillStyle(d);if(s.borderWidth>0){l.setLineWidth(s.borderWidth*n.pix);l.closePath();l.stroke()}l.fill()}};break;case"triangle":for(let e=0;e<h.length;e++){let t=h[e];if(t!==null&&e>a&&e<g){var c=t.x-r*s.widthRatio/2;var m=n.height-t.y-n.area[2];l.beginPath();var d=t.color||i[e].color;var T=t.color||i[e].color;if(s.linearType!=="none"){var x=l.createLinearGradient(c,t.y,c,n.height-n.area[2]);if(s.linearType=="opacity"){x.addColorStop(0,hexToRgb(d,s.linearOpacity));x.addColorStop(1,hexToRgb(d,1))}else{x.addColorStop(0,hexToRgb(s.customColor[i[e].linearIndex],s.linearOpacity));x.addColorStop(s.colorStop,hexToRgb(s.customColor[i[e].linearIndex],s.linearOpacity));x.addColorStop(1,hexToRgb(d,1))}d=x}l.moveTo(c,n.height-n.area[2]);l.lineTo(t.x,t.y);l.lineTo(c+t.width,n.height-n.area[2]);l.setStrokeStyle(T);l.setFillStyle(d);if(s.borderWidth>0){l.setLineWidth(s.borderWidth*n.pix);l.stroke()}l.fill()}};break;case"mount":for(let e=0;e<h.length;e++){let t=h[e];if(t!==null&&e>a&&e<g){var c=t.x-r*s.widthRatio/2;var m=n.height-t.y-n.area[2];l.beginPath();var d=t.color||i[e].color;var T=t.color||i[e].color;if(s.linearType!=="none"){var x=l.createLinearGradient(c,t.y,c,n.height-n.area[2]);if(s.linearType=="opacity"){x.addColorStop(0,hexToRgb(d,s.linearOpacity));x.addColorStop(1,hexToRgb(d,1))}else{x.addColorStop(0,hexToRgb(s.customColor[i[e].linearIndex],s.linearOpacity));x.addColorStop(s.colorStop,hexToRgb(s.customColor[i[e].linearIndex],s.linearOpacity));x.addColorStop(1,hexToRgb(d,1))}d=x}l.moveTo(c,n.height-n.area[2]);l.bezierCurveTo(t.x-t.width/4,n.height-n.area[2],t.x-t.width/4,t.y,t.x,t.y);l.bezierCurveTo(t.x+t.width/4,t.y,t.x+t.width/4,n.height-n.area[2],c+t.width,n.height-n.area[2]);l.setStrokeStyle(T);l.setFillStyle(d);if(s.borderWidth>0){l.setLineWidth(s.borderWidth*n.pix);l.stroke()}l.fill()}};break;case"sharp":for(let e=0;e<h.length;e++){let t=h[e];if(t!==null&&e>a&&e<g){var c=t.x-r*s.widthRatio/2;var m=n.height-t.y-n.area[2];l.beginPath();var d=t.color||i[e].color;var T=t.color||i[e].color;if(s.linearType!=="none"){var x=l.createLinearGradient(c,t.y,c,n.height-n.area[2]);if(s.linearType=="opacity"){x.addColorStop(0,hexToRgb(d,s.linearOpacity));x.addColorStop(1,hexToRgb(d,1))}else{x.addColorStop(0,hexToRgb(s.customColor[i[e].linearIndex],s.linearOpacity));x.addColorStop(s.colorStop,hexToRgb(s.customColor[i[e].linearIndex],s.linearOpacity));x.addColorStop(1,hexToRgb(d,1))}d=x}l.moveTo(c,n.height-n.area[2]);l.quadraticCurveTo(t.x-0,n.height-n.area[2]-m/4,t.x,t.y);l.quadraticCurveTo(t.x+0,n.height-n.area[2]-m/4,c+t.width,n.height-n.area[2]);l.setStrokeStyle(T);l.setFillStyle(d);if(s.borderWidth>0){l.setLineWidth(s.borderWidth*n.pix);l.stroke()}l.fill()}};break}if(n.dataLabel!==false&&f===1){let t,e,a;t=[].concat(n.chartData.yAxisData.ranges[0]);e=t.pop();a=t.shift();var h=getMountDataPoints(i,e,a,p,r,n,s,f);drawMountPointText(h,i,o,l,n)}l.restore();return{xAxisPoints:p,calPoints:h,eachSpacing:r}}function drawBarDataPoints(y,v,m,T){let b=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;let P=[];let w=(v.height-v.area[0]-v.area[2])/v.categories.length;for(let t=0;t<v.categories.length;t++){P.push(v.area[0]+w/2+w*t)}let S=assign({},{type:"group",width:w/2,meterBorder:4,meterFillColor:"#FFFFFF",barBorderCircle:false,barBorderRadius:[],seriesGap:2,linearType:"none",linearOpacity:1,customColor:[],colorStop:0},v.extra.bar);let A=[];T.save();let C=-2;let D=P.length+2;if(v.tooltip&&v.tooltip.textList&&v.tooltip.textList.length&&b===1){drawBarToolTipSplitArea(v.tooltip.offset.y,v,m,T,w)}S.customColor=fillCustomColor(S.linearType,S.customColor,y,m);y.forEach(function(a,t){let o,e,d;o=[].concat(v.chartData.xAxisData.ranges);d=o.pop();e=o.shift();var x=a.data;switch(S.type){case"group":var i=getBarDataPoints(x,e,d,P,w,v,m,b);var f=getBarStackDataPoints(x,e,d,P,w,v,m,t,y,b);A.push(f);i=fixBarData(i,w,y.length,t,m,v);for(let t=0;t<i.length;t++){let o=i[t];if(o!==null&&t>C&&t<D){var n=v.area[3];var r=o.y-o.width/2;var p=o.height;T.beginPath();var l=o.color||a.color;var g=o.color||a.color;if(S.linearType!=="none"){var s=T.createLinearGradient(n,o.y,o.x,o.y);if(S.linearType=="opacity"){s.addColorStop(0,hexToRgb(l,S.linearOpacity));s.addColorStop(1,hexToRgb(l,1))}else{s.addColorStop(0,hexToRgb(S.customColor[a.linearIndex],S.linearOpacity));s.addColorStop(S.colorStop,hexToRgb(S.customColor[a.linearIndex],S.linearOpacity));s.addColorStop(1,hexToRgb(l,1))}l=s}if(S.barBorderRadius&&S.barBorderRadius.length===4||S.barBorderCircle===true){const u=n;const h=o.width;const c=o.y-o.width/2;const p=o.height;if(S.barBorderCircle){S.barBorderRadius=[h/2,h/2,0,0]}let[t,e,a,i]=S.barBorderRadius;let r=Math.min(h/2,p/2);t=t>r?r:t;e=e>r?r:e;a=a>r?r:a;i=i>r?r:i;t=t<0?0:t;e=e<0?0:e;a=a<0?0:a;i=i<0?0:i;T.arc(u+i,c+i,i,-Math.PI,-Math.PI/2);T.arc(o.x-t,c+t,t,-Math.PI/2,0);T.arc(o.x-e,c+h-e,e,0,Math.PI/2);T.arc(u+a,c+h-a,a,Math.PI/2,Math.PI)}else{T.moveTo(n,r);T.lineTo(o.x,r);T.lineTo(o.x,r+o.width);T.lineTo(n,r+o.width);T.lineTo(n,r);T.setLineWidth(1);T.setStrokeStyle(g)}T.setFillStyle(l);T.closePath();T.fill()}};break;case"stack":var i=getBarStackDataPoints(x,e,d,P,w,v,m,t,y,b);A.push(i);i=fixBarStackData(i,w,y.length,t,m,v,y);for(let e=0;e<i.length;e++){let t=i[e];if(t!==null&&e>C&&e<D){T.beginPath();var l=t.color||a.color;var n=t.x0;T.setFillStyle(l);T.moveTo(n,t.y-t.width/2);T.fillRect(n,t.y-t.width/2,t.height,t.width);T.closePath();T.fill()}};break}});if(v.dataLabel!==false&&b===1){y.forEach(function(t,e){let a,i,r;a=[].concat(v.chartData.xAxisData.ranges);r=a.pop();i=a.shift();var o=t.data;switch(S.type){case"group":var n=getBarDataPoints(o,i,r,P,w,v,m,b);n=fixBarData(n,w,y.length,e,m,v);drawBarPointText(n,t,m,T,v);break;case"stack":var n=getBarStackDataPoints(o,i,r,P,w,v,m,e,y,b);drawBarPointText(n,t,m,T,v);break}})}return{yAxisPoints:P,calPoints:A,eachSpacing:w}}function drawCandleDataPoints(e,t,h,c,d){var u=arguments.length>5&&arguments[5]!==undefined?arguments[5]:1;var s=assign({},{color:{},average:{}},h.extra.candle);s.color=assign({},{upLine:"#f04864",upFill:"#f04864",downLine:"#2fc25b",downFill:"#2fc25b"},s.color);s.average=assign({},{show:false,name:[],day:[],color:c.color},s.average);h.extra.candle=s;let a=h.chartData.xAxisData,x=a.xAxisPoints,f=a.eachSpacing;let y=[];d.save();let p=-2;let v=x.length+2;let g=0;let m=h.width+f;if(h._scrollDistance_&&h._scrollDistance_!==0&&h.enableScroll===true){d.translate(h._scrollDistance_,0);p=Math.floor(-h._scrollDistance_/f)-2;v=p+h.xAxis.itemCount+4;g=-h._scrollDistance_-f*2+h.area[3];m=g+(h.xAxis.itemCount+4)*f}if(s.average.show||t){t.forEach(function(e,t){let a,i,r;a=[].concat(h.chartData.yAxisData.ranges[e.index]);i=a.pop();r=a.shift();var o=e.data;var n=getDataPoints(o,i,r,x,f,h,c,u);var l=splitPoints(n,e);for(let t=0;t<l.length;t++){let i=l[t];d.beginPath();d.setStrokeStyle(e.color);d.setLineWidth(1);if(i.length===1){d.moveTo(i[0].x,i[0].y);d.arc(i[0].x,i[0].y,1,0,2*Math.PI)}else{d.moveTo(i[0].x,i[0].y);let a=0;for(let e=0;e<i.length;e++){let t=i[e];if(a==0&&t.x>g){d.moveTo(t.x,t.y);a=1}if(e>0&&t.x>g&&t.x<m){var s=createCurveControlPoints(i,e-1);d.bezierCurveTo(s.ctrA.x,s.ctrA.y,s.ctrB.x,s.ctrB.y,t.x,t.y)}}d.moveTo(i[0].x,i[0].y)}d.closePath();d.stroke()}})}e.forEach(function(t,e){let a,i,r;a=[].concat(h.chartData.yAxisData.ranges[t.index]);i=a.pop();r=a.shift();var o=t.data;var n=getCandleDataPoints(o,i,r,x,f,h,c,u);y.push(n);var l=splitPoints(n,t);for(let e=0;e<l[0].length;e++){if(e>p&&e<v){let t=l[0][e];d.beginPath();if(o[e][1]-o[e][0]>0){d.setStrokeStyle(s.color.upLine);d.setFillStyle(s.color.upFill);d.setLineWidth(1*h.pix);d.moveTo(t[3].x,t[3].y);d.lineTo(t[1].x,t[1].y);d.lineTo(t[1].x-f/4,t[1].y);d.lineTo(t[0].x-f/4,t[0].y);d.lineTo(t[0].x,t[0].y);d.lineTo(t[2].x,t[2].y);d.lineTo(t[0].x,t[0].y);d.lineTo(t[0].x+f/4,t[0].y);d.lineTo(t[1].x+f/4,t[1].y);d.lineTo(t[1].x,t[1].y);d.moveTo(t[3].x,t[3].y)}else{d.setStrokeStyle(s.color.downLine);d.setFillStyle(s.color.downFill);d.setLineWidth(1*h.pix);d.moveTo(t[3].x,t[3].y);d.lineTo(t[0].x,t[0].y);d.lineTo(t[0].x-f/4,t[0].y);d.lineTo(t[1].x-f/4,t[1].y);d.lineTo(t[1].x,t[1].y);d.lineTo(t[2].x,t[2].y);d.lineTo(t[1].x,t[1].y);d.lineTo(t[1].x+f/4,t[1].y);d.lineTo(t[0].x+f/4,t[0].y);d.lineTo(t[0].x,t[0].y);d.moveTo(t[3].x,t[3].y)}d.closePath();d.fill();d.stroke()}}});d.restore();return{xAxisPoints:x,calPoints:y,eachSpacing:f}}function drawAreaDataPoints(t,s,h,c){var d=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;var x=assign({},{type:"straight",opacity:.2,addLine:false,width:2,gradient:false},s.extra.area);let e=s.chartData.xAxisData,y=e.xAxisPoints,f=e.eachSpacing;let p=s.height-s.area[2];let v=[];c.save();let g=0;let u=s.width+f;if(s._scrollDistance_&&s._scrollDistance_!==0&&s.enableScroll===true){c.translate(s._scrollDistance_,0);g=-s._scrollDistance_-f*2+s.area[3];u=g+(s.xAxis.itemCount+4)*f}t.forEach(function(e,t){let a,i,r;a=[].concat(s.chartData.yAxisData.ranges[e.index]);i=a.pop();r=a.shift();let o=e.data;let n=getDataPoints(o,i,r,y,f,s,h,d);v.push(n);let l=splitPoints(n,e);for(let t=0;t<l.length;t++){let r=l[t];c.beginPath();c.setStrokeStyle(hexToRgb(e.color,x.opacity));if(x.gradient){let t=c.createLinearGradient(0,s.area[0],0,s.height-s.area[2]);t.addColorStop("0",hexToRgb(e.color,x.opacity));t.addColorStop("1.0",hexToRgb("#FFFFFF",.1));c.setFillStyle(t)}else{c.setFillStyle(hexToRgb(e.color,x.opacity))}c.setLineWidth(x.width*s.pix);if(r.length>1){let t=r[0];let e=r[r.length-1];c.moveTo(t.x,t.y);let i=0;if(x.type==="curve"){for(let a=0;a<r.length;a++){let e=r[a];if(i==0&&e.x>g){c.moveTo(e.x,e.y);i=1}if(a>0&&e.x>g&&e.x<u){let t=createCurveControlPoints(r,a-1);c.bezierCurveTo(t.ctrA.x,t.ctrA.y,t.ctrB.x,t.ctrB.y,e.x,e.y)}}}if(x.type==="straight"){for(let e=0;e<r.length;e++){let t=r[e];if(i==0&&t.x>g){c.moveTo(t.x,t.y);i=1}if(e>0&&t.x>g&&t.x<u){c.lineTo(t.x,t.y)}}}if(x.type==="step"){for(let e=0;e<r.length;e++){let t=r[e];if(i==0&&t.x>g){c.moveTo(t.x,t.y);i=1}if(e>0&&t.x>g&&t.x<u){c.lineTo(t.x,r[e-1].y);c.lineTo(t.x,t.y)}}}c.lineTo(e.x,p);c.lineTo(t.x,p);c.lineTo(t.x,t.y)}else{let t=r[0];c.moveTo(t.x-f/2,t.y);c.lineTo(t.x+f/2,t.y);c.lineTo(t.x+f/2,p);c.lineTo(t.x-f/2,p);c.moveTo(t.x-f/2,t.y)}c.closePath();c.fill();if(x.addLine){if(e.lineType=="dash"){let t=e.dashLength?e.dashLength:8;t*=s.pix;c.setLineDash([t,t])}c.beginPath();c.setStrokeStyle(e.color);c.setLineWidth(x.width*s.pix);if(r.length===1){c.moveTo(r[0].x,r[0].y);c.arc(r[0].x,r[0].y,1,0,2*Math.PI)}else{c.moveTo(r[0].x,r[0].y);let i=0;if(x.type==="curve"){for(let a=0;a<r.length;a++){let e=r[a];if(i==0&&e.x>g){c.moveTo(e.x,e.y);i=1}if(a>0&&e.x>g&&e.x<u){let t=createCurveControlPoints(r,a-1);c.bezierCurveTo(t.ctrA.x,t.ctrA.y,t.ctrB.x,t.ctrB.y,e.x,e.y)}}}if(x.type==="straight"){for(let e=0;e<r.length;e++){let t=r[e];if(i==0&&t.x>g){c.moveTo(t.x,t.y);i=1}if(e>0&&t.x>g&&t.x<u){c.lineTo(t.x,t.y)}}}if(x.type==="step"){for(let e=0;e<r.length;e++){let t=r[e];if(i==0&&t.x>g){c.moveTo(t.x,t.y);i=1}if(e>0&&t.x>g&&t.x<u){c.lineTo(t.x,r[e-1].y);c.lineTo(t.x,t.y)}}}c.moveTo(r[0].x,r[0].y)}c.stroke();c.setLineDash([])}}if(s.dataPointShape!==false){drawPointShape(n,e.color,e.pointShape,c,s)}});if(s.dataLabel!==false&&d===1){t.forEach(function(t,e){let a,i,r;a=[].concat(s.chartData.yAxisData.ranges[t.index]);i=a.pop();r=a.shift();var o=t.data;var n=getDataPoints(o,i,r,y,f,s,h,d);drawPointText(n,t,h,c,s)})}c.restore();return{xAxisPoints:y,calPoints:v,eachSpacing:f}}function drawScatterDataPoints(t,s,h,c){var d=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;var i=assign({},{type:"circle"},s.extra.scatter);let e=s.chartData.xAxisData,x=e.xAxisPoints,f=e.eachSpacing;var r=[];c.save();let a=0;let o=s.width+f;if(s._scrollDistance_&&s._scrollDistance_!==0&&s.enableScroll===true){c.translate(s._scrollDistance_,0);a=-s._scrollDistance_-f*2+s.area[3];o=a+(s.xAxis.itemCount+4)*f}t.forEach(function(t,e){let a,i,r;a=[].concat(s.chartData.yAxisData.ranges[t.index]);i=a.pop();r=a.shift();var o=t.data;var n=getDataPoints(o,i,r,x,f,s,h,d);c.beginPath();c.setStrokeStyle(t.color);c.setFillStyle(t.color);c.setLineWidth(1*s.pix);var l=t.pointShape;if(l==="diamond"){n.forEach(function(t,e){if(t!==null){c.moveTo(t.x,t.y-4.5);c.lineTo(t.x-4.5,t.y);c.lineTo(t.x,t.y+4.5);c.lineTo(t.x+4.5,t.y);c.lineTo(t.x,t.y-4.5)}})}else if(l==="circle"){n.forEach(function(t,e){if(t!==null){c.moveTo(t.x+2.5*s.pix,t.y);c.arc(t.x,t.y,3*s.pix,0,2*Math.PI,false)}})}else if(l==="square"){n.forEach(function(t,e){if(t!==null){c.moveTo(t.x-3.5,t.y-3.5);c.rect(t.x-3.5,t.y-3.5,7,7)}})}else if(l==="triangle"){n.forEach(function(t,e){if(t!==null){c.moveTo(t.x,t.y-4.5);c.lineTo(t.x-4.5,t.y+4.5);c.lineTo(t.x+4.5,t.y+4.5);c.lineTo(t.x,t.y-4.5)}})}else if(l==="triangle"){return}c.closePath();c.fill();c.stroke()});if(s.dataLabel!==false&&d===1){t.forEach(function(t,e){let a,i,r;a=[].concat(s.chartData.yAxisData.ranges[t.index]);i=a.pop();r=a.shift();var o=t.data;var n=getDataPoints(o,i,r,x,f,s,h,d);drawPointText(n,t,h,c,s)})}c.restore();return{xAxisPoints:x,calPoints:r,eachSpacing:f}}function drawBubbleDataPoints(l,s,h,c){var d=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;var x=assign({},{opacity:1,border:2},s.extra.bubble);let t=s.chartData.xAxisData,f=t.xAxisPoints,p=t.eachSpacing;var e=[];c.save();let a=0;let i=s.width+p;if(s._scrollDistance_&&s._scrollDistance_!==0&&s.enableScroll===true){c.translate(s._scrollDistance_,0);a=-s._scrollDistance_-p*2+s.area[3];i=a+(s.xAxis.itemCount+4)*p}l.forEach(function(t,e){let a,i,r;a=[].concat(s.chartData.yAxisData.ranges[t.index]);i=a.pop();r=a.shift();var o=t.data;var n=getDataPoints(o,i,r,f,p,s,h,d);c.beginPath();c.setStrokeStyle(t.color);c.setLineWidth(x.border*s.pix);c.setFillStyle(hexToRgb(t.color,x.opacity));n.forEach(function(t,e){c.moveTo(t.x+t.r,t.y);c.arc(t.x,t.y,t.r*s.pix,0,2*Math.PI,false)});c.closePath();c.fill();c.stroke();if(s.dataLabel!==false&&d===1){n.forEach(function(t,e){c.beginPath();var a=l.textSize*s.pix||h.fontSize;c.setFontSize(a);c.setFillStyle(l.textColor||"#FFFFFF");c.setTextAlign("center");c.fillText(String(t.t),t.x,t.y+a/2);c.closePath();c.stroke();c.setTextAlign("left")})}});c.restore();return{xAxisPoints:f,calPoints:e,eachSpacing:p}}function drawLineDataPoints(t,s,h,c){var d=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;var x=assign({},{type:"straight",width:2},s.extra.line);x.width*=s.pix;let e=s.chartData.xAxisData,f=e.xAxisPoints,p=e.eachSpacing;var y=[];c.save();let g=0;let u=s.width+p;if(s._scrollDistance_&&s._scrollDistance_!==0&&s.enableScroll===true){c.translate(s._scrollDistance_,0);g=-s._scrollDistance_-p*2+s.area[3];u=g+(s.xAxis.itemCount+4)*p}t.forEach(function(e,t){let a,i,r;a=[].concat(s.chartData.yAxisData.ranges[e.index]);i=a.pop();r=a.shift();var o=e.data;var n=getDataPoints(o,i,r,f,p,s,h,d);y.push(n);var l=splitPoints(n,e);if(e.lineType=="dash"){let t=e.dashLength?e.dashLength:8;t*=s.pix;c.setLineDash([t,t])}c.beginPath();c.setStrokeStyle(e.color);c.setLineWidth(x.width);l.forEach(function(i,t){if(i.length===1){c.moveTo(i[0].x,i[0].y);c.arc(i[0].x,i[0].y,1,0,2*Math.PI)}else{c.moveTo(i[0].x,i[0].y);let a=0;if(x.type==="curve"){for(let e=0;e<i.length;e++){let t=i[e];if(a==0&&t.x>g){c.moveTo(t.x,t.y);a=1}if(e>0&&t.x>g&&t.x<u){var r=createCurveControlPoints(i,e-1);c.bezierCurveTo(r.ctrA.x,r.ctrA.y,r.ctrB.x,r.ctrB.y,t.x,t.y)}}}if(x.type==="straight"){for(let e=0;e<i.length;e++){let t=i[e];if(a==0&&t.x>g){c.moveTo(t.x,t.y);a=1}if(e>0&&t.x>g&&t.x<u){c.lineTo(t.x,t.y)}}}if(x.type==="step"){for(let e=0;e<i.length;e++){let t=i[e];if(a==0&&t.x>g){c.moveTo(t.x,t.y);a=1}if(e>0&&t.x>g&&t.x<u){c.lineTo(t.x,i[e-1].y);c.lineTo(t.x,t.y)}}}c.moveTo(i[0].x,i[0].y)}});c.stroke();c.setLineDash([]);if(s.dataPointShape!==false){drawPointShape(n,e.color,e.pointShape,c,s)}});if(s.dataLabel!==false&&d===1){t.forEach(function(t,e){let a,i,r;a=[].concat(s.chartData.yAxisData.ranges[t.index]);i=a.pop();r=a.shift();var o=t.data;var n=getDataPoints(o,i,r,f,p,s,h,d);drawPointText(n,t,h,c,s)})}c.restore();return{xAxisPoints:f,calPoints:y,eachSpacing:p}}function drawMixDataPoints(t,v,m,T){let D=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;let e=v.chartData.xAxisData,b=e.xAxisPoints,P=e.eachSpacing;let w=assign({},{width:P/2,barBorderCircle:false,barBorderRadius:[],seriesGap:2,linearType:"none",linearOpacity:1,customColor:[],colorStop:0},v.extra.mix.column);let S=assign({},{opacity:.2,gradient:false},v.extra.mix.area);let M=v.height-v.area[2];let L=[];var _=0;var F=0;t.forEach(function(t,e){if(t.type=="column"){F+=1}});T.save();let k=-2;let R=b.length+2;let A=0;let C=v.width+P;if(v._scrollDistance_&&v._scrollDistance_!==0&&v.enableScroll===true){T.translate(v._scrollDistance_,0);k=Math.floor(-v._scrollDistance_/P)-2;R=k+v.xAxis.itemCount+4;A=-v._scrollDistance_-P*2+v.area[3];C=A+(v.xAxis.itemCount+4)*P}w.customColor=fillCustomColor(w.linearType,w.customColor,t,m);t.forEach(function(n,t){let o,x,f;o=[].concat(v.chartData.yAxisData.ranges[n.index]);x=o.pop();f=o.shift();var p=n.data;var a=getDataPoints(p,x,f,b,P,v,m,D);L.push(a);if(n.type=="column"){a=fixColumeData(a,P,F,_,m,v);for(let t=0;t<a.length;t++){let o=a[t];if(o!==null&&t>k&&t<R){var l=o.x-o.width/2;var s=v.height-o.y-v.area[2];T.beginPath();var e=o.color||n.color;var g=o.color||n.color;if(w.linearType!=="none"){var i=T.createLinearGradient(l,o.y,l,v.height-v.area[2]);if(w.linearType=="opacity"){i.addColorStop(0,hexToRgb(e,w.linearOpacity));i.addColorStop(1,hexToRgb(e,1))}else{i.addColorStop(0,hexToRgb(w.customColor[n.linearIndex],w.linearOpacity));i.addColorStop(w.colorStop,hexToRgb(w.customColor[n.linearIndex],w.linearOpacity));i.addColorStop(1,hexToRgb(e,1))}e=i}if(w.barBorderRadius&&w.barBorderRadius.length===4||w.barBorderCircle){const h=l;const c=o.y;const d=o.width;const s=v.height-v.area[2]-o.y;if(w.barBorderCircle){w.barBorderRadius=[d/2,d/2,0,0]}let[t,e,a,i]=w.barBorderRadius;let r=Math.min(d/2,s/2);t=t>r?r:t;e=e>r?r:e;a=a>r?r:a;i=i>r?r:i;t=t<0?0:t;e=e<0?0:e;a=a<0?0:a;i=i<0?0:i;T.arc(h+t,c+t,t,-Math.PI,-Math.PI/2);T.arc(h+d-e,c+e,e,-Math.PI/2,0);T.arc(h+d-a,c+s-a,a,0,Math.PI/2);T.arc(h+i,c+s-i,i,Math.PI/2,Math.PI)}else{T.moveTo(l,o.y);T.lineTo(l+o.width,o.y);T.lineTo(l+o.width,v.height-v.area[2]);T.lineTo(l,v.height-v.area[2]);T.lineTo(l,o.y);T.setLineWidth(1);T.setStrokeStyle(g)}T.setFillStyle(e);T.closePath();T.fill()}}_+=1}if(n.type=="area"){let e=splitPoints(a,n);for(let t=0;t<e.length;t++){let i=e[t];T.beginPath();T.setStrokeStyle(n.color);T.setStrokeStyle(hexToRgb(n.color,S.opacity));if(S.gradient){let t=T.createLinearGradient(0,v.area[0],0,v.height-v.area[2]);t.addColorStop("0",hexToRgb(n.color,S.opacity));t.addColorStop("1.0",hexToRgb("#FFFFFF",.1));T.setFillStyle(t)}else{T.setFillStyle(hexToRgb(n.color,S.opacity))}T.setLineWidth(2*v.pix);if(i.length>1){var r=i[0];let t=i[i.length-1];T.moveTo(r.x,r.y);let a=0;if(n.style==="curve"){for(let e=0;e<i.length;e++){let t=i[e];if(a==0&&t.x>A){T.moveTo(t.x,t.y);a=1}if(e>0&&t.x>A&&t.x<C){var u=createCurveControlPoints(i,e-1);T.bezierCurveTo(u.ctrA.x,u.ctrA.y,u.ctrB.x,u.ctrB.y,t.x,t.y)}}}else{for(let e=0;e<i.length;e++){let t=i[e];if(a==0&&t.x>A){T.moveTo(t.x,t.y);a=1}if(e>0&&t.x>A&&t.x<C){T.lineTo(t.x,t.y)}}}T.lineTo(t.x,M);T.lineTo(r.x,M);T.lineTo(r.x,r.y)}else{let t=i[0];T.moveTo(t.x-P/2,t.y);T.lineTo(t.x+P/2,t.y);T.lineTo(t.x+P/2,M);T.lineTo(t.x-P/2,M);T.moveTo(t.x-P/2,t.y)}T.closePath();T.fill()}}if(n.type=="line"){var y=splitPoints(a,n);y.forEach(function(i,t){if(n.lineType=="dash"){let t=n.dashLength?n.dashLength:8;t*=v.pix;T.setLineDash([t,t])}T.beginPath();T.setStrokeStyle(n.color);T.setLineWidth(2*v.pix);if(i.length===1){T.moveTo(i[0].x,i[0].y);T.arc(i[0].x,i[0].y,1,0,2*Math.PI)}else{T.moveTo(i[0].x,i[0].y);let a=0;if(n.style=="curve"){for(let e=0;e<i.length;e++){let t=i[e];if(a==0&&t.x>A){T.moveTo(t.x,t.y);a=1}if(e>0&&t.x>A&&t.x<C){var r=createCurveControlPoints(i,e-1);T.bezierCurveTo(r.ctrA.x,r.ctrA.y,r.ctrB.x,r.ctrB.y,t.x,t.y)}}}else{for(let e=0;e<i.length;e++){let t=i[e];if(a==0&&t.x>A){T.moveTo(t.x,t.y);a=1}if(e>0&&t.x>A&&t.x<C){T.lineTo(t.x,t.y)}}}T.moveTo(i[0].x,i[0].y)}T.stroke();T.setLineDash([])})}if(n.type=="point"){n.addPoint=true}if(n.addPoint==true&&n.type!=="column"){drawPointShape(a,n.color,n.pointShape,T,v)}});if(v.dataLabel!==false&&D===1){var _=0;t.forEach(function(t,e){let a,i,r;a=[].concat(v.chartData.yAxisData.ranges[t.index]);i=a.pop();r=a.shift();var o=t.data;var n=getDataPoints(o,i,r,b,P,v,m,D);if(t.type!=="column"){drawPointText(n,t,m,T,v)}else{n=fixColumeData(n,P,F,_,m,v);drawPointText(n,t,m,T,v);_+=1}})}T.restore();return{xAxisPoints:b,calPoints:L,eachSpacing:P}}function drawToolTipBridge(t,e,a,i,r,o){var n=t.extra.tooltip||{};if(n.horizentalLine&&t.tooltip&&i===1&&(t.type=="line"||t.type=="area"||t.type=="column"||t.type=="mount"||t.type=="candle"||t.type=="mix")){drawToolTipHorizentalLine(t,e,a,r,o)}a.save();if(t._scrollDistance_&&t._scrollDistance_!==0&&t.enableScroll===true){a.translate(t._scrollDistance_,0)}if(t.tooltip&&t.tooltip.textList&&t.tooltip.textList.length&&i===1){drawToolTip(t.tooltip.textList,t.tooltip.offset,t,e,a,r,o)}a.restore()}function drawXAxis(r,l,s,h){let t=l.chartData.xAxisData,c=t.xAxisPoints,e=t.startX,a=t.endX,d=t.eachSpacing;var p="center";if(l.type=="bar"||l.type=="line"||l.type=="area"||l.type=="scatter"||l.type=="bubble"){p=l.xAxis.boundaryGap}var x=l.height-l.area[2];var i=l.area[0];if(l.enableScroll&&l.xAxis.scrollShow){var o=l.height-l.area[2]+s.xAxisHeight;var n=a-e;var g=d*(c.length-1);if(l.type=="mount"&&l.extra&&l.extra.mount&&l.extra.mount.widthRatio&&l.extra.mount.widthRatio>1){if(l.extra.mount.widthRatio>2)l.extra.mount.widthRatio=2;g+=(l.extra.mount.widthRatio-1)*d}var u=n*n/g;var y=0;if(l._scrollDistance_){y=-l._scrollDistance_*n/g}h.beginPath();h.setLineCap("round");h.setLineWidth(6*l.pix);h.setStrokeStyle(l.xAxis.scrollBackgroundColor||"#EFEBEF");h.moveTo(e,o);h.lineTo(a,o);h.stroke();h.closePath();h.beginPath();h.setLineCap("round");h.setLineWidth(6*l.pix);h.setStrokeStyle(l.xAxis.scrollColor||"#A6A6A6");h.moveTo(e+y,o);h.lineTo(e+y+u,o);h.stroke();h.closePath();h.setLineCap("butt")}h.save();if(l._scrollDistance_&&l._scrollDistance_!==0){h.translate(l._scrollDistance_,0)}if(l.xAxis.calibration===true){h.setStrokeStyle(l.xAxis.gridColor||"#cccccc");h.setLineCap("butt");h.setLineWidth(1*l.pix);c.forEach(function(t,e){if(e>0){h.beginPath();h.moveTo(t-d/2,x);h.lineTo(t-d/2,x+3*l.pix);h.closePath();h.stroke()}})}if(l.xAxis.disableGrid!==true){h.setStrokeStyle(l.xAxis.gridColor||"#cccccc");h.setLineCap("butt");h.setLineWidth(1*l.pix);if(l.xAxis.gridType=="dash"){h.setLineDash([l.xAxis.dashLength*l.pix,l.xAxis.dashLength*l.pix])}l.xAxis.gridEval=l.xAxis.gridEval||1;c.forEach(function(t,e){if(e%l.xAxis.gridEval==0){h.beginPath();h.moveTo(t,x);h.lineTo(t,i);h.stroke()}});h.setLineDash([])}if(l.xAxis.disabled!==true){let t=r.length;if(l.xAxis.labelCount){if(l.xAxis.itemCount){t=Math.ceil(r.length/l.xAxis.itemCount*l.xAxis.labelCount)}else{t=l.xAxis.labelCount}t-=1}let e=Math.ceil(r.length/t);let a=[];let i=r.length;for(let t=0;t<i;t++){if(t%e!==0){a.push("")}else{a.push(r[t])}}a[i-1]=r[i-1];var f=l.xAxis.fontSize*l.pix||s.fontSize;if(s._xAxisTextAngle_===0){a.forEach(function(t,e){var a=l.xAxis.formatter?l.xAxis.formatter(t,e,l):t;var i=-measureText(String(a),f,h)/2;if(p=="center"){i+=d/2}var r=0;if(l.xAxis.scrollShow){r=6*l.pix}h.beginPath();h.setFontSize(f);h.setFillStyle(l.xAxis.fontColor||l.fontColor);h.fillText(String(a),c[e]+i,x+f+(s.xAxisHeight-r-f)/2);h.closePath();h.stroke()})}else{a.forEach(function(t,e){var a=l.xAxis.formatter?l.xAxis.formatter(t):t;h.save();h.beginPath();h.setFontSize(f);h.setFillStyle(l.xAxis.fontColor||l.fontColor);var i=measureText(String(a),f,h);var r=c[e];if(p=="center"){r=c[e]+d/2}var o=0;if(l.xAxis.scrollShow){o=6*l.pix}var n=x+6*l.pix+f-f*Math.abs(Math.sin(s._xAxisTextAngle_));if(l.xAxis.rotateAngle<0){r-=f/2;i=0}else{r+=f/2;i=-i}h.translate(r,n);h.rotate(-1*s._xAxisTextAngle_);h.fillText(String(a),i,0);h.closePath();h.stroke();h.restore()})}}h.restore();if(l.xAxis.axisLine){h.beginPath();h.setStrokeStyle(l.xAxis.axisLineColor);h.setLineWidth(1*l.pix);h.moveTo(e,l.height-l.area[2]);h.lineTo(a,l.height-l.area[2]);h.stroke()}}function drawYAxisGrid(c,e,d,a){if(e.yAxis.disableGrid===true){return}let t=e.height-e.area[0]-e.area[2];let i=t/e.yAxis.splitNumber;let r=e.area[3];let o=e.chartData.xAxisData.xAxisPoints,n=e.chartData.xAxisData.eachSpacing;let l=n*(o.length-1);if(e.type=="mount"&&e.extra&&e.extra.mount&&e.extra.mount.widthRatio&&e.extra.mount.widthRatio>1){if(e.extra.mount.widthRatio>2)e.extra.mount.widthRatio=2;l+=(e.extra.mount.widthRatio-1)*n}let x=r+l;let s=[];let h=1;if(e.xAxis.axisLine===false){h=0}for(let t=h;t<e.yAxis.splitNumber+1;t++){s.push(e.height-e.area[2]-i*t)}a.save();if(e._scrollDistance_&&e._scrollDistance_!==0){a.translate(e._scrollDistance_,0)}if(e.yAxis.gridType=="dash"){a.setLineDash([e.yAxis.dashLength*e.pix,e.yAxis.dashLength*e.pix])}a.setStrokeStyle(e.yAxis.gridColor);a.setLineWidth(1*e.pix);s.forEach(function(t,e){a.beginPath();a.moveTo(r,t);a.lineTo(x,t);a.stroke()});a.setLineDash([]);a.restore()}function drawYAxis(e,h,a,c){if(h.yAxis.disabled===true){return}var i=h.height-h.area[0]-h.area[2];var r=i/h.yAxis.splitNumber;var o=h.area[3];var n=h.width-h.area[1];var l=h.height-h.area[2];var t=l+a.xAxisHeight;if(h.xAxis.scrollShow){t-=3*h.pix}if(h.xAxis.rotateLabel){t=h.height-h.area[2]+h.fontSize*h.pix/2}c.beginPath();c.setFillStyle(h.background);if(h.enableScroll==true&&h.xAxis.scrollPosition&&h.xAxis.scrollPosition!=="left"){c.fillRect(0,0,o,t)}if(h.enableScroll==true&&h.xAxis.scrollPosition&&h.xAxis.scrollPosition!=="right"){c.fillRect(n,0,h.width,t)}c.closePath();c.stroke();let d=h.area[3];let x=h.width-h.area[1];let f=h.area[3]+(h.width-h.area[1]-h.area[3])/2;if(h.yAxis.data){for(let e=0;e<h.yAxis.data.length;e++){let s=h.yAxis.data[e];var p=[];if(s.type==="categories"){for(let t=0;t<=s.categories.length;t++){p.push(h.area[0]+i/s.categories.length/2+i/s.categories.length*t)}}else{for(let t=0;t<=h.yAxis.splitNumber;t++){p.push(h.area[0]+r*t)}}if(s.disabled!==true){let t=h.chartData.yAxisData.rangesFormat[e];let o=s.fontSize?s.fontSize*h.pix:a.fontSize;let n=h.chartData.yAxisData.yAxisWidth[e];let l=s.textAlign||"right";t.forEach(function(t,e){var a=p[e];c.beginPath();c.setFontSize(o);c.setLineWidth(1*h.pix);c.setStrokeStyle(s.axisLineColor||"#cccccc");c.setFillStyle(s.fontColor||h.fontColor);let i=0;let r=4*h.pix;if(n.position=="left"){if(s.calibration==true){c.moveTo(d,a);c.lineTo(d-3*h.pix,a);r+=3*h.pix}switch(l){case"left":c.setTextAlign("left");i=d-n.width;break;case"right":c.setTextAlign("right");i=d-r;break;default:c.setTextAlign("center");i=d-n.width/2}c.fillText(String(t),i,a+o/2-3*h.pix)}else if(n.position=="right"){if(s.calibration==true){c.moveTo(x,a);c.lineTo(x+3*h.pix,a);r+=3*h.pix}switch(l){case"left":c.setTextAlign("left");i=x+r;break;case"right":c.setTextAlign("right");i=x+n.width;break;default:c.setTextAlign("center");i=x+n.width/2}c.fillText(String(t),i,a+o/2-3*h.pix)}else if(n.position=="center"){if(s.calibration==true){c.moveTo(f,a);c.lineTo(f-3*h.pix,a);r+=3*h.pix}switch(l){case"left":c.setTextAlign("left");i=f-n.width;break;case"right":c.setTextAlign("right");i=f-r;break;default:c.setTextAlign("center");i=f-n.width/2}c.fillText(String(t),i,a+o/2-3*h.pix)}c.closePath();c.stroke();c.setTextAlign("left")});if(s.axisLine!==false){c.beginPath();c.setStrokeStyle(s.axisLineColor||"#cccccc");c.setLineWidth(1*h.pix);if(n.position=="left"){c.moveTo(d,h.height-h.area[2]);c.lineTo(d,h.area[0])}else if(n.position=="right"){c.moveTo(x,h.height-h.area[2]);c.lineTo(x,h.area[0])}else if(n.position=="center"){c.moveTo(f,h.height-h.area[2]);c.lineTo(f,h.area[0])}c.stroke()}if(h.yAxis.showTitle){let t=s.titleFontSize*h.pix||a.fontSize;let e=s.title;c.beginPath();c.setFontSize(t);c.setFillStyle(s.titleFontColor||h.fontColor);if(n.position=="left"){c.fillText(e,d-measureText(e,t,c)/2+(s.titleOffsetX||0),h.area[0]-(10-(s.titleOffsetY||0))*h.pix)}else if(n.position=="right"){c.fillText(e,x-measureText(e,t,c)/2+(s.titleOffsetX||0),h.area[0]-(10-(s.titleOffsetY||0))*h.pix)}else if(n.position=="center"){c.fillText(e,f-measureText(e,t,c)/2+(s.titleOffsetX||0),h.area[0]-(10-(s.titleOffsetY||0))*h.pix)}c.closePath();c.stroke()}if(n.position=="left"){d-=n.width+h.yAxis.padding*h.pix}else{x+=n.width+h.yAxis.padding*h.pix}}}}}function drawLegend(t,l,y,s,e){if(l.legend.show===false){return}let h=e.legendData;let a=h.points;let c=h.area;let d=l.legend.padding*l.pix;let x=l.legend.fontSize*l.pix;let f=15*l.pix;let p=5*l.pix;let g=l.legend.itemGap*l.pix;let u=Math.max(l.legend.lineHeight*l.pix,x);s.beginPath();s.setLineWidth(l.legend.borderWidth*l.pix);s.setStrokeStyle(l.legend.borderColor);s.setFillStyle(l.legend.backgroundColor);s.moveTo(c.start.x,c.start.y);s.rect(c.start.x,c.start.y,c.width,c.height);s.closePath();s.fill();s.stroke();a.forEach(function(i,t){let e=0;let a=0;e=h.widthArr[t];a=h.heightArr[t];let r=0;let o=0;if(l.legend.position=="top"||l.legend.position=="bottom"){switch(l.legend.float){case"left":r=c.start.x+d;break;case"right":r=c.start.x+c.width-e;break;default:r=c.start.x+(c.width-e)/2}o=c.start.y+d+t*u}else{if(t==0){e=0}else{e=h.widthArr[t-1]}r=c.start.x+d+e;o=c.start.y+d+(c.height-a)/2}s.setFontSize(y.fontSize);for(let a=0;a<i.length;a++){let t=i[a];t.area=[0,0,0,0];t.area[0]=r;t.area[1]=o;t.area[3]=o+u;s.beginPath();s.setLineWidth(1*l.pix);s.setStrokeStyle(t.show?t.color:l.legend.hiddenColor);s.setFillStyle(t.show?t.color:l.legend.hiddenColor);switch(t.legendShape){case"line":s.moveTo(r,o+.5*u-2*l.pix);s.fillRect(r,o+.5*u-2*l.pix,15*l.pix,4*l.pix);break;case"triangle":s.moveTo(r+7.5*l.pix,o+.5*u-5*l.pix);s.lineTo(r+2.5*l.pix,o+.5*u+5*l.pix);s.lineTo(r+12.5*l.pix,o+.5*u+5*l.pix);s.lineTo(r+7.5*l.pix,o+.5*u-5*l.pix);break;case"diamond":s.moveTo(r+7.5*l.pix,o+.5*u-5*l.pix);s.lineTo(r+2.5*l.pix,o+.5*u);s.lineTo(r+7.5*l.pix,o+.5*u+5*l.pix);s.lineTo(r+12.5*l.pix,o+.5*u);s.lineTo(r+7.5*l.pix,o+.5*u-5*l.pix);break;case"circle":s.moveTo(r+7.5*l.pix,o+.5*u);s.arc(r+7.5*l.pix,o+.5*u,5*l.pix,0,2*Math.PI);break;case"rect":s.moveTo(r,o+.5*u-5*l.pix);s.fillRect(r,o+.5*u-5*l.pix,15*l.pix,10*l.pix);break;case"square":s.moveTo(r+5*l.pix,o+.5*u-5*l.pix);s.fillRect(r+5*l.pix,o+.5*u-5*l.pix,10*l.pix,10*l.pix);break;case"none":break;default:s.moveTo(r,o+.5*u-5*l.pix);s.fillRect(r,o+.5*u-5*l.pix,15*l.pix,10*l.pix)}s.closePath();s.fill();s.stroke();r+=f+p;let e=.5*u+.5*x-2;const n=t.legendText?t.legendText:t.name;s.beginPath();s.setFontSize(x);s.setFillStyle(t.show?l.legend.fontColor:l.legend.hiddenColor);s.fillText(n,r,o+e);s.closePath();s.stroke();if(l.legend.position=="top"||l.legend.position=="bottom"){r+=measureText(n,x,s)+g;t.area[2]=r}else{t.area[2]=r+measureText(n,x,s)+g;r-=f+p;o+=u}}})}function drawPieDataPoints(t,r,e,o){var a=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;var n=assign({},{activeOpacity:.5,activeRadius:10,offsetAngle:0,labelWidth:15,ringWidth:30,customRadius:0,border:false,borderWidth:2,borderColor:"#FFFFFF",centerColor:"#FFFFFF",linearType:"none",customColor:[]},r.type=="pie"?r.extra.pie:r.extra.ring);var l={x:r.area[3]+(r.width-r.area[1]-r.area[3])/2,y:r.area[0]+(r.height-r.area[0]-r.area[2])/2};if(e.pieChartLinePadding==0){e.pieChartLinePadding=n.activeRadius*r.pix}var i=Math.min((r.width-r.area[1]-r.area[3])/2-e.pieChartLinePadding-e.pieChartTextPadding-e._pieTextMaxLength_,(r.height-r.area[0]-r.area[2])/2-e.pieChartLinePadding-e.pieChartTextPadding);i=i<10?10:i;if(n.customRadius>0){i=n.customRadius*r.pix}t=getPieDataPoints(t,i,a);var h=n.activeRadius*r.pix;n.customColor=fillCustomColor(n.linearType,n.customColor,t,e);t=t.map(function(t){t._start_+=n.offsetAngle*Math.PI/180;return t});t.forEach(function(t,e){if(r.tooltip){if(r.tooltip.index==e){o.beginPath();o.setFillStyle(hexToRgb(t.color,n.activeOpacity||.5));o.moveTo(l.x,l.y);o.arc(l.x,l.y,t._radius_+h,t._start_,t._start_+2*t._proportion_*Math.PI);o.closePath();o.fill()}}o.beginPath();o.setLineWidth(n.borderWidth*r.pix);o.lineJoin="round";o.setStrokeStyle(n.borderColor);var a=t.color;if(n.linearType=="custom"){var i;if(o.createCircularGradient){i=o.createCircularGradient(l.x,l.y,t._radius_)}else{i=o.createRadialGradient(l.x,l.y,0,l.x,l.y,t._radius_)}i.addColorStop(0,hexToRgb(n.customColor[t.linearIndex],1));i.addColorStop(1,hexToRgb(t.color,1));a=i}o.setFillStyle(a);o.moveTo(l.x,l.y);o.arc(l.x,l.y,t._radius_,t._start_,t._start_+2*t._proportion_*Math.PI);o.closePath();o.fill();if(n.border==true){o.stroke()}});if(r.type==="ring"){var s=i*.6;if(typeof n.ringWidth==="number"&&n.ringWidth>0){s=Math.max(0,i-n.ringWidth*r.pix)}o.beginPath();o.setFillStyle(n.centerColor);o.moveTo(l.x,l.y);o.arc(l.x,l.y,s,0,2*Math.PI);o.closePath();o.fill()}if(r.dataLabel!==false&&a===1){drawPieText(t,r,e,o,i,l)}if(a===1&&r.type==="ring"){drawRingTitle(r,e,o,l)}return{center:l,radius:i,series:t}}function drawRoseDataPoints(t,r,e,o){var a=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;var n=assign({},{type:"area",activeOpacity:.5,activeRadius:10,offsetAngle:0,labelWidth:15,border:false,borderWidth:2,borderColor:"#FFFFFF",linearType:"none",customColor:[]},r.extra.rose);if(e.pieChartLinePadding==0){e.pieChartLinePadding=n.activeRadius*r.pix}var l={x:r.area[3]+(r.width-r.area[1]-r.area[3])/2,y:r.area[0]+(r.height-r.area[0]-r.area[2])/2};var i=Math.min((r.width-r.area[1]-r.area[3])/2-e.pieChartLinePadding-e.pieChartTextPadding-e._pieTextMaxLength_,(r.height-r.area[0]-r.area[2])/2-e.pieChartLinePadding-e.pieChartTextPadding);i=i<10?10:i;var s=n.minRadius||i*.5;t=getRoseDataPoints(t,n.type,s,i,a);var h=n.activeRadius*r.pix;n.customColor=fillCustomColor(n.linearType,n.customColor,t,e);t=t.map(function(t){t._start_+=(n.offsetAngle||0)*Math.PI/180;return t});t.forEach(function(t,e){if(r.tooltip){if(r.tooltip.index==e){o.beginPath();o.setFillStyle(hexToRgb(t.color,n.activeOpacity||.5));o.moveTo(l.x,l.y);o.arc(l.x,l.y,h+t._radius_,t._start_,t._start_+2*t._rose_proportion_*Math.PI);o.closePath();o.fill()}}o.beginPath();o.setLineWidth(n.borderWidth*r.pix);o.lineJoin="round";o.setStrokeStyle(n.borderColor);var a=t.color;if(n.linearType=="custom"){var i;if(o.createCircularGradient){i=o.createCircularGradient(l.x,l.y,t._radius_)}else{i=o.createRadialGradient(l.x,l.y,0,l.x,l.y,t._radius_)}i.addColorStop(0,hexToRgb(n.customColor[t.linearIndex],1));i.addColorStop(1,hexToRgb(t.color,1));a=i}o.setFillStyle(a);o.moveTo(l.x,l.y);o.arc(l.x,l.y,t._radius_,t._start_,t._start_+2*t._rose_proportion_*Math.PI);o.closePath();o.fill();if(n.border==true){o.stroke()}});if(r.dataLabel!==false&&a===1){drawPieText(t,r,e,o,i,l)}return{center:l,radius:i,series:t}}function drawArcbarDataPoints(a,i,t,r){var e=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;var o=assign({},{startAngle:.75,endAngle:.25,type:"default",lineCap:"round",width:12,gap:2,linearType:"none",customColor:[]},i.extra.arcbar);a=getArcbarDataPoints(a,o,e);var n;if(o.centerX||o.centerY){n={x:o.centerX?o.centerX:i.width/2,y:o.centerY?o.centerY:i.height/2}}else{n={x:i.width/2,y:i.height/2}}var l;if(o.radius){l=o.radius}else{l=Math.min(n.x,n.y);l-=5*i.pix;l-=o.width/2}l=l<10?10:l;o.customColor=fillCustomColor(o.linearType,o.customColor,a,t);for(let e=0;e<a.length;e++){let t=a[e];r.setLineWidth(o.width*i.pix);r.setStrokeStyle(o.backgroundColor||"#E9E9E9");r.setLineCap(o.lineCap);r.beginPath();if(o.type=="default"){r.arc(n.x,n.y,l-(o.width*i.pix+o.gap*i.pix)*e,o.startAngle*Math.PI,o.endAngle*Math.PI,false)}else{r.arc(n.x,n.y,l-(o.width*i.pix+o.gap*i.pix)*e,0,2*Math.PI,false)}r.stroke();var s=t.color;if(o.linearType=="custom"){var h=r.createLinearGradient(n.x-l,n.y,n.x+l,n.y);h.addColorStop(1,hexToRgb(o.customColor[t.linearIndex],1));h.addColorStop(0,hexToRgb(t.color,1));s=h}r.setLineWidth(o.width*i.pix);r.setStrokeStyle(s);r.setLineCap(o.lineCap);r.beginPath();r.arc(n.x,n.y,l-(o.width*i.pix+o.gap*i.pix)*e,o.startAngle*Math.PI,t._proportion_*Math.PI,false);r.stroke()}drawRingTitle(i,t,r,n);return{center:n,radius:l,series:a}}function drawGaugeDataPoints(n,h,c,t,d){var x=arguments.length>5&&arguments[5]!==undefined?arguments[5]:1;var f=assign({},{type:"default",startAngle:.75,endAngle:.25,width:15,labelOffset:13,splitLine:{fixRadius:0,splitNumber:10,width:15,color:"#FFFFFF",childNumber:5,childWidth:5},pointer:{width:15,color:"auto"}},c.extra.gauge);if(f.oldAngle==undefined){f.oldAngle=f.startAngle}if(f.oldData==undefined){f.oldData=0}n=getGaugeAxisPoints(n,f.startAngle,f.endAngle);var p={x:c.width/2,y:c.height/2};var g=Math.min(p.x,p.y);g-=5*c.pix;g-=f.width/2;g=g<10?10:g;var u=g-f.width;var y=0;if(f.type=="progress"){var v=g-f.width*3;d.beginPath();let t=d.createLinearGradient(p.x,p.y-v,p.x,p.y+v);t.addColorStop("0",hexToRgb(h[0].color,.3));t.addColorStop("1.0",hexToRgb("#FFFFFF",.1));d.setFillStyle(t);d.arc(p.x,p.y,v,0,2*Math.PI,false);d.fill();d.setLineWidth(f.width);d.setStrokeStyle(hexToRgb(h[0].color,.3));d.setLineCap("round");d.beginPath();d.arc(p.x,p.y,u,f.startAngle*Math.PI,f.endAngle*Math.PI,false);d.stroke();y=f.startAngle-f.endAngle+1;let e=y/f.splitLine.splitNumber;let a=y/f.splitLine.splitNumber/f.splitLine.childNumber;let i=-g-f.width*.5-f.splitLine.fixRadius;let r=-g-f.width-f.splitLine.fixRadius+f.splitLine.width;d.save();d.translate(p.x,p.y);d.rotate((f.startAngle-1)*Math.PI);let o=f.splitLine.splitNumber*f.splitLine.childNumber+1;let n=h[0].data*x;for(let t=0;t<o;t++){d.beginPath();if(n>t/o){d.setStrokeStyle(hexToRgb(h[0].color,1))}else{d.setStrokeStyle(hexToRgb(h[0].color,.3))}d.setLineWidth(3*c.pix);d.moveTo(i,0);d.lineTo(r,0);d.stroke();d.rotate(a*Math.PI)}d.restore();h=getGaugeArcbarDataPoints(h,f,x);d.setLineWidth(f.width);d.setStrokeStyle(h[0].color);d.setLineCap("round");d.beginPath();d.arc(p.x,p.y,u,f.startAngle*Math.PI,h[0]._proportion_*Math.PI,false);d.stroke();let l=g-f.width*2.5;d.save();d.translate(p.x,p.y);d.rotate((h[0]._proportion_-1)*Math.PI);d.beginPath();d.setLineWidth(f.width/3);let s=d.createLinearGradient(0,-l*.6,0,l*.6);s.addColorStop("0",hexToRgb("#FFFFFF",0));s.addColorStop("0.5",hexToRgb(h[0].color,1));s.addColorStop("1.0",hexToRgb("#FFFFFF",0));d.setStrokeStyle(s);d.arc(0,0,l,.85*Math.PI,1.15*Math.PI,false);d.stroke();d.beginPath();d.setLineWidth(1);d.setStrokeStyle(h[0].color);d.setFillStyle(h[0].color);d.moveTo(-l-f.width/3/2,-4);d.lineTo(-l-f.width/3/2-4,0);d.lineTo(-l-f.width/3/2,4);d.lineTo(-l-f.width/3/2,-4);d.stroke();d.fill();d.restore()}else{d.setLineWidth(f.width);d.setLineCap("butt");for(let e=0;e<n.length;e++){let t=n[e];d.beginPath();d.setStrokeStyle(t.color);d.arc(p.x,p.y,g,t._startAngle_*Math.PI,t._endAngle_*Math.PI,false);d.stroke()}d.save();y=f.startAngle-f.endAngle+1;let e=y/f.splitLine.splitNumber;let a=y/f.splitLine.splitNumber/f.splitLine.childNumber;let i=-g-f.width*.5-f.splitLine.fixRadius;let r=-g-f.width*.5-f.splitLine.fixRadius+f.splitLine.width;let o=-g-f.width*.5-f.splitLine.fixRadius+f.splitLine.childWidth;d.translate(p.x,p.y);d.rotate((f.startAngle-1)*Math.PI);for(let t=0;t<f.splitLine.splitNumber+1;t++){d.beginPath();d.setStrokeStyle(f.splitLine.color);d.setLineWidth(2*c.pix);d.moveTo(i,0);d.lineTo(r,0);d.stroke();d.rotate(e*Math.PI)}d.restore();d.save();d.translate(p.x,p.y);d.rotate((f.startAngle-1)*Math.PI);for(let t=0;t<f.splitLine.splitNumber*f.splitLine.childNumber+1;t++){d.beginPath();d.setStrokeStyle(f.splitLine.color);d.setLineWidth(1*c.pix);d.moveTo(i,0);d.lineTo(o,0);d.stroke();d.rotate(a*Math.PI)}d.restore();h=getGaugeDataPoints(h,n,f,x);for(let e=0;e<h.length;e++){let t=h[e];d.save();d.translate(p.x,p.y);d.rotate((t._proportion_-1)*Math.PI);d.beginPath();d.setFillStyle(t.color);d.moveTo(f.pointer.width,0);d.lineTo(0,-f.pointer.width/2);d.lineTo(-u,0);d.lineTo(0,f.pointer.width/2);d.lineTo(f.pointer.width,0);d.closePath();d.fill();d.beginPath();d.setFillStyle("#FFFFFF");d.arc(0,0,f.pointer.width/6,0,2*Math.PI,false);d.fill();d.restore()}if(c.dataLabel!==false){drawGaugeLabel(f,g,p,c,t,d)}}drawRingTitle(c,t,d,p);if(x===1&&c.type==="gauge"){c.extra.gauge.oldAngle=h[0]._proportion_;c.extra.gauge.oldData=h[0].data}return{center:p,radius:g,innerRadius:u,categories:n,totalAngle:y}}function drawRadarDataPoints(o,n,i,l){var t=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;var s=assign({},{gridColor:"#cccccc",gridType:"radar",gridEval:1,axisLabel:false,axisLabelTofix:0,labelColor:"#666666",labelPointShow:false,labelPointRadius:3,labelPointColor:"#cccccc",opacity:.2,gridCount:3,border:false,borderWidth:2,linearType:"none",customColor:[]},n.extra.radar);var a=getRadarCoordinateSeries(n.categories.length);var h={x:n.area[3]+(n.width-n.area[1]-n.area[3])/2,y:n.area[0]+(n.height-n.area[0]-n.area[2])/2};var r=(n.width-n.area[1]-n.area[3])/2;var d=(n.height-n.area[0]-n.area[2])/2;var c=Math.min(r-(getMaxTextListLength(n.categories,i.fontSize,l)+i.radarLabelTextMargin),d-i.radarLabelTextMargin);c-=i.radarLabelTextMargin*n.pix;c=c<10?10:c;l.beginPath();l.setLineWidth(1*n.pix);l.setStrokeStyle(s.gridColor);a.forEach(function(t,e){var a=convertCoordinateOrigin(c*Math.cos(t),c*Math.sin(t),h);l.moveTo(h.x,h.y);if(e%s.gridEval==0){l.lineTo(a.x,a.y)}});l.stroke();l.closePath();var x=function t(i){var r={};l.beginPath();l.setLineWidth(1*n.pix);l.setStrokeStyle(s.gridColor);if(s.gridType=="radar"){a.forEach(function(t,e){var a=convertCoordinateOrigin(c/s.gridCount*i*Math.cos(t),c/s.gridCount*i*Math.sin(t),h);if(e===0){r=a;l.moveTo(a.x,a.y)}else{l.lineTo(a.x,a.y)}});l.lineTo(r.x,r.y)}else{var e=convertCoordinateOrigin(c/s.gridCount*i*Math.cos(1.5),c/s.gridCount*i*Math.sin(1.5),h);l.arc(h.x,h.y,h.y-e.y,0,2*Math.PI,false)}l.stroke();l.closePath()};for(var e=1;e<=s.gridCount;e++){x(e)}s.customColor=fillCustomColor(s.linearType,s.customColor,o,i);var f=getRadarDataPoints(a,h,c,o,n,t);f.forEach(function(t,e){l.beginPath();l.setLineWidth(s.borderWidth*n.pix);l.setStrokeStyle(t.color);var a=hexToRgb(t.color,s.opacity);if(s.linearType=="custom"){var i;if(l.createCircularGradient){i=l.createCircularGradient(h.x,h.y,c)}else{i=l.createRadialGradient(h.x,h.y,0,h.x,h.y,c)}i.addColorStop(0,hexToRgb(s.customColor[o[e].linearIndex],s.opacity));i.addColorStop(1,hexToRgb(t.color,s.opacity));a=i}l.setFillStyle(a);t.data.forEach(function(t,e){if(e===0){l.moveTo(t.position.x,t.position.y)}else{l.lineTo(t.position.x,t.position.y)}});l.closePath();l.fill();if(s.border===true){l.stroke()}l.closePath();if(n.dataPointShape!==false){var r=t.data.map(function(t){return t.position});drawPointShape(r,t.color,t.pointShape,l,n)}});if(s.axisLabel===true){const p=Math.max(s.max,Math.max.apply(null,dataCombine(o)));const g=c/s.gridCount;const u=n.fontSize*n.pix;l.setFontSize(u);l.setFillStyle(n.fontColor);l.setTextAlign("left");for(var e=0;e<s.gridCount+1;e++){let t=e*p/s.gridCount;t=t.toFixed(s.axisLabelTofix);l.fillText(String(t),h.x+3*n.pix,h.y-e*g+u/2)}}drawRadarLabel(a,c,h,n,i,l);if(n.dataLabel!==false&&t===1){f.forEach(function(t,e){l.beginPath();var a=t.textSize*n.pix||i.fontSize;l.setFontSize(a);l.setFillStyle(t.textColor||n.fontColor);t.data.forEach(function(t,e){if(Math.abs(t.position.x-h.x)<2){if(t.position.y<h.y){l.setTextAlign("center");l.fillText(t.value,t.position.x,t.position.y-4)}else{l.setTextAlign("center");l.fillText(t.value,t.position.x,t.position.y+a+2)}}else{if(t.position.x<h.x){l.setTextAlign("right");l.fillText(t.value,t.position.x-4,t.position.y+a/2-2)}else{l.setTextAlign("left");l.fillText(t.value,t.position.x+4,t.position.y+a/2-2)}}});l.closePath();l.stroke()});l.setTextAlign("left")}return{center:h,radius:c,angleList:a}}function lonlat2mercator(t,e){var a=Array(2);var i=t*20037508.34/180;var r=Math.log(Math.tan((90+e)*Math.PI/360))/(Math.PI/180);r=r*20037508.34/180;a[0]=i;a[1]=r;return a}function mercator2lonlat(t,e){var a=Array(2);var i=t/20037508.34*180;var r=e/20037508.34*180;r=180/Math.PI*(2*Math.atan(Math.exp(r*Math.PI/180))-Math.PI/2);a[0]=i;a[1]=r;return a}function getBoundingBox(t){var e={},a;e.xMin=180;e.xMax=0;e.yMin=90;e.yMax=0;for(var i=0;i<t.length;i++){var r=t[i].geometry.coordinates;for(var o=0;o<r.length;o++){a=r[o];if(a.length==1){a=a[0]}for(var n=0;n<a.length;n++){var l=a[n][0];var s=a[n][1];var h={x:l,y:s};e.xMin=e.xMin<h.x?e.xMin:h.x;e.xMax=e.xMax>h.x?e.xMax:h.x;e.yMin=e.yMin<h.y?e.yMin:h.y;e.yMax=e.yMax>h.y?e.yMax:h.y}}}return e}function coordinateToPoint(t,e,a,i,r,o){return{x:(e-a.xMin)*i+r,y:(a.yMax-t)*i+o}}function pointToCoordinate(t,e,a,i,r,o){return{x:(e-r)/i+a.xMin,y:a.yMax-(t-o)/i}}function isRayIntersectsSegment(t,e,a){if(e[1]==a[1]){return false}if(e[1]>t[1]&&a[1]>t[1]){return false}if(e[1]<t[1]&&a[1]<t[1]){return false}if(e[1]==t[1]&&a[1]>t[1]){return false}if(a[1]==t[1]&&e[1]>t[1]){return false}if(e[0]<t[0]&&a[1]<t[1]){return false}let i=a[0]-(a[0]-e[0])*(a[1]-t[1])/(a[1]-e[1]);if(i<t[0]){return false}else{return true}}function isPoiWithinPoly(r,e,o){let n=0;for(let t=0;t<e.length;t++){let i=e[t][0];if(e.length==1){i=e[t][0]}for(let a=0;a<i.length-1;a++){let t=i[a];let e=i[a+1];if(o){t=lonlat2mercator(i[a][0],i[a][1]);e=lonlat2mercator(i[a+1][0],i[a+1][1])}if(isRayIntersectsSegment(r,t,e)){n+=1}}}if(n%2==1){return true}else{return false}}function drawMapDataPoints(c,a,d,i){var r=assign({},{border:true,mercator:false,borderWidth:1,borderColor:"#666666",fillOpacity:.6,activeBorderColor:"#f04864",activeFillColor:"#facc14",activeFillOpacity:1},a.extra.map);var t,o;var n=c;var l=getBoundingBox(n);if(r.mercator){var x=lonlat2mercator(l.xMax,l.yMax);var f=lonlat2mercator(l.xMin,l.yMin);l.xMax=x[0];l.yMax=x[1];l.xMin=f[0];l.yMin=f[1]}var p=a.width/Math.abs(l.xMax-l.xMin);var g=a.height/Math.abs(l.yMax-l.yMin);var s=p<g?p:g;var u=a.width/2-Math.abs(l.xMax-l.xMin)/2*s;var y=a.height/2-Math.abs(l.yMax-l.yMin)/2*s;for(var h=0;h<n.length;h++){i.beginPath();i.setLineWidth(r.borderWidth*a.pix);i.setStrokeStyle(r.borderColor);i.setFillStyle(hexToRgb(c[h].color,r.fillOpacity));if(a.tooltip){if(a.tooltip.index==h){i.setStrokeStyle(r.activeBorderColor);i.setFillStyle(hexToRgb(r.activeFillColor,r.activeFillOpacity))}}var v=n[h].geometry.coordinates;for(var m=0;m<v.length;m++){t=v[m];if(t.length==1){t=t[0]}for(var e=0;e<t.length;e++){var T=Array(2);if(r.mercator){T=lonlat2mercator(t[e][0],t[e][1])}else{T=t[e]}o=coordinateToPoint(T[1],T[0],l,s,u,y);if(e===0){i.beginPath();i.moveTo(o.x,o.y)}else{i.lineTo(o.x,o.y)}}i.fill();if(r.border==true){i.stroke()}}}if(a.dataLabel==true){for(var h=0;h<n.length;h++){var b=n[h].properties.centroid;if(b){if(r.mercator){b=lonlat2mercator(n[h].properties.centroid[0],n[h].properties.centroid[1])}o=coordinateToPoint(b[1],b[0],l,s,u,y);let t=n[h].textSize*a.pix||d.fontSize;let e=n[h].properties.name;i.beginPath();i.setFontSize(t);i.setFillStyle(n[h].textColor||a.fontColor);i.fillText(e,o.x-measureText(e,t,i)/2,o.y+t/2);i.closePath();i.stroke()}}}a.chartData.mapData={bounds:l,scale:s,xoffset:u,yoffset:y,mercator:r.mercator};drawToolTipBridge(a,d,i,1);i.draw()}function normalInt(t,e,a){a=a==0?1:a;var i=[];for(var r=0;r<a;r++){i[r]=Math.random()}return Math.floor(i.reduce(function(t,e){return t+e})/a*(e-t))+t}function collisionNew(e,a,i,r){var o=false;for(let t=0;t<a.length;t++){if(a[t].area){if(e[3]<a[t].area[1]||e[0]>a[t].area[2]||e[1]>a[t].area[3]||e[2]<a[t].area[0]){if(e[0]<0||e[1]<0||e[2]>i||e[3]>r){o=true;break}else{o=false}}else{o=true;break}}}return o}function getWordCloudPoint(c,t,d){let x=c.series;switch(t){case"normal":for(let l=0;l<x.length;l++){let t=x[l].name;let e=x[l].textSize*c.pix;let a=measureText(t,e,d);let i,r;let o;let n=0;while(true){n++;i=normalInt(-c.width/2,c.width/2,5)-a/2;r=normalInt(-c.height/2,c.height/2,5)+e/2;o=[i-5+c.width/2,r-5-e+c.height/2,i+a+5+c.width/2,r+5+c.height/2];let t=collisionNew(o,x,c.width,c.height);if(!t)break;if(n==1e3){o=[-100,-100,-100,-100];break}}x[l].area=o}break;case"vertical":function f(){if(Math.random()>.7){return true}else{return false}};for(let h=0;h<x.length;h++){let t=x[h].name;let e=x[h].textSize*c.pix;let a=measureText(t,e,d);let i=f();let r,o,n,l;let s=0;while(true){s++;let t;if(i){r=normalInt(-c.width/2,c.width/2,5)-a/2;o=normalInt(-c.height/2,c.height/2,5)+e/2;n=[o-5-a+c.width/2,-r-5+c.height/2,o+5+c.width/2,-r+e+5+c.height/2];l=[c.width-(c.width/2-c.height/2)-(-r+e+5+c.height/2)-5,c.height/2-c.width/2+(o-5-a+c.width/2)-5,c.width-(c.width/2-c.height/2)-(-r+e+5+c.height/2)+e,c.height/2-c.width/2+(o-5-a+c.width/2)+a+5];t=collisionNew(l,x,c.height,c.width)}else{r=normalInt(-c.width/2,c.width/2,5)-a/2;o=normalInt(-c.height/2,c.height/2,5)+e/2;n=[r-5+c.width/2,o-5-e+c.height/2,r+a+5+c.width/2,o+5+c.height/2];t=collisionNew(n,x,c.width,c.height)}if(!t)break;if(s==1e3){n=[-1e3,-1e3,-1e3,-1e3];break}}if(i){x[h].area=l;x[h].areav=n}else{x[h].area=n}x[h].rotate=i};break}return x}function drawWordCloudDataPoints(t,r,e,o){let n=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;let a=assign({},{type:"normal",autoColors:true},r.extra.word);if(!r.chartData.wordCloudData){r.chartData.wordCloudData=getWordCloudPoint(r,a.type,o)}o.beginPath();o.setFillStyle(r.background);o.rect(0,0,r.width,r.height);o.fill();o.save();let l=r.chartData.wordCloudData;o.translate(r.width/2,r.height/2);for(let i=0;i<l.length;i++){o.save();if(l[i].rotate){o.rotate(90*Math.PI/180)}let t=l[i].name;let e=l[i].textSize*r.pix;let a=measureText(t,e,o);o.beginPath();o.setStrokeStyle(l[i].color);o.setFillStyle(l[i].color);o.setFontSize(e);if(l[i].rotate){if(l[i].areav[0]>0){if(r.tooltip){if(r.tooltip.index==i){o.strokeText(t,(l[i].areav[0]+5-r.width/2)*n-a*(1-n)/2,(l[i].areav[1]+5+e-r.height/2)*n)}else{o.fillText(t,(l[i].areav[0]+5-r.width/2)*n-a*(1-n)/2,(l[i].areav[1]+5+e-r.height/2)*n)}}else{o.fillText(t,(l[i].areav[0]+5-r.width/2)*n-a*(1-n)/2,(l[i].areav[1]+5+e-r.height/2)*n)}}}else{if(l[i].area[0]>0){if(r.tooltip){if(r.tooltip.index==i){o.strokeText(t,(l[i].area[0]+5-r.width/2)*n-a*(1-n)/2,(l[i].area[1]+5+e-r.height/2)*n)}else{o.fillText(t,(l[i].area[0]+5-r.width/2)*n-a*(1-n)/2,(l[i].area[1]+5+e-r.height/2)*n)}}else{o.fillText(t,(l[i].area[0]+5-r.width/2)*n-a*(1-n)/2,(l[i].area[1]+5+e-r.height/2)*n)}}}o.stroke();o.restore()}o.restore()}function drawFunnelDataPoints(e,a,t,i){let c=arguments.length>4&&arguments[4]!==undefined?arguments[4]:1;let r=assign({},{type:"funnel",activeWidth:10,activeOpacity:.3,border:false,borderWidth:2,borderColor:"#FFFFFF",fillOpacity:1,labelAlign:"right",linearType:"none",customColor:[]},a.extra.funnel);let o=(a.height-a.area[0]-a.area[2])/e.length;let n={x:a.area[3]+(a.width-a.area[1]-a.area[3])/2,y:a.height-a.area[2]};let l=r.activeWidth*a.pix;let d=Math.min((a.width-a.area[1]-a.area[3])/2-l,(a.height-a.area[0]-a.area[2])/2-l);e=getFunnelDataPoints(e,d,r.type,o,c);i.save();i.translate(n.x,n.y);r.customColor=fillCustomColor(r.linearType,r.customColor,e,t);if(r.type=="pyramid"){for(let t=0;t<e.length;t++){if(t==e.length-1){if(a.tooltip){if(a.tooltip.index==t){i.beginPath();i.setFillStyle(hexToRgb(e[t].color,r.activeOpacity));i.moveTo(-l,-o);i.lineTo(-e[t].radius-l,0);i.lineTo(e[t].radius+l,0);i.lineTo(l,-o);i.lineTo(-l,-o);i.closePath();i.fill()}}e[t].funnelArea=[n.x-e[t].radius,n.y-o*(t+1),n.x+e[t].radius,n.y-o*t];i.beginPath();i.setLineWidth(r.borderWidth*a.pix);i.setStrokeStyle(r.borderColor);var s=hexToRgb(e[t].color,r.fillOpacity);if(r.linearType=="custom"){var h=i.createLinearGradient(e[t].radius,-o,-e[t].radius,-o);h.addColorStop(0,hexToRgb(e[t].color,r.fillOpacity));h.addColorStop(.5,hexToRgb(r.customColor[e[t].linearIndex],r.fillOpacity));h.addColorStop(1,hexToRgb(e[t].color,r.fillOpacity));s=h}i.setFillStyle(s);i.moveTo(0,-o);i.lineTo(-e[t].radius,0);i.lineTo(e[t].radius,0);i.lineTo(0,-o);i.closePath();i.fill();if(r.border==true){i.stroke()}}else{if(a.tooltip){if(a.tooltip.index==t){i.beginPath();i.setFillStyle(hexToRgb(e[t].color,r.activeOpacity));i.moveTo(0,0);i.lineTo(-e[t].radius-l,0);i.lineTo(-e[t+1].radius-l,-o);i.lineTo(e[t+1].radius+l,-o);i.lineTo(e[t].radius+l,0);i.lineTo(0,0);i.closePath();i.fill()}}e[t].funnelArea=[n.x-e[t].radius,n.y-o*(t+1),n.x+e[t].radius,n.y-o*t];i.beginPath();i.setLineWidth(r.borderWidth*a.pix);i.setStrokeStyle(r.borderColor);var s=hexToRgb(e[t].color,r.fillOpacity);if(r.linearType=="custom"){var h=i.createLinearGradient(e[t].radius,-o,-e[t].radius,-o);h.addColorStop(0,hexToRgb(e[t].color,r.fillOpacity));h.addColorStop(.5,hexToRgb(r.customColor[e[t].linearIndex],r.fillOpacity));h.addColorStop(1,hexToRgb(e[t].color,r.fillOpacity));s=h}i.setFillStyle(s);i.moveTo(0,0);i.lineTo(-e[t].radius,0);i.lineTo(-e[t+1].radius,-o);i.lineTo(e[t+1].radius,-o);i.lineTo(e[t].radius,0);i.lineTo(0,0);i.closePath();i.fill();if(r.border==true){i.stroke()}}i.translate(0,-o)}}else{for(let t=0;t<e.length;t++){if(t==0){if(a.tooltip){if(a.tooltip.index==t){i.beginPath();i.setFillStyle(hexToRgb(e[t].color,r.activeOpacity));i.moveTo(-l,0);i.lineTo(-e[t].radius-l,-o);i.lineTo(e[t].radius+l,-o);i.lineTo(l,0);i.lineTo(-l,0);i.closePath();i.fill()}}e[t].funnelArea=[n.x-e[t].radius,n.y-o,n.x+e[t].radius,n.y];i.beginPath();i.setLineWidth(r.borderWidth*a.pix);i.setStrokeStyle(r.borderColor);var s=hexToRgb(e[t].color,r.fillOpacity);if(r.linearType=="custom"){var h=i.createLinearGradient(e[t].radius,-o,-e[t].radius,-o);h.addColorStop(0,hexToRgb(e[t].color,r.fillOpacity));h.addColorStop(.5,hexToRgb(r.customColor[e[t].linearIndex],r.fillOpacity));h.addColorStop(1,hexToRgb(e[t].color,r.fillOpacity));s=h}i.setFillStyle(s);i.moveTo(0,0);i.lineTo(-e[t].radius,-o);i.lineTo(e[t].radius,-o);i.lineTo(0,0);i.closePath();i.fill();if(r.border==true){i.stroke()}}else{if(a.tooltip){if(a.tooltip.index==t){i.beginPath();i.setFillStyle(hexToRgb(e[t].color,r.activeOpacity));i.moveTo(0,0);i.lineTo(-e[t-1].radius-l,0);i.lineTo(-e[t].radius-l,-o);i.lineTo(e[t].radius+l,-o);i.lineTo(e[t-1].radius+l,0);i.lineTo(0,0);i.closePath();i.fill()}}e[t].funnelArea=[n.x-e[t].radius,n.y-o*(t+1),n.x+e[t].radius,n.y-o*t];i.beginPath();i.setLineWidth(r.borderWidth*a.pix);i.setStrokeStyle(r.borderColor);var s=hexToRgb(e[t].color,r.fillOpacity);if(r.linearType=="custom"){var h=i.createLinearGradient(e[t].radius,-o,-e[t].radius,-o);h.addColorStop(0,hexToRgb(e[t].color,r.fillOpacity));h.addColorStop(.5,hexToRgb(r.customColor[e[t].linearIndex],r.fillOpacity));h.addColorStop(1,hexToRgb(e[t].color,r.fillOpacity));s=h}i.setFillStyle(s);i.moveTo(0,0);i.lineTo(-e[t-1].radius,0);i.lineTo(-e[t].radius,-o);i.lineTo(e[t].radius,-o);i.lineTo(e[t-1].radius,0);i.lineTo(0,0);i.closePath();i.fill();if(r.border==true){i.stroke()}}i.translate(0,-o)}}i.restore();if(a.dataLabel!==false&&c===1){drawFunnelText(e,a,i,o,r.labelAlign,l,n)}return{center:n,radius:d,series:e}}function drawFunnelText(l,s,h,c,d,x,f){for(let n=0;n<l.length;n++){let t=l[n];if(t.labelShow===false){continue}let e,a,i,r;let o=t.formatter?t.formatter(t,n,l,s):util.toFixed(t._proportion_*100)+"%";o=t.labelText?t.labelText:o;if(d=="right"){if(s.extra.funnel.type==="pyramid"){if(n==l.length-1){e=(t.funnelArea[2]+f.x)/2}else{e=(t.funnelArea[2]+l[n+1].funnelArea[2])/2}}else{if(n==0){e=(t.funnelArea[2]+f.x)/2}else{e=(t.funnelArea[2]+l[n-1].funnelArea[2])/2}}a=e+x*2;i=t.funnelArea[1]+c/2;r=t.textSize*s.pix||s.fontSize*s.pix;h.setLineWidth(1*s.pix);h.setStrokeStyle(t.color);h.setFillStyle(t.color);h.beginPath();h.moveTo(e,i);h.lineTo(a,i);h.stroke();h.closePath();h.beginPath();h.moveTo(a,i);h.arc(a,i,2*s.pix,0,2*Math.PI);h.closePath();h.fill();h.beginPath();h.setFontSize(r);h.setFillStyle(t.textColor||s.fontColor);h.fillText(o,a+5,i+r/2-2);h.closePath();h.stroke();h.closePath()}else{if(s.extra.funnel.type==="pyramid"){if(n==l.length-1){e=(t.funnelArea[0]+f.x)/2}else{e=(t.funnelArea[0]+l[n+1].funnelArea[0])/2}}else{if(n==0){e=(t.funnelArea[0]+f.x)/2}else{e=(t.funnelArea[0]+l[n-1].funnelArea[0])/2}}a=e-x*2;i=t.funnelArea[1]+c/2;r=t.textSize*s.pix||s.fontSize*s.pix;h.setLineWidth(1*s.pix);h.setStrokeStyle(t.color);h.setFillStyle(t.color);h.beginPath();h.moveTo(e,i);h.lineTo(a,i);h.stroke();h.closePath();h.beginPath();h.moveTo(a,i);h.arc(a,i,2,0,2*Math.PI);h.closePath();h.fill();h.beginPath();h.setFontSize(r);h.setFillStyle(t.textColor||s.fontColor);h.fillText(o,a-5-measureText(o,r,h),i+r/2-2);h.closePath();h.stroke();h.closePath()}}}function drawCanvas(t,e){e.draw()}var Timing={easeIn:function t(e){return Math.pow(e,3)},easeOut:function t(e){return Math.pow(e-1,3)+1},easeInOut:function t(e){if((e/=.5)<1){return.5*Math.pow(e,3)}else{return.5*(Math.pow(e-2,3)+2)}},linear:function t(e){return e}};function Animation(r){this.isStop=false;r.duration=typeof r.duration==="undefined"?1e3:r.duration;r.timing=r.timing||"easeInOut";var o=17;function t(){if(typeof setTimeout!=="undefined"){return function(e,t){setTimeout(function(){var t=+new Date;e(t)},t)}}else if(typeof requestAnimationFrame!=="undefined"){return requestAnimationFrame}else{return function(t){t(null)}}}var n=t();var l=null;var s=function t(e){if(e===null||this.isStop===true){r.onProcess&&r.onProcess(1);r.onAnimationFinish&&r.onAnimationFinish();return}if(l===null){l=e}if(e-l<r.duration){var a=(e-l)/r.duration;var i=Timing[r.timing];a=i(a);r.onProcess&&r.onProcess(a);n(s,o)}else{r.onProcess&&r.onProcess(1);r.onAnimationFinish&&r.onAnimationFinish()}};s=s.bind(this);n(s,o)}Animation.prototype.stop=function(){this.isStop=true};function drawCharts(t,l,n,s){var h=this;var c=l.series;if(t==="pie"||t==="ring"||t==="mount"||t==="rose"||t==="funnel"){c=fixPieSeries(c,l,n)}var d=l.categories;if(t==="mount"){d=[];for(let t=0;t<c.length;t++){if(c[t].show!==false)d.push(c[t].name)}l.categories=d}c=fillSeries(c,l,n);var e=l.animation?l.duration:0;h.animationInstance&&h.animationInstance.stop();var x=null;if(t=="candle"){let t=assign({},l.extra.candle.average);if(t.show){x=calCandleMA(t.day,t.name,t.color,c[0].data);x=fillSeries(x,l,n);l.seriesMA=x}else if(l.seriesMA){x=l.seriesMA=fillSeries(l.seriesMA,l,n)}else{x=c}}else{x=c}l._series_=c=filterSeries(c);l.area=new Array(4);for(let t=0;t<4;t++){l.area[t]=l.padding[t]*l.pix}var a=calLegendData(x,l,n,l.chartData,s),r=a.area.wholeHeight,o=a.area.wholeWidth;switch(l.legend.position){case"top":l.area[0]+=r;break;case"bottom":l.area[2]+=r;break;case"left":l.area[3]+=o;break;case"right":l.area[1]+=o;break}let f={},i=0;if(l.type==="line"||l.type==="column"||l.type==="mount"||l.type==="area"||l.type==="mix"||l.type==="candle"||l.type==="scatter"||l.type==="bubble"||l.type==="bar"){f=calYAxisData(c,l,n,s);i=f.yAxisWidth;if(l.yAxis.showTitle){let e=0;for(let t=0;t<l.yAxis.data.length;t++){e=Math.max(e,l.yAxis.data[t].titleFontSize?l.yAxis.data[t].titleFontSize*l.pix:n.fontSize)}l.area[0]+=e}let e=0,a=0;for(let t=0;t<i.length;t++){if(i[t].position=="left"){if(a>0){l.area[3]+=i[t].width+l.yAxis.padding*l.pix}else{l.area[3]+=i[t].width}a+=1}else if(i[t].position=="right"){if(e>0){l.area[1]+=i[t].width+l.yAxis.padding*l.pix}else{l.area[1]+=i[t].width}e+=1}}}else{n.yAxisWidth=i}l.chartData.yAxisData=f;if(l.categories&&l.categories.length&&l.type!=="radar"&&l.type!=="gauge"&&l.type!=="bar"){l.chartData.xAxisData=getXAxisPoints(l.categories,l,n);let t=calCategoriesData(l.categories,l,n,l.chartData.xAxisData.eachSpacing,s),e=t.xAxisHeight,a=t.angle;n.xAxisHeight=e;n._xAxisTextAngle_=a;l.area[2]+=e;l.chartData.categoriesData=t}else{if(l.type==="line"||l.type==="area"||l.type==="scatter"||l.type==="bubble"||l.type==="bar"){l.chartData.xAxisData=calXAxisData(c,l,n,s);d=l.chartData.xAxisData.rangesFormat;let t=calCategoriesData(d,l,n,l.chartData.xAxisData.eachSpacing,s),e=t.xAxisHeight,a=t.angle;n.xAxisHeight=e;n._xAxisTextAngle_=a;l.area[2]+=e;l.chartData.categoriesData=t}else{l.chartData.xAxisData={xAxisPoints:[]}}}if(l.enableScroll&&l.xAxis.scrollAlign=="right"&&l._scrollDistance_===undefined){let t=0,e=l.chartData.xAxisData.xAxisPoints,a=l.chartData.xAxisData.startX,i=l.chartData.xAxisData.endX,r=l.chartData.xAxisData.eachSpacing;let o=r*(e.length-1);let n=i-a;t=n-o;h.scrollOption.currentOffset=t;h.scrollOption.startTouchX=t;h.scrollOption.distance=0;h.scrollOption.lastMoveTime=0;l._scrollDistance_=t}if(t==="pie"||t==="ring"||t==="rose"){n._pieTextMaxLength_=l.dataLabel===false?0:getPieTextMaxLength(x,n,s,l)}switch(t){case"word":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function(t){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawWordCloudDataPoints(c,l,n,s,t);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"map":s.clearRect(0,0,l.width,l.height);drawMapDataPoints(c,l,n,s);break;case"funnel":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function(t){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.funnelData=drawFunnelDataPoints(c,l,n,s,t);drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,t);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"line":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawLineDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"scatter":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawScatterDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"bubble":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawBubbleDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"mix":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawMixDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"column":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawColumnDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"mount":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawMountDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"bar":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawXAxis(d,l,n,s);var a=drawBarDataPoints(c,l,n,s,e),i=a.yAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.yAxisPoints=i;l.chartData.xAxisPoints=l.chartData.xAxisData.xAxisPoints;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"area":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawAreaDataPoints(c,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"ring":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.pieData=drawPieDataPoints(c,l,n,s,e);drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"pie":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.pieData=drawPieDataPoints(c,l,n,s,e);drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"rose":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.pieData=drawRoseDataPoints(c,l,n,s,e);drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"radar":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.radarData=drawRadarDataPoints(c,l,n,s,e);drawLegend(l.series,l,n,s,l.chartData);drawToolTipBridge(l,n,s,e);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"arcbar":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.arcbarData=drawArcbarDataPoints(c,l,n,s,e);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"gauge":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}l.chartData.gaugeData=drawGaugeDataPoints(d,c,l,n,s,e);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break;case"candle":this.animationInstance=new Animation({timing:l.timing,duration:e,onProcess:function t(e){s.clearRect(0,0,l.width,l.height);if(l.rotate){contextRotate(s,l)}drawYAxisGrid(d,l,n,s);drawXAxis(d,l,n,s);var a=drawCandleDataPoints(c,x,l,n,s,e),i=a.xAxisPoints,r=a.calPoints,o=a.eachSpacing;l.chartData.xAxisPoints=i;l.chartData.calPoints=r;l.chartData.eachSpacing=o;drawYAxis(c,l,n,s);if(l.enableMarkLine!==false&&e===1){drawMarkLine(l,n,s)}if(x){drawLegend(x,l,n,s,l.chartData)}else{drawLegend(l.series,l,n,s,l.chartData)}drawToolTipBridge(l,n,s,e,o,i);drawCanvas(l,s)},onAnimationFinish:function t(){h.uevent.trigger("renderComplete")}});break}}function uChartsEvent(){this.events={}}uChartsEvent.prototype.addEventListener=function(t,e){this.events[t]=this.events[t]||[];this.events[t].push(e)};uChartsEvent.prototype.delEventListener=function(t){this.events[t]=[]};uChartsEvent.prototype.trigger=function(){for(var t=arguments.length,e=Array(t),a=0;a<t;a++){e[a]=arguments[a]}var i=e[0];var r=e.slice(1);if(!!this.events[i]){this.events[i].forEach(function(t){try{t.apply(null,r)}catch(t){}})}};var uCharts=function t(a){a.pix=a.pixelRatio?a.pixelRatio:1;a.fontSize=a.fontSize?a.fontSize:13;a.fontColor=a.fontColor?a.fontColor:config.fontColor;if(a.background==""||a.background=="none"){a.background="#FFFFFF"}a.title=assign({},a.title);a.subtitle=assign({},a.subtitle);a.duration=a.duration?a.duration:1e3;a.yAxis=assign({},{data:[],showTitle:false,disabled:false,disableGrid:false,splitNumber:5,gridType:"solid",dashLength:4*a.pix,gridColor:"#cccccc",padding:10,fontColor:"#666666"},a.yAxis);a.xAxis=assign({},{rotateLabel:false,rotateAngle:45,disabled:false,disableGrid:false,splitNumber:5,calibration:false,gridType:"solid",dashLength:4,scrollAlign:"left",boundaryGap:"center",axisLine:true,axisLineColor:"#cccccc"},a.xAxis);a.xAxis.scrollPosition=a.xAxis.scrollAlign;a.legend=assign({},{show:true,position:"bottom",float:"center",backgroundColor:"rgba(0,0,0,0)",borderColor:"rgba(0,0,0,0)",borderWidth:0,padding:5,margin:5,itemGap:10,fontSize:a.fontSize,lineHeight:a.fontSize,fontColor:a.fontColor,formatter:{},hiddenColor:"#CECECE"},a.legend);a.extra=assign({},a.extra);a.rotate=a.rotate?true:false;a.animation=a.animation?true:false;a.rotate=a.rotate?true:false;a.canvas2d=a.canvas2d?true:false;let e=assign({},config);e.color=a.color?a.color:e.color;if(a.type=="pie"){e.pieChartLinePadding=a.dataLabel===false?0:a.extra.pie.labelWidth*a.pix||e.pieChartLinePadding*a.pix}if(a.type=="ring"){e.pieChartLinePadding=a.dataLabel===false?0:a.extra.ring.labelWidth*a.pix||e.pieChartLinePadding*a.pix}if(a.type=="rose"){e.pieChartLinePadding=a.dataLabel===false?0:a.extra.rose.labelWidth*a.pix||e.pieChartLinePadding*a.pix}e.pieChartTextPadding=a.dataLabel===false?0:e.pieChartTextPadding*a.pix;e.rotate=a.rotate;if(a.rotate){let t=a.width;let e=a.height;a.width=e;a.height=t}a.padding=a.padding?a.padding:e.padding;e.yAxisWidth=config.yAxisWidth*a.pix;e.xAxisHeight=config.xAxisHeight*a.pix;if(a.enableScroll&&a.xAxis.scrollShow){e.xAxisHeight+=6*a.pix}e.fontSize=a.fontSize*a.pix;e.titleFontSize=config.titleFontSize*a.pix;e.subtitleFontSize=config.subtitleFontSize*a.pix;e.toolTipPadding=config.toolTipPadding*a.pix;e.toolTipLineHeight=config.toolTipLineHeight*a.pix;if(!a.context){throw new Error("[uCharts] æœªèŽ·å–åˆ°context!注意:v2.0版本后,需要自行获取canvas的绘图上下文并传入opts.context!")}this.context=a.context;if(!this.context.setTextAlign){this.context.setStrokeStyle=function(t){return this.strokeStyle=t};this.context.setLineWidth=function(t){return this.lineWidth=t};this.context.setLineCap=function(t){return this.lineCap=t};this.context.setFontSize=function(t){return this.font=t+"px sans-serif"};this.context.setFillStyle=function(t){return this.fillStyle=t};this.context.setTextAlign=function(t){return this.textAlign=t};this.context.draw=function(){}}if(!this.context.setLineDash){this.context.setLineDash=function(t){}}a.chartData={};this.uevent=new uChartsEvent;this.scrollOption={currentOffset:0,startTouchX:0,distance:0,lastMoveTime:0};this.opts=a;this.config=e;drawCharts.call(this,a.type,a,e,this.context)};uCharts.prototype.updateData=function(){let t=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.opts=assign({},this.opts,t);this.opts.updateData=true;let c=t.scrollPosition||"current";switch(c){case"current":this.opts._scrollDistance_=this.scrollOption.currentOffset;break;case"left":this.opts._scrollDistance_=0;this.scrollOption={currentOffset:0,startTouchX:0,distance:0,lastMoveTime:0};break;case"right":let t=calYAxisData(this.opts.series,this.opts,this.config,this.context),e=t.yAxisWidth;this.config.yAxisWidth=e;let a=0;let i=getXAxisPoints(this.opts.categories,this.opts,this.config),r=i.xAxisPoints,o=i.startX,n=i.endX,l=i.eachSpacing;let s=l*(r.length-1);let h=n-o;a=h-s;this.scrollOption={currentOffset:a,startTouchX:a,distance:0,lastMoveTime:0};this.opts._scrollDistance_=a;break}drawCharts.call(this,this.opts.type,this.opts,this.config,this.context)};uCharts.prototype.zoom=function(){var t=arguments.length>0&&arguments[0]!==undefined?arguments[0]:this.opts.xAxis.itemCount;if(this.opts.enableScroll!==true){console.log("[uCharts] è¯·å¯ç”¨æ»šåŠ¨æ¡åŽä½¿ç”¨");return}let e=Math.round(Math.abs(this.scrollOption.currentOffset)/this.opts.chartData.eachSpacing)+Math.round(this.opts.xAxis.itemCount/2);this.opts.animation=false;this.opts.xAxis.itemCount=t.itemCount;let a=calYAxisData(this.opts.series,this.opts,this.config,this.context),i=a.yAxisWidth;this.config.yAxisWidth=i;let r=0;let o=getXAxisPoints(this.opts.categories,this.opts,this.config),h=o.xAxisPoints,c=o.startX,d=o.endX,n=o.eachSpacing;let x=n*e;let l=d-c;let s=l-n*(h.length-1);r=l/2-x;if(r>0){r=0}if(r<s){r=s}this.scrollOption={currentOffset:r,startTouchX:0,distance:0,lastMoveTime:0};calValidDistance(this,r,this.opts.chartData,this.config,this.opts);this.opts._scrollDistance_=r;drawCharts.call(this,this.opts.type,this.opts,this.config,this.context)};uCharts.prototype.dobuleZoom=function(t){if(this.opts.enableScroll!==true){console.log("[uCharts] è¯·å¯ç”¨æ»šåŠ¨æ¡åŽä½¿ç”¨");return}const a=t.changedTouches;if(a.length<2){return}for(var e=0;e<a.length;e++){a[e].x=a[e].x?a[e].x:a[e].clientX;a[e].y=a[e].y?a[e].y:a[e].clientY}const i=[getTouches(a[0],this.opts,t),getTouches(a[1],this.opts,t)];const c=Math.abs(i[0].x-i[1].x);if(!this.scrollOption.moveCount){let t={changedTouches:[{x:a[0].x,y:this.opts.area[0]/this.opts.pix+2}]};let e={changedTouches:[{x:a[1].x,y:this.opts.area[0]/this.opts.pix+2}]};if(this.opts.rotate){t={changedTouches:[{x:this.opts.height/this.opts.pix-this.opts.area[0]/this.opts.pix-2,y:a[0].y}]};e={changedTouches:[{x:this.opts.height/this.opts.pix-this.opts.area[0]/this.opts.pix-2,y:a[1].y}]}}const s=this.getCurrentDataIndex(t).index;const h=this.getCurrentDataIndex(e).index;const v=Math.abs(s-h);this.scrollOption.moveCount=v;this.scrollOption.moveCurrent1=Math.min(s,h);this.scrollOption.moveCurrent2=Math.max(s,h);return}let d=c/this.scrollOption.moveCount;let r=(this.opts.width-this.opts.area[1]-this.opts.area[3])/d;r=r<=2?2:r;r=r>=this.opts.categories.length?this.opts.categories.length:r;this.opts.animation=false;this.opts.xAxis.itemCount=r;let o=0;let n=getXAxisPoints(this.opts.categories,this.opts,this.config),x=n.xAxisPoints,f=n.startX,p=n.endX,l=n.eachSpacing;let g=l*this.scrollOption.moveCurrent1;let u=p-f;let y=u-l*(x.length-1);o=-g+Math.min(i[0].x,i[1].x)-this.opts.area[3]-l;if(o>0){o=0}if(o<y){o=y}this.scrollOption.currentOffset=o;this.scrollOption.startTouchX=0;this.scrollOption.distance=0;calValidDistance(this,o,this.opts.chartData,this.config,this.opts);this.opts._scrollDistance_=o;drawCharts.call(this,this.opts.type,this.opts,this.config,this.context)};uCharts.prototype.stopAnimation=function(){this.animationInstance&&this.animationInstance.stop()};uCharts.prototype.addEventListener=function(t,e){this.uevent.addEventListener(t,e)};uCharts.prototype.delEventListener=function(t){this.uevent.delEventListener(t)};uCharts.prototype.getCurrentDataIndex=function(e){var a=null;if(e.changedTouches){a=e.changedTouches[0]}else{a=e.mp.changedTouches[0]}if(a){let t=getTouches(a,this.opts,e);if(this.opts.type==="pie"||this.opts.type==="ring"){return findPieChartCurrentIndex({x:t.x,y:t.y},this.opts.chartData.pieData,this.opts)}else if(this.opts.type==="rose"){return findRoseChartCurrentIndex({x:t.x,y:t.y},this.opts.chartData.pieData,this.opts)}else if(this.opts.type==="radar"){return findRadarChartCurrentIndex({x:t.x,y:t.y},this.opts.chartData.radarData,this.opts.categories.length)}else if(this.opts.type==="funnel"){return findFunnelChartCurrentIndex({x:t.x,y:t.y},this.opts.chartData.funnelData)}else if(this.opts.type==="map"){return findMapChartCurrentIndex({x:t.x,y:t.y},this.opts)}else if(this.opts.type==="word"){return findWordChartCurrentIndex({x:t.x,y:t.y},this.opts.chartData.wordCloudData)}else if(this.opts.type==="bar"){return findBarChartCurrentIndex({x:t.x,y:t.y},this.opts.chartData.calPoints,this.opts,this.config,Math.abs(this.scrollOption.currentOffset))}else{return findCurrentIndex({x:t.x,y:t.y},this.opts.chartData.calPoints,this.opts,this.config,Math.abs(this.scrollOption.currentOffset))}}return-1};uCharts.prototype.getLegendDataIndex=function(e){var a=null;if(e.changedTouches){a=e.changedTouches[0]}else{a=e.mp.changedTouches[0]}if(a){let t=getTouches(a,this.opts,e);return findLegendIndex({x:t.x,y:t.y},this.opts.chartData.legendData)}return-1};uCharts.prototype.touchLegend=function(t){var e=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var a=null;if(t.changedTouches){a=t.changedTouches[0]}else{a=t.mp.changedTouches[0]}if(a){var i=getTouches(a,this.opts,t);var r=this.getLegendDataIndex(t);if(r>=0){if(this.opts.type=="candle"){this.opts.seriesMA[r].show=!this.opts.seriesMA[r].show}else{this.opts.series[r].show=!this.opts.series[r].show}this.opts.animation=e.animation?true:false;this.opts._scrollDistance_=this.scrollOption.currentOffset;drawCharts.call(this,this.opts.type,this.opts,this.config,this.context)}}};uCharts.prototype.showToolTip=function(t){var e=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var c=null;if(t.changedTouches){c=t.changedTouches[0]}else{c=t.mp.changedTouches[0]}if(!c){console.log("[uCharts] æœªèŽ·å–åˆ°event坐标信息")}var a=getTouches(c,this.opts,t);var d=this.scrollOption.currentOffset;var i=assign({},this.opts,{_scrollDistance_:d,animation:false});if(this.opts.type==="line"||this.opts.type==="area"||this.opts.type==="column"||this.opts.type==="scatter"||this.opts.type==="bubble"){var r=this.getCurrentDataIndex(t);var o=e.index==undefined?r.index:e.index;if(o>-1||o.length>0){var n=getSeriesDataItem(this.opts.series,o,r.group);if(n.length!==0){var l=getToolTipData(n,this.opts,o,r.group,this.opts.categories,e),s=l.textList,h=l.offset;h.y=a.y;i.tooltip={textList:e.textList!==undefined?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}}drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="mount"){var o=e.index==undefined?this.getCurrentDataIndex(t).index:e.index;if(o>-1){var i=assign({},this.opts,{animation:false});var n=assign({},i._series_[o]);var s=[{text:e.formatter?e.formatter(n,undefined,o,i):n.name+": "+n.data,color:n.color}];var h={x:i.chartData.calPoints[o].x,y:a.y};i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="bar"){var r=this.getCurrentDataIndex(t);var o=e.index==undefined?r.index:e.index;if(o>-1||o.length>0){var n=getSeriesDataItem(this.opts.series,o,r.group);if(n.length!==0){var l=getToolTipData(n,this.opts,o,r.group,this.opts.categories,e),s=l.textList,h=l.offset;h.x=a.x;i.tooltip={textList:e.textList!==undefined?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}}drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="mix"){var r=this.getCurrentDataIndex(t);var o=e.index==undefined?r.index:e.index;if(o>-1){var d=this.scrollOption.currentOffset;var i=assign({},this.opts,{_scrollDistance_:d,animation:false});var n=getSeriesDataItem(this.opts.series,o);if(n.length!==0){var x=getMixToolTipData(n,this.opts,o,this.opts.categories,e),s=x.textList,h=x.offset;h.y=a.y;i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}}drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="candle"){var r=this.getCurrentDataIndex(t);var o=e.index==undefined?r.index:e.index;if(o>-1){var d=this.scrollOption.currentOffset;var i=assign({},this.opts,{_scrollDistance_:d,animation:false});var n=getSeriesDataItem(this.opts.series,o);if(n.length!==0){var l=getCandleToolTipData(this.opts.series[0].data,n,this.opts,o,this.opts.categories,this.opts.extra.candle,e),s=l.textList,h=l.offset;h.y=a.y;i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}}drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="pie"||this.opts.type==="ring"||this.opts.type==="rose"||this.opts.type==="funnel"){var o=e.index==undefined?this.getCurrentDataIndex(t):e.index;if(o>-1){var i=assign({},this.opts,{animation:false});var n=assign({},i._series_[o]);var s=[{text:e.formatter?e.formatter(n,undefined,o,i):n.name+": "+n.data,color:n.color}];var h={x:a.x,y:a.y};i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="map"){var o=e.index==undefined?this.getCurrentDataIndex(t):e.index;if(o>-1){var i=assign({},this.opts,{animation:false});var n=assign({},this.opts.series[o]);n.name=n.properties.name;var s=[{text:e.formatter?e.formatter(n,undefined,o,this.opts):n.name,color:n.color}];var h={x:a.x,y:a.y};i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}i.updateData=false;drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="word"){var o=e.index==undefined?this.getCurrentDataIndex(t):e.index;if(o>-1){var i=assign({},this.opts,{animation:false});var n=assign({},this.opts.series[o]);var s=[{text:e.formatter?e.formatter(n,undefined,o,this.opts):n.name,color:n.color}];var h={x:a.x,y:a.y};i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}i.updateData=false;drawCharts.call(this,i.type,i,this.config,this.context)}if(this.opts.type==="radar"){var o=e.index==undefined?this.getCurrentDataIndex(t):e.index;if(o>-1){var i=assign({},this.opts,{animation:false});var n=getSeriesDataItem(this.opts.series,o);if(n.length!==0){var s=n.map(t=>{return{text:e.formatter?e.formatter(t,this.opts.categories[o],o,this.opts):t.name+": "+t.data,color:t.color}});var h={x:a.x,y:a.y};i.tooltip={textList:e.textList?e.textList:s,offset:e.offset!==undefined?e.offset:h,option:e,index:o}}}drawCharts.call(this,i.type,i,this.config,this.context)}};uCharts.prototype.translate=function(t){this.scrollOption={currentOffset:t,startTouchX:t,distance:0,lastMoveTime:0};let e=assign({},this.opts,{_scrollDistance_:t,animation:false});drawCharts.call(this,this.opts.type,e,this.config,this.context)};uCharts.prototype.scrollStart=function(t){var e=null;if(t.changedTouches){e=t.changedTouches[0]}else{e=t.mp.changedTouches[0]}var a=getTouches(e,this.opts,t);if(e&&this.opts.enableScroll===true){this.scrollOption.startTouchX=a.x}};uCharts.prototype.scroll=function(t){if(this.scrollOption.lastMoveTime===0){this.scrollOption.lastMoveTime=Date.now()}let e=this.opts.touchMoveLimit||60;let a=Date.now();let i=a-this.scrollOption.lastMoveTime;if(i<Math.floor(1e3/e))return;if(this.scrollOption.startTouchX==0)return;this.scrollOption.lastMoveTime=a;var r=null;if(t.changedTouches){r=t.changedTouches[0]}else{r=t.mp.changedTouches[0]}if(r&&this.opts.enableScroll===true){var o=getTouches(r,this.opts,t);var n;n=o.x-this.scrollOption.startTouchX;var l=this.scrollOption.currentOffset;var s=calValidDistance(this,l+n,this.opts.chartData,this.config,this.opts);this.scrollOption.distance=n=s-l;var h=assign({},this.opts,{_scrollDistance_:l+n,animation:false});this.opts=h;drawCharts.call(this,h.type,h,this.config,this.context);return l+n}};uCharts.prototype.scrollEnd=function(t){if(this.opts.enableScroll===true){var e=this.scrollOption,a=e.currentOffset,i=e.distance;this.scrollOption.currentOffset=a+i;this.scrollOption.distance=0;this.scrollOption.moveCount=0}};export default uCharts;
uni_modules/qiun-data-charts/license.md
uni_modules/qiun-data-charts/package.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,84 @@
{
  "id": "qiun-data-charts",
  "displayName": "秋云 ucharts echarts é«˜æ€§èƒ½è·¨å…¨ç«¯å›¾è¡¨ç»„ä»¶",
  "version": "2.4.3-20220505",
  "description": "uCharts æ–°å¢žåŒæŒ‡ç¼©æ”¾ã€æ–°å¢žå±±å³°å›¾ï¼æ”¯æŒH5及APP用 ucharts echarts æ¸²æŸ“图表,uniapp可视化首选组件",
  "keywords": [
    "ucharts",
    "echarts",
    "f2",
    "图表",
    "可视化"
],
  "repository": "https://gitee.com/uCharts/uCharts",
  "engines": {
    "HBuilderX": "^3.3.8"
  },
  "dcloudext": {
    "category": [
        "前端组件",
        "通用组件"
    ],
    "sale": {
      "regular": {
        "price": "0.00"
      },
      "sourcecode": {
        "price": "0.00"
      }
    },
    "contact": {
      "qq": "474119"
    },
    "declaration": {
      "ads": "无",
      "data": "插件不采集任何数据",
      "permissions": "无"
    },
    "npmurl": "https://www.npmjs.com/~qiun"
  },
  "uni_modules": {
    "dependencies": [],
    "encrypt": [],
    "platforms": {
      "cloud": {
        "tcb": "y",
        "aliyun": "y"
      },
      "client": {
        "App": {
          "app-vue": "y",
          "app-nvue": "y"
        },
        "H5-mobile": {
          "Safari": "y",
          "Android Browser": "y",
          "微信浏览器(Android)": "y",
          "QQ浏览器(Android)": "y"
        },
        "H5-pc": {
          "Chrome": "y",
          "IE": "y",
          "Edge": "y",
          "Firefox": "y",
          "Safari": "y"
        },
        "小程序": {
          "微信": "y",
          "阿里": "y",
          "百度": "y",
          "字节跳动": "y",
          "QQ": "y"
        },
        "快应用": {
          "华为": "y",
          "联盟": "y"
        },
        "Vue": {
            "vue2": "y",
            "vue3": "y"
        }
      }
    }
  }
}
uni_modules/qiun-data-charts/readme.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,102 @@
## <font color='red'>写给uCharts使用者的一封信</font>
<font color='red'>
亲爱的用户:
- ç”±äºŽæœ€è¿‘上线的官网中实行了部分收费体验,收到了许多用户的使用反馈,大致反馈的问题都指向同一矛头:为何新官网的在线工具也要收费?对于这件事,我们深表歉意。由于新官网本身未提供技术文档,使得用户误以为我们对文档实行了收费。经我们连夜整改,新官网目前已经将技术文档开放出来供大家阅读使用,并免费对外开放了【演示】中的查看全端全平台的代码的功能,为此再次向所受影响的用户们致以诚恳的歉意。
- å…¶æ¬¡ï¼Œæˆ‘们须澄清几点,如下:
1. uCharts的插件本身遵循开源原则,并不收费,用户可自行到DCloud市场与Gitee码云上获取源码
2. uCharts的技术文档永久对用户开放
3. æ”¶è´¹å†…容仅针对原生工具、组件工具、定制功能以及模板市场的部分收费模板
- uCharts为什么实行收费原则?
1. æœåŠ¡å™¨çš„è´¹ç”¨æ”¯æ’‘
2. å›¢é˜Ÿçš„运营支出;正如你所见,我们的群里有大量的用户在请教图表配置与反馈问题,群里的每一位管理员都在花费不少精力在积极解决用户的问题,然而遇到巨大的咨询量时,我们无法及时、精准解答回复,因此,我们推出了会员优先服务
3. ä¸Žå…¶è¯´æ¨¡æ¿å¸‚场是收费,倒不如说给野生用户提供了创造价值的机会,用户既可以在上面发布模板赚取费用,遇到心动的模板也能免费/付费使用
- æ”¶è´¹ä¸æ˜¯ç›®çš„,正如你们所见,用户可以申请成为[【开发者】](https://www.ucharts.cn/v2/#/agreement/developer),开发者不限制任何官网功能,并享有官方指导、开发、改造uCharts的权力,并且活动期间【返还超级会员费用】!我们想说的是,我们新版官网上线旨在希望更多的用户加入到开发者的队伍,我们共同去维护uCharts!
我们相信:星星之火可以燎原!
uCharts技术团队
2022.4.23
</font>
![logo](https://img-blog.csdnimg.cn/4a276226973841468c1be356f8d9438b.png)
[![star](https://gitee.com/uCharts/uCharts/badge/star.svg?theme=gvp)](https://gitee.com/uCharts/uCharts/stargazers)
[![fork](https://gitee.com/uCharts/uCharts/badge/fork.svg?theme=gvp)](https://gitee.com/uCharts/uCharts/members)
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![npm package](https://img.shields.io/npm/v/@qiun/ucharts.svg?style=flat-square)](https://www.npmjs.com/~qiun)
## uCharts简介
`uCharts`是一款基于`canvas API`开发的适用于所有前端应用的图表库,开发者编写一套代码,可运行到 Web、iOS、Android(基于 uni-app / taro ï¼‰ã€ä»¥åŠå„种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等更多支持 canvas API çš„平台。
## å®˜æ–¹ç½‘ç«™
## [https://www.ucharts.cn](https://www.ucharts.cn)
## å¿«é€Ÿä½“验
一套代码编到多个平台,依次扫描二维码,亲自体验uCharts图表跨平台效果!其他平台请自行编译。
![](https://www.ucharts.cn/images/web/guide/qrcode20220224.png)
## è‡´å¼€å‘者
感谢各位开发者`四年`来对秋云及uCharts的支持,uCharts的进步离不开各位开发者的鼓励与贡献。为更好的帮助各位开发者使用图表工具,我们推出了新版官网,增加了在线定制、问答社区、在线配置等一些增值服务,为确保您能更好的应用图表组件,建议您先`仔细阅读本页指南`以及`常见问题`,而不是下载下来`直接使用`。如仍然不能解决,请到`官网社区`或开通会员后加入`专属VIP会员群`提问将会很快得到回答。
## ç¤¾ç¾¤æ”¯æŒ
uCharts官方拥有4个2000人的QQ群及专属VIP会员群支持,庞大的用户量证明我们一直在努力,请各位放心使用!uCharts的开源图表组件的开发,团队付出了大量的时间与精力,经过四来的考验,不会有比较明显的bug,请各位放心使用。如果您有更好的想法,可以在`码云提交Pull Requests`以帮助更多开发者完成需求,再次感谢各位对uCharts的鼓励与支持!
#### å®˜æ–¹äº¤æµç¾¤
- äº¤æµç¾¤1:371774600(已满)
- äº¤æµç¾¤2:619841586(已满)
- äº¤æµç¾¤3:955340127(已满)
- äº¤æµç¾¤4:641669795
- å£ä»¤`uniapp`
#### ä¸“属VIP会员群
- å¼€é€šä¼šå‘˜åŽè¯¦è§ã€è´¦å·è¯¦æƒ…】页面中顶部的滚动通知
- å£ä»¤`您的用户ID`
## ç‰ˆæƒä¿¡æ¯
uCharts始终坚持开源,遵循 [Apache Licence 2.0](https://www.apache.org/licenses/LICENSE-2.0.html) å¼€æºåè®®ï¼Œæ„å‘³ç€æ‚¨æ— éœ€æ”¯ä»˜ä»»ä½•费用,即可将uCharts应用到您的产品中。
注意:这并不意味着您可以将uCharts应用到非法的领域,比如涉及赌博,暴力等方面。如因此产生纠纷或法律问题,uCharts相关方及秋云科技不承担任何责任。
## åˆä½œä¼™ä¼´
[![DIY官网](https://www.ucharts.cn/images/web/guide/links/diy-gw.png)](https://www.diygw.com/)
[![HasChat](https://www.ucharts.cn/images/web/guide/links/haschat.png)](https://gitee.com/howcode/has-chat)
[![uViewUI](https://www.ucharts.cn/images/web/guide/links/uView.png)](https://www.uviewui.com/)
[![图鸟UI](https://www.ucharts.cn/images/web/guide/links/tuniao.png)](https://ext.dcloud.net.cn/plugin?id=7088)
[![thorui](https://www.ucharts.cn/images/web/guide/links/thorui.png)](https://ext.dcloud.net.cn/publisher?id=202)
[![FirstUI](https://www.ucharts.cn/images/web/guide/links/first.png)](https://www.firstui.cn/)
[![nProUI](https://www.ucharts.cn/images/web/guide/links/nPro.png)](https://ext.dcloud.net.cn/plugin?id=5169)
[![GraceUI](https://www.ucharts.cn/images/web/guide/links/grace.png)](https://www.graceui.com/)
## æ›´æ–°è®°å½•
详见官网指南中说明,[点击此处查看](https://www.ucharts.cn/v2/#/guide/index?id=100)
## ç›¸å…³é“¾æŽ¥
- [uCharts官网](https://www.ucharts.cn)
- [DCloud插件市场地址](https://ext.dcloud.net.cn/plugin?id=271)
- [uCharts码云开源托管地址](https://gitee.com/uCharts/uCharts) [![star](https://gitee.com/uCharts/uCharts/badge/star.svg?theme=gvp)](https://gitee.com/uCharts/uCharts/stargazers)
- [uCharts npm开源地址](https://www.ucharts.cn)
- [ECharts官网](https://echarts.apache.org/zh/index.html)
- [ECharts配置手册](https://echarts.apache.org/zh/option.html)
- [图表组件在项目中的应用 ReportPlus数据报表](https://www.ucharts.cn/v2/#/layout/info?id=1)
uni_modules/qiun-data-charts/static/app-plus/echarts.min.js
uni_modules/qiun-data-charts/static/h5/echarts.min.js
uni_modules/uview-ui/LICENSE
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 www.uviewui.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
uni_modules/uview-ui/README.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,104 @@
<p align="center">
    <img alt="logo" src="https://uviewui.com/common/logo.png" width="120" height="120" style="margin-bottom: 10px;">
</p>
<h3 align="center" style="margin: 30px 0 30px;font-weight: bold;font-size:40px;">uView</h3>
<h3 align="center">多平台快速开发的UI框架</h3>
## è¯´æ˜Ž
uView UI,是[uni-app](https://uniapp.dcloud.io/)生态优秀的UI框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水
## ç‰¹æ€§
- å…¼å®¹å®‰å“,iOS,微信小程序,H5,QQ小程序,百度小程序,支付宝小程序,头条小程序
- 60+精选组件,功能丰富,多端兼容,让您快速集成,开箱即用
- ä¼—多贴心的JS利器,让您飞镖在手,召之即来,百步穿杨
- ä¼—多的常用页面和布局,让您专注逻辑,事半功倍
- è¯¦å°½çš„æ–‡æ¡£æ”¯æŒï¼ŒçŽ°ä»£åŒ–çš„æ¼”ç¤ºæ•ˆæžœ
- æŒ‰éœ€å¼•入,精简打包体积
## å®‰è£…
```bash
# npm方式安装,插件市场导入无需执行此命令
npm i uview-ui
```
## å¿«é€Ÿä¸Šæ‰‹
1. `main.js`引入uView库
```js
// main.js
import uView from 'uview-ui';
Vue.use(uView);
```
2. `App.vue`引入基础样式(注意style标签需声明scss属性支持)
```css
/* App.vue */
<style lang="scss">
@import "uview-ui/index.scss";
</style>
```
3. `uni.scss`引入全局scss变量文件
```css
/* uni.scss */
@import "uview-ui/theme.scss";
```
4. `pages.json`配置easycom规则(按需引入)
```js
// pages.json
{
    "easycom": {
        // npm安装的方式不需要前面的"@/",下载安装的方式需要"@/"
        // npm安装方式
        "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
        // ä¸‹è½½å®‰è£…方式
        // "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
    },
    // æ­¤ä¸ºæœ¬èº«å·²æœ‰çš„内容
    "pages": [
        // ......
    ]
}
```
请通过[快速上手](https://www.uviewui.com/components/quickstart.html)了解更详细的内容
## ä½¿ç”¨æ–¹æ³•
配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。
```html
<template>
    <u-button text="按钮"></u-button>
</template>
```
请通过[快速上手](https://www.uviewui.com/components/quickstart.html)了解更详细的内容
## é“¾æŽ¥
- [官方文档](https://www.uviewui.com/)
- [更新日志](https://www.www.uviewui.com/components/changelog.html)
- [升级指南](https://www.uviewui.com/components/changelog.html)
- [关于我们](https://www.uviewui.com/cooperation/about.html)
## é¢„览
您可以通过**微信**扫码,查看最佳的演示效果。
<br>
<br>
<img src="https://uviewui.com/common/weixin_mini_qrcode.png" width="220" height="220" >
## æèµ uView的研发
uView文档和源码全部开源免费,如果您认为uView帮到了您的开发工作,您可以捐赠uView的研发工作,捐赠无门槛,哪怕是一杯可乐也好(相信这比打赏主播更有意义)。
<img src="https://uviewui.com/common/alipay.png" width="220" ><img style="margin-left: 100px;" src="https://uviewui.com/common/wechat.png" width="220" >
## ç‰ˆæƒä¿¡æ¯
uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。
uni_modules/uview-ui/changelog.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,326 @@
## 2.0.31(2022-04-19)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¿®å¤`upload`在`vue`页面上传成功后没有成功标志的问题
2. è§£å†³æ¼”示项目中微信小程序模拟上传图片一直出于上传中问题
3. ä¿®å¤`u-code-input`组件在`nvue`页面编译到`app`平台上光标异常问题(`app`去除此功能)
4. ä¿®å¤`actionSheet`组件标题关闭按钮点击事件名称错误的问题
5. å…¶ä»–修复
## 2.0.30(2022-04-04)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. `u-rate`增加`readonly`属性
2. `tabs`滑块支持设置背景图片
3. ä¿®å¤`u-subsection` `mode`为`subsection`时,滑块样式不正确的问题
4. `u-code-input`添加光标效果动画
5. ä¿®å¤`popup`的`open`事件不触发
6. ä¿®å¤`u-flex-column`无效的问题
7. ä¿®å¤`u-datetime-picker`索引在特定场合异常问题
8. ä¿®å¤`u-datetime-picker`最小时间字符串模板错误问题
9. `u-swiper`添加`m3u8`验证
10. `u-swiper`修改判断image和video逻辑
11. ä¿®å¤`swiper`无法使用本地图片问题,增加`type`参数
12. ä¿®å¤`u-row-notice`格式错误问题
13. ä¿®å¤`u-switch`组件当`unit`为`rpx`时,`nodeStyle`消失的问题
14. ä¿®å¤`datetime-picker`组件`showToolbar`与`visibleItemCount`属性无效的问题
15. ä¿®å¤`upload`组件条件编译位置判断错误,导致`previewImage`属性设置为`false`时,整个组件都会被隐藏的问题
16. ä¿®å¤`u-checkbox-group`设置`shape`属性无效的问题
17. ä¿®å¤`u-upload`的`capture`传入字符串的时候不生效的问题
18. ä¿®å¤`u-action-sheet`组件,关闭事件逻辑错误的问题
19. ä¿®å¤`u-list`触顶事件的触发错误的问题
20. ä¿®å¤`u-text`只有手机号可拨打的问题
21. ä¿®å¤`u-textarea`不能换行的问题
22. å…¶ä»–修复
## 2.0.29(2022-03-13)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¿®å¤`u--text`组件设置`decoration`属性未生效的问题
2. ä¿®å¤`u-datetime-picker`使用`formatter`后返回值不正确
3. ä¿®å¤`u-datetime-picker` `intercept` å¯èƒ½ä¸ºundefined
4. ä¿®å¤å·²è®¾ç½®å•位 uni..config.unit = 'rpx'时,线型指示器 `transform` çš„位置翻倍,导致指示器超出宽度
5. ä¿®å¤mixin中bem方法生成的类名在支付宝和字节小程序中失效
6. ä¿®å¤é»˜è®¤å€¼ä¼ å€¼ä¸ºç©ºçš„æ—¶å€™ï¼Œæ‰“å¼€`u-datetime-picker`报错,不能选中第一列时间的bug
7. ä¿®å¤`u-datetime-picker`使用`formatter`后返回值不正确
8. ä¿®å¤`u-image`组件`loading`无效果的问题
9. ä¿®å¤`config.unit`属性设为`rpx`时,导航栏占用高度不足导致塌陷的问题
10. ä¿®å¤`u-datetime-picker`组件`itemHeight`无效问题
11. å…¶ä»–修复
## 2.0.28(2022-02-22)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. search组件新增searchIconSize属性
2. å…¼å®¹Safari/Webkit中传入时间格式如2022-02-17 12:00:56
3. ä¿®å¤text value.js åˆ¤æ–­æ—¥æœŸå‡ºformat错误问题
4. priceFormat格式化金额出现精度错误
5. priceFormat在部分情况下出现精度损失问题
6. ä¼˜åŒ–表单rules提示
7. ä¿®å¤avatar组件src为空时,展示状态不对
8. å…¶ä»–修复
## 2.0.27(2022-01-28)
# uView2.0重磅发布,利剑出鞘,一统江湖
1.样式修复
## 2.0.26(2022-01-28)
# uView2.0重磅发布,利剑出鞘,一统江湖
1.样式修复
## 2.0.25(2022-01-27)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¿®å¤text组件mode=price时,可能会导致精度错误的问题
2. æ·»åŠ $u.setConfig()方法,可设置uView内置的config, props, zIndex, color属性,详见:[修改uView内置配置方案](https://uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
3. ä¼˜åŒ–form组件在errorType=toast时,如果输入错误页面会有抖动的问题
4. ä¿®å¤$u.addUnit()对配置默认单位可能无效的问题
## 2.0.24(2022-01-25)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¿®å¤swiper在current指定非0时缩放有误
2. ä¿®å¤u-icon添加stop属性的时候报错
3. ä¼˜åŒ–遗留的通过正则判断rpx单位的问题
4. ä¼˜åŒ–Layout布局 vue使用gutter时,会超出固定区域
5. ä¼˜åŒ–search组件高度单位问题(rpx -> px)
6. ä¿®å¤u-image slot åŠ è½½å’Œé”™è¯¯çš„å›¾ç‰‡å¤±åŽ»äº†é«˜åº¦
7. ä¿®å¤u-index-list中footer插槽与header插槽存在性判断错误
8. ä¿®å¤éƒ¨åˆ†æœºåž‹ä¸‹u-popup关闭时会闪烁
9. ä¿®å¤u-image在nvue-app下失去宽高
10. ä¿®å¤u-popup运行报错
11. ä¿®å¤u-tooltip报错
12. ä¿®å¤box-sizing在app下的警告
13. ä¿®å¤u-navbar在小程序中报运行时错误
14. å…¶ä»–修复
## 2.0.23(2022-01-24)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¿®å¤image组件在hx3.3.9的nvue下可能会显示异常的问题
2. ä¿®å¤col组件gutter参数带rpx单位处理不正确的问题
3. ä¿®å¤text组件单行时无法显示省略号的问题
4. navbar添加titleStyle参数
5. å‡çº§åˆ°hx3.3.9可消除nvue下控制台样式警告的问题
## 2.0.22(2022-01-19)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. $u.page()方法优化,避免在特殊场景可能报错的问题
2. picker组件添加immediateChange参数
3. æ–°å¢ž$u.pages()方法
## 2.0.21(2022-01-19)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¼˜åŒ–:form组件在用户设置rules的时候提示用户model必传
2. ä¼˜åŒ–遗留的通过正则判断rpx单位的问题
3. ä¿®å¤å¾®ä¿¡å°ç¨‹åºçŽ¯å¢ƒä¸­tabbar组件开启safeAreaInsetBottom属性后,placeholder高度填充不正确
4. ä¿®å¤swiper在current指定非0时缩放有误
5. ä¿®å¤u-icon添加stop属性的时候报错
6. ä¿®å¤upload组件在accept=all的时候没有作用
7. ä¿®å¤åœ¨text组件mode为phone时call属性无效的问题
8. å¤„理u-form clearValidate方法
9. å…¶ä»–修复
## 2.0.20(2022-01-14)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¿®å¤calendar默认会选择一个日期,如果直接点确定的话,无法取到值的问题
2. ä¿®å¤Slider缺少disabled props è¿˜æœ‰æ³¨é‡Š
3. ä¿®å¤u-notice-bar点击事件无法拿到index索引值的问题
4. ä¿®å¤u-collapse-item在vue文件下,app端自定义插槽不生效的问题
5. ä¼˜åŒ–头像为空时显示默认头像
6. ä¿®å¤å›¾ç‰‡åœ°å€èµ‹å€¼åŽåˆ¤æ–­åŠ è½½çŠ¶æ€ä¸ºå®Œæˆé—®é¢˜
7. ä¿®å¤æ—¥åŽ†æ»šåŠ¨åˆ°é»˜è®¤æ—¥æœŸæœˆä»½åŒºåŸŸ
8. search组件暴露点击左边icon事件
9. ä¿®å¤u-form clearValidate方法不生效
10. upload h5端增加返回文件参数(文件的name参数)
11. å¤„理upload选择文件后url为blob类型无法预览的问题
12. u-code-input ä¿®å¤è¾“入框没有往左移出一半屏幕
13. ä¿®å¤Upload上传 disabled为true时,控制台报hoverClass类型错误
14. ä¸´æ—¶å¤„理ios app下grid点击坍塌问题
15. å…¶ä»–修复
## 2.0.19(2021-12-29)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¼˜åŒ–微信小程序包体积可在微信中预览,请升级HbuilderX3.3.4,同时在“运行->运行到小程序模拟器”中勾选“运行时是否压缩代码”
2. ä¼˜åŒ–微信小程序setData性能,处理某些方法如$u.route()无法在模板中使用的问题
3. navbar添加autoBack参数
4. å…è®¸avatar组件的事件冒泡
5. ä¿®å¤cell组件报错问题
6. å…¶ä»–修复
## 2.0.18(2021-12-28)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¿®å¤app端编译报错问题
2. é‡æ–°å¤„理微信小程序端setData过大的性能问题
3. ä¿®å¤è¾¹æ¡†é—®é¢˜
4. ä¿®å¤æœ€å¤§æœ€å°æœˆä»½ä¸å¤§äºŽ0则没有数据出现的问题
5. ä¿®å¤SwipeAction微信小程序端无法上下滑动问题
6. ä¿®å¤input的placeholder在小程序端默认显示为true问题
7. ä¿®å¤divider组件click事件无效问题
8. ä¿®å¤u-code-input maxlength å±žæ€§å€¼ä¸º String ç±»åž‹æ—¶æ˜¾ç¤ºå¼‚常
9. ä¿®å¤å½“ grid只有 1到2时 åœ¨å°ç¨‹åºç«¯algin设置无效的问题
10. å¤„理form-item的label为top时,取消错误提示的左边距
11. å…¶ä»–修复
## 2.0.17(2021-12-26)
## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. è§£å†³HBuilderX3.3.3.20211225版本导致的样式问题
2. calendar日历添加monthNum参数
3. navbar添加center slot
## 2.0.16(2021-12-25)
## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. è§£å†³å¾®ä¿¡å°ç¨‹åºsetData性能问题
2. ä¿®å¤count-down组件change事件不触发问题
## 2.0.15(2021-12-21)
## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¿®å¤Cell单元格titleWidth无效
2. ä¿®å¤cheakbox组件ischecked不更新
3. ä¿®å¤keyboard是否显示"."按键默认值问题
4. ä¿®å¤number-keyboard是否显示键盘的"."符号问题
5. ä¿®å¤Input输入框 readonly无效
6. ä¿®å¤u-avatar å¯¼è‡´æ‰“包app、H5时候报错问题
7. ä¿®å¤Upload上传deletable无效
8. ä¿®å¤upload当设置maxSize时无效的问题
9. ä¿®å¤tabs lineWidth传入带单位的字符串的时候偏移量计算错误问题
10. ä¿®å¤rate组件在有padding的view内,显示的星星位置和可触摸区域不匹配,无法正常选中星星
## 2.0.13(2021-12-14)
## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¿®å¤é…ç½®é»˜è®¤å•位为rpx可能会导致自定义导航栏高度异常的问题
## 2.0.12(2021-12-14)
## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¿®å¤tabs组件在vue环境下划线消失的问题
2. ä¿®å¤upload组件在安卓小程序无法选择视频的问题
3. æ·»åŠ uni.$u.config.unit配置,用于配置参数默认单位,详见:[默认单位配置](https://www.uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
4. ä¿®å¤textarea组件在没绑定v-model时,字符统计不生效问题
5. ä¿®å¤nvue下控制是否出现滚动条失效问题
## 2.0.11(2021-12-13)
## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. text组件align参数无效的问题
2. subsection组件添加keyName参数
3. upload组件无法判断[Object file]类型的问题
4. å¤„理notify层级过低问题
5. codeInput组件添加disabledDot参数
6. å¤„理actionSheet组件round参数无效的问题
7. calendar组件添加round参数用于控制圆角值
8. å¤„理swipeAction组件在vue环境下默认被打开的问题
9. button组件的throttleTime节流参数无效的问题
10. è§£å†³u-notify手动关闭方法close()无效的问题
11. input组件readonly不生效问题
12. tag组件type参数为info不生效问题
## 2.0.10(2021-12-08)
## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¿®å¤button sendMessagePath属性不生效
2. ä¿®å¤DatetimePicker选择器title无效
3. ä¿®å¤u-toast设置loading=true不生效
4. ä¿®å¤u-text金额模式传0报错
5. ä¿®å¤u-toast组件的icon属性配置不生效
6. button的icon在特殊场景下的颜色优化
7. IndexList优化,增加#
## 2.0.9(2021-12-01)
## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¼˜åŒ–swiper的height支持100%值(仅vue有效),修复嵌入视频时click事件无法触发的问题
2. ä¼˜åŒ–tabs组件对list值为空的判断,或者动态变化list时重新计算相关尺寸的问题
3. ä¼˜åŒ–datetime-picker组件逻辑,让其后续打开的默认值为上一次的选中值,需要通过v-model绑定值才有效
4. ä¿®å¤upload内嵌在其他组件中,选择图片可能不会换行的问题
## 2.0.8(2021-12-01)
## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¿®å¤toast的position参数无效问题
2. å¤„理input在ios nvue上无法获得焦点的问题
3. avatar-group组件添加extraValue参数,让剩余展示数量可手动控制
4. tabs组件添加keyName参数用于配置从对象中读取的键名
5. å¤„理text组件名字脱敏默认配置无效的问题
6. å¤„理picker组件item文本太长换行问题
## 2.0.7(2021-11-30)
## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. ä¿®å¤radio和checkbox动态改变v-model无效的问题。
2. ä¼˜åŒ–form规则validator在微信小程序用法
3. ä¿®å¤backtop组件mode参数在微信小程序无效的问题
4. å¤„理Album的previewFullImage属性无效的问题
5. å¤„理u-datetime-picker组件mode='time'在选择改变时间时,控制台报错的问题
## 2.0.6(2021-11-27)
## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. å¤„理tag组件在vue下边框无效的问题。
2. å¤„理popup组件圆角参数可能无效的问题。
3. å¤„理tabs组件lineColor参数可能无效的问题。
4. propgress组件在值很小时,显示异常的问题。
## 2.0.5(2021-11-25)
## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. calendar在vue下显示异常问题。
2. form组件labelPosition和errorType参数无效的问题
3. input组件inputAlign无效的问题
4. å…¶ä»–一些修复
## 2.0.4(2021-11-23)
## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
# uView2.0重磅发布,利剑出鞘,一统江湖
0. input组件缺失@confirm事件,以及subfix和prefix无效问题
1. component.scss文件样式在vue下干扰全局布局问题
2. ä¿®å¤subsection在vue环境下表现异常的问题
3. tag组件的bgColor等参数无效的问题
4. upload组件不换行的问题
5. å…¶ä»–的一些修复处理
## 2.0.3(2021-11-16)
## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. uView2.0已实现全面兼容nvue
2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
3. ç›®å‰uView2.0为公测阶段,相关细节可能会有变动
4. æˆ‘们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
5. å¤„理modal的confirm回调事件拼写错误问题
6. å¤„理input组件@input事件参数错误问题
7. å…¶ä»–一些修复
## 2.0.2(2021-11-16)
## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. uView2.0已实现全面兼容nvue
2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
3. ç›®å‰uView2.0为公测阶段,相关细节可能会有变动
4. æˆ‘们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
5. ä¿®å¤input组件formatter参数缺失问题
6. ä¼˜åŒ–loading-icon组件的scss写法问题,防止不兼容新版本scss
## 2.0.0(2020-11-15)
## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
# uView2.0重磅发布,利剑出鞘,一统江湖
1. uView2.0已实现全面兼容nvue
2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
3. ç›®å‰uView2.0为公测阶段,相关细节可能会有变动
4. æˆ‘们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
5. ä¿®å¤input组件formatter参数缺失问题
uni_modules/uview-ui/components/u--form/u--form.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,78 @@
<template>
    <uvForm
        ref="uForm"
        :model="model"
        :rules="rules"
        :errorType="errorType"
        :borderBottom="borderBottom"
        :labelPosition="labelPosition"
        :labelWidth="labelWidth"
        :labelAlign="labelAlign"
        :labelStyle="labelStyle"
        :customStyle="customStyle"
    >
        <slot />
    </uvForm>
</template>
<script>
    /**
     * æ­¤ç»„件存在的理由是,在nvue下,u-form被uni-app官方占用了,u-form在nvue中相当于form组件
     * æ‰€ä»¥åœ¨nvue下,取名为u--form,内部其实还是u-form.vue,只不过做一层中转
     */
    import uvForm from '../u-form/u-form.vue';
    import props from '../u-form/props.js'
    export default {
        // #ifdef MP-WEIXIN
        name: 'u-form',
        // #endif
        // #ifndef MP-WEIXIN
        name: 'u--form',
        // #endif
        mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
        components: {
            uvForm
        },
        created() {
            this.children = []
        },
        methods: {
            // æ‰‹åŠ¨è®¾ç½®æ ¡éªŒçš„è§„åˆ™ï¼Œå¦‚æžœè§„åˆ™ä¸­æœ‰å‡½æ•°çš„è¯ï¼Œå¾®ä¿¡å°ç¨‹åºä¸­ä¼šè¿‡æ»¤æŽ‰ï¼Œæ‰€ä»¥åªèƒ½æ‰‹åŠ¨è°ƒç”¨è®¾ç½®è§„åˆ™
            setRules(rules) {
                this.$refs.uForm.setRules(rules)
            },
            validate() {
                /**
                 * åœ¨å¾®ä¿¡å°ç¨‹åºä¸­ï¼Œé€šè¿‡this.$parent拿到的父组件是u--form,而不是其内嵌的u-form
                 * å¯¼è‡´åœ¨u-form组件中,拿不到对应的children数组,从而校验无效,所以这里每次调用u-form组件中的
                 * å¯¹åº”方法的时候,在小程序中都先将u--form的children赋值给u-form中的children
                 */
                // #ifdef MP-WEIXIN
                this.setMpData()
                // #endif
                return this.$refs.uForm.validate()
            },
            validateField(value, callback) {
                // #ifdef MP-WEIXIN
                this.setMpData()
                // #endif
                return this.$refs.uForm.validateField(value, callback)
            },
            resetFields() {
                // #ifdef MP-WEIXIN
                this.setMpData()
                // #endif
                return this.$refs.uForm.resetFields()
            },
            clearValidate(props) {
                // #ifdef MP-WEIXIN
                this.setMpData()
                // #endif
                return this.$refs.uForm.clearValidate(props)
            },
            setMpData() {
                this.$refs.uForm.children = this.children
            }
        },
    }
</script>
uni_modules/uview-ui/components/u--image/u--image.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
<template>
    <uvImage
        :src="src"
        :mode="mode"
        :width="width"
        :height="height"
        :shape="shape"
        :radius="radius"
        :lazyLoad="lazyLoad"
        :showMenuByLongpress="showMenuByLongpress"
        :loadingIcon="loadingIcon"
        :errorIcon="errorIcon"
        :showLoading="showLoading"
        :showError="showError"
        :fade="fade"
        :webp="webp"
        :duration="duration"
        :bgColor="bgColor"
        :customStyle="customStyle"
        @click="$emit('click')"
        @error="$emit('error')"
        @load="$emit('load')"
    >
        <template v-slot:loading>
            <slot name="loading"></slot>
        </template>
        <template v-slot:error>
            <slot name="error"></slot>
        </template>
    </uvImage>
</template>
<script>
    /**
     * æ­¤ç»„件存在的理由是,在nvue下,u-image被uni-app官方占用了,u-image在nvue中相当于image组件
     * æ‰€ä»¥åœ¨nvue下,取名为u--image,内部其实还是u-iamge.vue,只不过做一层中转
     */
    import uvImage from '../u-image/u-image.vue';
    import props from '../u-image/props.js';
    export default {
        name: 'u--image',
        mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
        components: {
            uvImage
        },
    }
</script>
uni_modules/uview-ui/components/u--input/u--input.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
<template>
    <uvInput
        :value="value"
        :type="type"
        :fixed="fixed"
        :disabled="disabled"
        :disabledColor="disabledColor"
        :clearable="clearable"
        :password="password"
        :maxlength="maxlength"
        :placeholder="placeholder"
        :placeholderClass="placeholderClass"
        :placeholderStyle="placeholderStyle"
        :showWordLimit="showWordLimit"
        :confirmType="confirmType"
        :confirmHold="confirmHold"
        :holdKeyboard="holdKeyboard"
        :focus="focus"
        :autoBlur="autoBlur"
        :disableDefaultPadding="disableDefaultPadding"
        :cursor="cursor"
        :cursorSpacing="cursorSpacing"
        :selectionStart="selectionStart"
        :selectionEnd="selectionEnd"
        :adjustPosition="adjustPosition"
        :inputAlign="inputAlign"
        :fontSize="fontSize"
        :color="color"
        :prefixIcon="prefixIcon"
        :suffixIcon="suffixIcon"
        :suffixIconStyle="suffixIconStyle"
        :prefixIconStyle="prefixIconStyle"
        :border="border"
        :readonly="readonly"
        :shape="shape"
        :customStyle="customStyle"
        :formatter="formatter"
        @focus="$emit('focus')"
        @blur="$emit('blur')"
        @keyboardheightchange="$emit('keyboardheightchange')"
        @change="e => $emit('change', e)"
        @input="e => $emit('input', e)"
        @confirm="e => $emit('confirm', e)"
        @clear="$emit('clear')"
        @click="$emit('click')"
    >
        <!-- #ifdef MP -->
        <slot name="prefix"></slot>
        <slot name="suffix"></slot>
        <!-- #endif -->
        <!-- #ifndef MP -->
        <slot name="prefix" slot="prefix"></slot>
        <slot name="suffix" slot="suffix"></slot>
        <!-- #endif -->
    </uvInput>
</template>
<script>
    /**
     * æ­¤ç»„件存在的理由是,在nvue下,u-input被uni-app官方占用了,u-input在nvue中相当于input组件
     * æ‰€ä»¥åœ¨nvue下,取名为u--input,内部其实还是u-input.vue,只不过做一层中转
     */
    import uvInput from '../u-input/u-input.vue';
    import props from '../u-input/props.js'
    export default {
        name: 'u--input',
        mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
        components: {
            uvInput
        },
    }
</script>
uni_modules/uview-ui/components/u--text/u--text.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
<template>
    <uvText
        :type="type"
        :show="show"
        :text="text"
        :prefixIcon="prefixIcon"
        :suffixIcon="suffixIcon"
        :mode="mode"
        :href="href"
        :format="format"
        :call="call"
        :openType="openType"
        :bold="bold"
        :block="block"
        :lines="lines"
        :color="color"
        :decoration="decoration"
        :size="size"
        :iconStyle="iconStyle"
        :margin="margin"
        :lineHeight="lineHeight"
        :align="align"
        :wordWrap="wordWrap"
        :customStyle="customStyle"
        @click="$emit('click')"
    ></uvText>
</template>
<script>
/**
 * æ­¤ç»„件存在的理由是,在nvue下,u-text被uni-app官方占用了,u-text在nvue中相当于input组件
 * æ‰€ä»¥åœ¨nvue下,取名为u--input,内部其实还是u-text.vue,只不过做一层中转
 * ä¸ä½¿ç”¨v-bind="$attrs",而是分开独立写传参,是因为微信小程序不支持此写法
 */
import uvText from "../u-text/u-text.vue";
import props from "../u-text/props.js";
export default {
    name: "u--text",
    mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
    components: {
        uvText,
    },
};
</script>
uni_modules/uview-ui/components/u--textarea/u--textarea.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
<template>
    <uvTextarea
        :value="value"
        :placeholder="placeholder"
        :height="height"
        :confirmType="confirmType"
        :disabled="disabled"
        :count="count"
        :focus="focus"
        :autoHeight="autoHeight"
        :fixed="fixed"
        :cursorSpacing="cursorSpacing"
        :cursor="cursor"
        :showConfirmBar="showConfirmBar"
        :selectionStart="selectionStart"
        :selectionEnd="selectionEnd"
        :adjustPosition="adjustPosition"
        :disableDefaultPadding="disableDefaultPadding"
        :holdKeyboard="holdKeyboard"
        :maxlength="maxlength"
        :border="border"
        :customStyle="customStyle"
        :formatter="formatter"
        @focus="e => $emit('focus')"
        @blur="e => $emit('blur')"
        @linechange="e => $emit('linechange', e)"
        @confirm="e => $emit('confirm')"
        @input="e => $emit('input', e)"
        @keyboardheightchange="e => $emit('keyboardheightchange')"
    ></uvTextarea>
</template>
<script>
    /**
     * æ­¤ç»„件存在的理由是,在nvue下,u--textarea被uni-app官方占用了,u-textarea在nvue中相当于textarea组件
     * æ‰€ä»¥åœ¨nvue下,取名为u--textarea,内部其实还是u-textarea.vue,只不过做一层中转
     */
    import uvTextarea from '../u-textarea/u-textarea.vue';
    import props from '../u-textarea/props.js'
    export default {
        name: 'u--textarea',
        mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
        components: {
            uvTextarea
        },
    }
</script>
uni_modules/uview-ui/components/u-action-sheet/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
export default {
    props: {
        // æ“ä½œèœå•是否展示 ï¼ˆé»˜è®¤false)
        show: {
            type: Boolean,
            default: uni.$u.props.actionSheet.show
        },
        // æ ‡é¢˜
        title: {
            type: String,
            default: uni.$u.props.actionSheet.title
        },
        // é€‰é¡¹ä¸Šæ–¹çš„æè¿°ä¿¡æ¯
        description: {
            type: String,
            default: uni.$u.props.actionSheet.description
        },
        // æ•°æ®
        actions: {
            type: Array,
            default: uni.$u.props.actionSheet.actions
        },
        // å–消按钮的文字,不为空时显示按钮
        cancelText: {
            type: String,
            default: uni.$u.props.actionSheet.cancelText
        },
        // ç‚¹å‡»æŸä¸ªèœå•项时是否关闭弹窗
        closeOnClickAction: {
            type: Boolean,
            default: uni.$u.props.actionSheet.closeOnClickAction
        },
        // å¤„理底部安全区(默认true)
        safeAreaInsetBottom: {
            type: Boolean,
            default: uni.$u.props.actionSheet.safeAreaInsetBottom
        },
        // å°ç¨‹åºçš„æ‰“开方式
        openType: {
            type: String,
            default: uni.$u.props.actionSheet.openType
        },
        // ç‚¹å‡»é®ç½©æ˜¯å¦å…è®¸å…³é—­ (默认true)
        closeOnClickOverlay: {
            type: Boolean,
            default: uni.$u.props.actionSheet.closeOnClickOverlay
        },
        // åœ†è§’值
        round: {
            type: [Boolean, String, Number],
            default: uni.$u.props.actionSheet.round
        }
    }
}
uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,278 @@
<template>
    <u-popup
        :show="show"
        mode="bottom"
        @close="closeHandler"
        :safeAreaInsetBottom="safeAreaInsetBottom"
        :round="round"
    >
        <view class="u-action-sheet">
            <view
                class="u-action-sheet__header"
                v-if="title"
            >
                <text class="u-action-sheet__header__title u-line-1">{{title}}</text>
                <view
                    class="u-action-sheet__header__icon-wrap"
                    @tap.stop="cancel"
                >
                    <u-icon
                        name="close"
                        size="17"
                        color="#c8c9cc"
                        bold
                    ></u-icon>
                </view>
            </view>
            <text
                class="u-action-sheet__description"
                :style="[{
                    marginTop: `${title && description ? 0 : '18px'}`
                }]"
                v-if="description"
            >{{description}}</text>
            <slot>
                <u-line v-if="description"></u-line>
                <view class="u-action-sheet__item-wrap">
                    <template v-for="(item, index) in actions">
                        <!-- #ifdef MP -->
                        <button
                            :key="index"
                            class="u-reset-button"
                            :openType="item.openType"
                            @getuserinfo="onGetUserInfo"
                            @contact="onContact"
                            @getphonenumber="onGetPhoneNumber"
                            @error="onError"
                            @launchapp="onLaunchApp"
                            @opensetting="onOpenSetting"
                            :lang="lang"
                            :session-from="sessionFrom"
                            :send-message-title="sendMessageTitle"
                            :send-message-path="sendMessagePath"
                            :send-message-img="sendMessageImg"
                            :show-message-card="showMessageCard"
                            :app-parameter="appParameter"
                            @tap="selectHandler(index)"
                            :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
                        >
                            <!-- #endif -->
                            <view
                                class="u-action-sheet__item-wrap__item"
                                @tap.stop="selectHandler(index)"
                                :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
                                :hover-stay-time="150"
                            >
                                <template v-if="!item.loading">
                                    <text
                                        class="u-action-sheet__item-wrap__item__name"
                                        :style="[itemStyle(index)]"
                                    >{{ item.name }}</text>
                                    <text
                                        v-if="item.subname"
                                        class="u-action-sheet__item-wrap__item__subname"
                                    >{{ item.subname }}</text>
                                </template>
                                <u-loading-icon
                                    v-else
                                    custom-class="van-action-sheet__loading"
                                    size="18"
                                    mode="circle"
                                />
                            </view>
                            <!-- #ifdef MP -->
                        </button>
                        <!-- #endif -->
                        <u-line v-if="index !== actions.length - 1"></u-line>
                    </template>
                </view>
            </slot>
            <u-gap
                bgColor="#eaeaec"
                height="6"
                v-if="cancelText"
            ></u-gap>
            <view hover-class="u-action-sheet--hover">
                <text
                    @touchmove.stop.prevent
                    :hover-stay-time="150"
                    v-if="cancelText"
                    class="u-action-sheet__cancel-text"
                    @tap="cancel"
                >{{cancelText}}</text>
            </view>
        </view>
    </u-popup>
</template>
<script>
    import openType from '../../libs/mixin/openType'
    import button from '../../libs/mixin/button'
    import props from './props.js';
    /**
     * ActionSheet æ“ä½œèœå•
     * @description æœ¬ç»„件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。
     * @tutorial https://www.uviewui.com/components/actionSheet.html
     *
     * @property {Boolean}            show                æ“ä½œèœå•是否展示 ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String}            title                æ“ä½œèœå•标题
     * @property {String}            description            é€‰é¡¹ä¸Šæ–¹çš„æè¿°ä¿¡æ¯
     * @property {Array<Object>}    actions                æŒ‰é’®çš„æ–‡å­—数组,见官方文档示例
     * @property {String}            cancelText            å–消按钮的提示文字,不为空时显示按钮
     * @property {Boolean}            closeOnClickAction    ç‚¹å‡»æŸä¸ªèœå•项时是否关闭弹窗 ï¼ˆé»˜è®¤ true ï¼‰
     * @property {Boolean}            safeAreaInsetBottom    å¤„理底部安全区 ï¼ˆé»˜è®¤ true ï¼‰
     * @property {String}            openType            å°ç¨‹åºçš„æ‰“开方式 (contact | launchApp | getUserInfo | openSetting ï½œgetPhoneNumber ï½œerror )
     * @property {Boolean}            closeOnClickOverlay    ç‚¹å‡»é®ç½©æ˜¯å¦å…è®¸å…³é—­  (默认 true )
     * @property {Number|String}    round                åœ†è§’值,默认无圆角  (默认 0 )
     * @property {String}            lang                æŒ‡å®šè¿”回用户信息的语言,zh_CN ç®€ä½“中文,zh_TW ç¹ä½“中文,en è‹±æ–‡
     * @property {String}            sessionFrom            ä¼šè¯æ¥æºï¼ŒopenType="contact"时有效
     * @property {String}            sendMessageTitle    ä¼šè¯å†…消息卡片标题,openType="contact"时有效
     * @property {String}            sendMessagePath        ä¼šè¯å†…消息卡片点击跳转小程序路径,openType="contact"时有效
     * @property {String}            sendMessageImg        ä¼šè¯å†…消息卡片图片,openType="contact"时有效
     * @property {Boolean}            showMessageCard        æ˜¯å¦æ˜¾ç¤ºä¼šè¯å†…消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效 ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String}            appParameter        æ‰“å¼€ APP æ—¶ï¼Œå‘ APP ä¼ é€’的参数,openType=launchApp æ—¶æœ‰æ•ˆ
     *
     * @event {Function} select            ç‚¹å‡»ActionSheet列表项时触发
     * @event {Function} close            ç‚¹å‡»å–消按钮时触发
     * @event {Function} getuserinfo    ç”¨æˆ·ç‚¹å‡»è¯¥æŒ‰é’®æ—¶ï¼Œä¼šè¿”回获取到的用户信息,回调的 detail æ•°æ®ä¸Ž wx.getUserInfo è¿”回的一致,openType="getUserInfo"时有效
     * @event {Function} contact        å®¢æœæ¶ˆæ¯å›žè°ƒï¼ŒopenType="contact"时有效
     * @event {Function} getphonenumber    èŽ·å–ç”¨æˆ·æ‰‹æœºå·å›žè°ƒï¼ŒopenType="getPhoneNumber"时有效
     * @event {Function} error            å½“使用开放能力时,发生错误的回调,openType="error"时有效
     * @event {Function} launchapp        æ‰“å¼€ APP æˆåŠŸçš„å›žè°ƒï¼ŒopenType="launchApp"时有效
     * @event {Function} opensetting    åœ¨æ‰“开授权设置页后回调,openType="openSetting"时有效
     * @example <u-action-sheet :actions="list" :title="title" :show="show"></u-action-sheet>
     */
    export default {
        name: "u-action-sheet",
        // ä¸€äº›props参数和methods方法,通过mixin混入,因为其他文件也会用到
        mixins: [openType, button, uni.$u.mixin, props],
        data() {
            return {
            }
        },
        computed: {
            // æ“ä½œé¡¹ç›®çš„æ ·å¼
            itemStyle() {
                return (index) => {
                    let style = {};
                    if (this.actions[index].color) style.color = this.actions[index].color
                    if (this.actions[index].fontSize) style.fontSize = uni.$u.addUnit(this.actions[index].fontSize)
                    // é€‰é¡¹è¢«ç¦ç”¨çš„æ ·å¼
                    if (this.actions[index].disabled) style.color = '#c0c4cc'
                    return style;
                }
            },
        },
        methods: {
            closeHandler() {
                // å…è®¸ç‚¹å‡»é®ç½©å…³é—­æ—¶ï¼Œæ‰å‘出close事件
                if(this.closeOnClickOverlay) {
                    this.$emit('close')
                }
            },
            // ç‚¹å‡»å–消按钮
            cancel() {
                this.$emit('close')
            },
            selectHandler(index) {
                const item = this.actions[index]
                if (item && !item.disabled && !item.loading) {
                    this.$emit('select', item)
                    if (this.closeOnClickAction) {
                        this.$emit('close')
                    }
                }
            },
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    $u-action-sheet-reset-button-width:100% !default;
    $u-action-sheet-title-font-size: 16px !default;
    $u-action-sheet-title-padding: 12px 30px !default;
    $u-action-sheet-title-color: $u-main-color !default;
    $u-action-sheet-header-icon-wrap-right:15px !default;
    $u-action-sheet-header-icon-wrap-top:15px !default;
    $u-action-sheet-description-font-size:13px !default;
    $u-action-sheet-description-color:14px !default;
    $u-action-sheet-description-margin: 18px 15px !default;
    $u-action-sheet-item-wrap-item-padding:15px !default;
    $u-action-sheet-item-wrap-name-font-size:16px !default;
    $u-action-sheet-item-wrap-subname-font-size:13px !default;
    $u-action-sheet-item-wrap-subname-color: #c0c4cc !default;
    $u-action-sheet-item-wrap-subname-margin-top:10px !default;
    $u-action-sheet-cancel-text-font-size:16px !default;
    $u-action-sheet-cancel-text-color:$u-content-color !default;
    $u-action-sheet-cancel-text-font-size:15px !default;
    $u-action-sheet-cancel-text-hover-background-color:rgb(242, 243, 245) !default;
    .u-reset-button {
        width: $u-action-sheet-reset-button-width;
    }
    .u-action-sheet {
        text-align: center;
        &__header {
            position: relative;
            padding: $u-action-sheet-title-padding;
            &__title {
                font-size: $u-action-sheet-title-font-size;
                color: $u-action-sheet-title-color;
                font-weight: bold;
                text-align: center;
            }
            &__icon-wrap {
                position: absolute;
                right: $u-action-sheet-header-icon-wrap-right;
                top: $u-action-sheet-header-icon-wrap-top;
            }
        }
        &__description {
            font-size: $u-action-sheet-description-font-size;
            color: $u-tips-color;
            margin: $u-action-sheet-description-margin;
            text-align: center;
        }
        &__item-wrap {
            &__item {
                padding: $u-action-sheet-item-wrap-item-padding;
                @include flex;
                align-items: center;
                justify-content: center;
                flex-direction: column;
                &__name {
                    font-size: $u-action-sheet-item-wrap-name-font-size;
                    color: $u-main-color;
                    text-align: center;
                }
                &__subname {
                    font-size: $u-action-sheet-item-wrap-subname-font-size;
                    color: $u-action-sheet-item-wrap-subname-color;
                    margin-top: $u-action-sheet-item-wrap-subname-margin-top;
                    text-align: center;
                }
            }
        }
        &__cancel-text {
            font-size: $u-action-sheet-cancel-text-font-size;
            color: $u-action-sheet-cancel-text-color;
            text-align: center;
            padding: $u-action-sheet-cancel-text-font-size;
        }
        &--hover {
            background-color: $u-action-sheet-cancel-text-hover-background-color;
        }
    }
</style>
uni_modules/uview-ui/components/u-album/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
export default {
    props: {
        // å›¾ç‰‡åœ°å€ï¼ŒArray<String>|Array<Object>形式
        urls: {
            type: Array,
            default: uni.$u.props.album.urls
        },
        // æŒ‡å®šä»Žæ•°ç»„的对象元素中读取哪个属性作为图片地址
        keyName: {
            type: String,
            default: uni.$u.props.album.keyName
        },
        // å•图时,图片长边的长度
        singleSize: {
            type: [String, Number],
            default: uni.$u.props.album.singleSize
        },
        // å¤šå›¾æ—¶ï¼Œå›¾ç‰‡è¾¹é•¿
        multipleSize: {
            type: [String, Number],
            default: uni.$u.props.album.multipleSize
        },
        // å¤šå›¾æ—¶ï¼Œå›¾ç‰‡æ°´å¹³å’Œåž‚直之间的间隔
        space: {
            type: [String, Number],
            default: uni.$u.props.album.space
        },
        // å•图时,图片缩放裁剪的模式
        singleMode: {
            type: String,
            default: uni.$u.props.album.singleMode
        },
        // å¤šå›¾æ—¶ï¼Œå›¾ç‰‡ç¼©æ”¾è£å‰ªçš„æ¨¡å¼
        multipleMode: {
            type: String,
            default: uni.$u.props.album.multipleMode
        },
        // æœ€å¤šå±•示的图片数量,超出时最后一个位置将会显示剩余图片数量
        maxCount: {
            type: [String, Number],
            default: uni.$u.props.album.maxCount
        },
        // æ˜¯å¦å¯ä»¥é¢„览图片
        previewFullImage: {
            type: Boolean,
            default: uni.$u.props.album.previewFullImage
        },
        // æ¯è¡Œå±•示图片数量,如设置,singleSize和multipleSize将会无效
        rowCount: {
            type: [String, Number],
            default: uni.$u.props.album.rowCount
        },
        // è¶…出maxCount时是否显示查看更多的提示
        showMore: {
            type: Boolean,
            default: uni.$u.props.album.showMore
        }
    }
}
uni_modules/uview-ui/components/u-album/u-album.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,259 @@
<template>
    <view class="u-album">
        <view
            class="u-album__row"
            ref="u-album__row"
            v-for="(arr, index) in showUrls"
            :forComputedUse="albumWidth"
            :key="index"
        >
            <view
                class="u-album__row__wrapper"
                v-for="(item, index1) in arr"
                :key="index1"
                :style="[imageStyle(index + 1, index1 + 1)]"
                @tap="previewFullImage ? onPreviewTap(getSrc(item)) : ''"
            >
                <image
                    :src="getSrc(item)"
                    :mode="
                        urls.length === 1
                            ? imageHeight > 0
                                ? singleMode
                                : 'widthFix'
                            : multipleMode
                    "
                    :style="[
                        {
                            width: imageWidth,
                            height: imageHeight
                        }
                    ]"
                ></image>
                <view
                    v-if="
                        showMore &&
                        urls.length > rowCount * showUrls.length &&
                        index === showUrls.length - 1 &&
                        index1 === showUrls[showUrls.length - 1].length - 1
                    "
                    class="u-album__row__wrapper__text"
                >
                    <u--text
                        :text="`+${urls.length - maxCount}`"
                        color="#fff"
                        :size="multipleSize * 0.3"
                        align="center"
                        customStyle="justify-content: center"
                    ></u--text>
                </view>
            </view>
        </view>
    </view>
</template>
<script>
import props from './props.js'
// #ifdef APP-NVUE
// ç”±äºŽweex为阿里的KPI业绩考核的产物,所以不支持百分比单位,这里需要通过dom查询组件的宽度
const dom = uni.requireNativePlugin('dom')
// #endif
/**
 * Album ç›¸å†Œ
 * @description æœ¬ç»„件提供一个类似相册的功能,让开发者开发起来更加得心应手。减少重复的模板代码
 * @tutorial https://www.uviewui.com/components/album.html
 *
 * @property {Array}           urls             å›¾ç‰‡åœ°å€åˆ—表 Array<String>|Array<Object>形式
 * @property {String}          keyName          æŒ‡å®šä»Žæ•°ç»„的对象元素中读取哪个属性作为图片地址
 * @property {String | Number} singleSize       å•图时,图片长边的长度  ï¼ˆé»˜è®¤ 180 ï¼‰
 * @property {String | Number} multipleSize     å¤šå›¾æ—¶ï¼Œå›¾ç‰‡è¾¹é•¿ ï¼ˆé»˜è®¤ 70 ï¼‰
 * @property {String | Number} space            å¤šå›¾æ—¶ï¼Œå›¾ç‰‡æ°´å¹³å’Œåž‚直之间的间隔 ï¼ˆé»˜è®¤ 6 ï¼‰
 * @property {String}          singleMode       å•图时,图片缩放裁剪的模式 ï¼ˆé»˜è®¤ 'scaleToFill' ï¼‰
 * @property {String}          multipleMode     å¤šå›¾æ—¶ï¼Œå›¾ç‰‡ç¼©æ”¾è£å‰ªçš„æ¨¡å¼ ï¼ˆé»˜è®¤ 'aspectFill' ï¼‰
 * @property {String | Number} maxCount         å–消按钮的提示文字 ï¼ˆé»˜è®¤ 9 ï¼‰
 * @property {Boolean}         previewFullImage æ˜¯å¦å¯ä»¥é¢„览图片 ï¼ˆé»˜è®¤ true ï¼‰
 * @property {String | Number} rowCount         æ¯è¡Œå±•示图片数量,如设置,singleSize和multipleSize将会无效    ï¼ˆé»˜è®¤ 3 ï¼‰
 * @property {Boolean}         showMore         è¶…出maxCount时是否显示查看更多的提示 ï¼ˆé»˜è®¤ true ï¼‰
 *
 * @event    {Function}        albumWidth       æŸäº›ç‰¹æ®Šçš„æƒ…况下,需要让文字与相册的宽度相等,这里事件的形式对外发送  ï¼ˆå›žè°ƒå‚æ•° width ï¼‰
 * @example <u-album :urls="urls2" @albumWidth="width => albumWidth = width" multipleSize="68" ></u-album>
 */
export default {
    name: 'u-album',
    mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
    data() {
        return {
            // å•图的宽度
            singleWidth: 0,
            // å•图的高度
            singleHeight: 0,
            // å•图时,如果无法获取图片的尺寸信息,让图片宽度默认为容器的一定百分比
            singlePercent: 0.6
        }
    },
    watch: {
        urls: {
            immediate: true,
            handler(newVal) {
                if (newVal.length === 1) {
                    this.getImageRect()
                }
            }
        }
    },
    computed: {
        imageStyle() {
            return (index1, index2) => {
                const { space, rowCount, multipleSize, urls } = this,
                    { addUnit, addStyle } = uni.$u,
                    rowLen = this.showUrls.length,
                    allLen = this.urls.length
                const style = {
                    marginRight: addUnit(space),
                    marginBottom: addUnit(space)
                }
                // å¦‚果为最后一行,则每个图片都无需下边框
                if (index1 === rowLen) style.marginBottom = 0
                // æ¯è¡Œçš„æœ€å³è¾¹ä¸€å¼ å’Œæ€»é•¿åº¦çš„æœ€åŽä¸€å¼ æ— éœ€å³è¾¹æ¡†
                if (
                    index2 === rowCount ||
                    (index1 === rowLen &&
                        index2 === this.showUrls[index1 - 1].length)
                )
                    style.marginRight = 0
                return style
            }
        },
        // å°†æ•°ç»„划分为二维数组
        showUrls() {
            const arr = []
            this.urls.map((item, index) => {
                // é™åˆ¶æœ€å¤§å±•示数量
                if (index + 1 <= this.maxCount) {
                    // è®¡ç®—该元素为第几个素组内
                    const itemIndex = Math.floor(index / this.rowCount)
                    // åˆ¤æ–­å¯¹åº”的索引是否存在
                    if (!arr[itemIndex]) {
                        arr[itemIndex] = []
                    }
                    arr[itemIndex].push(item)
                }
            })
            return arr
        },
        imageWidth() {
            return uni.$u.addUnit(
                this.urls.length === 1 ? this.singleWidth : this.multipleSize
            )
        },
        imageHeight() {
            return uni.$u.addUnit(
                this.urls.length === 1 ? this.singleHeight : this.multipleSize
            )
        },
        // æ­¤å˜é‡æ— å®žé™…用途,仅仅是为了利用computed特性,让其在urls长度等变化时,重新计算图片的宽度
        // å› ä¸ºç”¨æˆ·åœ¨æŸäº›ç‰¹æ®Šçš„æƒ…况下,需要让文字与相册的宽度相等,所以这里事件的形式对外发送
        albumWidth() {
            let width = 0
            if (this.urls.length === 1) {
                width = this.singleWidth
            } else {
                width =
                    this.showUrls[0].length * this.multipleSize +
                    this.space * (this.showUrls[0].length - 1)
            }
            this.$emit('albumWidth', width)
            return width
        }
    },
    methods: {
        // é¢„览图片
        onPreviewTap(url) {
            const urls = this.urls.map((item) => {
                return this.getSrc(item)
            })
            uni.previewImage({
                current: url,
                urls
            })
        },
        // èŽ·å–å›¾ç‰‡çš„è·¯å¾„
        getSrc(item) {
            return uni.$u.test.object(item)
                ? (this.keyName && item[this.keyName]) || item.src
                : item
        },
        // å•图时,获取图片的尺寸
        // åœ¨å°ç¨‹åºä¸­ï¼Œéœ€è¦å°†ç½‘络图片的的域名添加到小程序的download域名才可能获取尺寸
        // åœ¨æ²¡æœ‰æ·»åŠ çš„æƒ…å†µä¸‹ï¼Œè®©å•å›¾å®½åº¦é»˜è®¤ä¸ºç›’å­çš„ä¸€å®šå®½åº¦(singlePercent)
        getImageRect() {
            const src = this.getSrc(this.urls[0])
            uni.getImageInfo({
                src,
                success: (res) => {
                    // åˆ¤æ–­å›¾ç‰‡æ¨ªå‘还是竖向展示方式
                    const isHorizotal = res.width >= res.height
                    this.singleWidth = isHorizotal
                        ? this.singleSize
                        : (res.width / res.height) * this.singleSize
                    this.singleHeight = !isHorizotal
                        ? this.singleSize
                        : (res.height / res.width) * this.singleWidth
                },
                fail: () => {
                    this.getComponentWidth()
                }
            })
        },
        // èŽ·å–ç»„ä»¶çš„å®½åº¦
        async getComponentWidth() {
            // å»¶æ—¶ä¸€å®šæ—¶é—´ï¼Œä»¥èŽ·å–dom尺寸
            await uni.$u.sleep(30)
            // #ifndef APP-NVUE
            this.$uGetRect('.u-album__row').then((size) => {
                this.singleWidth = size.width * this.singlePercent
            })
            // #endif
            // #ifdef APP-NVUE
            // è¿™é‡Œref="u-album__row"所在的标签为通过for循环出来,导致this.$refs['u-album__row']是一个数组
            const ref = this.$refs['u-album__row'][0]
            ref &&
                dom.getComponentRect(ref, (res) => {
                    this.singleWidth = res.size.width * this.singlePercent
                })
            // #endif
        }
    }
}
</script>
<style lang="scss" scoped>
@import '../../libs/css/components.scss';
.u-album {
    @include flex(column);
    &__row {
        @include flex(row);
        flex-wrap: wrap;
        &__wrapper {
            position: relative;
            &__text {
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background-color: rgba(0, 0, 0, 0.3);
                @include flex(row);
                justify-content: center;
                align-items: center;
            }
        }
    }
}
</style>
uni_modules/uview-ui/components/u-alert/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
export default {
    props: {
        // æ˜¾ç¤ºæ–‡å­—
        title: {
            type: String,
            default: uni.$u.props.alert.title
        },
        // ä¸»é¢˜ï¼Œsuccess/warning/info/error
        type: {
            type: String,
            default: uni.$u.props.alert.type
        },
        // è¾…助性文字
        description: {
            type: String,
            default: uni.$u.props.alert.description
        },
        // æ˜¯å¦å¯å…³é—­
        closable: {
            type: Boolean,
            default: uni.$u.props.alert.closable
        },
        // æ˜¯å¦æ˜¾ç¤ºå›¾æ ‡
        showIcon: {
            type: Boolean,
            default: uni.$u.props.alert.showIcon
        },
        // æµ…或深色调,light-浅色,dark-深色
        effect: {
            type: String,
            default: uni.$u.props.alert.effect
        },
        // æ–‡å­—是否居中
        center: {
            type: Boolean,
            default: uni.$u.props.alert.center
        },
        // å­—体大小
        fontSize: {
            type: [String, Number],
            default: uni.$u.props.alert.fontSize
        }
    }
}
uni_modules/uview-ui/components/u-alert/u-alert.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,243 @@
<template>
    <u-transition
        mode="fade"
        :show="show"
    >
        <view
            class="u-alert"
            :class="[`u-alert--${type}--${effect}`]"
            @tap.stop="clickHandler"
            :style="[$u.addStyle(customStyle)]"
        >
            <view
                class="u-alert__icon"
                v-if="showIcon"
            >
                <u-icon
                    :name="iconName"
                    size="18"
                    :color="iconColor"
                ></u-icon>
            </view>
            <view
                class="u-alert__content"
                :style="[{
                    paddingRight: closable ? '20px' : 0
                }]"
            >
                <text
                    class="u-alert__content__title"
                    v-if="title"
                    :style="[{
                        fontSize: $u.addUnit(fontSize),
                        textAlign: center ? 'center' : 'left'
                    }]"
                    :class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"
                >{{ title }}</text>
                <text
                    class="u-alert__content__desc"
                    v-if="description"
                    :style="[{
                        fontSize: $u.addUnit(fontSize),
                        textAlign: center ? 'center' : 'left'
                    }]"
                    :class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"
                >{{ description }}</text>
            </view>
            <view
                class="u-alert__close"
                v-if="closable"
                @tap.stop="closeHandler"
            >
                <u-icon
                    name="close"
                    :color="iconColor"
                    size="15"
                ></u-icon>
            </view>
        </view>
    </u-transition>
</template>
<script>
    import props from './props.js';
    /**
     * Alert  è­¦å‘Šæç¤º
     * @description è­¦å‘Šæç¤ºï¼Œå±•现需要关注的信息。
     * @tutorial https://www.uviewui.com/components/alertTips.html
     *
     * @property {String}            title       æ˜¾ç¤ºçš„æ–‡å­—
     * @property {String}            type        ä½¿ç”¨é¢„设的颜色  ï¼ˆé»˜è®¤ 'warning' ï¼‰
     * @property {String}            description è¾…助性文字,颜色比title浅一点,字号也小一点,可选
     * @property {Boolean}            closable    å…³é—­æŒ‰é’®(默认为叉号icon图标)  ï¼ˆé»˜è®¤ false ï¼‰
     * @property {Boolean}            showIcon    æ˜¯å¦æ˜¾ç¤ºå·¦è¾¹çš„辅助图标   ï¼ˆ é»˜è®¤ false ï¼‰
     * @property {String}            effect      å¤šå›¾æ—¶ï¼Œå›¾ç‰‡ç¼©æ”¾è£å‰ªçš„æ¨¡å¼  ï¼ˆé»˜è®¤ 'light' ï¼‰
     * @property {Boolean}            center        æ–‡å­—是否居中  ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String | Number}    fontSize    å­—体大小  ï¼ˆé»˜è®¤ 14 ï¼‰
     * @property {Object}            customStyle    å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     * @event    {Function}        click       ç‚¹å‡»ç»„件时触发
     * @example  <u-alert :title="title"  type = "warning" :closable="closable" :description = "description"></u-alert>
     */
    export default {
        name: 'u-alert',
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
                show: true
            }
        },
        computed: {
            iconColor() {
                return this.effect === 'light' ? this.type : '#fff'
            },
            // ä¸åŒä¸»é¢˜å¯¹åº”不同的图标
            iconName() {
                switch (this.type) {
                    case 'success':
                        return 'checkmark-circle-fill';
                        break;
                    case 'error':
                        return 'close-circle-fill';
                        break;
                    case 'warning':
                        return 'error-circle-fill';
                        break;
                    case 'info':
                        return 'info-circle-fill';
                        break;
                    case 'primary':
                        return 'more-circle-fill';
                        break;
                    default:
                        return 'error-circle-fill';
                }
            }
        },
        methods: {
            // ç‚¹å‡»å†…容
            clickHandler() {
                this.$emit('click')
            },
            // ç‚¹å‡»å…³é—­æŒ‰é’®
            closeHandler() {
                this.show = false
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-alert {
        position: relative;
        background-color: $u-primary;
        padding: 8px 10px;
        @include flex(row);
        align-items: center;
        border-top-left-radius: 4px;
        border-top-right-radius: 4px;
        border-bottom-left-radius: 4px;
        border-bottom-right-radius: 4px;
        &--primary--dark {
            background-color: $u-primary;
        }
        &--primary--light {
            background-color: #ecf5ff;
        }
        &--error--dark {
            background-color: $u-error;
        }
        &--error--light {
            background-color: #FEF0F0;
        }
        &--success--dark {
            background-color: $u-success;
        }
        &--success--light {
            background-color: #f5fff0;
        }
        &--warning--dark {
            background-color: $u-warning;
        }
        &--warning--light {
            background-color: #FDF6EC;
        }
        &--info--dark {
            background-color: $u-info;
        }
        &--info--light {
            background-color: #f4f4f5;
        }
        &__icon {
            margin-right: 5px;
        }
        &__content {
            @include flex(column);
            flex: 1;
            &__title {
                color: $u-main-color;
                font-size: 14px;
                font-weight: bold;
                color: #fff;
                margin-bottom: 2px;
            }
            &__desc {
                color: $u-main-color;
                font-size: 14px;
                flex-wrap: wrap;
                color: #fff;
            }
        }
        &__title--dark,
        &__desc--dark {
            color: #FFFFFF;
        }
        &__text--primary--light,
        &__text--primary--light {
            color: $u-primary;
        }
        &__text--success--light,
        &__text--success--light {
            color: $u-success;
        }
        &__text--warning--light,
        &__text--warning--light {
            color: $u-warning;
        }
        &__text--error--light,
        &__text--error--light {
            color: $u-error;
        }
        &__text--info--light,
        &__text--info--light {
            color: $u-info;
        }
        &__close {
            position: absolute;
            top: 11px;
            right: 10px;
        }
    }
</style>
uni_modules/uview-ui/components/u-avatar-group/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
export default {
    props: {
        // å¤´åƒå›¾ç‰‡ç»„
        urls: {
            type: Array,
            default: uni.$u.props.avatarGroup.urls
        },
        // æœ€å¤šå±•示的头像数量
        maxCount: {
            type: [String, Number],
            default: uni.$u.props.avatarGroup.maxCount
        },
        // å¤´åƒå½¢çж
        shape: {
            type: String,
            default: uni.$u.props.avatarGroup.shape
        },
        // å›¾ç‰‡è£å‰ªæ¨¡å¼
        mode: {
            type: String,
            default: uni.$u.props.avatarGroup.mode
        },
        // è¶…出maxCount时是否显示查看更多的提示
        showMore: {
            type: Boolean,
            default: uni.$u.props.avatarGroup.showMore
        },
        // å¤´åƒå¤§å°
        size: {
            type: [String, Number],
            default: uni.$u.props.avatarGroup.size
        },
        // æŒ‡å®šä»Žæ•°ç»„的对象元素中读取哪个属性作为图片地址
        keyName: {
            type: String,
            default: uni.$u.props.avatarGroup.keyName
        },
        // å¤´åƒä¹‹é—´çš„遮挡比例
        gap: {
            type: [String, Number],
            validator(value) {
                return value >= 0 && value <= 1
            },
            default: uni.$u.props.avatarGroup.gap
        },
        // éœ€é¢å¤–显示的值
        extraValue: {
            type: [Number, String],
            default: uni.$u.props.avatarGroup.extraValue
        }
    }
}
uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,103 @@
<template>
    <view class="u-avatar-group">
        <view
            class="u-avatar-group__item"
            v-for="(item, index) in showUrl"
            :key="index"
            :style="{
                marginLeft: index === 0 ? 0 : $u.addUnit(-size * gap)
            }"
        >
            <u-avatar
                :size="size"
                :shape="shape"
                :mode="mode"
                :src="$u.test.object(item) ? keyName && item[keyName] || item.url : item"
            ></u-avatar>
            <view
                class="u-avatar-group__item__show-more"
                v-if="showMore && index === showUrl.length - 1 && (urls.length > maxCount || extraValue > 0)"
                @tap="clickHandler"
            >
                <u--text
                    color="#ffffff"
                    :size="size * 0.4"
                    :text="`+${extraValue || urls.length - showUrl.length}`"
                    align="center"
                    customStyle="justify-content: center"
                ></u--text>
            </view>
        </view>
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * AvatarGroup  å¤´åƒç»„
     * @description æœ¬ç»„件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
     * @tutorial https://www.uviewui.com/components/avatar.html
     *
     * @property {Array}           urls     å¤´åƒå›¾ç‰‡ç»„ ï¼ˆé»˜è®¤ [] ï¼‰
     * @property {String | Number} maxCount æœ€å¤šå±•示的头像数量 ï¼ˆ é»˜è®¤ 5 ï¼‰
     * @property {String}          shape    å¤´åƒå½¢çŠ¶ï¼ˆ 'circle' (默认) | 'square' ï¼‰
     * @property {String}          mode     å›¾ç‰‡è£å‰ªæ¨¡å¼ï¼ˆé»˜è®¤ 'scaleToFill' ï¼‰
     * @property {Boolean}         showMore è¶…出maxCount时是否显示查看更多的提示 ï¼ˆé»˜è®¤ true ï¼‰
     * @property {String | Number} size      å¤´åƒå¤§å° ï¼ˆé»˜è®¤ 40 ï¼‰
     * @property {String}          keyName  æŒ‡å®šä»Žæ•°ç»„的对象元素中读取哪个属性作为图片地址
     * @property {String | Number} gap      å¤´åƒä¹‹é—´çš„遮挡比例(0.4代表遮挡40%)  ï¼ˆé»˜è®¤ 0.5 ï¼‰
     * @property {String | Number} extraValue  éœ€é¢å¤–显示的值
     * @event    {Function}        showMore å¤´åƒç»„更多点击
     * @example  <u-avatar-group:urls="urls" size="35" gap="0.4" ></u-avatar-group:urls=>
     */
    export default {
        name: 'u-avatar-group',
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
            }
        },
        computed: {
            showUrl() {
                return this.urls.slice(0, this.maxCount)
            }
        },
        methods: {
            clickHandler() {
                this.$emit('showMore')
            }
        },
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-avatar-group {
        @include flex;
        &__item {
            margin-left: -10px;
            position: relative;
            &--no-indent {
                // å¦‚果你想质疑作者不会使用:first-child,说明你太年轻,因为nvue不支持
                margin-left: 0;
            }
            &__show-more {
                position: absolute;
                top: 0;
                bottom: 0;
                left: 0;
                right: 0;
                background-color: rgba(0, 0, 0, 0.3);
                @include flex;
                align-items: center;
                justify-content: center;
                border-radius: 100px;
            }
        }
    }
</style>
uni_modules/uview-ui/components/u-avatar/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,78 @@
export default {
    props: {
        // å¤´åƒå›¾ç‰‡è·¯å¾„(不能为相对路径)
        src: {
            type: String,
            default: uni.$u.props.avatar.src
        },
        // å¤´åƒå½¢çŠ¶ï¼Œcircle-圆形,square-方形
        shape: {
            type: String,
            default: uni.$u.props.avatar.shape
        },
        // å¤´åƒå°ºå¯¸
        size: {
            type: [String, Number],
            default: uni.$u.props.avatar.size
        },
        // è£å‰ªæ¨¡å¼
        mode: {
            type: String,
            default: uni.$u.props.avatar.mode
        },
        // æ˜¾ç¤ºçš„æ–‡å­—
        text: {
            type: String,
            default: uni.$u.props.avatar.text
        },
        // èƒŒæ™¯è‰²
        bgColor: {
            type: String,
            default: uni.$u.props.avatar.bgColor
        },
        // æ–‡å­—颜色
        color: {
            type: String,
            default: uni.$u.props.avatar.color
        },
        // æ–‡å­—大小
        fontSize: {
            type: [String, Number],
            default: uni.$u.props.avatar.fontSize
        },
        // æ˜¾ç¤ºçš„图标
        icon: {
            type: String,
            default: uni.$u.props.avatar.icon
        },
        // æ˜¾ç¤ºå°ç¨‹åºå¤´åƒï¼Œåªå¯¹ç™¾åº¦ï¼Œå¾®ä¿¡ï¼ŒQQ小程序有效
        mpAvatar: {
            type: Boolean,
            default: uni.$u.props.avatar.mpAvatar
        },
        // æ˜¯å¦ä½¿ç”¨éšæœºèƒŒæ™¯è‰²
        randomBgColor: {
            type: Boolean,
            default: uni.$u.props.avatar.randomBgColor
        },
        // åŠ è½½å¤±è´¥çš„é»˜è®¤å¤´åƒ(组件有内置默认图片)
        defaultUrl: {
            type: String,
            default: uni.$u.props.avatar.defaultUrl
        },
        // å¦‚果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
        colorIndex: {
            type: [String, Number],
            // æ ¡éªŒå‚数规则,索引在0-19之间
            validator(n) {
                return uni.$u.test.range(n, [0, 19]) || n === ''
            },
            default: uni.$u.props.avatar.colorIndex
        },
        // ç»„件标识符
        name: {
            type: String,
            default: uni.$u.props.avatar.name
        }
    }
}
uni_modules/uview-ui/components/u-avatar/u-avatar.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,172 @@
<template>
    <view
        class="u-avatar"
        :class="[`u-avatar--${shape}`]"
        :style="[{
            backgroundColor: (text || icon) ? (randomBgColor ? colors[colorIndex !== '' ? colorIndex : $u.random(0, 19)] : bgColor) : 'transparent',
            width: $u.addUnit(size),
            height: $u.addUnit(size),
        }, $u.addStyle(customStyle)]"
        @tap="clickHandler"
    >
        <slot>
            <!-- #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU  -->
            <open-data
                v-if="mpAvatar && allowMp"
                type="userAvatarUrl"
                :style="[{
                    width: $u.addUnit(size),
                    height: $u.addUnit(size)
                }]"
            />
            <!-- #endif -->
            <!-- #ifndef MP-WEIXIN && MP-QQ && MP-BAIDU  -->
            <template v-if="mpAvatar && allowMp"></template>
            <!-- #endif -->
            <u-icon
                v-else-if="icon"
                :name="icon"
                :size="fontSize"
                :color="color"
            ></u-icon>
            <u--text
                v-else-if="text"
                :text="text"
                :size="fontSize"
                :color="color"
                align="center"
                customStyle="justify-content: center"
            ></u--text>
            <image
                class="u-avatar__image"
                v-else
                :class="[`u-avatar__image--${shape}`]"
                :src="avatarUrl || defaultUrl"
                :mode="mode"
                @error="errorHandler"
                :style="[{
                    width: $u.addUnit(size),
                    height: $u.addUnit(size)
                }]"
            ></image>
        </slot>
    </view>
</template>
<script>
    import props from './props.js';
    const base64Avatar =
        "data:image/jpg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMraHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjREMEQwRkY0RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjREMEQwRkY1RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NEQwRDBGRjJGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NEQwRDBGRjNGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYGCAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8fAQcHBw0MDRgQEBgaFREVGh8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx//wAARCADIAMgDAREAAhEBAxEB/8QAcQABAQEAAwEBAAAAAAAAAAAAAAUEAQMGAgcBAQAAAAAAAAAAAAAAAAAAAAAQAAIBAwICBgkDBQAAAAAAAAABAhEDBCEFMVFBYXGREiKBscHRMkJSEyOh4XLxYjNDFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A/fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHbHFyZ/Dam+yLA+Z2L0Pjtyj2poD4AAAAAAAAAAAAAAAAAAAAAAAAKWFs9y6lcvvwQeqj8z9wFaziY1n/HbUX9XF97A7QAGXI23EvJ1goyfzR0YEfN269jeZ+a03pNe0DIAAAAAAAAAAAAAAAAAAAACvtO3RcVkXlWutuL9YFYAAAAAOJRjKLjJVi9GmB5/csH/mu1h/in8PU+QGMAAAAAAAAAAAAAAAAAAaMDG/6MmMH8C80+xAelSSVFolwQAAAAAAAHVlWI37ErUulaPk+hgeYnCUJuElSUXRrrQHAAAAAAAAAAAAAAAAABa2Oz4bM7r4zdF2ICmAAAAAAAAAg7zZ8GX41wuJP0rRgYAAAAAAAAAAAAAAAAAD0m2R8ODaXU33tsDSAAAAAAAAAlb9HyWZcnJd9PcBHAAAAAAAAAAAAAAAAAPS7e64Vn+KA0AAAAAAAAAJm+v8Ftf3ewCKAAAAAAAAAAAAAAAAAX9muqeGo9NttP06+0DcAAAAAAAAAjb7dTu2ra+VOT9P8AQCWAAAAAAAAAAAAAAAAAUNmyPt5Ltv4bui/kuAF0AAAAAAADiUlGLlJ0SVW+oDzOXfd/Ind6JPRdS0QHSAAAAAAAAAAAAAAAAAE2nVaNcGB6Lbs6OTao9LsF51z60BrAAAAAABJ3jOVHjW3r/sa9QEgAAAAAAAAAAAAAAAAAAAPu1duWriuW34ZR4MC9hbnZyEoy8l36XwfYBsAAADaSq9EuLAlZ+7xSdrGdW9Hc5dgEdtt1erfFgAAAAAAAAAAAAAAAAADVjbblX6NR8MH80tEBRs7HYivyzlN8lovaBPzduvY0m6eK10TXtAyAarO55lpJK54orolr+4GqO/Xaea1FvqbXvA+Z77kNeW3GPbV+4DJfzcm/pcm3H6Vou5AdAFLC2ed2Pjv1txa8sV8T6wOL+yZEKu1JXFy4MDBOE4ScZxcZLinoB8gAAAAAAAAAAAB242LeyJ+C3GvN9C7QLmJtePYpKS+5c+p8F2IDYAANJqj1T4oCfk7Nj3G5Wn9qXJax7gJ93Z82D8sVNc4v30A6Xg5i42Z+iLfqARwcyT0sz9MWvWBps7LlTf5Grce9/oBTxdtxseklHxT+uWr9AGoAB138ezfj4bsFJdD6V2MCPm7RdtJzs1uW1xXzL3gTgAAAAAAAAADRhYc8q74I6RWs5ckB6GxYtWLat21SK731sDsAAAAAAAAAAAAAAAASt021NO/YjrxuQXT1oCOAAAAAAABzGLlJRSq26JAelwsWONYjbXxcZvmwO8AAAAAAAAAAAAAAAAAAef3TEWPkVivx3NY9T6UBiAAAAAABo2+VmGXblddIJ8eivRUD0oAAAAAAAAAAAAAAAAAAAYt4tKeFKVNYNSXfRgefAAAAAAAAr7VuSSWPedKaW5v1MCsAAAAAAAAAAAAAAAAAAIe6bj96Ts2n+JPzSXzP3ATgAAAAAAAAFbbt1UUrOQ9FpC4/UwK6aaqtU+DAAAAAAAAAAAAAAA4lKMIuUmoxWrb4ARNx3R3q2rLpa4Sl0y/YCcAAAAAAAAAAANmFud7G8r89r6X0dgFvGzLGRGtuWvTF6NAdwAAAAAAAAAAAy5W442PVN+K59EePp5ARMvOv5MvO6QXCC4AZwAAAAAAAAAAAAAcxlKLUotprg1owN+PvORborq+7Hnwl3gUbO74VzRydt8pKn68ANcJwmqwkpLmnUDkAAAAfNy9atqtyagut0AxXt5xIV8Fbj6lRd7Am5G65V6qUvtwfyx94GMAAAAAAAAAAAAAAAAAAAOU2nVOj5gdsc3LiqRvTpyqwOxbnnrhdfpSfrQB7pnv/AGvuS9gHXPMy5/Fem1yq0v0A6W29XqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//Z";
    /**
     * Avatar  å¤´åƒ
     * @description æœ¬ç»„件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
     * @tutorial https://www.uviewui.com/components/avatar.html
     *
     * @property {String}            src                å¤´åƒè·¯å¾„,如加载失败,将会显示默认头像(不能为相对路径)
     * @property {String}            shape            å¤´åƒå½¢çж  ï¼ˆ circle (默认) | square)
     * @property {String | Number}    size            å¤´åƒå°ºå¯¸ï¼Œå¯ä»¥ä¸ºæŒ‡å®šå­—符串(large, default, mini),或者数值 ï¼ˆé»˜è®¤ 40 ï¼‰
     * @property {String}            mode            å¤´åƒå›¾ç‰‡çš„裁剪类型,与uni的image组件的mode参数一致,如效果达不到需求,可尝试传widthFix值 ï¼ˆé»˜è®¤ 'scaleToFill' ï¼‰
     * @property {String}            text            ç”¨æ–‡å­—替代图片,级别优先于src
     * @property {String}            bgColor            èƒŒæ™¯é¢œè‰²ï¼Œä¸€èˆ¬æ˜¾ç¤ºæ–‡å­—时用 ï¼ˆé»˜è®¤ '#c0c4cc' ï¼‰
     * @property {String}            color            æ–‡å­—颜色 ï¼ˆé»˜è®¤ '#ffffff' ï¼‰
     * @property {String | Number}    fontSize        æ–‡å­—大小  ï¼ˆé»˜è®¤ 18 ï¼‰
     * @property {String}            icon            æ˜¾ç¤ºçš„图标
     * @property {Boolean}            mpAvatar        æ˜¾ç¤ºå°ç¨‹åºå¤´åƒï¼Œåªå¯¹ç™¾åº¦ï¼Œå¾®ä¿¡ï¼ŒQQ小程序有效  ï¼ˆé»˜è®¤ false ï¼‰
     * @property {Boolean}            randomBgColor    æ˜¯å¦ä½¿ç”¨éšæœºèƒŒæ™¯è‰²  ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String}            defaultUrl        åŠ è½½å¤±è´¥çš„é»˜è®¤å¤´åƒ(组件有内置默认图片)
     * @property {String | Number}    colorIndex        å¦‚果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
     * @property {String}            name            ç»„件标识符  ï¼ˆé»˜è®¤ 'level' ï¼‰
     * @property {Object}            customStyle        å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     *
     * @event    {Function}        click       ç‚¹å‡»ç»„件时触发   index: ç”¨æˆ·ä¼ é€’的标识符
     * @example  <u-avatar :src="src" mode="square"></u-avatar>
     */
    export default {
        name: 'u-avatar',
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
                // å¦‚果配置randomBgColor参数为true,在图标或者文字的模式下,会随机从中取出一个颜色值当做背景色
                colors: ['#ffb34b', '#f2bba9', '#f7a196', '#f18080', '#88a867', '#bfbf39', '#89c152', '#94d554', '#f19ec2',
                    '#afaae4', '#e1b0df', '#c38cc1', '#72dcdc', '#9acdcb', '#77b1cc', '#448aca', '#86cefa', '#98d1ee',
                    '#73d1f1',
                    '#80a7dc'
                ],
                avatarUrl: this.src,
                allowMp: false
            }
        },
        watch: {
            // ç›‘听头像src的变化,赋值给内部的avatarUrl变量,因为图片加载失败时,需要修改图片的src为默认值
            // è€Œç»„件内部不能直接修改props的值,所以需要一个中间变量
            src: {
                immediate: true,
                handler(newVal) {
                    this.avatarUrl = newVal
                    // å¦‚果没有传src,则主动触发error事件,用于显示默认的头像,否则src为''空字符等的时候,会无内容展示
                    if(!newVal) {
                        this.errorHandler()
                    }
                }
            }
        },
        computed: {
            imageStyle() {
                const style = {}
                return style
            }
        },
        created() {
            this.init()
        },
        methods: {
            init() {
                // ç›®å‰åªæœ‰è¿™å‡ ä¸ªå°ç¨‹åºå¹³å°å…·æœ‰open-data标签
                // å…¶ä»–平台可以通过uni.getUserInfo类似接口获取信息,但是需要弹窗授权(首次),不合符组件逻辑
                // æ•…目前自动获取小程序头像只支持这几个平台
                // #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU
                this.allowMp = true
                // #endif
            },
            // åˆ¤æ–­ä¼ å…¥çš„name属性,是否图片路径,只要带有"/"均认为是图片形式
            isImg() {
                return this.src.indexOf('/') !== -1
            },
            // å›¾ç‰‡åŠ è½½æ—¶å¤±è´¥æ—¶è§¦å‘
            errorHandler() {
                this.avatarUrl = this.defaultUrl || base64Avatar
            },
            clickHandler() {
                this.$emit('click', this.name)
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-avatar {
        @include flex;
        align-items: center;
        justify-content: center;
        &--circle {
            border-radius: 100px;
        }
        &--square {
            border-radius: 4px;
        }
        &__image {
            &--circle {
                border-radius: 100px;
            }
            &--square {
                border-radius: 4px;
            }
        }
    }
</style>
uni_modules/uview-ui/components/u-back-top/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
export default {
    props: {
        // è¿”回顶部的形状,circle-圆形,square-方形
        mode: {
            type: String,
            default: uni.$u.props.backtop.mode
        },
        // è‡ªå®šä¹‰å›¾æ ‡
        icon: {
            type: String,
            default: uni.$u.props.backtop.icon
        },
        // æç¤ºæ–‡å­—
        text: {
            type: String,
            default: uni.$u.props.backtop.text
        },
        // è¿”回顶部滚动时间
        duration: {
            type: [String, Number],
            default: uni.$u.props.backtop.duration
        },
        // æ»šåŠ¨è·ç¦»
        scrollTop: {
            type: [String, Number],
            default: uni.$u.props.backtop.scrollTop
        },
        // è·ç¦»é¡¶éƒ¨å¤šå°‘距离显示,单位px
        top: {
            type: [String, Number],
            default: uni.$u.props.backtop.top
        },
        // è¿”回顶部按钮到底部的距离,单位px
        bottom: {
            type: [String, Number],
            default: uni.$u.props.backtop.bottom
        },
        // è¿”回顶部按钮到右边的距离,单位px
        right: {
            type: [String, Number],
            default: uni.$u.props.backtop.right
        },
        // å±‚级
        zIndex: {
            type: [String, Number],
            default: uni.$u.props.backtop.zIndex
        },
        // å›¾æ ‡çš„æ ·å¼ï¼Œå¯¹è±¡å½¢å¼
        iconStyle: {
            type: Object,
            default: uni.$u.props.backtop.iconStyle
        }
    }
}
uni_modules/uview-ui/components/u-back-top/u-back-top.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,129 @@
<template>
    <u-transition
        mode="fade"
        :customStyle="backTopStyle"
        :show="show"
    >
        <view
            class="u-back-top"
            :style="[contentStyle]"
            v-if="!$slots.default && !$slots.$default"
            @click="backToTop"
        >
            <u-icon
                :name="icon"
                :custom-style="iconStyle"
            ></u-icon>
            <text
                v-if="text"
                class="u-back-top__text"
            >{{text}}</text>
        </view>
        <slot v-else />
    </u-transition>
</template>
<script>
    import props from './props.js';
    // #ifdef APP-NVUE
    const dom = weex.requireModule('dom')
    // #endif
    /**
     * backTop è¿”回顶部
     * @description æœ¬ç»„件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。
     * @tutorial https://uviewui.com/components/backTop.html
     *
     * @property {String}            mode          è¿”回顶部的形状,circle-圆形,square-方形 ï¼ˆé»˜è®¤ 'circle' ï¼‰
     * @property {String}             icon         è‡ªå®šä¹‰å›¾æ ‡ ï¼ˆé»˜è®¤ 'arrow-upward' ï¼‰ è§å®˜æ–¹æ–‡æ¡£ç¤ºä¾‹
     * @property {String}             text         æç¤ºæ–‡å­—
     * @property {String | Number}  duration    è¿”回顶部滚动时间 ï¼ˆé»˜è®¤ 100)
     * @property {String | Number}  scrollTop    æ»šåŠ¨è·ç¦» ï¼ˆé»˜è®¤ 0 ï¼‰
     * @property {String | Number}  top          è·ç¦»é¡¶éƒ¨å¤šå°‘距离显示,单位px ï¼ˆé»˜è®¤ 400 ï¼‰
     * @property {String | Number}  bottom      è¿”回顶部按钮到底部的距离,单位px ï¼ˆé»˜è®¤ 100 ï¼‰
     * @property {String | Number}  right          è¿”回顶部按钮到右边的距离,单位px ï¼ˆé»˜è®¤ 20 ï¼‰
     * @property {String | Number}  zIndex         å±‚级   ï¼ˆé»˜è®¤ 9 ï¼‰
     * @property {Object<Object>}      iconStyle     å›¾æ ‡çš„æ ·å¼ï¼Œå¯¹è±¡å½¢å¼   ï¼ˆé»˜è®¤ {color: '#909399',fontSize: '19px'})
     * @property {Object}            customStyle    å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     *
     * @example <u-back-top :scrollTop="scrollTop"></u-back-top>
     */
    export default {
        name: 'u-back-top',
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        computed: {
            backTopStyle() {
                // åŠ¨ç”»ç»„ä»¶æ ·å¼
                const style = {
                    bottom: uni.$u.addUnit(this.bottom),
                    right: uni.$u.addUnit(this.right),
                    width: '40px',
                    height: '40px',
                    position: 'fixed',
                    zIndex: 10,
                }
                return style
            },
            show() {
                return uni.$u.getPx(this.scrollTop) > uni.$u.getPx(this.top)
            },
            contentStyle() {
                const style = {}
                let radius = 0
                // æ˜¯å¦åœ†å½¢
                if(this.mode === 'circle') {
                    radius = '100px'
                } else {
                    radius = '4px'
                }
                // ä¸ºäº†å…¼å®¹å®‰å“nvue,只能这么分开写
                style.borderTopLeftRadius = radius
                style.borderTopRightRadius = radius
                style.borderBottomLeftRadius = radius
                style.borderBottomRightRadius = radius
                return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
            }
        },
        methods: {
            backToTop() {
                // #ifdef APP-NVUE
                if (!this.$parent.$refs['u-back-top']) {
                    uni.$u.error(`nvue页面需要给页面最外层元素设置"ref='u-back-top'`)
                }
                dom.scrollToElement(this.$parent.$refs['u-back-top'], {
                    offset: 0
                })
                // #endif
                // #ifndef APP-NVUE
                uni.pageScrollTo({
                    scrollTop: 0,
                    duration: this.duration
                });
                // #endif
                this.$emit('click')
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import '../../libs/css/components.scss';
     $u-back-top-flex:1 !default;
     $u-back-top-height:100% !default;
     $u-back-top-background-color:#E1E1E1 !default;
     $u-back-top-tips-font-size:12px !default;
    .u-back-top {
        @include flex;
        flex-direction: column;
        align-items: center;
        flex:$u-back-top-flex;
        height: $u-back-top-height;
        justify-content: center;
        background-color: $u-back-top-background-color;
        &__tips {
            font-size:$u-back-top-tips-font-size;
            transform: scale(0.8);
        }
    }
</style>
uni_modules/uview-ui/components/u-badge/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
export default {
    props: {
        // æ˜¯å¦æ˜¾ç¤ºåœ†ç‚¹
        isDot: {
            type: Boolean,
            default: uni.$u.props.badge.isDot
        },
        // æ˜¾ç¤ºçš„内容
        value: {
            type: [Number, String],
            default: uni.$u.props.badge.value
        },
        // æ˜¯å¦æ˜¾ç¤º
        show: {
            type: Boolean,
            default: uni.$u.props.badge.show
        },
        // æœ€å¤§å€¼ï¼Œè¶…过最大值会显示 '{max}+'
        max: {
            type: [Number, String],
            default: uni.$u.props.badge.max
        },
        // ä¸»é¢˜ç±»åž‹ï¼Œerror|warning|success|primary
        type: {
            type: String,
            default: uni.$u.props.badge.type
        },
        // å½“数值为 0 æ—¶ï¼Œæ˜¯å¦å±•示 Badge
        showZero: {
            type: Boolean,
            default: uni.$u.props.badge.showZero
        },
        // èƒŒæ™¯é¢œè‰²ï¼Œä¼˜å…ˆçº§æ¯”type高,如设置,type参数会失效
        bgColor: {
            type: [String, null],
            default: uni.$u.props.badge.bgColor
        },
        // å­—体颜色
        color: {
            type: [String, null],
            default: uni.$u.props.badge.color
        },
        // å¾½æ ‡å½¢çŠ¶ï¼Œcircle-四角均为圆角,horn-左下角为直角
        shape: {
            type: String,
            default: uni.$u.props.badge.shape
        },
        // è®¾ç½®æ•°å­—的显示方式,overflow|ellipsis|limit
        // overflow会根据max字段判断,超出显示`${max}+`
        // ellipsis会根据max判断,超出显示`${max}...`
        // limit会依据1000作为判断条件,超出1000,显示`${value/1000}K`,比如2.2k、3.34w,最多保留2位小数
        numberType: {
            type: String,
            default: uni.$u.props.badge.numberType
        },
        // è®¾ç½®badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效
        offset: {
            type: Array,
            default: uni.$u.props.badge.offset
        },
        // æ˜¯å¦åè½¬èƒŒæ™¯å’Œå­—体颜色
        inverted: {
            type: Boolean,
            default: uni.$u.props.badge.inverted
        },
        // æ˜¯å¦ç»å¯¹å®šä½
        absolute: {
            type: Boolean,
            default: uni.$u.props.badge.absolute
        }
    }
}
uni_modules/uview-ui/components/u-badge/u-badge.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,171 @@
<template>
    <text
        v-if="show && ((Number(value) === 0 ? showZero : true) || isDot)"
        :class="[isDot ? 'u-badge--dot' : 'u-badge--not-dot', inverted && 'u-badge--inverted', shape === 'horn' && 'u-badge--horn', `u-badge--${type}${inverted ? '--inverted' : ''}`]"
        :style="[$u.addStyle(customStyle), badgeStyle]"
        class="u-badge"
    >{{ isDot ? '' :showValue }}</text>
</template>
<script>
    import props from './props.js';
    /**
     * badge å¾½æ ‡æ•°
     * @description è¯¥ç»„件一般用于图标右上角显示未读的消息数量,提示用户点击,有圆点和圆包含文字两种形式。
     * @tutorial https://uviewui.com/components/badge.html
     *
     * @property {Boolean}             isDot         æ˜¯å¦æ˜¾ç¤ºåœ†ç‚¹ ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String | Number}     value         æ˜¾ç¤ºçš„内容
     * @property {Boolean}             show         æ˜¯å¦æ˜¾ç¤º ï¼ˆé»˜è®¤ true ï¼‰
     * @property {String | Number}     max         æœ€å¤§å€¼ï¼Œè¶…过最大值会显示 '{max}+'  ï¼ˆé»˜è®¤999)
     * @property {String}             type         ä¸»é¢˜ç±»åž‹ï¼Œerror|warning|success|primary ï¼ˆé»˜è®¤ 'error' ï¼‰
     * @property {Boolean}             showZero    å½“数值为 0 æ—¶ï¼Œæ˜¯å¦å±•示 Badge ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String}             bgColor     èƒŒæ™¯é¢œè‰²ï¼Œä¼˜å…ˆçº§æ¯”type高,如设置,type参数会失效
     * @property {String}             color         å­—体颜色 ï¼ˆé»˜è®¤ '#ffffff' ï¼‰
     * @property {String}             shape         å¾½æ ‡å½¢çŠ¶ï¼Œcircle-四角均为圆角,horn-左下角为直角 ï¼ˆé»˜è®¤ 'circle' ï¼‰
     * @property {String}             numberType    è®¾ç½®æ•°å­—的显示方式,overflow|ellipsis|limit  ï¼ˆé»˜è®¤ 'overflow' ï¼‰
     * @property {Array}}             offset        è®¾ç½®badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效
     * @property {Boolean}             inverted    æ˜¯å¦åè½¬èƒŒæ™¯å’Œå­—体颜色(默认 false ï¼‰
     * @property {Boolean}             absolute    æ˜¯å¦ç»å¯¹å®šä½ï¼ˆé»˜è®¤ false ï¼‰
     * @property {Object}            customStyle    å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     * @example <u-badge :type="type" :count="count"></u-badge>
     */
    export default {
        name: 'u-badge',
        mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
        computed: {
            // æ˜¯å¦å°†badge中心与父组件右上角重合
            boxStyle() {
                let style = {};
                return style;
            },
            // æ•´ä¸ªç»„件的样式
            badgeStyle() {
                const style = {}
                if(this.color) {
                    style.color = this.color
                }
                if (this.bgColor && !this.inverted) {
                    style.backgroundColor = this.bgColor
                }
                if (this.absolute) {
                    style.position = 'absolute'
                    // å¦‚果有设置offset参数
                    if(this.offset.length) {
                        // top和right分为为offset的第一个和第二个值,如果没有第二个值,则right等于top
                        const top = this.offset[0]
                        const right = this.offset[1] || top
                        style.top = uni.$u.addUnit(top)
                        style.right = uni.$u.addUnit(right)
                    }
                }
                return style
            },
            showValue() {
                switch (this.numberType) {
                    case "overflow":
                        return Number(this.value) > Number(this.max) ? this.max + "+" : this.value
                        break;
                    case "ellipsis":
                        return Number(this.value) > Number(this.max) ? "..." : this.value
                        break;
                    case "limit":
                        return Number(this.value) > 999 ? Number(this.value) >= 9999 ?
                            Math.floor(this.value / 1e4 * 100) / 100 + "w" : Math.floor(this.value /
                                1e3 * 100) / 100 + "k" : this.value
                        break;
                    default:
                        return Number(this.value)
                }
            },
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    $u-badge-primary: $u-primary !default;
    $u-badge-error: $u-error !default;
    $u-badge-success: $u-success !default;
    $u-badge-info: $u-info !default;
    $u-badge-warning: $u-warning !default;
    $u-badge-dot-radius: 100px !default;
    $u-badge-dot-size: 8px !default;
    $u-badge-dot-right: 4px !default;
    $u-badge-dot-top: 0 !default;
    $u-badge-text-font-size: 11px !default;
    $u-badge-text-right: 10px !default;
    $u-badge-text-padding: 2px 5px !default;
    $u-badge-text-align: center !default;
    $u-badge-text-color: #FFFFFF !default;
    .u-badge {
        border-top-right-radius: $u-badge-dot-radius;
        border-top-left-radius: $u-badge-dot-radius;
        border-bottom-left-radius: $u-badge-dot-radius;
        border-bottom-right-radius: $u-badge-dot-radius;
        @include flex;
        line-height: $u-badge-text-font-size;
        text-align: $u-badge-text-align;
        font-size: $u-badge-text-font-size;
        color: $u-badge-text-color;
        &--dot {
            height: $u-badge-dot-size;
            width: $u-badge-dot-size;
        }
        &--inverted {
            font-size: 13px;
        }
        &--not-dot {
            padding: $u-badge-text-padding;
        }
        &--horn {
            border-bottom-left-radius: 0;
        }
        &--primary {
            background-color: $u-badge-primary;
        }
        &--primary--inverted {
            color: $u-badge-primary;
        }
        &--error {
            background-color: $u-badge-error;
        }
        &--error--inverted {
            color: $u-badge-error;
        }
        &--success {
            background-color: $u-badge-success;
        }
        &--success--inverted {
            color: $u-badge-success;
        }
        &--info {
            background-color: $u-badge-info;
        }
        &--info--inverted {
            color: $u-badge-info;
        }
        &--warning {
            background-color: $u-badge-warning;
        }
        &--warning--inverted {
            color: $u-badge-warning;
        }
    }
</style>
uni_modules/uview-ui/components/u-button/nvue.scss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
$u-button-active-opacity:0.75 !default;
$u-button-loading-text-margin-left:4px !default;
$u-button-text-color: #FFFFFF !default;
$u-button-text-plain-error-color:$u-error !default;
$u-button-text-plain-warning-color:$u-warning !default;
$u-button-text-plain-success-color:$u-success !default;
$u-button-text-plain-info-color:$u-info !default;
$u-button-text-plain-primary-color:$u-primary !default;
.u-button {
    &--active {
        opacity: $u-button-active-opacity;
    }
    &--active--plain {
        background-color: rgb(217, 217, 217);
    }
    &__loading-text {
        margin-left:$u-button-loading-text-margin-left;
    }
    &__text,
    &__loading-text {
        color:$u-button-text-color;
    }
    &__text--plain--error {
        color:$u-button-text-plain-error-color;
    }
    &__text--plain--warning {
        color:$u-button-text-plain-warning-color;
    }
    &__text--plain--success{
        color:$u-button-text-plain-success-color;
    }
    &__text--plain--info {
        color:$u-button-text-plain-info-color;
    }
    &__text--plain--primary {
        color:$u-button-text-plain-primary-color;
    }
}
uni_modules/uview-ui/components/u-button/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,161 @@
/*
 * @Author       : LQ
 * @Description  :
 * @version      : 1.0
 * @Date         : 2021-08-16 10:04:04
 * @LastAuthor   : LQ
 * @lastTime     : 2021-08-16 10:04:24
 * @FilePath     : /u-view2.0/uview-ui/components/u-button/props.js
 */
export default {
    props: {
        // æ˜¯å¦ç»†è¾¹æ¡†
        hairline: {
            type: Boolean,
            default: uni.$u.props.button.hairline
        },
        // æŒ‰é’®çš„预置样式,info,primary,error,warning,success
        type: {
            type: String,
            default: uni.$u.props.button.type
        },
        // æŒ‰é’®å°ºå¯¸ï¼Œlarge,normal,small,mini
        size: {
            type: String,
            default: uni.$u.props.button.size
        },
        // æŒ‰é’®å½¢çŠ¶ï¼Œcircle(两边为半圆),square(带圆角)
        shape: {
            type: String,
            default: uni.$u.props.button.shape
        },
        // æŒ‰é’®æ˜¯å¦é•‚空
        plain: {
            type: Boolean,
            default: uni.$u.props.button.plain
        },
        // æ˜¯å¦ç¦æ­¢çŠ¶æ€
        disabled: {
            type: Boolean,
            default: uni.$u.props.button.disabled
        },
        // æ˜¯å¦åŠ è½½ä¸­
        loading: {
            type: Boolean,
            default: uni.$u.props.button.loading
        },
        // åŠ è½½ä¸­æç¤ºæ–‡å­—
        loadingText: {
            type: [String, Number],
            default: uni.$u.props.button.loadingText
        },
        // åŠ è½½çŠ¶æ€å›¾æ ‡ç±»åž‹
        loadingMode: {
            type: String,
            default: uni.$u.props.button.loadingMode
        },
        // åŠ è½½å›¾æ ‡å¤§å°
        loadingSize: {
            type: [String, Number],
            default: uni.$u.props.button.loadingSize
        },
        // å¼€æ”¾èƒ½åŠ›ï¼Œå…·ä½“è¯·çœ‹uniapp稳定关于button组件部分说明
        // https://uniapp.dcloud.io/component/button
        openType: {
            type: String,
            default: uni.$u.props.button.openType
        },
        // ç”¨äºŽ <form> ç»„件,点击分别会触发 <form> ç»„ä»¶çš„ submit/reset äº‹ä»¶
        // å–值为submit(提交表单),reset(重置表单)
        formType: {
            type: String,
            default: uni.$u.props.button.formType
        },
        // æ‰“å¼€ APP æ—¶ï¼Œå‘ APP ä¼ é€’的参数,open-type=launchApp时有效
        // åªå¾®ä¿¡å°ç¨‹åºã€QQ小程序有效
        appParameter: {
            type: String,
            default: uni.$u.props.button.appParameter
        },
        // æŒ‡å®šæ˜¯å¦é˜»æ­¢æœ¬èŠ‚ç‚¹çš„ç¥–å…ˆèŠ‚ç‚¹å‡ºçŽ°ç‚¹å‡»æ€ï¼Œå¾®ä¿¡å°ç¨‹åºæœ‰æ•ˆ
        hoverStopPropagation: {
            type: Boolean,
            default: uni.$u.props.button.hoverStopPropagation
        },
        // æŒ‡å®šè¿”回用户信息的语言,zh_CN ç®€ä½“中文,zh_TW ç¹ä½“中文,en è‹±æ–‡ã€‚只微信小程序有效
        lang: {
            type: String,
            default: uni.$u.props.button.lang
        },
        // ä¼šè¯æ¥æºï¼Œopen-type="contact"时有效。只微信小程序有效
        sessionFrom: {
            type: String,
            default: uni.$u.props.button.sessionFrom
        },
        // ä¼šè¯å†…消息卡片标题,open-type="contact"时有效
        // é»˜è®¤å½“前标题,只微信小程序有效
        sendMessageTitle: {
            type: String,
            default: uni.$u.props.button.sendMessageTitle
        },
        // ä¼šè¯å†…消息卡片点击跳转小程序路径,open-type="contact"时有效
        // é»˜è®¤å½“前分享路径,只微信小程序有效
        sendMessagePath: {
            type: String,
            default: uni.$u.props.button.sendMessagePath
        },
        // ä¼šè¯å†…消息卡片图片,open-type="contact"时有效
        // é»˜è®¤å½“前页面截图,只微信小程序有效
        sendMessageImg: {
            type: String,
            default: uni.$u.props.button.sendMessageImg
        },
        // æ˜¯å¦æ˜¾ç¤ºä¼šè¯å†…消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,
        // ç”¨æˆ·ç‚¹å‡»åŽå¯ä»¥å¿«é€Ÿå‘送小程序消息,open-type="contact"时有效
        showMessageCard: {
            type: Boolean,
            default: uni.$u.props.button.showMessageCard
        },
        // é¢å¤–传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取
        dataName: {
            type: String,
            default: uni.$u.props.button.dataName
        },
        // èŠ‚æµï¼Œä¸€å®šæ—¶é—´å†…åªèƒ½è§¦å‘ä¸€æ¬¡
        throttleTime: {
            type: [String, Number],
            default: uni.$u.props.button.throttleTime
        },
        // æŒ‰ä½åŽå¤šä¹…出现点击态,单位毫秒
        hoverStartTime: {
            type: [String, Number],
            default: uni.$u.props.button.hoverStartTime
        },
        // æ‰‹æŒ‡æ¾å¼€åŽç‚¹å‡»æ€ä¿ç•™æ—¶é—´ï¼Œå•位毫秒
        hoverStayTime: {
            type: [String, Number],
            default: uni.$u.props.button.hoverStayTime
        },
        // æŒ‰é’®æ–‡å­—,之所以通过props传入,是因为slot传入的话
        // nvue中无法控制文字的样式
        text: {
            type: [String, Number],
            default: uni.$u.props.button.text
        },
        // æŒ‰é’®å›¾æ ‡
        icon: {
            type: String,
            default: uni.$u.props.button.icon
        },
        // æŒ‰é’®å›¾æ ‡
        iconColor: {
            type: String,
            default: uni.$u.props.button.icon
        },
        // æŒ‰é’®é¢œè‰²ï¼Œæ”¯æŒä¼ å…¥linear-gradient渐变色
        color: {
            type: String,
            default: uni.$u.props.button.color
        }
    }
}
uni_modules/uview-ui/components/u-button/u-button.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,490 @@
<template>
    <!-- #ifndef APP-NVUE -->
    <button
        :hover-start-time="Number(hoverStartTime)"
        :hover-stay-time="Number(hoverStayTime)"
        :form-type="formType"
        :open-type="openType"
        :app-parameter="appParameter"
        :hover-stop-propagation="hoverStopPropagation"
        :send-message-title="sendMessageTitle"
        :send-message-path="sendMessagePath"
        :lang="lang"
        :data-name="dataName"
        :session-from="sessionFrom"
        :send-message-img="sendMessageImg"
        :show-message-card="showMessageCard"
        @getphonenumber="getphonenumber"
        @getuserinfo="getuserinfo"
        @error="error"
        @opensetting="opensetting"
        @launchapp="launchapp"
        :hover-class="!disabled && !loading ? 'u-button--active' : ''"
        class="u-button u-reset-button"
        :style="[baseColor, $u.addStyle(customStyle)]"
        @tap="clickHandler"
        :class="bemClass"
    >
        <template v-if="loading">
            <u-loading-icon
                :mode="loadingMode"
                :size="textSize * 1.15"
                :color="loadingColor"
            ></u-loading-icon>
            <text
                class="u-button__loading-text"
                :style="[{ fontSize: textSize + 'px' }]"
                >{{ loadingText || text }}</text
            >
        </template>
        <template v-else>
            <u-icon
                v-if="icon"
                :name="icon"
                :color="iconColorCom"
                :size="textSize * 1.35"
                :customStyle="{ marginRight: '2px' }"
            ></u-icon>
            <slot>
                <text
                    class="u-button__text"
                    :style="[{ fontSize: textSize + 'px' }]"
                    >{{ text }}</text
                >
            </slot>
        </template>
    </button>
    <!-- #endif -->
    <!-- #ifdef APP-NVUE -->
    <view
        :hover-start-time="Number(hoverStartTime)"
        :hover-stay-time="Number(hoverStayTime)"
        class="u-button"
        :hover-class="
            !disabled && !loading && !color && (plain || type === 'info')
                ? 'u-button--active--plain'
                : !disabled && !loading && !plain
                ? 'u-button--active'
                : ''
        "
        @tap="clickHandler"
        :class="bemClass"
        :style="[baseColor, $u.addStyle(customStyle)]"
    >
        <template v-if="loading">
            <u-loading-icon
                :mode="loadingMode"
                :size="textSize * 1.15"
                :color="loadingColor"
            ></u-loading-icon>
            <text
                class="u-button__loading-text"
                :style="[nvueTextStyle]"
                :class="[plain && `u-button__text--plain--${type}`]"
                >{{ loadingText || text }}</text
            >
        </template>
        <template v-else>
            <u-icon
                v-if="icon"
                :name="icon"
                :color="iconColorCom"
                :size="textSize * 1.35"
            ></u-icon>
            <text
                class="u-button__text"
                :style="[
                    {
                        marginLeft: icon ? '2px' : 0,
                    },
                    nvueTextStyle,
                ]"
                :class="[plain && `u-button__text--plain--${type}`]"
                >{{ text }}</text
            >
        </template>
    </view>
    <!-- #endif -->
</template>
<script>
import button from "../../libs/mixin/button.js";
import openType from "../../libs/mixin/openType.js";
import props from "./props.js";
/**
 * button æŒ‰é’®
 * @description Button æŒ‰é’®
 * @tutorial https://www.uviewui.com/components/button.html
 *
 * @property {Boolean}            hairline                æ˜¯å¦æ˜¾ç¤ºæŒ‰é’®çš„细边框 (默认 true )
 * @property {String}            type                    æŒ‰é’®çš„预置样式,info,primary,error,warning,success (默认 'info' )
 * @property {String}            size                    æŒ‰é’®å°ºå¯¸ï¼Œlarge,normal,mini ï¼ˆé»˜è®¤ normal)
 * @property {String}            shape                    æŒ‰é’®å½¢çŠ¶ï¼Œcircle(两边为半圆),square(带圆角) ï¼ˆé»˜è®¤ 'square' ï¼‰
 * @property {Boolean}            plain                    æŒ‰é’®æ˜¯å¦é•‚空,背景色透明 ï¼ˆé»˜è®¤ false)
 * @property {Boolean}            disabled                æ˜¯å¦ç¦ç”¨ ï¼ˆé»˜è®¤ false)
 * @property {Boolean}            loading                    æŒ‰é’®åç§°å‰æ˜¯å¦å¸¦ loading å›¾æ ‡(App-nvue å¹³å°ï¼Œåœ¨ ios ä¸Šä¸ºé›ªèŠ±ï¼ŒAndroid上为圆圈) ï¼ˆé»˜è®¤ false)
 * @property {String | Number}    loadingText                åŠ è½½ä¸­æç¤ºæ–‡å­—
 * @property {String}            loadingMode                åŠ è½½çŠ¶æ€å›¾æ ‡ç±»åž‹ ï¼ˆé»˜è®¤ 'spinner' ï¼‰
 * @property {String | Number}    loadingSize                åŠ è½½å›¾æ ‡å¤§å° ï¼ˆé»˜è®¤ 15 ï¼‰
 * @property {String}            openType                å¼€æ”¾èƒ½åŠ›ï¼Œå…·ä½“è¯·çœ‹uniapp稳定关于button组件部分说明
 * @property {String}            formType                ç”¨äºŽ <form> ç»„件,点击分别会触发 <form> ç»„ä»¶çš„ submit/reset äº‹ä»¶
 * @property {String}            appParameter            æ‰“å¼€ APP æ—¶ï¼Œå‘ APP ä¼ é€’的参数,open-type=launchApp时有效 ï¼ˆæ³¨ï¼šåªå¾®ä¿¡å°ç¨‹åºã€QQ小程序有效)
 * @property {Boolean}            hoverStopPropagation    æŒ‡å®šæ˜¯å¦é˜»æ­¢æœ¬èŠ‚ç‚¹çš„ç¥–å…ˆèŠ‚ç‚¹å‡ºçŽ°ç‚¹å‡»æ€ï¼Œå¾®ä¿¡å°ç¨‹åºæœ‰æ•ˆï¼ˆé»˜è®¤ true ï¼‰
 * @property {String}            lang                    æŒ‡å®šè¿”回用户信息的语言,zh_CN ç®€ä½“中文,zh_TW ç¹ä½“中文,en è‹±æ–‡ï¼ˆé»˜è®¤ en ï¼‰
 * @property {String}            sessionFrom                ä¼šè¯æ¥æºï¼ŒopenType="contact"时有效
 * @property {String}            sendMessageTitle        ä¼šè¯å†…消息卡片标题,openType="contact"时有效
 * @property {String}            sendMessagePath            ä¼šè¯å†…消息卡片点击跳转小程序路径,openType="contact"时有效
 * @property {String}            sendMessageImg            ä¼šè¯å†…消息卡片图片,openType="contact"时有效
 * @property {Boolean}            showMessageCard            æ˜¯å¦æ˜¾ç¤ºä¼šè¯å†…消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效(默认false)
 * @property {String}            dataName                é¢å¤–传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取
 * @property {String | Number}    throttleTime            èŠ‚æµï¼Œä¸€å®šæ—¶é—´å†…åªèƒ½è§¦å‘ä¸€æ¬¡ ï¼ˆé»˜è®¤ 0 )
 * @property {String | Number}    hoverStartTime            æŒ‰ä½åŽå¤šä¹…出现点击态,单位毫秒 ï¼ˆé»˜è®¤ 0 )
 * @property {String | Number}    hoverStayTime            æ‰‹æŒ‡æ¾å¼€åŽç‚¹å‡»æ€ä¿ç•™æ—¶é—´ï¼Œå•位毫秒 ï¼ˆé»˜è®¤ 200 )
 * @property {String | Number}    text                    æŒ‰é’®æ–‡å­—,之所以通过props传入,是因为slot传入的话(注:nvue中无法控制文字的样式)
 * @property {String}            icon                    æŒ‰é’®å›¾æ ‡
 * @property {String}            iconColor                æŒ‰é’®å›¾æ ‡é¢œè‰²
 * @property {String}            color                    æŒ‰é’®é¢œè‰²ï¼Œæ”¯æŒä¼ å…¥linear-gradient渐变色
 * @property {Object}            customStyle                å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
 *
 * @event {Function}    click            éžç¦æ­¢å¹¶ä¸”非加载中,才能点击
 * @event {Function}    getphonenumber    open-type="getPhoneNumber"时有效
 * @event {Function}    getuserinfo        ç”¨æˆ·ç‚¹å‡»è¯¥æŒ‰é’®æ—¶ï¼Œä¼šè¿”回获取到的用户信息,从返回参数的detail中获取到的值同uni.getUserInfo
 * @event {Function}    error            å½“使用开放能力时,发生错误的回调
 * @event {Function}    opensetting        åœ¨æ‰“开授权设置页并关闭后回调
 * @event {Function}    launchapp        æ‰“å¼€ APP æˆåŠŸçš„å›žè°ƒ
 * @example <u-button>月落</u-button>
 */
export default {
    name: "u-button",
    // #ifdef MP
    mixins: [uni.$u.mpMixin, uni.$u.mixin, button, openType, props],
    // #endif
    // #ifndef MP
    mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
    // #endif
    data() {
        return {};
    },
    computed: {
        // ç”Ÿæˆbem风格的类名
        bemClass() {
            // this.bem为一个computed变量,在mixin中
            if (!this.color) {
                return this.bem(
                    "button",
                    ["type", "shape", "size"],
                    ["disabled", "plain", "hairline"]
                );
            } else {
                // ç”±äºŽnvue的原因,在有color参数时,不需要传入type,否则会生成type相关的类型,影响最终的样式
                return this.bem(
                    "button",
                    ["shape", "size"],
                    ["disabled", "plain", "hairline"]
                );
            }
        },
        loadingColor() {
            if (this.plain) {
                // å¦‚果有设置color值,则用color值,否则使用type主题颜色
                return this.color
                    ? this.color
                    : uni.$u.config.color[`u-${this.type}`];
            }
            if (this.type === "info") {
                return "#c9c9c9";
            }
            return "rgb(200, 200, 200)";
        },
        iconColorCom() {
            // å¦‚果是镂空状态,设置了color就用color值,否则使用主题颜色,
            // u-icon的color能接受一个主题颜色的值
            if (this.iconColor) return this.iconColor;
            if (this.plain) {
                return this.color ? this.color : this.type;
            } else {
                return this.type === "info" ? "#000000" : "#ffffff";
            }
        },
        baseColor() {
            let style = {};
            if (this.color) {
                // é’ˆå¯¹è‡ªå®šä¹‰äº†color颜色的情况,镂空状态下,就是用自定义的颜色
                style.color = this.plain ? this.color : "white";
                if (!this.plain) {
                    // éžé•‚空,背景色使用自定义的颜色
                    style["background-color"] = this.color;
                }
                if (this.color.indexOf("gradient") !== -1) {
                    // å¦‚果自定义的颜色为渐变色,不显示边框,以及通过backgroundImage设置渐变色
                    // weex文档说明可以写borderWidth的形式,为什么这里需要分开写?
                    // å› ä¸ºweex是阿里巴巴为了部门业绩考核而做的你懂的东西,所以需要这么写才有效
                    style.borderTopWidth = 0;
                    style.borderRightWidth = 0;
                    style.borderBottomWidth = 0;
                    style.borderLeftWidth = 0;
                    if (!this.plain) {
                        style.backgroundImage = this.color;
                    }
                } else {
                    // éžæ¸å˜è‰²ï¼Œåˆ™è®¾ç½®è¾¹æ¡†ç›¸å…³çš„属性
                    style.borderColor = this.color;
                    style.borderWidth = "1px";
                    style.borderStyle = "solid";
                }
            }
            return style;
        },
        // nvue版本按钮的字体不会继承父组件的颜色,需要对每一个text组件进行单独的设置
        nvueTextStyle() {
            let style = {};
            // é’ˆå¯¹è‡ªå®šä¹‰äº†color颜色的情况,镂空状态下,就是用自定义的颜色
            if (this.type === "info") {
                style.color = "#323233";
            }
            if (this.color) {
                style.color = this.plain ? this.color : "white";
            }
            style.fontSize = this.textSize + "px";
            return style;
        },
        // å­—体大小
        textSize() {
            let fontSize = 14,
                { size } = this;
            if (size === "large") fontSize = 16;
            if (size === "normal") fontSize = 14;
            if (size === "small") fontSize = 12;
            if (size === "mini") fontSize = 10;
            return fontSize;
        },
    },
    methods: {
        clickHandler() {
            // éžç¦æ­¢å¹¶ä¸”非加载中,才能点击
            if (!this.disabled && !this.loading) {
                // è¿›è¡ŒèŠ‚æµæŽ§åˆ¶ï¼Œæ¯this.throttle毫秒内,只在开始处执行
                uni.$u.throttle(() => {
                    this.$emit("click");
                }, this.throttleTime);
            }
        },
        // ä¸‹é¢ä¸ºå¯¹æŽ¥uniapp官方按钮开放能力事件回调的对接
        getphonenumber(res) {
            this.$emit("getphonenumber", res);
        },
        getuserinfo(res) {
            this.$emit("getuserinfo", res);
        },
        error(res) {
            this.$emit("error", res);
        },
        opensetting(res) {
            this.$emit("opensetting", res);
        },
        launchapp(res) {
            this.$emit("launchapp", res);
        },
    },
};
</script>
<style lang="scss" scoped>
@import "../../libs/css/components.scss";
/* #ifndef APP-NVUE */
@import "./vue.scss";
/* #endif */
/* #ifdef APP-NVUE */
@import "./nvue.scss";
/* #endif */
$u-button-u-button-height: 40px !default;
$u-button-text-font-size: 15px !default;
$u-button-loading-text-font-size: 15px !default;
$u-button-loading-text-margin-left: 4px !default;
$u-button-large-width: 100% !default;
$u-button-large-height: 50px !default;
$u-button-normal-padding: 0 12px !default;
$u-button-large-padding: 0 15px !default;
$u-button-normal-font-size: 14px !default;
$u-button-small-min-width: 60px !default;
$u-button-small-height: 30px !default;
$u-button-small-padding: 0px 8px !default;
$u-button-mini-padding: 0px 8px !default;
$u-button-small-font-size: 12px !default;
$u-button-mini-height: 22px !default;
$u-button-mini-font-size: 10px !default;
$u-button-mini-min-width: 50px !default;
$u-button-disabled-opacity: 0.5 !default;
$u-button-info-color: #323233 !default;
$u-button-info-background-color: #fff !default;
$u-button-info-border-color: #ebedf0 !default;
$u-button-info-border-width: 1px !default;
$u-button-info-border-style: solid !default;
$u-button-success-color: #fff !default;
$u-button-success-background-color: $u-success !default;
$u-button-success-border-color: $u-button-success-background-color !default;
$u-button-success-border-width: 1px !default;
$u-button-success-border-style: solid !default;
$u-button-primary-color: #fff !default;
$u-button-primary-background-color: $u-primary !default;
$u-button-primary-border-color: $u-button-primary-background-color !default;
$u-button-primary-border-width: 1px !default;
$u-button-primary-border-style: solid !default;
$u-button-error-color: #fff !default;
$u-button-error-background-color: $u-error !default;
$u-button-error-border-color: $u-button-error-background-color !default;
$u-button-error-border-width: 1px !default;
$u-button-error-border-style: solid !default;
$u-button-warning-color: #fff !default;
$u-button-warning-background-color: $u-warning !default;
$u-button-warning-border-color: $u-button-warning-background-color !default;
$u-button-warning-border-width: 1px !default;
$u-button-warning-border-style: solid !default;
$u-button-block-width: 100% !default;
$u-button-circle-border-top-right-radius: 100px !default;
$u-button-circle-border-top-left-radius: 100px !default;
$u-button-circle-border-bottom-left-radius: 100px !default;
$u-button-circle-border-bottom-right-radius: 100px !default;
$u-button-square-border-top-right-radius: 3px !default;
$u-button-square-border-top-left-radius: 3px !default;
$u-button-square-border-bottom-left-radius: 3px !default;
$u-button-square-border-bottom-right-radius: 3px !default;
$u-button-icon-min-width: 1em !default;
$u-button-plain-background-color: #fff !default;
$u-button-hairline-border-width: 0.5px !default;
.u-button {
    height: $u-button-u-button-height;
    position: relative;
    align-items: center;
    justify-content: center;
    @include flex;
    /* #ifndef APP-NVUE */
    box-sizing: border-box;
    /* #endif */
    flex-direction: row;
    &__text {
        font-size: $u-button-text-font-size;
    }
    &__loading-text {
        font-size: $u-button-loading-text-font-size;
        margin-left: $u-button-loading-text-margin-left;
    }
    &--large {
        /* #ifndef APP-NVUE */
        width: $u-button-large-width;
        /* #endif */
        height: $u-button-large-height;
        padding: $u-button-large-padding;
    }
    &--normal {
        padding: $u-button-normal-padding;
        font-size: $u-button-normal-font-size;
    }
    &--small {
        /* #ifndef APP-NVUE */
        min-width: $u-button-small-min-width;
        /* #endif */
        height: $u-button-small-height;
        padding: $u-button-small-padding;
        font-size: $u-button-small-font-size;
    }
    &--mini {
        height: $u-button-mini-height;
        font-size: $u-button-mini-font-size;
        /* #ifndef APP-NVUE */
        min-width: $u-button-mini-min-width;
        /* #endif */
        padding: $u-button-mini-padding;
    }
    &--disabled {
        opacity: $u-button-disabled-opacity;
    }
    &--info {
        color: $u-button-info-color;
        background-color: $u-button-info-background-color;
        border-color: $u-button-info-border-color;
        border-width: $u-button-info-border-width;
        border-style: $u-button-info-border-style;
    }
    &--success {
        color: $u-button-success-color;
        background-color: $u-button-success-background-color;
        border-color: $u-button-success-border-color;
        border-width: $u-button-success-border-width;
        border-style: $u-button-success-border-style;
    }
    &--primary {
        color: $u-button-primary-color;
        background-color: $u-button-primary-background-color;
        border-color: $u-button-primary-border-color;
        border-width: $u-button-primary-border-width;
        border-style: $u-button-primary-border-style;
    }
    &--error {
        color: $u-button-error-color;
        background-color: $u-button-error-background-color;
        border-color: $u-button-error-border-color;
        border-width: $u-button-error-border-width;
        border-style: $u-button-error-border-style;
    }
    &--warning {
        color: $u-button-warning-color;
        background-color: $u-button-warning-background-color;
        border-color: $u-button-warning-border-color;
        border-width: $u-button-warning-border-width;
        border-style: $u-button-warning-border-style;
    }
    &--block {
        @include flex;
        width: $u-button-block-width;
    }
    &--circle {
        border-top-right-radius: $u-button-circle-border-top-right-radius;
        border-top-left-radius: $u-button-circle-border-top-left-radius;
        border-bottom-left-radius: $u-button-circle-border-bottom-left-radius;
        border-bottom-right-radius: $u-button-circle-border-bottom-right-radius;
    }
    &--square {
        border-bottom-left-radius: $u-button-square-border-top-right-radius;
        border-bottom-right-radius: $u-button-square-border-top-left-radius;
        border-top-left-radius: $u-button-square-border-bottom-left-radius;
        border-top-right-radius: $u-button-square-border-bottom-right-radius;
    }
    &__icon {
        /* #ifndef APP-NVUE */
        min-width: $u-button-icon-min-width;
        line-height: inherit !important;
        vertical-align: top;
        /* #endif */
    }
    &--plain {
        background-color: $u-button-plain-background-color;
    }
    &--hairline {
        border-width: $u-button-hairline-border-width !important;
    }
}
</style>
uni_modules/uview-ui/components/u-button/vue.scss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,80 @@
// nvue下hover-class无效
$u-button-before-top:50% !default;
$u-button-before-left:50% !default;
$u-button-before-width:100% !default;
$u-button-before-height:100% !default;
$u-button-before-transform:translate(-50%, -50%) !default;
$u-button-before-opacity:0 !default;
$u-button-before-background-color:#000 !default;
$u-button-before-border-color:#000 !default;
$u-button-active-before-opacity:.15 !default;
$u-button-icon-margin-left:4px !default;
$u-button-plain-u-button-info-color:$u-info;
$u-button-plain-u-button-success-color:$u-success;
$u-button-plain-u-button-error-color:$u-error;
$u-button-plain-u-button-warning-color:$u-error;
.u-button {
    width: 100%;
    &__text {
        white-space: nowrap;
        line-height: 1;
    }
    &:before {
        position: absolute;
        top:$u-button-before-top;
        left:$u-button-before-left;
        width:$u-button-before-width;
        height:$u-button-before-height;
        border: inherit;
        border-radius: inherit;
        transform:$u-button-before-transform;
        opacity:$u-button-before-opacity;
        content: " ";
        background-color:$u-button-before-background-color;
        border-color:$u-button-before-border-color;
    }
    &--active {
        &:before {
            opacity: .15
        }
    }
    &__icon+&__text:not(:empty),
    &__loading-text {
        margin-left:$u-button-icon-margin-left;
    }
    &--plain {
        &.u-button--primary {
            color: $u-primary;
        }
    }
    &--plain {
        &.u-button--info {
            color:$u-button-plain-u-button-info-color;
        }
    }
    &--plain {
        &.u-button--success {
            color:$u-button-plain-u-button-success-color;
        }
    }
    &--plain {
        &.u-button--error {
            color:$u-button-plain-u-button-error-color;
        }
    }
    &--plain {
        &.u-button--warning {
            color:$u-button-plain-u-button-warning-color;
        }
    }
}
uni_modules/uview-ui/components/u-calendar/header.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,99 @@
<template>
    <view class="u-calendar-header u-border-bottom">
        <text
            class="u-calendar-header__title"
            v-if="showTitle"
        >{{ title }}</text>
        <text
            class="u-calendar-header__subtitle"
            v-if="showSubtitle"
        >{{ subtitle }}</text>
        <view class="u-calendar-header__weekdays">
            <text class="u-calendar-header__weekdays__weekday">一</text>
            <text class="u-calendar-header__weekdays__weekday">二</text>
            <text class="u-calendar-header__weekdays__weekday">三</text>
            <text class="u-calendar-header__weekdays__weekday">四</text>
            <text class="u-calendar-header__weekdays__weekday">五</text>
            <text class="u-calendar-header__weekdays__weekday">六</text>
            <text class="u-calendar-header__weekdays__weekday">日</text>
        </view>
    </view>
</template>
<script>
    export default {
        name: 'u-calendar-header',
        mixins: [uni.$u.mpMixin, uni.$u.mixin],
        props: {
            // æ ‡é¢˜
            title: {
                type: String,
                default: ''
            },
            // å‰¯æ ‡é¢˜
            subtitle: {
                type: String,
                default: ''
            },
            // æ˜¯å¦æ˜¾ç¤ºæ ‡é¢˜
            showTitle: {
                type: Boolean,
                default: true
            },
            // æ˜¯å¦æ˜¾ç¤ºå‰¯æ ‡é¢˜
            showSubtitle: {
                type: Boolean,
                default: true
            },
        },
        data() {
            return {
            }
        },
        methods: {
            name() {
            }
        },
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-calendar-header {
        padding-bottom: 4px;
        &__title {
            font-size: 16px;
            color: $u-main-color;
            text-align: center;
            height: 42px;
            line-height: 42px;
            font-weight: bold;
        }
        &__subtitle {
            font-size: 14px;
            color: $u-main-color;
            height: 40px;
            text-align: center;
            line-height: 40px;
            font-weight: bold;
        }
        &__weekdays {
            @include flex;
            justify-content: space-between;
            &__weekday {
                font-size: 13px;
                color: $u-main-color;
                line-height: 30px;
                flex: 1;
                text-align: center;
            }
        }
    }
</style>
uni_modules/uview-ui/components/u-calendar/month.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,579 @@
<template>
    <view class="u-calendar-month-wrapper" ref="u-calendar-month-wrapper">
        <view v-for="(item, index) in months" :key="index" :class="[`u-calendar-month-${index}`]"
            :ref="`u-calendar-month-${index}`" :id="`month-${index}`">
            <text v-if="index !== 0" class="u-calendar-month__title">{{ item.year }}å¹´{{ item.month }}月</text>
            <view class="u-calendar-month__days">
                <view v-if="showMark" class="u-calendar-month__days__month-mark-wrapper">
                    <text class="u-calendar-month__days__month-mark-wrapper__text">{{ item.month }}</text>
                </view>
                <view class="u-calendar-month__days__day" v-for="(item1, index1) in item.date" :key="index1"
                    :style="[dayStyle(index, index1, item1)]" @tap="clickHandler(index, index1, item1)"
                    :class="[item1.selected && 'u-calendar-month__days__day__select--selected']">
                    <view class="u-calendar-month__days__day__select" :style="[daySelectStyle(index, index1, item1)]">
                        <text class="u-calendar-month__days__day__select__info"
                            :class="[item1.disabled && 'u-calendar-month__days__day__select__info--disabled']"
                            :style="[textStyle(item1)]">{{ item1.day }}</text>
                        <text v-if="getBottomInfo(index, index1, item1)"
                            class="u-calendar-month__days__day__select__buttom-info"
                            :class="[item1.disabled && 'u-calendar-month__days__day__select__buttom-info--disabled']"
                            :style="[textStyle(item1)]">{{ getBottomInfo(index, index1, item1) }}</text>
                        <text v-if="item1.dot" class="u-calendar-month__days__day__select__dot"></text>
                    </view>
                </view>
            </view>
        </view>
    </view>
</template>
<script>
    // #ifdef APP-NVUE
    // ç”±äºŽnvue不支持百分比单位,需要查询宽度来计算每个日期的宽度
    const dom = uni.requireNativePlugin('dom')
    // #endif
    import dayjs from '../../libs/util/dayjs.js';
    export default {
        name: 'u-calendar-month',
        mixins: [uni.$u.mpMixin, uni.$u.mixin],
        props: {
            // æ˜¯å¦æ˜¾ç¤ºæœˆä»½èƒŒæ™¯è‰²
            showMark: {
                type: Boolean,
                default: true
            },
            // ä¸»é¢˜è‰²ï¼Œå¯¹åº•部按钮和选中日期有效
            color: {
                type: String,
                default: '#3c9cff'
            },
            // æœˆä»½æ•°æ®
            months: {
                type: Array,
                default: () => []
            },
            // æ—¥æœŸé€‰æ‹©ç±»åž‹
            mode: {
                type: String,
                default: 'single'
            },
            // æ—¥æœŸè¡Œé«˜
            rowHeight: {
                type: [String, Number],
                default: 58
            },
            // mode=multiple时,最多可选多少个日期
            maxCount: {
                type: [String, Number],
                default: Infinity
            },
            // mode=range时,第一个日期底部的提示文字
            startText: {
                type: String,
                default: '开始'
            },
            // mode=range时,最后一个日期底部的提示文字
            endText: {
                type: String,
                default: '结束'
            },
            // é»˜è®¤é€‰ä¸­çš„æ—¥æœŸï¼Œmode为multiple或range是必须为数组格式
            defaultDate: {
                type: [Array, String, Date],
                default: null
            },
            // æœ€å°çš„可选日期
            minDate: {
                type: [String, Number],
                default: 0
            },
            // æœ€å¤§å¯é€‰æ—¥æœŸ
            maxDate: {
                type: [String, Number],
                default: 0
            },
            // å¦‚果没有设置maxDate,则往后推多少个月
            maxMonth: {
                type: [String, Number],
                default: 2
            },
            // æ˜¯å¦ä¸ºåªè¯»çŠ¶æ€ï¼Œåªè¯»çŠ¶æ€ä¸‹ç¦æ­¢é€‰æ‹©æ—¥æœŸ
            readonly: {
                type: Boolean,
                default: uni.$u.props.calendar.readonly
            },
            // æ—¥æœŸåŒºé—´æœ€å¤šå¯é€‰å¤©æ•°ï¼Œé»˜è®¤æ— é™åˆ¶ï¼Œmode = range时有效
            maxRange: {
                type: [Number, String],
                default: Infinity
            },
            // èŒƒå›´é€‰æ‹©è¶…过最多可选天数时的提示文案,mode = range时有效
            rangePrompt: {
                type: String,
                default: ''
            },
            // èŒƒå›´é€‰æ‹©è¶…过最多可选天数时,是否展示提示文案,mode = range时有效
            showRangePrompt: {
                type: Boolean,
                default: true
            },
            // æ˜¯å¦å…è®¸æ—¥æœŸèŒƒå›´çš„起止时间为同一天,mode = range时有效
            allowSameDay: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                // æ¯ä¸ªæ—¥æœŸçš„宽度
                width: 0,
                // å½“前选中的日期item
                item: {},
                selected: []
            }
        },
        watch: {
            selectedChange: {
                immediate: true,
                handler(n) {
                    this.setDefaultDate()
                }
            }
        },
        computed: {
            // å¤šä¸ªæ¡ä»¶çš„变化,会引起选中日期的变化,这里统一管理监听
            selectedChange() {
                return [this.minDate, this.maxDate, this.defaultDate]
            },
            dayStyle(index1, index2, item) {
                return (index1, index2, item) => {
                    const style = {}
                    let week = item.week
                    // ä¸è¿›è¡Œå››èˆäº”入的形式保留2位小数
                    const dayWidth = Number(parseFloat(this.width / 7).toFixed(3).slice(0, -1))
                    // å¾—出每个日期的宽度
                    // #ifdef APP-NVUE
                    style.width = uni.$u.addUnit(dayWidth)
                    // #endif
                    style.height = uni.$u.addUnit(this.rowHeight)
                    if (index2 === 0) {
                        // èŽ·å–å½“å‰ä¸ºæ˜ŸæœŸå‡ ï¼Œå¦‚æžœä¸º0,则为星期天,减一为每月第一天时,需要向左偏移的item个数
                        week = (week === 0 ? 7 : week) - 1
                        style.marginLeft = uni.$u.addUnit(week * dayWidth)
                    }
                    if (this.mode === 'range') {
                        // ä¹‹æ‰€ä»¥éœ€è¦è¿™ä¹ˆå†™ï¼Œæ˜¯å› ä¸ºDCloud公司的iOS客户端的开发者能力有限导致的bug
                        style.paddingLeft = 0
                        style.paddingRight = 0
                        style.paddingBottom = 0
                        style.paddingTop = 0
                    }
                    return style
                }
            },
            daySelectStyle() {
                return (index1, index2, item) => {
                    let date = dayjs(item.date).format("YYYY-MM-DD"),
                        style = {}
                    // åˆ¤æ–­date是否在selected数组中,因为月份可能会需要补0,所以使用dateSame判断,而不用数组的includes判断
                    if (this.selected.some(item => this.dateSame(item, date))) {
                        style.backgroundColor = this.color
                    }
                    if (this.mode === 'single') {
                        if (date === this.selected[0]) {
                            // å› ä¸ºéœ€è¦å¯¹nvue的兼容,只能这么写,无法缩写,也无法通过类名控制等等
                            style.borderTopLeftRadius = '3px'
                            style.borderBottomLeftRadius = '3px'
                            style.borderTopRightRadius = '3px'
                            style.borderBottomRightRadius = '3px'
                        }
                    } else if (this.mode === 'range') {
                        if (this.selected.length >= 2) {
                            const len = this.selected.length - 1
                            // ç¬¬ä¸€ä¸ªæ—¥æœŸè®¾ç½®å·¦ä¸Šè§’和左下角的圆角
                            if (this.dateSame(date, this.selected[0])) {
                                style.borderTopLeftRadius = '3px'
                                style.borderBottomLeftRadius = '3px'
                            }
                            // æœ€åŽä¸€ä¸ªæ—¥æœŸè®¾ç½®å³ä¸Šè§’和右下角的圆角
                            if (this.dateSame(date, this.selected[len])) {
                                style.borderTopRightRadius = '3px'
                                style.borderBottomRightRadius = '3px'
                            }
                            // å¤„于第一和最后一个之间的日期,背景色设置为浅色,通过将对应颜色进行等分,再取其尾部的颜色值
                            if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
                                    .selected[len]))) {
                                style.backgroundColor = uni.$u.colorGradient(this.color, '#ffffff', 100)[90]
                                // å¢žåŠ ä¸€ä¸ªé€æ˜Žåº¦ï¼Œè®©èŒƒå›´åŒºé—´çš„èƒŒæ™¯è‰²ä¹Ÿèƒ½çœ‹åˆ°åº•éƒ¨çš„mark水印字符
                                style.opacity = 0.7
                            }
                        } else if (this.selected.length === 1) {
                            // ä¹‹æ‰€ä»¥éœ€è¦è¿™ä¹ˆå†™ï¼Œæ˜¯å› ä¸ºDCloud公司的iOS客户端的开发者能力有限导致的bug
                            // è¿›è¡Œè¿˜åŽŸæ“ä½œï¼Œå¦åˆ™åœ¨nvue的iOS,uni-app有bug,会导致诡异的表现
                            style.borderTopLeftRadius = '3px'
                            style.borderBottomLeftRadius = '3px'
                        }
                    } else {
                        if (this.selected.some(item => this.dateSame(item, date))) {
                            style.borderTopLeftRadius = '3px'
                            style.borderBottomLeftRadius = '3px'
                            style.borderTopRightRadius = '3px'
                            style.borderBottomRightRadius = '3px'
                        }
                    }
                    return style
                }
            },
            // æŸä¸ªæ—¥æœŸæ˜¯å¦è¢«é€‰ä¸­
            textStyle() {
                return (item) => {
                    const date = dayjs(item.date).format("YYYY-MM-DD"),
                        style = {}
                    // é€‰ä¸­çš„æ—¥æœŸï¼Œæç¤ºæ–‡å­—设置白色
                    if (this.selected.some(item => this.dateSame(item, date))) {
                        style.color = '#ffffff'
                    }
                    if (this.mode === 'range') {
                        const len = this.selected.length - 1
                        // å¦‚果是范围选择模式,第一个和最后一个之间的日期,文字颜色设置为高亮的主题色
                        if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
                                .selected[len]))) {
                            style.color = this.color
                        }
                    }
                    return style
                }
            },
            // èŽ·å–åº•éƒ¨çš„æç¤ºæ–‡å­—
            getBottomInfo() {
                return (index1, index2, item) => {
                    const date = dayjs(item.date).format("YYYY-MM-DD")
                    const bottomInfo = item.bottomInfo
                    // å½“为日期范围模式时,且选择的日期个数大于0时
                    if (this.mode === 'range' && this.selected.length > 0) {
                        if (this.selected.length === 1) {
                            // é€‰æ‹©äº†ä¸€ä¸ªæ—¥æœŸæ—¶ï¼Œå¦‚果当前日期为数组中的第一个日期,则显示底部文字为“开始”
                            if (this.dateSame(date, this.selected[0])) return this.startText
                            else return bottomInfo
                        } else {
                            const len = this.selected.length - 1
                            // å¦‚果数组中的日期大于2个时,第一个和最后一个显示为开始和结束日期
                            if (this.dateSame(date, this.selected[0]) && this.dateSame(date, this.selected[1]) &&
                                len === 1) {
                                // å¦‚果长度为2,且第一个等于第二个日期,则提示语放在同一个item中
                                return `${this.startText}/${this.endText}`
                            } else if (this.dateSame(date, this.selected[0])) {
                                return this.startText
                            } else if (this.dateSame(date, this.selected[len])) {
                                return this.endText
                            } else {
                                return bottomInfo
                            }
                        }
                    } else {
                        return bottomInfo
                    }
                }
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                // åˆå§‹åŒ–默认选中
                this.$emit('monthSelected', this.selected)
                this.$nextTick(() => {
                    // è¿™é‡Œéœ€è¦å¦ä¸€ä¸ªå»¶æ—¶ï¼Œå› ä¸ºèŽ·å–å®½åº¦åŽï¼Œä¼šè¿›è¡Œæœˆä»½æ•°æ®æ¸²æŸ“ï¼Œåªæœ‰æ¸²æŸ“å®Œæˆä¹‹åŽï¼Œæ‰æœ‰çœŸæ­£çš„é«˜åº¦
                    // å› ä¸ºnvue下,$nextTick并不是100%可靠的
                    uni.$u.sleep(10).then(() => {
                        this.getWrapperWidth()
                        this.getMonthRect()
                    })
                })
            },
            // åˆ¤æ–­ä¸¤ä¸ªæ—¥æœŸæ˜¯å¦ç›¸ç­‰
            dateSame(date1, date2) {
                return dayjs(date1).isSame(dayjs(date2))
            },
            // èŽ·å–æœˆä»½æ•°æ®åŒºåŸŸçš„å®½åº¦ï¼Œå› ä¸ºnvue不支持百分比,所以无法通过css设置每个日期item的宽度
            getWrapperWidth() {
                // #ifdef APP-NVUE
                dom.getComponentRect(this.$refs['u-calendar-month-wrapper'], res => {
                    this.width = res.size.width
                })
                // #endif
                // #ifndef APP-NVUE
                this.$uGetRect('.u-calendar-month-wrapper').then(size => {
                    this.width = size.width
                })
                // #endif
            },
            getMonthRect() {
                // èŽ·å–æ¯ä¸ªæœˆä»½æ•°æ®çš„å°ºå¯¸ï¼Œç”¨äºŽçˆ¶ç»„ä»¶åœ¨scroll-view滚动事件中,监听当前滚动到了第几个月份
                const promiseAllArr = this.months.map((item, index) => this.getMonthRectByPromise(
                    `u-calendar-month-${index}`))
                // ä¸€æ¬¡æ€§è¿”回
                Promise.all(promiseAllArr).then(
                    sizes => {
                        let height = 1
                        const topArr = []
                        for (let i = 0; i < this.months.length; i++) {
                            // æ·»åŠ åˆ°months数组中,供scroll-view滚动事件中,判断当前滚动到哪个月份
                            topArr[i] = height
                            height += sizes[i].height
                        }
                        // ç”±äºŽå¾®ä¿¡ä¸‹ï¼Œæ— æ³•通过this.months[i].top的形式(引用类型)去修改父组件的month的top值,所以使用事件形式对外发出
                        this.$emit('updateMonthTop', topArr)
                    })
            },
            // èŽ·å–æ¯ä¸ªæœˆä»½åŒºåŸŸçš„å°ºå¯¸
            getMonthRectByPromise(el) {
                // #ifndef APP-NVUE
                // $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://www.uviewui.com/js/getRect.html
                // ç»„件内部一般用this.$uGetRect,对外的为uni.$u.getRect,二者功能一致,名称不同
                return new Promise(resolve => {
                    this.$uGetRect(`.${el}`).then(size => {
                        resolve(size)
                    })
                })
                // #endif
                // #ifdef APP-NVUE
                // nvue下,使用dom模块查询元素高度
                // è¿”回一个promise,让调用此方法的主体能使用then回调
                return new Promise(resolve => {
                    dom.getComponentRect(this.$refs[el][0], res => {
                        resolve(res.size)
                    })
                })
                // #endif
            },
            // ç‚¹å‡»æŸä¸€ä¸ªæ—¥æœŸ
            clickHandler(index1, index2, item) {
                if (this.readonly) {
                    return;
                }
                this.item = item
                const date = dayjs(item.date).format("YYYY-MM-DD")
                if (item.disabled) return
                // å¯¹ä¸Šä¸€æ¬¡é€‰æ‹©çš„æ—¥æœŸæ•°ç»„进行深度克隆
                let selected = uni.$u.deepClone(this.selected)
                if (this.mode === 'single') {
                    // å•选情况下,让数组中的元素为当前点击的日期
                    selected = [date]
                } else if (this.mode === 'multiple') {
                    if (selected.some(item => this.dateSame(item, date))) {
                        // å¦‚果点击的日期已在数组中,则进行移除操作,也就是达到反选的效果
                        const itemIndex = selected.findIndex(item => item === date)
                        selected.splice(itemIndex, 1)
                    } else {
                        // å¦‚果点击的日期不在数组中,且已有的长度小于总可选长度时,则添加到数组中去
                        if (selected.length < this.maxCount) selected.push(date)
                    }
                } else {
                    // é€‰æ‹©åŒºé—´å½¢å¼
                    if (selected.length === 0 || selected.length >= 2) {
                        // å¦‚果原来就为0或者大于2的长度,则当前点击的日期,就是开始日期
                        selected = [date]
                    } else if (selected.length === 1) {
                        // å¦‚果已经选择了开始日期
                        const existsDate = selected[0]
                        // å¦‚果当前选择的日期小于上一次选择的日期,则当前的日期定为开始日期
                        if (dayjs(date).isBefore(existsDate)) {
                            selected = [date]
                        } else if (dayjs(date).isAfter(existsDate)) {
                            // å½“前日期减去最大可选的日期天数,如果大于起始时间,则进行提示
                            if(dayjs(dayjs(date).subtract(this.maxRange, 'day')).isAfter(dayjs(selected[0])) && this.showRangePrompt) {
                                if(this.rangePrompt) {
                                    uni.$u.toast(this.rangePrompt)
                                } else {
                                    uni.$u.toast(`选择天数不能超过 ${this.maxRange} å¤©`)
                                }
                                return
                            }
                            // å¦‚果当前日期大于已有日期,将当前的添加到数组尾部
                            selected.push(date)
                            const startDate = selected[0]
                            const endDate = selected[1]
                            const arr = []
                            let i = 0
                            do {
                                // å°†å¼€å§‹å’Œç»“束日期之间的日期添加到数组中
                                arr.push(dayjs(startDate).add(i, 'day').format("YYYY-MM-DD"))
                                i++
                                // ç´¯åŠ çš„æ—¥æœŸå°äºŽç»“æŸæ—¥æœŸæ—¶ï¼Œç»§ç»­ä¸‹ä¸€æ¬¡çš„å¾ªçŽ¯
                            } while (dayjs(startDate).add(i, 'day').isBefore(dayjs(endDate)))
                            // ä¸ºäº†ä¸€æ¬¡æ€§ä¿®æ”¹æ•°ç»„,避免computed中多次触发,这里才用arr变量一次性赋值的方式,同时将最后一个日期添加近来
                            arr.push(endDate)
                            selected = arr
                        } else {
                            // é€‰æ‹©åŒºé—´æ—¶ï¼Œåªæœ‰ä¸€ä¸ªæ—¥æœŸçš„æƒ…况下,且不允许选择起止为同一天的话,不允许选择自己
                            if (selected[0] === date && !this.allowSameDay) return
                            selected.push(date)
                        }
                    }
                }
                this.setSelected(selected)
            },
            // è®¾ç½®é»˜è®¤æ—¥æœŸ
            setDefaultDate() {
                if (!this.defaultDate) {
                    // å¦‚果没有设置默认日期,则将当天日期设置为默认选中的日期
                    const selected = [dayjs().format("YYYY-MM-DD")]
                    return this.setSelected(selected, false)
                }
                let defaultDate = []
                const minDate = this.minDate || dayjs().format("YYYY-MM-DD")
                const maxDate = this.maxDate || dayjs(minDate).add(this.maxMonth - 1, 'month').format("YYYY-MM-DD")
                if (this.mode === 'single') {
                    // å•选模式,可以是字符串或数组,Date对象等
                    if (!uni.$u.test.array(this.defaultDate)) {
                        defaultDate = [dayjs(this.defaultDate).format("YYYY-MM-DD")]
                    } else {
                        defaultDate = [this.defaultDate[0]]
                    }
                } else {
                    // å¦‚果为非数组,则不执行
                    if (!uni.$u.test.array(this.defaultDate)) return
                    defaultDate = this.defaultDate
                }
                // è¿‡æ»¤ç”¨æˆ·ä¼ é€’的默认数组,取出只在可允许最大值与最小值之间的元素
                defaultDate = defaultDate.filter(item => {
                    return dayjs(item).isAfter(dayjs(minDate).subtract(1, 'day')) && dayjs(item).isBefore(dayjs(
                        maxDate).add(1, 'day'))
                })
                this.setSelected(defaultDate, false)
            },
            setSelected(selected, event = true) {
                this.selected = selected
                event && this.$emit('monthSelected', this.selected)
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-calendar-month-wrapper {
        margin-top: 4px;
    }
    .u-calendar-month {
        &__title {
            font-size: 14px;
            line-height: 42px;
            height: 42px;
            color: $u-main-color;
            text-align: center;
            font-weight: bold;
        }
        &__days {
            position: relative;
            @include flex;
            flex-wrap: wrap;
            &__month-mark-wrapper {
                position: absolute;
                top: 0;
                bottom: 0;
                left: 0;
                right: 0;
                @include flex;
                justify-content: center;
                align-items: center;
                &__text {
                    font-size: 155px;
                    color: rgba(231, 232, 234, 0.83);
                }
            }
            &__day {
                @include flex;
                padding: 2px;
                /* #ifndef APP-NVUE */
                // vue下使用css进行宽度计算,因为某些安卓机会无法进行js获取父元素宽度进行计算得出,会有偏移
                width: calc(100% / 7);
                box-sizing: border-box;
                /* #endif */
                &__select {
                    flex: 1;
                    @include flex;
                    align-items: center;
                    justify-content: center;
                    position: relative;
                    &__dot {
                        width: 7px;
                        height: 7px;
                        border-radius: 100px;
                        background-color: $u-error;
                        position: absolute;
                        top: 12px;
                        right: 7px;
                    }
                    &__buttom-info {
                        color: $u-content-color;
                        text-align: center;
                        position: absolute;
                        bottom: 5px;
                        font-size: 10px;
                        text-align: center;
                        left: 0;
                        right: 0;
                        &--selected {
                            color: #ffffff;
                        }
                        &--disabled {
                            color: #cacbcd;
                        }
                    }
                    &__info {
                        text-align: center;
                        font-size: 16px;
                        &--selected {
                            color: #ffffff;
                        }
                        &--disabled {
                            color: #cacbcd;
                        }
                    }
                    &--selected {
                        background-color: $u-primary;
                        @include flex;
                        justify-content: center;
                        align-items: center;
                        flex: 1;
                        border-radius: 3px;
                    }
                    &--range-selected {
                        opacity: 0.3;
                        border-radius: 0;
                    }
                    &--range-start-selected {
                        border-top-right-radius: 0;
                        border-bottom-right-radius: 0;
                    }
                    &--range-end-selected {
                        border-top-left-radius: 0;
                        border-bottom-left-radius: 0;
                    }
                }
            }
        }
    }
</style>
uni_modules/uview-ui/components/u-calendar/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,144 @@
export default {
    props: {
        // æ—¥åŽ†é¡¶éƒ¨æ ‡é¢˜
        title: {
            type: String,
            default: uni.$u.props.calendar.title
        },
        // æ˜¯å¦æ˜¾ç¤ºæ ‡é¢˜
        showTitle: {
            type: Boolean,
            default: uni.$u.props.calendar.showTitle
        },
        // æ˜¯å¦æ˜¾ç¤ºå‰¯æ ‡é¢˜
        showSubtitle: {
            type: Boolean,
            default: uni.$u.props.calendar.showSubtitle
        },
        // æ—¥æœŸç±»åž‹é€‰æ‹©ï¼Œsingle-选择单个日期,multiple-可以选择多个日期,range-选择日期范围
        mode: {
            type: String,
            default: uni.$u.props.calendar.mode
        },
        // mode=range时,第一个日期底部的提示文字
        startText: {
            type: String,
            default: uni.$u.props.calendar.startText
        },
        // mode=range时,最后一个日期底部的提示文字
        endText: {
            type: String,
            default: uni.$u.props.calendar.endText
        },
        // è‡ªå®šä¹‰åˆ—表
        customList: {
            type: Array,
            default: uni.$u.props.calendar.customList
        },
        // ä¸»é¢˜è‰²ï¼Œå¯¹åº•部按钮和选中日期有效
        color: {
            type: String,
            default: uni.$u.props.calendar.color
        },
        // æœ€å°çš„可选日期
        minDate: {
            type: [String, Number],
            default: uni.$u.props.calendar.minDate
        },
        // æœ€å¤§å¯é€‰æ—¥æœŸ
        maxDate: {
            type: [String, Number],
            default: uni.$u.props.calendar.maxDate
        },
        // é»˜è®¤é€‰ä¸­çš„æ—¥æœŸï¼Œmode为multiple或range是必须为数组格式
        defaultDate: {
            type: [Array, String, Date, null],
            default: uni.$u.props.calendar.defaultDate
        },
        // mode=multiple时,最多可选多少个日期
        maxCount: {
            type: [String, Number],
            default: uni.$u.props.calendar.maxCount
        },
        // æ—¥æœŸè¡Œé«˜
        rowHeight: {
            type: [String, Number],
            default: uni.$u.props.calendar.rowHeight
        },
        // æ—¥æœŸæ ¼å¼åŒ–函数
        formatter: {
            type: [Function, null],
            default: uni.$u.props.calendar.formatter
        },
        // æ˜¯å¦æ˜¾ç¤ºå†œåކ
        showLunar: {
            type: Boolean,
            default: uni.$u.props.calendar.showLunar
        },
        // æ˜¯å¦æ˜¾ç¤ºæœˆä»½èƒŒæ™¯è‰²
        showMark: {
            type: Boolean,
            default: uni.$u.props.calendar.showMark
        },
        // ç¡®å®šæŒ‰é’®çš„æ–‡å­—
        confirmText: {
            type: String,
            default: uni.$u.props.calendar.confirmText
        },
        // ç¡®è®¤æŒ‰é’®å¤„于禁用状态时的文字
        confirmDisabledText: {
            type: String,
            default: uni.$u.props.calendar.confirmDisabledText
        },
        // æ˜¯å¦æ˜¾ç¤ºæ—¥åŽ†å¼¹çª—
        show: {
            type: Boolean,
            default: uni.$u.props.calendar.show
        },
        // æ˜¯å¦å…è®¸ç‚¹å‡»é®ç½©å…³é—­æ—¥åކ
        closeOnClickOverlay: {
            type: Boolean,
            default: uni.$u.props.calendar.closeOnClickOverlay
        },
        // æ˜¯å¦ä¸ºåªè¯»çŠ¶æ€ï¼Œåªè¯»çŠ¶æ€ä¸‹ç¦æ­¢é€‰æ‹©æ—¥æœŸ
        readonly: {
            type: Boolean,
            default: uni.$u.props.calendar.readonly
        },
        //     æ˜¯å¦å±•示确认按钮
        showConfirm: {
            type: Boolean,
            default: uni.$u.props.calendar.showConfirm
        },
        // æ—¥æœŸåŒºé—´æœ€å¤šå¯é€‰å¤©æ•°ï¼Œé»˜è®¤æ— é™åˆ¶ï¼Œmode = range时有效
        maxRange: {
            type: [Number, String],
            default: uni.$u.props.calendar.maxRange
        },
        // èŒƒå›´é€‰æ‹©è¶…过最多可选天数时的提示文案,mode = range时有效
        rangePrompt: {
            type: String,
            default: uni.$u.props.calendar.rangePrompt
        },
        // èŒƒå›´é€‰æ‹©è¶…过最多可选天数时,是否展示提示文案,mode = range时有效
        showRangePrompt: {
            type: Boolean,
            default: uni.$u.props.calendar.showRangePrompt
        },
        // æ˜¯å¦å…è®¸æ—¥æœŸèŒƒå›´çš„起止时间为同一天,mode = range时有效
        allowSameDay: {
            type: Boolean,
            default: uni.$u.props.calendar.allowSameDay
        },
        // åœ†è§’值
        round: {
            type: [Boolean, String, Number],
            default: uni.$u.props.calendar.round
        },
        // æœ€å¤šå±•示月份数量
        monthNum: {
            type: [Number, String],
            default: 3
        }
    }
}
uni_modules/uview-ui/components/u-calendar/u-calendar.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,383 @@
<template>
    <u-popup
        :show="show"
        mode="bottom"
        closeable
        @close="close"
        :round="round"
        :closeOnClickOverlay="closeOnClickOverlay"
    >
        <view class="u-calendar">
            <uHeader
                :title="title"
                :subtitle="subtitle"
                :showSubtitle="showSubtitle"
                :showTitle="showTitle"
            ></uHeader>
            <scroll-view
                :style="{
                    height: $u.addUnit(listHeight)
                }"
                scroll-y
                @scroll="onScroll"
                :scroll-top="scrollTop"
                :scrollIntoView="scrollIntoView"
            >
                <uMonth
                    :color="color"
                    :rowHeight="rowHeight"
                    :showMark="showMark"
                    :months="months"
                    :mode="mode"
                    :maxCount="maxCount"
                    :startText="startText"
                    :endText="endText"
                    :defaultDate="defaultDate"
                    :minDate="innerMinDate"
                    :maxDate="innerMaxDate"
                    :maxMonth="monthNum"
                    :readonly="readonly"
                    :maxRange="maxRange"
                    :rangePrompt="rangePrompt"
                    :showRangePrompt="showRangePrompt"
                    :allowSameDay="allowSameDay"
                    ref="month"
                    @monthSelected="monthSelected"
                    @updateMonthTop="updateMonthTop"
                ></uMonth>
            </scroll-view>
            <slot name="footer" v-if="showConfirm">
                <view class="u-calendar__confirm">
                    <u-button
                        shape="circle"
                        :text="
                            buttonDisabled ? confirmDisabledText : confirmText
                        "
                        :color="color"
                        @click="confirm"
                        :disabled="buttonDisabled"
                    ></u-button>
                </view>
            </slot>
        </view>
    </u-popup>
</template>
<script>
import uHeader from './header.vue'
import uMonth from './month.vue'
import props from './props.js'
import util from './util.js'
import dayjs from '../../libs/util/dayjs.js'
import Calendar from '../../libs/util/calendar.js'
/**
 * Calendar æ—¥åކ
 * @description  æ­¤ç»„件用于单个选择日期,范围选择日期等,日历被包裹在底部弹起的容器中.
 * @tutorial https://www.uviewui.com/components/calendar.html
 *
 * @property {String}                title                æ ‡é¢˜å†…容 (默认 æ—¥æœŸé€‰æ‹© )
 * @property {Boolean}                showTitle            æ˜¯å¦æ˜¾ç¤ºæ ‡é¢˜  (默认 true )
 * @property {Boolean}                showSubtitle        æ˜¯å¦æ˜¾ç¤ºå‰¯æ ‡é¢˜    (默认 true )
 * @property {String}                mode                æ—¥æœŸç±»åž‹é€‰æ‹©  single-选择单个日期,multiple-可以选择多个日期,range-选择日期范围 ï¼ˆ é»˜è®¤ 'single' )
 * @property {String}                startText            mode=range时,第一个日期底部的提示文字  (默认 '开始' )
 * @property {String}                endText                mode=range时,最后一个日期底部的提示文字 (默认 '结束' )
 * @property {Array}                customList            è‡ªå®šä¹‰åˆ—表
 * @property {String}                color                ä¸»é¢˜è‰²ï¼Œå¯¹åº•部按钮和选中日期有效  (默认 â€˜#3c9cff' )
 * @property {String | Number}        minDate                æœ€å°çš„可选日期     (默认 0 )
 * @property {String | Number}        maxDate                æœ€å¤§å¯é€‰æ—¥æœŸ  (默认 0 )
 * @property {Array | String| Date}    defaultDate            é»˜è®¤é€‰ä¸­çš„æ—¥æœŸï¼Œmode为multiple或range是必须为数组格式
 * @property {String | Number}        maxCount            mode=multiple时,最多可选多少个日期  (默认     Number.MAX_SAFE_INTEGER  )
 * @property {String | Number}        rowHeight            æ—¥æœŸè¡Œé«˜ (默认 56 )
 * @property {Function}                formatter            æ—¥æœŸæ ¼å¼åŒ–函数
 * @property {Boolean}                showLunar            æ˜¯å¦æ˜¾ç¤ºå†œåކ  (默认 false )
 * @property {Boolean}                showMark            æ˜¯å¦æ˜¾ç¤ºæœˆä»½èƒŒæ™¯è‰² (默认 true )
 * @property {String}                confirmText            ç¡®å®šæŒ‰é’®çš„æ–‡å­— (默认 '确定' )
 * @property {String}                confirmDisabledText    ç¡®è®¤æŒ‰é’®å¤„于禁用状态时的文字 (默认 '确定' )
 * @property {Boolean}                show                æ˜¯å¦æ˜¾ç¤ºæ—¥åŽ†å¼¹çª— (默认 false )
 * @property {Boolean}                closeOnClickOverlay    æ˜¯å¦å…è®¸ç‚¹å‡»é®ç½©å…³é—­æ—¥åކ (默认 false )
 * @property {Boolean}                readonly            æ˜¯å¦ä¸ºåªè¯»çŠ¶æ€ï¼Œåªè¯»çŠ¶æ€ä¸‹ç¦æ­¢é€‰æ‹©æ—¥æœŸ (默认 false )
 * @property {String | Number}        maxRange            æ—¥æœŸåŒºé—´æœ€å¤šå¯é€‰å¤©æ•°ï¼Œé»˜è®¤æ— é™åˆ¶ï¼Œmode = range时有效
 * @property {String}                rangePrompt            èŒƒå›´é€‰æ‹©è¶…过最多可选天数时的提示文案,mode = range时有效
 * @property {Boolean}                showRangePrompt        èŒƒå›´é€‰æ‹©è¶…过最多可选天数时,是否展示提示文案,mode = range时有效 (默认 true )
 * @property {Boolean}                allowSameDay        æ˜¯å¦å…è®¸æ—¥æœŸèŒƒå›´çš„起止时间为同一天,mode = range时有效 (默认 false )
 * @property {Number|String}        round                åœ†è§’值,默认无圆角  (默认 0 )
 * @property {Number|String}        monthNum            æœ€å¤šå±•示的月份数量  (默认 3 )
 *
 * @event {Function()} confirm         ç‚¹å‡»ç¡®å®šæŒ‰é’®æ—¶è§¦å‘        é€‰æ‹©æ—¥æœŸç›¸å…³çš„返回参数
 * @event {Function()} close         æ—¥åŽ†å…³é—­æ—¶è§¦å‘            å¯å®šä¹‰é¡µé¢å…³é—­æ—¶çš„回调事件
 * @example <u-calendar  :defaultDate="defaultDateMultiple" :show="show" mode="multiple" @confirm="confirm">
    </u-calendar>
 * */
export default {
    name: 'u-calendar',
    mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
    components: {
        uHeader,
        uMonth
    },
    data() {
        return {
            // éœ€è¦æ˜¾ç¤ºçš„æœˆä»½çš„æ•°ç»„
            months: [],
            // åœ¨æœˆä»½æ»šåŠ¨åŒºåŸŸä¸­ï¼Œå½“å‰è§†å›¾ä¸­æœˆä»½çš„index索引
            monthIndex: 0,
            // æœˆä»½æ»šåŠ¨åŒºåŸŸçš„é«˜åº¦
            listHeight: 0,
            // month组件中选择的日期数组
            selected: [],
            scrollIntoView: '',
            scrollTop:0,
            // è¿‡æ»¤å¤„理方法
            innerFormatter: (value) => value
        }
    },
    watch: {
        selectedChange: {
            immediate: true,
            handler(n) {
                this.setMonth()
            }
        },
        // æ‰“开弹窗时,设置月份数据
        show: {
            immediate: true,
            handler(n) {
                this.setMonth()
            }
        }
    },
    computed: {
        // ç”±äºŽmaxDate和minDate可以为字符串(2021-10-10),或者数值(时间戳),但是dayjs如果接受字符串形式的时间戳会有问题,这里进行处理
        innerMaxDate() {
            return uni.$u.test.number(this.maxDate)
                ? Number(this.maxDate)
                : this.maxDate
        },
        innerMinDate() {
            return uni.$u.test.number(this.minDate)
                ? Number(this.minDate)
                : this.minDate
        },
        // å¤šä¸ªæ¡ä»¶çš„变化,会引起选中日期的变化,这里统一管理监听
        selectedChange() {
            return [this.innerMinDate, this.innerMaxDate, this.defaultDate]
        },
        subtitle() {
            // åˆå§‹åŒ–时,this.months为空数组,所以需要特别判断处理
            if (this.months.length) {
                return `${this.months[this.monthIndex].year}å¹´${
                    this.months[this.monthIndex].month
                }月`
            } else {
                return ''
            }
        },
        buttonDisabled() {
            // å¦‚果为range类型,且选择的日期个数不足1个时,让底部的按钮出于disabled状态
            if (this.mode === 'range') {
                if (this.selected.length <= 1) {
                    return true
                } else {
                    return false
                }
            } else {
                return false
            }
        }
    },
    mounted() {
        this.start = Date.now()
        this.init()
    },
    methods: {
        // åœ¨å¾®ä¿¡å°ç¨‹åºä¸­ï¼Œä¸æ”¯æŒå°†å‡½æ•°å½“做props参数,故只能通过ref形式调用
        setFormatter(e) {
            this.innerFormatter = e
        },
        // month组件内部选择日期后,通过事件通知给父组件
        monthSelected(e) {
            this.selected = e
            if (!this.showConfirm) {
                // åœ¨ä¸éœ€è¦ç¡®è®¤æŒ‰é’®çš„æƒ…况下,如果为单选,或者范围多选且已选长度大于2,则直接进行返还
                if (
                    this.mode === 'multiple' ||
                    this.mode === 'single' ||
                    (this.mode === 'range' && this.selected.length >= 2)
                ) {
                    this.$emit('confirm', this.selected)
                }
            }
        },
        init() {
            // æ ¡éªŒmaxDate,不能小于当前时间
            if (
                this.innerMaxDate &&
                new Date(this.innerMaxDate).getTime() <= Date.now()
            ) {
                return uni.$u.error('maxDate不能小于当前时间')
            }
            // æ»šåŠ¨åŒºåŸŸçš„é«˜åº¦
            this.listHeight = this.rowHeight * 5 + 30
            this.setMonth()
        },
        close() {
            this.$emit('close')
        },
        // ç‚¹å‡»ç¡®å®šæŒ‰é’®
        confirm() {
            if (!this.buttonDisabled) {
                this.$emit('confirm', this.selected)
            }
        },
        // èŽ·å¾—ä¸¤ä¸ªæ—¥æœŸä¹‹é—´çš„æœˆä»½æ•°
        getMonths(minDate, maxDate) {
            const minYear = dayjs(minDate).year()
            const minMonth = dayjs(minDate).month() + 1
            const maxYear = dayjs(maxDate).year()
            const maxMonth = dayjs(maxDate).month() + 1
            return (maxYear - minYear) * 12 + (maxMonth - minMonth) + 1
        },
        // è®¾ç½®æœˆä»½æ•°æ®
        setMonth() {
            // æœ€å°æ—¥æœŸçš„æ¯«ç§’æ•°
            const minDate = this.innerMinDate || dayjs().valueOf()
            // å¦‚果没有指定最大日期,则往后推3个月
            const maxDate =
                this.innerMaxDate ||
                dayjs(minDate)
                    .add(this.monthNum - 1, 'month')
                    .valueOf()
            // æœ€å¤§æœ€å°æœˆä»½ä¹‹é—´çš„共有多少个月份,
            const months = uni.$u.range(
                1,
                this.monthNum,
                this.getMonths(minDate, maxDate)
            )
            // å…ˆæ¸…空数组
            this.months = []
            for (let i = 0; i < months; i++) {
                this.months.push({
                    date: new Array(
                        dayjs(minDate).add(i, 'month').daysInMonth()
                    )
                        .fill(1)
                        .map((item, index) => {
                            // æ—¥æœŸï¼Œå–值1-31
                            let day = index + 1
                            // æ˜ŸæœŸï¼Œ0-6,0为周日
                            const week = dayjs(minDate)
                                .add(i, 'month')
                                .date(day)
                                .day()
                            const date = dayjs(minDate)
                                .add(i, 'month')
                                .date(day)
                                .format('YYYY-MM-DD')
                            let bottomInfo = ''
                            if (this.showLunar) {
                                // å°†æ—¥æœŸè½¬ä¸ºå†œåŽ†æ ¼å¼
                                const lunar = Calendar.solar2lunar(
                                    dayjs(date).year(),
                                    dayjs(date).month() + 1,
                                    dayjs(date).date()
                                )
                                bottomInfo = lunar.IDayCn
                            }
                            let config = {
                                day,
                                week,
                                // å°äºŽæœ€å°å…è®¸çš„æ—¥æœŸï¼Œæˆ–者大于最大的日期,则设置为disabled状态
                                disabled:
                                    dayjs(date).isBefore(
                                        dayjs(minDate).format('YYYY-MM-DD')
                                    ) ||
                                    dayjs(date).isAfter(
                                        dayjs(maxDate).format('YYYY-MM-DD')
                                    ),
                                // è¿”回一个日期对象,供外部的formatter获取当前日期的年月日等信息,进行加工处理
                                date: new Date(date),
                                bottomInfo,
                                dot: false,
                                month:
                                    dayjs(minDate).add(i, 'month').month() + 1
                            }
                            const formatter =
                                this.formatter || this.innerFormatter
                            return formatter(config)
                        }),
                    // å½“前所属的月份
                    month: dayjs(minDate).add(i, 'month').month() + 1,
                    // å½“前年份
                    year: dayjs(minDate).add(i, 'month').year()
                })
            }
        },
        // æ»šåŠ¨åˆ°é»˜è®¤è®¾ç½®çš„æœˆä»½
        scrollIntoDefaultMonth(selected) {
            // æŸ¥è¯¢é»˜è®¤æ—¥æœŸåœ¨å¯é€‰åˆ—表的下标
            const _index = this.months.findIndex(({
                  year,
                  month
              }) => {
                month = uni.$u.padZero(month)
                return `${year}-${month}` === selected
            })
            if (_index !== -1) {
                // #ifndef MP-WEIXIN
                this.$nextTick(() => {
                    this.scrollIntoView = `month-${_index}`
                })
                // #endif
                // #ifdef MP-WEIXIN
                this.scrollTop = this.months[_index].top || 0;
                // #endif
            }
        },
        // scroll-view滚动监听
        onScroll(event) {
            // ä¸å…è®¸å°äºŽ0的滚动值,如果scroll-view到顶了,继续下拉,会出现负数值
            const scrollTop = Math.max(0, event.detail.scrollTop)
            // å°†å½“前滚动条数值,除以滚动区域的高度,可以得出当前滚动到了哪一个月份的索引
            for (let i = 0; i < this.months.length; i++) {
                if (scrollTop >= (this.months[i].top || this.listHeight)) {
                    this.monthIndex = i
                }
            }
        },
        // æ›´æ–°æœˆä»½çš„top值
        updateMonthTop(topArr = []) {
            // è®¾ç½®å¯¹åº”月份的top值,用于onScroll方法更新月份
            topArr.map((item, index) => {
                this.months[index].top = item
            })
            // èŽ·å–é»˜è®¤æ—¥æœŸçš„ä¸‹æ ‡
            if (!this.defaultDate) {
                // å¦‚果没有设置默认日期,则将当天日期设置为默认选中的日期
                const selected = dayjs().format("YYYY-MM")
                this.scrollIntoDefaultMonth(selected)
                return
            }
            let selected = dayjs().format("YYYY-MM");
            // å•选模式,可以是字符串或数组,Date对象等
            if (!uni.$u.test.array(this.defaultDate)) {
                selected = dayjs(this.defaultDate).format("YYYY-MM")
            } else {
                selected = dayjs(this.defaultDate[0]).format("YYYY-MM");
            }
            this.scrollIntoDefaultMonth(selected)
        }
    }
}
</script>
<style lang="scss" scoped>
@import '../../libs/css/components.scss';
.u-calendar {
    &__confirm {
        padding: 7px 18px;
    }
}
</style>
uni_modules/uview-ui/components/u-calendar/util.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
export default {
    methods: {
        // è®¾ç½®æœˆä»½æ•°æ®
        setMonth() {
            // æœˆåˆæ˜¯å‘¨å‡ 
            const day = dayjs(this.date).date(1).day()
            const start = day == 0 ? 6 : day - 1
            // æœ¬æœˆå¤©æ•°
            const days = dayjs(this.date).endOf('month').format('D')
            // ä¸Šä¸ªæœˆå¤©æ•°
            const prevDays = dayjs(this.date).endOf('month').subtract(1, 'month').format('D')
            // æ—¥æœŸæ•°æ®
            const arr = []
            // æ¸…空表格
            this.month = []
            // æ·»åŠ ä¸Šæœˆæ•°æ®
            arr.push(
                ...new Array(start).fill(1).map((e, i) => {
                    const day = prevDays - start + i + 1
                    return {
                        value: day,
                        disabled: true,
                        date: dayjs(this.date).subtract(1, 'month').date(day).format('YYYY-MM-DD')
                    }
                })
            )
            // æ·»åŠ æœ¬æœˆæ•°æ®
            arr.push(
                ...new Array(days - 0).fill(1).map((e, i) => {
                    const day = i + 1
                    return {
                        value: day,
                        date: dayjs(this.date).date(day).format('YYYY-MM-DD')
                    }
                })
            )
            // æ·»åŠ ä¸‹ä¸ªæœˆ
            arr.push(
                ...new Array(42 - days - start).fill(1).map((e, i) => {
                    const day = i + 1
                    return {
                        value: day,
                        disabled: true,
                        date: dayjs(this.date).add(1, 'month').date(day).format('YYYY-MM-DD')
                    }
                })
            )
            // åˆ†å‰²æ•°ç»„
            for (let n = 0; n < arr.length; n += 7) {
                this.month.push(
                    arr.slice(n, n + 7).map((e, i) => {
                        e.index = i + n
                        // è‡ªå®šä¹‰ä¿¡æ¯
                        const custom = this.customList.find((c) => c.date == e.date)
                        // å†œåކ
                        if (this.lunar) {
                            const {
                                IDayCn,
                                IMonthCn
                            } = this.getLunar(e.date)
                            e.lunar = IDayCn == '初一' ? IMonthCn : IDayCn
                        }
                        return {
                            ...e,
                            ...custom
                        }
                    })
                )
            }
        }
    }
}
uni_modules/uview-ui/components/u-car-keyboard/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
export default {
    props: {
        // æ˜¯å¦æ‰“乱键盘按键的顺序
        random: {
            type: Boolean,
            default: false
        },
        // è¾“入一个中文后,是否自动切换到英文
        autoChange: {
            type: Boolean,
            default: false
        }
    }
}
uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,311 @@
<template>
    <view
        class="u-keyboard"
        @touchmove.stop.prevent="noop"
    >
        <view
            v-for="(group, i) in abc ? engKeyBoardList : areaList"
            :key="i"
            class="u-keyboard__button"
            :index="i"
            :class="[i + 1 === 4 && 'u-keyboard__button--center']"
        >
            <view
                v-if="i === 3"
                class="u-keyboard__button__inner-wrapper"
            >
                <view
                    class="u-keyboard__button__inner-wrapper__left"
                    hover-class="u-hover-class"
                    :hover-stay-time="200"
                    @tap="changeCarInputMode"
                >
                    <text
                        class="u-keyboard__button__inner-wrapper__left__lang"
                        :class="[!abc && 'u-keyboard__button__inner-wrapper__left__lang--active']"
                    >中</text>
                    <text class="u-keyboard__button__inner-wrapper__left__line">/</text>
                    <text
                        class="u-keyboard__button__inner-wrapper__left__lang"
                        :class="[abc && 'u-keyboard__button__inner-wrapper__left__lang--active']"
                    >英</text>
                </view>
            </view>
            <view
                class="u-keyboard__button__inner-wrapper"
                v-for="(item, j) in group"
                :key="j"
            >
                <view
                    class="u-keyboard__button__inner-wrapper__inner"
                    :hover-stay-time="200"
                    @tap="carInputClick(i, j)"
                    hover-class="u-hover-class"
                >
                    <text class="u-keyboard__button__inner-wrapper__inner__text">{{ item }}</text>
                </view>
            </view>
            <view
                v-if="i === 3"
                @touchstart="backspaceClick"
                @touchend="clearTimer"
                class="u-keyboard__button__inner-wrapper"
            >
                <view
                    class="u-keyboard__button__inner-wrapper__right"
                    hover-class="u-hover-class"
                    :hover-stay-time="200"
                >
                    <u-icon
                        size="28"
                        name="backspace"
                        color="#303133"
                    ></u-icon>
                </view>
            </view>
        </view>
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * keyboard é”®ç›˜ç»„ä»¶
     * @description æ­¤ä¸ºuView自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3种模式,都有可以打乱按键顺序的选项。
     * @tutorial https://uviewui.com/components/keyboard.html
     * @property {Boolean} random æ˜¯å¦æ‰“乱键盘的顺序
     * @event {Function} change ç‚¹å‡»é”®ç›˜è§¦å‘
     * @event {Function} backspace ç‚¹å‡»é€€æ ¼é”®è§¦å‘
     * @example <u-keyboard ref="uKeyboard" mode="car" v-model="show"></u-keyboard>
     */
    export default {
        name: "u-keyboard",
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
                // è½¦ç‰Œè¾“入时,abc=true为输入车牌号码,bac=false为输入省份中文简称
                abc: false
            };
        },
        computed: {
            areaList() {
                let data = [
                    '京',
                    '沪',
                    '粤',
                    'æ´¥',
                    '冀',
                    '豫',
                    '云',
                    'è¾½',
                    '黑',
                    '湘',
                    '皖',
                    '鲁',
                    '苏',
                    '浙',
                    'èµ£',
                    '鄂',
                    '桂',
                    '甘',
                    '晋',
                    '陕',
                    '蒙',
                    '吉',
                    '闽',
                    'è´µ',
                    '渝',
                    '川',
                    '青',
                    '琼',
                    '宁',
                    '挂',
                    '藏',
                    '港',
                    'æ¾³',
                    '新',
                    '使',
                    'å­¦'
                ];
                let tmp = [];
                // æ‰“乱顺序
                if (this.random) data = uni.$u.randomArray(data);
                // åˆ‡å‰²æˆäºŒç»´æ•°ç»„
                tmp[0] = data.slice(0, 10);
                tmp[1] = data.slice(10, 20);
                tmp[2] = data.slice(20, 30);
                tmp[3] = data.slice(30, 36);
                return tmp;
            },
            engKeyBoardList() {
                let data = [
                    1,
                    2,
                    3,
                    4,
                    5,
                    6,
                    7,
                    8,
                    9,
                    0,
                    'Q',
                    'W',
                    'E',
                    'R',
                    'T',
                    'Y',
                    'U',
                    'I',
                    'O',
                    'P',
                    'A',
                    'S',
                    'D',
                    'F',
                    'G',
                    'H',
                    'J',
                    'K',
                    'L',
                    'Z',
                    'X',
                    'C',
                    'V',
                    'B',
                    'N',
                    'M'
                ];
                let tmp = [];
                if (this.random) data = uni.$u.randomArray(data);
                tmp[0] = data.slice(0, 10);
                tmp[1] = data.slice(10, 20);
                tmp[2] = data.slice(20, 30);
                tmp[3] = data.slice(30, 36);
                return tmp;
            }
        },
        methods: {
            // ç‚¹å‡»é”®ç›˜æŒ‰é’®
            carInputClick(i, j) {
                let value = '';
                // ä¸åŒæ¨¡å¼ï¼ŒèŽ·å–ä¸åŒæ•°ç»„çš„å€¼
                if (this.abc) value = this.engKeyBoardList[i][j];
                else value = this.areaList[i][j];
                // å¦‚果允许自动切换,则将中文状态切换为英文
                if (!this.abc && this.autoChange) uni.$u.sleep(200).then(() => this.abc = true)
                this.$emit('change', value);
            },
            // ä¿®æ”¹æ±½è½¦ç‰Œé”®ç›˜çš„输入模式,中文|英文
            changeCarInputMode() {
                this.abc = !this.abc;
            },
            // ç‚¹å‡»é€€æ ¼é”®
            backspaceClick() {
                this.$emit('backspace');
                clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
                this.timer = null;
                this.timer = setInterval(() => {
                    this.$emit('backspace');
                }, 250);
            },
            clearTimer() {
                clearInterval(this.timer);
                this.timer = null;
            },
        }
    };
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    $u-car-keyboard-background-color: rgb(224, 228, 230) !default;
    $u-car-keyboard-padding:6px 0 6px !default;
    $u-car-keyboard-button-inner-width:64rpx !default;
    $u-car-keyboard-button-inner-background-color:#FFFFFF !default;
    $u-car-keyboard-button-height:80rpx !default;
    $u-car-keyboard-button-inner-box-shadow:0 1px 0px #999992 !default;
    $u-car-keyboard-button-border-radius:4px !default;
    $u-car-keyboard-button-inner-margin:8rpx 5rpx !default;
    $u-car-keyboard-button-text-font-size:16px !default;
    $u-car-keyboard-button-text-color:$u-main-color !default;
    $u-car-keyboard-center-inner-margin: 0 4rpx !default;
    $u-car-keyboard-special-button-width:134rpx !default;
    $u-car-keyboard-lang-font-size:16px !default;
    $u-car-keyboard-lang-color:$u-main-color !default;
    $u-car-keyboard-active-color:$u-primary !default;
    $u-car-keyboard-line-font-size:15px !default;
    $u-car-keyboard-line-color:$u-main-color !default;
    $u-car-keyboard-line-margin:0 1px !default;
    $u-car-keyboard-u-hover-class-background-color:#BBBCC6 !default;
    .u-keyboard {
        @include flex(column);
        justify-content: space-around;
        background-color: $u-car-keyboard-background-color;
        align-items: stretch;
        padding: $u-car-keyboard-padding;
        &__button {
            @include flex;
            justify-content: center;
            flex: 1;
            /* #ifndef APP-NVUE */
            /* #endif */
            &__inner-wrapper {
                box-shadow: $u-car-keyboard-button-inner-box-shadow;
                margin: $u-car-keyboard-button-inner-margin;
                border-radius: $u-car-keyboard-button-border-radius;
                &__inner {
                    @include flex;
                    justify-content: center;
                    align-items: center;
                    width: $u-car-keyboard-button-inner-width;
                    background-color: $u-car-keyboard-button-inner-background-color;
                    height: $u-car-keyboard-button-height;
                    border-radius: $u-car-keyboard-button-border-radius;
                    &__text {
                        font-size: $u-car-keyboard-button-text-font-size;
                        color: $u-car-keyboard-button-text-color;
                    }
                }
                &__left,
                &__right {
                    border-radius: $u-car-keyboard-button-border-radius;
                    width: $u-car-keyboard-special-button-width;
                    height: $u-car-keyboard-button-height;
                    background-color: $u-car-keyboard-u-hover-class-background-color;
                    @include flex;
                    justify-content: center;
                    align-items: center;
                    box-shadow: $u-car-keyboard-button-inner-box-shadow;
                }
                &__left {
                    &__line {
                        font-size: $u-car-keyboard-line-font-size;
                        color: $u-car-keyboard-line-color;
                        margin: $u-car-keyboard-line-margin;
                    }
                    &__lang {
                        font-size: $u-car-keyboard-lang-font-size;
                        color: $u-car-keyboard-lang-color;
                        &--active {
                            color: $u-car-keyboard-active-color;
                        }
                    }
                }
            }
        }
    }
    .u-hover-class {
        background-color: $u-car-keyboard-u-hover-class-background-color;
    }
</style>
uni_modules/uview-ui/components/u-cell-group/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
export default {
    props: {
        // åˆ†ç»„标题
        title: {
            type: String,
            default: uni.$u.props.cellGroup.title
        },
        // æ˜¯å¦æ˜¾ç¤ºå¤–边框
        border: {
            type: Boolean,
            default: uni.$u.props.cellGroup.border
        }
    }
}
uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
<template>
    <view :style="[$u.addStyle(customStyle)]" :class="[customClass]" class="u-cell-group">
        <view v-if="title" class="u-cell-group__title">
            <slot name="title">
                <text class="u-cell-group__title__text">{{ title }}</text>
            </slot>
        </view>
        <view class="u-cell-group__wrapper">
            <u-line v-if="border"></u-line>
            <slot />
        </view>
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * cellGroup  å•元格
     * @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。
     * @tutorial https://uviewui.com/components/cell.html
     *
     * @property {String}    title        åˆ†ç»„标题
     * @property {Boolean}    border        æ˜¯å¦æ˜¾ç¤ºå¤–边框 (默认 true )
     * @property {Object}    customStyle    å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     *
     * @event {Function} click     ç‚¹å‡»cell列表时触发
     * @example <u-cell-group title="设置喜好">
     */
    export default {
        name: 'u-cell-group',
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    $u-cell-group-title-padding: 16px 16px 8px !default;
    $u-cell-group-title-font-size: 15px !default;
    $u-cell-group-title-line-height: 16px !default;
    $u-cell-group-title-color: $u-main-color !default;
    .u-cell-group {
        flex: 1;
        &__title {
            padding: $u-cell-group-title-padding;
            &__text {
                font-size: $u-cell-group-title-font-size;
                line-height: $u-cell-group-title-line-height;
                color: $u-cell-group-title-color;
            }
        }
        &__wrapper {
            position: relative;
        }
    }
</style>
uni_modules/uview-ui/components/u-cell/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,110 @@
export default {
    props: {
        // æ ‡é¢˜
        title: {
            type: [String, Number],
            default: uni.$u.props.cell.title
        },
        // æ ‡é¢˜ä¸‹æ–¹çš„æè¿°ä¿¡æ¯
        label: {
            type: [String, Number],
            default: uni.$u.props.cell.label
        },
        // å³ä¾§çš„内容
        value: {
            type: [String, Number],
            default: uni.$u.props.cell.value
        },
        // å·¦ä¾§å›¾æ ‡åç§°ï¼Œæˆ–者图片链接(本地文件建议使用绝对地址)
        icon: {
            type: String,
            default: uni.$u.props.cell.icon
        },
        // æ˜¯å¦ç¦ç”¨cell
        disabled: {
            type: Boolean,
            default: uni.$u.props.cell.disabled
        },
        // æ˜¯å¦æ˜¾ç¤ºä¸‹è¾¹æ¡†
        border: {
            type: Boolean,
            default: uni.$u.props.cell.border
        },
        // å†…容是否垂直居中(主要是针对右侧的value部分)
        center: {
            type: Boolean,
            default: uni.$u.props.cell.center
        },
        // ç‚¹å‡»åŽè·³è½¬çš„URL地址
        url: {
            type: String,
            default: uni.$u.props.cell.url
        },
        // é“¾æŽ¥è·³è½¬çš„æ–¹å¼ï¼Œå†…部使用的是uView封装的route方法,可能会进行拦截操作
        linkType: {
            type: String,
            default: uni.$u.props.cell.linkType
        },
        // æ˜¯å¦å¼€å¯ç‚¹å‡»åé¦ˆ(表现为点击时加上灰色背景)
        clickable: {
            type: Boolean,
            default: uni.$u.props.cell.clickable
        },
        // æ˜¯å¦å±•示右侧箭头并开启点击反馈
        isLink: {
            type: Boolean,
            default: uni.$u.props.cell.isLink
        },
        // æ˜¯å¦æ˜¾ç¤ºè¡¨å•状态下的必填星号(此组件可能会内嵌入input组件)
        required: {
            type: Boolean,
            default: uni.$u.props.cell.required
        },
        // å³ä¾§çš„图标箭头
        rightIcon: {
            type: String,
            default: uni.$u.props.cell.rightIcon
        },
        // å³ä¾§ç®­å¤´çš„æ–¹å‘,可选值为:left,up,down
        arrowDirection: {
            type: String,
            default: uni.$u.props.cell.arrowDirection
        },
        // å·¦ä¾§å›¾æ ‡æ ·å¼
        iconStyle: {
            type: [Object, String],
            default: () => {
                return uni.$u.props.cell.iconStyle
            }
        },
        // å³ä¾§ç®­å¤´å›¾æ ‡çš„æ ·å¼
        rightIconStyle: {
            type: [Object, String],
            default: () => {
                return uni.$u.props.cell.rightIconStyle
            }
        },
        // æ ‡é¢˜çš„æ ·å¼
        titleStyle: {
            type: [Object, String],
            default: () => {
                return uni.$u.props.cell.titleStyle
            }
        },
        // å•位元的大小,可选值为large
        size: {
            type: String,
            default: uni.$u.props.cell.size
        },
        // ç‚¹å‡»cell是否阻止事件传播
        stop: {
            type: Boolean,
            default: uni.$u.props.cell.stop
        },
        // æ ‡è¯†ç¬¦ï¼Œcell被点击时返回
        name: {
            type: [Number, String],
            default: uni.$u.props.cell.name
        }
    }
}
uni_modules/uview-ui/components/u-cell/u-cell.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,229 @@
<template>
    <view class="u-cell" :class="[customClass]" :style="[$u.addStyle(customStyle)]"
        :hover-class="(!disabled && (clickable || isLink)) ? 'u-cell--clickable' : ''" :hover-stay-time="250"
        @tap="clickHandler">
        <view class="u-cell__body" :class="[ center && 'u-cell--center', size === 'large' && 'u-cell__body--large']">
            <view class="u-cell__body__content">
                <view class="u-cell__left-icon-wrap" v-if="$slots.icon || icon">
                    <slot name="icon" v-if="$slots.icon">
                    </slot>
                    <u-icon v-else :name="icon" :custom-style="iconStyle" :size="size === 'large' ? 22 : 18"></u-icon>
                </view>
                <view class="u-cell__title">
                    <slot name="title">
                        <text v-if="title" class="u-cell__title-text" :style="[titleTextStyle]"
                            :class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__title-text--large']">{{ title }}</text>
                    </slot>
                    <slot name="label">
                        <text class="u-cell__label" v-if="label"
                            :class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__label--large']">{{ label }}</text>
                    </slot>
                </view>
            </view>
            <slot name="value">
                <text class="u-cell__value"
                    :class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__value--large']"
                    v-if="!$u.test.empty(value)">{{ value }}</text>
            </slot>
            <view class="u-cell__right-icon-wrap" v-if="$slots['right-icon'] || isLink"
                :class="[`u-cell__right-icon-wrap--${arrowDirection}`]">
                <slot name="right-icon" v-if="$slots['right-icon']">
                </slot>
                <u-icon v-else :name="rightIcon" :custom-style="rightIconStyle" :color="disabled ? '#c8c9cc' : 'info'"
                    :size="size === 'large' ? 18 : 16"></u-icon>
            </view>
        </view>
        <u-line v-if="border"></u-line>
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * cell  å•元格
     * @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。
     * @tutorial https://uviewui.com/components/cell.html
     * @property {String | Number}    title            æ ‡é¢˜
     * @property {String | Number}    label            æ ‡é¢˜ä¸‹æ–¹çš„æè¿°ä¿¡æ¯
     * @property {String | Number}    value            å³ä¾§çš„内容
     * @property {String}            icon            å·¦ä¾§å›¾æ ‡åç§°ï¼Œæˆ–者图片链接(本地文件建议使用绝对地址)
     * @property {Boolean}            disabled        æ˜¯å¦ç¦ç”¨cell
     * @property {Boolean}            border            æ˜¯å¦æ˜¾ç¤ºä¸‹è¾¹æ¡† (默认 true )
     * @property {Boolean}            center            å†…容是否垂直居中(主要是针对右侧的value部分) (默认 false )
     * @property {String}            url                ç‚¹å‡»åŽè·³è½¬çš„URL地址
     * @property {String}            linkType        é“¾æŽ¥è·³è½¬çš„æ–¹å¼ï¼Œå†…部使用的是uView封装的route方法,可能会进行拦截操作 (默认 'navigateTo' )
     * @property {Boolean}            clickable        æ˜¯å¦å¼€å¯ç‚¹å‡»åé¦ˆ(表现为点击时加上灰色背景) ï¼ˆé»˜è®¤ false ï¼‰
     * @property {Boolean}            isLink            æ˜¯å¦å±•示右侧箭头并开启点击反馈 ï¼ˆé»˜è®¤ false ï¼‰
     * @property {Boolean}            required        æ˜¯å¦æ˜¾ç¤ºè¡¨å•状态下的必填星号(此组件可能会内嵌入input组件) ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String}            rightIcon        å³ä¾§çš„图标箭头 ï¼ˆé»˜è®¤ 'arrow-right')
     * @property {String}            arrowDirection    å³ä¾§ç®­å¤´çš„æ–¹å‘,可选值为:left,up,down
     * @property {Object | String}            rightIconStyle    å³ä¾§ç®­å¤´å›¾æ ‡çš„æ ·å¼
     * @property {Object | String}            titleStyle        æ ‡é¢˜çš„æ ·å¼
     * @property {Object | String}            iconStyle        å·¦ä¾§å›¾æ ‡æ ·å¼
     * @property {String}            size            å•位元的大小,可选值为 large,normal,mini
     * @property {Boolean}            stop            ç‚¹å‡»cell是否阻止事件传播 (默认 true )
     * @property {Object}            customStyle        å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     *
     * @event {Function}            click            ç‚¹å‡»cell列表时触发
     * @example è¯¥ç»„件需要搭配cell-group组件使用,见官方文档示例
     */
    export default {
        name: 'u-cell',
        data() {
            return {
            }
        },
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        computed: {
            titleTextStyle() {
                return uni.$u.addStyle(this.titleStyle)
            }
        },
        methods: {
            // ç‚¹å‡»cell
            clickHandler(e) {
                if (this.disabled) return
                this.$emit('click', {
                    name: this.name
                })
                // å¦‚果配置了url(æ­¤props参数通过mixin引入)参数,跳转页面
                this.openPage()
                // æ˜¯å¦é˜»æ­¢äº‹ä»¶ä¼ æ’­
                this.stop && this.preventEvent(e)
            },
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    $u-cell-padding: 10px 15px !default;
    $u-cell-font-size: 15px !default;
    $u-cell-line-height: 24px !default;
    $u-cell-color: $u-main-color !default;
    $u-cell-icon-size: 16px !default;
    $u-cell-title-font-size: 15px !default;
    $u-cell-title-line-height: 22px !default;
    $u-cell-title-color: $u-main-color !default;
    $u-cell-label-font-size: 12px !default;
    $u-cell-label-color: $u-tips-color !default;
    $u-cell-label-line-height: 18px !default;
    $u-cell-value-font-size: 14px !default;
    $u-cell-value-color: $u-content-color !default;
    $u-cell-clickable-color: $u-bg-color !default;
    $u-cell-disabled-color: #c8c9cc !default;
    $u-cell-padding-top-large: 13px !default;
    $u-cell-padding-bottom-large: 13px !default;
    $u-cell-value-font-size-large: 15px !default;
    $u-cell-label-font-size-large: 14px !default;
    $u-cell-title-font-size-large: 16px !default;
    $u-cell-left-icon-wrap-margin-right: 4px !default;
    $u-cell-right-icon-wrap-margin-left: 4px !default;
    $u-cell-title-flex:1 !default;
    $u-cell-label-margin-top:5px !default;
    .u-cell {
        &__body {
            @include flex();
            /* #ifndef APP-NVUE */
            box-sizing: border-box;
            /* #endif */
            padding: $u-cell-padding;
            font-size: $u-cell-font-size;
            color: $u-cell-color;
            // line-height: $u-cell-line-height;
            align-items: center;
            &__content {
                @include flex(row);
                align-items: center;
                flex: 1;
            }
            &--large {
                padding-top: $u-cell-padding-top-large;
                padding-bottom: $u-cell-padding-bottom-large;
            }
        }
        &__left-icon-wrap,
        &__right-icon-wrap {
            @include flex();
            align-items: center;
            // height: $u-cell-line-height;
            font-size: $u-cell-icon-size;
        }
        &__left-icon-wrap {
            margin-right: $u-cell-left-icon-wrap-margin-right;
        }
        &__right-icon-wrap {
            margin-left: $u-cell-right-icon-wrap-margin-left;
            transition: transform 0.3s;
            &--up {
                transform: rotate(-90deg);
            }
            &--down {
                transform: rotate(90deg);
            }
        }
        &__title {
            flex: $u-cell-title-flex;
            &-text {
                font-size: $u-cell-title-font-size;
                line-height: $u-cell-title-line-height;
                color: $u-cell-title-color;
                &--large {
                    font-size: $u-cell-title-font-size-large;
                }
            }
        }
        &__label {
            margin-top: $u-cell-label-margin-top;
            font-size: $u-cell-label-font-size;
            color: $u-cell-label-color;
            line-height: $u-cell-label-line-height;
            &--large {
                font-size: $u-cell-label-font-size-large;
            }
        }
        &__value {
            text-align: right;
            font-size: $u-cell-value-font-size;
            line-height: $u-cell-line-height;
            color: $u-cell-value-color;
            &--large {
                font-size: $u-cell-value-font-size-large;
            }
        }
        &--clickable {
            background-color: $u-cell-clickable-color;
        }
        &--disabled {
            color: $u-cell-disabled-color;
            /* #ifndef APP-NVUE */
            cursor: not-allowed;
            /* #endif */
        }
        &--center {
            align-items: center;
        }
    }
</style>
uni_modules/uview-ui/components/u-checkbox-group/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,82 @@
export default {
    props: {
        // æ ‡è¯†ç¬¦
        name: {
            type: String,
            default: uni.$u.props.checkboxGroup.name
        },
        // ç»‘定的值
        value: {
            type: Array,
            default: uni.$u.props.checkboxGroup.value
        },
        // å½¢çŠ¶ï¼Œcircle-圆形,square-方形
        shape: {
            type: String,
            default: uni.$u.props.checkboxGroup.shape
        },
        // æ˜¯å¦ç¦ç”¨å…¨éƒ¨checkbox
        disabled: {
            type: Boolean,
            default: uni.$u.props.checkboxGroup.disabled
        },
        // é€‰ä¸­çŠ¶æ€ä¸‹çš„é¢œè‰²ï¼Œå¦‚è®¾ç½®æ­¤å€¼ï¼Œå°†ä¼šè¦†ç›–parent的activeColor值
        activeColor: {
            type: String,
            default: uni.$u.props.checkboxGroup.activeColor
        },
        // æœªé€‰ä¸­çš„颜色
        inactiveColor: {
            type: String,
            default: uni.$u.props.checkboxGroup.inactiveColor
        },
        // æ•´ä¸ªç»„件的尺寸,默认px
        size: {
            type: [String, Number],
            default: uni.$u.props.checkboxGroup.size
        },
        // å¸ƒå±€æ–¹å¼ï¼Œrow-横向,column-纵向
        placement: {
            type: String,
            default: uni.$u.props.checkboxGroup.placement
        },
        // label的字体大小,px单位
        labelSize: {
            type: [String, Number],
            default: uni.$u.props.checkboxGroup.labelSize
        },
        // label的字体颜色
        labelColor: {
            type: [String],
            default: uni.$u.props.checkboxGroup.labelColor
        },
        // æ˜¯å¦ç¦æ­¢ç‚¹å‡»æ–‡æœ¬æ“ä½œ
        labelDisabled: {
            type: Boolean,
            default: uni.$u.props.checkboxGroup.labelDisabled
        },
        // å›¾æ ‡é¢œè‰²
        iconColor: {
            type: String,
            default: uni.$u.props.checkboxGroup.iconColor
        },
        // å›¾æ ‡çš„大小,单位px
        iconSize: {
            type: [String, Number],
            default: uni.$u.props.checkboxGroup.iconSize
        },
        // å‹¾é€‰å›¾æ ‡çš„对齐方式,left-左边,right-右边
        iconPlacement: {
            type: String,
            default: uni.$u.props.checkboxGroup.iconPlacement
        },
        // ç«–向配列时,是否显示下划线
        borderBottom: {
            type: Boolean,
            default: uni.$u.props.checkboxGroup.borderBottom
        }
    }
}
uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,103 @@
<template>
    <view
        class="u-checkbox-group"
        :class="bemClass"
    >
        <slot></slot>
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * checkboxGroup å¤é€‰æ¡†ç»„
     * @description å¤é€‰æ¡†ç»„件一般用于需要多个选择的场景,该组件功能完整,使用方便
     * @tutorial https://www.uviewui.com/components/checkbox.html
     * @property {String}            name            æ ‡è¯†ç¬¦
     * @property {Array}            value            ç»‘定的值
     * @property {String}            shape            å½¢çŠ¶ï¼Œcircle-圆形,square-方形 ï¼ˆé»˜è®¤ 'square' ï¼‰
     * @property {Boolean}            disabled        æ˜¯å¦ç¦ç”¨å…¨éƒ¨checkbox ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String}            activeColor        é€‰ä¸­çŠ¶æ€ä¸‹çš„é¢œè‰²ï¼Œå¦‚è®¾ç½®æ­¤å€¼ï¼Œå°†ä¼šè¦†ç›–parent的activeColor值 ï¼ˆé»˜è®¤ '#2979ff' ï¼‰
     * @property {String}            inactiveColor    æœªé€‰ä¸­çš„颜色 ï¼ˆé»˜è®¤ '#c8c9cc' ï¼‰
     * @property {String | Number}    size            æ•´ä¸ªç»„件的尺寸 å•位px ï¼ˆé»˜è®¤ 18 ï¼‰
     * @property {String}            placement        å¸ƒå±€æ–¹å¼ï¼Œrow-横向,column-纵向 ï¼ˆé»˜è®¤ 'row' ï¼‰
     * @property {String | Number}    labelSize        label的字体大小,px单位  ï¼ˆé»˜è®¤ 14 ï¼‰
     * @property {String}            labelColor        label的字体颜色 ï¼ˆé»˜è®¤ '#303133' ï¼‰
     * @property {Boolean}            labelDisabled    æ˜¯å¦ç¦æ­¢ç‚¹å‡»æ–‡æœ¬æ“ä½œ (默认 false )
     * @property {String}            iconColor        å›¾æ ‡é¢œè‰² ï¼ˆé»˜è®¤ '#ffffff' ï¼‰
     * @property {String | Number}    iconSize        å›¾æ ‡çš„大小,单位px ï¼ˆé»˜è®¤ 12 ï¼‰
     * @property {String}            iconPlacement    å‹¾é€‰å›¾æ ‡çš„对齐方式,left-左边,right-右边  ï¼ˆé»˜è®¤ 'left' ï¼‰
     * @property {Boolean}            borderBottom    placement为row时,是否显示下边框 ï¼ˆé»˜è®¤ false ï¼‰
     * @event {Function}    change    ä»»ä¸€ä¸ªcheckbox状态发生变化时触发,回调为一个对象
     * @event {Function}    input    ä¿®æ”¹é€šè¿‡v-model绑定的值时触发,回调为一个对象
     * @example <u-checkbox-group></u-checkbox-group>
     */
    export default {
        name: 'u-checkbox-group',
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        computed: {
            // è¿™é‡Œcomputed的变量,都是子组件u-checkbox需要用到的,由于头条小程序的兼容性差异,子组件无法实时监听父组件参数的变化
            // æ‰€ä»¥éœ€è¦æ‰‹åŠ¨é€šçŸ¥å­ç»„ä»¶ï¼Œè¿™é‡Œè¿”å›žä¸€ä¸ªparentData变量,供watch监听,在其中去通知每一个子组件重新从父组件(u-checkbox-group)
            // æ‹‰å–父组件新的变化后的参数
            parentData() {
                return [this.value, this.disabled, this.inactiveColor, this.activeColor, this.size, this.labelDisabled, this.shape,
                    this.iconSize, this.borderBottom, this.placement
                ]
            },
            bemClass() {
                // this.bem为一个computed变量,在mixin中
                return this.bem('checkbox-group', ['placement'])
            },
        },
        watch: {
            // å½“父组件需要子组件需要共享的参数发生了变化,手动通知子组件
            parentData() {
                if (this.children.length) {
                    this.children.map(child => {
                        // åˆ¤æ–­å­ç»„ä»¶(u-checkbox)如果有init方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
                        typeof(child.init) === 'function' && child.init()
                    })
                }
            },
        },
        data() {
            return {
            }
        },
        created() {
            this.children = []
        },
        methods: {
            // å°†å…¶ä»–çš„checkbox设置为未选中的状态
            unCheckedOther(childInstance) {
                const values = []
                this.children.map(child => {
                    // å°†è¢«é€‰ä¸­çš„checkbox,放到数组中返回
                    if (child.isChecked) {
                        values.push(child.name)
                    }
                })
                // å‘出事件
                this.$emit('change', values)
                // ä¿®æ”¹é€šè¿‡v-model绑定的值
                this.$emit('input', values)
            },
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-checkbox-group {
        &--row {
            @include flex;
        }
        &--column {
            @include flex(column);
        }
    }
</style>
uni_modules/uview-ui/components/u-checkbox/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
export default {
    props: {
        // checkbox的名称
        name: {
            type: [String, Number, Boolean],
            default: uni.$u.props.checkbox.name
        },
        // å½¢çŠ¶ï¼Œsquare为方形,circle为圆型
        shape: {
            type: String,
            default: uni.$u.props.checkbox.shape
        },
        // æ•´ä½“的大小
        size: {
            type: [String, Number],
            default: uni.$u.props.checkbox.size
        },
        // æ˜¯å¦é»˜è®¤é€‰ä¸­
        checked: {
            type: Boolean,
            default: uni.$u.props.checkbox.checked
        },
        // æ˜¯å¦ç¦ç”¨
        disabled: {
            type: [String, Boolean],
            default: uni.$u.props.checkbox.disabled
        },
        // é€‰ä¸­çŠ¶æ€ä¸‹çš„é¢œè‰²ï¼Œå¦‚è®¾ç½®æ­¤å€¼ï¼Œå°†ä¼šè¦†ç›–parent的activeColor值
        activeColor: {
            type: String,
            default: uni.$u.props.checkbox.activeColor
        },
        // æœªé€‰ä¸­çš„颜色
        inactiveColor: {
            type: String,
            default: uni.$u.props.checkbox.inactiveColor
        },
        // å›¾æ ‡çš„大小,单位px
        iconSize: {
            type: [String, Number],
            default: uni.$u.props.checkbox.iconSize
        },
        // å›¾æ ‡é¢œè‰²
        iconColor: {
            type: String,
            default: uni.$u.props.checkbox.iconColor
        },
        // label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式
        label: {
            type: [String, Number],
            default: uni.$u.props.checkbox.label
        },
        // label的字体大小,px单位
        labelSize: {
            type: [String, Number],
            default: uni.$u.props.checkbox.labelSize
        },
        // label的颜色
        labelColor: {
            type: String,
            default: uni.$u.props.checkbox.labelColor
        },
        // æ˜¯å¦ç¦æ­¢ç‚¹å‡»æç¤ºè¯­é€‰ä¸­å¤é€‰æ¡†
        labelDisabled: {
            type: [String, Boolean],
            default: uni.$u.props.checkbox.labelDisabled
        }
    }
}
uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,344 @@
<template>
    <view
        class="u-checkbox"
        :style="[checkboxStyle]"
        @tap.stop="wrapperClickHandler"
        :class="[`u-checkbox-label--${parentData.iconPlacement}`, parentData.borderBottom && parentData.placement === 'column' && 'u-border-bottom']"
    >
        <view
            class="u-checkbox__icon-wrap"
            @tap.stop="iconClickHandler"
            :class="iconClasses"
            :style="[iconWrapStyle]"
        >
            <slot name="icon">
                <u-icon
                    class="u-checkbox__icon-wrap__icon"
                    name="checkbox-mark"
                    :size="elIconSize"
                    :color="elIconColor"
                />
            </slot>
        </view>
        <text
            @tap.stop="labelClickHandler"
            :style="{
                color: elDisabled ? elInactiveColor : elLabelColor,
                fontSize: elLabelSize,
                lineHeight: elLabelSize
            }"
        >{{label}}</text>
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * checkbox  å¤é€‰æ¡†
     * @description å¤é€‰æ¡†ç»„件一般用于需要多个选择的场景,该组件功能完整,使用方便
     * @tutorial https://uviewui.com/components/checkbox.html
     * @property {String | Number | Boolean}    name            checkbox组件的标示符
     * @property {String}                        shape            å½¢çŠ¶ï¼Œsquare为方形,circle为圆型
     * @property {String | Number}                size            æ•´ä½“的大小
     * @property {Boolean}                        checked            æ˜¯å¦é»˜è®¤é€‰ä¸­
     * @property {String | Boolean}                disabled        æ˜¯å¦ç¦ç”¨
     * @property {String}                        activeColor        é€‰ä¸­çŠ¶æ€ä¸‹çš„é¢œè‰²ï¼Œå¦‚è®¾ç½®æ­¤å€¼ï¼Œå°†ä¼šè¦†ç›–parent的activeColor值
     * @property {String}                        inactiveColor    æœªé€‰ä¸­çš„颜色
     * @property {String | Number}                iconSize        å›¾æ ‡çš„大小,单位px
     * @property {String}                        iconColor        å›¾æ ‡é¢œè‰²
     * @property {String | Number}                label            label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式
     * @property {String}                        labelColor         label的颜色
     * @property {String | Number}                labelSize        label的字体大小,px单位
     * @property {String | Boolean}                labelDisabled    æ˜¯å¦ç¦æ­¢ç‚¹å‡»æç¤ºè¯­é€‰ä¸­å¤é€‰æ¡†
     * @property {Object}                        customStyle        å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     *
     * @event {Function}    change    ä»»ä¸€ä¸ªcheckbox状态发生变化时触发,回调为一个对象
     * @example <u-checkbox v-model="checked" :disabled="false">天涯</u-checkbox>
     */
    export default {
        name: "u-checkbox",
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        data() {
            return {
                isChecked: false,
                // çˆ¶ç»„件的默认值,因为头条小程序不支持在computed中使用this.parent.shape的形式
                // æ•…只能使用如此方法
                parentData: {
                    iconSize: 12,
                    labelDisabled: null,
                    disabled: null,
                    shape: 'square',
                    activeColor: null,
                    inactiveColor: null,
                    size: 18,
                    value: null,
                    iconColor: null,
                    placement: 'row',
                    borderBottom: false,
                    iconPlacement: 'left'
                }
            }
        },
        computed: {
            // æ˜¯å¦ç¦ç”¨ï¼Œå¦‚果父组件u-raios-group禁用的话,将会忽略子组件的配置
            elDisabled() {
                return this.disabled !== '' ? this.disabled : this.parentData.disabled !== null ? this.parentData.disabled : false;
            },
            // æ˜¯å¦ç¦ç”¨label点击
            elLabelDisabled() {
                return this.labelDisabled !== '' ? this.labelDisabled : this.parentData.labelDisabled !== null ? this.parentData.labelDisabled :
                    false;
            },
            // ç»„件尺寸,对应size的值,默认值为21px
            elSize() {
                return this.size ? this.size : (this.parentData.size ? this.parentData.size : 21);
            },
            // ç»„件的勾选图标的尺寸,默认12px
            elIconSize() {
                return this.iconSize ? this.iconSize : (this.parentData.iconSize ? this.parentData.iconSize : 12);
            },
            // ç»„件选中激活时的颜色
            elActiveColor() {
                return this.activeColor ? this.activeColor : (this.parentData.activeColor ? this.parentData.activeColor : '#2979ff');
            },
            // ç»„件选未中激活时的颜色
            elInactiveColor() {
                return this.inactiveColor ? this.inactiveColor : (this.parentData.inactiveColor ? this.parentData.inactiveColor :
                    '#c8c9cc');
            },
            // label的颜色
            elLabelColor() {
                return this.labelColor ? this.labelColor : (this.parentData.labelColor ? this.parentData.labelColor : '#606266')
            },
            // ç»„件的形状
            elShape() {
                return this.shape ? this.shape : (this.parentData.shape ? this.parentData.shape : 'circle');
            },
            // label大小
            elLabelSize() {
                return uni.$u.addUnit(this.labelSize ? this.labelSize : (this.parentData.labelSize ? this.parentData.labelSize :
                    '15'))
            },
            elIconColor() {
                const iconColor = this.iconColor ? this.iconColor : (this.parentData.iconColor ? this.parentData.iconColor :
                    '#ffffff');
                // å›¾æ ‡çš„颜色
                if (this.elDisabled) {
                    // disabled状态下,已勾选的checkbox图标改为elInactiveColor
                    return this.isChecked ? this.elInactiveColor : 'transparent'
                } else {
                    return this.isChecked ? iconColor : 'transparent'
                }
            },
            iconClasses() {
                let classes = []
                // ç»„件的形状
                classes.push('u-checkbox__icon-wrap--' + this.elShape)
                if (this.elDisabled) {
                    classes.push('u-checkbox__icon-wrap--disabled')
                }
                if (this.isChecked && this.elDisabled) {
                    classes.push('u-checkbox__icon-wrap--disabled--checked')
                }
                // æ”¯ä»˜å®ï¼Œå¤´æ¡å°ç¨‹åºæ— æ³•动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效
                // #ifdef MP-ALIPAY || MP-TOUTIAO
                classes = classes.join(' ')
                // #endif
                return classes
            },
            iconWrapStyle() {
                // checkbox的整体样式
                const style = {}
                style.backgroundColor = this.isChecked && !this.elDisabled ? this.elActiveColor : '#ffffff'
                style.borderColor = this.isChecked && !this.elDisabled ? this.elActiveColor : this.elInactiveColor
                style.width = uni.$u.addUnit(this.elSize)
                style.height = uni.$u.addUnit(this.elSize)
                // å¦‚果是图标在右边的话,移除它的右边距
                if (this.parentData.iconPlacement === 'right') {
                    style.marginRight = 0
                }
                return style
            },
            checkboxStyle() {
                const style = {}
                if (this.parentData.borderBottom && this.parentData.placement === 'row') {
                    uni.$u.error('检测到您将borderBottom设置为true,需要同时将u-checkbox-group的placement设置为column才有效')
                }
                // å½“父组件设置了显示下边框并且排列形式为纵向时,给内容和边框之间加上一定间隔
                if (this.parentData.borderBottom && this.parentData.placement === 'column') {
                    style.paddingBottom = '8px'
                }
                return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                // æ”¯ä»˜å®å°ç¨‹åºä¸æ”¯æŒprovide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环引用
                this.updateParentData()
                if (!this.parent) {
                    uni.$u.error('u-checkbox必须搭配u-checkbox-group组件使用')
                }
                // è®¾ç½®åˆå§‹åŒ–时,是否默认选中的状态,父组件u-checkbox-group的value可能是array,所以额外判断
                if (this.checked) {
                    this.isChecked = true
                } else if (uni.$u.test.array(this.parentData.value)) {
                    // æŸ¥æ‰¾æ•°ç»„是是否存在this.name元素值
                    this.isChecked = this.parentData.value.some(item => {
                        return item === this.name
                    })
                }
            },
            updateParentData() {
                this.getParentData('u-checkbox-group')
            },
            // æ¨ªå‘两端排列时,点击组件即可触发选中事件
            wrapperClickHandler(e) {
                this.parentData.iconPlacement === 'right' && this.iconClickHandler(e)
            },
            // ç‚¹å‡»å›¾æ ‡
            iconClickHandler(e) {
                this.preventEvent(e)
                // å¦‚果整体被禁用,不允许被点击
                if (!this.elDisabled) {
                    this.setRadioCheckedStatus()
                }
            },
            // ç‚¹å‡»label
            labelClickHandler(e) {
                this.preventEvent(e)
                // å¦‚果按钮整体被禁用或者label被禁用,则不允许点击文字修改状态
                if (!this.elLabelDisabled && !this.elDisabled) {
                    this.setRadioCheckedStatus()
                }
            },
            emitEvent() {
                this.$emit('change', this.isChecked)
                // å°è¯•调用u-form的验证方法,进行一定延迟,否则微信小程序更新可能会不及时
                this.$nextTick(() => {
                    uni.$u.formValidate(this, 'change')
                })
            },
            // æ”¹å˜ç»„件选中状态
            // è¿™é‡Œçš„æ”¹å˜çš„依据是,更改本组件的checked值为true,同时通过父组件遍历所有u-checkbox实例
            // å°†æœ¬ç»„件外的其他u-checkbox的checked都设置为false(都被取消选中状态),因而只剩下一个为选中状态
            setRadioCheckedStatus() {
                // å°†æœ¬ç»„件标记为与原来相反的状态
                this.isChecked = !this.isChecked
                this.emitEvent()
                typeof this.parent.unCheckedOther === 'function' && this.parent.unCheckedOther(this)
            }
        },
        watch:{
            checked(){
                this.isChecked = this.checked
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    $u-checkbox-icon-wrap-margin-right:6px !default;
    $u-checkbox-icon-wrap-font-size:6px !default;
    $u-checkbox-icon-wrap-border-width:1px !default;
    $u-checkbox-icon-wrap-border-color:#c8c9cc !default;
    $u-checkbox-icon-wrap-icon-line-height:0 !default;
    $u-checkbox-icon-wrap-circle-border-radius:100% !default;
    $u-checkbox-icon-wrap-square-border-radius:3px !default;
    $u-checkbox-icon-wrap-checked-color:#fff !default;
    $u-checkbox-icon-wrap-checked-background-color:red !default;
    $u-checkbox-icon-wrap-checked-border-color:#2979ff !default;
    $u-checkbox-icon-wrap-disabled-background-color:#ebedf0 !default;
    $u-checkbox-icon-wrap-disabled-checked-color:#c8c9cc !default;
    $u-checkbox-label-margin-left:5px !default;
    $u-checkbox-label-margin-right:12px !default;
    $u-checkbox-label-color:$u-content-color !default;
    $u-checkbox-label-font-size:15px !default;
    $u-checkbox-label-disabled-color:#c8c9cc !default;
    .u-checkbox {
        /* #ifndef APP-NVUE */
        @include flex(row);
        /* #endif */
        overflow: hidden;
        flex-direction: row;
        align-items: center;
        &-label--left {
            flex-direction: row
        }
        &-label--right {
            flex-direction: row-reverse;
            justify-content: space-between
        }
        &__icon-wrap {
            /* #ifndef APP-NVUE */
            box-sizing: border-box;
            // nvue下,border-color过渡有问题
            transition-property: border-color, background-color, color;
            transition-duration: 0.2s;
            /* #endif */
            color: $u-content-color;
            @include flex;
            align-items: center;
            justify-content: center;
            color: transparent;
            text-align: center;
            margin-right: $u-checkbox-icon-wrap-margin-right;
            font-size: $u-checkbox-icon-wrap-font-size;
            border-width: $u-checkbox-icon-wrap-border-width;
            border-color: $u-checkbox-icon-wrap-border-color;
            border-style: solid;
            /* #ifdef MP-TOUTIAO */
            // å¤´æ¡å°ç¨‹åºå…¼å®¹æ€§é—®é¢˜ï¼Œéœ€è¦è®¾ç½®è¡Œé«˜ä¸º0,否则图标偏下
            &__icon {
                line-height: $u-checkbox-icon-wrap-icon-line-height;
            }
            /* #endif */
            &--circle {
                border-radius: $u-checkbox-icon-wrap-circle-border-radius;
            }
            &--square {
                border-radius: $u-checkbox-icon-wrap-square-border-radius;
            }
            &--checked {
                color: $u-checkbox-icon-wrap-checked-color;
                background-color: $u-checkbox-icon-wrap-checked-background-color;
                border-color: $u-checkbox-icon-wrap-checked-border-color;
            }
            &--disabled {
                background-color: $u-checkbox-icon-wrap-disabled-background-color !important;
            }
            &--disabled--checked {
                color: $u-checkbox-icon-wrap-disabled-checked-color !important;
            }
        }
        &__label {
            /* #ifndef APP-NVUE */
            word-wrap: break-word;
            /* #endif */
            margin-left: $u-checkbox-label-margin-left;
            margin-right: $u-checkbox-label-margin-right;
            color: $u-checkbox-label-color;
            font-size: $u-checkbox-label-font-size;
            &--disabled {
                color: $u-checkbox-label-disabled-color;
            }
        }
    }
</style>
uni_modules/uview-ui/components/u-circle-progress/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
export default {
    props: {
        percentage: {
            type: [String, Number],
            default: uni.$u.props.circleProgress.percentage
        }
    }
}
uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,198 @@
<template>
    <view class="u-circle-progress">
        <view class="u-circle-progress__left">
            <view
                class="u-circle-progress__left__circle"
                :style="[leftSyle]"
                ref="left-circle"
            >
            </view>
        </view>
        <view
            class="u-circle-progress__right"
        >
            <view
                class="u-circle-progress__right__circle"
                ref="right-circle"
                :style="[rightSyle]"
            >
            </view>
        </view>
        <view class="u-circle-progress__circle">
        </view>
    </view>
</template>
<script>
    import props from './props.js';
    // #ifdef APP-NVUE
    const animation = uni.requireNativePlugin('animation')
    // #endif
    /**
     * CircleProgress åœ†å½¢è¿›åº¦æ¡ TODO: å¾…完善
     * @description å±•示操作或任务的当前进度,比如上传文件,是一个圆形的进度环。
     * @tutorial https://www.uviewui.com/components/circleProgress.html
     * @property {String | Number}    percentage    åœ†çŽ¯è¿›åº¦ç™¾åˆ†æ¯”å€¼ï¼Œä¸ºæ•°å€¼ç±»åž‹ï¼Œ0-100 (默认 30 )
     * @example
     */
    export default {
        name: 'u-circle-progress',
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        data() {
            return {
                leftBorderColor: 'rgb(200, 200, 200)',
                rightBorderColor: 'rgb(200, 200, 200)',
            }
        },
        computed: {
            leftSyle() {
                const style = {}
                style.borderTopColor = this.leftBorderColor
                style.borderRightColor = this.leftBorderColor
                return style
            },
            rightSyle() {
                const style = {}
                style.borderLeftColor = this.rightBorderColor
                style.borderBottomColor = this.rightBorderColor
                return style
            }
        },
        mounted() {
            uni.$u.sleep().then(() => {
                this.rightBorderColor = 'rgb(66, 185, 131)'
                // this.init()
            })
        },
        methods: {
            init() {
                animation.transition(this.$refs['right-circle'].ref, {
                    styles: {
                        transform: 'rotate(45deg)',
                        transformOrigin: 'center center'
                    },
                }, () => {
                    this.rightBorderColor = 'rgb(66, 185, 131)'
                    // animation.transition(this.$refs['right-circle'].ref, {
                    //     styles: {
                    //         transform: 'rotate(225deg)',
                    //         transformOrigin: 'center center'
                    //     },
                    //     duration: 3000,
                    // }, () => {
                    //     animation.transition(this.$refs['left-circle'].ref, {
                    //         styles: {
                    //             transform: 'rotate(45deg)',
                    //             transformOrigin: 'center center'
                    //         },
                    //     }, () => {
                    //         this.leftBorderColor = 'rgb(66, 185, 131)'
                    //         animation.transition(this.$refs['left-circle'].ref, {
                    //             styles: {
                    //                 transform: 'rotate(225deg)',
                    //                 transformOrigin: 'center center'
                    //             },
                    //             duration: 1500,
                    //         }, () => {
                    //         })
                    //     })
                    // })
                })
            }
        },
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-circle-progress {
        @include flex(row);
        position: relative;
        border-radius: 100px;
        height: 100px;
        width: 100px;
        // transform: rotate(0deg);
        // background-color: rgb(66, 185, 131);
        background-color: rgb(200, 200, 200);
        overflow: hidden;
        justify-content: space-between;
        &__circle {
            border-radius: 100px;
            height: 90px;
            width: 90px;
            transform: translate(-50%, -50%);
            background-color: rgb(255, 255, 255);
            left: 50px;
            top: 50px;
            position: absolute;
        }
        &__left {
            position: absolute;
            left: 0;
            width: 50px;
            height: 100px;
            overflow: hidden;
            box-sizing: border-box;
            // background-color: rgb(66, 185, 131);
            // background-color: rgb(200, 200, 200);
            // transform-origin: left center;
            &__circle {
                box-sizing: border-box;
                // background-color: red;
                border-left-color: transparent;
                border-bottom-color: transparent;
                border-top-left-radius: 50px;
                border-top-right-radius: 50px;
                border-bottom-right-radius: 50px;
                // border-left-color: rgb(66, 185, 131);
                // border-bottom-color: rgb(66, 185, 131);
                border-top-color: rgb(66, 185, 131);
                border-right-color: rgb(66, 185, 131);
                border-width: 5px;
                width: 100px;
                height: 100px;
                transform: rotate(225deg);
                // border-radius: 100px;
            }
        }
        &__right {
            position: absolute;
            right: 0;
            width: 50px;
            height: 100px;
            overflow: hidden;
            &__circle {
                position: absolute;
                right: 0;
                box-sizing: border-box;
                // background-color: red;
                border-top-color: transparent;
                border-right-color: transparent;
                border-top-left-radius: 50px;
                border-bottom-left-radius: 50px;
                border-bottom-right-radius: 50px;
                // border-left-color: rgb(66, 185, 131);
                // border-bottom-color: rgb(66, 185, 131);
                border-left-color: rgb(200, 200, 200);
                border-bottom-color: rgb(200, 200, 200);
                border-width: 5px;
                width: 100px;
                height: 100px;
                transform: rotate(45deg);
                transform-origin: center center;
                // border-radius: 100px;
            }
        }
    }
</style>
uni_modules/uview-ui/components/u-code-input/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
export default {
    props: {
        // æœ€å¤§è¾“入长度
        maxlength: {
            type: [String, Number],
            default: uni.$u.props.codeInput.maxlength
        },
        // æ˜¯å¦ç”¨åœ†ç‚¹å¡«å……
        dot: {
            type: Boolean,
            default: uni.$u.props.codeInput.dot
        },
        // æ˜¾ç¤ºæ¨¡å¼ï¼Œbox-盒子模式,line-底部横线模式
        mode: {
            type: String,
            default: uni.$u.props.codeInput.mode
        },
        // æ˜¯å¦ç»†è¾¹æ¡†
        hairline: {
            type: Boolean,
            default: uni.$u.props.codeInput.hairline
        },
        // å­—符间的距离
        space: {
            type: [String, Number],
            default: uni.$u.props.codeInput.space
        },
        // é¢„置值
        value: {
            type: [String, Number],
            default: uni.$u.props.codeInput.value
        },
        // æ˜¯å¦è‡ªåŠ¨èŽ·å–ç„¦ç‚¹
        focus: {
            type: Boolean,
            default: uni.$u.props.codeInput.focus
        },
        // å­—体是否加粗
        bold: {
            type: Boolean,
            default: uni.$u.props.codeInput.bold
        },
        // å­—体颜色
        color: {
            type: String,
            default: uni.$u.props.codeInput.color
        },
        // å­—体大小
        fontSize: {
            type: [String, Number],
            default: uni.$u.props.codeInput.fontSize
        },
        // è¾“入框的大小,宽等于高
        size: {
            type: [String, Number],
            default: uni.$u.props.codeInput.size
        },
        // æ˜¯å¦éšè—åŽŸç”Ÿé”®ç›˜ï¼Œå¦‚æžœæƒ³ç”¨è‡ªå®šä¹‰é”®ç›˜çš„è¯ï¼Œéœ€è®¾ç½®æ­¤å‚æ•°ä¸ºtrue
        disabledKeyboard: {
            type: Boolean,
            default: uni.$u.props.codeInput.disabledKeyboard
        },
        // è¾¹æ¡†å’Œçº¿æ¡é¢œè‰²
        borderColor: {
            type: String,
            default: uni.$u.props.codeInput.borderColor
        },
        // æ˜¯å¦ç¦æ­¢è¾“å…¥"."符号
        disabledDot: {
            type: Boolean,
            default: uni.$u.props.codeInput.disabledDot
        }
    }
}
uni_modules/uview-ui/components/u-code-input/u-code-input.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,251 @@
<template>
    <view class="u-code-input">
        <view
            class="u-code-input__item"
            :style="[itemStyle(index)]"
            v-for="(item, index) in codeLength"
            :key="index"
        >
            <view
                class="u-code-input__item__dot"
                v-if="dot && codeArray.length > index"
            ></view>
            <text
                v-else
                :style="{
                    fontSize: $u.addUnit(fontSize),
                    fontWeight: bold ? 'bold' : 'normal',
                    color: color
                }"
            >{{codeArray[index]}}</text>
            <view
                class="u-code-input__item__line"
                v-if="mode === 'line'"
                :style="[lineStyle]"
            ></view>
            <!-- #ifndef APP-PLUS -->
            <view v-if="isFocus && codeArray.length === index" :style="{backgroundColor: color}" class="u-code-input__item__cursor"></view>
            <!-- #endif -->
        </view>
        <input
            :disabled="disabledKeyboard"
            type="number"
            :focus="focus"
            :value="inputValue"
            :maxlength="maxlength"
            class="u-code-input__input"
            @input="inputHandler"
            :style="{
                height: $u.addUnit(size)
            }"
            @focus="isFocus = true"
            @blur="isFocus = false"
        />
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * CodeInput éªŒè¯ç è¾“å…¥
     * @description è¯¥ç»„件一般用于验证用户短信验证码的场景,也可以结合uView的键盘组件使用
     * @tutorial https://www.uviewui.com/components/codeInput.html
     * @property {String | Number}    maxlength            æœ€å¤§è¾“入长度 ï¼ˆé»˜è®¤ 6 ï¼‰
     * @property {Boolean}            dot                    æ˜¯å¦ç”¨åœ†ç‚¹å¡«å…… ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String}            mode                æ˜¾ç¤ºæ¨¡å¼ï¼Œbox-盒子模式,line-底部横线模式 ï¼ˆé»˜è®¤ 'box' ï¼‰
     * @property {Boolean}            hairline            æ˜¯å¦ç»†è¾¹æ¡† ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String | Number}    space                å­—符间的距离 ï¼ˆé»˜è®¤ 10 ï¼‰
     * @property {String | Number}    value                é¢„置值
     * @property {Boolean}            focus                æ˜¯å¦è‡ªåŠ¨èŽ·å–ç„¦ç‚¹ ï¼ˆé»˜è®¤ false ï¼‰
     * @property {Boolean}            bold                å­—体和输入横线是否加粗 ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String}            color                å­—体颜色 ï¼ˆé»˜è®¤ '#606266' ï¼‰
     * @property {String | Number}    fontSize            å­—体大小,单位px ï¼ˆé»˜è®¤ 18 ï¼‰
     * @property {String | Number}    size                è¾“入框的大小,宽等于高 ï¼ˆé»˜è®¤ 35 ï¼‰
     * @property {Boolean}            disabledKeyboard    æ˜¯å¦éšè—åŽŸç”Ÿé”®ç›˜ï¼Œå¦‚æžœæƒ³ç”¨è‡ªå®šä¹‰é”®ç›˜çš„è¯ï¼Œéœ€è®¾ç½®æ­¤å‚æ•°ä¸ºtrue ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String}            borderColor            è¾¹æ¡†å’Œçº¿æ¡é¢œè‰² ï¼ˆé»˜è®¤ '#c9cacc' ï¼‰
     * @property {Boolean}            disabledDot            æ˜¯å¦ç¦æ­¢è¾“å…¥"."符号 ï¼ˆé»˜è®¤ true ï¼‰
     *
     * @event {Function}    change    è¾“入内容发生改变时触发,具体见上方说明            value:当前输入的值
     * @event {Function}    finish    è¾“入字符个数达maxlength值时触发,见上方说明    value:当前输入的值
     * @example    <u-code-input v-model="value4" :focus="true"></u-code-input>
     */
    export default {
        name: 'u-code-input',
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
                inputValue: '',
                isFocus: this.focus
            }
        },
        watch: {
            value: {
                immediate: true,
                handler(val) {
                    // è½¬ä¸ºå­—符串,超出部分截掉
                    this.inputValue = String(val).substring(0, this.maxlength)
                }
            },
        },
        computed: {
            // æ ¹æ®é•¿åº¦ï¼Œå¾ªçŽ¯è¾“å…¥æ¡†çš„ä¸ªæ•°ï¼Œå› ä¸ºå¤´æ¡å°ç¨‹åºæ•°å€¼ä¸èƒ½ç”¨äºŽv-for
            codeLength() {
                return new Array(Number(this.maxlength))
            },
            // å¾ªçޝitem的样式
            itemStyle() {
                return index => {
                    const addUnit = uni.$u.addUnit
                    const style = {
                        width: addUnit(this.size),
                        height: addUnit(this.size)
                    }
                    // ç›’子模式下,需要额外进行处理
                    if (this.mode === 'box') {
                        // è®¾ç½®ç›’子的边框,如果是细边框,则设置为0.5px宽度
                        style.border = `${this.hairline ? 0.5 : 1}px solid ${this.borderColor}`
                        // å¦‚果盒子间距为0的话
                        if (uni.$u.getPx(this.space) === 0) {
                            // ç»™ç¬¬ä¸€å’Œæœ€åŽä¸€ä¸ªç›’子设置圆角
                            if (index === 0) {
                                style.borderTopLeftRadius = '3px'
                                style.borderBottomLeftRadius = '3px'
                            }
                            if (index === this.codeLength.length - 1) {
                                style.borderTopRightRadius = '3px'
                                style.borderBottomRightRadius = '3px'
                            }
                            // æœ€åŽä¸€ä¸ªç›’子的右边框需要保留
                            if (index !== this.codeLength.length - 1) {
                                style.borderRight = 'none'
                            }
                        }
                    }
                    if (index !== this.codeLength.length - 1) {
                        // è®¾ç½®éªŒè¯ç å­—符之间的距离,通过margin-right设置,最后一个字符,无需右边框
                        style.marginRight = addUnit(this.space)
                    } else {
                        // æœ€åŽä¸€ä¸ªç›’子的有边框需要保留
                        style.marginRight = 0
                    }
                    return style
                }
            },
            // å°†è¾“入的值,转为数组,给item历遍时,根据当前的索引显示数组的元素
            codeArray() {
                return String(this.inputValue).split('')
            },
            // ä¸‹åˆ’线模式下,横线的样式
            lineStyle() {
                const style = {}
                style.height = this.hairline ? '2px' : '4px'
                style.width = uni.$u.addUnit(this.size)
                // çº¿æ¡æ¨¡å¼ä¸‹ï¼ŒèƒŒæ™¯è‰²å³ä¸ºè¾¹æ¡†é¢œè‰²
                style.backgroundColor = this.borderColor
                return style
            }
        },
        methods: {
            // ç›‘听输入框的值发生变化
            inputHandler(e) {
                const value = e.detail.value
                this.inputValue = value
                // æ˜¯å¦å…è®¸è¾“入“.”符号
                if(this.disabledDot) {
                    this.$nextTick(() => {
                        this.inputValue = value.replace('.', '')
                    })
                }
                // æœªè¾¾åˆ°maxlength之前,发送change事件,达到后发送finish事件
                this.$emit('change', value)
                // ä¿®æ”¹é€šè¿‡v-model双向绑定的值
                this.$emit('input', value)
                // è¾¾åˆ°ç”¨æˆ·æŒ‡å®šè¾“入长度时,发出完成事件
                if (String(value).length >= Number(this.maxlength)) {
                    this.$emit('finish', value)
                }
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    $u-code-input-cursor-width: 1px;
    $u-code-input-cursor-height: 40%;
    $u-code-input-cursor-animation-duration: 1s;
    $u-code-input-cursor-animation-name: u-cursor-flicker;
    .u-code-input {
        @include flex;
        position: relative;
        overflow: hidden;
        &__item {
            @include flex;
            justify-content: center;
            align-items: center;
            position: relative;
            &__text {
                font-size: 15px;
                color: $u-content-color;
            }
            &__dot {
                width: 7px;
                height: 7px;
                border-radius: 100px;
                background-color: $u-content-color;
            }
            &__line {
                position: absolute;
                bottom: 0;
                height: 4px;
                border-radius: 100px;
                width: 40px;
                background-color: $u-content-color;
            }
            /* #ifndef APP-PLUS */
            &__cursor {
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%,-50%);
                width: $u-code-input-cursor-width;
                height: $u-code-input-cursor-height;
                animation: $u-code-input-cursor-animation-duration u-cursor-flicker infinite;
            }
            /* #endif */
        }
        &__input {
            // ä¹‹æ‰€ä»¥éœ€è¦input输入框,是因为有它才能唤起键盘
            // è¿™é‡Œå°†å®ƒè®¾ç½®ä¸ºä¸¤å€çš„屏幕宽度,再将左边的一半移出屏幕,为了不让用户看到输入的内容
            position: absolute;
            left: -750rpx;
            width: 1500rpx;
            top: 0;
            background-color: transparent;
            text-align: left;
        }
    }
    /* #ifndef APP-PLUS */
    @keyframes u-cursor-flicker {
        0% {
            opacity: 0;
        }
        50% {
            opacity: 1;
        }
        100% {
            opacity: 0;
        }
    }
    /* #endif */
</style>
uni_modules/uview-ui/components/u-code/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
export default {
    props: {
        // å€’计时总秒数
        seconds: {
            type: [String, Number],
            default: uni.$u.props.code.seconds
        },
        // å°šæœªå¼€å§‹æ—¶æç¤º
        startText: {
            type: String,
            default: uni.$u.props.code.startText
        },
        // æ­£åœ¨å€’计时中的提示
        changeText: {
            type: String,
            default: uni.$u.props.code.changeText
        },
        // å€’计时结束时的提示
        endText: {
            type: String,
            default: uni.$u.props.code.endText
        },
        // æ˜¯å¦åœ¨H5刷新或各端返回再进入时继续倒计时
        keepRunning: {
            type: Boolean,
            default: uni.$u.props.code.keepRunning
        },
        // ä¸ºäº†åŒºåˆ†å¤šä¸ªé¡µé¢ï¼Œæˆ–者一个页面多个倒计时组件本地存储的继续倒计时变了
        uniqueKey: {
            type: String,
            default: uni.$u.props.code.uniqueKey
        }
    }
}
uni_modules/uview-ui/components/u-code/u-code.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,129 @@
<template>
    <view class="u-code">
        <!-- æ­¤ç»„件功能由js完成,无需写html逻辑 -->
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * Code éªŒè¯ç è¾“入框
     * @description è€ƒè™‘到用户实际发送验证码的场景,可能是一个按钮,也可能是一段文字,提示语各有不同,所以本组件 ä¸æä¾›ç•Œé¢æ˜¾ç¤ºï¼Œåªæä¾›æç¤ºè¯­ï¼Œç”±ç”¨æˆ·å°†æç¤ºè¯­åµŒå…¥åˆ°å…·ä½“的场景
     * @tutorial https://www.uviewui.com/components/code.html
     * @property {String | Number}    seconds            å€’计时所需的秒数(默认 60 ï¼‰
     * @property {String}            startText        å¼€å§‹å‰çš„æç¤ºè¯­ï¼Œè§å®˜ç½‘说明(默认 '获取验证码' ï¼‰
     * @property {String}            changeText        å€’计时期间的提示语,必须带有字母"x",见官网说明(默认 'X秒重新获取' ï¼‰
     * @property {String}            endText            å€’计结束的提示语,见官网说明(默认 '重新获取' ï¼‰
     * @property {Boolean}            keepRunning        æ˜¯å¦åœ¨H5刷新或各端返回再进入时继续倒计时( é»˜è®¤false ï¼‰
     * @property {String}            uniqueKey        ä¸ºäº†åŒºåˆ†å¤šä¸ªé¡µé¢ï¼Œæˆ–者一个页面多个倒计时组件本地存储的继续倒计时变了
     *
     * @event {Function}    change    å€’计时期间,每秒触发一次
     * @event {Function}    start    å¼€å§‹å€’计时触发
     * @event {Function}    end        ç»“束倒计时触发
     * @example <u-code ref="uCode" @change="codeChange" seconds="20"></u-code>
     */
    export default {
        name: "u-code",
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        data() {
            return {
                secNum: this.seconds,
                timer: null,
                canGetCode: true, // æ˜¯å¦å¯ä»¥æ‰§è¡ŒéªŒè¯ç æ“ä½œ
            }
        },
        mounted() {
            this.checkKeepRunning()
        },
        watch: {
            seconds: {
                immediate: true,
                handler(n) {
                    this.secNum = n
                }
            }
        },
        methods: {
            checkKeepRunning() {
                // èŽ·å–ä¸Šä¸€æ¬¡é€€å‡ºé¡µé¢(H5还包括刷新)时的时间戳,如果没有上次的保存,此值可能为空
                let lastTimestamp = Number(uni.getStorageSync(this.uniqueKey + '_$uCountDownTimestamp'))
                if(!lastTimestamp) return this.changeEvent(this.startText)
                // å½“前秒的时间戳
                let nowTimestamp = Math.floor((+ new Date()) / 1000)
                // åˆ¤æ–­å½“前的时间戳,是否小于上一次的本该按设定结束,却提前结束的时间戳
                if(this.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) {
                    // å‰©ä½™å°šæœªæ‰§è¡Œå®Œçš„倒计秒数
                    this.secNum = lastTimestamp - nowTimestamp
                    // æ¸…除本地保存的变量
                    uni.removeStorageSync(this.uniqueKey + '_$uCountDownTimestamp')
                    // å¼€å§‹å€’计时
                    this.start()
                } else {
                    // å¦‚果不存在需要继续上一次的倒计时,执行正常的逻辑
                    this.changeEvent(this.startText)
                }
            },
            // å¼€å§‹å€’计时
            start() {
                // é˜²æ­¢å¿«é€Ÿç‚¹å‡»èŽ·å–éªŒè¯ç çš„æŒ‰é’®è€Œå¯¼è‡´å†…éƒ¨äº§ç”Ÿå¤šä¸ªå®šæ—¶å™¨å¯¼è‡´æ··ä¹±
                if(this.timer) {
                    clearInterval(this.timer)
                    this.timer = null
                }
                this.$emit('start')
                this.canGetCode = false
                // è¿™é‡Œæ”¾è¿™å¥ï¼Œæ˜¯ä¸ºäº†ä¸€å¼€å§‹æ—¶å°±æç¤ºï¼Œå¦åˆ™è¦ç­‰setInterval的1秒后才会有提示
                this.changeEvent(this.changeText.replace(/x|X/, this.secNum))
                this.setTimeToStorage()
                this.timer = setInterval(() => {
                    if (--this.secNum) {
                        // ç”¨å½“前倒计时的秒数替换提示字符串中的"x"字母
                        this.changeEvent(this.changeText.replace(/x|X/, this.secNum))
                    } else {
                        clearInterval(this.timer)
                        this.timer = null
                        this.changeEvent(this.endText)
                        this.secNum = this.seconds
                        this.$emit('end')
                        this.canGetCode = true
                    }
                }, 1000)
            },
            // é‡ç½®ï¼Œå¯ä»¥è®©ç”¨æˆ·å†æ¬¡èŽ·å–éªŒè¯ç 
            reset() {
                this.canGetCode = true
                clearInterval(this.timer)
                this.secNum = this.seconds
                this.changeEvent(this.endText)
            },
            changeEvent(text) {
                this.$emit('change', text)
            },
            // ä¿å­˜æ—¶é—´æˆ³ï¼Œä¸ºäº†é˜²æ­¢å€’计时尚未结束,H5刷新或者各端的右上角返回上一页再进来
            setTimeToStorage() {
                if(!this.keepRunning || !this.timer) return
                // è®°å½•当前的时间戳,为了下次进入页面,如果还在倒计时内的话,继续倒计时
                // å€’计时尚未结束,结果大于0;倒计时已经开始,就会小于初始值,如果等于初始值,说明没有开始倒计时,无需处理
                if(this.secNum > 0 && this.secNum <= this.seconds) {
                    // èŽ·å–å½“å‰æ—¶é—´æˆ³(+ new Date()为特殊写法),除以1000变成秒,再去除小数部分
                    let nowTimestamp = Math.floor((+ new Date()) / 1000)
                    // å°†æœ¬è¯¥ç»“束时候的时间戳保存起来 => å½“前时间戳 + å‰©ä½™çš„ç§’æ•°
                    uni.setStorage({
                        key: this.uniqueKey + '_$uCountDownTimestamp',
                        data: nowTimestamp + Number(this.secNum)
                    })
                }
            }
        },
        // ç»„件销毁的时候,清除定时器,否则定时器会继续存在,系统不会自动清除
        beforeDestroy() {
            this.setTimeToStorage()
            clearTimeout(this.timer)
            this.timer = null
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
</style>
uni_modules/uview-ui/components/u-col/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
export default {
    props: {
        // å çˆ¶å®¹å™¨å®½åº¦çš„多少等分,总分为12份
        span: {
            type: [String, Number],
            default: uni.$u.props.col.span
        },
        // æŒ‡å®šæ …格左侧的间隔数(总12栏)
        offset: {
            type: [String, Number],
            default: uni.$u.props.col.offset
        },
        // æ°´å¹³æŽ’列方式,可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`)
        justify: {
            type: String,
            default: uni.$u.props.col.justify
        },
        // åž‚直对齐方式,可选值为top、center、bottom、stretch
        align: {
            type: String,
            default: uni.$u.props.col.align
        },
        // æ–‡å­—对齐方式
        textAlign: {
            type: String,
            default: uni.$u.props.col.textAlign
        }
    }
}
uni_modules/uview-ui/components/u-col/u-col.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,162 @@
<template>
    <view
        class="u-col"
        ref="u-col"
        :class="[
            'u-col-' + span
        ]"
        :style="[colStyle]"
        @tap="clickHandler"
    >
        <slot></slot>
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * CodeInput æ …格系统的列
     * @description è¯¥ç»„件一般用于Layout å¸ƒå±€ é€šè¿‡åŸºç¡€çš„ 12 åˆ†æ ï¼Œè¿…速简便地创建布局
     * @tutorial https://www.uviewui.com/components/Layout.html
     * @property {String | Number}    span        æ …格占据的列数,总12等份 (默认 12 )
     * @property {String | Number}    offset        åˆ†æ å·¦è¾¹åç§»ï¼Œè®¡ç®—方式与span相同 (默认 0 )
     * @property {String}            justify        æ°´å¹³æŽ’列方式,可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`)  (默认 'start' )
     * @property {String}            align        åž‚直对齐方式,可选值为top、center、bottom、stretch (默认 'stretch' )
     * @property {String}            textAlign    æ–‡å­—水平对齐方式 (默认 'left' )
     * @property {Object}            customStyle    å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     * @event {Function}    click    col被点击,会阻止事件冒泡到row
     * @example     <u-col  span="3" offset="3" > <view class="demo-layout bg-purple"></view> </u-col>
     */
    export default {
        name: 'u-col',
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
                width: 0,
                parentData: {
                    gutter: 0
                },
                gridNum: 12
            }
        },
        computed: {
            uJustify() {
                if (this.justify == 'end' || this.justify == 'start') return 'flex-' + this.justify
                else if (this.justify == 'around' || this.justify == 'between') return 'space-' + this.justify
                else return this.justify
            },
            uAlignItem() {
                if (this.align == 'top') return 'flex-start'
                if (this.align == 'bottom') return 'flex-end'
                else return this.align
            },
            colStyle() {
                const style = {
                    // è¿™é‡Œå†™æˆ"padding: 0 10px"的形式是因为nvue的需要
                    paddingLeft: uni.$u.addUnit(uni.$u.getPx(this.parentData.gutter)/2),
                    paddingRight: uni.$u.addUnit(uni.$u.getPx(this.parentData.gutter)/2),
                    alignItems: this.uAlignItem,
                    justifyContent: this.uJustify,
                    textAlign: this.textAlign,
                    // #ifndef APP-NVUE
                    // åœ¨éžnvue上,使用百分比形式
                    flex: `0 0 ${100 / this.gridNum * this.span}%`,
                    marginLeft: 100 / 12 * this.offset + '%',
                    // #endif
                    // #ifdef APP-NVUE
                    // åœ¨nvue上,由于无法使用百分比单位,这里需要获取父组件的宽度,再计算得出该有对应的百分比尺寸
                    width: uni.$u.addUnit(Math.floor(this.width / this.gridNum * Number(this.span))),
                    marginLeft: uni.$u.addUnit(Math.floor(this.width / this.gridNum * Number(this.offset))),
                    // #endif
                }
                return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            async init() {
                // æ”¯ä»˜å®å°ç¨‹åºä¸æ”¯æŒprovide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环引用
                this.updateParentData()
                this.width = await this.parent.getComponentWidth()
            },
            updateParentData() {
                this.getParentData('u-row')
            },
            clickHandler(e) {
                this.$emit('click');
            }
        },
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-col {
        padding: 0;
        /* #ifndef APP-NVUE */
        box-sizing:border-box;
        /* #endif */
        /* #ifdef MP */
        display: block;
        /* #endif */
    }
    // nvue下百分比无效
    /* #ifndef APP-NVUE */
    .u-col-0 {
        width: 0;
    }
    .u-col-1 {
        width: calc(100%/12);
    }
    .u-col-2 {
        width: calc(100%/12 * 2);
    }
    .u-col-3 {
        width: calc(100%/12 * 3);
    }
    .u-col-4 {
        width: calc(100%/12 * 4);
    }
    .u-col-5 {
        width: calc(100%/12 * 5);
    }
    .u-col-6 {
        width: calc(100%/12 * 6);
    }
    .u-col-7 {
        width: calc(100%/12 * 7);
    }
    .u-col-8 {
        width: calc(100%/12 * 8);
    }
    .u-col-9 {
        width: calc(100%/12 * 9);
    }
    .u-col-10 {
        width: calc(100%/12 * 10);
    }
    .u-col-11 {
        width: calc(100%/12 * 11);
    }
    .u-col-12 {
        width: calc(100%/12 * 12);
    }
    /* #endif */
</style>
uni_modules/uview-ui/components/u-collapse-item/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
export default {
    props: {
        // æ ‡é¢˜
        title: {
            type: String,
            default: uni.$u.props.collapseItem.title
        },
        // æ ‡é¢˜å³ä¾§å†…容
        value: {
            type: String,
            default: uni.$u.props.collapseItem.value
        },
        // æ ‡é¢˜ä¸‹æ–¹çš„æè¿°ä¿¡æ¯
        label: {
            type: String,
            default: uni.$u.props.collapseItem.label
        },
        // æ˜¯å¦ç¦ç”¨æŠ˜å é¢æ¿
        disabled: {
            type: Boolean,
            default: uni.$u.props.collapseItem.disabled
        },
        // æ˜¯å¦å±•示右侧箭头并开启点击反馈
        isLink: {
            type: Boolean,
            default: uni.$u.props.collapseItem.isLink
        },
        // æ˜¯å¦å¼€å¯ç‚¹å‡»åé¦ˆ
        clickable: {
            type: Boolean,
            default: uni.$u.props.collapseItem.clickable
        },
        // æ˜¯å¦æ˜¾ç¤ºå†…边框
        border: {
            type: Boolean,
            default: uni.$u.props.collapseItem.border
        },
        // æ ‡é¢˜çš„对齐方式
        align: {
            type: String,
            default: uni.$u.props.collapseItem.align
        },
        // å”¯ä¸€æ ‡è¯†ç¬¦
        name: {
            type: [String, Number],
            default: uni.$u.props.collapseItem.name
        },
        // æ ‡é¢˜å·¦ä¾§å›¾ç‰‡ï¼Œå¯ä¸ºç»å¯¹è·¯å¾„的图片或内置图标
        icon: {
            type: String,
            default: uni.$u.props.collapseItem.icon
        },
        // é¢æ¿å±•开收起的过渡时间,单位ms
        duration: {
            type: Number,
            default: uni.$u.props.collapseItem.duration
        }
    }
}
uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,225 @@
<template>
    <view class="u-collapse-item">
        <u-cell
            :title="title"
            :value="value"
            :label="label"
            :icon="icon"
            :isLink="isLink"
            :clickable="clickable"
            :border="parentData.border && showBorder"
            @click="clickHandler"
            :arrowDirection="expanded ? 'up' : 'down'"
            :disabled="disabled"
        >
            <!-- #ifndef MP-WEIXIN -->
            <!-- å¾®ä¿¡å°ç¨‹åºä¸æ”¯æŒï¼Œå› ä¸ºå¾®ä¿¡ä¸­ä¸æ”¯æŒ <slot name="title" slot="title" />的写法 -->
            <template slot="title">
                <slot name="title"></slot>
            </template>
            <template slot="icon">
                <slot name="icon"></slot>
            </template>
            <template slot="value">
                <slot name="value"></slot>
            </template>
            <template slot="right-icon">
                <slot name="right-icon"></slot>
            </template>
            <!-- #endif -->
        </u-cell>
        <view
            class="u-collapse-item__content"
            :animation="animationData"
            ref="animation"
        >
            <view
                class="u-collapse-item__content__text content-class"
                :id="elId"
                :ref="elId"
            ><slot /></view>
        </view>
        <u-line v-if="parentData.border"></u-line>
    </view>
</template>
<script>
    import props from './props.js';
    // #ifdef APP-NVUE
    const animation = uni.requireNativePlugin('animation')
    const dom = uni.requireNativePlugin('dom')
    // #endif
    /**
     * collapseItem æŠ˜å é¢æ¿Item
     * @description é€šè¿‡æŠ˜å é¢æ¿æ”¶çº³å†…容区域(搭配u-collapse使用)
     * @tutorial https://www.uviewui.com/components/collapse.html
     * @property {String}            title         æ ‡é¢˜
     * @property {String}            value         æ ‡é¢˜å³ä¾§å†…容
     * @property {String}            label         æ ‡é¢˜ä¸‹æ–¹çš„æè¿°ä¿¡æ¯
     * @property {Boolean}            disbled     æ˜¯å¦ç¦ç”¨æŠ˜å é¢æ¿ ( é»˜è®¤ false )
     * @property {Boolean}            isLink         æ˜¯å¦å±•示右侧箭头并开启点击反馈 ( é»˜è®¤ true )
     * @property {Boolean}            clickable    æ˜¯å¦å¼€å¯ç‚¹å‡»åé¦ˆ ( é»˜è®¤ true )
     * @property {Boolean}            border        æ˜¯å¦æ˜¾ç¤ºå†…边框 ( é»˜è®¤ true )
     * @property {String}            align        æ ‡é¢˜çš„对齐方式 ( é»˜è®¤ 'left' )
     * @property {String | Number}    name        å”¯ä¸€æ ‡è¯†ç¬¦
     * @property {String}            icon        æ ‡é¢˜å·¦ä¾§å›¾ç‰‡ï¼Œå¯ä¸ºç»å¯¹è·¯å¾„的图片或内置图标
     * @event {Function}            change             æŸä¸ªitem被打开或者收起时触发
     * @example <u-collapse-item :title="item.head" v-for="(item, index) in itemList" :key="index">{{item.body}}</u-collapse-item>
     */
    export default {
        name: "u-collapse-item",
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
                elId: uni.$u.guid(),
                // uni.createAnimation的导出数据
                animationData: {},
                // æ˜¯å¦å±•开状态
                expanded: false,
                // æ ¹æ®expanded确定是否显示border,为了控制展开时,cell的下划线更好的显示效果,进行一定时间的延时
                showBorder: false,
                // æ˜¯å¦åŠ¨ç”»ä¸­ï¼Œå¦‚æžœæ˜¯åˆ™ä¸å…è®¸ç»§ç»­è§¦å‘ç‚¹å‡»
                animating: false,
                // çˆ¶ç»„ä»¶u-collapse的参数
                parentData: {
                    accordion: false,
                    border: false
                }
            };
        },
        watch: {
            expanded(n) {
                clearTimeout(this.timer)
                this.timer = null
                // è¿™é‡Œæ ¹æ®expanded的值来进行一定的延时,是为了cell的下划线更好的显示效果
                this.timer = setTimeout(() => {
                    this.showBorder = n
                }, n ? 10 : 290)
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            // å¼‚步获取内容,或者动态修改了内容时,需要重新初始化
            init() {
                // åˆå§‹åŒ–数据
                this.updateParentData()
                if (!this.parent) {
                    return uni.$u.error('u-collapse-item必须要搭配u-collapse组件使用')
                }
                const {
                    value,
                    accordion,
                    children = []
                } = this.parent
                if (accordion) {
                    if (uni.$u.test.array(value)) {
                        return uni.$u.error('手风琴模式下,u-collapse组件的value参数不能为数组')
                    }
                    this.expanded = this.name == value
                } else {
                    if (!uni.$u.test.array(value) && value !== null) {
                        return uni.$u.error('非手风琴模式下,u-collapse组件的value参数必须为数组')
                    }
                    this.expanded = (value || []).some(item => item == this.name)
                }
                // è®¾ç½®ç»„件的展开或收起状态
                this.$nextTick(function() {
                    this.setContentAnimate()
                })
            },
            updateParentData() {
                // æ­¤æ–¹æ³•在mixin中
                this.getParentData('u-collapse')
            },
            async setContentAnimate() {
                // æ¯æ¬¡é¢æ¿æ‰“开或者收起时,都查询元素尺寸
                // å¥½å¤„是,父组件从服务端获取内容后,变更折叠面板后可以获得最新的高度
                const rect = await this.queryRect()
                const height = this.expanded ? rect.height : 0
                this.animating = true
                // #ifdef APP-NVUE
                const ref = this.$refs['animation'].ref
                animation.transition(ref, {
                    styles: {
                        height: height + 'px'
                    },
                    duration: this.duration,
                    // å¿…须设置为true,否则会到面板收起或展开时,页面其他元素不会随之调整它们的布局
                    needLayout: true,
                    timingFunction: 'ease-in-out',
                }, () => {
                    this.animating = false
                })
                // #endif
                // #ifndef APP-NVUE
                const animation = uni.createAnimation({
                    timingFunction: 'ease-in-out',
                });
                animation
                    .height(height)
                    .step({
                        duration: this.duration,
                    })
                    .step()
                // å¯¼å‡ºåŠ¨ç”»æ•°æ®ç»™é¢æ¿çš„animationData值
                this.animationData = animation.export()
                // æ ‡è¯†åŠ¨ç”»ç»“æŸ
                uni.$u.sleep(this.duration).then(() => {
                    this.animating = false
                })
                // #endif
            },
            // ç‚¹å‡»collapsehead头部
            clickHandler() {
                if (this.disabled && this.animating) return
                // è®¾ç½®æœ¬ç»„件为相反的状态
                this.parent && this.parent.onChange(this)
            },
            // æŸ¥è¯¢å†…容高度
            queryRect() {
                // #ifndef APP-NVUE
                // $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://www.uviewui.com/js/getRect.html
                // ç»„件内部一般用this.$uGetRect,对外的为uni.$u.getRect,二者功能一致,名称不同
                return new Promise(resolve => {
                    this.$uGetRect(`#${this.elId}`).then(size => {
                        resolve(size)
                    })
                })
                // #endif
                // #ifdef APP-NVUE
                // nvue下,使用dom模块查询元素高度
                // è¿”回一个promise,让调用此方法的主体能使用then回调
                return new Promise(resolve => {
                    dom.getComponentRect(this.$refs[this.elId], res => {
                        resolve(res.size)
                    })
                })
                // #endif
            }
        },
    };
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-collapse-item {
        &__content {
            overflow: hidden;
            height: 0;
            &__text {
                padding: 12px 15px;
                color: $u-content-color;
                font-size: 14px;
                line-height: 18px;
            }
        }
    }
</style>
uni_modules/uview-ui/components/u-collapse/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
export default {
    props: {
        // å½“前展开面板的name,非手风琴模式:[<string | number>],手风琴模式:string | number
        value: {
            type: [String, Number, Array, null],
            default: uni.$u.props.collapse.value
        },
        // æ˜¯å¦æ‰‹é£Žç´æ¨¡å¼
        accordion: {
            type: Boolean,
            default: uni.$u.props.collapse.accordion
        },
        // æ˜¯å¦æ˜¾ç¤ºå¤–边框
        border: {
            type: Boolean,
            default: uni.$u.props.collapse.border
        }
    }
}
uni_modules/uview-ui/components/u-collapse/u-collapse.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,90 @@
<template>
    <view class="u-collapse">
        <u-line v-if="border"></u-line>
        <slot />
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * collapse æŠ˜å é¢æ¿
     * @description é€šè¿‡æŠ˜å é¢æ¿æ”¶çº³å†…容区域
     * @tutorial https://www.uviewui.com/components/collapse.html
     * @property {String | Number | Array}    value        å½“前展开面板的name,非手风琴模式:[<string | number>],手风琴模式:string | number
     * @property {Boolean}                    accordion    æ˜¯å¦æ‰‹é£Žç´æ¨¡å¼ï¼ˆ é»˜è®¤ false ï¼‰
     * @property {Boolean}                    border        æ˜¯å¦æ˜¾ç¤ºå¤–边框 ( é»˜è®¤ true ï¼‰
     * @event {Function}    change         å½“前激活面板展开时触发(如果是手风琴模式,参数activeNames类型为String,否则为Array)
     * @example <u-collapse></u-collapse>
     */
    export default {
        name: "u-collapse",
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        watch: {
            needInit() {
                this.init()
            }
        },
        created() {
            this.children = []
        },
        computed: {
            needInit() {
                // é€šè¿‡computed,同时监听accordion和value值的变化
                // å†é€šè¿‡watch去执行init()方法,进行再一次的初始化
                return [this.accordion, this.value]
            }
        },
        watch: {
            // å½“父组件需要子组件需要共享的参数发生了变化,手动通知子组件
            parentData() {
                if (this.children.length) {
                    this.children.map(child => {
                        // åˆ¤æ–­å­ç»„ä»¶(u-checkbox)如果有updateParentData方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
                        typeof(child.updateParentData) === 'function' && child.updateParentData()
                    })
                }
            },
        },
        methods: {
            // é‡æ–°åˆå§‹åŒ–一次内部的所有子元素
            init() {
                this.children.map(child => {
                    child.init()
                })
            },
            /**
             * collapse-item被点击时触发,由collapse统一处理各子组件的状态
             * @param {Object} target è¢«æ“ä½œçš„面板的实例
             */
            onChange(target) {
                let changeArr = []
                this.children.map((child, index) => {
                    // å¦‚果是手风琴模式,将其他的折叠面板收起来
                    if (this.accordion) {
                        child.expanded = child === target ? !target.expanded : false
                        child.setContentAnimate()
                    } else {
                        if(child === target) {
                            child.expanded = !child.expanded
                            child.setContentAnimate()
                        }
                    }
                    // æ‹¼æŽ¥change事件中,数组元素的状态
                    changeArr.push({
                        // å¦‚果没有定义name属性,则默认返回组件的index索引
                        name: child.name || index,
                        status: child.expanded ? 'open' : 'close'
                    })
                })
                this.$emit('change', changeArr)
                this.$emit(target.expanded ? 'open' : 'close', target.name)
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
</style>
uni_modules/uview-ui/components/u-column-notice/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,55 @@
export default {
    props: {
        // æ˜¾ç¤ºçš„内容,字符串
        text: {
            type: [Array],
            default: uni.$u.props.columnNotice.text
        },
        // æ˜¯å¦æ˜¾ç¤ºå·¦ä¾§çš„音量图标
        icon: {
            type: String,
            default: uni.$u.props.columnNotice.icon
        },
        // é€šå‘Šæ¨¡å¼ï¼Œlink-显示右箭头,closable-显示右侧关闭图标
        mode: {
            type: String,
            default: uni.$u.props.columnNotice.mode
        },
        // æ–‡å­—颜色,各图标也会使用文字颜色
        color: {
            type: String,
            default: uni.$u.props.columnNotice.color
        },
        // èƒŒæ™¯é¢œè‰²
        bgColor: {
            type: String,
            default: uni.$u.props.columnNotice.bgColor
        },
        // å­—体大小,单位px
        fontSize: {
            type: [String, Number],
            default: uni.$u.props.columnNotice.fontSize
        },
        // æ°´å¹³æ»šåŠ¨æ—¶çš„æ»šåŠ¨é€Ÿåº¦ï¼Œå³æ¯ç§’æ»šåŠ¨å¤šå°‘px(px),这有利于控制文字无论多少时,都能有一个恒定的速度
        speed: {
            type: [String, Number],
            default: uni.$u.props.columnNotice.speed
        },
        // direction = row时,是否使用步进形式滚动
        step: {
            type: Boolean,
            default: uni.$u.props.columnNotice.step
        },
        // æ»šåŠ¨ä¸€ä¸ªå‘¨æœŸçš„æ—¶é—´é•¿ï¼Œå•ä½ms
        duration: {
            type: [String, Number],
            default: uni.$u.props.columnNotice.duration
        },
        // æ˜¯å¦ç¦æ­¢ç”¨æ‰‹æ»‘动切换
        // ç›®å‰HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序
        disableTouch: {
            type: Boolean,
            default: uni.$u.props.columnNotice.disableTouch
        }
    }
}
uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,160 @@
<template>
    <view
        class="u-notice"
        @tap="clickHandler"
    >
        <slot name="icon">
            <view
                class="u-notice__left-icon"
                v-if="icon"
            >
                <u-icon
                    :name="icon"
                    :color="color"
                    size="19"
                ></u-icon>
            </view>
        </slot>
        <swiper
            :disable-touch="disableTouch"
            :vertical="step ? false : true"
            circular
            :interval="duration"
            :autoplay="true"
            class="u-notice__swiper"
            @change="noticeChange"
        >
            <swiper-item
                v-for="(item, index) in text"
                :key="index"
                class="u-notice__swiper__item"
            >
                <text
                    class="u-notice__swiper__item__text u-line-1"
                    :style="[textStyle]"
                >{{ item }}</text>
            </swiper-item>
        </swiper>
        <view
            class="u-notice__right-icon"
            v-if="['link', 'closable'].includes(mode)"
        >
            <u-icon
                v-if="mode === 'link'"
                name="arrow-right"
                :size="17"
                :color="color"
            ></u-icon>
            <u-icon
                v-if="mode === 'closable'"
                name="close"
                :size="16"
                :color="color"
                @click="close"
            ></u-icon>
        </view>
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * ColumnNotice æ»šåŠ¨é€šçŸ¥ä¸­çš„åž‚ç›´æ»šåŠ¨ å†…部组件
     * @description è¯¥ç»„件用于滚动通告场景,是其中的垂直滚动方式
     * @tutorial https://www.uviewui.com/components/noticeBar.html
     * @property {Array}            text             æ˜¾ç¤ºçš„内容,字符串
     * @property {String}            icon             æ˜¯å¦æ˜¾ç¤ºå·¦ä¾§çš„音量图标 ï¼ˆ é»˜è®¤ 'volume' ï¼‰
     * @property {String}            mode             é€šå‘Šæ¨¡å¼ï¼Œlink-显示右箭头,closable-显示右侧关闭图标
     * @property {String}            color             æ–‡å­—颜色,各图标也会使用文字颜色 ï¼ˆ é»˜è®¤ '#f9ae3d' ï¼‰
     * @property {String}            bgColor         èƒŒæ™¯é¢œè‰² ï¼ˆ é»˜è®¤ '#fdf6ec' ï¼‰
     * @property {String | Number}    fontSize        å­—体大小,单位px  ï¼ˆ é»˜è®¤ 14 ï¼‰
     * @property {String | Number}    speed            æ°´å¹³æ»šåŠ¨æ—¶çš„æ»šåŠ¨é€Ÿåº¦ï¼Œå³æ¯ç§’æ»šåŠ¨å¤šå°‘px(rpx),这有利于控制文字无论多少时,都能有一个恒定的速度 ï¼ˆ é»˜è®¤ 80 ï¼‰
     * @property {Boolean}            step            direction = row时,是否使用步进形式滚动 ï¼ˆ é»˜è®¤ false ï¼‰
     * @property {String | Number}    duration        æ»šåŠ¨ä¸€ä¸ªå‘¨æœŸçš„æ—¶é—´é•¿ï¼Œå•ä½ms ï¼ˆ é»˜è®¤ 1500 ï¼‰
     * @property {Boolean}            disableTouch    æ˜¯å¦ç¦æ­¢ç”¨æ‰‹æ»‘动切换   ç›®å‰HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序 ï¼ˆ é»˜è®¤ true ï¼‰
     * @example
     */
    export default {
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        watch: {
            text: {
                immediate: true,
                handler(newValue, oldValue) {
                    if(!uni.$u.test.array(newValue)) {
                        uni.$u.error('noticebar组件direction为column时,要求text参数为数组形式')
                    }
                }
            }
        },
        computed: {
            // æ–‡å­—内容的样式
            textStyle() {
                let style = {}
                style.color = this.color
                style.fontSize = uni.$u.addUnit(this.fontSize)
                return style
            },
            // åž‚直或者水平滚动
            vertical() {
                if (this.mode == 'horizontal') return false
                else return true
            },
        },
        data() {
            return {
                index:0
            }
        },
        methods: {
            noticeChange(e){
                this.index = e.detail.current
            },
            // ç‚¹å‡»é€šå‘Šæ 
            clickHandler() {
                this.$emit('click', this.index)
            },
            // ç‚¹å‡»å…³é—­æŒ‰é’®
            close() {
                this.$emit('close')
            }
        }
    };
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-notice {
        @include flex;
        align-items: center;
        justify-content: space-between;
        &__left-icon {
            align-items: center;
            margin-right: 5px;
        }
        &__right-icon {
            margin-left: 5px;
            align-items: center;
        }
        &__swiper {
            height: 16px;
            @include flex;
            align-items: center;
            flex: 1;
            &__item {
                @include flex;
                align-items: center;
                overflow: hidden;
                &__text {
                    font-size: 14px;
                    color: $u-warning;
                }
            }
        }
    }
</style>
uni_modules/uview-ui/components/u-count-down/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
export default {
    props: {
        // å€’计时时长,单位ms
        time: {
            type: [String, Number],
            default: uni.$u.props.countDown.time
        },
        // æ—¶é—´æ ¼å¼ï¼ŒDD-日,HH-时,mm-分,ss-秒,SSS-毫秒
        format: {
            type: String,
            default: uni.$u.props.countDown.format
        },
        // æ˜¯å¦è‡ªåŠ¨å¼€å§‹å€’è®¡æ—¶
        autoStart: {
            type: Boolean,
            default: uni.$u.props.countDown.autoStart
        },
        // æ˜¯å¦å±•示毫秒倒计时
        millisecond: {
            type: Boolean,
            default: uni.$u.props.countDown.millisecond
        }
    }
}
uni_modules/uview-ui/components/u-count-down/u-count-down.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,163 @@
<template>
    <view class="u-count-down">
        <slot>
            <text class="u-count-down__text">{{ formattedTime }}</text>
        </slot>
    </view>
</template>
<script>
    import props from './props.js';
    import {
        isSameSecond,
        parseFormat,
        parseTimeData
    } from './utils';
    /**
     * u-count-down å€’计时
     * @description è¯¥ç»„件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。
     * @tutorial https://uviewui.com/components/countDown.html
     * @property {String | Number}    time        å€’计时时长,单位ms ï¼ˆé»˜è®¤ 0 ï¼‰
     * @property {String}            format        æ—¶é—´æ ¼å¼ï¼ŒDD-日,HH-时,mm-分,ss-秒,SSS-毫秒  ï¼ˆé»˜è®¤ 'HH:mm:ss' ï¼‰
     * @property {Boolean}            autoStart    æ˜¯å¦è‡ªåŠ¨å¼€å§‹å€’è®¡æ—¶ ï¼ˆé»˜è®¤ true ï¼‰
     * @property {Boolean}            millisecond    æ˜¯å¦å±•示毫秒倒计时 ï¼ˆé»˜è®¤ false ï¼‰
     * @event {Function} finish å€’计时结束时触发
     * @event {Function} change å€’计时变化时触发
     * @event {Function} start    å¼€å§‹å€’计时
     * @event {Function} pause    æš‚停倒计时
     * @event {Function} reset    é‡è®¾å€’计时,若 auto-start ä¸º true,重设后会自动开始倒计时
     * @example <u-count-down :time="time"></u-count-down>
     */
    export default {
        name: 'u-count-down',
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
                timer: null,
                // å„单位(天,时,分等)剩余时间
                timeData: parseTimeData(0),
                // æ ¼å¼åŒ–后的时间,如"03:23:21"
                formattedTime: '0',
                // å€’计时是否正在进行中
                runing: false,
                endTime: 0, // ç»“束的毫秒时间戳
                remainTime: 0, // å‰©ä½™çš„æ¯«ç§’æ—¶é—´
            }
        },
        watch: {
            time(n) {
                this.reset()
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                this.reset()
            },
            // å¼€å§‹å€’计时
            start() {
                if (this.runing) return
                // æ ‡è¯†ä¸ºè¿›è¡Œä¸­
                this.runing = true
                // ç»“束时间戳 = æ­¤åˆ»æ—¶é—´æˆ³ + å‰©ä½™çš„æ—¶é—´
                this.endTime = Date.now() + this.remainTime
                this.toTick()
            },
            // æ ¹æ®æ˜¯å¦å±•示毫秒,执行不同操作函数
            toTick() {
                if (this.millisecond) {
                    this.microTick()
                } else {
                    this.macroTick()
                }
            },
            macroTick() {
                this.clearTimeout()
                // æ¯éš”一定时间,更新一遍定时器的值
                // åŒæ—¶æ­¤å®šæ—¶å™¨çš„作用也能带来毫秒级的更新
                this.timer = setTimeout(() => {
                    // èŽ·å–å‰©ä½™æ—¶é—´
                    const remain = this.getRemainTime()
                    // é‡è®¾å‰©ä½™æ—¶é—´
                    if (!isSameSecond(remain, this.remainTime) || remain === 0) {
                        this.setRemainTime(remain)
                    }
                    // å¦‚果剩余时间不为0,则继续检查更新倒计时
                    if (this.remainTime !== 0) {
                        this.macroTick()
                    }
                }, 30)
            },
            microTick() {
                this.clearTimeout()
                this.timer = setTimeout(() => {
                    this.setRemainTime(this.getRemainTime())
                    if (this.remainTime !== 0) {
                        this.microTick()
                    }
                }, 50)
            },
            // èŽ·å–å‰©ä½™çš„æ—¶é—´
            getRemainTime() {
                // å–最大值,防止出现小于0的剩余时间值
                return Math.max(this.endTime - Date.now(), 0)
            },
            // è®¾ç½®å‰©ä½™çš„æ—¶é—´
            setRemainTime(remain) {
                this.remainTime = remain
                // æ ¹æ®å‰©ä½™çš„æ¯«ç§’时间,得出该有天,小时,分钟等的值,返回一个对象
                const timeData = parseTimeData(remain)
                this.$emit('change', timeData)
                // å¾—出格式化后的时间
                this.formattedTime = parseFormat(this.format, timeData)
                // å¦‚果时间已到,停止倒计时
                if (remain <= 0) {
                    this.pause()
                    this.$emit('finish')
                }
            },
            // é‡ç½®å€’计时
            reset() {
                this.pause()
                this.remainTime = this.time
                this.setRemainTime(this.remainTime)
                if (this.autoStart) {
                    this.start()
                }
            },
            // æš‚停倒计时
            pause() {
                this.runing = false;
                this.clearTimeout()
            },
            // æ¸…空定时器
            clearTimeout() {
                clearTimeout(this.timer)
                this.timer = null
            }
        },
        beforeDestroy() {
            this.clearTimeout()
        }
    }
</script>
<style
    lang="scss"
    scoped
>
    @import "../../libs/css/components.scss";
    $u-count-down-text-color:$u-content-color !default;
    $u-count-down-text-font-size:15px !default;
    $u-count-down-text-line-height:22px !default;
    .u-count-down {
        &__text {
            color: $u-count-down-text-color;
            font-size: $u-count-down-text-font-size;
            line-height: $u-count-down-text-line-height;
        }
    }
</style>
uni_modules/uview-ui/components/u-count-down/utils.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
// è¡¥0,如1 -> 01
function padZero(num, targetLength = 2) {
    let str = `${num}`
    while (str.length < targetLength) {
        str = `0${str}`
    }
    return str
}
const SECOND = 1000
const MINUTE = 60 * SECOND
const HOUR = 60 * MINUTE
const DAY = 24 * HOUR
export function parseTimeData(time) {
    const days = Math.floor(time / DAY)
    const hours = Math.floor((time % DAY) / HOUR)
    const minutes = Math.floor((time % HOUR) / MINUTE)
    const seconds = Math.floor((time % MINUTE) / SECOND)
    const milliseconds = Math.floor(time % SECOND)
    return {
        days,
        hours,
        minutes,
        seconds,
        milliseconds
    }
}
export function parseFormat(format, timeData) {
    let {
        days,
        hours,
        minutes,
        seconds,
        milliseconds
    } = timeData
    // å¦‚果格式化字符串中不存在DD(天),则将天的时间转为小时中去
    if (format.indexOf('DD') === -1) {
        hours += days * 24
    } else {
        // å¯¹å¤©è¡¥0
        format = format.replace('DD', padZero(days))
    }
    // å…¶ä»–同理于DD的格式化处理方式
    if (format.indexOf('HH') === -1) {
        minutes += hours * 60
    } else {
        format = format.replace('HH', padZero(hours))
    }
    if (format.indexOf('mm') === -1) {
        seconds += minutes * 60
    } else {
        format = format.replace('mm', padZero(minutes))
    }
    if (format.indexOf('ss') === -1) {
        milliseconds += seconds * 1000
    } else {
        format = format.replace('ss', padZero(seconds))
    }
    return format.replace('SSS', padZero(milliseconds, 3))
}
export function isSameSecond(time1, time2) {
    return Math.floor(time1 / 1000) === Math.floor(time2 / 1000)
}
uni_modules/uview-ui/components/u-count-to/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
export default {
    props: {
        // å¼€å§‹çš„æ•°å€¼ï¼Œé»˜è®¤ä»Ž0增长到某一个数
        startVal: {
            type: [String, Number],
            default: uni.$u.props.countTo.startVal
        },
        // è¦æ»šåŠ¨çš„ç›®æ ‡æ•°å€¼ï¼Œå¿…é¡»
        endVal: {
            type: [String, Number],
            default: uni.$u.props.countTo.endVal
        },
        // æ»šåŠ¨åˆ°ç›®æ ‡æ•°å€¼çš„åŠ¨ç”»æŒç»­æ—¶é—´ï¼Œå•ä½ä¸ºæ¯«ç§’ï¼ˆms)
        duration: {
            type: [String, Number],
            default: uni.$u.props.countTo.duration
        },
        // è®¾ç½®æ•°å€¼åŽæ˜¯å¦è‡ªåŠ¨å¼€å§‹æ»šåŠ¨
        autoplay: {
            type: Boolean,
            default: uni.$u.props.countTo.autoplay
        },
        // è¦æ˜¾ç¤ºçš„小数位数
        decimals: {
            type: [String, Number],
            default: uni.$u.props.countTo.decimals
        },
        // æ˜¯å¦åœ¨å³å°†åˆ°è¾¾ç›®æ ‡æ•°å€¼çš„æ—¶å€™ï¼Œä½¿ç”¨ç¼“慢滚动的效果
        useEasing: {
            type: Boolean,
            default: uni.$u.props.countTo.useEasing
        },
        // åè¿›åˆ¶åˆ†å‰²
        decimal: {
            type: [String, Number],
            default: uni.$u.props.countTo.decimal
        },
        // å­—体颜色
        color: {
            type: String,
            default: uni.$u.props.countTo.color
        },
        // å­—体大小
        fontSize: {
            type: [String, Number],
            default: uni.$u.props.countTo.fontSize
        },
        // æ˜¯å¦åŠ ç²—å­—ä½“
        bold: {
            type: Boolean,
            default: uni.$u.props.countTo.bold
        },
        // åƒä½åˆ†éš”符,类似金额的分割(ï¿¥23,321.05中的",")
        separator: {
            type: String,
            default: uni.$u.props.countTo.separator
        }
    }
}
uni_modules/uview-ui/components/u-count-to/u-count-to.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,184 @@
<template>
    <text
        class="u-count-num"
        :style="{
            fontSize: $u.addUnit(fontSize),
            fontWeight: bold ? 'bold' : 'normal',
            color: color
        }"
    >{{ displayValue }}</text>
</template>
<script>
    import props from './props.js';
/**
 * countTo æ•°å­—滚动
 * @description è¯¥ç»„件一般用于需要滚动数字到某一个值的场景,目标要求是一个递增的值。
 * @tutorial https://www.uviewui.com/components/countTo.html
 * @property {String | Number}    startVal    å¼€å§‹çš„æ•°å€¼ï¼Œé»˜è®¤ä»Ž0增长到某一个数(默认 0 ï¼‰
 * @property {String | Number}    endVal        è¦æ»šåŠ¨çš„ç›®æ ‡æ•°å€¼ï¼Œå¿…é¡» ï¼ˆé»˜è®¤ 0 ï¼‰
 * @property {String | Number}    duration    æ»šåŠ¨åˆ°ç›®æ ‡æ•°å€¼çš„åŠ¨ç”»æŒç»­æ—¶é—´ï¼Œå•ä½ä¸ºæ¯«ç§’ï¼ˆms) ï¼ˆé»˜è®¤ 2000 ï¼‰
 * @property {Boolean}            autoplay    è®¾ç½®æ•°å€¼åŽæ˜¯å¦è‡ªåŠ¨å¼€å§‹æ»šåŠ¨ ï¼ˆé»˜è®¤ true ï¼‰
 * @property {String | Number}    decimals    è¦æ˜¾ç¤ºçš„小数位数,见官网说明(默认 0 ï¼‰
 * @property {Boolean}            useEasing    æ»šåŠ¨ç»“æŸæ—¶ï¼Œæ˜¯å¦ç¼“åŠ¨ç»“å°¾ï¼Œè§å®˜ç½‘è¯´æ˜Žï¼ˆé»˜è®¤ true ï¼‰
 * @property {String}            decimal        åè¿›åˆ¶åˆ†å‰² ï¼ˆ é»˜è®¤ "." ï¼‰
 * @property {String}            color        å­—体颜色( é»˜è®¤ '#606266' )
 * @property {String | Number}    fontSize    å­—体大小,单位px( é»˜è®¤ 22 ï¼‰
 * @property {Boolean}            bold        å­—体是否加粗(默认 false ï¼‰
 * @property {String}            separator    åƒä½åˆ†éš”符,见官网说明
 * @event {Function} end æ•°å€¼æ»šåŠ¨åˆ°ç›®æ ‡å€¼æ—¶è§¦å‘
 * @example <u-count-to ref="uCountTo" :end-val="endVal" :autoplay="autoplay"></u-count-to>
 */
export default {
    name: 'u-count-to',
    data() {
        return {
            localStartVal: this.startVal,
            displayValue: this.formatNumber(this.startVal),
            printVal: null,
            paused: false, // æ˜¯å¦æš‚停
            localDuration: Number(this.duration),
            startTime: null, // å¼€å§‹çš„æ—¶é—´
            timestamp: null, // æ—¶é—´æˆ³
            remaining: null, // åœç•™çš„æ—¶é—´
            rAF: null,
            lastTime: 0 // ä¸Šä¸€æ¬¡çš„æ—¶é—´
        };
    },
    mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
    computed: {
        countDown() {
            return this.startVal > this.endVal;
        }
    },
    watch: {
        startVal() {
            this.autoplay && this.start();
        },
        endVal() {
            this.autoplay && this.start();
        }
    },
    mounted() {
        this.autoplay && this.start();
    },
    methods: {
        easingFn(t, b, c, d) {
            return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b;
        },
        requestAnimationFrame(callback) {
            const currTime = new Date().getTime();
            // ä¸ºäº†ä½¿setTimteout的尽可能的接近每秒60帧的效果
            const timeToCall = Math.max(0, 16 - (currTime - this.lastTime));
            const id = setTimeout(() => {
                callback(currTime + timeToCall);
            }, timeToCall);
            this.lastTime = currTime + timeToCall;
            return id;
        },
        cancelAnimationFrame(id) {
            clearTimeout(id);
        },
        // å¼€å§‹æ»šåŠ¨æ•°å­—
        start() {
            this.localStartVal = this.startVal;
            this.startTime = null;
            this.localDuration = this.duration;
            this.paused = false;
            this.rAF = this.requestAnimationFrame(this.count);
        },
        // æš‚定状态,重新再开始滚动;或者滚动状态下,暂停
        reStart() {
            if (this.paused) {
                this.resume();
                this.paused = false;
            } else {
                this.stop();
                this.paused = true;
            }
        },
        // æš‚停
        stop() {
            this.cancelAnimationFrame(this.rAF);
        },
        // é‡æ–°å¼€å§‹(暂停的情况下)
        resume() {
            if (!this.remaining) return
            this.startTime = 0;
            this.localDuration = this.remaining;
            this.localStartVal = this.printVal;
            this.requestAnimationFrame(this.count);
        },
        // é‡ç½®
        reset() {
            this.startTime = null;
            this.cancelAnimationFrame(this.rAF);
            this.displayValue = this.formatNumber(this.startVal);
        },
        count(timestamp) {
            if (!this.startTime) this.startTime = timestamp;
            this.timestamp = timestamp;
            const progress = timestamp - this.startTime;
            this.remaining = this.localDuration - progress;
            if (this.useEasing) {
                if (this.countDown) {
                    this.printVal = this.localStartVal - this.easingFn(progress, 0, this.localStartVal - this.endVal, this.localDuration);
                } else {
                    this.printVal = this.easingFn(progress, this.localStartVal, this.endVal - this.localStartVal, this.localDuration);
                }
            } else {
                if (this.countDown) {
                    this.printVal = this.localStartVal - (this.localStartVal - this.endVal) * (progress / this.localDuration);
                } else {
                    this.printVal = this.localStartVal + (this.endVal - this.localStartVal) * (progress / this.localDuration);
                }
            }
            if (this.countDown) {
                this.printVal = this.printVal < this.endVal ? this.endVal : this.printVal;
            } else {
                this.printVal = this.printVal > this.endVal ? this.endVal : this.printVal;
            }
            this.displayValue = this.formatNumber(this.printVal) || 0;
            if (progress < this.localDuration) {
                this.rAF = this.requestAnimationFrame(this.count);
            } else {
                this.$emit('end');
            }
        },
        // åˆ¤æ–­æ˜¯å¦æ•°å­—
        isNumber(val) {
            return !isNaN(parseFloat(val));
        },
        formatNumber(num) {
            // å°†num转为Number类型,因为其值可能为字符串数值,调用toFixed会报错
            num = Number(num);
            num = num.toFixed(Number(this.decimals));
            num += '';
            const x = num.split('.');
            let x1 = x[0];
            const x2 = x.length > 1 ? this.decimal + x[1] : '';
            const rgx = /(\d+)(\d{3})/;
            if (this.separator && !this.isNumber(this.separator)) {
                while (rgx.test(x1)) {
                    x1 = x1.replace(rgx, '$1' + this.separator + '$2');
                }
            }
            return x1 + x2;
        },
        destroyed() {
            this.cancelAnimationFrame(this.rAF);
        }
    }
};
</script>
<style lang="scss" scoped>
@import "../../libs/css/components.scss";
.u-count-num {
    /* #ifndef APP-NVUE */
    display: inline-flex;
    /* #endif */
    text-align: center;
}
</style>
uni_modules/uview-ui/components/u-datetime-picker/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,116 @@
export default {
    props: {
        // æ˜¯å¦æ‰“开组件
        show: {
            type: Boolean,
            default: uni.$u.props.datetimePicker.show
        },
        // æ˜¯å¦å±•示顶部的操作栏
        showToolbar: {
            type: Boolean,
            default: uni.$u.props.datetimePicker.showToolbar
        },
        // ç»‘定值
        value: {
            type: [String, Number],
            default: uni.$u.props.datetimePicker.value
        },
        // é¡¶éƒ¨æ ‡é¢˜
        title: {
            type: String,
            default: uni.$u.props.datetimePicker.title
        },
        // å±•示格式,mode=date为日期选择,mode=time为时间选择,mode=year-month为年月选择,mode=datetime为日期时间选择
        mode: {
            type: String,
            default: uni.$u.props.datetimePicker.mode
        },
        // å¯é€‰çš„æœ€å¤§æ—¶é—´
        maxDate: {
            type: Number,
            // æœ€å¤§é»˜è®¤å€¼ä¸ºåŽ10å¹´
            default: uni.$u.props.datetimePicker.maxDate
        },
        // å¯é€‰çš„æœ€å°æ—¶é—´
        minDate: {
            type: Number,
            // æœ€å°é»˜è®¤å€¼ä¸ºå‰10å¹´
            default: uni.$u.props.datetimePicker.minDate
        },
        // å¯é€‰çš„æœ€å°å°æ—¶ï¼Œä»…mode=time有效
        minHour: {
            type: Number,
            default: uni.$u.props.datetimePicker.minHour
        },
        // å¯é€‰çš„æœ€å¤§å°æ—¶ï¼Œä»…mode=time有效
        maxHour: {
            type: Number,
            default: uni.$u.props.datetimePicker.maxHour
        },
        // å¯é€‰çš„æœ€å°åˆ†é’Ÿï¼Œä»…mode=time有效
        minMinute: {
            type: Number,
            default: uni.$u.props.datetimePicker.minMinute
        },
        // å¯é€‰çš„æœ€å¤§åˆ†é’Ÿï¼Œä»…mode=time有效
        maxMinute: {
            type: Number,
            default: uni.$u.props.datetimePicker.maxMinute
        },
        // é€‰é¡¹è¿‡æ»¤å‡½æ•°
        filter: {
            type: [Function, null],
            default: uni.$u.props.datetimePicker.filter
        },
        // é€‰é¡¹æ ¼å¼åŒ–函数
        formatter: {
            type: [Function, null],
            default: uni.$u.props.datetimePicker.formatter
        },
        // æ˜¯å¦æ˜¾ç¤ºåŠ è½½ä¸­çŠ¶æ€
        loading: {
            type: Boolean,
            default: uni.$u.props.datetimePicker.loading
        },
        // å„列中,单个选项的高度
        itemHeight: {
            type: [String, Number],
            default: uni.$u.props.datetimePicker.itemHeight
        },
        // å–消按钮的文字
        cancelText: {
            type: String,
            default: uni.$u.props.datetimePicker.cancelText
        },
        // ç¡®è®¤æŒ‰é’®çš„æ–‡å­—
        confirmText: {
            type: String,
            default: uni.$u.props.datetimePicker.confirmText
        },
        // å–消按钮的颜色
        cancelColor: {
            type: String,
            default: uni.$u.props.datetimePicker.cancelColor
        },
        // ç¡®è®¤æŒ‰é’®çš„颜色
        confirmColor: {
            type: String,
            default: uni.$u.props.datetimePicker.confirmColor
        },
        // æ¯åˆ—中可见选项的数量
        visibleItemCount: {
            type: [String, Number],
            default: uni.$u.props.datetimePicker.visibleItemCount
        },
        // æ˜¯å¦å…è®¸ç‚¹å‡»é®ç½©å…³é—­é€‰æ‹©å™¨
        closeOnClickOverlay: {
            type: Boolean,
            default: uni.$u.props.datetimePicker.closeOnClickOverlay
        },
        // å„列的默认索引
        defaultIndex: {
            type: Array,
            default: uni.$u.props.datetimePicker.defaultIndex
        }
    }
}
uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,360 @@
<template>
    <u-picker
        ref="picker"
        :show="show"
        :closeOnClickOverlay="closeOnClickOverlay"
        :columns="columns"
        :title="title"
        :itemHeight="itemHeight"
        :showToolbar="showToolbar"
        :visibleItemCount="visibleItemCount"
        :defaultIndex="innerDefaultIndex"
        :cancelText="cancelText"
        :confirmText="confirmText"
        :cancelColor="cancelColor"
        :confirmColor="confirmColor"
        @close="close"
        @cancel="cancel"
        @confirm="confirm"
        @change="change"
    >
    </u-picker>
</template>
<script>
    function times(n, iteratee) {
        let index = -1
        const result = Array(n < 0 ? 0 : n)
        while (++index < n) {
            result[index] = iteratee(index)
        }
        return result
    }
    import props from './props.js';
    import dayjs from '../../libs/util/dayjs.js';
    /**
     * DatetimePicker æ—¶é—´æ—¥æœŸé€‰æ‹©å™¨
     * @description æ­¤é€‰æ‹©å™¨ç”¨äºŽæ—¶é—´æ—¥æœŸ
     * @tutorial https://www.uviewui.com/components/datetimePicker.html
     * @property {Boolean}            show                ç”¨äºŽæŽ§åˆ¶é€‰æ‹©å™¨çš„弹出与收起 ( é»˜è®¤ false )
     * @property {Boolean}            showToolbar            æ˜¯å¦æ˜¾ç¤ºé¡¶éƒ¨çš„æ“ä½œæ   ( é»˜è®¤ true )
     * @property {String | Number}    value                ç»‘定值
     * @property {String}            title                é¡¶éƒ¨æ ‡é¢˜
     * @property {String}            mode                å±•示格式 mode=date为日期选择,mode=time为时间选择,mode=year-month为年月选择,mode=datetime为日期时间选择  ( é»˜è®¤ â€˜datetime )
     * @property {Number}            maxDate                å¯é€‰çš„æœ€å¤§æ—¶é—´  é»˜è®¤å€¼ä¸ºåŽ10å¹´
     * @property {Number}            minDate                å¯é€‰çš„æœ€å°æ—¶é—´  é»˜è®¤å€¼ä¸ºå‰10å¹´
     * @property {Number}            minHour                å¯é€‰çš„æœ€å°å°æ—¶ï¼Œä»…mode=time有效   ( é»˜è®¤ 0 )
     * @property {Number}            maxHour                å¯é€‰çš„æœ€å¤§å°æ—¶ï¼Œä»…mode=time有效      ( é»˜è®¤ 23 )
     * @property {Number}            minMinute            å¯é€‰çš„æœ€å°åˆ†é’Ÿï¼Œä»…mode=time有效      ( é»˜è®¤ 0 )
     * @property {Number}            maxMinute            å¯é€‰çš„æœ€å¤§åˆ†é’Ÿï¼Œä»…mode=time有效   ( é»˜è®¤ 59 )
     * @property {Function}            filter                é€‰é¡¹è¿‡æ»¤å‡½æ•°
     * @property {Function}            formatter            é€‰é¡¹æ ¼å¼åŒ–函数
     * @property {Boolean}            loading                æ˜¯å¦æ˜¾ç¤ºåŠ è½½ä¸­çŠ¶æ€   ( é»˜è®¤ false )
     * @property {String | Number}    itemHeight            å„列中,单个选项的高度   ( é»˜è®¤ 44 )
     * @property {String}            cancelText            å–消按钮的文字  ( é»˜è®¤ '取消' )
     * @property {String}            confirmText            ç¡®è®¤æŒ‰é’®çš„æ–‡å­—  ( é»˜è®¤ '确认' )
     * @property {String}            cancelColor            å–消按钮的颜色  ( é»˜è®¤ '#909193' )
     * @property {String}            confirmColor        ç¡®è®¤æŒ‰é’®çš„颜色  ( é»˜è®¤ '#3c9cff' )
     * @property {String | Number}    visibleItemCount    æ¯åˆ—中可见选项的数量  ( é»˜è®¤ 5 )
     * @property {Boolean}            closeOnClickOverlay    æ˜¯å¦å…è®¸ç‚¹å‡»é®ç½©å…³é—­é€‰æ‹©å™¨  ( é»˜è®¤ false )
     * @property {Array}            defaultIndex        å„列的默认索引
     * @event {Function} close å…³é—­é€‰æ‹©å™¨æ—¶è§¦å‘
     * @event {Function} confirm ç‚¹å‡»ç¡®å®šæŒ‰é’®ï¼Œè¿”回当前选择的值
     * @event {Function} change å½“选择值变化时触发
     * @event {Function} cancel ç‚¹å‡»å–消按钮
     * @example  <u-datetime-picker :show="show" :value="value1"  mode="datetime" ></u-datetime-picker>
     */
    export default {
        name: 'datetime-picker',
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
                columns: [],
                innerDefaultIndex: [],
                innerFormatter: (type, value) => value
            }
        },
        watch: {
            show(newValue, oldValue) {
                if (newValue) {
                    this.updateColumnValue(this.innerValue)
                }
            },
            propsChange() {
                this.init()
            }
        },
        computed: {
            // å¦‚果以下这些变量发生了变化,意味着需要重新初始化各列的值
            propsChange() {
                return [this.mode, this.maxDate, this.minDate, this.minHour, this.maxHour, this.minMinute, this.maxMinute, this.filter, ]
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                this.innerValue = this.correctValue(this.value)
                this.updateColumnValue(this.innerValue)
            },
            // åœ¨å¾®ä¿¡å°ç¨‹åºä¸­ï¼Œä¸æ”¯æŒå°†å‡½æ•°å½“做props参数,故只能通过ref形式调用
            setFormatter(e) {
                this.innerFormatter = e
            },
            // å…³é—­é€‰æ‹©å™¨
            close() {
                if (this.closeOnClickOverlay) {
                    this.$emit('close')
                }
            },
            // ç‚¹å‡»å·¥å…·æ çš„取消按钮
            cancel() {
                this.$emit('cancel')
            },
            // ç‚¹å‡»å·¥å…·æ çš„确定按钮
            confirm() {
                this.$emit('confirm', {
                    value: this.innerValue,
                    mode: this.mode
                })
                this.$emit('input', this.innerValue)
            },
            //用正则截取输出值,当出现多组数字时,抛出错误
            intercept(e,type){
                let judge = e.match(/\d+/g)
                //判断是否掺杂数字
                if(judge.length>1){
                    uni.$u.error("请勿在过滤或格式化函数时添加数字")
                    return 0
                }else if(type&&judge[0].length==4){//判断是否是年份
                    return judge[0]
                }else if(judge[0].length>2){
                    uni.$u.error("请勿在过滤或格式化函数时添加数字")
                    return 0
                }else{
                    return judge[0]
                }
            },
            // åˆ—发生变化时触发
            change(e) {
                const { indexs, values } = e
                let selectValue = ''
                if(this.mode === 'time') {
                    // æ ¹æ®value各列索引,从各列数组中,取出当前时间的选中值
                    selectValue = `${this.intercept(values[0][indexs[0]])}:${this.intercept(values[1][indexs[1]])}`
                } else {
                    // å°†é€‰æ‹©çš„值转为数值,比如'03'转为数值的3,'2019'转为数值的2019
                    const year = parseInt(this.intercept(values[0][indexs[0]],'year'))
                    const month = parseInt(this.intercept(values[1][indexs[1]]))
                    let date = parseInt(values[2] ? this.intercept(values[2][indexs[2]]) : 1)
                    let hour = 0, minute = 0
                    // æ­¤æœˆä»½çš„æœ€å¤§å¤©æ•°
                    const maxDate = dayjs(`${year}-${month}`).daysInMonth()
                    // year-month模式下,date不会出现在列中,设置为1,为了符合后边需要减1的需求
                    if (this.mode === 'year-month') {
                        date = 1
                    }
                    // ä¸å…è®¸è¶…过maxDate值
                    date = Math.min(maxDate, date)
                    if (this.mode === 'datetime') {
                        hour = parseInt(this.intercept(values[3][indexs[3]]))
                        minute = parseInt(this.intercept(values[4][indexs[4]]))
                    }
                    // è½¬ä¸ºæ—¶é—´æ¨¡å¼
                    selectValue = Number(new Date(year, month - 1, date, hour, minute))
                }
                // å–出准确的合法值,防止超越边界的情况
                selectValue = this.correctValue(selectValue)
                this.innerValue = selectValue
                this.updateColumnValue(selectValue)
                // å‘出change时间,value为当前选中的时间戳
                this.$emit('change', {
                    value: selectValue,
                    // #ifndef MP-WEIXIN
                    // å¾®ä¿¡å°ç¨‹åºä¸èƒ½ä¼ é€’this实例,会因为循环引用而报错
                    picker: this.$refs.picker,
                    // #endif
                    mode: this.mode
                })
            },
            // æ›´æ–°å„列的值,进行补0、格式化等操作
            updateColumnValue(value) {
                this.innerValue = value
                this.updateColumns()
                this.updateIndexs(value)
            },
            // æ›´æ–°ç´¢å¼•
            updateIndexs(value) {
                let values = []
                const formatter = this.formatter || this.innerFormatter
                const padZero = uni.$u.padZero
                if (this.mode === 'time') {
                    // å°†time模式的时间用:分隔成数组
                    const timeArr = value.split(':')
                    // ä½¿ç”¨formatter格式化方法进行管道处理
                    values = [formatter('hour', timeArr[0]), formatter('minute', timeArr[1])]
                } else {
                    const date = new Date(value)
                    values = [
                        formatter('year', `${dayjs(value).year()}`),
                        // æœˆä»½è¡¥0
                        formatter('month', padZero(dayjs(value).month() + 1))
                    ]
                    if (this.mode === 'date') {
                        // date模式,需要添加天列
                        values.push(formatter('day', padZero(dayjs(value).date())))
                    }
                    if (this.mode === 'datetime') {
                        // æ•°ç»„çš„push方法,可以写入多个参数
                        values.push(formatter('day', padZero(dayjs(value).date())), formatter('hour', padZero(dayjs(value).hour())), formatter('minute', padZero(dayjs(value).minute())))
                    }
                }
                // æ ¹æ®å½“前各列的所有值,从各列默认值中找到默认值在各列中的索引
                const indexs = this.columns.map((column, index) => {
                    // é€šè¿‡å–大值,可以保证不会出现找不到索引的-1情况
                    return Math.max(0, column.findIndex(item => item === values[index]))
                })
                this.innerDefaultIndex = indexs
            },
            // æ›´æ–°å„列的值
            updateColumns() {
                const formatter = this.formatter || this.innerFormatter
                // èŽ·å–å„åˆ—çš„å€¼ï¼Œå¹¶ä¸”map后,对各列的具体值进行补0操作
                const results = this.getOriginColumns().map((column) => column.values.map((value) => formatter(column.type, value)))
                this.columns = results
            },
            getOriginColumns() {
                // ç”Ÿæˆå„列的值
                const results = this.getRanges().map(({ type, range }) => {
                    let values = times(range[1] - range[0] + 1, (index) => {
                        let value = range[0] + index
                        value = type === 'year' ? `${value}` : uni.$u.padZero(value)
                        return value
                    })
                    // è¿›è¡Œè¿‡æ»¤
                    if (this.filter) {
                        values = this.filter(type, values)
                    }
                    return { type, values }
                })
                return results
            },
            // é€šè¿‡æœ€å¤§å€¼å’Œæœ€å°å€¼ç”Ÿæˆæ•°ç»„
            generateArray(start, end) {
                return Array.from(new Array(end + 1).keys()).slice(start)
            },
            // å¾—出合法的时间
            correctValue(value) {
                const isDateMode = this.mode !== 'time'
                if (isDateMode && !uni.$u.test.date(value)) {
                    // å¦‚果是日期类型,但是又没有设置合法的当前时间的话,使用最小时间为当前时间
                    value = this.minDate
                } else if (!isDateMode && !value) {
                    // å¦‚果是时间类型,而又没有默认值的话,就用最小时间
                    value = `${uni.$u.padZero(this.minHour)}:${uni.$u.padZero(this.minMinute)}`
                }
                // æ—¶é—´ç±»åž‹
                if (!isDateMode) {
                    if (String(value).indexOf(':') === -1) return uni.$u.error('时间错误,请传递如12:24的格式')
                    let [hour, minute] = value.split(':')
                    // å¯¹æ—¶é—´è¡¥é›¶ï¼ŒåŒæ—¶æŽ§åˆ¶åœ¨æœ€å°å€¼å’Œæœ€å¤§å€¼ä¹‹é—´
                    hour = uni.$u.padZero(uni.$u.range(this.minHour, this.maxHour, Number(hour)))
                    minute = uni.$u.padZero(uni.$u.range(this.minMinute, this.maxMinute, Number(minute)))
                    return `${ hour }:${ minute }`
                } else {
                    // å¦‚果是日期格式,控制在最小日期和最大日期之间
                    value = dayjs(value).isBefore(dayjs(this.minDate)) ? this.minDate : value
                    value = dayjs(value).isAfter(dayjs(this.maxDate)) ? this.maxDate : value
                    return value
                }
            },
            // èŽ·å–æ¯åˆ—çš„æœ€å¤§å’Œæœ€å°å€¼
            getRanges() {
                if (this.mode === 'time') {
                    return [
                        {
                            type: 'hour',
                            range: [this.minHour, this.maxHour],
                        },
                        {
                            type: 'minute',
                            range: [this.minMinute, this.maxMinute],
                        },
                    ];
                }
                const { maxYear, maxDate, maxMonth, maxHour, maxMinute, } = this.getBoundary('max', this.innerValue);
                const { minYear, minDate, minMonth, minHour, minMinute, } = this.getBoundary('min', this.innerValue);
                const result = [
                    {
                        type: 'year',
                        range: [minYear, maxYear],
                    },
                    {
                        type: 'month',
                        range: [minMonth, maxMonth],
                    },
                    {
                        type: 'day',
                        range: [minDate, maxDate],
                    },
                    {
                        type: 'hour',
                        range: [minHour, maxHour],
                    },
                    {
                        type: 'minute',
                        range: [minMinute, maxMinute],
                    },
                ];
                if (this.mode === 'date')
                    result.splice(3, 2);
                if (this.mode === 'year-month')
                    result.splice(2, 3);
                return result;
            },
            // æ ¹æ®minDate、maxDate、minHour、maxHour等边界值,判断各列的开始和结束边界值
            getBoundary(type, innerValue) {
                const value = new Date(innerValue)
                const boundary = new Date(this[`${type}Date`])
                const year = dayjs(boundary).year()
                let month = 1
                let date = 1
                let hour = 0
                let minute = 0
                if (type === 'max') {
                    month = 12
                    // æœˆä»½çš„天数
                    date = dayjs(value).daysInMonth()
                    hour = 23
                    minute = 59
                }
                // èŽ·å–è¾¹ç•Œå€¼ï¼Œé€»è¾‘æ˜¯ï¼šå½“å¹´è¾¾åˆ°äº†è¾¹ç•Œå€¼(最大或最小年),就检查月允许的最大和最小值,以此类推
                if (dayjs(value).year() === year) {
                    month = dayjs(boundary).month() + 1
                    if (dayjs(value).month() + 1 === month) {
                        date = dayjs(boundary).date()
                        if (dayjs(value).date() === date) {
                            hour = dayjs(boundary).hour()
                            if (dayjs(value).hour() === hour) {
                                minute = dayjs(boundary).minute()
                            }
                        }
                    }
                }
                return {
                    [`${type}Year`]: year,
                    [`${type}Month`]: month,
                    [`${type}Date`]: date,
                    [`${type}Hour`]: hour,
                    [`${type}Minute`]: minute
                }
            },
        },
    }
</script>
<style lang="scss" scoped>
    @import '../../libs/css/components.scss';
</style>
uni_modules/uview-ui/components/u-divider/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
export default {
    props: {
        // æ˜¯å¦è™šçº¿
        dashed: {
            type: Boolean,
            default: uni.$u.props.divider.dashed
        },
        // æ˜¯å¦ç»†çº¿
        hairline: {
            type: Boolean,
            default: uni.$u.props.divider.hairline
        },
        // æ˜¯å¦ä»¥ç‚¹æ›¿ä»£æ–‡å­—,优先于text字段起作用
        dot: {
            type: Boolean,
            default: uni.$u.props.divider.dot
        },
        // å†…容文本的位置,left-左边,center-中间,right-右边
        textPosition: {
            type: String,
            default: uni.$u.props.divider.textPosition
        },
        // æ–‡æœ¬å†…容
        text: {
            type: [String, Number],
            default: uni.$u.props.divider.text
        },
        // æ–‡æœ¬å¤§å°
        textSize: {
            type: [String, Number],
            default: uni.$u.props.divider.textSize
        },
        // æ–‡æœ¬é¢œè‰²
        textColor: {
            type: String,
            default: uni.$u.props.divider.textColor
        },
        // çº¿æ¡é¢œè‰²
        lineColor: {
            type: String,
            default: uni.$u.props.divider.lineColor
        }
    }
}
uni_modules/uview-ui/components/u-divider/u-divider.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,116 @@
<template>
    <view
        class="u-divider"
        :style="[$u.addStyle(customStyle)]"
        @tap="click"
    >
        <u-line
            :color="lineColor"
            :customStyle="leftLineStyle"
            :hairline="hairline"
            :dashed="dashed"
        ></u-line>
        <text
            v-if="dot"
            class="u-divider__dot"
        >●</text>
        <text
            v-else-if="text"
            class="u-divider__text"
            :style="[textStyle]"
        >{{text}}</text>
        <u-line
            :color="lineColor"
            :customStyle="rightLineStyle"
            :hairline="hairline"
            :dashed="dashed"
        ></u-line>
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * divider åˆ†å‰²çº¿
     * @description åŒºéš”内容的分割线,一般用于页面底部"没有更多"的提示。
     * @tutorial https://www.uviewui.com/components/divider.html
     * @property {Boolean}            dashed            æ˜¯å¦è™šçº¿ ï¼ˆé»˜è®¤ false ï¼‰
     * @property {Boolean}            hairline        æ˜¯å¦ç»†çº¿ ï¼ˆé»˜è®¤  true ï¼‰
     * @property {Boolean}            dot                æ˜¯å¦ä»¥ç‚¹æ›¿ä»£æ–‡å­—,优先于text字段起作用 ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String}            textPosition    å†…容文本的位置,left-左边,center-中间,right-右边 ï¼ˆé»˜è®¤ 'center' ï¼‰
     * @property {String | Number}    text            æ–‡æœ¬å†…容
     * @property {String | Number}    textSize        æ–‡æœ¬å¤§å° ï¼ˆé»˜è®¤ 14)
     * @property {String}            textColor        æ–‡æœ¬é¢œè‰² ï¼ˆé»˜è®¤ '#909399' ï¼‰
     * @property {String}            lineColor        çº¿æ¡é¢œè‰² ï¼ˆé»˜è®¤ '#dcdfe6' ï¼‰
     * @property {Object}            customStyle        å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     *
     * @event {Function}    click    divider组件被点击时触发
     * @example <u-divider :color="color">锦瑟无端五十弦</u-divider>
     */
    export default {
        name:'u-divider',
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        computed: {
            textStyle() {
                const style = {}
                style.fontSize = uni.$u.addUnit(this.textSize)
                style.color = this.textColor
                return style
            },
            // å·¦è¾¹çº¿æ¡çš„的样式
            leftLineStyle() {
                const style = {}
                // å¦‚果是在左边,设置左边的宽度为固定值
                if (this.textPosition === 'left') {
                    style.width = '80rpx'
                } else {
                    style.flex = 1
                }
                return style
            },
            // å³è¾¹çº¿æ¡çš„的样式
            rightLineStyle() {
                const style = {}
                // å¦‚果是在右边,设置右边的宽度为固定值
                if (this.textPosition === 'right') {
                    style.width = '80rpx'
                } else {
                    style.flex = 1
                }
                return style
            }
        },
        methods: {
            // divider组件被点击时触发
            click() {
                this.$emit('click');
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import '../../libs/css/components.scss';
    $u-divider-margin:15px 0 !default;
    $u-divider-text-margin:0 15px !default;
    $u-divider-dot-font-size:12px !default;
    $u-divider-dot-margin:0 12px !default;
    $u-divider-dot-color: #c0c4cc !default;
    .u-divider {
        @include flex;
        flex-direction: row;
        align-items: center;
        margin: $u-divider-margin;
        &__text {
            margin: $u-divider-text-margin;
        }
        &__dot {
            font-size: $u-divider-dot-font-size;
            margin: $u-divider-dot-margin;
            color: $u-divider-dot-color;
        }
    }
</style>
uni_modules/uview-ui/components/u-dropdown-item/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
export default {
    props: {
        // å½“前选中项的value值
        value: {
            type: [Number, String, Array],
            default: ''
        },
        // èœå•项标题
        title: {
            type: [String, Number],
            default: ''
        },
        // é€‰é¡¹æ•°æ®ï¼Œå¦‚果传入了默认slot,此参数无效
        options: {
            type: Array,
            default() {
                return []
            }
        },
        // æ˜¯å¦ç¦ç”¨æ­¤èœå•项
        disabled: {
            type: Boolean,
            default: false
        },
        // ä¸‹æ‹‰å¼¹çª—的高度
        height: {
            type: [Number, String],
            default: 'auto'
        },
        // ç‚¹å‡»é®ç½©æ˜¯å¦å¯ä»¥æ”¶èµ·å¼¹çª—
        closeOnClickOverlay: {
            type: Boolean,
            default: true
        }
    }
}
uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,146 @@
<template>
    <view class="u-drawdown-item">
        <u-overlay
            customStyle="top: 126px"
            :show="show"
            :closeOnClickOverlay="closeOnClickOverlay"
            @click="overlayClick"
        ></u-overlay>
        <view
            class="u-drawdown-item__content"
            :style="[style]"
            :animation="animationData"
            ref="animation"
        >
            <slot />
        </view>
    </view>
</template>
<script>
    // #ifdef APP-NVUE
    const animation = uni.requireNativePlugin('animation')
    const dom = uni.requireNativePlugin('dom')
    // #endif
    import props from './props.js';
    /**
     * Drawdownitem
     * @description
     * @tutorial url
     * @property {String}
     * @event {Function}
     * @example
     */
    export default {
        name: 'u-drawdown-item',
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
                show: false,
                top: '126px',
                // uni.createAnimation的导出数据
                animationData: {},
            }
        },
        mounted() {
            this.init()
        },
        watch: {
            // å‘生变化时,需要去更新父组件对应的值
            dataChange(newValue, oldValue) {
                this.updateParentData()
            }
        },
        computed: {
            // ç›‘听对应变量的变化
            dataChange() {
                return [this.title, this.disabled]
            },
            style() {
                const style = {
                    zIndex: 10071,
                    position: 'fixed',
                    display: 'flex',
                    left: 0,
                    right: 0
                }
                style.top = uni.$u.addUnit(this.top)
                return style
            }
        },
        methods: {
            init() {
                this.updateParentData()
            },
            // æ›´æ–°çˆ¶ç»„件所需的数据
            updateParentData() {
                // èŽ·å–çˆ¶ç»„ä»¶u-dropdown
                this.getParentData('u-dropdown')
                if (!this.parent) uni.$u.error('u-dropdown-item必须配合u-dropdown使用')
                // æŸ¥æ‰¾çˆ¶ç»„ä»¶menuList数组中对应的标题数据
                const menuIndex = this.parent.menuList.findIndex(item => item.title === this.title)
                const menuContent = {
                    title: this.title,
                    disabled: this.disabled
                }
                if (menuIndex >= 0) {
                    // å¦‚果能找到,则直接修改
                    this.parent.menuList[menuIndex] = menuContent;
                } else {
                    // å¦‚果无法找到,则为第一次添加,直接push即可
                    this.parent.menuList.push(menuContent);
                }
            },
            async setContentAnimate(height) {
                this.animating = true
                // #ifdef APP-NVUE
                const ref = this.$refs['animation'].ref
                animation.transition(ref, {
                    styles: {
                        height: uni.$u.addUnit(height)
                    },
                    duration: this.duration,
                    timingFunction: 'ease-in-out',
                }, () => {
                    this.animating = false
                })
                // #endif
                // #ifndef APP-NVUE
                const animation = uni.createAnimation({
                    timingFunction: 'ease-in-out',
                });
                animation
                    .height(height)
                    .step({
                        duration: this.duration,
                    })
                    .step()
                // å¯¼å‡ºåŠ¨ç”»æ•°æ®ç»™é¢æ¿çš„animationData值
                this.animationData = animation.export()
                // æ ‡è¯†åŠ¨ç”»ç»“æŸ
                uni.$u.sleep(this.duration).then(() => {
                    this.animating = false
                })
                // #endif
            },
            overlayClick() {
                this.show = false
                this.setContentAnimate(0)
            }
        },
    }
</script>
<style lang="scss" scoped>
    @import '../../libs/css/components.scss';
    .u-drawdown-item {
        &__content {
            background-color: #FFFFFF;
            overflow: hidden;
            height: 0;
        }
    }
</style>
uni_modules/uview-ui/components/u-dropdown/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
export default {
    props: {
        // æ ‡é¢˜é€‰ä¸­æ—¶çš„æ ·å¼
        activeStyle: {
            type: [String, Object],
            default: () => ({
                color: '#2979ff',
                fontSize: '14px'
            })
        },
        // æ ‡é¢˜æœªé€‰ä¸­æ—¶çš„æ ·å¼
        inactiveStyle: {
            type: [String, Object],
            default: () => ({
                color: '#606266',
                fontSize: '14px'
            })
        },
        // ç‚¹å‡»é®ç½©æ˜¯å¦å…³é—­èœå•
        closeOnClickMask: {
            type: Boolean,
            default: true
        },
        // ç‚¹å‡»å½“前激活项标题是否关闭菜单
        closeOnClickSelf: {
            type: Boolean,
            default: true
        },
        // è¿‡æ¸¡æ—¶é—´
        duration: {
            type: [Number, String],
            default: 300
        },
        // æ ‡é¢˜èœå•的高度
        height: {
            type: [Number, String],
            default: 40
        },
        // æ˜¯å¦æ˜¾ç¤ºä¸‹è¾¹æ¡†
        borderBottom: {
            type: Boolean,
            default: false
        },
        // æ ‡é¢˜çš„字体大小
        titleSize: {
            type: [Number, String],
            default: 14
        },
        // ä¸‹æ‹‰å‡ºæ¥çš„内容部分的圆角值
        borderRadius: {
            type: [Number, String],
            default: 0
        },
        // èœå•右侧的icon图标
        menuIcon: {
            type: String,
            default: 'arrow-down'
        },
        // èœå•右侧图标的大小
        menuIconSize: {
            type: [Number, String],
            default: 14
        }
    }
}
uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,127 @@
<template>
    <view class="u-drawdown">
        <view
            class="u-dropdown__menu"
            :style="{
                height: $u.addUnit(height)
            }"
            ref="u-dropdown__menu"
        >
            <view
                class="u-dropdown__menu__item"
                v-for="(item, index) in menuList"
                :key="index"
                @tap.stop="clickHandler(item, index)"
            >
                <view class="u-dropdown__menu__item__content">
                    <text
                        class="u-dropdown__menu__item__content__text"
                        :style="[index === current ? activeStyle : inactiveStyle]"
                    >{{item.title}}</text>
                    <view
                        class="u-dropdown__menu__item__content__arrow"
                        :class="[index === current && 'u-dropdown__menu__item__content__arrow--rotate']"
                    >
                        <u-icon
                            :name="menuIcon"
                            :size="$u.addUnit(menuIconSize)"
                        ></u-icon>
                    </view>
                </view>
            </view>
        </view>
        <view class="u-dropdown__content">
            <slot />
        </view>
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * Dropdown
     * @description
     * @tutorial url
     * @property {String}
     * @event {Function}
     * @example
     */
    export default {
        name: 'u-dropdown',
        mixins: [uni.$u.mixin, props],
        data() {
            return {
                // èœå•数组
                menuList: [],
                current: 0
            }
        },
        computed: {
        },
        created() {
            // å¼•用所有子组件(u-dropdown-item)的this,不能在data中声明变量,否则在微信小程序会造成循环引用而报错
            this.children = [];
        },
        methods: {
            clickHandler(item, index) {
                this.children.map(child => {
                    if(child.title === item.title) {
                        // this.queryRect('u-dropdown__menu').then(size => {
                            child.$emit('click')
                            child.setContentAnimate(child.show ? 0 : 300)
                            child.show = !child.show
                        // })
                    } else {
                        child.show = false
                        child.setContentAnimate(0)
                    }
                })
            },
            // èŽ·å–æ ‡ç­¾çš„å°ºå¯¸ä½ç½®
            queryRect(el) {
                // #ifndef APP-NVUE
                // $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://www.uviewui.com/js/getRect.html
                // ç»„件内部一般用this.$uGetRect,对外的为this.$u.getRect,二者功能一致,名称不同
                return new Promise(resolve => {
                    this.$uGetRect(`.${el}`).then(size => {
                        resolve(size)
                    })
                })
                // #endif
                // #ifdef APP-NVUE
                // nvue下,使用dom模块查询元素高度
                // è¿”回一个promise,让调用此方法的主体能使用then回调
                return new Promise(resolve => {
                    dom.getComponentRect(this.$refs[el], res => {
                        resolve(res.size)
                    })
                })
                // #endif
            },
        },
    }
</script>
<style lang="scss">
    @import '../../libs/css/components.scss';
    .u-dropdown {
        &__menu {
            @include flex;
            &__item {
                flex: 1;
                @include flex;
                justify-content: center;
                &__content {
                    @include flex;
                    align-items: center;
                }
            }
        }
    }
</style>
uni_modules/uview-ui/components/u-empty/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
export default {
    props: {
        // å†…置图标名称,或图片路径,建议绝对路径
        icon: {
            type: String,
            default: uni.$u.props.empty.icon
        },
        // æç¤ºæ–‡å­—
        text: {
            type: String,
            default: uni.$u.props.empty.text
        },
        // æ–‡å­—颜色
        textColor: {
            type: String,
            default: uni.$u.props.empty.textColor
        },
        // æ–‡å­—大小
        textSize: {
            type: [String, Number],
            default: uni.$u.props.empty.textSize
        },
        // å›¾æ ‡çš„颜色
        iconColor: {
            type: String,
            default: uni.$u.props.empty.iconColor
        },
        // å›¾æ ‡çš„大小
        iconSize: {
            type: [String, Number],
            default: uni.$u.props.empty.iconSize
        },
        // é€‰æ‹©é¢„置的图标类型
        mode: {
            type: String,
            default: uni.$u.props.empty.mode
        },
        //  å›¾æ ‡å®½åº¦ï¼Œå•位px
        width: {
            type: [String, Number],
            default: uni.$u.props.empty.width
        },
        // å›¾æ ‡é«˜åº¦ï¼Œå•位px
        height: {
            type: [String, Number],
            default: uni.$u.props.empty.height
        },
        // æ˜¯å¦æ˜¾ç¤ºç»„ä»¶
        show: {
            type: Boolean,
            default: uni.$u.props.empty.show
        },
        // ç»„件距离上一个元素之间的距离,默认px单位
        marginTop: {
            type: [String, Number],
            default: uni.$u.props.empty.marginTop
        }
    }
}
uni_modules/uview-ui/components/u-empty/u-empty.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,128 @@
<template>
    <view
        class="u-empty"
        :style="[emptyStyle]"
        v-if="show"
    >
        <u-icon
            v-if="!isSrc"
            :name="mode === 'message' ? 'chat' : `empty-${mode}`"
            :size="iconSize"
            :color="iconColor"
            margin-top="14"
        ></u-icon>
        <image
            v-else
            :style="{
                width: $u.addUnit(width),
                height: $u.addUnit(height),
            }"
            :src="icon"
            mode="widthFix"
        ></image>
        <text
            class="u-empty__text"
            :style="[textStyle]"
        >{{text ? text : icons[mode]}}</text>
        <view class="u-empty__wrap" v-if="$slots.default || $slots.$default">
            <slot />
        </view>
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * empty å†…容为空
     * @description è¯¥ç»„件用于需要加载内容,但是加载的第一页数据就为空,提示一个"没有内容"的场景, æˆ‘们精心挑选了十几个场景的图标,方便您使用。
     * @tutorial https://www.uviewui.com/components/empty.html
     * @property {String}            icon        å†…置图标名称,或图片路径,建议绝对路径
     * @property {String}            text        æç¤ºæ–‡å­—
     * @property {String}            textColor    æ–‡å­—颜色 (默认 '#c0c4cc' )
     * @property {String | Number}    textSize    æ–‡å­—大小 ï¼ˆé»˜è®¤ 14 ï¼‰
     * @property {String}            iconColor    å›¾æ ‡çš„颜色 ï¼ˆé»˜è®¤ '#c0c4cc' ï¼‰
     * @property {String | Number}    iconSize    å›¾æ ‡çš„大小 ï¼ˆé»˜è®¤ 90 ï¼‰
     * @property {String}            mode        é€‰æ‹©é¢„置的图标类型 ï¼ˆé»˜è®¤ 'data' ï¼‰
     * @property {String | Number}    width        å›¾æ ‡å®½åº¦ï¼Œå•位px ï¼ˆé»˜è®¤ 160 ï¼‰
     * @property {String | Number}    height        å›¾æ ‡é«˜åº¦ï¼Œå•位px ï¼ˆé»˜è®¤ 160 ï¼‰
     * @property {Boolean}            show        æ˜¯å¦æ˜¾ç¤ºç»„ä»¶ ï¼ˆé»˜è®¤ true ï¼‰
     * @property {String | Number}    marginTop    ç»„件距离上一个元素之间的距离,默认px单位 ï¼ˆé»˜è®¤ 0 ï¼‰
     * @property {Object}            customStyle    å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     *
     * @event {Function} click ç‚¹å‡»ç»„件时触发
     * @event {Function} close ç‚¹å‡»å…³é—­æŒ‰é’®æ—¶è§¦å‘
     * @example <u-empty text="所谓伊人,在水一方" mode="list"></u-empty>
     */
    export default {
        name: "u-empty",
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
                icons: {
                    car: '购物车为空',
                    page: '页面不存在',
                    search: '没有搜索结果',
                    address: '没有收货地址',
                    wifi: '没有WiFi',
                    order: '订单为空',
                    coupon: '没有优惠券',
                    favor: '暂无收藏',
                    permission: '无权限',
                    history: '无历史记录',
                    news: '无新闻列表',
                    message: '消息列表为空',
                    list: '列表为空',
                    data: '数据为空',
                    comment: '暂无评论',
                }
            }
        },
        computed: {
            // ç»„件样式
            emptyStyle() {
                const style = {}
                style.marginTop = uni.$u.addUnit(this.marginTop)
                // åˆå¹¶customStyle样式,此参数通过mixin中的props传递
                return uni.$u.deepMerge(uni.$u.addStyle(this.customStyle), style)
            },
            // æ–‡æœ¬æ ·å¼
            textStyle() {
                const style = {}
                style.color = this.textColor
                style.fontSize = uni.$u.addUnit(this.textSize)
                return style
            },
            // åˆ¤æ–­icon是否图片路径
            isSrc() {
                return this.icon.indexOf('/') >= 0
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import '../../libs/css/components.scss';
    $u-empty-text-margin-top:20rpx !default;
    $u-empty-slot-margin-top:20rpx !default;
    .u-empty {
        @include flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        &__text {
            @include flex;
            justify-content: center;
            align-items: center;
            margin-top: $u-empty-text-margin-top;
        }
    }
        .u-slot-wrap {
            @include flex;
            justify-content: center;
            align-items: center;
            margin-top:$u-empty-slot-margin-top;
        }
</style>
uni_modules/uview-ui/components/u-form-item/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
export default {
    props: {
        // input的label提示语
        label: {
            type: String,
            default: uni.$u.props.formItem.label
        },
        // ç»‘定的值
        prop: {
            type: String,
            default: uni.$u.props.formItem.prop
        },
        // æ˜¯å¦æ˜¾ç¤ºè¡¨å•域的下划线边框
        borderBottom: {
            type: [String, Boolean],
            default: uni.$u.props.formItem.borderBottom
        },
        // label的宽度,单位px
        labelWidth: {
            type: [String, Number],
            default: uni.$u.props.formItem.labelWidth
        },
        // å³ä¾§å›¾æ ‡
        rightIcon: {
            type: String,
            default: uni.$u.props.formItem.rightIcon
        },
        // å·¦ä¾§å›¾æ ‡
        leftIcon: {
            type: String,
            default: uni.$u.props.formItem.leftIcon
        },
        // æ˜¯å¦æ˜¾ç¤ºå·¦è¾¹çš„必填星号,只作显示用,具体校验必填的逻辑,请在rules中配置
        required: {
            type: Boolean,
            default: uni.$u.props.formItem.required
        },
        leftIconStyle: {
            type: [String, Object],
            default: uni.$u.props.formItem.leftIconStyle,
        }
    }
}
uni_modules/uview-ui/components/u-form-item/u-form-item.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,235 @@
<template>
    <view class="u-form-item">
        <view
            class="u-form-item__body"
            @tap="clickHandler"
            :style="[$u.addStyle(customStyle), {
                flexDirection: parentData.labelPosition === 'left' ? 'row' : 'column'
            }]"
        >
            <!-- å¾®ä¿¡å°ç¨‹åºä¸­ï¼Œå°†ä¸€ä¸ªå‚数设置空字符串,结果会变成字符串"true" -->
            <slot name="label">
                <!-- {{required}} -->
                <view
                    class="u-form-item__body__left"
                    v-if="required || leftIcon || label"
                    :style="{
                        width: $u.addUnit(labelWidth || parentData.labelWidth),
                        marginBottom: parentData.labelPosition === 'left' ? 0 : '5px',
                    }"
                >
                    <!-- ä¸ºäº†å—对齐 -->
                    <view class="u-form-item__body__left__content">
                        <!-- nvue不支持伪元素before -->
                        <text
                            v-if="required"
                            class="u-form-item__body__left__content__required"
                        >*</text>
                        <view
                            class="u-form-item__body__left__content__icon"
                            v-if="leftIcon"
                        >
                            <u-icon
                                :name="leftIcon"
                                :custom-style="leftIconStyle"
                            ></u-icon>
                        </view>
                        <text
                            class="u-form-item__body__left__content__label"
                            :style="[parentData.labelStyle, {
                                justifyContent: parentData.labelAlign === 'left' ? 'flex-start' : parentData.labelAlign === 'center' ? 'center' : 'flex-end'
                            }]"
                        >{{ label }}</text>
                    </view>
                </view>
            </slot>
            <view class="u-form-item__body__right">
                <view class="u-form-item__body__right__content">
                    <view class="u-form-item__body__right__content__slot">
                        <slot />
                    </view>
                    <view
                        class="item__body__right__content__icon"
                        v-if="$slots.right"
                    >
                        <slot name="right" />
                    </view>
                </view>
            </view>
        </view>
        <slot name="error">
            <text
                v-if="!!message && parentData.errorType === 'message'"
                class="u-form-item__body__right__message"
                :style="{
                    marginLeft:  $u.addUnit(parentData.labelPosition === 'top' ? 0 : (labelWidth || parentData.labelWidth))
                }"
            >{{ message }}</text>
        </slot>
        <u-line
            v-if="borderBottom"
            :color="message && parentData.errorType === 'border-bottom' ? $u.color.error : propsLine.color"
            :customStyle="`margin-top: ${message && parentData.errorType === 'message' ? '5px' : 0}`"
        ></u-line>
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * Form è¡¨å•
     * @description æ­¤ç»„件一般用于表单场景,可以配置Input输入框,Select弹出框,进行表单验证等。
     * @tutorial https://www.uviewui.com/components/form.html
     * @property {String}            label            input的label提示语
     * @property {String}            prop            ç»‘定的值
     * @property {String | Boolean}    borderBottom    æ˜¯å¦æ˜¾ç¤ºè¡¨å•域的下划线边框
     * @property {String | Number}    labelWidth        label的宽度,单位px
     * @property {String}            rightIcon        å³ä¾§å›¾æ ‡
     * @property {String}            leftIcon        å·¦ä¾§å›¾æ ‡
     * @property {String | Object} leftIconStyle å·¦ä¾§å›¾æ ‡çš„æ ·å¼
     * @property {Boolean}            required        æ˜¯å¦æ˜¾ç¤ºå·¦è¾¹çš„必填星号,只作显示用,具体校验必填的逻辑,请在rules中配置 (默认 false )
     *
     * @example <u-form-item label="姓名" prop="userInfo.name" borderBottom ref="item1"></u-form-item>
     */
    export default {
        name: 'u-form-item',
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
                // é”™è¯¯æç¤ºè¯­
                message: '',
                parentData: {
                    // æç¤ºæ–‡æœ¬çš„位置
                    labelPosition: 'left',
                    // æç¤ºæ–‡æœ¬å¯¹é½æ–¹å¼
                    labelAlign: 'left',
                    // æç¤ºæ–‡æœ¬çš„æ ·å¼
                    labelStyle: {},
                    // æç¤ºæ–‡æœ¬çš„宽度
                    labelWidth: 45,
                    // é”™è¯¯æç¤ºæ–¹å¼
                    errorType: 'message'
                }
            }
        },
        // ç»„件创建完成时,将当前实例保存到u-form中
        computed: {
            propsLine() {
                return uni.$u.props.line
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                // çˆ¶ç»„件的实例
                this.updateParentData()
                if (!this.parent) {
                    uni.$u.error('u-form-item需要结合u-form组件使用')
                }
            },
            // èŽ·å–çˆ¶ç»„ä»¶çš„å‚æ•°
            updateParentData() {
                // æ­¤æ–¹æ³•写在mixin中
                this.getParentData('u-form');
            },
            // ç§»é™¤u-form-item的校验结果
            clearValidate() {
                this.message = null
            },
            // æ¸…空当前的组件的校验结果,并重置为初始值
            resetField() {
                // æ‰¾åˆ°åŽŸå§‹å€¼
                const value = uni.$u.getProperty(this.parent.originalModel, this.prop)
                // å°†u-form的model的prop属性链还原原始值
                uni.$u.setProperty(this.parent.model, this.prop, value)
                // ç§»é™¤æ ¡éªŒç»“æžœ
                this.message = null
            },
            // ç‚¹å‡»ç»„ä»¶
            clickHandler() {
                this.$emit('click')
            }
        },
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-form-item {
        @include flex(column);
        font-size: 14px;
        color: $u-main-color;
        &__body {
            @include flex;
            padding: 10px 0;
            &__left {
                @include flex;
                align-items: center;
                &__content {
                    position: relative;
                    @include flex;
                    align-items: center;
                    padding-right: 10rpx;
                    flex: 1;
                    &__icon {
                        margin-right: 8rpx;
                    }
                    &__required {
                        position: absolute;
                        left: -9px;
                        color: $u-error;
                        line-height: 20px;
                        font-size: 20px;
                        top: 3px;
                    }
                    &__label {
                        @include flex;
                        align-items: center;
                        flex: 1;
                        color: $u-main-color;
                        font-size: 15px;
                    }
                }
            }
            &__right {
                flex: 1;
                &__content {
                    @include flex;
                    align-items: center;
                    flex: 1;
                    &__slot {
                        flex: 1;
                        /* #ifndef MP */
                        @include flex;
                        align-items: center;
                        /* #endif */
                    }
                    &__icon {
                        margin-left: 10rpx;
                        color: $u-light-color;
                        font-size: 30rpx;
                    }
                }
                &__message {
                    font-size: 12px;
                    line-height: 12px;
                    color: $u-error;
                }
            }
        }
    }
</style>
uni_modules/uview-ui/components/u-form/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
export default {
    props: {
        // å½“前form的需要验证字段的集合
        model: {
            type: Object,
            default: uni.$u.props.form.model
        },
        // éªŒè¯è§„则
        rules: {
            type: [Object, Function, Array],
            default: uni.$u.props.form.rules
        },
        // æœ‰é”™è¯¯æ—¶çš„æç¤ºæ–¹å¼ï¼Œmessage-提示信息,toast-进行toast提示
        // border-bottom-下边框呈现红色,none-无提示
        errorType: {
            type: String,
            default: uni.$u.props.form.errorType
        },
        // æ˜¯å¦æ˜¾ç¤ºè¡¨å•域的下划线边框
        borderBottom: {
            type: Boolean,
            default: uni.$u.props.form.borderBottom
        },
        // label的位置,left-左边,top-上边
        labelPosition: {
            type: String,
            default: uni.$u.props.form.labelPosition
        },
        // label的宽度,单位px
        labelWidth: {
            type: [String, Number],
            default: uni.$u.props.form.labelWidth
        },
        // lable字体的对齐方式
        labelAlign: {
            type: String,
            default: uni.$u.props.form.labelAlign
        },
        // lable的样式,对象形式
        labelStyle: {
            type: Object,
            default: uni.$u.props.form.labelStyle
        }
    }
}
uni_modules/uview-ui/components/u-form/u-form.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,214 @@
<template>
    <view class="u-form">
        <slot />
    </view>
</template>
<script>
    import props from "./props.js";
    import Schema from "../../libs/util/async-validator";
    // åŽ»é™¤è­¦å‘Šä¿¡æ¯
    Schema.warning = function() {};
    /**
     * Form è¡¨å•
     * @description æ­¤ç»„件一般用于表单场景,可以配置Input输入框,Select弹出框,进行表单验证等。
     * @tutorial https://www.uviewui.com/components/form.html
     * @property {Object}                        model            å½“前form的需要验证字段的集合
     * @property {Object | Function | Array}    rules            éªŒè¯è§„则
     * @property {String}                        errorType        é”™è¯¯çš„æç¤ºæ–¹å¼ï¼Œè§ä¸Šæ–¹è¯´æ˜Ž ( é»˜è®¤ message )
     * @property {Boolean}                        borderBottom    æ˜¯å¦æ˜¾ç¤ºè¡¨å•域的下划线边框   ( é»˜è®¤ true ï¼‰
     * @property {String}                        labelPosition    è¡¨å•域提示文字的位置,left-左侧,top-上方 ( é»˜è®¤ 'left' ï¼‰
     * @property {String | Number}                labelWidth        æç¤ºæ–‡å­—的宽度,单位px  ( é»˜è®¤ 45 ï¼‰
     * @property {String}                        labelAlign        lable字体的对齐方式   ( é»˜è®¤ â€˜left' ï¼‰
     * @property {Object}                        labelStyle        lable的样式,对象形式
     * @example <u--formlabelPosition="left" :model="model1" :rules="rules" ref="form1"></u--form>
     */
    export default {
        name: "u-form",
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        provide() {
            return {
                uForm: this,
            };
        },
        data() {
            return {
                formRules: {},
                // è§„则校验器
                validator: {},
                // åŽŸå§‹çš„model快照,用于resetFields方法重置表单时使用
                originalModel: null,
            };
        },
        watch: {
            // ç›‘听规则的变化
            rules: {
                immediate: true,
                handler(n) {
                    this.setRules(n);
                },
            },
            // ç›‘听属性的变化,通知子组件u-form-item重新获取信息
            propsChange(n) {
                if (this.children?.length) {
                    this.children.map((child) => {
                        // åˆ¤æ–­å­ç»„ä»¶(u-form-item)如果有updateParentData方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
                        typeof child.updateParentData == "function" &&
                            child.updateParentData();
                    });
                }
            },
            // ç›‘听model的初始值作为重置表单的快照
            model: {
                immediate: true,
                handler(n) {
                    if (!this.originalModel) {
                        this.originalModel = uni.$u.deepClone(n);
                    }
                },
            },
        },
        computed: {
            propsChange() {
                return [
                    this.errorType,
                    this.borderBottom,
                    this.labelPosition,
                    this.labelWidth,
                    this.labelAlign,
                    this.labelStyle,
                ];
            },
        },
        created() {
            // å­˜å‚¨å½“前form下的所有u-form-item的实例
            // ä¸èƒ½å®šä¹‰åœ¨data中,否则微信小程序会造成循环引用而报错
            this.children = [];
        },
        methods: {
            // æ‰‹åŠ¨è®¾ç½®æ ¡éªŒçš„è§„åˆ™ï¼Œå¦‚æžœè§„åˆ™ä¸­æœ‰å‡½æ•°çš„è¯ï¼Œå¾®ä¿¡å°ç¨‹åºä¸­ä¼šè¿‡æ»¤æŽ‰ï¼Œæ‰€ä»¥åªèƒ½æ‰‹åŠ¨è°ƒç”¨è®¾ç½®è§„åˆ™
            setRules(rules) {
                // åˆ¤æ–­æ˜¯å¦æœ‰è§„则
                if (Object.keys(rules).length === 0) return;
                if (process.env.NODE_ENV === 'development' && Object.keys(this.model).length === 0) {
                    uni.$u.error('设置rules,model必须设置!如果已经设置,请刷新页面。');
                    return;
                };
                this.formRules = rules;
                // é‡æ–°å°†è§„则赋予Validator
                this.validator = new Schema(rules);
            },
            // æ¸…空所有u-form-item组件的内容,本质上是调用了u-form-item组件中的resetField()方法
            resetFields() {
                this.resetModel();
            },
            // é‡ç½®model为初始值的快照
            resetModel(obj) {
                // åŽ†éæ‰€æœ‰u-form-item,根据其prop属性,还原model的原始快照
                this.children.map((child) => {
                    const prop = child?.prop;
                    const value = uni.$u.getProperty(this.originalModel, prop);
                    uni.$u.setProperty(this.model, prop, value);
                });
            },
            // æ¸…空校验结果
            clearValidate(props) {
                props = [].concat(props);
                this.children.map((child) => {
                    // å¦‚æžœu-form-item的prop在props数组中,则清除对应的校验结果信息
                    if (props[0] === undefined || props.includes(child.prop)) {
                        child.message = null;
                    }
                });
            },
            // å¯¹éƒ¨åˆ†è¡¨å•字段进行校验
            async validateField(value, callback, event = null) {
                // $nextTick是必须的,否则model的变更,可能会延后于此方法的执行
                this.$nextTick(() => {
                    // æ ¡éªŒé”™è¯¯ä¿¡æ¯ï¼Œè¿”回给回调方法,用于存放所有form-item的错误信息
                    const errorsRes = [];
                    // å¦‚果为字符串,转为数组
                    value = [].concat(value);
                    // åŽ†échildren所有子form-item
                    this.children.map((child) => {
                        // ç”¨äºŽå­˜æ”¾form-item的错误信息
                        const childErrors = [];
                        if (value.includes(child.prop)) {
                            // èŽ·å–å¯¹åº”çš„å±žæ€§ï¼Œé€šè¿‡ç±»ä¼¼'a.b.c'的形式
                            const propertyVal = uni.$u.getProperty(
                                this.model,
                                child.prop
                            );
                            // å±žæ€§é“¾æ•°ç»„
                            const propertyChain = child.prop.split(".");
                            const propertyName =
                                propertyChain[propertyChain.length - 1];
                            const rule = this.formRules[child.prop];
                            // å¦‚果不存在对应的规则,直接返回,否则校验器会报错
                            if (!rule) return;
                            // rule规则可为数组形式,也可为对象形式,此处拼接成为数组
                            const rules = [].concat(rule);
                            // å¯¹rules数组进行校验
                            for (let i = 0; i < rules.length; i++) {
                                const ruleItem = rules[i];
                                // å°†u-form-item的触发器转为数组形式
                                const trigger = [].concat(ruleItem?.trigger);
                                // å¦‚果是有传入触发事件,但是此form-item却没有配置此触发器的话,不执行校验操作
                                if (event && !trigger.includes(event)) continue;
                                // å®žä¾‹åŒ–校验对象,传入构造规则
                                const validator = new Schema({
                                    [propertyName]: ruleItem,
                                });
                                validator.validate({
                                        [propertyName]: propertyVal,
                                    },
                                    (errors, fields) => {
                                        if (uni.$u.test.array(errors)) {
                                            errorsRes.push(...errors);
                                            childErrors.push(...errors);
                                        }
                                        child.message =
                                            childErrors[0]?.message ?? null;
                                    }
                                );
                            }
                        }
                    });
                    // æ‰§è¡Œå›žè°ƒå‡½æ•°
                    typeof callback === "function" && callback(errorsRes);
                });
            },
            // æ ¡éªŒå…¨éƒ¨æ•°æ®
            validate(callback) {
                // å¼€å‘环境才提示,生产环境不会提示
                if (process.env.NODE_ENV === 'development' && Object.keys(this.formRules).length === 0) {
                    uni.$u.error('未设置rules,请看文档说明!如果已经设置,请刷新页面。');
                    return;
                }
                return new Promise((resolve, reject) => {
                    // $nextTick是必须的,否则model的变更,可能会延后于validate方法
                    this.$nextTick(() => {
                        // èŽ·å–æ‰€æœ‰form-item的prop,交给validateField方法进行校验
                        const formItemProps = this.children.map(
                            (item) => item.prop
                        );
                        this.validateField(formItemProps, (errors) => {
                            if(errors.length) {
                                // å¦‚果错误提示方式为toast,则进行提示
                                this.errorType === 'toast' && uni.$u.toast(errors[0].message)
                                reject(errors)
                            } else {
                                resolve(true)
                            }
                        });
                    });
                });
            },
        },
    };
</script>
<style lang="scss" scoped>
</style>
uni_modules/uview-ui/components/u-gap/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
export default {
    props: {
        // èƒŒæ™¯é¢œè‰²ï¼ˆé»˜è®¤transparent)
        bgColor: {
            type: String,
            default: uni.$u.props.gap.bgColor
        },
        // åˆ†å‰²æ§½é«˜åº¦ï¼Œå•位px(默认30)
        height: {
            type: [String, Number],
            default: uni.$u.props.gap.height
        },
        // ä¸Žä¸Šä¸€ä¸ªç»„件的距离
        marginTop: {
            type: [String, Number],
            default: uni.$u.props.gap.marginTop
        },
        // ä¸Žä¸‹ä¸€ä¸ªç»„件的距离
        marginBottom: {
            type: [String, Number],
            default: uni.$u.props.gap.marginBottom
        }
    }
}
uni_modules/uview-ui/components/u-gap/u-gap.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
<template>
    <view class="u-gap" :style="[gapStyle]"></view>
</template>
<script>
    import props from './props.js';
    /**
     * gap é—´é𔿧½
     * @description è¯¥ç»„件一般用于内容块之间的用一个灰色块隔开的场景,方便用户风格统一,减少工作量
     * @tutorial https://www.uviewui.com/components/gap.html
     * @property {String}            bgColor            èƒŒæ™¯é¢œè‰² ï¼ˆé»˜è®¤ 'transparent' ï¼‰
     * @property {String | Number}    height            åˆ†å‰²æ§½é«˜åº¦ï¼Œå•位px ï¼ˆé»˜è®¤ 20 ï¼‰
     * @property {String | Number}    marginTop        ä¸Žå‰ä¸€ä¸ªç»„件的距离,单位px( é»˜è®¤ 0 ï¼‰
     * @property {String | Number}    marginBottom    ä¸ŽåŽä¸€ä¸ªç»„件的距离,单位px ï¼ˆé»˜è®¤ 0 ï¼‰
     * @property {Object}            customStyle        å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     *
     * @example <u-gap height="80" bg-color="#bbb"></u-gap>
     */
    export default {
        name: "u-gap",
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        computed: {
            gapStyle() {
                const style = {
                    backgroundColor: this.bgColor,
                    height: uni.$u.addUnit(this.height),
                    marginTop: uni.$u.addUnit(this.marginTop),
                    marginBottom: uni.$u.addUnit(this.marginBottom),
                }
                return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
            }
        }
    };
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
</style>
uni_modules/uview-ui/components/u-grid-item/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
export default {
    props: {
        // å®«æ ¼çš„name
        name: {
            type: [String, Number, null],
            default: uni.$u.props.gridItem.name
        },
        // èƒŒæ™¯é¢œè‰²
        bgColor: {
            type: String,
            default: uni.$u.props.gridItem.bgColor
        }
    }
}
uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,209 @@
<template>
    <!-- #ifndef APP-NVUE -->
    <view
        class="u-grid-item"
        hover-class="u-grid-item--hover-class"
        :hover-stay-time="200"
        @tap="clickHandler"
        :class="classes"
        :style="[itemStyle]"
    >
        <slot />
    </view>
    <!-- #endif -->
    <!-- #ifdef APP-NVUE -->
    <view
        class="u-grid-item"
        :hover-stay-time="200"
        @tap="clickHandler"
        :class="classes"
        :style="[itemStyle]"
    >
        <slot />
    </view>
    <!-- #endif -->
</template>
<script>
    import props from './props.js';
    /**
     * gridItem æç¤º
     * @description å®«æ ¼ç»„件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。搭配u-grid使用
     * @tutorial https://www.uviewui.com/components/grid.html
     * @property {String | Number}    name        å®«æ ¼çš„name ( é»˜è®¤ null )
     * @property {String}            bgColor        å®«æ ¼çš„背景颜色 ï¼ˆé»˜è®¤ 'transparent' ï¼‰
     * @property {Object}            customStyle    è‡ªå®šä¹‰æ ·å¼ï¼Œå¯¹è±¡å½¢å¼
     * @event {Function} click ç‚¹å‡»å®«æ ¼è§¦å‘
     * @example <u-grid-item></u-grid-item>
     */
    export default {
        name: "u-grid-item",
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        data() {
            return {
                parentData: {
                    col: 3, // çˆ¶ç»„件划分的宫格数
                    border: true, // æ˜¯å¦æ˜¾ç¤ºè¾¹æ¡†ï¼Œæ ¹æ®çˆ¶ç»„件决定
                },
                // #ifdef APP-NVUE
                width: 0, // nvue下才这么计算,vue下放到computed中,否则会因为延时造成闪烁
                // #endif
                classes: [], // ç±»åé›†åˆï¼Œç”¨äºŽåˆ¤æ–­æ˜¯å¦æ˜¾ç¤ºå³è¾¹å’Œä¸‹è¾¹æ¡†
            };
        },
        mounted() {
            this.init()
        },
        computed: {
            // #ifndef APP-NVUE
            // vue下放到computed中,否则会因为延时造成闪烁
            width() {
                return 100 / Number(this.parentData.col) + '%'
            },
            // #endif
            itemStyle() {
                const style = {
                    background: this.bgColor,
                    width: this.width
                }
                return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
            }
        },
        methods: {
            init() {
                // ç”¨äºŽåœ¨çˆ¶ç»„ä»¶u-grid的children中被添加入子组件时,
                // é‡æ–°è®¡ç®—item的边框
                uni.$on('$uGridItem', () => {
                    this.gridItemClasses()
                })
                // çˆ¶ç»„件的实例
                this.updateParentData()
                // #ifdef APP-NVUE
                // èŽ·å–å…ƒç´ è¯¥æœ‰çš„é•¿åº¦ï¼Œnvue下要延时才准确
                this.$nextTick(function(){
                    this.getItemWidth()
                })
                // #endif
                // å‘出事件,通知所有的grid-item都重新计算自己的边框
                uni.$emit('$uGridItem')
                this.gridItemClasses()
            },
            // èŽ·å–çˆ¶ç»„ä»¶çš„å‚æ•°
            updateParentData() {
                // æ­¤æ–¹æ³•写在mixin中
                this.getParentData('u-grid');
            },
            clickHandler() {
                let name = this.name
                // å¦‚果没有设置name属性,历遍父组件的children数组,判断当前的元素是否和本实例this相等,找出当前组件的索引
                const children = this.parent?.children
                if(children && this.name === null) {
                    name = children.findIndex(child => child === this)
                }
                // è°ƒç”¨çˆ¶ç»„件方法,发出事件
                this.parent && this.parent.childClick(name)
                this.$emit('click', name)
            },
            async getItemWidth() {
                // å¦‚果是nvue,不能使用百分比,只能使用固定宽度
                let width = 0
                if(this.parent) {
                    // èŽ·å–çˆ¶ç»„ä»¶å®½åº¦åŽï¼Œé™¤ä»¥æ …æ ¼æ•°ï¼Œå¾—å‡ºæ¯ä¸ªitem的宽度
                    const parentWidth = await this.getParentWidth()
                    width = parentWidth / Number(this.parentData.col) + 'px'
                }
                this.width = width
            },
            // èŽ·å–çˆ¶å…ƒç´ çš„å°ºå¯¸
            getParentWidth() {
                // #ifdef APP-NVUE
                // è¿”回一个promise,让调用者可以用await同步获取
                const dom = uni.requireNativePlugin('dom')
                return new Promise(resolve => {
                    // è°ƒç”¨çˆ¶ç»„ä»¶çš„ref
                    dom.getComponentRect(this.parent.$refs['u-grid'], res => {
                        resolve(res.size.width)
                    })
                })
                // #endif
            },
            gridItemClasses() {
                if(this.parentData.border) {
                    const classes = []
                    this.parent.children.map((child, index) =>{
                        if(this === child) {
                            const len = this.parent.children.length
                            // è´´è¿‘右边屏幕边沿的child,并且最后一个(比如只有横向2个的时候),无需右边框
                            if((index + 1) % this.parentData.col !== 0 && index + 1 !== len) {
                                classes.push('u-border-right')
                            }
                            // æ€»çš„宫格数量对列数取余的值
                            // å¦‚果取余后,值为0,则意味着要将最后一排的宫格,都不需要下边框
                            const lessNum = len % this.parentData.col === 0 ? this.parentData.col : len % this.parentData.col
                            // æœ€ä¸‹é¢çš„一排child,无需下边框
                            if(index < len - lessNum) {
                                classes.push('u-border-bottom')
                            }
                        }
                    })
                    // æ”¯ä»˜å®ï¼Œå¤´æ¡å°ç¨‹åºæ— æ³•动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效
                    // #ifdef MP-ALIPAY || MP-TOUTIAO
                    classes = classes.join(' ')
                    // #endif
                    this.classes = classes
                }
            }
        },
        beforeDestroy() {
            // ç§»é™¤äº‹ä»¶ç›‘听,释放性能
            uni.$off('$uGridItem')
        }
    };
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
      $u-grid-item-hover-class-opcatiy:.5 !default;
      $u-grid-item-margin-top:1rpx !default;
      $u-grid-item-border-right-width:0.5px !default;
      $u-grid-item-border-bottom-width:0.5px !default;
      $u-grid-item-border-right-color:$u-border-color !default;
      $u-grid-item-border-bottom-color:$u-border-color !default;
    .u-grid-item {
        align-items: center;
        justify-content: center;
        position: relative;
        flex-direction: column;
        /* #ifndef APP-NVUE */
        box-sizing: border-box;
        display: flex;
        /* #endif */
        /* #ifdef MP */
        position: relative;
        float: left;
        /* #endif */
        /* #ifdef MP-WEIXIN */
        margin-top:$u-grid-item-margin-top;
        /* #endif */
        &--hover-class {
            opacity:$u-grid-item-hover-class-opcatiy;
        }
    }
    /* #ifdef APP-NVUE */
    // ç”±äºŽnvue不支持组件内引入app.vue中再引入的样式,所以需要写在这里
    .u-border-right {
        border-right-width:$u-grid-item-border-right-width;
        border-color: $u-grid-item-border-right-color;
    }
    .u-border-bottom {
        border-bottom-width:$u-grid-item-border-bottom-width;
        border-color:$u-grid-item-border-bottom-color;
    }
    /* #endif */
</style>
uni_modules/uview-ui/components/u-grid/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
export default {
    props: {
        // åˆ†æˆå‡ åˆ—
        col: {
            type: [String, Number],
            default: uni.$u.props.grid.col
        },
        // æ˜¯å¦æ˜¾ç¤ºè¾¹æ¡†
        border: {
            type: Boolean,
            default: uni.$u.props.grid.border
        },
        // å®«æ ¼å¯¹é½æ–¹å¼ï¼Œè¡¨çŽ°ä¸ºæ•°é‡å°‘çš„æ—¶å€™ï¼Œé å·¦ï¼Œå±…ä¸­ï¼Œè¿˜æ˜¯é å³
        align: {
            type: String,
            default: uni.$u.props.grid.align
        }
    }
}
uni_modules/uview-ui/components/u-grid/u-grid.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,97 @@
<template>
    <view
        class="u-grid"
        ref='u-grid'
        :style="[gridStyle]"
    >
        <slot />
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * grid å®«æ ¼å¸ƒå±€
     * @description å®«æ ¼ç»„件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。
     * @tutorial https://www.uviewui.com/components/grid.html
     * @property {String | Number}    col            å®«æ ¼çš„列数(默认 3 ï¼‰
     * @property {Boolean}            border        æ˜¯å¦æ˜¾ç¤ºå®«æ ¼çš„边框(默认 false ï¼‰
     * @property {String}            align        å®«æ ¼å¯¹é½æ–¹å¼ï¼Œè¡¨çŽ°ä¸ºæ•°é‡å°‘çš„æ—¶å€™ï¼Œé å·¦ï¼Œå±…ä¸­ï¼Œè¿˜æ˜¯é å³ ï¼ˆé»˜è®¤ 'left' ï¼‰
     * @property {Object}            customStyle    å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     * @event {Function} click ç‚¹å‡»å®«æ ¼è§¦å‘
     * @example <u-grid :col="3" @click="click"></u-grid>
     */
    export default {
        name: 'u-grid',
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        data() {
            return {
                index: 0,
                width: 0
            }
        },
        watch: {
            // å½“父组件需要子组件需要共享的参数发生了变化,手动通知子组件
            parentData() {
                if (this.children.length) {
                    this.children.map(child => {
                        // åˆ¤æ–­å­ç»„ä»¶(u-radio)如果有updateParentData方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
                        typeof(child.updateParentData) == 'function' && child.updateParentData();
                    })
                }
            },
        },
        created() {
            // å¦‚果将children定义在data中,在微信小程序会造成循环引用而报错
            this.children = []
        },
        computed: {
            // è®¡ç®—父组件的值是否发生变化
            parentData() {
                return [this.hoverClass, this.col, this.size, this.border];
            },
            // å®«æ ¼å¯¹é½æ–¹å¼
            gridStyle() {
                let style = {};
                switch (this.align) {
                    case 'left':
                        style.justifyContent = 'flex-start';
                        break;
                    case 'center':
                        style.justifyContent = 'center';
                        break;
                    case 'right':
                        style.justifyContent = 'flex-end';
                        break;
                    default:
                        style.justifyContent = 'flex-start';
                };
                return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle));
            }
        },
        methods: {
            // æ­¤æ–¹æ³•ç”±u-grid-item触发,用于在u-grid发出事件
            childClick(name) {
                this.$emit('click', name)
            }
        }
    };
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
     $u-grid-width:100% !default;
    .u-grid {
        /* #ifdef MP */
        width: $u-grid-width;
        position: relative;
        box-sizing: border-box;
        overflow: hidden;
        display: block;
        /* #endif */
        justify-content: center;
        @include flex;
        flex-wrap: wrap;
        align-items: center;
    }
</style>
uni_modules/uview-ui/components/u-icon/icons.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,214 @@
export default {
    'uicon-level': '\ue693',
    'uicon-column-line': '\ue68e',
    'uicon-checkbox-mark': '\ue807',
    'uicon-folder': '\ue7f5',
    'uicon-movie': '\ue7f6',
    'uicon-star-fill': '\ue669',
    'uicon-star': '\ue65f',
    'uicon-phone-fill': '\ue64f',
    'uicon-phone': '\ue622',
    'uicon-apple-fill': '\ue881',
    'uicon-chrome-circle-fill': '\ue885',
    'uicon-backspace': '\ue67b',
    'uicon-attach': '\ue632',
    'uicon-cut': '\ue948',
    'uicon-empty-car': '\ue602',
    'uicon-empty-coupon': '\ue682',
    'uicon-empty-address': '\ue646',
    'uicon-empty-favor': '\ue67c',
    'uicon-empty-permission': '\ue686',
    'uicon-empty-news': '\ue687',
    'uicon-empty-search': '\ue664',
    'uicon-github-circle-fill': '\ue887',
    'uicon-rmb': '\ue608',
    'uicon-person-delete-fill': '\ue66a',
    'uicon-reload': '\ue788',
    'uicon-order': '\ue68f',
    'uicon-server-man': '\ue6bc',
    'uicon-search': '\ue62a',
    'uicon-fingerprint': '\ue955',
    'uicon-more-dot-fill': '\ue630',
    'uicon-scan': '\ue662',
    'uicon-share-square': '\ue60b',
    'uicon-map': '\ue61d',
    'uicon-map-fill': '\ue64e',
    'uicon-tags': '\ue629',
    'uicon-tags-fill': '\ue651',
    'uicon-bookmark-fill': '\ue63b',
    'uicon-bookmark': '\ue60a',
    'uicon-eye': '\ue613',
    'uicon-eye-fill': '\ue641',
    'uicon-mic': '\ue64a',
    'uicon-mic-off': '\ue649',
    'uicon-calendar': '\ue66e',
    'uicon-calendar-fill': '\ue634',
    'uicon-trash': '\ue623',
    'uicon-trash-fill': '\ue658',
    'uicon-play-left': '\ue66d',
    'uicon-play-right': '\ue610',
    'uicon-minus': '\ue618',
    'uicon-plus': '\ue62d',
    'uicon-info': '\ue653',
    'uicon-info-circle': '\ue7d2',
    'uicon-info-circle-fill': '\ue64b',
    'uicon-question': '\ue715',
    'uicon-error': '\ue6d3',
    'uicon-close': '\ue685',
    'uicon-checkmark': '\ue6a8',
    'uicon-android-circle-fill': '\ue67e',
    'uicon-android-fill': '\ue67d',
    'uicon-ie': '\ue87b',
    'uicon-IE-circle-fill': '\ue889',
    'uicon-google': '\ue87a',
    'uicon-google-circle-fill': '\ue88a',
    'uicon-setting-fill': '\ue872',
    'uicon-setting': '\ue61f',
    'uicon-minus-square-fill': '\ue855',
    'uicon-plus-square-fill': '\ue856',
    'uicon-heart': '\ue7df',
    'uicon-heart-fill': '\ue851',
    'uicon-camera': '\ue7d7',
    'uicon-camera-fill': '\ue870',
    'uicon-more-circle': '\ue63e',
    'uicon-more-circle-fill': '\ue645',
    'uicon-chat': '\ue620',
    'uicon-chat-fill': '\ue61e',
    'uicon-bag-fill': '\ue617',
    'uicon-bag': '\ue619',
    'uicon-error-circle-fill': '\ue62c',
    'uicon-error-circle': '\ue624',
    'uicon-close-circle': '\ue63f',
    'uicon-close-circle-fill': '\ue637',
    'uicon-checkmark-circle': '\ue63d',
    'uicon-checkmark-circle-fill': '\ue635',
    'uicon-question-circle-fill': '\ue666',
    'uicon-question-circle': '\ue625',
    'uicon-share': '\ue631',
    'uicon-share-fill': '\ue65e',
    'uicon-shopping-cart': '\ue621',
    'uicon-shopping-cart-fill': '\ue65d',
    'uicon-bell': '\ue609',
    'uicon-bell-fill': '\ue640',
    'uicon-list': '\ue650',
    'uicon-list-dot': '\ue616',
    'uicon-zhihu': '\ue6ba',
    'uicon-zhihu-circle-fill': '\ue709',
    'uicon-zhifubao': '\ue6b9',
    'uicon-zhifubao-circle-fill': '\ue6b8',
    'uicon-weixin-circle-fill': '\ue6b1',
    'uicon-weixin-fill': '\ue6b2',
    'uicon-twitter-circle-fill': '\ue6ab',
    'uicon-twitter': '\ue6aa',
    'uicon-taobao-circle-fill': '\ue6a7',
    'uicon-taobao': '\ue6a6',
    'uicon-weibo-circle-fill': '\ue6a5',
    'uicon-weibo': '\ue6a4',
    'uicon-qq-fill': '\ue6a1',
    'uicon-qq-circle-fill': '\ue6a0',
    'uicon-moments-circel-fill': '\ue69a',
    'uicon-moments': '\ue69b',
    'uicon-qzone': '\ue695',
    'uicon-qzone-circle-fill': '\ue696',
    'uicon-baidu-circle-fill': '\ue680',
    'uicon-baidu': '\ue681',
    'uicon-facebook-circle-fill': '\ue68a',
    'uicon-facebook': '\ue689',
    'uicon-car': '\ue60c',
    'uicon-car-fill': '\ue636',
    'uicon-warning-fill': '\ue64d',
    'uicon-warning': '\ue694',
    'uicon-clock-fill': '\ue638',
    'uicon-clock': '\ue60f',
    'uicon-edit-pen': '\ue612',
    'uicon-edit-pen-fill': '\ue66b',
    'uicon-email': '\ue611',
    'uicon-email-fill': '\ue642',
    'uicon-minus-circle': '\ue61b',
    'uicon-minus-circle-fill': '\ue652',
    'uicon-plus-circle': '\ue62e',
    'uicon-plus-circle-fill': '\ue661',
    'uicon-file-text': '\ue663',
    'uicon-file-text-fill': '\ue665',
    'uicon-pushpin': '\ue7e3',
    'uicon-pushpin-fill': '\ue86e',
    'uicon-grid': '\ue673',
    'uicon-grid-fill': '\ue678',
    'uicon-play-circle': '\ue647',
    'uicon-play-circle-fill': '\ue655',
    'uicon-pause-circle-fill': '\ue654',
    'uicon-pause': '\ue8fa',
    'uicon-pause-circle': '\ue643',
    'uicon-eye-off': '\ue648',
    'uicon-eye-off-outline': '\ue62b',
    'uicon-gift-fill': '\ue65c',
    'uicon-gift': '\ue65b',
    'uicon-rmb-circle-fill': '\ue657',
    'uicon-rmb-circle': '\ue677',
    'uicon-kefu-ermai': '\ue656',
    'uicon-server-fill': '\ue751',
    'uicon-coupon-fill': '\ue8c4',
    'uicon-coupon': '\ue8ae',
    'uicon-integral': '\ue704',
    'uicon-integral-fill': '\ue703',
    'uicon-home-fill': '\ue964',
    'uicon-home': '\ue965',
    'uicon-hourglass-half-fill': '\ue966',
    'uicon-hourglass': '\ue967',
    'uicon-account': '\ue628',
    'uicon-plus-people-fill': '\ue626',
    'uicon-minus-people-fill': '\ue615',
    'uicon-account-fill': '\ue614',
    'uicon-thumb-down-fill': '\ue726',
    'uicon-thumb-down': '\ue727',
    'uicon-thumb-up': '\ue733',
    'uicon-thumb-up-fill': '\ue72f',
    'uicon-lock-fill': '\ue979',
    'uicon-lock-open': '\ue973',
    'uicon-lock-opened-fill': '\ue974',
    'uicon-lock': '\ue97a',
    'uicon-red-packet-fill': '\ue690',
    'uicon-photo-fill': '\ue98b',
    'uicon-photo': '\ue98d',
    'uicon-volume-off-fill': '\ue659',
    'uicon-volume-off': '\ue644',
    'uicon-volume-fill': '\ue670',
    'uicon-volume': '\ue633',
    'uicon-red-packet': '\ue691',
    'uicon-download': '\ue63c',
    'uicon-arrow-up-fill': '\ue6b0',
    'uicon-arrow-down-fill': '\ue600',
    'uicon-play-left-fill': '\ue675',
    'uicon-play-right-fill': '\ue676',
    'uicon-rewind-left-fill': '\ue679',
    'uicon-rewind-right-fill': '\ue67a',
    'uicon-arrow-downward': '\ue604',
    'uicon-arrow-leftward': '\ue601',
    'uicon-arrow-rightward': '\ue603',
    'uicon-arrow-upward': '\ue607',
    'uicon-arrow-down': '\ue60d',
    'uicon-arrow-right': '\ue605',
    'uicon-arrow-left': '\ue60e',
    'uicon-arrow-up': '\ue606',
    'uicon-skip-back-left': '\ue674',
    'uicon-skip-forward-right': '\ue672',
    'uicon-rewind-right': '\ue66f',
    'uicon-rewind-left': '\ue671',
    'uicon-arrow-right-double': '\ue68d',
    'uicon-arrow-left-double': '\ue68c',
    'uicon-wifi-off': '\ue668',
    'uicon-wifi': '\ue667',
    'uicon-empty-data': '\ue62f',
    'uicon-empty-history': '\ue684',
    'uicon-empty-list': '\ue68b',
    'uicon-empty-page': '\ue627',
    'uicon-empty-order': '\ue639',
    'uicon-man': '\ue697',
    'uicon-woman': '\ue69c',
    'uicon-man-add': '\ue61c',
    'uicon-man-add-fill': '\ue64c',
    'uicon-man-delete': '\ue61a',
    'uicon-man-delete-fill': '\ue66a',
    'uicon-zh': '\ue70a',
    'uicon-en': '\ue692'
}
uni_modules/uview-ui/components/u-icon/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,89 @@
export default {
    props: {
        // å›¾æ ‡ç±»å
        name: {
            type: String,
            default: uni.$u.props.icon.name
        },
        // å›¾æ ‡é¢œè‰²ï¼Œå¯æŽ¥å—主题色
        color: {
            type: String,
            default: uni.$u.props.icon.color
        },
        // å­—体大小,单位px
        size: {
            type: [String, Number],
            default: uni.$u.props.icon.size
        },
        // æ˜¯å¦æ˜¾ç¤ºç²—体
        bold: {
            type: Boolean,
            default: uni.$u.props.icon.bold
        },
        // ç‚¹å‡»å›¾æ ‡çš„æ—¶å€™ä¼ é€’事件出去的index(用于区分点击了哪一个)
        index: {
            type: [String, Number],
            default: uni.$u.props.icon.index
        },
        // è§¦æ‘¸å›¾æ ‡æ—¶çš„类名
        hoverClass: {
            type: String,
            default: uni.$u.props.icon.hoverClass
        },
        // è‡ªå®šä¹‰æ‰©å±•前缀,方便用户扩展自己的图标库
        customPrefix: {
            type: String,
            default: uni.$u.props.icon.customPrefix
        },
        // å›¾æ ‡å³è¾¹æˆ–者下面的文字
        label: {
            type: [String, Number],
            default: uni.$u.props.icon.label
        },
        // label的位置,只能右边或者下边
        labelPos: {
            type: String,
            default: uni.$u.props.icon.labelPos
        },
        // label的大小
        labelSize: {
            type: [String, Number],
            default: uni.$u.props.icon.labelSize
        },
        // label的颜色
        labelColor: {
            type: String,
            default: uni.$u.props.icon.labelColor
        },
        // label与图标的距离
        space: {
            type: [String, Number],
            default: uni.$u.props.icon.space
        },
        // å›¾ç‰‡çš„mode
        imgMode: {
            type: String,
            default: uni.$u.props.icon.imgMode
        },
        // ç”¨äºŽæ˜¾ç¤ºå›¾ç‰‡å°å›¾æ ‡æ—¶ï¼Œå›¾ç‰‡çš„宽度
        width: {
            type: [String, Number],
            default: uni.$u.props.icon.width
        },
        // ç”¨äºŽæ˜¾ç¤ºå›¾ç‰‡å°å›¾æ ‡æ—¶ï¼Œå›¾ç‰‡çš„高度
        height: {
            type: [String, Number],
            default: uni.$u.props.icon.height
        },
        // ç”¨äºŽè§£å†³æŸäº›æƒ…况下,让图标垂直居中的用途
        top: {
            type: [String, Number],
            default: uni.$u.props.icon.top
        },
        // æ˜¯å¦é˜»æ­¢äº‹ä»¶ä¼ æ’­
        stop: {
            type: Boolean,
            default: uni.$u.props.icon.stop
        }
    }
}
uni_modules/uview-ui/components/u-icon/u-icon.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,234 @@
<template>
    <view
        class="u-icon"
        @tap="clickHandler"
        :class="['u-icon--' + labelPos]"
    >
        <image
            class="u-icon__img"
            v-if="isImg"
            :src="name"
            :mode="imgMode"
            :style="[imgStyle, $u.addStyle(customStyle)]"
        ></image>
        <text
            v-else
            class="u-icon__icon"
            :class="uClasses"
            :style="[iconStyle, $u.addStyle(customStyle)]"
            :hover-class="hoverClass"
        >{{icon}}</text>
        <!-- è¿™é‡Œè¿›è¡Œç©ºå­—符串判断,如果仅仅是v-if="label",可能会出现传递0的时候,结果也无法显示 -->
        <text
            v-if="label !== ''"
            class="u-icon__label"
            :style="{
            color: labelColor,
            fontSize: $u.addUnit(labelSize),
            marginLeft: labelPos == 'right' ? $u.addUnit(space) : 0,
            marginTop: labelPos == 'bottom' ? $u.addUnit(space) : 0,
            marginRight: labelPos == 'left' ? $u.addUnit(space) : 0,
            marginBottom: labelPos == 'top' ? $u.addUnit(space) : 0,
        }"
        >{{ label }}</text>
    </view>
</template>
<script>
    // #ifdef APP-NVUE
    // nvue通过weex的dom模块引入字体,相关文档地址如下:
    // https://weex.apache.org/zh/docs/modules/dom.html#addrule
    const fontUrl = 'https://at.alicdn.com/t/font_2225171_8kdcwk4po24.ttf'
    const domModule = weex.requireModule('dom')
    domModule.addRule('fontFace', {
        'fontFamily': "uicon-iconfont",
        'src': `url('${fontUrl}')`
    })
    // #endif
    // å¼•入图标名称,已经对应的unicode
    import icons from './icons'
    import props from './props.js';;
    /**
     * icon å›¾æ ‡
     * @description åŸºäºŽå­—体的图标集,包含了大多数常见场景的图标。
     * @tutorial https://www.uviewui.com/components/icon.html
     * @property {String}            name            å›¾æ ‡åç§°ï¼Œè§ç¤ºä¾‹å›¾æ ‡é›†
     * @property {String}            color            å›¾æ ‡é¢œè‰²,可接受主题色 ï¼ˆé»˜è®¤ color['u-content-color'] ï¼‰
     * @property {String | Number}    size            å›¾æ ‡å­—体大小,单位px ï¼ˆé»˜è®¤ '16px' ï¼‰
     * @property {Boolean}            bold            æ˜¯å¦æ˜¾ç¤ºç²—体 ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String | Number}    index            ç‚¹å‡»å›¾æ ‡çš„æ—¶å€™ä¼ é€’事件出去的index(用于区分点击了哪一个)
     * @property {String}            hoverClass        å›¾æ ‡æŒ‰ä¸‹åŽ»çš„æ ·å¼ç±»ï¼Œç”¨æ³•åŒuni的view组件的hoverClass参数,详情见官网
     * @property {String}            customPrefix    è‡ªå®šä¹‰æ‰©å±•前缀,方便用户扩展自己的图标库 ï¼ˆé»˜è®¤ 'uicon' ï¼‰
     * @property {String | Number}    label            å›¾æ ‡å³ä¾§çš„label文字
     * @property {String}            labelPos        label相对于图标的位置,只能right或bottom ï¼ˆé»˜è®¤ 'right' ï¼‰
     * @property {String | Number}    labelSize        label字体大小,单位px ï¼ˆé»˜è®¤ '15px' ï¼‰
     * @property {String}            labelColor        å›¾æ ‡å³ä¾§çš„label文字颜色 ï¼ˆ é»˜è®¤ color['u-content-color'] ï¼‰
     * @property {String | Number}    space            label与图标的距离,单位px ï¼ˆé»˜è®¤ '3px' ï¼‰
     * @property {String}            imgMode            å›¾ç‰‡çš„mode
     * @property {String | Number}    width            æ˜¾ç¤ºå›¾ç‰‡å°å›¾æ ‡æ—¶çš„宽度
     * @property {String | Number}    height            æ˜¾ç¤ºå›¾ç‰‡å°å›¾æ ‡æ—¶çš„高度
     * @property {String | Number}    top                å›¾æ ‡åœ¨åž‚直方向上的定位 ç”¨äºŽè§£å†³æŸäº›æƒ…况下,让图标垂直居中的用途  ï¼ˆé»˜è®¤ 0 ï¼‰
     * @property {Boolean}            stop            æ˜¯å¦é˜»æ­¢äº‹ä»¶ä¼ æ’­ ï¼ˆé»˜è®¤ false ï¼‰
     * @property {Object}            customStyle        icon的样式,对象形式
     * @event {Function} click ç‚¹å‡»å›¾æ ‡æ—¶è§¦å‘
     * @event {Function} touchstart äº‹ä»¶è§¦æ‘¸æ—¶è§¦å‘
     * @example <u-icon name="photo" color="#2979ff" size="28"></u-icon>
     */
    export default {
        name: 'u-icon',
        data() {
            return {
            }
        },
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        computed: {
            uClasses() {
                let classes = []
                classes.push(this.customPrefix + '-' + this.name)
                // // uView的自定义图标类名为u-iconfont
                // if (this.customPrefix == 'uicon') {
                //     classes.push('u-iconfont')
                // } else {
                //     classes.push(this.customPrefix)
                // }
                // ä¸»é¢˜è‰²ï¼Œé€šè¿‡ç±»é…ç½®
                if (this.color && uni.$u.config.type.includes(this.color)) classes.push('u-icon__icon--' + this.color)
                // é˜¿é‡Œï¼Œå¤´æ¡ï¼Œç™¾åº¦å°ç¨‹åºé€šè¿‡æ•°ç»„绑定类名时,无法直接使用[a, b, c]的形式,否则无法识别
                // æ•…需将其拆成一个字符串的形式,通过空格隔开各个类名
                //#ifdef MP-ALIPAY || MP-TOUTIAO || MP-BAIDU
                classes = classes.join(' ')
                //#endif
                return classes
            },
            iconStyle() {
                let style = {}
                style = {
                    fontSize: uni.$u.addUnit(this.size),
                    lineHeight: uni.$u.addUnit(this.size),
                    fontWeight: this.bold ? 'bold' : 'normal',
                    // æŸäº›ç‰¹æ®Šæƒ…况需要设置一个到顶部的距离,才能更好的垂直居中
                    top: uni.$u.addUnit(this.top)
                }
                // éžä¸»é¢˜è‰²å€¼æ—¶ï¼Œæ‰å½“作颜色值
                if (this.color && !uni.$u.config.type.includes(this.color)) style.color = this.color
                return style
            },
            // åˆ¤æ–­ä¼ å…¥çš„name属性,是否图片路径,只要带有"/"均认为是图片形式
            isImg() {
                return this.name.indexOf('/') !== -1
            },
            imgStyle() {
                let style = {}
                // å¦‚果设置width和height属性,则优先使用,否则使用size属性
                style.width = this.width ? uni.$u.addUnit(this.width) : uni.$u.addUnit(this.size)
                style.height = this.height ? uni.$u.addUnit(this.height) : uni.$u.addUnit(this.size)
                return style
            },
            // é€šè¿‡å›¾æ ‡åï¼ŒæŸ¥æ‰¾å¯¹åº”的图标
            icon() {
                // å¦‚果内置的图标中找不到对应的图标,就直接返回name值,因为用户可能传入的是unicode代码
                return icons['uicon-' + this.name] || this.name
            }
        },
        methods: {
            clickHandler(e) {
                this.$emit('click', this.index)
                // æ˜¯å¦é˜»æ­¢äº‹ä»¶å†’泡
                this.stop && this.preventEvent(e)
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    // å˜é‡å®šä¹‰
    $u-icon-primary: $u-primary !default;
    $u-icon-success: $u-success !default;
    $u-icon-info: $u-info !default;
    $u-icon-warning: $u-warning !default;
    $u-icon-error: $u-error !default;
    $u-icon-label-line-height:1 !default;
    /* #ifndef APP-NVUE */
    // éžnvue下加载字体
    @font-face {
        font-family: 'uicon-iconfont';
        src: url('https://at.alicdn.com/t/font_2225171_8kdcwk4po24.ttf') format('truetype');
    }
    /* #endif */
    .u-icon {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        align-items: center;
        &--left {
            flex-direction: row-reverse;
            align-items: center;
        }
        &--right {
            flex-direction: row;
            align-items: center;
        }
        &--top {
            flex-direction: column-reverse;
            justify-content: center;
        }
        &--bottom {
            flex-direction: column;
            justify-content: center;
        }
        &__icon {
            font-family: uicon-iconfont;
            position: relative;
            @include flex;
            align-items: center;
            &--primary {
                color: $u-icon-primary;
            }
            &--success {
                color: $u-icon-success;
            }
            &--error {
                color: $u-icon-error;
            }
            &--warning {
                color: $u-icon-warning;
            }
            &--info {
                color: $u-icon-info;
            }
        }
        &__img {
            /* #ifndef APP-NVUE */
            height: auto;
            will-change: transform;
            /* #endif */
        }
        &__label {
            /* #ifndef APP-NVUE */
            line-height: $u-icon-label-line-height;
            /* #endif */
        }
    }
</style>
uni_modules/uview-ui/components/u-image/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,84 @@
export default {
    props: {
        // å›¾ç‰‡åœ°å€
        src: {
            type: String,
            default: uni.$u.props.image.src
        },
        // è£å‰ªæ¨¡å¼
        mode: {
            type: String,
            default: uni.$u.props.image.mode
        },
        // å®½åº¦ï¼Œå•位任意
        width: {
            type: [String, Number],
            default: uni.$u.props.image.width
        },
        // é«˜åº¦ï¼Œå•位任意
        height: {
            type: [String, Number],
            default: uni.$u.props.image.height
        },
        // å›¾ç‰‡å½¢çŠ¶ï¼Œcircle-圆形,square-方形
        shape: {
            type: String,
            default: uni.$u.props.image.shape
        },
        // åœ†è§’,单位任意
        radius: {
            type: [String, Number],
            default: uni.$u.props.image.radius
        },
        // æ˜¯å¦æ‡’加载,微信小程序、App、百度小程序、字节跳动小程序
        lazyLoad: {
            type: Boolean,
            default: uni.$u.props.image.lazyLoad
        },
        // å¼€å¯é•¿æŒ‰å›¾ç‰‡æ˜¾ç¤ºè¯†åˆ«å¾®ä¿¡å°ç¨‹åºç èœå•
        showMenuByLongpress: {
            type: Boolean,
            default: uni.$u.props.image.showMenuByLongpress
        },
        // åŠ è½½ä¸­çš„å›¾æ ‡ï¼Œæˆ–è€…å°å›¾ç‰‡
        loadingIcon: {
            type: String,
            default: uni.$u.props.image.loadingIcon
        },
        // åŠ è½½å¤±è´¥çš„å›¾æ ‡ï¼Œæˆ–è€…å°å›¾ç‰‡
        errorIcon: {
            type: String,
            default: uni.$u.props.image.errorIcon
        },
        // æ˜¯å¦æ˜¾ç¤ºåŠ è½½ä¸­çš„å›¾æ ‡æˆ–è€…è‡ªå®šä¹‰çš„slot
        showLoading: {
            type: Boolean,
            default: uni.$u.props.image.showLoading
        },
        // æ˜¯å¦æ˜¾ç¤ºåŠ è½½é”™è¯¯çš„å›¾æ ‡æˆ–è€…è‡ªå®šä¹‰çš„slot
        showError: {
            type: Boolean,
            default: uni.$u.props.image.showError
        },
        // æ˜¯å¦éœ€è¦æ·¡å…¥æ•ˆæžœ
        fade: {
            type: Boolean,
            default: uni.$u.props.image.fade
        },
        // åªæ”¯æŒç½‘络资源,只对微信小程序有效
        webp: {
            type: Boolean,
            default: uni.$u.props.image.webp
        },
        // è¿‡æ¸¡æ—¶é—´ï¼Œå•位ms
        duration: {
            type: [String, Number],
            default: uni.$u.props.image.duration
        },
        // èƒŒæ™¯é¢œè‰²ï¼Œç”¨äºŽæ·±è‰²é¡µé¢åŠ è½½å›¾ç‰‡æ—¶ï¼Œä¸ºäº†å’ŒèƒŒæ™¯è‰²èžåˆ
        bgColor: {
            type: String,
            default: uni.$u.props.image.bgColor
        }
    }
}
uni_modules/uview-ui/components/u-image/u-image.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,232 @@
<template>
    <u-transition
        mode="fade"
        :show="show"
        :duration="fade ? 1000 : 0"
    >
        <view
            class="u-image"
            @tap="onClick"
            :style="[wrapStyle, backgroundStyle]"
        >
            <image
                v-if="!isError"
                :src="src"
                :mode="mode"
                @error="onErrorHandler"
                @load="onLoadHandler"
                :show-menu-by-longpress="showMenuByLongpress"
                :lazy-load="lazyLoad"
                class="u-image__image"
                :style="{
                    borderRadius: shape == 'circle' ? '10000px' : $u.addUnit(radius),
                    width: $u.addUnit(width),
                    height: $u.addUnit(height)
                }"
            ></image>
            <view
                v-if="showLoading && loading"
                class="u-image__loading"
                :style="{
                    borderRadius: shape == 'circle' ? '50%' : $u.addUnit(radius),
                    backgroundColor: this.bgColor,
                    width: $u.addUnit(width),
                    height: $u.addUnit(height)
                }"
            >
                <slot name="loading">
                    <u-icon
                        :name="loadingIcon"
                        :width="width"
                        :height="height"
                    ></u-icon>
                </slot>
            </view>
            <view
                v-if="showError && isError && !loading"
                class="u-image__error"
                :style="{
                    borderRadius: shape == 'circle' ? '50%' : $u.addUnit(radius),
                    width: $u.addUnit(width),
                    height: $u.addUnit(height)
                }"
            >
                <slot name="error">
                    <u-icon
                        :name="errorIcon"
                        :width="width"
                        :height="height"
                    ></u-icon>
                </slot>
            </view>
        </view>
    </u-transition>
</template>
<script>
    import props from './props.js';
    /**
     * Image å›¾ç‰‡
     * @description æ­¤ç»„件为uni-app的image组件的加强版,在继承了原有功能外,还支持淡入动画、加载中、加载失败提示、圆角值和形状等。
     * @tutorial https://uviewui.com/components/image.html
     * @property {String}            src                 å›¾ç‰‡åœ°å€
     * @property {String}            mode                 è£å‰ªæ¨¡å¼ï¼Œè§å®˜ç½‘说明 ï¼ˆé»˜è®¤ 'aspectFill' ï¼‰
     * @property {String | Number}    width                 å®½åº¦ï¼Œå•位任意,如果为数值,则为px单位 ï¼ˆé»˜è®¤ '300' ï¼‰
     * @property {String | Number}    height                 é«˜åº¦ï¼Œå•位任意,如果为数值,则为px单位 ï¼ˆé»˜è®¤ '225' ï¼‰
     * @property {String}            shape                 å›¾ç‰‡å½¢çŠ¶ï¼Œcircle-圆形,square-方形 ï¼ˆé»˜è®¤ 'square' ï¼‰
     * @property {String | Number}    radius                 åœ†è§’值,单位任意,如果为数值,则为px单位 ï¼ˆé»˜è®¤ 0 ï¼‰
     * @property {Boolean}            lazyLoad            æ˜¯å¦æ‡’加载,仅微信小程序、App、百度小程序、字节跳动小程序有效 ï¼ˆé»˜è®¤ true ï¼‰
     * @property {Boolean}            showMenuByLongpress    æ˜¯å¦å¼€å¯é•¿æŒ‰å›¾ç‰‡æ˜¾ç¤ºè¯†åˆ«å°ç¨‹åºç èœå•,仅微信小程序有效 ï¼ˆé»˜è®¤ true ï¼‰
     * @property {String}            loadingIcon         åŠ è½½ä¸­çš„å›¾æ ‡ï¼Œæˆ–è€…å°å›¾ç‰‡ ï¼ˆé»˜è®¤ 'photo' ï¼‰
     * @property {String}            errorIcon             åŠ è½½å¤±è´¥çš„å›¾æ ‡ï¼Œæˆ–è€…å°å›¾ç‰‡ ï¼ˆé»˜è®¤ 'error-circle' ï¼‰
     * @property {Boolean}            showLoading         æ˜¯å¦æ˜¾ç¤ºåŠ è½½ä¸­çš„å›¾æ ‡æˆ–è€…è‡ªå®šä¹‰çš„slot ï¼ˆé»˜è®¤ true ï¼‰
     * @property {Boolean}            showError             æ˜¯å¦æ˜¾ç¤ºåŠ è½½é”™è¯¯çš„å›¾æ ‡æˆ–è€…è‡ªå®šä¹‰çš„slot ï¼ˆé»˜è®¤ true ï¼‰
     * @property {Boolean}            fade                 æ˜¯å¦éœ€è¦æ·¡å…¥æ•ˆæžœ ï¼ˆé»˜è®¤ true ï¼‰
     * @property {Boolean}            webp                 åªæ”¯æŒç½‘络资源,只对微信小程序有效 ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String | Number}    duration             æ­é…fade参数的过渡时间,单位ms ï¼ˆé»˜è®¤ 500 ï¼‰
     * @property {String}            bgColor             èƒŒæ™¯é¢œè‰²ï¼Œç”¨äºŽæ·±è‰²é¡µé¢åŠ è½½å›¾ç‰‡æ—¶ï¼Œä¸ºäº†å’ŒèƒŒæ™¯è‰²èžåˆ  (默认 '#f3f4f6' )
     * @property {Object}            customStyle          å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     * @event {Function}    click    ç‚¹å‡»å›¾ç‰‡æ—¶è§¦å‘
     * @event {Function}    error    å›¾ç‰‡åŠ è½½å¤±è´¥æ—¶è§¦å‘
     * @event {Function} load å›¾ç‰‡åŠ è½½æˆåŠŸæ—¶è§¦å‘
     * @example <u-image width="100%" height="300px" :src="src"></u-image>
     */
    export default {
        name: 'u-image',
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
                // å›¾ç‰‡æ˜¯å¦åŠ è½½é”™è¯¯ï¼Œå¦‚æžœæ˜¯ï¼Œåˆ™æ˜¾ç¤ºé”™è¯¯å ä½å›¾
                isError: false,
                // åˆå§‹åŒ–组件时,默认为加载中状态
                loading: true,
                // ä¸é€æ˜Žåº¦ï¼Œä¸ºäº†å®žçŽ°æ·¡å…¥æ·¡å‡ºçš„æ•ˆæžœ
                opacity: 1,
                // è¿‡æ¸¡æ—¶é—´ï¼Œå› ä¸ºprops的值无法修改,故需要一个中间值
                durationTime: this.duration,
                // å›¾ç‰‡åŠ è½½å®Œæˆæ—¶ï¼ŒåŽ»æŽ‰èƒŒæ™¯é¢œè‰²ï¼Œå› ä¸ºå¦‚æžœæ˜¯png图片,就会显示灰色的背景
                backgroundStyle: {},
                // ç”¨äºŽfade模式的控制组件显示与否
                show: false
            };
        },
        watch: {
            src: {
                immediate: true,
                handler(n) {
                    if (!n) {
                        // å¦‚果传入null或者'',或者false,或者undefined,标记为错误状态
                        this.isError = true
                    } else {
                        this.isError = false;
                        this.loading = true;
                    }
                }
            }
        },
        computed: {
            wrapStyle() {
                let style = {};
                // é€šè¿‡è°ƒç”¨addUnit()方法,如果有单位,如百分比,px单位等,直接返回,如果是纯粹的数值,则加上rpx单位
                style.width = this.$u.addUnit(this.width);
                style.height = this.$u.addUnit(this.height);
                // å¦‚果是显示圆形,设置一个很多的半径值即可
                style.borderRadius = this.shape == 'circle' ? '10000px' : uni.$u.addUnit(this.radius)
                // å¦‚果设置圆角,必须要有hidden,否则可能圆角无效
                style.overflow = this.borderRadius > 0 ? 'hidden' : 'visible'
                // if (this.fade) {
                //     style.opacity = this.opacity
                //     // nvue下,这几个属性必须要分开写
                //     style.transitionDuration = `${this.durationTime}ms`
                //     style.transitionTimingFunction = 'ease-in-out'
                //     style.transitionProperty = 'opacity'
                // }
                return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle));
            }
        },
        mounted() {
            this.show = true
        },
        methods: {
            // ç‚¹å‡»å›¾ç‰‡
            onClick() {
                this.$emit('click')
            },
            // å›¾ç‰‡åŠ è½½å¤±è´¥
            onErrorHandler(err) {
                this.loading = false
                this.isError = true
                this.$emit('error', err)
            },
            // å›¾ç‰‡åŠ è½½å®Œæˆï¼Œæ ‡è®°loading结束
            onLoadHandler() {
                this.loading = false
                this.isError = false
                this.$emit('load')
                this.removeBgColor()
                // å¦‚果不需要动画效果,就不执行下方代码,同时移除加载时的背景颜色
                // å¦åˆ™æ— éœ€fade效果时,png图片依然能看到下方的背景色
                // if (!this.fade) return this.removeBgColor();
                // // åŽŸæ¥opacity为1(不透明,是为了显示占位图),改成0(透明,意味着该元素显示的是背景颜色,默认的灰色),再改成1,是为了获得过渡效果
                // this.opacity = 0;
                // // è¿™é‡Œè®¾ç½®ä¸º0,是为了图片展示到背景全透明这个过程时间为0,延时之后延时之后重新设置为duration,是为了获得背景透明(灰色)
                // // åˆ°å›¾ç‰‡å±•示的过程中的淡入效果
                // this.durationTime = 0;
                // // å»¶æ—¶50ms,否则在浏览器H5,过渡效果无效
                // setTimeout(() => {
                //     this.durationTime = this.duration;
                //     this.opacity = 1;
                //     setTimeout(() => {
                //         this.removeBgColor();
                //     }, this.durationTime);
                // }, 50);
            },
            // ç§»é™¤å›¾ç‰‡çš„背景色
            removeBgColor() {
                // æ·¡å…¥åŠ¨ç”»è¿‡æ¸¡å®ŒæˆåŽï¼Œå°†èƒŒæ™¯è®¾ç½®ä¸ºé€æ˜Žè‰²ï¼Œå¦åˆ™png图片会看到灰色的背景
                this.backgroundStyle = {
                    backgroundColor: 'transparent'
                };
            }
        }
    };
</script>
<style lang="scss" scoped>
    @import '../../libs/css/components.scss';
    $u-image-error-top:0px !default;
    $u-image-error-left:0px !default;
    $u-image-error-width:100% !default;
    $u-image-error-hight:100% !default;
    $u-image-error-background-color:$u-bg-color !default;
    $u-image-error-color:$u-tips-color !default;
    $u-image-error-font-size: 46rpx !default;
    .u-image {
        position: relative;
        transition: opacity 0.5s ease-in-out;
        &__image {
            width: 100%;
            height: 100%;
        }
        &__loading,
        &__error {
            position: absolute;
            top: $u-image-error-top;
            left: $u-image-error-left;
            width: $u-image-error-width;
            height: $u-image-error-hight;
            @include flex;
            align-items: center;
            justify-content: center;
            background-color: $u-image-error-background-color;
            color: $u-image-error-color;
            font-size: $u-image-error-font-size;
        }
    }
</style>
uni_modules/uview-ui/components/u-index-anchor/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
export default {
    props: {
        // åˆ—表锚点文本内容
        text: {
            type: [String, Number],
            default: uni.$u.props.indexAnchor.text
        },
        // åˆ—表锚点文字颜色
        color: {
            type: String,
            default: uni.$u.props.indexAnchor.color
        },
        // åˆ—表锚点文字大小,单位默认px
        size: {
            type: [String, Number],
            default: uni.$u.props.indexAnchor.size
        },
        // åˆ—表锚点背景颜色
        bgColor: {
            type: String,
            default: uni.$u.props.indexAnchor.bgColor
        },
        // åˆ—表锚点高度,单位默认px
        height: {
            type: [String, Number],
            default: uni.$u.props.indexAnchor.height
        }
    }
}
uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,91 @@
<template>
    <!-- #ifdef APP-NVUE -->
    <header>
    <!-- #endif -->
    <view
        class="u-index-anchor u-border-bottom"
        :ref="`u-index-anchor-${text}`"
        :style="{
            height: $u.addUnit(height),
            backgroundColor: bgColor
        }"
    >
        <text
            class="u-index-anchor__text"
            :style="{
                fontSize: $u.addUnit(size),
                color: color
            }"
        >{{ text }}</text>
    </view>
    <!-- #ifdef APP-NVUE -->
    </header>
    <!-- #endif -->
</template>
<script>
    import props from './props.js';
    // #ifdef APP-NVUE
    const dom = uni.requireNativePlugin('dom')
    // #endif
    /**
     * IndexAnchor åˆ—表锚点
     * @description
     * @tutorial https://uviewui.com/components/indexList.html
     * @property {String | Number}    text    åˆ—表锚点文本内容
     * @property {String}            color    åˆ—表锚点文字颜色 ( é»˜è®¤ '#606266' )
     * @property {String | Number}    size    åˆ—表锚点文字大小,单位默认px ( é»˜è®¤ 14 )
     * @property {String}            bgColor    åˆ—表锚点背景颜色 ( é»˜è®¤ '#dedede' )
     * @property {String | Number}    height    åˆ—表锚点高度,单位默认px ( é»˜è®¤ 32 )
     * @example <u-index-anchor :text="indexList[index]"></u-index-anchor>
     */
    export default {
        name: 'u-index-anchor',
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        data() {
            return {
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                // æ­¤å¤„会活动父组件实例,并赋值给实例的parent属性
                const indexList = uni.$u.$parent.call(this, 'u-index-list')
                if (!indexList) {
                    return uni.$u.error('u-index-anchor必须要搭配u-index-list组件使用')
                }
                // å°†å½“前实例放入到u-index-list中
                indexList.anchors.push(this)
                const indexListItem = uni.$u.$parent.call(this, 'u-index-item')
                // #ifndef APP-NVUE
                // åªæœ‰åœ¨éžnvue下,u-index-anchor才是嵌套在u-index-item中的
                if (!indexListItem) {
                    return uni.$u.error('u-index-anchor必须要搭配u-index-item组件使用')
                }
                // è®¾ç½®u-index-item的id为anchor的text标识符,因为非nvue下滚动列表需要依赖scroll-view滚动到元素的特性
                indexListItem.id = this.text.charCodeAt(0)
                // #endif
            }
        },
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-index-anchor {
        position: sticky;
        top: 0;
        @include flex;
        align-items: center;
        padding-left: 15px;
        z-index: 1;
        &__text {
            @include flex;
            align-items: center;
        }
    }
</style>
uni_modules/uview-ui/components/u-index-item/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
export default {
    props: {
    }
}
uni_modules/uview-ui/components/u-index-item/u-index-item.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,87 @@
<template>
    <!-- #ifdef APP-NVUE -->
    <cell ref="u-index-item">
        <!-- #endif -->
        <view
            class="u-index-item"
            :id="`u-index-item-${id}`"
            :class="[`u-index-item-${id}`]"
        >
            <slot />
        </view>
        <!-- #ifdef APP-NVUE -->
    </cell>
    <!-- #endif -->
</template>
<script>
    import props from './props.js';
    // #ifdef APP-NVUE
    // ç”±äºŽweex为阿里的KPI业绩考核的产物,所以不支持百分比单位,这里需要通过dom查询组件的宽度
    const dom = uni.requireNativePlugin('dom')
    // #endif
    /**
     * IndexItem
     * @description
     * @tutorial https://uviewui.com/components/indexList.html
     * @property {String}
     * @event {Function}
     * @example
     */
    export default {
        name: 'u-index-item',
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        data() {
            return {
                // æœ¬ç»„件到滚动条顶部的距离
                top: 0,
                height: 0,
                id: ''
            }
        },
        created() {
            // å­ç»„ä»¶u-index-anchor的实例
            this.anchor = {}
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                // æ­¤å¤„会活动父组件实例,并赋值给实例的parent属性
                this.getParentData('u-index-list')
                if (!this.parent) {
                    return uni.$u.error('u-index-item必须要搭配u-index-list组件使用')
                }
                uni.$u.sleep().then(() =>{
                    this.getIndexItemRect().then(size => {
                        // ç”±äºŽå¯¹è±¡çš„引用特性,此处会同时生效到父组件的children数组的本实例的top属性中,供父组件判断读取
                        this.top = Math.ceil(size.top)
                        this.height = Math.ceil(size.height)
                    })
                })
            },
            getIndexItemRect() {
                return new Promise(resolve => {
                    // #ifndef APP-NVUE
                    this.$uGetRect('.u-index-item').then(size => {
                        resolve(size)
                    })
                    // #endif
                    // #ifdef APP-NVUE
                    const ref = this.$refs['u-index-item']
                    dom.getComponentRect(ref, res => {
                        resolve(res.size)
                    })
                    // #endif
                })
            }
        },
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
</style>
uni_modules/uview-ui/components/u-index-list/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
export default {
    props: {
        // å³è¾¹é”šç‚¹éžæ¿€æ´»çš„颜色
        inactiveColor: {
            type: String,
            default: uni.$u.props.indexList.inactiveColor
        },
        // å³è¾¹é”šç‚¹æ¿€æ´»çš„颜色
        activeColor: {
            type: String,
            default: uni.$u.props.indexList.activeColor
        },
        // ç´¢å¼•字符列表,数组形式
        indexList: {
            type: Array,
            default: uni.$u.props.indexList.indexList
        },
        // æ˜¯å¦å¼€å¯é”šç‚¹è‡ªåЍ吏顶
        sticky: {
            type: Boolean,
            default: uni.$u.props.indexList.sticky
        },
        // è‡ªå®šä¹‰å¯¼èˆªæ çš„高度
        customNavHeight: {
            type: [String, Number],
            default: uni.$u.props.indexList.customNavHeight
        }
    }
}
uni_modules/uview-ui/components/u-index-list/u-index-list.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,440 @@
<template>
    <view class="u-index-list">
        <!-- #ifdef APP-NVUE -->
        <list
            :scrollTop="scrollTop"
            enable-back-to-top
            :offset-accuracy="1"
            :style="{
                maxHeight: $u.addUnit(scrollViewHeight)
            }"
            @scroll="scrollHandler"
            ref="uList"
        >
            <cell
                v-if="$slots.header"
                ref="header"
            >
                <slot name="header" />
            </cell>
            <slot />
            <cell v-if="$slots.footer">
                <slot name="footer" />
            </cell>
        </list>
        <!-- #endif -->
        <!-- #ifndef APP-NVUE -->
        <scroll-view
            :scrollTop="scrollTop"
            :scrollIntoView="scrollIntoView"
            :offset-accuracy="1"
            :style="{
                maxHeight: $u.addUnit(scrollViewHeight)
            }"
            scroll-y
            @scroll="scrollHandler"
            ref="uList"
        >
            <view v-if="$slots.header">
                <slot name="header" />
            </view>
            <slot />
            <view v-if="$slots.footer">
                <slot name="footer" />
            </view>
        </scroll-view>
        <!-- #endif -->
        <view
            class="u-index-list__letter"
            ref="u-index-list__letter"
            :style="{ top: $u.addUnit(letterInfo.top || 100) }"
            @touchstart="touchStart"
            @touchmove.stop.prevent="touchMove"
            @touchend.stop.prevent="touchEnd"
            @touchcancel.stop.prevent="touchEnd"
        >
            <view
                class="u-index-list__letter__item"
                v-for="(item, index) in uIndexList"
                :key="index"
                :style="{
                    backgroundColor: activeIndex === index ? activeColor : 'transparent'
                }"
            >
                <text
                    class="u-index-list__letter__item__index"
                    :style="{color: activeIndex === index ? '#fff' : inactiveColor}"
                >{{ item }}</text>
            </view>
        </view>
        <u-transition
            mode="fade"
            :show="touching"
            :customStyle="{
                position: 'fixed',
                right: '50px',
                top: $u.addUnit(indicatorTop),
                zIndex: 2
            }"
        >
            <view
                class="u-index-list__indicator"
                :class="['u-index-list__indicator--show']"
                :style="{
                    height: $u.addUnit(indicatorHeight),
                    width: $u.addUnit(indicatorHeight)
                }"
            >
                <text class="u-index-list__indicator__text">{{ uIndexList[activeIndex] }}</text>
            </view>
        </u-transition>
    </view>
</template>
<script>
    const indexList = () => {
        const indexList = [];
        const charCodeOfA = 'A'.charCodeAt(0);
        for (let i = 0; i < 26; i++) {
            indexList.push(String.fromCharCode(charCodeOfA + i));
        }
        return indexList;
    }
    import props from './props.js';
    // #ifdef APP-NVUE
    // ç”±äºŽweex为阿里的KPI业绩考核的产物,所以不支持百分比单位,这里需要通过dom查询组件的宽度
    const dom = uni.requireNativePlugin('dom')
    // #endif
    /**
     * IndexList ç´¢å¼•列表
     * @description  é€šè¿‡æŠ˜å é¢æ¿æ”¶çº³å†…容区域
     * @tutorial https://uviewui.com/components/indexList.html
     * @property {String}            inactiveColor    å³è¾¹é”šç‚¹éžæ¿€æ´»çš„颜色 ( é»˜è®¤ '#606266' )
     * @property {String}            activeColor        å³è¾¹é”šç‚¹æ¿€æ´»çš„颜色 ( é»˜è®¤ '#5677fc' )
     * @property {Array}            indexList        ç´¢å¼•字符列表,数组形式
     * @property {Boolean}            sticky            æ˜¯å¦å¼€å¯é”šç‚¹è‡ªåЍ吏顶 ( é»˜è®¤ true )
     * @property {String | Number}    customNavHeight    è‡ªå®šä¹‰å¯¼èˆªæ çš„高度 ( é»˜è®¤ 0 )
     * */
    export default {
        name: 'u-index-list',
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        // #ifdef MP-WEIXIN
        // å°†è‡ªå®šä¹‰èŠ‚ç‚¹è®¾ç½®æˆè™šæ‹Ÿçš„ï¼Œæ›´åŠ æŽ¥è¿‘Vue组件的表现,能更好的使用flex属性
        options: {
            virtualHost: true
        },
        // #endif
        data() {
            return {
                // å½“前正在被选中的字母索引
                activeIndex: -1,
                touchmoveIndex: 1,
                // ç´¢å¼•字母的信息
                letterInfo: {
                    height: 0,
                    itemHeight: 0,
                    top: 0
                },
                // è®¾ç½®å­—母指示器的高度,后面为了让指示器跟随字母,并将尖角部分指向字母的中部,需要依赖此值
                indicatorHeight: 50,
                // å­—母放大指示器的top值,为了让其指向当前激活的字母
                // indicatorTop: 0
                // å½“前是否正在被触摸状态
                touching: false,
                // æ»šåŠ¨æ¡é¡¶éƒ¨top值
                scrollTop: 0,
                // scroll-view的高度
                scrollViewHeight: 0,
                // ç³»ç»Ÿä¿¡æ¯
                sys: uni.$u.sys(),
                scrolling: false,
                scrollIntoView: '',
            }
        },
        computed: {
            // å¦‚果有传入外部的indexList锚点数组则使用,否则使用内部生成A-Z字母
            uIndexList() {
                return this.indexList.length ? this.indexList : indexList()
            },
            // å­—母放大指示器的top值,为了让其指向当前激活的字母
            indicatorTop() {
                const {
                    top,
                    itemHeight
                } = this.letterInfo
                return Math.floor(top + itemHeight * this.activeIndex + itemHeight / 2 - this.indicatorHeight / 2)
            }
        },
        watch: {
            // ç›‘听字母索引的变化,重新设置尺寸
            uIndexList: {
                immediate: true,
                handler() {
                    uni.$u.sleep().then(() => {
                        this.setIndexListLetterInfo()
                    })
                }
            }
        },
        created() {
            this.children = []
            this.anchors = []
            this.init()
        },
        mounted() {
            this.setIndexListLetterInfo()
        },
        methods: {
            init() {
                // è®¾ç½®åˆ—表的高度为整个屏幕的高度
                //减去this.customNavHeight,并将this.scrollViewHeight设置为maxHeight
                //解决当u-index-list组件放在tabbar页面时,scroll-view内容较少时,还能滚动
                this.scrollViewHeight = this.sys.windowHeight - this.customNavHeight
            },
            // ç´¢å¼•列表被触摸
            touchStart(e) {
                // èŽ·å–è§¦æ‘¸ç‚¹ä¿¡æ¯
                const touchStart = e.changedTouches[0]
                if (!touchStart) return
                this.touching = true
                const {
                    pageY
                } = touchStart
                // æ ¹æ®å½“前触摸点的坐标,获取当前触摸的为第几个字母
                const currentIndex = this.getIndexListLetter(pageY)
                this.setValueForTouch(currentIndex)
            },
            // ç´¢å¼•字母列表被触摸滑动中
            touchMove(e) {
                // èŽ·å–è§¦æ‘¸ç‚¹ä¿¡æ¯
                let touchMove = e.changedTouches[0]
                if (!touchMove) return;
                // æ»‘动结束后迅速开始第二次滑动时候 touching ä¸º false é€ æˆä¸æ˜¾ç¤º indicator é—®é¢˜
                if (!this.touching) {
                    this.touching = true
                }
                const {
                    pageY
                } = touchMove
                const currentIndex = this.getIndexListLetter(pageY)
                this.setValueForTouch(currentIndex)
            },
            // è§¦æ‘¸ç»“束
            touchEnd(e) {
                // å»¶æ—¶ä¸€å®šæ—¶é—´åŽå†éšè—æŒ‡ç¤ºå™¨ï¼Œä¸ºäº†è®©ç”¨æˆ·çœ‹çš„æ›´ç›´è§‚,同时也是为了消除快速切换u-transition的show带来的影响
                uni.$u.sleep(300).then(() => {
                    this.touching = false
                })
            },
            // èŽ·å–ç´¢å¼•åˆ—è¡¨çš„å°ºå¯¸ä»¥åŠå•ä¸ªå­—ç¬¦çš„å°ºå¯¸ä¿¡æ¯
            getIndexListLetterRect() {
                return new Promise(resolve => {
                    // å»¶æ—¶ä¸€å®šæ—¶é—´ï¼Œä»¥èŽ·å–dom尺寸
                    // #ifndef APP-NVUE
                    this.$uGetRect('.u-index-list__letter').then(size => {
                        resolve(size)
                    })
                    // #endif
                    // #ifdef APP-NVUE
                    const ref = this.$refs['u-index-list__letter']
                    dom.getComponentRect(ref, res => {
                        resolve(res.size)
                    })
                    // #endif
                })
            },
            // è®¾ç½®indexList索引的尺寸信息
            setIndexListLetterInfo() {
                this.getIndexListLetterRect().then(size => {
                    const {
                        height
                    } = size
                    const sys = uni.$u.sys()
                    const windowHeight = sys.windowHeight
                    let customNavHeight = 0
                    // æ¶ˆé™¤å„端导航栏非原生和原生导致的差异,让索引列表字母对屏幕垂直居中
                    if (this.customNavHeight == 0) {
                        // #ifdef H5
                        customNavHeight = sys.windowTop
                        // #endif
                        // #ifndef H5
                        // åœ¨éžH5中,为原生导航栏,其高度不算在windowHeight内,这里设置为负值,后面相加时变成减去其高度的一半
                        customNavHeight = -(sys.statusBarHeight + 44)
                        // #endif
                    } else {
                        customNavHeight = uni.$u.getPx(this.customNavHeight)
                    }
                    this.letterInfo = {
                        height,
                        // ä¸ºäº†è®©å­—母列表对屏幕绝对居中,让其对导航栏进行修正,也即往上偏移导航栏的一半高度
                        top: (windowHeight - height) / 2 + customNavHeight / 2,
                        itemHeight: Math.floor(height / this.uIndexList.length)
                    }
                })
            },
            // èŽ·å–å½“å‰è¢«è§¦æ‘¸çš„ç´¢å¼•å­—æ¯
            getIndexListLetter(pageY) {
                const {
                    top,
                    height,
                    itemHeight
                } = this.letterInfo
                // å¯¹H5的pageY进行修正,这是由于uni-app自作多情在H5中将触摸点的坐标跟H5的导航栏结合导致的问题
                // #ifdef H5
                pageY += uni.$u.sys().windowTop
                // #endif
                // å¯¹ç¬¬ä¸€å’Œæœ€åŽä¸€ä¸ªå­—母做边界处理,因为用户可能在字母列表上触摸到两端的尽头后依然继续滑动
                if (pageY < top) {
                    return 0
                } else if (pageY >= top + height) {
                    // å¦‚果超出了,取最后一个字母
                    return this.uIndexList.length - 1
                } else {
                    // å°†è§¦æ‘¸ç‚¹çš„Y轴偏移值,减去索引字母的top值,除以每个字母的高度,即可得到当前触摸点落在哪个字母上
                    return Math.floor((pageY - top) / itemHeight);
                }
            },
            // è®¾ç½®å„项由触摸而导致变化的值
            setValueForTouch(currentIndex) {
                // å¦‚果偏移量太小,前后得出的会是同一个索引字母,为了防抖,进行返回
                if (currentIndex === this.activeIndex) return
                this.activeIndex = currentIndex
                // #ifndef APP-NVUE || MP-WEIXIN
                // åœ¨éžnvue中,由于anchor和item都在u-index-item中,所以需要对index-item进行偏移
                this.scrollIntoView = `u-index-item-${this.uIndexList[currentIndex].charCodeAt(0)}`
                // #endif
                // #ifdef MP-WEIXIN
                // å¾®ä¿¡å°ç¨‹åºä¸‹ï¼Œscroll-view的scroll-into-view属性无法对slot中的内容的id生效,只能通过设置scrollTop的形式去移动滚动条
                this.scrollTop = this.children[currentIndex].top
                // #endif
                // #ifdef APP-NVUE
                // åœ¨nvue中,由于cell和header为同级元素,所以实际是需要对header(anchor)进行偏移
                const anchor = `u-index-anchor-${this.uIndexList[currentIndex]}`
                dom.scrollToElement(this.anchors[currentIndex].$refs[anchor], {
                    offset: 0,
                    animated: false
                })
                // #endif
            },
            getHeaderRect() {
                // èŽ·å–header slot的高度,因为list组件中获取元素的尺寸是没有top值的
                return new Promise(resolve => {
                    dom.getComponentRect(this.$refs.header, res => {
                        resolve(res.size)
                    })
                })
            },
            // scroll-view的滚动事件
            async scrollHandler(e) {
                if (this.touching || this.scrolling) return
                // æ¯è¿‡ä¸€å®šæ—¶é—´å–样一次,减少资源损耗以及可能带来的卡顿
                this.scrolling = true
                uni.$u.sleep(10).then(() => {
                    this.scrolling = false
                })
                let scrollTop = 0
                const len = this.children.length
                let children = this.children
                const anchors = this.anchors
                // #ifdef APP-NVUE
                // nvue下获取的滚动条偏移为负数,需要转为正数
                scrollTop = Math.abs(e.contentOffset.y)
                // èŽ·å–header slot的尺寸信息
                const header = await this.getHeaderRect()
                // item的top值,在nvue下,模拟出的anchor的top,类似非nvue下的index-item的top
                let top = header.height
                // ç”±äºŽlist组件无法获取cell的top值,这里通过header slot和各个item之间的height,模拟出类似非nvue下的位置信息
                children = this.children.map((item, index) => {
                    const child = {
                        height: item.height,
                        top
                    }
                    // è¿›è¡Œç´¯åŠ ï¼Œç»™ä¸‹ä¸€ä¸ªitem提供计算依据
                    top += item.height + anchors[index].height
                    return child
                })
                // #endif
                // #ifndef APP-NVUE
                // éžnvue通过detail获取滚动条位移
                scrollTop = e.detail.scrollTop
                // #endif
                for (let i = 0; i < len; i++) {
                    const item = children[i],
                        nextItem = children[i + 1]
                    // å¦‚果滚动条高度小于第一个item的top值,此时无需设置任意字母为高亮
                    if (scrollTop <= children[0].top || scrollTop >= children[len - 1].top + children[len -
                            1].height) {
                        this.activeIndex = -1
                        break
                    } else if (!nextItem) {
                        // å½“不存在下一个item时,意味着历遍到了最后一个
                        this.activeIndex = len - 1
                        break
                    } else if (scrollTop > item.top && scrollTop < nextItem.top) {
                        this.activeIndex = i
                        break
                    }
                }
            },
        },
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-index-list {
        &__letter {
            position: fixed;
            right: 0;
            text-align: center;
            z-index: 3;
            padding: 0 6px;
            &__item {
                width: 16px;
                height: 16px;
                border-radius: 100px;
                margin: 1px 0;
                @include flex;
                align-items: center;
                justify-content: center;
                &--active {
                    background-color: $u-primary;
                }
                &__index {
                    font-size: 12px;
                    text-align: center;
                    line-height: 12px;
                }
            }
        }
        &__indicator {
            width: 50px;
            height: 50px;
            border-radius: 100px 100px 0 100px;
            text-align: center;
            color: #ffffff;
            background-color: #c9c9c9;
            transform: rotate(-45deg);
            @include flex;
            justify-content: center;
            align-items: center;
            &__text {
                font-size: 28px;
                line-height: 28px;
                font-weight: bold;
                color: #fff;
                transform: rotate(45deg);
                text-align: center;
            }
        }
    }
</style>
uni_modules/uview-ui/components/u-input/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,182 @@
export default {
    props: {
        // è¾“入的值
        value: {
            type: [String, Number],
            default: uni.$u.props.input.value
        },
        // è¾“入框类型
        // number-数字输入键盘,app-vue下可以输入浮点数,app-nvue和小程序平台下只能输入整数
        // idcard-身份证输入键盘,微信、支付宝、百度、QQ小程序
        // digit-带小数点的数字键盘,App的nvue页面、微信、支付宝、百度、头条、QQ小程序
        // text-文本输入键盘
        type: {
            type: String,
            default: uni.$u.props.input.type
        },
        // å¦‚æžœ textarea æ˜¯åœ¨ä¸€ä¸ª position:fixed çš„区域,需要显示指定属性 fixed ä¸º true,
        // å…¼å®¹æ€§ï¼šå¾®ä¿¡å°ç¨‹åºã€ç™¾åº¦å°ç¨‹åºã€å­—节跳动小程序、QQ小程序
        fixed: {
            type: Boolean,
            default: uni.$u.props.input.fixed
        },
        // æ˜¯å¦ç¦ç”¨è¾“入框
        disabled: {
            type: Boolean,
            default: uni.$u.props.input.disabled
        },
        // ç¦ç”¨çŠ¶æ€æ—¶çš„èƒŒæ™¯è‰²
        disabledColor: {
            type: String,
            default: uni.$u.props.input.disabledColor
        },
        // æ˜¯å¦æ˜¾ç¤ºæ¸…除控件
        clearable: {
            type: Boolean,
            default: uni.$u.props.input.clearable
        },
        // æ˜¯å¦å¯†ç ç±»åž‹
        password: {
            type: Boolean,
            default: uni.$u.props.input.password
        },
        // æœ€å¤§è¾“入长度,设置为 -1 çš„æ—¶å€™ä¸é™åˆ¶æœ€å¤§é•¿åº¦
        maxlength: {
            type: [String, Number],
            default: uni.$u.props.input.maxlength
        },
        //     è¾“入框为空时的占位符
        placeholder: {
            type: String,
            default: uni.$u.props.input.placeholder
        },
        // æŒ‡å®šplaceholder的样式类,注意页面或组件的style中写了scoped时,需要在类名前写/deep/
        placeholderClass: {
            type: String,
            default: uni.$u.props.input.placeholderClass
        },
        // æŒ‡å®šplaceholder的样式
        placeholderStyle: {
            type: [String, Object],
            default: uni.$u.props.input.placeholderStyle
        },
        // æ˜¯å¦æ˜¾ç¤ºè¾“入字数统计,只在 type ="text"或type ="textarea"时有效
        showWordLimit: {
            type: Boolean,
            default: uni.$u.props.input.showWordLimit
        },
        // è®¾ç½®å³ä¸‹è§’按钮的文字,有效值:send|search|next|go|done,兼容性详见uni-app文档
        // https://uniapp.dcloud.io/component/input
        // https://uniapp.dcloud.io/component/textarea
        confirmType: {
            type: String,
            default: uni.$u.props.input.confirmType
        },
        // ç‚¹å‡»é”®ç›˜å³ä¸‹è§’按钮时是否保持键盘不收起,H5无效
        confirmHold: {
            type: Boolean,
            default: uni.$u.props.input.confirmHold
        },
        // focus时,点击页面的时候不收起键盘,微信小程序有效
        holdKeyboard: {
            type: Boolean,
            default: uni.$u.props.input.holdKeyboard
        },
        // è‡ªåŠ¨èŽ·å–ç„¦ç‚¹
        // åœ¨ H5 å¹³å°èƒ½å¦èšç„¦ä»¥åŠè½¯é”®ç›˜æ˜¯å¦è·Ÿéšå¼¹å‡ºï¼Œå–决于当前浏览器本身的实现。nvue é¡µé¢ä¸æ”¯æŒï¼Œéœ€ä½¿ç”¨ç»„ä»¶çš„ focus()、blur() æ–¹æ³•控制焦点
        focus: {
            type: Boolean,
            default: uni.$u.props.input.focus
        },
        // é”®ç›˜æ”¶èµ·æ—¶ï¼Œæ˜¯å¦è‡ªåŠ¨å¤±åŽ»ç„¦ç‚¹ï¼Œç›®å‰ä»…App3.0.0+有效
        autoBlur: {
            type: Boolean,
            default: uni.$u.props.input.autoBlur
        },
        // æ˜¯å¦åŽ»æŽ‰ iOS ä¸‹çš„默认内边距,仅微信小程序,且type=textarea时有效
        disableDefaultPadding: {
            type: Boolean,
            default: uni.$u.props.input.disableDefaultPadding
        },
        // æŒ‡å®šfocus时光标的位置
        cursor: {
            type: [String, Number],
            default: uni.$u.props.input.cursor
        },
        // è¾“入框聚焦时底部与键盘的距离
        cursorSpacing: {
            type: [String, Number],
            default: uni.$u.props.input.cursorSpacing
        },
        // å…‰æ ‡èµ·å§‹ä½ç½®ï¼Œè‡ªåŠ¨èšé›†æ—¶æœ‰æ•ˆï¼Œéœ€ä¸Žselection-end搭配使用
        selectionStart: {
            type: [String, Number],
            default: uni.$u.props.input.selectionStart
        },
        // å…‰æ ‡ç»“束位置,自动聚集时有效,需与selection-start搭配使用
        selectionEnd: {
            type: [String, Number],
            default: uni.$u.props.input.selectionEnd
        },
        // é”®ç›˜å¼¹èµ·æ—¶ï¼Œæ˜¯å¦è‡ªåŠ¨ä¸ŠæŽ¨é¡µé¢
        adjustPosition: {
            type: Boolean,
            default: uni.$u.props.input.adjustPosition
        },
        // è¾“入框内容对齐方式,可选值为:left|center|right
        inputAlign: {
            type: String,
            default: uni.$u.props.input.inputAlign
        },
        // è¾“入框字体的大小
        fontSize: {
            type: [String, Number],
            default: uni.$u.props.input.fontSize
        },
        // è¾“入框字体颜色
        color: {
            type: String,
            default: uni.$u.props.input.color
        },
        // è¾“入框前置图标
        prefixIcon: {
            type: String,
            default: uni.$u.props.input.prefixIcon
        },
        // å‰ç½®å›¾æ ‡æ ·å¼ï¼Œå¯¹è±¡æˆ–字符串
        prefixIconStyle: {
            type: [String, Object],
            default: uni.$u.props.input.prefixIconStyle
        },
        // è¾“入框后置图标
        suffixIcon: {
            type: String,
            default: uni.$u.props.input.suffixIcon
        },
        // åŽç½®å›¾æ ‡æ ·å¼ï¼Œå¯¹è±¡æˆ–字符串
        suffixIconStyle: {
            type: [String, Object],
            default: uni.$u.props.input.suffixIconStyle
        },
        // è¾¹æ¡†ç±»åž‹ï¼Œsurround-四周边框,bottom-底部边框,none-无边框
        border: {
            type: String,
            default: uni.$u.props.input.border
        },
        // æ˜¯å¦åªè¯»ï¼Œä¸Ždisabled不同之处在于disabled会置灰组件,而readonly则不会
        readonly: {
            type: Boolean,
            default: uni.$u.props.input.readonly
        },
        // è¾“入框形状,circle-圆形,square-方形
        shape: {
            type: String,
            default: uni.$u.props.input.shape
        },
        // ç”¨äºŽå¤„理或者过滤输入框内容的方法
        formatter: {
            type: [Function, null],
            default: uni.$u.props.input.formatter
        }
    }
}
uni_modules/uview-ui/components/u-input/u-input.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,353 @@
<template>
    <view class="u-input" :class="inputClass" :style="[wrapperStyle]">
        <view class="u-input__content">
            <view
                class="u-input__content__prefix-icon"
                v-if="prefixIcon || $slots.prefix"
            >
                <slot name="prefix">
                    <u-icon
                        :name="prefixIcon"
                        size="18"
                        :customStyle="prefixIconStyle"
                    ></u-icon>
                </slot>
            </view>
            <view class="u-input__content__field-wrapper" @tap="clickHandler">
                <!-- æ ¹æ®uni-app的input组件文档,H5和APP中只要声明了password参数(无论true还是false),type均失效,此时
                    ä¸ºäº†é˜²æ­¢type=number时,又存在password属性,type无效,此时需要设置password为undefined
                 -->
                <input
                    class="u-input__content__field-wrapper__field"
                    :style="[inputStyle]"
                    :type="type"
                    :focus="focus"
                    :cursor="cursor"
                    :value="innerValue"
                    :auto-blur="autoBlur"
                    :disabled="disabled || readonly"
                    :maxlength="maxlength"
                    :placeholder="placeholder"
                    :placeholder-style="placeholderStyle"
                    :placeholder-class="placeholderClass"
                    :confirm-type="confirmType"
                    :confirm-hold="confirmHold"
                    :hold-keyboard="holdKeyboard"
                    :cursor-spacing="cursorSpacing"
                    :adjust-position="adjustPosition"
                    :selection-end="selectionEnd"
                    :selection-start="selectionStart"
                    :password="password || type === 'password' || undefined"
                    @input="onInput"
                    @blur="onBlur"
                    @focus="onFocus"
                    @confirm="onConfirm"
                    @keyboardheightchange="onkeyboardheightchange"
                />
            </view>
            <view
                class="u-input__content__clear"
                v-if="isShowClear"
                @tap="onClear"
            >
                <u-icon
                    name="close"
                    size="11"
                    color="#ffffff"
                    customStyle="line-height: 12px"
                ></u-icon>
            </view>
            <view
                class="u-input__content__subfix-icon"
                v-if="suffixIcon || $slots.suffix"
            >
                <slot name="suffix">
                    <u-icon
                        :name="suffixIcon"
                        size="18"
                        :customStyle="suffixIconStyle"
                    ></u-icon>
                </slot>
            </view>
        </view>
    </view>
</template>
<script>
import props from "./props.js";
/**
 * Input è¾“入框
 * @description  æ­¤ç»„件为一个输入框,默认没有边框和样式,是专门为配合表单组件u-form而设计的,利用它可以快速实现表单验证,输入内容,下拉选择等功能。
 * @tutorial https://uviewui.com/components/input.html
 * @property {String | Number}    value                    è¾“入的值
 * @property {String}            type                    è¾“入框类型,见上方说明 ï¼ˆ é»˜è®¤ 'text' ï¼‰
 * @property {Boolean}            fixed                    å¦‚æžœ textarea æ˜¯åœ¨ä¸€ä¸ª position:fixed çš„区域,需要显示指定属性 fixed ä¸º true,兼容性:微信小程序、百度小程序、字节跳动小程序、QQ小程序 ï¼ˆ é»˜è®¤ false ï¼‰
 * @property {Boolean}            disabled                æ˜¯å¦ç¦ç”¨è¾“入框 ï¼ˆ é»˜è®¤ false ï¼‰
 * @property {String}            disabledColor            ç¦ç”¨çŠ¶æ€æ—¶çš„èƒŒæ™¯è‰²ï¼ˆ é»˜è®¤ '#f5f7fa' ï¼‰
 * @property {Boolean}            clearable                æ˜¯å¦æ˜¾ç¤ºæ¸…除控件 ï¼ˆ é»˜è®¤ false ï¼‰
 * @property {Boolean}            password                æ˜¯å¦å¯†ç ç±»åž‹ ï¼ˆ é»˜è®¤ false ï¼‰
 * @property {String | Number}    maxlength                æœ€å¤§è¾“入长度,设置为 -1 çš„æ—¶å€™ä¸é™åˆ¶æœ€å¤§é•¿åº¦ ï¼ˆ é»˜è®¤ -1 ï¼‰
 * @property {String}            placeholder                è¾“入框为空时的占位符
 * @property {String}            placeholderClass        æŒ‡å®šplaceholder的样式类,注意页面或组件的style中写了scoped时,需要在类名前写/deep/ ï¼ˆ é»˜è®¤ 'input-placeholder' ï¼‰
 * @property {String | Object}    placeholderStyle        æŒ‡å®šplaceholder的样式,字符串/对象形式,如"color: red;"
 * @property {Boolean}            showWordLimit            æ˜¯å¦æ˜¾ç¤ºè¾“入字数统计,只在 type ="text"或type ="textarea"时有效 ï¼ˆ é»˜è®¤ false ï¼‰
 * @property {String}            confirmType                è®¾ç½®å³ä¸‹è§’按钮的文字,兼容性详见uni-app文档 ï¼ˆ é»˜è®¤ 'done' ï¼‰
 * @property {Boolean}            confirmHold                ç‚¹å‡»é”®ç›˜å³ä¸‹è§’按钮时是否保持键盘不收起,H5无效 ï¼ˆ é»˜è®¤ false ï¼‰
 * @property {Boolean}            holdKeyboard            focus时,点击页面的时候不收起键盘,微信小程序有效 ï¼ˆ é»˜è®¤ false ï¼‰
 * @property {Boolean}            focus                    è‡ªåŠ¨èŽ·å–ç„¦ç‚¹ï¼Œåœ¨ H5 å¹³å°èƒ½å¦èšç„¦ä»¥åŠè½¯é”®ç›˜æ˜¯å¦è·Ÿéšå¼¹å‡ºï¼Œå–决于当前浏览器本身的实现。nvue é¡µé¢ä¸æ”¯æŒï¼Œéœ€ä½¿ç”¨ç»„ä»¶çš„ focus()、blur() æ–¹æ³•控制焦点 ï¼ˆ é»˜è®¤ false ï¼‰
 * @property {Boolean}            autoBlur                é”®ç›˜æ”¶èµ·æ—¶ï¼Œæ˜¯å¦è‡ªåŠ¨å¤±åŽ»ç„¦ç‚¹ï¼Œç›®å‰ä»…App3.0.0+有效 ï¼ˆ é»˜è®¤ false ï¼‰
 * @property {Boolean}            disableDefaultPadding    æ˜¯å¦åŽ»æŽ‰ iOS ä¸‹çš„默认内边距,仅微信小程序,且type=textarea时有效 ï¼ˆ é»˜è®¤ false ï¼‰
 * @property {String ï½œ Number}    cursor                    æŒ‡å®šfocus时光标的位置( é»˜è®¤ -1 ï¼‰
 * @property {String ï½œ Number}    cursorSpacing            è¾“入框聚焦时底部与键盘的距离 ï¼ˆ é»˜è®¤ 30 ï¼‰
 * @property {String ï½œ Number}    selectionStart            å…‰æ ‡èµ·å§‹ä½ç½®ï¼Œè‡ªåŠ¨èšé›†æ—¶æœ‰æ•ˆï¼Œéœ€ä¸Žselection-end搭配使用 ï¼ˆ é»˜è®¤ -1 ï¼‰
 * @property {String ï½œ Number}    selectionEnd            å…‰æ ‡ç»“束位置,自动聚集时有效,需与selection-start搭配使用 ï¼ˆ é»˜è®¤ -1 ï¼‰
 * @property {Boolean}            adjustPosition            é”®ç›˜å¼¹èµ·æ—¶ï¼Œæ˜¯å¦è‡ªåŠ¨ä¸ŠæŽ¨é¡µé¢ ï¼ˆ é»˜è®¤ true ï¼‰
 * @property {String}            inputAlign                è¾“入框内容对齐方式( é»˜è®¤ 'left' ï¼‰
 * @property {String | Number}    fontSize                è¾“入框字体的大小 ï¼ˆ é»˜è®¤ '15px' ï¼‰
 * @property {String}            color                    è¾“入框字体颜色    ï¼ˆ é»˜è®¤ '#303133' ï¼‰
 * @property {Function}            formatter                å†…容式化函数
 * @property {String}            prefixIcon                è¾“入框前置图标
 * @property {String | Object}    prefixIconStyle            å‰ç½®å›¾æ ‡æ ·å¼ï¼Œå¯¹è±¡æˆ–字符串
 * @property {String}            suffixIcon                è¾“入框后置图标
 * @property {String | Object}    suffixIconStyle            åŽç½®å›¾æ ‡æ ·å¼ï¼Œå¯¹è±¡æˆ–字符串
 * @property {String}            border                    è¾¹æ¡†ç±»åž‹ï¼Œsurround-四周边框,bottom-底部边框,none-无边框 ï¼ˆ é»˜è®¤ 'surround' ï¼‰
 * @property {Boolean}            readonly                æ˜¯å¦åªè¯»ï¼Œä¸Ždisabled不同之处在于disabled会置灰组件,而readonly则不会 ï¼ˆ é»˜è®¤ false ï¼‰
 * @property {String}            shape                    è¾“入框形状,circle-圆形,square-方形 ï¼ˆ é»˜è®¤ 'square' ï¼‰
 * @property {Object}            customStyle                å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
 *
 * @example <u-input v-model="value" :password="true" suffix-icon="lock-fill" />
 */
export default {
    name: "u-input",
    mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
    data() {
        return {
            // è¾“入框的值
            innerValue: "",
            // æ˜¯å¦å¤„于获得焦点状态
            focused: false,
            // value是否第一次变化,在watch中,由于加入immediate属性,会在第一次触发,此时不应该认为value发生了变化
            firstChange: true,
            // value绑定值的变化是由内部还是外部引起的
            changeFromInner: false,
            // è¿‡æ»¤å¤„理方法
            innerFormatter: value => value
        };
    },
    watch: {
        value: {
            immediate: true,
            handler(newVal, oldVal) {
                this.innerValue = newVal;
                /* #ifdef H5 */
                // åœ¨H5中,外部value变化后,修改input中的值,不会触发@input事件,此时手动调用值变化方法
                if (
                    this.firstChange === false &&
                    this.changeFromInner === false
                ) {
                    this.valueChange();
                }
                /* #endif */
                this.firstChange = false;
                // é‡ç½®changeFromInner的值为false,标识下一次引起默认为外部引起的
                this.changeFromInner = false;
            },
        },
    },
    computed: {
        // æ˜¯å¦æ˜¾ç¤ºæ¸…除控件
        isShowClear() {
            const { clearable, readonly, focused, innerValue } = this;
            return !!clearable && !readonly && !!focused && innerValue !== "";
        },
        // ç»„件的类名
        inputClass() {
            let classes = [],
                { border, disabled, shape } = this;
            border === "surround" &&
                (classes = classes.concat(["u-border", "u-input--radius"]));
            classes.push(`u-input--${shape}`);
            border === "bottom" &&
                (classes = classes.concat([
                    "u-border-bottom",
                    "u-input--no-radius",
                ]));
            return classes.join(" ");
        },
        // ç»„件的样式
        wrapperStyle() {
            const style = {};
            // ç¦ç”¨çŠ¶æ€ä¸‹ï¼Œè¢«èƒŒæ™¯è‰²åŠ ä¸Šå¯¹åº”çš„æ ·å¼
            if (this.disabled) {
                style.backgroundColor = this.disabledColor;
            }
            // æ— è¾¹æ¡†æ—¶ï¼ŒåŽ»é™¤å†…è¾¹è·
            if (this.border === "none") {
                style.padding = "0";
            } else {
                // ç”±äºŽuni-app的iOS开发者能力有限,导致需要分开写才有效
                style.paddingTop = "6px";
                style.paddingBottom = "6px";
                style.paddingLeft = "9px";
                style.paddingRight = "9px";
            }
            return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle));
        },
        // è¾“入框的样式
        inputStyle() {
            const style = {
                color: this.color,
                fontSize: uni.$u.addUnit(this.fontSize),
                textAlign: this.inputAlign
            };
            return style;
        },
    },
    methods: {
        // åœ¨å¾®ä¿¡å°ç¨‹åºä¸­ï¼Œä¸æ”¯æŒå°†å‡½æ•°å½“做props参数,故只能通过ref形式调用
        setFormatter(e) {
            this.innerFormatter = e
        },
        // å½“键盘输入时,触发input事件
        onInput(e) {
            let { value = "" } = e.detail || {};
            // æ ¼å¼åŒ–过滤方法
            const formatter = this.formatter || this.innerFormatter
            const formatValue = formatter(value)
            // ä¸ºäº†é¿å…props的单向数据流特性,需要先将innerValue值设置为当前值,再在$nextTick中重新赋予设置后的值才有效
            this.innerValue = value
            this.$nextTick(() => {
                this.innerValue = formatValue;
                this.valueChange();
            })
        },
        // è¾“入框失去焦点时触发
        onBlur(event) {
            this.$emit("blur", event.detail.value);
            // H5端的blur会先于点击清除控件的点击click事件触发,导致focused
            // çž¬é—´ä¸ºfalse,从而隐藏了清除控件而无法被点击到
            uni.$u.sleep(50).then(() => {
                this.focused = false;
            });
            // å°è¯•调用u-form的验证方法
            uni.$u.formValidate(this, "blur");
        },
        // è¾“入框聚焦时触发
        onFocus(event) {
            this.focused = true;
            this.$emit("focus");
        },
        // ç‚¹å‡»å®ŒæˆæŒ‰é’®æ—¶è§¦å‘
        onConfirm(event) {
            this.$emit("confirm", this.innerValue);
        },
        // é”®ç›˜é«˜åº¦å‘生变化的时候触发此事件
        // å…¼å®¹æ€§ï¼šå¾®ä¿¡å°ç¨‹åº2.7.0+、App 3.1.0+
        onkeyboardheightchange() {
            this.$emit("keyboardheightchange");
        },
        // å†…容发生变化,进行处理
        valueChange() {
            const value = this.innerValue;
            this.$nextTick(() => {
                this.$emit("input", value);
                // æ ‡è¯†value值的变化是由内部引起的
                this.changeFromInner = true;
                this.$emit("change", value);
                // å°è¯•调用u-form的验证方法
                uni.$u.formValidate(this, "change");
            });
        },
        // ç‚¹å‡»æ¸…除控件
        onClear() {
            this.innerValue = "";
            this.$nextTick(() => {
                this.valueChange();
                this.$emit("clear");
            });
        },
        /**
         * åœ¨å®‰å“nvue上,事件无法冒泡
         * åœ¨æŸäº›æ—¶é—´ï¼Œæˆ‘们希望监听u-from-item的点击事件,此时会导致点击u-form-item内的u-input后
         * æ— æ³•触发u-form-item的点击事件,这里通过手动调用u-form-item的方法进行触发
         */
        clickHandler() {
            // #ifdef APP-NVUE
            if (uni.$u.os() === "android") {
                const formItem = uni.$u.$parent.call(this, "u-form-item");
                if (formItem) {
                    formItem.clickHandler();
                }
            }
            // #endif
        },
    },
};
</script>
<style lang="scss" scoped>
@import "../../libs/css/components.scss";
.u-input {
    @include flex(row);
    align-items: center;
    justify-content: space-between;
    flex: 1;
    &--radius,
    &--square {
        border-radius: 4px;
    }
    &--no-radius {
        border-radius: 0;
    }
    &--circle {
        border-radius: 100px;
    }
    &__content {
        flex: 1;
        @include flex(row);
        align-items: center;
        justify-content: space-between;
        &__field-wrapper {
            position: relative;
            @include flex(row);
            margin: 0;
            flex: 1;
            &__field {
                line-height: 26px;
                text-align: left;
                color: $u-main-color;
                height: 24px;
                font-size: 15px;
                flex: 1;
            }
        }
        &__clear {
            width: 20px;
            height: 20px;
            border-radius: 100px;
            background-color: #c6c7cb;
            @include flex(row);
            align-items: center;
            justify-content: center;
            transform: scale(0.82);
            margin-left: 4px;
        }
        &__subfix-icon {
            margin-left: 4px;
        }
        &__prefix-icon {
            margin-right: 4px;
        }
    }
}
</style>
uni_modules/uview-ui/components/u-keyboard/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,84 @@
export default {
    props: {
        // é”®ç›˜çš„类型,number-数字键盘,card-身份证键盘,car-车牌号键盘
        mode: {
            type: String,
            default: uni.$u.props.keyboard.mode
        },
        // æ˜¯å¦æ˜¾ç¤ºé”®ç›˜çš„"."符号
        dotDisabled: {
            type: Boolean,
            default: uni.$u.props.keyboard.dotDisabled
        },
        // æ˜¯å¦æ˜¾ç¤ºé¡¶éƒ¨å·¥å…·æ¡
        tooltip: {
            type: Boolean,
            default: uni.$u.props.keyboard.tooltip
        },
        // æ˜¯å¦æ˜¾ç¤ºå·¥å…·æ¡ä¸­é—´çš„æç¤º
        showTips: {
            type: Boolean,
            default: uni.$u.props.keyboard.showTips
        },
        // å·¥å…·æ¡ä¸­é—´çš„æç¤ºæ–‡å­—
        tips: {
            type: String,
            default: uni.$u.props.keyboard.tips
        },
        // æ˜¯å¦æ˜¾ç¤ºå·¥å…·æ¡å·¦è¾¹çš„"取消"按钮
        showCancel: {
            type: Boolean,
            default: uni.$u.props.keyboard.showCancel
        },
        // æ˜¯å¦æ˜¾ç¤ºå·¥å…·æ¡å³è¾¹çš„"完成"按钮
        showConfirm: {
            type: Boolean,
            default: uni.$u.props.keyboard.showConfirm
        },
        // æ˜¯å¦æ‰“乱键盘按键的顺序
        random: {
            type: Boolean,
            default: uni.$u.props.keyboard.random
        },
        // æ˜¯å¦å¼€å¯åº•部安全区适配,开启的话,会在iPhoneX机型底部添加一定的内边距
        safeAreaInsetBottom: {
            type: Boolean,
            default: uni.$u.props.keyboard.safeAreaInsetBottom
        },
        // æ˜¯å¦å…è®¸é€šè¿‡ç‚¹å‡»é®ç½©å…³é—­é”®ç›˜
        closeOnClickOverlay: {
            type: Boolean,
            default: uni.$u.props.keyboard.closeOnClickOverlay
        },
        // æŽ§åˆ¶é”®ç›˜çš„弹出与收起
        show: {
            type: Boolean,
            default: uni.$u.props.keyboard.show
        },
        // æ˜¯å¦æ˜¾ç¤ºé®ç½©ï¼ŒæŸäº›æ—¶å€™æ•°å­—键盘时,用户希望看到自己的数值,所以可能不想要遮罩
        overlay: {
            type: Boolean,
            default: uni.$u.props.keyboard.overlay
        },
        // z-index值
        zIndex: {
            type: [String, Number],
            default: uni.$u.props.keyboard.zIndex
        },
        // å–消按钮的文字
        cancelText: {
            type: String,
            default: uni.$u.props.keyboard.cancelText
        },
        // ç¡®è®¤æŒ‰é’®çš„æ–‡å­—
        confirmText: {
            type: String,
            default: uni.$u.props.keyboard.confirmText
        },
        // è¾“入一个中文后,是否自动切换到英文
        autoChange: {
            type: Boolean,
            default: uni.$u.props.keyboard.autoChange
        }
    }
}
uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,164 @@
<template>
    <u-popup
        :overlay="overlay"
        :closeOnClickOverlay="closeOnClickOverlay"
        mode="bottom"
        :popup="false"
        :show="show"
        :safeAreaInsetBottom="safeAreaInsetBottom"
        @close="popupClose"
        :zIndex="zIndex"
        :customStyle="{
            backgroundColor: 'rgb(214, 218, 220)'
        }"
    >
        <view class="u-keyboard">
            <slot />
            <view
                class="u-keyboard__tooltip"
                v-if="tooltip"
            >
                <view
                    hover-class="u-hover-class"
                    :hover-stay-time="100"
                >
                    <text
                        class="u-keyboard__tooltip__item u-keyboard__tooltip__cancel"
                        v-if="showCancel"
                        @tap="onCancel"
                    >{{showCancel && cancelText}}</text>
                </view>
                <view>
                    <text
                        v-if="showTips"
                        class="u-keyboard__tooltip__item u-keyboard__tooltip__tips"
                    >{{tips ? tips : mode == 'number' ? '数字键盘' : mode == 'card' ? '身份证键盘' : '车牌号键盘'}}</text>
                </view>
                <view
                    hover-class="u-hover-class"
                    :hover-stay-time="100"
                >
                    <text
                        v-if="showConfirm"
                        @tap="onConfirm"
                        class="u-keyboard__tooltip__item u-keyboard__tooltip__submit"
                        hover-class="u-hover-class"
                    >{{showConfirm && confirmText}}</text>
                </view>
            </view>
            <template v-if="mode == 'number' || mode == 'card'">
                <u-number-keyboard
                    :random="random"
                    @backspace="backspace"
                    @change="change"
                    :mode="mode"
                    :dotDisabled="dotDisabled"
                ></u-number-keyboard>
            </template>
            <template v-else>
                <u-car-keyboard
                    :random="random"
                    :autoChange="autoChange"
                    @backspace="backspace"
                    @change="change"
                ></u-car-keyboard>
            </template>
        </view>
    </u-popup>
</template>
<script>
    import props from './props.js';
    /**
     * keyboard é”®ç›˜
     * @description æ­¤ä¸ºuViw自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3中模式,都有可以打乱按键顺序的选项。
     * @tutorial https://www.uviewui.com/components/keyboard.html
     * @property {String}            mode                é”®ç›˜ç±»åž‹ï¼Œè§å®˜ç½‘基本使用的说明 ï¼ˆé»˜è®¤ 'number' ï¼‰
     * @property {Boolean}            dotDisabled            æ˜¯å¦æ˜¾ç¤º"."按键,只在mode=number时有效 ï¼ˆé»˜è®¤ false ï¼‰
     * @property {Boolean}            tooltip                æ˜¯å¦æ˜¾ç¤ºé”®ç›˜é¡¶éƒ¨å·¥å…·æ¡ ï¼ˆé»˜è®¤ true ï¼‰
     * @property {Boolean}            showTips            æ˜¯å¦æ˜¾ç¤ºå·¥å…·æ¡ä¸­é—´çš„æç¤º ï¼ˆé»˜è®¤ true ï¼‰
     * @property {String}            tips                å·¥å…·æ¡ä¸­é—´çš„æç¤ºæ–‡å­—,见上方基本使用的说明,如不需要,请传""空字符
     * @property {Boolean}            showCancel            æ˜¯å¦æ˜¾ç¤ºå·¥å…·æ¡å·¦è¾¹çš„"取消"按钮 ï¼ˆé»˜è®¤ true ï¼‰
     * @property {Boolean}            showConfirm            æ˜¯å¦æ˜¾ç¤ºå·¥å…·æ¡å³è¾¹çš„"完成"按钮( é»˜è®¤ true ï¼‰
     * @property {Boolean}            random                æ˜¯å¦æ‰“乱键盘按键的顺序 ï¼ˆé»˜è®¤ false ï¼‰
     * @property {Boolean}            safeAreaInsetBottom    æ˜¯å¦å¼€å¯åº•部安全区适配 ï¼ˆé»˜è®¤ true ï¼‰
     * @property {Boolean}            closeOnClickOverlay    æ˜¯å¦å…è®¸ç‚¹å‡»é®ç½©æ”¶èµ·é”®ç›˜ ï¼ˆé»˜è®¤ true ï¼‰
     * @property {Boolean}            show                æŽ§åˆ¶é”®ç›˜çš„弹出与收起(默认 false ï¼‰
     * @property {Boolean}            overlay                æ˜¯å¦æ˜¾ç¤ºé®ç½© ï¼ˆé»˜è®¤ true ï¼‰
     * @property {String | Number}    zIndex                å¼¹å‡ºé”®ç›˜çš„z-index值 ï¼ˆé»˜è®¤ 1075 ï¼‰
     * @property {String}            cancelText            å–消按钮的文字 ï¼ˆé»˜è®¤ '取消' ï¼‰
     * @property {String}            confirmText            ç¡®è®¤æŒ‰é’®çš„æ–‡å­— ï¼ˆé»˜è®¤ '确认' ï¼‰
     * @property {Object}            customStyle            è‡ªå®šä¹‰æ ·å¼ï¼Œå¯¹è±¡å½¢å¼
     * @event {Function} change æŒ‰é”®è¢«ç‚¹å‡»(不包含退格键被点击)
     * @event {Function} cancel é”®ç›˜é¡¶éƒ¨å·¥å…·æ¡å·¦è¾¹çš„"取消"按钮被点击
     * @event {Function} confirm é”®ç›˜é¡¶éƒ¨å·¥å…·æ¡å³è¾¹çš„"完成"按钮被点击
     * @event {Function} backspace é”®ç›˜é€€æ ¼é”®è¢«ç‚¹å‡»
     * @example <u-keyboard mode="number" v-model="show"></u-keyboard>
     */
    export default {
        name: "u-keyboard",
        data() {
            return {
            }
        },
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        methods: {
            change(e) {
                this.$emit('change', e);
            },
            // é”®ç›˜å…³é—­
            popupClose() {
                this.$emit('close');
            },
            // è¾“入完成
            onConfirm() {
                this.$emit('confirm');
            },
            // å–消输入
            onCancel() {
                this.$emit('cancel');
            },
            // é€€æ ¼é”®
            backspace() {
                this.$emit('backspace');
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-keyboard {
        &__tooltip {
            @include flex;
            justify-content: space-between;
            background-color: #FFFFFF;
            padding: 14px 12px;
            &__item {
                color: #333333;
                flex: 1;
                text-align: center;
                font-size: 15px;
            }
            &__submit {
                text-align: right;
                color: $u-primary;
            }
            &__cancel {
                text-align: left;
                color: #888888;
            }
            &__tips {
                color: $u-tips-color;
            }
        }
    }
</style>
uni_modules/uview-ui/components/u-line-progress/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
export default {
    props: {
        // æ¿€æ´»éƒ¨åˆ†çš„颜色
        activeColor: {
            type: String,
            default: uni.$u.props.lineProgress.activeColor
        },
        inactiveColor: {
            type: String,
            default: uni.$u.props.lineProgress.color
        },
        // è¿›åº¦ç™¾åˆ†æ¯”,数值
        percentage: {
            type: [String, Number],
            default: uni.$u.props.lineProgress.inactiveColor
        },
        // æ˜¯å¦åœ¨è¿›åº¦æ¡å†…部显示百分比的值
        showText: {
            type: Boolean,
            default: uni.$u.props.lineProgress.showText
        },
        // è¿›åº¦æ¡çš„高度,单位px
        height: {
            type: [String, Number],
            default: uni.$u.props.lineProgress.height
        }
    }
}
uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,144 @@
<template>
    <view
        class="u-line-progress"
        :style="[$u.addStyle(customStyle)]"
    >
        <view
            class="u-line-progress__background"
            ref="u-line-progress__background"
            :style="[{
                backgroundColor: inactiveColor,
                height: $u.addUnit(height),
            }]"
        >
        </view>
        <view
            class="u-line-progress__line"
            :style="[progressStyle]"
        >
            <slot>
                <text v-if="showText && percentage >= 10" class="u-line-progress__text">{{innserPercentage + '%'}}</text>
            </slot>
        </view>
    </view>
</template>
<script>
    import props from './props.js';
    // #ifdef APP-NVUE
    const dom = uni.requireNativePlugin('dom')
    // #endif
    /**
     * lineProgress çº¿åž‹è¿›åº¦æ¡
     * @description å±•示操作或任务的当前进度,比如上传文件,是一个线形的进度条。
     * @tutorial https://www.uviewui.com/components/lineProgress.html
     * @property {String}            activeColor        æ¿€æ´»éƒ¨åˆ†çš„颜色 ( é»˜è®¤ '#19be6b' )
     * @property {String}            inactiveColor    èƒŒæ™¯è‰² ( é»˜è®¤ '#ececec' )
     * @property {String | Number}    percentage        è¿›åº¦ç™¾åˆ†æ¯”,数值 ( é»˜è®¤ 0 )
     * @property {Boolean}            showText        æ˜¯å¦åœ¨è¿›åº¦æ¡å†…部显示百分比的值 ( é»˜è®¤ true )
     * @property {String | Number}    height            è¿›åº¦æ¡çš„高度,单位px ( é»˜è®¤ 12 )
     *
     * @example <u-line-progress :percent="70" :show-percent="true"></u-line-progress>
     */
    export default {
        name: "u-line-progress",
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        data() {
            return {
                lineWidth: 0,
            }
        },
        watch: {
            percentage(n) {
                this.resizeProgressWidth()
            }
        },
        computed: {
            progressStyle() {
                let style = {}
                style.width = this.lineWidth
                style.backgroundColor = this.activeColor
                style.height = uni.$u.addUnit(this.height)
                return style
            },
            innserPercentage() {
                // æŽ§åˆ¶èŒƒå›´åœ¨0-100之间
                return uni.$u.range(0, 100, this.percentage)
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                uni.$u.sleep(20).then(() => {
                    this.resizeProgressWidth()
                })
            },
            getProgressWidth() {
                // #ifndef APP-NVUE
                return this.$uGetRect('.u-line-progress__background')
                // #endif
                // #ifdef APP-NVUE
                // è¿”回一个promise
                return new Promise(resolve => {
                    dom.getComponentRect(this.$refs['u-line-progress__background'], (res) => {
                        resolve(res.size)
                    })
                })
                // #endif
            },
            resizeProgressWidth() {
                this.getProgressWidth().then(size => {
                    const {
                        width
                    } = size
                    // é€šè¿‡è®¾ç½®çš„percentage值,计算其所占总长度的百分比
                    this.lineWidth = width * this.innserPercentage / 100 + 'px'
                })
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-line-progress {
        align-items: stretch;
        position: relative;
        @include flex(row);
        flex: 1;
        overflow: hidden;
        border-radius: 100px;
        &__background {
            background-color: #ececec;
            border-radius: 100px;
            flex: 1;
        }
        &__line {
            position: absolute;
            top: 0;
            left: 0;
            bottom: 0;
            align-items: center;
            @include flex(row);
            color: #ffffff;
            border-radius: 100px;
            transition: width 0.5s ease;
            justify-content: flex-end;
        }
        &__text {
            font-size: 10px;
            align-items: center;
            text-align: right;
            color: #FFFFFF;
            margin-right: 5px;
            transform: scale(0.9);
        }
    }
</style>
uni_modules/uview-ui/components/u-line/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
export default {
    props: {
        color: {
            type: String,
            default: uni.$u.props.line.color
        },
        // é•¿åº¦ï¼Œç«–向时表现为高度,横向时表现为长度,可以为百分比,带px单位的值等
        length: {
            type: [String, Number],
            default: uni.$u.props.line.length
        },
        // çº¿æ¡æ–¹å‘,col-竖向,row-横向
        direction: {
            type: String,
            default: uni.$u.props.line.direction
        },
        // æ˜¯å¦æ˜¾ç¤ºç»†è¾¹æ¡†
        hairline: {
            type: Boolean,
            default: uni.$u.props.line.hairline
        },
        // çº¿æ¡ä¸Žä¸Šä¸‹å·¦å³å…ƒç´ çš„间距,字符串形式,如"30px"、"20px 30px"
        margin: {
            type: [String, Number],
            default: uni.$u.props.line.margin
        },
        // æ˜¯å¦è™šçº¿ï¼Œtrue-实线,false-虚线
        dashed: {
            type: Boolean,
            default: uni.$u.props.line.dashed
        }
    }
}
uni_modules/uview-ui/components/u-line/u-line.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
<template>
    <view
        class="u-line"
        :style="[lineStyle]"
    >
    </view>
</template>
<script>
    import props from './props.js';
    /**
     * line çº¿æ¡
     * @description æ­¤ç»„件一般用于显示一根线条,用于分隔内容块,有横向和竖向两种模式,且能设置0.5px线条,使用也很简单
     * @tutorial https://www.uviewui.com/components/line.html
     * @property {String}            color        çº¿æ¡çš„颜色 ( é»˜è®¤ '#d6d7d9' )
     * @property {String | Number}    length        é•¿åº¦ï¼Œç«–向时表现为高度,横向时表现为长度,可以为百分比,带px单位的值等 ( é»˜è®¤ '100%' )
     * @property {String}            direction    çº¿æ¡çš„æ–¹å‘,row-横向,col-竖向 (默认 'row' )
     * @property {Boolean}            hairline    æ˜¯å¦æ˜¾ç¤ºç»†çº¿æ¡ (默认 true )
     * @property {String | Number}    margin        çº¿æ¡ä¸Žä¸Šä¸‹å·¦å³å…ƒç´ çš„间距,字符串形式,如"30px"  (默认 0 )
     * @property {Boolean}            dashed        æ˜¯å¦è™šçº¿ï¼Œtrue-虚线,false-实线 (默认 false )
     * @property {Object}            customStyle    å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     * @example <u-line color="red"></u-line>
     */
    export default {
        name: 'u-line',
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        computed: {
            lineStyle() {
                const style = {}
                style.margin = this.margin
                // å¦‚果是水平线条,边框高度为1px,再通过transform缩小一半,就是0.5px了
                if (this.direction === 'row') {
                    // æ­¤å¤„采用兼容分开写,兼容nvue的写法
                    style.borderBottomWidth = '1px'
                    style.borderBottomStyle = this.dashed ? 'dashed' : 'solid'
                    style.width = uni.$u.addUnit(this.length)
                    if (this.hairline) style.transform = 'scaleY(0.5)'
                } else {
                    // å¦‚果是竖向线条,边框宽度为1px,再通过transform缩小一半,就是0.5px了
                    style.borderLeftWidth = '1px'
                    style.borderLeftStyle = this.dashed ? 'dashed' : 'solid'
                    style.height = uni.$u.addUnit(this.length)
                    if (this.hairline) style.transform = 'scaleX(0.5)'
                }
                style.borderColor = this.color
                return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-line {
        /* #ifndef APP-NVUE */
        vertical-align: middle;
        /* #endif */
    }
</style>
uni_modules/uview-ui/components/u-link/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
export default {
    props: {
        // æ–‡å­—颜色
        color: {
            type: String,
            default: uni.$u.props.link.color
        },
        // å­—体大小,单位px
        fontSize: {
            type: [String, Number],
            default: uni.$u.props.link.fontSize
        },
        // æ˜¯å¦æ˜¾ç¤ºä¸‹åˆ’线
        underLine: {
            type: Boolean,
            default: uni.$u.props.link.underLine
        },
        // è¦è·³è½¬çš„链接
        href: {
            type: String,
            default: uni.$u.props.link.href
        },
        // å°ç¨‹åºä¸­å¤åˆ¶åˆ°ç²˜è´´æ¿çš„æç¤ºè¯­
        mpTips: {
            type: String,
            default: uni.$u.props.link.mpTips
        },
        // ä¸‹åˆ’线颜色
        lineColor: {
            type: String,
            default: uni.$u.props.link.lineColor
        },
        // è¶…链接的问题,不使用slot形式传入,是因为nvue下无法修改颜色
        text: {
            type: String,
            default: uni.$u.props.link.text
        }
    }
}
uni_modules/uview-ui/components/u-link/u-link.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,83 @@
<template>
    <text
        class="u-link"
        @tap.stop="openLink"
        :style="[linkStyle, $u.addStyle(customStyle)]"
    >{{text}}</text>
</template>
<script>
    import props from './props.js';
    /**
     * link è¶…链接
     * @description è¯¥ç»„件为超链接组件,在不同平台有不同表现形式:在APP平台会通过plus环境打开内置浏览器,在小程序中把链接复制到粘贴板,同时提示信息,在H5中通过window.open打开链接。
     * @tutorial https://www.uviewui.com/components/link.html
     * @property {String}            color        æ–‡å­—颜色 ï¼ˆé»˜è®¤ color['u-primary'] ï¼‰
     * @property {String ï½œ Number}    fontSize    å­—体大小,单位px ï¼ˆé»˜è®¤ 15 ï¼‰
     * @property {Boolean}            underLine    æ˜¯å¦æ˜¾ç¤ºä¸‹åˆ’线 ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String}            href        è·³è½¬çš„链接,要带上http(s)
     * @property {String}            mpTips        å„个小程序平台把链接复制到粘贴板后的提示语(默认“链接已复制,请在浏览器打开”)
     * @property {String}            lineColor    ä¸‹åˆ’线颜色,默认同color参数颜色
     * @property {String}            text        è¶…链接的问题,不使用slot形式传入,是因为nvue下无法修改颜色
     * @property {Object}            customStyle    å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     *
     * @example <u-link href="http://www.uviewui.com">蜀道难,难于上青天</u-link>
     */
    export default {
        name: "u-link",
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        computed: {
            linkStyle() {
                const style = {
                    color: this.color,
                    fontSize: uni.$u.addUnit(this.fontSize),
                    // line-height设置为比字体大小多2px
                    lineHeight: uni.$u.addUnit(uni.$u.getPx(this.fontSize) + 2),
                    textDecoration: this.underLine ? 'underline' : 'none'
                }
                // if (this.underLine) {
                //     style.borderBottomColor = this.lineColor || this.color
                //     style.borderBottomWidth = '1px'
                // }
                return style
            }
        },
        methods: {
            openLink() {
                // #ifdef APP-PLUS
                plus.runtime.openURL(this.href)
                // #endif
                // #ifdef H5
                window.open(this.href)
                // #endif
                // #ifdef MP
                uni.setClipboardData({
                    data: this.href,
                    success: () => {
                        uni.hideToast();
                        this.$nextTick(() => {
                            uni.$u.toast(this.mpTips);
                        })
                    }
                });
                // #endif
                this.$emit('click')
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    $u-link-line-height:1 !default;
    .u-link {
        /* #ifndef APP-NVUE */
        line-height: $u-link-line-height;
        /* #endif */
        @include flex;
        flex-wrap: wrap;
        flex: 1;
    }
</style>
uni_modules/uview-ui/components/u-list-item/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,9 @@
export default {
    props: {
        // ç”¨äºŽæ»šåŠ¨åˆ°æŒ‡å®šitem
        anchor: {
            type: [String, Number],
            default: uni.$u.props.listItem.anchor
        }
    }
}
uni_modules/uview-ui/components/u-list-item/u-list-item.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,116 @@
<template>
    <!-- #ifdef APP-NVUE -->
    <cell>
        <!-- #endif -->
        <view
            class="u-list-item"
            :ref="`u-list-item-${anchor}`"
            :anchor="`u-list-item-${anchor}`"
            :class="[`u-list-item-${anchor}`]"
        >
            <slot />
        </view>
        <!-- #ifdef APP-NVUE -->
    </cell>
    <!-- #endif -->
</template>
<script>
    import props from './props.js';
    // #ifdef APP-NVUE
    const dom = uni.requireNativePlugin('dom')
    // #endif
    /**
     * List åˆ—表
     * @description è¯¥ç»„件为高性能列表组件
     * @tutorial https://www.uviewui.com/components/list.html
     * @property {String | Number}    anchor    ç”¨äºŽæ»šåŠ¨åˆ°æŒ‡å®šitem
     * @example <u-list-ite v-for="(item, index) in indexList" :key="index" ></u-list-item>
     */
    export default {
        name: 'u-list-item',
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        data() {
            return {
                // èŠ‚ç‚¹ä¿¡æ¯
                rect: {},
                index: 0,
                show: true,
                sys: uni.$u.sys()
            }
        },
        computed: {
        },
        inject: ['uList'],
        watch: {
            // #ifndef APP-NVUE
            'uList.innerScrollTop'(n) {
                const preLoadScreen = this.uList.preLoadScreen
                const windowHeight = this.sys.windowHeight
                if(n <= windowHeight * preLoadScreen) {
                    this.parent.updateOffsetFromChild(0)
                } else if (this.rect.top <= n - windowHeight * preLoadScreen) {
                    this.parent.updateOffsetFromChild(this.rect.top)
                }
            }
            // #endif
        },
        created() {
            this.parent = {}
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                // åˆå§‹åŒ–数据
                this.updateParentData()
                this.index = this.parent.children.indexOf(this)
                this.resize()
            },
            updateParentData() {
                // æ­¤æ–¹æ³•在mixin中
                this.getParentData('u-list')
            },
            resize() {
                this.queryRect(`u-list-item-${this.anchor}`).then(size => {
                    const lastChild = this.parent.children[this.index - 1]
                    this.rect = size
                    const preLoadScreen = this.uList.preLoadScreen
                    const windowHeight = this.sys.windowHeight
                    // #ifndef APP-NVUE
                    if (lastChild) {
                        this.rect.top = lastChild.rect.top + lastChild.rect.height
                    }
                    if (size.top >= this.uList.innerScrollTop + (1 + preLoadScreen) * windowHeight) this.show =
                        false
                    // #endif
                })
            },
            // æŸ¥è¯¢å…ƒç´ å°ºå¯¸
            queryRect(el) {
                return new Promise(resolve => {
                    // #ifndef APP-NVUE
                    this.$uGetRect(`.${el}`).then(size => {
                        resolve(size)
                    })
                    // #endif
                    // #ifdef APP-NVUE
                    const ref = this.$refs[el]
                    dom.getComponentRect(ref, res => {
                        resolve(res.size)
                    })
                    // #endif
                })
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-list-item {}
</style>
uni_modules/uview-ui/components/u-list/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,76 @@
export default {
    props: {
        // æŽ§åˆ¶æ˜¯å¦å‡ºçŽ°æ»šåŠ¨æ¡ï¼Œä»…nvue有效
        showScrollbar: {
            type: Boolean,
            default: uni.$u.props.list.showScrollbar
        },
        // è·åº•部多少时触发scrolltolower事件
        lowerThreshold: {
            type: [String, Number],
            default: uni.$u.props.list.lowerThreshold
        },
        // è·é¡¶éƒ¨å¤šå°‘时触发scrolltoupper事件,非nvue有效
        upperThreshold: {
            type: [String, Number],
            default: uni.$u.props.list.upperThreshold
        },
        // è®¾ç½®ç«–向滚动条位置
        scrollTop: {
            type: [String, Number],
            default: uni.$u.props.list.scrollTop
        },
        // æŽ§åˆ¶ onscroll äº‹ä»¶è§¦å‘的频率,仅nvue有效
        offsetAccuracy: {
            type: [String, Number],
            default: uni.$u.props.list.offsetAccuracy
        },
        // å¯ç”¨ flexbox å¸ƒå±€ã€‚开启后,当前节点声明了display: flex就会成为flex container,并作用于其孩子节点,仅微信小程序有效
        enableFlex: {
            type: Boolean,
            default: uni.$u.props.list.enableFlex
        },
        // æ˜¯å¦æŒ‰åˆ†é¡µæ¨¡å¼æ˜¾ç¤ºList,默认值false
        pagingEnabled: {
            type: Boolean,
            default: uni.$u.props.list.pagingEnabled
        },
        // æ˜¯å¦å…è®¸List滚动
        scrollable: {
            type: Boolean,
            default: uni.$u.props.list.scrollable
        },
        // å€¼åº”为某子元素id(id不能以数字开头)
        scrollIntoView: {
            type: String,
            default: uni.$u.props.list.scrollIntoView
        },
        // åœ¨è®¾ç½®æ»šåŠ¨æ¡ä½ç½®æ—¶ä½¿ç”¨åŠ¨ç”»è¿‡æ¸¡
        scrollWithAnimation: {
            type: Boolean,
            default: uni.$u.props.list.scrollWithAnimation
        },
        // iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只对微信小程序有效
        enableBackToTop: {
            type: Boolean,
            default: uni.$u.props.list.enableBackToTop
        },
        // åˆ—表的高度
        height: {
            type: [String, Number],
            default: uni.$u.props.list.height
        },
        // åˆ—表宽度
        width: {
            type: [String, Number],
            default: uni.$u.props.list.width
        },
        // åˆ—表前后预渲染的屏数,1代表一个屏幕的高度,1.5代表1个半屏幕高度
        preLoadScreen: {
            type: [String, Number],
            default: uni.$u.props.list.preLoadScreen
        }
        // vue下,是否开启虚拟列表
    }
}
uni_modules/uview-ui/components/u-list/u-list.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,159 @@
<template>
    <!-- #ifdef APP-NVUE -->
    <list
        class="u-list"
        :enableBackToTop="enableBackToTop"
        :loadmoreoffset="lowerThreshold"
        :showScrollbar="showScrollbar"
        :style="[listStyle]"
        :offset-accuracy="Number(offsetAccuracy)"
        @scroll="onScroll"
        @loadmore="scrolltolower"
    >
        <slot />
    </list>
    <!-- #endif -->
    <!-- #ifndef APP-NVUE -->
    <scroll-view
        class="u-list"
        :scroll-into-view="scrollIntoView"
        :style="[listStyle]"
        scroll-y
        :scroll-top="Number(scrollTop)"
        :lower-threshold="Number(lowerThreshold)"
        :upper-threshold="Number(upperThreshold)"
        :show-scrollbar="showScrollbar"
        :enable-back-to-top="enableBackToTop"
        :scroll-with-animation="scrollWithAnimation"
        @scroll="onScroll"
        @scrolltolower="scrolltolower"
        @scrolltoupper="scrolltoupper"
    >
        <view :style="{
            paddingTop: `${offset}px`
        }">
            <slot />
        </view>
    </scroll-view>
    <!-- #endif -->
</template>
<script>
    import props from './props.js';
    // #ifdef APP-NVUE
    const dom = uni.requireNativePlugin('dom')
    // #endif
    /**
     * List åˆ—表
     * @description è¯¥ç»„件为高性能列表组件
     * @tutorial https://www.uviewui.com/components/list.html
     * @property {Boolean}            showScrollbar        æŽ§åˆ¶æ˜¯å¦å‡ºçŽ°æ»šåŠ¨æ¡ï¼Œä»…nvue有效 ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String ï½œ Number}    lowerThreshold        è·åº•部多少时触发scrolltolower事件 ï¼ˆé»˜è®¤ 50 ï¼‰
     * @property {String ï½œ Number}    upperThreshold        è·é¡¶éƒ¨å¤šå°‘时触发scrolltoupper事件,非nvue有效 ï¼ˆé»˜è®¤ 0 ï¼‰
     * @property {String ï½œ Number}    scrollTop            è®¾ç½®ç«–向滚动条位置(默认 0 ï¼‰
     * @property {String ï½œ Number}    offsetAccuracy        æŽ§åˆ¶ onscroll äº‹ä»¶è§¦å‘的频率,仅nvue有效(默认 10 ï¼‰
     * @property {Boolean}            enableFlex            å¯ç”¨ flexbox å¸ƒå±€ã€‚开启后,当前节点声明了display: flex就会成为flex container,并作用于其孩子节点,仅微信小程序有效(默认 false ï¼‰
     * @property {Boolean}            pagingEnabled        æ˜¯å¦æŒ‰åˆ†é¡µæ¨¡å¼æ˜¾ç¤ºList,(默认 false ï¼‰
     * @property {Boolean}            scrollable            æ˜¯å¦å…è®¸List滚动(默认 true ï¼‰
     * @property {String}            scrollIntoView        å€¼åº”为某子元素id(id不能以数字开头)
     * @property {Boolean}            scrollWithAnimation    åœ¨è®¾ç½®æ»šåŠ¨æ¡ä½ç½®æ—¶ä½¿ç”¨åŠ¨ç”»è¿‡æ¸¡ ï¼ˆé»˜è®¤ false ï¼‰
     * @property {Boolean}            enableBackToTop        iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只对微信小程序有效 ï¼ˆé»˜è®¤ false ï¼‰
     * @property {String ï½œ Number}    height                åˆ—表的高度 ï¼ˆé»˜è®¤ 0 ï¼‰
     * @property {String ï½œ Number}    width                åˆ—表宽度 ï¼ˆé»˜è®¤ 0 ï¼‰
     * @property {String ï½œ Number}    preLoadScreen        åˆ—表前后预渲染的屏数,1代表一个屏幕的高度,1.5代表1个半屏幕高度  ï¼ˆé»˜è®¤ 1 ï¼‰
     * @property {Object}            customStyle            å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     *
     * @example <u-list @scrolltolower="scrolltolower"></u-list>
     */
    export default {
        name: 'u-list',
        mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
        watch: {
            scrollIntoView(n) {
                this.scrollIntoViewById(n)
            }
        },
        data() {
            return {
                // è®°å½•内部滚动的距离
                innerScrollTop: 0,
                // vue下,scroll-view在上拉加载时的偏移值
                offset: 0,
                sys: uni.$u.sys()
            }
        },
        computed: {
            listStyle() {
                const style = {},
                    addUnit = uni.$u.addUnit
                if (this.width != 0) style.width = addUnit(this.width)
                if (this.height != 0) style.height = addUnit(this.height)
                // å¦‚果没有定义列表高度,则默认使用屏幕高度
                if (!style.height) style.height = addUnit(this.sys.windowHeight, 'px')
                return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
            }
        },
        provide() {
            return {
                uList: this
            }
        },
        created() {
            this.refs = []
            this.children = []
            this.anchors = []
        },
        mounted() {},
        methods: {
            updateOffsetFromChild(top) {
                this.offset = top
            },
            onScroll(e) {
                let scrollTop = 0
                // #ifdef APP-NVUE
                scrollTop = e.contentOffset.y
                // #endif
                // #ifndef APP-NVUE
                scrollTop = e.detail.scrollTop
                // #endif
                this.innerScrollTop = scrollTop
                this.$emit('scroll', Math.abs(scrollTop))
            },
            scrollIntoViewById(id) {
                // #ifdef APP-NVUE
                // æ ¹æ®id参数,找到所有u-list-item中匹配的节点,再通过dom模块滚动到对应的位置
                const item = this.refs.find(item => item.$refs[id] ? true : false)
                dom.scrollToElement(item.$refs[id], {
                    // æ˜¯å¦éœ€è¦æ»šåŠ¨åŠ¨ç”»
                    animated: this.scrollWithAnimation
                })
                // #endif
            },
            // æ»šåŠ¨åˆ°åº•éƒ¨è§¦å‘äº‹ä»¶
            scrolltolower(e) {
                uni.$u.sleep(30).then(() => {
                    this.$emit('scrolltolower')
                })
            },
            // #ifndef APP-NVUE
            // æ»šåŠ¨åˆ°åº•éƒ¨æ—¶è§¦å‘ï¼Œéžnvue有效
            scrolltoupper(e) {
                uni.$u.sleep(30).then(() => {
                    this.$emit('scrolltoupper')
                    // è¿™ä¸€å¥å¾ˆé‡è¦ï¼Œèƒ½ç»å¯¹ä¿è¯åœ¨æ€§åŠŸèƒ½éšœç¢çš„webview,滚动条到顶时,取消偏移值,让页面置顶
                    this.offset = 0
                })
            }
            // #endif
        },
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    .u-list {
        @include flex(column);
    }
</style>
uni_modules/uview-ui/components/u-loading-icon/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
export default {
    props: {
        // æ˜¯å¦æ˜¾ç¤ºç»„ä»¶
        show: {
            type: Boolean,
            default: uni.$u.props.loadingIcon.show
        },
        // é¢œè‰²
        color: {
            type: String,
            default: uni.$u.props.loadingIcon.color
        },
        // æç¤ºæ–‡å­—颜色
        textColor: {
            type: String,
            default: uni.$u.props.loadingIcon.textColor
        },
        // æ–‡å­—和图标是否垂直排列
        vertical: {
            type: Boolean,
            default: uni.$u.props.loadingIcon.vertical
        },
        // æ¨¡å¼é€‰æ‹©ï¼Œcircle-圆形,spinner-花朵形,semicircle-半圆形
        mode: {
            type: String,
            default: uni.$u.props.loadingIcon.mode
        },
        // å›¾æ ‡å¤§å°ï¼Œå•位默认px
        size: {
            type: [String, Number],
            default: uni.$u.props.loadingIcon.size
        },
        // æ–‡å­—大小
        textSize: {
            type: [String, Number],
            default: uni.$u.props.loadingIcon.textSize
        },
        // æ–‡å­—内容
        text: {
            type: [String, Number],
            default: uni.$u.props.loadingIcon.text
        },
        // åŠ¨ç”»æ¨¡å¼
        timingFunction: {
            type: String,
            default: uni.$u.props.loadingIcon.timingFunction
        },
        // åŠ¨ç”»æ‰§è¡Œå‘¨æœŸæ—¶é—´
        duration: {
            type: [String, Number],
            default: uni.$u.props.loadingIcon.duration
        },
        // mode=circle时的暗边颜色
        inactiveColor: {
            type: String,
            default: uni.$u.props.loadingIcon.inactiveColor
        }
    }
}
uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,343 @@
<template>
    <view
        class="u-loading-icon"
        :style="[$u.addStyle(customStyle)]"
        :class="[vertical && 'u-loading-icon--vertical']"
        v-if="show"
    >
        <view
            v-if="!webviewHide"
            class="u-loading-icon__spinner"
            :class="[`u-loading-icon__spinner--${mode}`]"
            ref="ani"
            :style="{
                color: color,
                width: $u.addUnit(size),
                height: $u.addUnit(size),
                borderTopColor: color,
                borderBottomColor: otherBorderColor,
                borderLeftColor: otherBorderColor,
                borderRightColor: otherBorderColor,
                'animation-duration': `${duration}ms`,
                'animation-timing-function': mode === 'semicircle' || mode === 'circle' ? timingFunction : ''
            }"
        >
            <block v-if="mode === 'spinner'">
                <!-- #ifndef APP-NVUE -->
                <view
                    v-for="(item, index) in array12"
                    :key="index"
                    class="u-loading-icon__dot"
                >
                </view>
                <!-- #endif -->
                <!-- #ifdef APP-NVUE -->
                <!-- æ­¤ç»„件内部图标部分无法设置宽高,即使通过width和height配置了也无效 -->
                <loading-indicator
                    v-if="!webviewHide"
                    class="u-loading-indicator"
                    :animating="true"
                    :style="{
                        color: color,
                        width: $u.addUnit(size),
                        height: $u.addUnit(size)
                    }"
                />
                <!-- #endif -->
            </block>
        </view>
        <text
            v-if="text"
            class="u-loading-icon__text"
            :style="{
                fontSize: $u.addUnit(textSize),
                color: textColor,
            }"
        >{{text}}</text>
    </view>
</template>
<script>
    import props from './props.js';
    // #ifdef APP-NVUE
    const animation = weex.requireModule('animation');
    // #endif
    /**
     * loading åŠ è½½åŠ¨ç”»
     * @description è­¦æ­¤ç»„件为一个小动画,目前用在uView的loadmore加载更多和switch开关等组件的正在加载状态场景。
     * @tutorial https://www.uviewui.com/components/loading.html
     * @property {Boolean}            show            æ˜¯å¦æ˜¾ç¤ºç»„ä»¶  (默认 true)
     * @property {String}            color            åŠ¨ç”»æ´»åŠ¨åŒºåŸŸçš„é¢œè‰²ï¼Œåªå¯¹ mode = flower æ¨¡å¼æœ‰æ•ˆï¼ˆé»˜è®¤color['u-tips-color'])
     * @property {String}            textColor        æç¤ºæ–‡æœ¬çš„颜色(默认color['u-tips-color'])
     * @property {Boolean}            vertical        æ–‡å­—和图标是否垂直排列 (默认 false )
     * @property {String}            mode            æ¨¡å¼é€‰æ‹©ï¼Œè§å®˜ç½‘说明(默认 'circle' ï¼‰
     * @property {String | Number}    size            åŠ è½½å›¾æ ‡çš„å¤§å°ï¼Œå•ä½px ï¼ˆé»˜è®¤ 24 ï¼‰
     * @property {String | Number}    textSize        æ–‡å­—大小(默认 15 ï¼‰
     * @property {String | Number}    text            æ–‡å­—内容
     * @property {String}            timingFunction    åŠ¨ç”»æ¨¡å¼ ï¼ˆé»˜è®¤ 'ease-in-out' ï¼‰
     * @property {String | Number}    duration        åŠ¨ç”»æ‰§è¡Œå‘¨æœŸæ—¶é—´ï¼ˆé»˜è®¤ 1200)
     * @property {String}            inactiveColor    mode=circle时的暗边颜色
     * @property {Object}            customStyle        å®šä¹‰éœ€è¦ç”¨åˆ°çš„外部样式
     * @example <u-loading mode="circle"></u-loading>
     */
    export default {
        name: 'u-loading-icon',
        mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
        data() {
            return {
                // Array.form可以通过一个伪数组对象创建指定长度的数组
                // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/from
                array12: Array.from({
                    length: 12
                }),
                // è¿™é‡Œéœ€è¦è®¾ç½®é»˜è®¤å€¼ä¸º360,否则在安卓nvue上,会延迟一个duration周期后才执行
                // åœ¨iOS nvue上,则会一开始默认执行两个周期的动画
                aniAngel: 360, // åŠ¨ç”»æ—‹è½¬è§’åº¦
                webviewHide: false, // ç›‘听webview的状态,如果隐藏了页面,则停止动画,以免性能消耗
                loading: false, // æ˜¯å¦è¿è¡Œä¸­ï¼Œé’ˆå¯¹nvue使用
            }
        },
        computed: {
            // å½“为circle类型时,给其另外三边设置一个更轻一些的颜色
            // ä¹‹æ‰€ä»¥éœ€è¦è¿™ä¹ˆåšçš„原因是,比如父组件传了color为红色,那么需要另外的三个边为浅红色
            // è€Œä¸èƒ½æ˜¯å›ºå®šçš„æŸä¸€ä¸ªå…¶ä»–颜色(因为这个固定的颜色可能浅蓝,导致效果没有那么细腻良好)
            otherBorderColor() {
                const lightColor = uni.$u.colorGradient(this.color, '#ffffff', 100)[80]
                if (this.mode === 'circle') {
                    return this.inactiveColor ? this.inactiveColor : lightColor
                } else {
                    return 'transparent'
                }
                // return this.mode === 'circle' ? this.inactiveColor ? this.inactiveColor : lightColor : 'transparent'
            }
        },
        watch: {
            show(n) {
                // nvue中,show为true,且为非loading状态,就重新执行动画模块
                // #ifdef APP-NVUE
                if (n && !this.loading) {
                    setTimeout(() => {
                        this.startAnimate()
                    }, 30)
                }
                // #endif
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                setTimeout(() => {
                    // #ifdef APP-NVUE
                    this.show && this.nvueAnimate()
                    // #endif
                    // #ifdef APP-PLUS
                    this.show && this.addEventListenerToWebview()
                    // #endif
                }, 20)
            },
            // ç›‘听webview的显示与隐藏
            addEventListenerToWebview() {
                // webview的堆栈
                const pages = getCurrentPages()
                // å½“前页面
                const page = pages[pages.length - 1]
                // å½“前页面的webview实例
                const currentWebview = page.$getAppWebview()
                // ç›‘听webview的显示与隐藏,从而停止或者开始动画(为了性能)
                currentWebview.addEventListener('hide', () => {
                    this.webviewHide = true
                })
                currentWebview.addEventListener('show', () => {
                    this.webviewHide = false
                })
            },
            // #ifdef APP-NVUE
            nvueAnimate() {
                // nvue下,非spinner类型时才需要旋转,因为nvue的spinner类型,使用了weex的
                // loading-indicator组件,自带旋转功能
                this.mode !== 'spinner' && this.startAnimate()
            },
            // æ‰§è¡Œnvue的animate模块动画
            startAnimate() {
                this.loading = true
                const ani = this.$refs.ani
                if (!ani) return
                animation.transition(ani, {
                    // è¿›è¡Œè§’度旋转
                    styles: {
                        transform: `rotate(${this.aniAngel}deg)`,
                        transformOrigin: 'center center'
                    },
                    duration: this.duration,
                    timingFunction: this.timingFunction,
                    // delay: 10
                }, () => {
                    // æ¯æ¬¡å¢žåŠ 360deg,为了让其重新旋转一周
                    this.aniAngel += 360
                    // åŠ¨ç”»ç»“æŸåŽï¼Œç»§ç»­å¾ªçŽ¯æ‰§è¡ŒåŠ¨ç”»ï¼Œéœ€è¦åŒæ—¶åˆ¤æ–­webviewHide变量
                    // nvue安卓,页面隐藏后依然会继续执行startAnimate方法
                    this.show && !this.webviewHide ? this.startAnimate() : this.loading = false
                })
            }
            // #endif
        }
    }
</script>
<style lang="scss" scoped>
    @import "../../libs/css/components.scss";
    $u-loading-icon-color: #c8c9cc !default;
    $u-loading-icon-text-margin-left:4px !default;
    $u-loading-icon-text-color:$u-content-color !default;
    $u-loading-icon-text-font-size:14px !default;
    $u-loading-icon-text-line-height:20px !default;
    $u-loading-width:30px !default;
    $u-loading-height:30px !default;
    $u-loading-max-width:100% !default;
    $u-loading-max-height:100% !default;
    $u-loading-semicircle-border-width: 2px !default;
    $u-loading-semicircle-border-color:transparent !default;
    $u-loading-semicircle-border-top-right-radius: 100px !default;
    $u-loading-semicircle-border-top-left-radius: 100px !default;
    $u-loading-semicircle-border-bottom-left-radius: 100px !default;
    $u-loading-semicircle-border-bottom-right-radiu: 100px !default;
    $u-loading-semicircle-border-style: solid !default;
    $u-loading-circle-border-top-right-radius: 100px !default;
    $u-loading-circle-border-top-left-radius: 100px !default;
    $u-loading-circle-border-bottom-left-radius: 100px !default;
    $u-loading-circle-border-bottom-right-radiu: 100px !default;
    $u-loading-circle-border-width:2px !default;
    $u-loading-circle-border-top-color:#e5e5e5 !default;
    $u-loading-circle-border-right-color:$u-loading-circle-border-top-color !default;
    $u-loading-circle-border-bottom-color:$u-loading-circle-border-top-color !default;
    $u-loading-circle-border-left-color:$u-loading-circle-border-top-color !default;
    $u-loading-circle-border-style:solid !default;
    $u-loading-icon-host-font-size:0px !default;
    $u-loading-icon-host-line-height:1 !default;
    $u-loading-icon-vertical-margin:6px 0 0 !default;
    $u-loading-icon-dot-top:0 !default;
    $u-loading-icon-dot-left:0 !default;
    $u-loading-icon-dot-width:100% !default;
    $u-loading-icon-dot-height:100% !default;
    $u-loading-icon-dot-before-width:2px !default;
    $u-loading-icon-dot-before-height:25% !default;
    $u-loading-icon-dot-before-margin:0 auto !default;
    $u-loading-icon-dot-before-background-color:currentColor !default;
    $u-loading-icon-dot-before-border-radius:40% !default;
    .u-loading-icon {
        /* #ifndef APP-NVUE */
        // display: inline-flex;
        /* #endif */
        flex-direction: row;
        align-items: center;
        justify-content: center;
        color: $u-loading-icon-color;
        &__text {
            margin-left: $u-loading-icon-text-margin-left;
            color: $u-loading-icon-text-color;
            font-size: $u-loading-icon-text-font-size;
            line-height: $u-loading-icon-text-line-height;
        }
        &__spinner {
            width: $u-loading-width;
            height: $u-loading-height;
            position: relative;
            /* #ifndef APP-NVUE */
            box-sizing: border-box;
            max-width: $u-loading-max-width;
            max-height: $u-loading-max-height;
            animation: u-rotate 1s linear infinite;
            /* #endif */
        }
        &__spinner--semicircle {
            border-width: $u-loading-semicircle-border-width;
            border-color: $u-loading-semicircle-border-color;
            border-top-right-radius: $u-loading-semicircle-border-top-right-radius;
            border-top-left-radius: $u-loading-semicircle-border-top-left-radius;
            border-bottom-left-radius: $u-loading-semicircle-border-bottom-left-radius;
            border-bottom-right-radius: $u-loading-semicircle-border-bottom-right-radiu;
            border-style: $u-loading-semicircle-border-style;
        }
        &__spinner--circle {
            border-top-right-radius: $u-loading-circle-border-top-right-radius;
            border-top-left-radius: $u-loading-circle-border-top-left-radius;
            border-bottom-left-radius: $u-loading-circle-border-bottom-left-radius;
            border-bottom-right-radius: $u-loading-circle-border-bottom-right-radiu;
            border-width: $u-loading-circle-border-width;
            border-top-color: $u-loading-circle-border-top-color;
            border-right-color: $u-loading-circle-border-right-color;
            border-bottom-color: $u-loading-circle-border-bottom-color;
            border-left-color: $u-loading-circle-border-left-color;
            border-style: $u-loading-circle-border-style;
        }
        &--vertical {
            flex-direction: column
        }
    }
    /* #ifndef APP-NVUE */
    :host {
        font-size: $u-loading-icon-host-font-size;
        line-height: $u-loading-icon-host-line-height;
    }
    .u-loading-icon {
        &__spinner--spinner {
            animation-timing-function: steps(12)
        }
        &__text:empty {
            display: none
        }
        &--vertical &__text {
            margin: $u-loading-icon-vertical-margin;
            color: $u-content-color;
        }
        &__dot {
            position: absolute;
            top: $u-loading-icon-dot-top;
            left: $u-loading-icon-dot-left;
            width: $u-loading-icon-dot-width;
            height: $u-loading-icon-dot-height;
            &:before {
                display: block;
                width: $u-loading-icon-dot-before-width;
                height: $u-loading-icon-dot-before-height;
                margin: $u-loading-icon-dot-before-margin;
                background-color: $u-loading-icon-dot-before-background-color;
                border-radius: $u-loading-icon-dot-before-border-radius;
                content: " "
            }
        }
    }
    @for $i from 1 through 12 {
        .u-loading-icon__dot:nth-of-type(#{$i}) {
            transform: rotate($i * 30deg);
            opacity: 1 - 0.0625 * ($i - 1);
        }
    }
    @keyframes u-rotate {
        0% {
            transform: rotate(0deg)
        }
        to {
            transform: rotate(1turn)
        }
    }
    /* #endif */
</style>
在上述文件截断后对比
uni_modules/uview-ui/components/u-loading-page/props.js uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue uni_modules/uview-ui/components/u-loadmore/props.js uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue uni_modules/uview-ui/components/u-modal/props.js uni_modules/uview-ui/components/u-modal/u-modal.vue uni_modules/uview-ui/components/u-navbar/props.js uni_modules/uview-ui/components/u-navbar/u-navbar.vue uni_modules/uview-ui/components/u-no-network/props.js uni_modules/uview-ui/components/u-no-network/u-no-network.vue uni_modules/uview-ui/components/u-notice-bar/props.js uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue uni_modules/uview-ui/components/u-notify/props.js uni_modules/uview-ui/components/u-notify/u-notify.vue uni_modules/uview-ui/components/u-number-box/props.js uni_modules/uview-ui/components/u-number-box/u-number-box.vue uni_modules/uview-ui/components/u-number-keyboard/props.js uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue uni_modules/uview-ui/components/u-overlay/props.js uni_modules/uview-ui/components/u-overlay/u-overlay.vue uni_modules/uview-ui/components/u-parse/node/node.vue uni_modules/uview-ui/components/u-parse/parser.js uni_modules/uview-ui/components/u-parse/props.js uni_modules/uview-ui/components/u-parse/u-parse.vue uni_modules/uview-ui/components/u-picker-column/props.js uni_modules/uview-ui/components/u-picker-column/u-picker-column.vue uni_modules/uview-ui/components/u-picker/props.js uni_modules/uview-ui/components/u-picker/u-picker.vue uni_modules/uview-ui/components/u-popup/props.js uni_modules/uview-ui/components/u-popup/u-popup.vue uni_modules/uview-ui/components/u-radio-group/props.js uni_modules/uview-ui/components/u-radio-group/u-radio-group.vue uni_modules/uview-ui/components/u-radio/props.js uni_modules/uview-ui/components/u-radio/u-radio.vue uni_modules/uview-ui/components/u-rate/props.js uni_modules/uview-ui/components/u-rate/u-rate.vue uni_modules/uview-ui/components/u-read-more/props.js uni_modules/uview-ui/components/u-read-more/u-read-more.vue uni_modules/uview-ui/components/u-row-notice/props.js uni_modules/uview-ui/components/u-row-notice/u-row-notice.vue uni_modules/uview-ui/components/u-row/props.js uni_modules/uview-ui/components/u-row/u-row.vue uni_modules/uview-ui/components/u-safe-bottom/props.js uni_modules/uview-ui/components/u-safe-bottom/u-safe-bottom.vue uni_modules/uview-ui/components/u-scroll-list/nvue.js uni_modules/uview-ui/components/u-scroll-list/other.js uni_modules/uview-ui/components/u-scroll-list/props.js uni_modules/uview-ui/components/u-scroll-list/scrollWxs.wxs uni_modules/uview-ui/components/u-scroll-list/u-scroll-list.vue uni_modules/uview-ui/components/u-search/props.js uni_modules/uview-ui/components/u-search/u-search.vue uni_modules/uview-ui/components/u-skeleton/props.js uni_modules/uview-ui/components/u-skeleton/u-skeleton.vue uni_modules/uview-ui/components/u-slider/mpother.js uni_modules/uview-ui/components/u-slider/mpwxs.js uni_modules/uview-ui/components/u-slider/mpwxs.wxs uni_modules/uview-ui/components/u-slider/nvue - 副本.js uni_modules/uview-ui/components/u-slider/nvue.js uni_modules/uview-ui/components/u-slider/props.js uni_modules/uview-ui/components/u-slider/u-slider.vue uni_modules/uview-ui/components/u-status-bar/props.js uni_modules/uview-ui/components/u-status-bar/u-status-bar.vue uni_modules/uview-ui/components/u-steps-item/props.js uni_modules/uview-ui/components/u-steps-item/u-steps-item.vue uni_modules/uview-ui/components/u-steps/props.js uni_modules/uview-ui/components/u-steps/u-steps.vue uni_modules/uview-ui/components/u-sticky/props.js uni_modules/uview-ui/components/u-sticky/u-sticky.vue uni_modules/uview-ui/components/u-subsection/props.js uni_modules/uview-ui/components/u-subsection/u-subsection.vue uni_modules/uview-ui/components/u-swipe-action-item/index - backup.wxs uni_modules/uview-ui/components/u-swipe-action-item/index.wxs uni_modules/uview-ui/components/u-swipe-action-item/nvue - backup.js uni_modules/uview-ui/components/u-swipe-action-item/nvue.js uni_modules/uview-ui/components/u-swipe-action-item/props.js uni_modules/uview-ui/components/u-swipe-action-item/u-swipe-action-item.vue uni_modules/uview-ui/components/u-swipe-action-item/wxs.js uni_modules/uview-ui/components/u-swipe-action/props.js uni_modules/uview-ui/components/u-swipe-action/u-swipe-action.vue uni_modules/uview-ui/components/u-swiper-indicator/props.js uni_modules/uview-ui/components/u-swiper-indicator/u-swiper-indicator.vue uni_modules/uview-ui/components/u-swiper/props.js uni_modules/uview-ui/components/u-swiper/u-swiper.vue uni_modules/uview-ui/components/u-switch/props.js uni_modules/uview-ui/components/u-switch/u-switch.vue uni_modules/uview-ui/components/u-tabbar-item/props.js uni_modules/uview-ui/components/u-tabbar-item/u-tabbar-item.vue uni_modules/uview-ui/components/u-tabbar/props.js uni_modules/uview-ui/components/u-tabbar/u-tabbar.vue uni_modules/uview-ui/components/u-table/props.js uni_modules/uview-ui/components/u-table/u-table.vue uni_modules/uview-ui/components/u-tabs-item/props.js uni_modules/uview-ui/components/u-tabs-item/u-tabs-item.vue uni_modules/uview-ui/components/u-tabs/props.js uni_modules/uview-ui/components/u-tabs/u-tabs.vue uni_modules/uview-ui/components/u-tag/props.js uni_modules/uview-ui/components/u-tag/u-tag.vue uni_modules/uview-ui/components/u-td/props.js uni_modules/uview-ui/components/u-td/u-td.vue uni_modules/uview-ui/components/u-text/props.js uni_modules/uview-ui/components/u-text/u-text.vue uni_modules/uview-ui/components/u-text/value.js uni_modules/uview-ui/components/u-textarea/props.js uni_modules/uview-ui/components/u-textarea/u-textarea.vue uni_modules/uview-ui/components/u-toast/u-toast.vue uni_modules/uview-ui/components/u-toolbar/props.js uni_modules/uview-ui/components/u-toolbar/u-toolbar.vue uni_modules/uview-ui/components/u-tooltip/clipboard.min.js uni_modules/uview-ui/components/u-tooltip/props.js uni_modules/uview-ui/components/u-tooltip/u-tooltip.vue uni_modules/uview-ui/components/u-tr/props.js uni_modules/uview-ui/components/u-tr/u-tr.vue uni_modules/uview-ui/components/u-transition/nvue.ani-map.js uni_modules/uview-ui/components/u-transition/props.js uni_modules/uview-ui/components/u-transition/transition.js uni_modules/uview-ui/components/u-transition/u-transition.vue uni_modules/uview-ui/components/u-transition/vue.ani-style.scss uni_modules/uview-ui/components/u-upload/mixin.js uni_modules/uview-ui/components/u-upload/props.js uni_modules/uview-ui/components/u-upload/u-upload.vue uni_modules/uview-ui/components/u-upload/utils.js uni_modules/uview-ui/components/uview-ui/uview-ui.vue uni_modules/uview-ui/index.js uni_modules/uview-ui/index.scss uni_modules/uview-ui/libs/config/color.js uni_modules/uview-ui/libs/config/config.js uni_modules/uview-ui/libs/config/props.js uni_modules/uview-ui/libs/config/props/actionSheet.js uni_modules/uview-ui/libs/config/props/album.js uni_modules/uview-ui/libs/config/props/alert.js uni_modules/uview-ui/libs/config/props/avatar.js uni_modules/uview-ui/libs/config/props/avatarGroup.js uni_modules/uview-ui/libs/config/props/backtop.js uni_modules/uview-ui/libs/config/props/badge.js uni_modules/uview-ui/libs/config/props/button.js uni_modules/uview-ui/libs/config/props/calendar.js uni_modules/uview-ui/libs/config/props/carKeyboard.js uni_modules/uview-ui/libs/config/props/cell.js uni_modules/uview-ui/libs/config/props/cellGroup.js uni_modules/uview-ui/libs/config/props/checkbox.js uni_modules/uview-ui/libs/config/props/checkboxGroup.js uni_modules/uview-ui/libs/config/props/circleProgress.js uni_modules/uview-ui/libs/config/props/code.js uni_modules/uview-ui/libs/config/props/codeInput.js uni_modules/uview-ui/libs/config/props/col.js uni_modules/uview-ui/libs/config/props/collapse.js uni_modules/uview-ui/libs/config/props/collapseItem.js uni_modules/uview-ui/libs/config/props/columnNotice.js uni_modules/uview-ui/libs/config/props/countDown.js uni_modules/uview-ui/libs/config/props/countTo.js uni_modules/uview-ui/libs/config/props/datetimePicker.js uni_modules/uview-ui/libs/config/props/divider.js uni_modules/uview-ui/libs/config/props/empty.js uni_modules/uview-ui/libs/config/props/form.js uni_modules/uview-ui/libs/config/props/formItem.js uni_modules/uview-ui/libs/config/props/gap.js uni_modules/uview-ui/libs/config/props/grid.js uni_modules/uview-ui/libs/config/props/gridItem.js uni_modules/uview-ui/libs/config/props/icon.js uni_modules/uview-ui/libs/config/props/image.js uni_modules/uview-ui/libs/config/props/indexAnchor.js uni_modules/uview-ui/libs/config/props/indexList.js uni_modules/uview-ui/libs/config/props/input.js uni_modules/uview-ui/libs/config/props/keyboard.js uni_modules/uview-ui/libs/config/props/line.js uni_modules/uview-ui/libs/config/props/lineProgress.js uni_modules/uview-ui/libs/config/props/link.js uni_modules/uview-ui/libs/config/props/list.js uni_modules/uview-ui/libs/config/props/listItem.js uni_modules/uview-ui/libs/config/props/loadingIcon.js uni_modules/uview-ui/libs/config/props/loadingPage.js uni_modules/uview-ui/libs/config/props/loadmore.js uni_modules/uview-ui/libs/config/props/modal.js uni_modules/uview-ui/libs/config/props/navbar.js uni_modules/uview-ui/libs/config/props/noNetwork.js uni_modules/uview-ui/libs/config/props/noticeBar.js uni_modules/uview-ui/libs/config/props/notify.js uni_modules/uview-ui/libs/config/props/numberBox.js uni_modules/uview-ui/libs/config/props/numberKeyboard.js uni_modules/uview-ui/libs/config/props/overlay.js uni_modules/uview-ui/libs/config/props/parse.js uni_modules/uview-ui/libs/config/props/picker.js uni_modules/uview-ui/libs/config/props/popup.js uni_modules/uview-ui/libs/config/props/radio.js uni_modules/uview-ui/libs/config/props/radioGroup.js uni_modules/uview-ui/libs/config/props/rate.js uni_modules/uview-ui/libs/config/props/readMore.js uni_modules/uview-ui/libs/config/props/row.js uni_modules/uview-ui/libs/config/props/rowNotice.js uni_modules/uview-ui/libs/config/props/scrollList.js uni_modules/uview-ui/libs/config/props/search.js uni_modules/uview-ui/libs/config/props/section.js uni_modules/uview-ui/libs/config/props/skeleton.js uni_modules/uview-ui/libs/config/props/slider.js uni_modules/uview-ui/libs/config/props/statusBar.js uni_modules/uview-ui/libs/config/props/steps.js uni_modules/uview-ui/libs/config/props/stepsItem.js uni_modules/uview-ui/libs/config/props/sticky.js uni_modules/uview-ui/libs/config/props/subsection.js uni_modules/uview-ui/libs/config/props/swipeAction.js uni_modules/uview-ui/libs/config/props/swipeActionItem.js uni_modules/uview-ui/libs/config/props/swiper.js uni_modules/uview-ui/libs/config/props/swipterIndicator.js uni_modules/uview-ui/libs/config/props/switch.js uni_modules/uview-ui/libs/config/props/tabbar.js uni_modules/uview-ui/libs/config/props/tabbarItem.js uni_modules/uview-ui/libs/config/props/tabs.js uni_modules/uview-ui/libs/config/props/tag.js uni_modules/uview-ui/libs/config/props/text.js uni_modules/uview-ui/libs/config/props/textarea.js uni_modules/uview-ui/libs/config/props/toast.js uni_modules/uview-ui/libs/config/props/toolbar.js uni_modules/uview-ui/libs/config/props/tooltip.js uni_modules/uview-ui/libs/config/props/transition.js uni_modules/uview-ui/libs/config/props/upload.js uni_modules/uview-ui/libs/config/zIndex.js uni_modules/uview-ui/libs/css/color.scss uni_modules/uview-ui/libs/css/common.scss uni_modules/uview-ui/libs/css/components.scss uni_modules/uview-ui/libs/css/flex.scss uni_modules/uview-ui/libs/css/h5.scss uni_modules/uview-ui/libs/css/mixin.scss uni_modules/uview-ui/libs/css/mp.scss uni_modules/uview-ui/libs/css/nvue.scss uni_modules/uview-ui/libs/css/vue.scss uni_modules/uview-ui/libs/function/colorGradient.js uni_modules/uview-ui/libs/function/debounce.js uni_modules/uview-ui/libs/function/digit.js uni_modules/uview-ui/libs/function/index.js uni_modules/uview-ui/libs/function/platform.js uni_modules/uview-ui/libs/function/test.js uni_modules/uview-ui/libs/function/throttle.js uni_modules/uview-ui/libs/luch-request/adapters/index.js uni_modules/uview-ui/libs/luch-request/core/InterceptorManager.js uni_modules/uview-ui/libs/luch-request/core/Request.js uni_modules/uview-ui/libs/luch-request/core/buildFullPath.js uni_modules/uview-ui/libs/luch-request/core/defaults.js uni_modules/uview-ui/libs/luch-request/core/dispatchRequest.js uni_modules/uview-ui/libs/luch-request/core/mergeConfig.js uni_modules/uview-ui/libs/luch-request/core/settle.js uni_modules/uview-ui/libs/luch-request/helpers/buildURL.js uni_modules/uview-ui/libs/luch-request/helpers/combineURLs.js uni_modules/uview-ui/libs/luch-request/helpers/isAbsoluteURL.js uni_modules/uview-ui/libs/luch-request/index.d.ts uni_modules/uview-ui/libs/luch-request/index.js uni_modules/uview-ui/libs/luch-request/utils.js uni_modules/uview-ui/libs/luch-request/utils/clone.js uni_modules/uview-ui/libs/mixin/button.js uni_modules/uview-ui/libs/mixin/mixin.js uni_modules/uview-ui/libs/mixin/mpMixin.js uni_modules/uview-ui/libs/mixin/mpShare.js uni_modules/uview-ui/libs/mixin/openType.js uni_modules/uview-ui/libs/mixin/style.js uni_modules/uview-ui/libs/mixin/touch.js uni_modules/uview-ui/libs/util/async-validator.js uni_modules/uview-ui/libs/util/calendar.js uni_modules/uview-ui/libs/util/dayjs.js uni_modules/uview-ui/libs/util/emitter.js uni_modules/uview-ui/libs/util/route.js uni_modules/uview-ui/package.json uni_modules/uview-ui/theme.scss utils/storage.js utils/verify.js vite.config.js (已删除) vue.config.js yarn.lock (已删除)