From 0decd78604b34e341ff95b2830ecfd3bd794f77b Mon Sep 17 00:00:00 2001
From: b2894lxlx <517289602@qq.com>
Date: Wed, 25 Mar 2026 15:59:24 +0800
Subject: [PATCH] =?UTF-8?q?20260325=E7=A8=B3=E5=AE=9A=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 2 +
App.vue | 18 +
api/chat.js | 15 +
api/coin.js | 6 +
api/common.js | 43 +
api/complain.js | 3 +
api/request.js | 106 ++
api/user.js | 27 +
components/HeaderItem.vue | 41 +
components/Login.vue | 204 +++
components/TitleItem.vue | 18 +
components/customTabbar.vue | 120 ++
config/color.js | 18 +
config/index.js | 23 +
index.html | 20 +
.../luch-request/adapters/index.js | 100 ++
.../luch-request/core/InterceptorManager.js | 51 +
.../luch-request/luch-request/core/Request.js | 197 +++
.../luch-request/core/buildFullPath.js | 20 +
.../luch-request/core/defaults.js | 31 +
.../luch-request/core/dispatchRequest.js | 6 +
.../luch-request/core/mergeConfig.js | 103 ++
.../luch-request/luch-request/core/settle.js | 16 +
.../luch-request/helpers/buildURL.js | 64 +
.../luch-request/helpers/combineURLs.js | 14 +
.../luch-request/helpers/isAbsoluteURL.js | 14 +
js_sdk/luch-request/luch-request/index.d.ts | 120 ++
js_sdk/luch-request/luch-request/index.js | 2 +
js_sdk/luch-request/luch-request/utils.js | 135 ++
.../luch-request/luch-request/utils/clone.js | 264 ++++
js_sdk/luch-request/package.json | 19 +
js_sdk/qqmap-wx-jssdk/qqmap-wx-jssdk.js | 1122 ++++++++++++++
js_sdk/qqmap-wx-jssdk/qqmap-wx-jssdk.min.js | 1 +
main.js | 40 +
manifest.json | 72 +
pages.json | 150 ++
pages/ai/index.vue | 265 ++++
pages/chat/index.vue | 1012 +++++++++++++
pages/chat/select.vue | 579 +++++++
pages/index/detail.vue | 645 ++++++++
pages/index/index.vue | 326 ++++
pages/msg/index.vue | 285 ++++
pages/user/coin.vue | 542 +++++++
pages/user/collect.vue | 136 ++
pages/user/feedback.vue | 259 ++++
pages/user/index.vue | 490 ++++++
pages/user/profile.vue | 119 ++
pages/user/setting.vue | 679 +++++++++
static/home-active.png | Bin 0 -> 23517 bytes
static/home.png | Bin 0 -> 23462 bytes
static/icon/haFill-23-star 1@1x.png | Bin 0 -> 587 bytes
static/icon/iconPark-comment 1@1x.png | Bin 0 -> 518 bytes
static/icon/iconPark-share-one 1@1x.png | Bin 0 -> 422 bytes
.../md-play_circle_filled 1 Copy 1@1x.png | Bin 0 -> 507 bytes
static/icon/stLine-diamond-l 1@1x.png | Bin 0 -> 664 bytes
static/icon/复制-black.png | Bin 0 -> 14638 bytes
static/icon/复制.png | Bin 0 -> 14203 bytes
static/icon/按钮2 1@1x.png | Bin 0 -> 3013 bytes
static/icon/话筒.png | Bin 0 -> 16779 bytes
static/icon/轮播图 Copy kTtd4FG@1x.png | Bin 0 -> 145071 bytes
static/icon/键盘.png | Bin 0 -> 13265 bytes
static/icon/音量.png | Bin 0 -> 3788 bytes
static/logo.jpg | Bin 0 -> 29700 bytes
static/logo.png | Bin 0 -> 2434 bytes
static/msg-active.png | Bin 0 -> 1949 bytes
static/msg.png | Bin 0 -> 423 bytes
static/service.png | Bin 0 -> 64976 bytes
static/stop.png | Bin 0 -> 2030 bytes
static/style/common.scss | 829 ++++++++++
static/user-active.png | Bin 0 -> 254 bytes
static/user.png | Bin 0 -> 592 bytes
uni.promisify.adaptor.js | 13 +
uni.scss | 78 +
uni_modules/iRainna-dayjs/changelog.md | 4 +
uni_modules/iRainna-dayjs/js_sdk/dayjs.min.js | 1 +
uni_modules/iRainna-dayjs/package.json | 81 +
uni_modules/iRainna-dayjs/readme.md | 10 +
uni_modules/m-tabbar/changelog.md | 76 +
.../m-tabbar/components/m-tabbar/m-tabbar.vue | 516 +++++++
uni_modules/m-tabbar/package.json | 81 +
uni_modules/m-tabbar/readme.md | 312 ++++
uni_modules/piaoyi-progress-bar/changelog.md | 2 +
.../piaoyi-progress-bar.vue | 157 ++
uni_modules/piaoyi-progress-bar/package.json | 15 +
uni_modules/piaoyi-progress-bar/readme.md | 56 +
uni_modules/uview-ui/LICENSE | 21 +
uni_modules/uview-ui/README.md | 66 +
uni_modules/uview-ui/changelog.md | 376 +++++
.../uview-ui/components/u--form/u--form.vue | 78 +
.../uview-ui/components/u--image/u--image.vue | 47 +
.../uview-ui/components/u--input/u--input.vue | 73 +
.../uview-ui/components/u--text/u--text.vue | 44 +
.../components/u--textarea/u--textarea.vue | 48 +
.../components/u-action-sheet/props.js | 54 +
.../u-action-sheet/u-action-sheet.vue | 278 ++++
.../uview-ui/components/u-album/props.js | 59 +
.../uview-ui/components/u-album/u-album.vue | 259 ++++
.../uview-ui/components/u-alert/props.js | 44 +
.../uview-ui/components/u-alert/u-alert.vue | 243 +++
.../components/u-avatar-group/props.js | 52 +
.../u-avatar-group/u-avatar-group.vue | 103 ++
.../uview-ui/components/u-avatar/props.js | 78 +
.../uview-ui/components/u-avatar/u-avatar.vue | 173 +++
.../uview-ui/components/u-back-top/props.js | 54 +
.../components/u-back-top/u-back-top.vue | 129 ++
.../uview-ui/components/u-badge/props.js | 72 +
.../uview-ui/components/u-badge/u-badge.vue | 171 +++
.../uview-ui/components/u-button/nvue.scss | 46 +
.../uview-ui/components/u-button/props.js | 161 ++
.../uview-ui/components/u-button/u-button.vue | 495 ++++++
.../uview-ui/components/u-button/vue.scss | 80 +
.../uview-ui/components/u-calendar/header.vue | 99 ++
.../uview-ui/components/u-calendar/month.vue | 579 +++++++
.../uview-ui/components/u-calendar/props.js | 144 ++
.../components/u-calendar/u-calendar.vue | 384 +++++
.../uview-ui/components/u-calendar/util.js | 85 ++
.../components/u-car-keyboard/props.js | 14 +
.../u-car-keyboard/u-car-keyboard.vue | 311 ++++
.../uview-ui/components/u-cell-group/props.js | 14 +
.../components/u-cell-group/u-cell-group.vue | 61 +
.../uview-ui/components/u-cell/props.js | 110 ++
.../uview-ui/components/u-cell/u-cell.vue | 229 +++
.../components/u-checkbox-group/props.js | 82 +
.../u-checkbox-group/u-checkbox-group.vue | 103 ++
.../uview-ui/components/u-checkbox/props.js | 69 +
.../components/u-checkbox/u-checkbox.vue | 344 +++++
.../components/u-circle-progress/props.js | 8 +
.../u-circle-progress/u-circle-progress.vue | 198 +++
.../uview-ui/components/u-code-input/props.js | 79 +
.../components/u-code-input/u-code-input.vue | 252 ++++
.../uview-ui/components/u-code/props.js | 34 +
.../uview-ui/components/u-code/u-code.vue | 129 ++
.../uview-ui/components/u-col/props.js | 29 +
.../uview-ui/components/u-col/u-col.vue | 162 ++
.../components/u-collapse-item/props.js | 59 +
.../u-collapse-item/u-collapse-item.vue | 225 +++
.../uview-ui/components/u-collapse/props.js | 19 +
.../components/u-collapse/u-collapse.vue | 90 ++
.../components/u-column-notice/props.js | 55 +
.../u-column-notice/u-column-notice.vue | 160 ++
.../uview-ui/components/u-count-down/props.js | 24 +
.../components/u-count-down/u-count-down.vue | 163 ++
.../uview-ui/components/u-count-down/utils.js | 62 +
.../uview-ui/components/u-count-to/props.js | 59 +
.../components/u-count-to/u-count-to.vue | 184 +++
.../components/u-datetime-picker/props.js | 116 ++
.../u-datetime-picker/u-datetime-picker.vue | 360 +++++
.../uview-ui/components/u-divider/props.js | 44 +
.../components/u-divider/u-divider.vue | 116 ++
.../components/u-dropdown-item/props.js | 36 +
.../u-dropdown-item/u-dropdown-item.vue | 127 ++
.../uview-ui/components/u-dropdown/props.js | 65 +
.../components/u-dropdown/u-dropdown.vue | 127 ++
.../uview-ui/components/u-empty/props.js | 59 +
.../uview-ui/components/u-empty/u-empty.vue | 128 ++
.../uview-ui/components/u-form-item/props.js | 48 +
.../components/u-form-item/u-form-item.vue | 235 +++
.../uview-ui/components/u-form/props.js | 45 +
.../uview-ui/components/u-form/u-form.vue | 214 +++
.../uview-ui/components/u-gap/props.js | 24 +
.../uview-ui/components/u-gap/u-gap.vue | 38 +
.../uview-ui/components/u-grid-item/props.js | 14 +
.../components/u-grid-item/u-grid-item.vue | 209 +++
.../uview-ui/components/u-grid/props.js | 19 +
.../uview-ui/components/u-grid/u-grid.vue | 97 ++
.../uview-ui/components/u-icon/icons.js | 214 +++
.../uview-ui/components/u-icon/props.js | 89 ++
.../uview-ui/components/u-icon/u-icon.vue | 234 +++
.../uview-ui/components/u-image/props.js | 84 ++
.../uview-ui/components/u-image/u-image.vue | 232 +++
.../components/u-index-anchor/props.js | 29 +
.../u-index-anchor/u-index-anchor.vue | 91 ++
.../uview-ui/components/u-index-item/props.js | 5 +
.../components/u-index-item/u-index-item.vue | 87 ++
.../uview-ui/components/u-index-list/props.js | 29 +
.../components/u-index-list/u-index-list.vue | 440 ++++++
.../uview-ui/components/u-input/props.js | 187 +++
.../uview-ui/components/u-input/u-input.vue | 354 +++++
.../uview-ui/components/u-keyboard/props.js | 84 ++
.../components/u-keyboard/u-keyboard.vue | 164 ++
.../components/u-line-progress/props.js | 28 +
.../u-line-progress/u-line-progress.vue | 144 ++
.../uview-ui/components/u-line/props.js | 33 +
.../uview-ui/components/u-line/u-line.vue | 62 +
.../uview-ui/components/u-link/props.js | 39 +
.../uview-ui/components/u-link/u-link.vue | 83 +
.../uview-ui/components/u-list-item/props.js | 9 +
.../components/u-list-item/u-list-item.vue | 116 ++
.../uview-ui/components/u-list/props.js | 76 +
.../uview-ui/components/u-list/u-list.vue | 157 ++
.../components/u-loading-icon/props.js | 59 +
.../u-loading-icon/u-loading-icon.vue | 343 +++++
.../components/u-loading-page/props.js | 49 +
.../u-loading-page/u-loading-page.vue | 115 ++
.../uview-ui/components/u-loadmore/props.js | 94 ++
.../components/u-loadmore/u-loadmore.vue | 150 ++
.../uview-ui/components/u-modal/props.js | 89 ++
.../uview-ui/components/u-modal/u-modal.vue | 228 +++
.../uview-ui/components/u-navbar/props.js | 89 ++
.../uview-ui/components/u-navbar/u-navbar.vue | 187 +++
.../uview-ui/components/u-no-network/props.js | 19 +
.../components/u-no-network/u-no-network.vue | 220 +++
.../uview-ui/components/u-notice-bar/props.js | 70 +
.../components/u-notice-bar/u-notice-bar.vue | 101 ++
.../uview-ui/components/u-notify/props.js | 49 +
.../uview-ui/components/u-notify/u-notify.vue | 211 +++
.../uview-ui/components/u-number-box/props.js | 109 ++
.../components/u-number-box/u-number-box.vue | 416 +++++
.../components/u-number-keyboard/props.js | 19 +
.../u-number-keyboard/u-number-keyboard.vue | 196 +++
.../uview-ui/components/u-overlay/props.js | 24 +
.../components/u-overlay/u-overlay.vue | 68 +
.../uview-ui/components/u-parse/node/node.vue | 499 ++++++
.../uview-ui/components/u-parse/parser.js | 1075 +++++++++++++
.../uview-ui/components/u-parse/props.js | 45 +
.../uview-ui/components/u-parse/u-parse.vue | 366 +++++
.../components/u-picker-column/props.js | 5 +
.../u-picker-column/u-picker-column.vue | 27 +
.../uview-ui/components/u-picker/props.js | 79 +
.../uview-ui/components/u-picker/u-picker.vue | 289 ++++
.../uview-ui/components/u-popup/props.js | 79 +
.../uview-ui/components/u-popup/u-popup.vue | 304 ++++
.../components/u-radio-group/props.js | 85 ++
.../u-radio-group/u-radio-group.vue | 108 ++
.../uview-ui/components/u-radio/props.js | 64 +
.../uview-ui/components/u-radio/u-radio.vue | 339 +++++
.../uview-ui/components/u-rate/props.js | 69 +
.../uview-ui/components/u-rate/u-rate.vue | 306 ++++
.../uview-ui/components/u-read-more/props.js | 61 +
.../components/u-read-more/u-read-more.vue | 157 ++
.../uview-ui/components/u-row-notice/props.js | 39 +
.../components/u-row-notice/u-row-notice.vue | 330 ++++
.../uview-ui/components/u-row/props.js | 19 +
.../uview-ui/components/u-row/u-row.vue | 93 ++
.../components/u-safe-bottom/props.js | 5 +
.../u-safe-bottom/u-safe-bottom.vue | 56 +
.../uview-ui/components/u-scroll-list/nvue.js | 28 +
.../components/u-scroll-list/other.js | 0
.../components/u-scroll-list/props.js | 34 +
.../components/u-scroll-list/scrollWxs.wxs | 50 +
.../u-scroll-list/u-scroll-list.vue | 224 +++
.../uview-ui/components/u-search/props.js | 118 ++
.../uview-ui/components/u-search/u-search.vue | 303 ++++
.../uview-ui/components/u-skeleton/props.js | 59 +
.../components/u-skeleton/u-skeleton.vue | 244 +++
.../uview-ui/components/u-slider/mpother.js | 113 ++
.../uview-ui/components/u-slider/mpwxs.js | 42 +
.../uview-ui/components/u-slider/mpwxs.wxs | 121 ++
.../components/u-slider/nvue - 副本.js | 180 +++
.../uview-ui/components/u-slider/nvue.js | 193 +++
.../uview-ui/components/u-slider/props.js | 54 +
.../uview-ui/components/u-slider/u-slider.vue | 55 +
.../uview-ui/components/u-status-bar/props.js | 8 +
.../components/u-status-bar/u-status-bar.vue | 46 +
.../uview-ui/components/u-steps-item/props.js | 24 +
.../components/u-steps-item/u-steps-item.vue | 316 ++++
.../uview-ui/components/u-steps/props.js | 39 +
.../uview-ui/components/u-steps/u-steps.vue | 80 +
.../uview-ui/components/u-sticky/props.js | 40 +
.../uview-ui/components/u-sticky/u-sticky.vue | 212 +++
.../uview-ui/components/u-subsection/props.js | 49 +
.../components/u-subsection/u-subsection.vue | 299 ++++
.../u-swipe-action-item/index - backup.wxs | 256 ++++
.../components/u-swipe-action-item/index.wxs | 225 +++
.../u-swipe-action-item/nvue - backup.js | 270 ++++
.../components/u-swipe-action-item/nvue.js | 174 +++
.../components/u-swipe-action-item/props.js | 41 +
.../u-swipe-action-item.vue | 190 +++
.../components/u-swipe-action-item/wxs.js | 15 +
.../components/u-swipe-action/props.js | 9 +
.../u-swipe-action/u-swipe-action.vue | 67 +
.../components/u-swiper-indicator/props.js | 29 +
.../u-swiper-indicator/u-swiper-indicator.vue | 110 ++
.../uview-ui/components/u-swiper/props.js | 125 ++
.../uview-ui/components/u-swiper/u-swiper.vue | 255 ++++
.../uview-ui/components/u-switch/props.js | 54 +
.../uview-ui/components/u-switch/u-switch.vue | 177 +++
.../components/u-tabbar-item/props.js | 35 +
.../u-tabbar-item/u-tabbar-item.vue | 142 ++
.../uview-ui/components/u-tabbar/props.js | 44 +
.../uview-ui/components/u-tabbar/u-tabbar.vue | 141 ++
.../uview-ui/components/u-table/props.js | 5 +
.../uview-ui/components/u-table/u-table.vue | 29 +
.../uview-ui/components/u-tabs-item/props.js | 5 +
.../components/u-tabs-item/u-tabs-item.vue | 29 +
.../uview-ui/components/u-tabs/props.js | 64 +
.../uview-ui/components/u-tabs/u-tabs.vue | 363 +++++
.../uview-ui/components/u-tag/props.js | 84 ++
.../uview-ui/components/u-tag/u-tag.vue | 358 +++++
uni_modules/uview-ui/components/u-td/props.js | 5 +
uni_modules/uview-ui/components/u-td/u-td.vue | 31 +
.../uview-ui/components/u-text/props.js | 110 ++
.../uview-ui/components/u-text/u-text.vue | 223 +++
.../uview-ui/components/u-text/value.js | 85 ++
.../uview-ui/components/u-textarea/props.js | 119 ++
.../components/u-textarea/u-textarea.vue | 239 +++
.../uview-ui/components/u-toast/u-toast.vue | 291 ++++
.../uview-ui/components/u-toolbar/props.js | 34 +
.../components/u-toolbar/u-toolbar.vue | 102 ++
.../components/u-tooltip/clipboard.min.js | 58 +
.../uview-ui/components/u-tooltip/props.js | 59 +
.../components/u-tooltip/u-tooltip.vue | 365 +++++
uni_modules/uview-ui/components/u-tr/props.js | 5 +
uni_modules/uview-ui/components/u-tr/u-tr.vue | 31 +
.../components/u-transition/nvue.ani-map.js | 68 +
.../uview-ui/components/u-transition/props.js | 24 +
.../components/u-transition/transition.js | 157 ++
.../components/u-transition/u-transition.vue | 92 ++
.../u-transition/vue.ani-style.scss | 113 ++
.../uview-ui/components/u-upload/mixin.js | 21 +
.../uview-ui/components/u-upload/props.js | 124 ++
.../uview-ui/components/u-upload/u-upload.vue | 558 +++++++
.../uview-ui/components/u-upload/utils.js | 151 ++
.../uview-ui/components/uview-ui/uview-ui.vue | 15 +
uni_modules/uview-ui/index.js | 79 +
uni_modules/uview-ui/index.scss | 23 +
uni_modules/uview-ui/libs/config/color.js | 17 +
uni_modules/uview-ui/libs/config/config.js | 34 +
uni_modules/uview-ui/libs/config/props.js | 190 +++
.../uview-ui/libs/config/props/actionSheet.js | 25 +
.../uview-ui/libs/config/props/album.js | 25 +
.../uview-ui/libs/config/props/alert.js | 22 +
.../uview-ui/libs/config/props/avatar.js | 28 +
.../uview-ui/libs/config/props/avatarGroup.js | 23 +
.../uview-ui/libs/config/props/backtop.js | 27 +
.../uview-ui/libs/config/props/badge.js | 27 +
.../uview-ui/libs/config/props/button.js | 42 +
.../uview-ui/libs/config/props/calendar.js | 42 +
.../uview-ui/libs/config/props/carKeyboard.js | 15 +
.../uview-ui/libs/config/props/cell.js | 35 +
.../uview-ui/libs/config/props/cellGroup.js | 17 +
.../uview-ui/libs/config/props/checkbox.js | 27 +
.../libs/config/props/checkboxGroup.js | 29 +
.../libs/config/props/circleProgress.js | 15 +
.../uview-ui/libs/config/props/code.js | 21 +
.../uview-ui/libs/config/props/codeInput.js | 29 +
uni_modules/uview-ui/libs/config/props/col.js | 19 +
.../uview-ui/libs/config/props/collapse.js | 17 +
.../libs/config/props/collapseItem.js | 25 +
.../libs/config/props/columnNotice.js | 24 +
.../uview-ui/libs/config/props/countDown.js | 18 +
.../uview-ui/libs/config/props/countTo.js | 25 +
.../libs/config/props/datetimePicker.js | 36 +
.../uview-ui/libs/config/props/divider.js | 23 +
.../uview-ui/libs/config/props/empty.js | 26 +
.../uview-ui/libs/config/props/form.js | 22 +
.../uview-ui/libs/config/props/formItem.js | 23 +
uni_modules/uview-ui/libs/config/props/gap.js | 19 +
.../uview-ui/libs/config/props/grid.js | 17 +
.../uview-ui/libs/config/props/gridItem.js | 16 +
.../uview-ui/libs/config/props/icon.js | 36 +
.../uview-ui/libs/config/props/image.js | 30 +
.../uview-ui/libs/config/props/indexAnchor.js | 19 +
.../uview-ui/libs/config/props/indexList.js | 19 +
.../uview-ui/libs/config/props/input.js | 48 +
.../uview-ui/libs/config/props/keyboard.js | 30 +
.../uview-ui/libs/config/props/line.js | 20 +
.../libs/config/props/lineProgress.js | 19 +
.../uview-ui/libs/config/props/link.js | 26 +
.../uview-ui/libs/config/props/list.js | 28 +
.../uview-ui/libs/config/props/listItem.js | 15 +
.../uview-ui/libs/config/props/loadingIcon.js | 30 +
.../uview-ui/libs/config/props/loadingPage.js | 23 +
.../uview-ui/libs/config/props/loadmore.js | 32 +
.../uview-ui/libs/config/props/modal.js | 31 +
.../uview-ui/libs/config/props/navbar.js | 32 +
.../uview-ui/libs/config/props/noNetwork.js | 18 +
.../uview-ui/libs/config/props/noticeBar.js | 27 +
.../uview-ui/libs/config/props/notify.js | 22 +
.../uview-ui/libs/config/props/numberBox.js | 35 +
.../libs/config/props/numberKeyboard.js | 17 +
.../uview-ui/libs/config/props/overlay.js | 18 +
.../uview-ui/libs/config/props/parse.js | 22 +
.../uview-ui/libs/config/props/picker.js | 29 +
.../uview-ui/libs/config/props/popup.js | 29 +
.../uview-ui/libs/config/props/radio.js | 27 +
.../uview-ui/libs/config/props/radioGroup.js | 30 +
.../uview-ui/libs/config/props/rate.js | 26 +
.../uview-ui/libs/config/props/readMore.js | 22 +
uni_modules/uview-ui/libs/config/props/row.js | 17 +
.../uview-ui/libs/config/props/rowNotice.js | 21 +
.../uview-ui/libs/config/props/scrollList.js | 20 +
.../uview-ui/libs/config/props/search.js | 37 +
.../uview-ui/libs/config/props/section.js | 24 +
.../uview-ui/libs/config/props/skeleton.js | 25 +
.../uview-ui/libs/config/props/slider.js | 25 +
.../uview-ui/libs/config/props/statusBar.js | 15 +
.../uview-ui/libs/config/props/steps.js | 21 +
.../uview-ui/libs/config/props/stepsItem.js | 18 +
.../uview-ui/libs/config/props/sticky.js | 20 +
.../uview-ui/libs/config/props/subsection.js | 23 +
.../uview-ui/libs/config/props/swipeAction.js | 15 +
.../libs/config/props/swipeActionItem.js | 21 +
.../uview-ui/libs/config/props/swiper.js | 39 +
.../libs/config/props/swipterIndicator.js | 19 +
.../uview-ui/libs/config/props/switch.js | 24 +
.../uview-ui/libs/config/props/tabbar.js | 22 +
.../uview-ui/libs/config/props/tabbarItem.js | 20 +
.../uview-ui/libs/config/props/tabs.js | 32 +
uni_modules/uview-ui/libs/config/props/tag.js | 29 +
.../uview-ui/libs/config/props/text.js | 38 +
.../uview-ui/libs/config/props/textarea.js | 36 +
.../uview-ui/libs/config/props/toast.js | 30 +
.../uview-ui/libs/config/props/toolbar.js | 21 +
.../uview-ui/libs/config/props/tooltip.js | 25 +
.../uview-ui/libs/config/props/transition.js | 18 +
.../uview-ui/libs/config/props/upload.js | 36 +
uni_modules/uview-ui/libs/config/zIndex.js | 20 +
uni_modules/uview-ui/libs/css/color.scss | 155 ++
uni_modules/uview-ui/libs/css/common.scss | 97 ++
uni_modules/uview-ui/libs/css/components.scss | 15 +
uni_modules/uview-ui/libs/css/flex.scss | 257 ++++
uni_modules/uview-ui/libs/css/h5.scss | 0
uni_modules/uview-ui/libs/css/mixin.scss | 8 +
uni_modules/uview-ui/libs/css/mp.scss | 0
uni_modules/uview-ui/libs/css/nvue.scss | 0
uni_modules/uview-ui/libs/css/vue.scss | 27 +
.../uview-ui/libs/function/colorGradient.js | 134 ++
.../uview-ui/libs/function/debounce.js | 29 +
uni_modules/uview-ui/libs/function/digit.js | 167 ++
uni_modules/uview-ui/libs/function/index.js | 731 +++++++++
.../uview-ui/libs/function/platform.js | 75 +
uni_modules/uview-ui/libs/function/test.js | 288 ++++
.../uview-ui/libs/function/throttle.js | 30 +
.../libs/luch-request/adapters/index.js | 97 ++
.../luch-request/core/InterceptorManager.js | 50 +
.../libs/luch-request/core/Request.js | 198 +++
.../libs/luch-request/core/buildFullPath.js | 20 +
.../libs/luch-request/core/defaults.js | 29 +
.../libs/luch-request/core/dispatchRequest.js | 3 +
.../libs/luch-request/core/mergeConfig.js | 103 ++
.../uview-ui/libs/luch-request/core/settle.js | 16 +
.../libs/luch-request/helpers/buildURL.js | 69 +
.../libs/luch-request/helpers/combineURLs.js | 14 +
.../luch-request/helpers/isAbsoluteURL.js | 14 +
.../uview-ui/libs/luch-request/index.d.ts | 116 ++
.../uview-ui/libs/luch-request/index.js | 3 +
.../uview-ui/libs/luch-request/utils.js | 131 ++
.../uview-ui/libs/luch-request/utils/clone.js | 264 ++++
uni_modules/uview-ui/libs/mixin/button.js | 13 +
uni_modules/uview-ui/libs/mixin/mixin.js | 160 ++
uni_modules/uview-ui/libs/mixin/mpMixin.js | 8 +
uni_modules/uview-ui/libs/mixin/mpShare.js | 13 +
uni_modules/uview-ui/libs/mixin/openType.js | 25 +
uni_modules/uview-ui/libs/mixin/style.js | 228 +++
uni_modules/uview-ui/libs/mixin/touch.js | 59 +
.../uview-ui/libs/util/async-validator.js | 1343 +++++++++++++++++
uni_modules/uview-ui/libs/util/calendar.js | 546 +++++++
uni_modules/uview-ui/libs/util/dayjs.js | 308 ++++
uni_modules/uview-ui/libs/util/emitter.js | 51 +
uni_modules/uview-ui/libs/util/route.js | 124 ++
uni_modules/uview-ui/package.json | 85 ++
uni_modules/uview-ui/theme.scss | 44 +
uni_modules/zero-markdown-view/changelog.md | 15 +
.../components/mp-html/highlight/config.js | 5 +
.../components/mp-html/highlight/index.js | 109 ++
.../components/mp-html/highlight/prism.min.js | 7 +
.../components/mp-html/markdown/index.js | 34 +
.../components/mp-html/markdown/marked.min.js | 6 +
.../components/mp-html/mp-html.vue | 503 ++++++
.../components/mp-html/node/node.vue | 678 +++++++++
.../components/mp-html/parser.js | 1335 ++++++++++++++++
.../components/mp-html/style/index.js | 129 ++
.../components/mp-html/style/parser.js | 175 +++
.../zero-markdown-view/zero-markdown-view.vue | 177 +++
uni_modules/zero-markdown-view/package.json | 86 ++
uni_modules/zero-markdown-view/readme.md | 134 ++
util/index.js | 238 +++
util/order.js | 100 ++
util/user.js | 51 +
470 files changed, 53100 insertions(+)
create mode 100644 .gitignore
create mode 100644 App.vue
create mode 100644 api/chat.js
create mode 100644 api/coin.js
create mode 100644 api/common.js
create mode 100644 api/complain.js
create mode 100644 api/request.js
create mode 100644 api/user.js
create mode 100644 components/HeaderItem.vue
create mode 100644 components/Login.vue
create mode 100644 components/TitleItem.vue
create mode 100644 components/customTabbar.vue
create mode 100644 config/color.js
create mode 100644 config/index.js
create mode 100644 index.html
create mode 100644 js_sdk/luch-request/luch-request/adapters/index.js
create mode 100644 js_sdk/luch-request/luch-request/core/InterceptorManager.js
create mode 100644 js_sdk/luch-request/luch-request/core/Request.js
create mode 100644 js_sdk/luch-request/luch-request/core/buildFullPath.js
create mode 100644 js_sdk/luch-request/luch-request/core/defaults.js
create mode 100644 js_sdk/luch-request/luch-request/core/dispatchRequest.js
create mode 100644 js_sdk/luch-request/luch-request/core/mergeConfig.js
create mode 100644 js_sdk/luch-request/luch-request/core/settle.js
create mode 100644 js_sdk/luch-request/luch-request/helpers/buildURL.js
create mode 100644 js_sdk/luch-request/luch-request/helpers/combineURLs.js
create mode 100644 js_sdk/luch-request/luch-request/helpers/isAbsoluteURL.js
create mode 100644 js_sdk/luch-request/luch-request/index.d.ts
create mode 100644 js_sdk/luch-request/luch-request/index.js
create mode 100644 js_sdk/luch-request/luch-request/utils.js
create mode 100644 js_sdk/luch-request/luch-request/utils/clone.js
create mode 100644 js_sdk/luch-request/package.json
create mode 100644 js_sdk/qqmap-wx-jssdk/qqmap-wx-jssdk.js
create mode 100644 js_sdk/qqmap-wx-jssdk/qqmap-wx-jssdk.min.js
create mode 100644 main.js
create mode 100644 manifest.json
create mode 100644 pages.json
create mode 100644 pages/ai/index.vue
create mode 100644 pages/chat/index.vue
create mode 100644 pages/chat/select.vue
create mode 100644 pages/index/detail.vue
create mode 100644 pages/index/index.vue
create mode 100644 pages/msg/index.vue
create mode 100644 pages/user/coin.vue
create mode 100644 pages/user/collect.vue
create mode 100644 pages/user/feedback.vue
create mode 100644 pages/user/index.vue
create mode 100644 pages/user/profile.vue
create mode 100644 pages/user/setting.vue
create mode 100644 static/home-active.png
create mode 100644 static/home.png
create mode 100644 static/icon/haFill-23-star 1@1x.png
create mode 100644 static/icon/iconPark-comment 1@1x.png
create mode 100644 static/icon/iconPark-share-one 1@1x.png
create mode 100644 static/icon/md-play_circle_filled 1 Copy 1@1x.png
create mode 100644 static/icon/stLine-diamond-l 1@1x.png
create mode 100644 static/icon/复制-black.png
create mode 100644 static/icon/复制.png
create mode 100644 static/icon/按钮2 1@1x.png
create mode 100644 static/icon/话筒.png
create mode 100644 static/icon/轮播图 Copy kTtd4FG@1x.png
create mode 100644 static/icon/键盘.png
create mode 100644 static/icon/音量.png
create mode 100644 static/logo.jpg
create mode 100644 static/logo.png
create mode 100644 static/msg-active.png
create mode 100644 static/msg.png
create mode 100644 static/service.png
create mode 100644 static/stop.png
create mode 100644 static/style/common.scss
create mode 100644 static/user-active.png
create mode 100644 static/user.png
create mode 100644 uni.promisify.adaptor.js
create mode 100644 uni.scss
create mode 100644 uni_modules/iRainna-dayjs/changelog.md
create mode 100644 uni_modules/iRainna-dayjs/js_sdk/dayjs.min.js
create mode 100644 uni_modules/iRainna-dayjs/package.json
create mode 100644 uni_modules/iRainna-dayjs/readme.md
create mode 100644 uni_modules/m-tabbar/changelog.md
create mode 100644 uni_modules/m-tabbar/components/m-tabbar/m-tabbar.vue
create mode 100644 uni_modules/m-tabbar/package.json
create mode 100644 uni_modules/m-tabbar/readme.md
create mode 100644 uni_modules/piaoyi-progress-bar/changelog.md
create mode 100644 uni_modules/piaoyi-progress-bar/components/piaoyi-progress-bar/piaoyi-progress-bar.vue
create mode 100644 uni_modules/piaoyi-progress-bar/package.json
create mode 100644 uni_modules/piaoyi-progress-bar/readme.md
create mode 100644 uni_modules/uview-ui/LICENSE
create mode 100644 uni_modules/uview-ui/README.md
create mode 100644 uni_modules/uview-ui/changelog.md
create mode 100644 uni_modules/uview-ui/components/u--form/u--form.vue
create mode 100644 uni_modules/uview-ui/components/u--image/u--image.vue
create mode 100644 uni_modules/uview-ui/components/u--input/u--input.vue
create mode 100644 uni_modules/uview-ui/components/u--text/u--text.vue
create mode 100644 uni_modules/uview-ui/components/u--textarea/u--textarea.vue
create mode 100644 uni_modules/uview-ui/components/u-action-sheet/props.js
create mode 100644 uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue
create mode 100644 uni_modules/uview-ui/components/u-album/props.js
create mode 100644 uni_modules/uview-ui/components/u-album/u-album.vue
create mode 100644 uni_modules/uview-ui/components/u-alert/props.js
create mode 100644 uni_modules/uview-ui/components/u-alert/u-alert.vue
create mode 100644 uni_modules/uview-ui/components/u-avatar-group/props.js
create mode 100644 uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue
create mode 100644 uni_modules/uview-ui/components/u-avatar/props.js
create mode 100644 uni_modules/uview-ui/components/u-avatar/u-avatar.vue
create mode 100644 uni_modules/uview-ui/components/u-back-top/props.js
create mode 100644 uni_modules/uview-ui/components/u-back-top/u-back-top.vue
create mode 100644 uni_modules/uview-ui/components/u-badge/props.js
create mode 100644 uni_modules/uview-ui/components/u-badge/u-badge.vue
create mode 100644 uni_modules/uview-ui/components/u-button/nvue.scss
create mode 100644 uni_modules/uview-ui/components/u-button/props.js
create mode 100644 uni_modules/uview-ui/components/u-button/u-button.vue
create mode 100644 uni_modules/uview-ui/components/u-button/vue.scss
create mode 100644 uni_modules/uview-ui/components/u-calendar/header.vue
create mode 100644 uni_modules/uview-ui/components/u-calendar/month.vue
create mode 100644 uni_modules/uview-ui/components/u-calendar/props.js
create mode 100644 uni_modules/uview-ui/components/u-calendar/u-calendar.vue
create mode 100644 uni_modules/uview-ui/components/u-calendar/util.js
create mode 100644 uni_modules/uview-ui/components/u-car-keyboard/props.js
create mode 100644 uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue
create mode 100644 uni_modules/uview-ui/components/u-cell-group/props.js
create mode 100644 uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue
create mode 100644 uni_modules/uview-ui/components/u-cell/props.js
create mode 100644 uni_modules/uview-ui/components/u-cell/u-cell.vue
create mode 100644 uni_modules/uview-ui/components/u-checkbox-group/props.js
create mode 100644 uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue
create mode 100644 uni_modules/uview-ui/components/u-checkbox/props.js
create mode 100644 uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue
create mode 100644 uni_modules/uview-ui/components/u-circle-progress/props.js
create mode 100644 uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue
create mode 100644 uni_modules/uview-ui/components/u-code-input/props.js
create mode 100644 uni_modules/uview-ui/components/u-code-input/u-code-input.vue
create mode 100644 uni_modules/uview-ui/components/u-code/props.js
create mode 100644 uni_modules/uview-ui/components/u-code/u-code.vue
create mode 100644 uni_modules/uview-ui/components/u-col/props.js
create mode 100644 uni_modules/uview-ui/components/u-col/u-col.vue
create mode 100644 uni_modules/uview-ui/components/u-collapse-item/props.js
create mode 100644 uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue
create mode 100644 uni_modules/uview-ui/components/u-collapse/props.js
create mode 100644 uni_modules/uview-ui/components/u-collapse/u-collapse.vue
create mode 100644 uni_modules/uview-ui/components/u-column-notice/props.js
create mode 100644 uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue
create mode 100644 uni_modules/uview-ui/components/u-count-down/props.js
create mode 100644 uni_modules/uview-ui/components/u-count-down/u-count-down.vue
create mode 100644 uni_modules/uview-ui/components/u-count-down/utils.js
create mode 100644 uni_modules/uview-ui/components/u-count-to/props.js
create mode 100644 uni_modules/uview-ui/components/u-count-to/u-count-to.vue
create mode 100644 uni_modules/uview-ui/components/u-datetime-picker/props.js
create mode 100644 uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue
create mode 100644 uni_modules/uview-ui/components/u-divider/props.js
create mode 100644 uni_modules/uview-ui/components/u-divider/u-divider.vue
create mode 100644 uni_modules/uview-ui/components/u-dropdown-item/props.js
create mode 100644 uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue
create mode 100644 uni_modules/uview-ui/components/u-dropdown/props.js
create mode 100644 uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue
create mode 100644 uni_modules/uview-ui/components/u-empty/props.js
create mode 100644 uni_modules/uview-ui/components/u-empty/u-empty.vue
create mode 100644 uni_modules/uview-ui/components/u-form-item/props.js
create mode 100644 uni_modules/uview-ui/components/u-form-item/u-form-item.vue
create mode 100644 uni_modules/uview-ui/components/u-form/props.js
create mode 100644 uni_modules/uview-ui/components/u-form/u-form.vue
create mode 100644 uni_modules/uview-ui/components/u-gap/props.js
create mode 100644 uni_modules/uview-ui/components/u-gap/u-gap.vue
create mode 100644 uni_modules/uview-ui/components/u-grid-item/props.js
create mode 100644 uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue
create mode 100644 uni_modules/uview-ui/components/u-grid/props.js
create mode 100644 uni_modules/uview-ui/components/u-grid/u-grid.vue
create mode 100644 uni_modules/uview-ui/components/u-icon/icons.js
create mode 100644 uni_modules/uview-ui/components/u-icon/props.js
create mode 100644 uni_modules/uview-ui/components/u-icon/u-icon.vue
create mode 100644 uni_modules/uview-ui/components/u-image/props.js
create mode 100644 uni_modules/uview-ui/components/u-image/u-image.vue
create mode 100644 uni_modules/uview-ui/components/u-index-anchor/props.js
create mode 100644 uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue
create mode 100644 uni_modules/uview-ui/components/u-index-item/props.js
create mode 100644 uni_modules/uview-ui/components/u-index-item/u-index-item.vue
create mode 100644 uni_modules/uview-ui/components/u-index-list/props.js
create mode 100644 uni_modules/uview-ui/components/u-index-list/u-index-list.vue
create mode 100644 uni_modules/uview-ui/components/u-input/props.js
create mode 100644 uni_modules/uview-ui/components/u-input/u-input.vue
create mode 100644 uni_modules/uview-ui/components/u-keyboard/props.js
create mode 100644 uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue
create mode 100644 uni_modules/uview-ui/components/u-line-progress/props.js
create mode 100644 uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue
create mode 100644 uni_modules/uview-ui/components/u-line/props.js
create mode 100644 uni_modules/uview-ui/components/u-line/u-line.vue
create mode 100644 uni_modules/uview-ui/components/u-link/props.js
create mode 100644 uni_modules/uview-ui/components/u-link/u-link.vue
create mode 100644 uni_modules/uview-ui/components/u-list-item/props.js
create mode 100644 uni_modules/uview-ui/components/u-list-item/u-list-item.vue
create mode 100644 uni_modules/uview-ui/components/u-list/props.js
create mode 100644 uni_modules/uview-ui/components/u-list/u-list.vue
create mode 100644 uni_modules/uview-ui/components/u-loading-icon/props.js
create mode 100644 uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue
create mode 100644 uni_modules/uview-ui/components/u-loading-page/props.js
create mode 100644 uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue
create mode 100644 uni_modules/uview-ui/components/u-loadmore/props.js
create mode 100644 uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue
create mode 100644 uni_modules/uview-ui/components/u-modal/props.js
create mode 100644 uni_modules/uview-ui/components/u-modal/u-modal.vue
create mode 100644 uni_modules/uview-ui/components/u-navbar/props.js
create mode 100644 uni_modules/uview-ui/components/u-navbar/u-navbar.vue
create mode 100644 uni_modules/uview-ui/components/u-no-network/props.js
create mode 100644 uni_modules/uview-ui/components/u-no-network/u-no-network.vue
create mode 100644 uni_modules/uview-ui/components/u-notice-bar/props.js
create mode 100644 uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue
create mode 100644 uni_modules/uview-ui/components/u-notify/props.js
create mode 100644 uni_modules/uview-ui/components/u-notify/u-notify.vue
create mode 100644 uni_modules/uview-ui/components/u-number-box/props.js
create mode 100644 uni_modules/uview-ui/components/u-number-box/u-number-box.vue
create mode 100644 uni_modules/uview-ui/components/u-number-keyboard/props.js
create mode 100644 uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue
create mode 100644 uni_modules/uview-ui/components/u-overlay/props.js
create mode 100644 uni_modules/uview-ui/components/u-overlay/u-overlay.vue
create mode 100644 uni_modules/uview-ui/components/u-parse/node/node.vue
create mode 100644 uni_modules/uview-ui/components/u-parse/parser.js
create mode 100644 uni_modules/uview-ui/components/u-parse/props.js
create mode 100644 uni_modules/uview-ui/components/u-parse/u-parse.vue
create mode 100644 uni_modules/uview-ui/components/u-picker-column/props.js
create mode 100644 uni_modules/uview-ui/components/u-picker-column/u-picker-column.vue
create mode 100644 uni_modules/uview-ui/components/u-picker/props.js
create mode 100644 uni_modules/uview-ui/components/u-picker/u-picker.vue
create mode 100644 uni_modules/uview-ui/components/u-popup/props.js
create mode 100644 uni_modules/uview-ui/components/u-popup/u-popup.vue
create mode 100644 uni_modules/uview-ui/components/u-radio-group/props.js
create mode 100644 uni_modules/uview-ui/components/u-radio-group/u-radio-group.vue
create mode 100644 uni_modules/uview-ui/components/u-radio/props.js
create mode 100644 uni_modules/uview-ui/components/u-radio/u-radio.vue
create mode 100644 uni_modules/uview-ui/components/u-rate/props.js
create mode 100644 uni_modules/uview-ui/components/u-rate/u-rate.vue
create mode 100644 uni_modules/uview-ui/components/u-read-more/props.js
create mode 100644 uni_modules/uview-ui/components/u-read-more/u-read-more.vue
create mode 100644 uni_modules/uview-ui/components/u-row-notice/props.js
create mode 100644 uni_modules/uview-ui/components/u-row-notice/u-row-notice.vue
create mode 100644 uni_modules/uview-ui/components/u-row/props.js
create mode 100644 uni_modules/uview-ui/components/u-row/u-row.vue
create mode 100644 uni_modules/uview-ui/components/u-safe-bottom/props.js
create mode 100644 uni_modules/uview-ui/components/u-safe-bottom/u-safe-bottom.vue
create mode 100644 uni_modules/uview-ui/components/u-scroll-list/nvue.js
create mode 100644 uni_modules/uview-ui/components/u-scroll-list/other.js
create mode 100644 uni_modules/uview-ui/components/u-scroll-list/props.js
create mode 100644 uni_modules/uview-ui/components/u-scroll-list/scrollWxs.wxs
create mode 100644 uni_modules/uview-ui/components/u-scroll-list/u-scroll-list.vue
create mode 100644 uni_modules/uview-ui/components/u-search/props.js
create mode 100644 uni_modules/uview-ui/components/u-search/u-search.vue
create mode 100644 uni_modules/uview-ui/components/u-skeleton/props.js
create mode 100644 uni_modules/uview-ui/components/u-skeleton/u-skeleton.vue
create mode 100644 uni_modules/uview-ui/components/u-slider/mpother.js
create mode 100644 uni_modules/uview-ui/components/u-slider/mpwxs.js
create mode 100644 uni_modules/uview-ui/components/u-slider/mpwxs.wxs
create mode 100644 uni_modules/uview-ui/components/u-slider/nvue - 副本.js
create mode 100644 uni_modules/uview-ui/components/u-slider/nvue.js
create mode 100644 uni_modules/uview-ui/components/u-slider/props.js
create mode 100644 uni_modules/uview-ui/components/u-slider/u-slider.vue
create mode 100644 uni_modules/uview-ui/components/u-status-bar/props.js
create mode 100644 uni_modules/uview-ui/components/u-status-bar/u-status-bar.vue
create mode 100644 uni_modules/uview-ui/components/u-steps-item/props.js
create mode 100644 uni_modules/uview-ui/components/u-steps-item/u-steps-item.vue
create mode 100644 uni_modules/uview-ui/components/u-steps/props.js
create mode 100644 uni_modules/uview-ui/components/u-steps/u-steps.vue
create mode 100644 uni_modules/uview-ui/components/u-sticky/props.js
create mode 100644 uni_modules/uview-ui/components/u-sticky/u-sticky.vue
create mode 100644 uni_modules/uview-ui/components/u-subsection/props.js
create mode 100644 uni_modules/uview-ui/components/u-subsection/u-subsection.vue
create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/index - backup.wxs
create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/index.wxs
create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/nvue - backup.js
create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/nvue.js
create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/props.js
create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/u-swipe-action-item.vue
create mode 100644 uni_modules/uview-ui/components/u-swipe-action-item/wxs.js
create mode 100644 uni_modules/uview-ui/components/u-swipe-action/props.js
create mode 100644 uni_modules/uview-ui/components/u-swipe-action/u-swipe-action.vue
create mode 100644 uni_modules/uview-ui/components/u-swiper-indicator/props.js
create mode 100644 uni_modules/uview-ui/components/u-swiper-indicator/u-swiper-indicator.vue
create mode 100644 uni_modules/uview-ui/components/u-swiper/props.js
create mode 100644 uni_modules/uview-ui/components/u-swiper/u-swiper.vue
create mode 100644 uni_modules/uview-ui/components/u-switch/props.js
create mode 100644 uni_modules/uview-ui/components/u-switch/u-switch.vue
create mode 100644 uni_modules/uview-ui/components/u-tabbar-item/props.js
create mode 100644 uni_modules/uview-ui/components/u-tabbar-item/u-tabbar-item.vue
create mode 100644 uni_modules/uview-ui/components/u-tabbar/props.js
create mode 100644 uni_modules/uview-ui/components/u-tabbar/u-tabbar.vue
create mode 100644 uni_modules/uview-ui/components/u-table/props.js
create mode 100644 uni_modules/uview-ui/components/u-table/u-table.vue
create mode 100644 uni_modules/uview-ui/components/u-tabs-item/props.js
create mode 100644 uni_modules/uview-ui/components/u-tabs-item/u-tabs-item.vue
create mode 100644 uni_modules/uview-ui/components/u-tabs/props.js
create mode 100644 uni_modules/uview-ui/components/u-tabs/u-tabs.vue
create mode 100644 uni_modules/uview-ui/components/u-tag/props.js
create mode 100644 uni_modules/uview-ui/components/u-tag/u-tag.vue
create mode 100644 uni_modules/uview-ui/components/u-td/props.js
create mode 100644 uni_modules/uview-ui/components/u-td/u-td.vue
create mode 100644 uni_modules/uview-ui/components/u-text/props.js
create mode 100644 uni_modules/uview-ui/components/u-text/u-text.vue
create mode 100644 uni_modules/uview-ui/components/u-text/value.js
create mode 100644 uni_modules/uview-ui/components/u-textarea/props.js
create mode 100644 uni_modules/uview-ui/components/u-textarea/u-textarea.vue
create mode 100644 uni_modules/uview-ui/components/u-toast/u-toast.vue
create mode 100644 uni_modules/uview-ui/components/u-toolbar/props.js
create mode 100644 uni_modules/uview-ui/components/u-toolbar/u-toolbar.vue
create mode 100644 uni_modules/uview-ui/components/u-tooltip/clipboard.min.js
create mode 100644 uni_modules/uview-ui/components/u-tooltip/props.js
create mode 100644 uni_modules/uview-ui/components/u-tooltip/u-tooltip.vue
create mode 100644 uni_modules/uview-ui/components/u-tr/props.js
create mode 100644 uni_modules/uview-ui/components/u-tr/u-tr.vue
create mode 100644 uni_modules/uview-ui/components/u-transition/nvue.ani-map.js
create mode 100644 uni_modules/uview-ui/components/u-transition/props.js
create mode 100644 uni_modules/uview-ui/components/u-transition/transition.js
create mode 100644 uni_modules/uview-ui/components/u-transition/u-transition.vue
create mode 100644 uni_modules/uview-ui/components/u-transition/vue.ani-style.scss
create mode 100644 uni_modules/uview-ui/components/u-upload/mixin.js
create mode 100644 uni_modules/uview-ui/components/u-upload/props.js
create mode 100644 uni_modules/uview-ui/components/u-upload/u-upload.vue
create mode 100644 uni_modules/uview-ui/components/u-upload/utils.js
create mode 100644 uni_modules/uview-ui/components/uview-ui/uview-ui.vue
create mode 100644 uni_modules/uview-ui/index.js
create mode 100644 uni_modules/uview-ui/index.scss
create mode 100644 uni_modules/uview-ui/libs/config/color.js
create mode 100644 uni_modules/uview-ui/libs/config/config.js
create mode 100644 uni_modules/uview-ui/libs/config/props.js
create mode 100644 uni_modules/uview-ui/libs/config/props/actionSheet.js
create mode 100644 uni_modules/uview-ui/libs/config/props/album.js
create mode 100644 uni_modules/uview-ui/libs/config/props/alert.js
create mode 100644 uni_modules/uview-ui/libs/config/props/avatar.js
create mode 100644 uni_modules/uview-ui/libs/config/props/avatarGroup.js
create mode 100644 uni_modules/uview-ui/libs/config/props/backtop.js
create mode 100644 uni_modules/uview-ui/libs/config/props/badge.js
create mode 100644 uni_modules/uview-ui/libs/config/props/button.js
create mode 100644 uni_modules/uview-ui/libs/config/props/calendar.js
create mode 100644 uni_modules/uview-ui/libs/config/props/carKeyboard.js
create mode 100644 uni_modules/uview-ui/libs/config/props/cell.js
create mode 100644 uni_modules/uview-ui/libs/config/props/cellGroup.js
create mode 100644 uni_modules/uview-ui/libs/config/props/checkbox.js
create mode 100644 uni_modules/uview-ui/libs/config/props/checkboxGroup.js
create mode 100644 uni_modules/uview-ui/libs/config/props/circleProgress.js
create mode 100644 uni_modules/uview-ui/libs/config/props/code.js
create mode 100644 uni_modules/uview-ui/libs/config/props/codeInput.js
create mode 100644 uni_modules/uview-ui/libs/config/props/col.js
create mode 100644 uni_modules/uview-ui/libs/config/props/collapse.js
create mode 100644 uni_modules/uview-ui/libs/config/props/collapseItem.js
create mode 100644 uni_modules/uview-ui/libs/config/props/columnNotice.js
create mode 100644 uni_modules/uview-ui/libs/config/props/countDown.js
create mode 100644 uni_modules/uview-ui/libs/config/props/countTo.js
create mode 100644 uni_modules/uview-ui/libs/config/props/datetimePicker.js
create mode 100644 uni_modules/uview-ui/libs/config/props/divider.js
create mode 100644 uni_modules/uview-ui/libs/config/props/empty.js
create mode 100644 uni_modules/uview-ui/libs/config/props/form.js
create mode 100644 uni_modules/uview-ui/libs/config/props/formItem.js
create mode 100644 uni_modules/uview-ui/libs/config/props/gap.js
create mode 100644 uni_modules/uview-ui/libs/config/props/grid.js
create mode 100644 uni_modules/uview-ui/libs/config/props/gridItem.js
create mode 100644 uni_modules/uview-ui/libs/config/props/icon.js
create mode 100644 uni_modules/uview-ui/libs/config/props/image.js
create mode 100644 uni_modules/uview-ui/libs/config/props/indexAnchor.js
create mode 100644 uni_modules/uview-ui/libs/config/props/indexList.js
create mode 100644 uni_modules/uview-ui/libs/config/props/input.js
create mode 100644 uni_modules/uview-ui/libs/config/props/keyboard.js
create mode 100644 uni_modules/uview-ui/libs/config/props/line.js
create mode 100644 uni_modules/uview-ui/libs/config/props/lineProgress.js
create mode 100644 uni_modules/uview-ui/libs/config/props/link.js
create mode 100644 uni_modules/uview-ui/libs/config/props/list.js
create mode 100644 uni_modules/uview-ui/libs/config/props/listItem.js
create mode 100644 uni_modules/uview-ui/libs/config/props/loadingIcon.js
create mode 100644 uni_modules/uview-ui/libs/config/props/loadingPage.js
create mode 100644 uni_modules/uview-ui/libs/config/props/loadmore.js
create mode 100644 uni_modules/uview-ui/libs/config/props/modal.js
create mode 100644 uni_modules/uview-ui/libs/config/props/navbar.js
create mode 100644 uni_modules/uview-ui/libs/config/props/noNetwork.js
create mode 100644 uni_modules/uview-ui/libs/config/props/noticeBar.js
create mode 100644 uni_modules/uview-ui/libs/config/props/notify.js
create mode 100644 uni_modules/uview-ui/libs/config/props/numberBox.js
create mode 100644 uni_modules/uview-ui/libs/config/props/numberKeyboard.js
create mode 100644 uni_modules/uview-ui/libs/config/props/overlay.js
create mode 100644 uni_modules/uview-ui/libs/config/props/parse.js
create mode 100644 uni_modules/uview-ui/libs/config/props/picker.js
create mode 100644 uni_modules/uview-ui/libs/config/props/popup.js
create mode 100644 uni_modules/uview-ui/libs/config/props/radio.js
create mode 100644 uni_modules/uview-ui/libs/config/props/radioGroup.js
create mode 100644 uni_modules/uview-ui/libs/config/props/rate.js
create mode 100644 uni_modules/uview-ui/libs/config/props/readMore.js
create mode 100644 uni_modules/uview-ui/libs/config/props/row.js
create mode 100644 uni_modules/uview-ui/libs/config/props/rowNotice.js
create mode 100644 uni_modules/uview-ui/libs/config/props/scrollList.js
create mode 100644 uni_modules/uview-ui/libs/config/props/search.js
create mode 100644 uni_modules/uview-ui/libs/config/props/section.js
create mode 100644 uni_modules/uview-ui/libs/config/props/skeleton.js
create mode 100644 uni_modules/uview-ui/libs/config/props/slider.js
create mode 100644 uni_modules/uview-ui/libs/config/props/statusBar.js
create mode 100644 uni_modules/uview-ui/libs/config/props/steps.js
create mode 100644 uni_modules/uview-ui/libs/config/props/stepsItem.js
create mode 100644 uni_modules/uview-ui/libs/config/props/sticky.js
create mode 100644 uni_modules/uview-ui/libs/config/props/subsection.js
create mode 100644 uni_modules/uview-ui/libs/config/props/swipeAction.js
create mode 100644 uni_modules/uview-ui/libs/config/props/swipeActionItem.js
create mode 100644 uni_modules/uview-ui/libs/config/props/swiper.js
create mode 100644 uni_modules/uview-ui/libs/config/props/swipterIndicator.js
create mode 100644 uni_modules/uview-ui/libs/config/props/switch.js
create mode 100644 uni_modules/uview-ui/libs/config/props/tabbar.js
create mode 100644 uni_modules/uview-ui/libs/config/props/tabbarItem.js
create mode 100644 uni_modules/uview-ui/libs/config/props/tabs.js
create mode 100644 uni_modules/uview-ui/libs/config/props/tag.js
create mode 100644 uni_modules/uview-ui/libs/config/props/text.js
create mode 100644 uni_modules/uview-ui/libs/config/props/textarea.js
create mode 100644 uni_modules/uview-ui/libs/config/props/toast.js
create mode 100644 uni_modules/uview-ui/libs/config/props/toolbar.js
create mode 100644 uni_modules/uview-ui/libs/config/props/tooltip.js
create mode 100644 uni_modules/uview-ui/libs/config/props/transition.js
create mode 100644 uni_modules/uview-ui/libs/config/props/upload.js
create mode 100644 uni_modules/uview-ui/libs/config/zIndex.js
create mode 100644 uni_modules/uview-ui/libs/css/color.scss
create mode 100644 uni_modules/uview-ui/libs/css/common.scss
create mode 100644 uni_modules/uview-ui/libs/css/components.scss
create mode 100644 uni_modules/uview-ui/libs/css/flex.scss
create mode 100644 uni_modules/uview-ui/libs/css/h5.scss
create mode 100644 uni_modules/uview-ui/libs/css/mixin.scss
create mode 100644 uni_modules/uview-ui/libs/css/mp.scss
create mode 100644 uni_modules/uview-ui/libs/css/nvue.scss
create mode 100644 uni_modules/uview-ui/libs/css/vue.scss
create mode 100644 uni_modules/uview-ui/libs/function/colorGradient.js
create mode 100644 uni_modules/uview-ui/libs/function/debounce.js
create mode 100644 uni_modules/uview-ui/libs/function/digit.js
create mode 100644 uni_modules/uview-ui/libs/function/index.js
create mode 100644 uni_modules/uview-ui/libs/function/platform.js
create mode 100644 uni_modules/uview-ui/libs/function/test.js
create mode 100644 uni_modules/uview-ui/libs/function/throttle.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/adapters/index.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/core/InterceptorManager.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/core/Request.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/core/buildFullPath.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/core/defaults.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/core/dispatchRequest.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/core/mergeConfig.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/core/settle.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/helpers/buildURL.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/helpers/combineURLs.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/helpers/isAbsoluteURL.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/index.d.ts
create mode 100644 uni_modules/uview-ui/libs/luch-request/index.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/utils.js
create mode 100644 uni_modules/uview-ui/libs/luch-request/utils/clone.js
create mode 100644 uni_modules/uview-ui/libs/mixin/button.js
create mode 100644 uni_modules/uview-ui/libs/mixin/mixin.js
create mode 100644 uni_modules/uview-ui/libs/mixin/mpMixin.js
create mode 100644 uni_modules/uview-ui/libs/mixin/mpShare.js
create mode 100644 uni_modules/uview-ui/libs/mixin/openType.js
create mode 100644 uni_modules/uview-ui/libs/mixin/style.js
create mode 100644 uni_modules/uview-ui/libs/mixin/touch.js
create mode 100644 uni_modules/uview-ui/libs/util/async-validator.js
create mode 100644 uni_modules/uview-ui/libs/util/calendar.js
create mode 100644 uni_modules/uview-ui/libs/util/dayjs.js
create mode 100644 uni_modules/uview-ui/libs/util/emitter.js
create mode 100644 uni_modules/uview-ui/libs/util/route.js
create mode 100644 uni_modules/uview-ui/package.json
create mode 100644 uni_modules/uview-ui/theme.scss
create mode 100644 uni_modules/zero-markdown-view/changelog.md
create mode 100644 uni_modules/zero-markdown-view/components/mp-html/highlight/config.js
create mode 100644 uni_modules/zero-markdown-view/components/mp-html/highlight/index.js
create mode 100644 uni_modules/zero-markdown-view/components/mp-html/highlight/prism.min.js
create mode 100644 uni_modules/zero-markdown-view/components/mp-html/markdown/index.js
create mode 100644 uni_modules/zero-markdown-view/components/mp-html/markdown/marked.min.js
create mode 100644 uni_modules/zero-markdown-view/components/mp-html/mp-html.vue
create mode 100644 uni_modules/zero-markdown-view/components/mp-html/node/node.vue
create mode 100644 uni_modules/zero-markdown-view/components/mp-html/parser.js
create mode 100644 uni_modules/zero-markdown-view/components/mp-html/style/index.js
create mode 100644 uni_modules/zero-markdown-view/components/mp-html/style/parser.js
create mode 100644 uni_modules/zero-markdown-view/components/zero-markdown-view/zero-markdown-view.vue
create mode 100644 uni_modules/zero-markdown-view/package.json
create mode 100644 uni_modules/zero-markdown-view/readme.md
create mode 100644 util/index.js
create mode 100644 util/order.js
create mode 100644 util/user.js
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d6212fc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/unpackage/
+/.idea/
diff --git a/App.vue b/App.vue
new file mode 100644
index 0000000..cab80c3
--- /dev/null
+++ b/App.vue
@@ -0,0 +1,18 @@
+
+
+
diff --git a/api/chat.js b/api/chat.js
new file mode 100644
index 0000000..cfd8cac
--- /dev/null
+++ b/api/chat.js
@@ -0,0 +1,15 @@
+import post, {del, get, put} from "@/api/request";
+
+export const chatListReq = () => get('/gx/gx-chat-list/userList')
+export const addChatListReq = (data) => post('/gx/gx-chat-list', data)
+export const updateChatListReq = data => put(`/gx/gx-chat-list`, data)
+export const deleteChatListReq = (id) => del(`/gx/gx-chat-list/${id}`)
+export const addChatHistoryReq = (data) => post('/gx/gx-chat-history', data)
+export const listChatHistoryReq = params => get('/gx/gx-chat-history', {params})
+export const listChatRoleReq = () => get('/gx/gx-role')
+export const chatRoleInfoReq = id => get(`/gx/gx-role/${id}`)
+export const sendChatReq = data => post('/chat/message', data)
+export const stopChatReq = data => post('/chat/messageStop', data)
+export const makeVoiceReq = data => post('/voice/make', data)
+export const makeTransReq = data => post('/voice/makeTrans', data)
+export const voiceGetResReq = (taskId) => post(`/voice/getRes/${taskId}`)
diff --git a/api/coin.js b/api/coin.js
new file mode 100644
index 0000000..0b97417
--- /dev/null
+++ b/api/coin.js
@@ -0,0 +1,6 @@
+import post, {del, get} from "@/api/request";
+
+export const coinListReq = () => get('/gx/gx-coin-log')
+export const coinAddReq = (data) => post('/gx/gx-coin-log', data)
+export const signLogListReq = () => get('/gx/gx-sign-log')
+export const signLogAddReq = (data) => post('/gx/gx-sign-log', data)
\ No newline at end of file
diff --git a/api/common.js b/api/common.js
new file mode 100644
index 0000000..9f54569
--- /dev/null
+++ b/api/common.js
@@ -0,0 +1,43 @@
+import post, {get} from "@/api/request";
+
+export const areaListReq = data => post('/area/list-by-level', data)
+
+export const areaInfoReq = data => post('/area/info', data)
+
+export const areaInfoByNameReq = data => post('/area/info-by-name', data)
+
+export const indexListReq = data => post('/com/publish-list/list', data)
+
+export const swiperListReq = () => get('/sys/sys-swiper')
+
+export const dictListReq = data => post('/system/dict/info', data)
+
+export const dictDataInfoReq = id => get(`/system/dict-data/${id}`)
+
+export const addViewNumReq = data => post('/shop/user-browse/add', data)
+
+export const sysSettingInfoReq = data => post('/sys', data)
+
+export const dictDataReq = params => get('/system/dict-data', {params})
+
+export const listArticleCateReq = params => get('/cms/article-category', {params})
+
+export const listArticleReq = params => get('/cms/article', {params})
+
+export const pageArticleReq = params => get('/cms/article/page', {params})
+
+export const articleInfoReq = id => get(`/cms/article/${id}`)
+
+export const adListReq = () => get(`/cms/cms-ad`)
+
+export const addArticleCollectReq = data => post(`/cms/article-collect`, data)
+
+export const addFeedbackReq = data => post(`/gx/gx-feedback`, data)
+
+export const listArticleCollectReq = () => get(`/cms/article-collect`)
+
+export const sysAreaListReq = params => get(`/sys/sys-area`, {params})
+
+export const articleCommentListReq = params => get(`/cms/article-comment`, {params})
+
+export const addArticleCommentReq = data => post(`/cms/article-comment`, data)
diff --git a/api/complain.js b/api/complain.js
new file mode 100644
index 0000000..dc0928a
--- /dev/null
+++ b/api/complain.js
@@ -0,0 +1,3 @@
+import post, {get} from "@/api/request";
+
+export const addComplain = data => post('/zhsq/zhsq-property-complaint', data)
\ No newline at end of file
diff --git a/api/request.js b/api/request.js
new file mode 100644
index 0000000..ece4358
--- /dev/null
+++ b/api/request.js
@@ -0,0 +1,106 @@
+import Request from '@/js_sdk/luch-request/luch-request/index.js'
+import {API} from '@/config'
+import {getUserInfo, clearUserInfo} from "@/util/user";
+
+const http = new Request();
+http.config.baseURL = API
+
+http.interceptors.request.use((config) => {
+ // uni.showLoading({title: '加载中'})
+ const token = getUserInfo().token
+ if (token && token !== 'undefined') {
+ config.header.Authorization = token
+ }
+ config.header.tenantId = 10543
+ return config
+}, config => {
+ return Promise.reject(config)
+})
+
+http.interceptors.response.use((response) => {
+ const url = response.config.url
+ // uni.hideLoading()
+ switch (parseInt(response.data.code)) {
+ case 401: {
+ if (['user-cart-num', 'new-order', 'user-cart-add', 'user-info'].indexOf(url) === -1) {
+ uni.showToast({
+ title: '请登录',
+ icon: 'error',
+ duration: 2000,
+ })
+ setTimeout(() => {
+ clearUserInfo()
+ }, 2000)
+ }
+ }
+ break;
+ case 500: {
+ if (['/user/change-pay-password', 'new-order-from-goods-list'].indexOf(url) === -1) {
+ console.log(response.data)
+ uni.showToast({
+ icon: 'none',
+ title: response.data.content.msg,
+ duration: 2000,
+ })
+ }
+ }
+ break;
+ case 502: {
+ uni.showToast({
+ icon: 'error',
+ title: '系统维护中',
+ duration: 2000,
+ })
+ }
+ }
+ return response
+}, (error) => {
+ if (error.code === 502) {
+ uni.showToast({
+ icon: 'error',
+ title: '系统维护中',
+ duration: 2000,
+ })
+ }
+ return Promise.reject(error)
+})
+
+const post = (url, formData, options) => {
+ return new Promise((resolve, reject) => {
+ http.post(url, formData, options).then(res => {
+ if (res.data.code === 0) resolve(res.data)
+ else if (res.data.code === 401) reject(res.data)
+ else reject(res.data)
+ })
+ })
+}
+
+export const get = (url, options) => {
+ // console.log(options)
+ return new Promise((resolve, reject) => {
+ http.get(url, options).then(res => {
+ resolve(res.data)
+ })
+ })
+}
+
+export const del = (url, options) => {
+ // console.log(options)
+ return new Promise((resolve, reject) => {
+ http.delete(url, options).then(res => {
+ resolve(res.data)
+ })
+ })
+}
+
+export const put = (url, formData, options) => {
+ return new Promise((resolve, reject) => {
+ http.put(url, formData, options).then(res => {
+ if (res.data.code === 0) resolve(res.data)
+ else if (res.data.code === 401) reject(res.data)
+ else reject(res.data)
+ })
+ })
+}
+
+export default post
\ No newline at end of file
diff --git a/api/user.js b/api/user.js
new file mode 100644
index 0000000..5694cd8
--- /dev/null
+++ b/api/user.js
@@ -0,0 +1,27 @@
+import post, {get, put} from "@/api/request";
+
+export const loginReq = data => post('/wx-login/getOpenId', data)
+
+export const loginByPhoneReq = data => post('/wx-login/loginByMpWxPhone', data)
+
+export const loginByPhoneForTestReq = data => post('/system/user/loginByPhoneForTest', data)
+
+export const userInfoReq = () => get('/auth/user')
+
+export const updateUserReq = data => put('/system/user/self', data)
+
+export const userInfoUpdateReq = data => post('/system/user/update', data)
+
+export const userInfoUpdateDataReq = data => post('/system/user/update-data', data)
+
+export const userSearchReq = data => post('/user/search', data)
+
+export const userSetCardReq = data => post('/user/set-card', data)
+
+export const userCardChargeReq = data => post('/user/card-charge', data)
+
+export const userCardReduceReq = data => post('/user/card-reduce', data)
+
+export const userCardUseReq = data => post('/user/card-use', data)
+
+export const addCoinLogReq = data => post('/gx/gx-coin-log', data)
diff --git a/components/HeaderItem.vue b/components/HeaderItem.vue
new file mode 100644
index 0000000..843e363
--- /dev/null
+++ b/components/HeaderItem.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/Login.vue b/components/Login.vue
new file mode 100644
index 0000000..c75b6cb
--- /dev/null
+++ b/components/Login.vue
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+ 为了提供更优质的服务,需要获取
+
+
+
+
+
+
+
+
+
+ 我已阅读并同意
+
+ 《用户协议》
+
+
+ 《隐私协议》
+
+
+
+
+
+
+
+ 拒绝
+
+
+ 允许
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 我已阅读并同意
+
+ 《用户协议》
+
+
+ 《隐私协议》
+
+
+
+
+
+
+
+ 关闭
+
+
+ 登录
+
+
+
+
+ 手机号登录
+
+ 一键授权登录
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/TitleItem.vue b/components/TitleItem.vue
new file mode 100644
index 0000000..3abe6ac
--- /dev/null
+++ b/components/TitleItem.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/customTabbar.vue b/components/customTabbar.vue
new file mode 100644
index 0000000..8d3a454
--- /dev/null
+++ b/components/customTabbar.vue
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/color.js b/config/color.js
new file mode 100644
index 0000000..27d3f21
--- /dev/null
+++ b/config/color.js
@@ -0,0 +1,18 @@
+export const YELLOW = '#e2d602'
+export const ORANGE = '#fd7600'
+export const ORANGE_LIGHT = '#FEEDA8'
+export const GREEN = '#98C147'
+export const GREEN_LIGHT = '#96b0a3'
+export const BLUE = '#3C4DA5'
+export const BLUE_LIGHT = '#049DFF'
+export const RED = '#FE6869'
+export const RED_LIGHT = '#F7B2B2'
+export const PURPLE = '#7F6CDE'
+export const PINK = '#FE5397'
+export const PURPLE_DARK = '#7F6CDE'
+export const PUBLISH = '#FDCB05'
+export const GRAY = '#999'
+export const PURPLE_LIGHT = '#7F6CDE'
+
+export const MAIN = BLUE
+export const LINEAR = 'linear-gradient(90deg, #049DFF, #2665c4)'
diff --git a/config/index.js b/config/index.js
new file mode 100644
index 0000000..37d5008
--- /dev/null
+++ b/config/index.js
@@ -0,0 +1,23 @@
+const MAIN_API_FN = () => {
+ if (process.env.NODE_ENV === 'development') {
+ // return 'http://127.0.0.1:10051'
+ return 'https://guoxue.gxwebsoft.com'
+ } else {
+ return 'https://guoxue.gxwebsoft.com'
+ }
+}
+
+const MAIN_WS_FN = () => {
+ if (process.env.NODE_ENV === 'development') {
+ return 'ws://127.0.0.1:10051/chat'
+ // return 'wss://guoxue.gxwebsoft.com/chat'
+ } else {
+ return 'wss://guoxue.gxwebsoft.com/chat'
+ }
+}
+
+export const MAIN_API = MAIN_API_FN()
+
+export const WS_API = MAIN_WS_FN()
+
+export const API = `${MAIN_API}/api`
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..b5d330d
--- /dev/null
+++ b/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/js_sdk/luch-request/luch-request/adapters/index.js b/js_sdk/luch-request/luch-request/adapters/index.js
new file mode 100644
index 0000000..9bcd653
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/adapters/index.js
@@ -0,0 +1,100 @@
+import buildURL from '../helpers/buildURL'
+import buildFullPath from '../core/buildFullPath'
+import settle from '../core/settle'
+import {isUndefined} from "../utils"
+
+/**
+ * 返回可选值存在的配置
+ * @param {Array} keys - 可选值数组
+ * @param {Object} config2 - 配置
+ * @return {{}} - 存在的配置项
+ */
+const mergeKeys = (keys, config2) => {
+ let config = {}
+ keys.forEach(prop => {
+ if (!isUndefined(config2[prop])) {
+ config[prop] = config2[prop]
+ }
+ })
+ return config
+}
+export default (config) => {
+ return new Promise((resolve, reject) => {
+ let fullPath = buildURL(buildFullPath(config.baseURL, config.url), config.params, config.paramsSerializer)
+ const _config = {
+ url: fullPath,
+ header: config.header,
+ complete: (response) => {
+ config.fullPath = fullPath
+ response.config = config
+ response.rawData = response.data
+ try {
+ // 对可能字符串不是json 的情况容错
+ if (typeof response.data === 'string') {
+ response.data = JSON.parse(response.data)
+ }
+ // eslint-disable-next-line no-empty
+ } catch (e) {
+ }
+ settle(resolve, reject, response)
+ }
+ }
+ let requestTask
+ if (config.method === 'UPLOAD') {
+ delete _config.header['content-type']
+ delete _config.header['Content-Type']
+ let otherConfig = {
+ // #ifdef MP-ALIPAY
+ fileType: config.fileType,
+ // #endif
+ filePath: config.filePath,
+ name: config.name
+ }
+ const optionalKeys = [
+ // #ifdef APP-PLUS || H5
+ 'files',
+ // #endif
+ // #ifdef H5
+ 'file',
+ // #endif
+ // #ifdef H5 || APP-PLUS
+ 'timeout',
+ // #endif
+ 'formData'
+ ]
+ requestTask = uni.uploadFile({..._config, ...otherConfig, ...mergeKeys(optionalKeys, config)})
+ } else if (config.method === 'DOWNLOAD') {
+ // #ifdef H5 || APP-PLUS
+ if (!isUndefined(config['timeout'])) {
+ _config['timeout'] = config['timeout']
+ }
+ // #endif
+ requestTask = uni.downloadFile(_config)
+ } else {
+ const optionalKeys = [
+ 'data',
+ 'method',
+ // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
+ 'timeout',
+ // #endif
+ 'dataType',
+ // #ifndef MP-ALIPAY
+ 'responseType',
+ // #endif
+ // #ifdef APP-PLUS
+ 'sslVerify',
+ // #endif
+ // #ifdef H5
+ 'withCredentials',
+ // #endif
+ // #ifdef APP-PLUS
+ 'firstIpv4',
+ // #endif
+ ]
+ requestTask = uni.request({..._config, ...mergeKeys(optionalKeys, config)})
+ }
+ if (config.getTask) {
+ config.getTask(requestTask, config)
+ }
+ })
+}
diff --git a/js_sdk/luch-request/luch-request/core/InterceptorManager.js b/js_sdk/luch-request/luch-request/core/InterceptorManager.js
new file mode 100644
index 0000000..3ea0d5e
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/core/InterceptorManager.js
@@ -0,0 +1,51 @@
+'use strict'
+
+
+function InterceptorManager() {
+ this.handlers = []
+}
+
+/**
+ * Add a new interceptor to the stack
+ *
+ * @param {Function} fulfilled The function to handle `then` for a `Promise`
+ * @param {Function} rejected The function to handle `reject` for a `Promise`
+ *
+ * @return {Number} An ID used to remove interceptor later
+ */
+InterceptorManager.prototype.use = function use(fulfilled, rejected) {
+ this.handlers.push({
+ fulfilled: fulfilled,
+ rejected: rejected
+ })
+ return this.handlers.length - 1
+}
+
+/**
+ * Remove an interceptor from the stack
+ *
+ * @param {Number} id The ID that was returned by `use`
+ */
+InterceptorManager.prototype.eject = function eject(id) {
+ if (this.handlers[id]) {
+ this.handlers[id] = null
+ }
+}
+
+/**
+ * Iterate over all the registered interceptors
+ *
+ * This method is particularly useful for skipping over any
+ * interceptors that may have become `null` calling `eject`.
+ *
+ * @param {Function} fn The function to call for each interceptor
+ */
+InterceptorManager.prototype.forEach = function forEach(fn) {
+ this.handlers.forEach(h => {
+ if (h !== null) {
+ fn(h)
+ }
+ })
+}
+
+export default InterceptorManager
diff --git a/js_sdk/luch-request/luch-request/core/Request.js b/js_sdk/luch-request/luch-request/core/Request.js
new file mode 100644
index 0000000..d11f152
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/core/Request.js
@@ -0,0 +1,197 @@
+/**
+ * @Class Request
+ * @description luch-request http请求插件
+ * @Author lu-ch
+ * @Email webwork.s@qq.com
+ * 文档: https://www.quanzhan.co/luch-request/
+ * github: https://github.com/lei-mu/luch-request
+ * DCloud: http://ext.dcloud.net.cn/plugin?id=392
+ */
+
+
+import dispatchRequest from './dispatchRequest'
+import InterceptorManager from './InterceptorManager'
+import mergeConfig from './mergeConfig'
+import defaults from './defaults'
+import { isPlainObject } from '../utils'
+import clone from '../utils/clone'
+
+export default class Request {
+ /**
+ * @param {Object} arg - 全局配置
+ * @param {String} arg.baseURL - 全局根路径
+ * @param {Object} arg.header - 全局header
+ * @param {String} arg.method = [GET|POST|PUT|DELETE|CONNECT|HEAD|OPTIONS|TRACE] - 全局默认请求方式
+ * @param {String} arg.dataType = [json] - 全局默认的dataType
+ * @param {String} arg.responseType = [text|arraybuffer] - 全局默认的responseType。支付宝小程序不支持
+ * @param {Object} arg.custom - 全局默认的自定义参数
+ * @param {Number} arg.timeout - 全局默认的超时时间,单位 ms。默认60000。H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
+ * @param {Boolean} arg.sslVerify - 全局默认的是否验证 ssl 证书。默认true.仅App安卓端支持(HBuilderX 2.3.3+)
+ * @param {Boolean} arg.withCredentials - 全局默认的跨域请求时是否携带凭证(cookies)。默认false。仅H5支持(HBuilderX 2.6.15+)
+ * @param {Boolean} arg.firstIpv4 - 全DNS解析时优先使用ipv4。默认false。仅 App-Android 支持 (HBuilderX 2.8.0+)
+ * @param {Function(statusCode):Boolean} arg.validateStatus - 全局默认的自定义验证器。默认statusCode >= 200 && statusCode < 300
+ */
+ constructor(arg = {}) {
+ if (!isPlainObject(arg)) {
+ arg = {}
+ console.warn('设置全局参数必须接收一个Object')
+ }
+ this.config = clone({...defaults, ...arg})
+ this.interceptors = {
+ request: new InterceptorManager(),
+ response: new InterceptorManager()
+ }
+ }
+
+ /**
+ * @Function
+ * @param {Request~setConfigCallback} f - 设置全局默认配置
+ */
+ setConfig(f) {
+ this.config = f(this.config)
+ }
+
+ middleware(config) {
+ config = mergeConfig(this.config, config)
+ let chain = [dispatchRequest, undefined]
+ let promise = Promise.resolve(config)
+
+ this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
+ chain.unshift(interceptor.fulfilled, interceptor.rejected)
+ })
+
+ this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
+ chain.push(interceptor.fulfilled, interceptor.rejected)
+ })
+
+ while (chain.length) {
+ promise = promise.then(chain.shift(), chain.shift())
+ }
+
+ return promise
+ }
+
+ /**
+ * @Function
+ * @param {Object} config - 请求配置项
+ * @prop {String} options.url - 请求路径
+ * @prop {Object} options.data - 请求参数
+ * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
+ * @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse
+ * @prop {Object} [options.header = config.header] - 请求header
+ * @prop {Object} [options.method = config.method] - 请求方法
+ * @returns {Promise}
+ */
+ request(config = {}) {
+ return this.middleware(config)
+ }
+
+ get(url, options = {}) {
+ return this.middleware({
+ url,
+ method: 'GET',
+ ...options
+ })
+ }
+
+ post(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'POST',
+ ...options
+ })
+ }
+
+ // #ifndef MP-ALIPAY || MP-KUAISHOU || MP-JD
+ put(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'PUT',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
+ delete(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'DELETE',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef H5 || MP-WEIXIN
+ connect(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'CONNECT',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef H5 || MP-WEIXIN || MP-BAIDU
+ head(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'HEAD',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
+ options(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'OPTIONS',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef H5 || MP-WEIXIN
+ trace(url, data, options = {}) {
+ return this.middleware({
+ url,
+ data,
+ method: 'TRACE',
+ ...options
+ })
+ }
+
+ // #endif
+
+ upload(url, config = {}) {
+ config.url = url
+ config.method = 'UPLOAD'
+ return this.middleware(config)
+ }
+
+ download(url, config = {}) {
+ config.url = url
+ config.method = 'DOWNLOAD'
+ return this.middleware(config)
+ }
+}
+
+
+/**
+ * setConfig回调
+ * @return {Object} - 返回操作后的config
+ * @callback Request~setConfigCallback
+ * @param {Object} config - 全局默认config
+ */
diff --git a/js_sdk/luch-request/luch-request/core/buildFullPath.js b/js_sdk/luch-request/luch-request/core/buildFullPath.js
new file mode 100644
index 0000000..f2852f4
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/core/buildFullPath.js
@@ -0,0 +1,20 @@
+'use strict'
+
+import isAbsoluteURL from '../helpers/isAbsoluteURL'
+import combineURLs from '../helpers/combineURLs'
+
+/**
+ * Creates a new URL by combining the baseURL with the requestedURL,
+ * only when the requestedURL is not already an absolute URL.
+ * If the requestURL is absolute, this function returns the requestedURL untouched.
+ *
+ * @param {string} baseURL The base URL
+ * @param {string} requestedURL Absolute or relative URL to combine
+ * @returns {string} The combined full path
+ */
+export default function buildFullPath(baseURL, requestedURL) {
+ if (baseURL && !isAbsoluteURL(requestedURL)) {
+ return combineURLs(baseURL, requestedURL)
+ }
+ return requestedURL
+}
diff --git a/js_sdk/luch-request/luch-request/core/defaults.js b/js_sdk/luch-request/luch-request/core/defaults.js
new file mode 100644
index 0000000..ef5a0d9
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/core/defaults.js
@@ -0,0 +1,31 @@
+/**
+ * 默认的全局配置
+ */
+
+
+export default {
+ baseURL: '',
+ header: {},
+ method: 'GET',
+ dataType: 'json',
+ paramsSerializer: null,
+ // #ifndef MP-ALIPAY
+ responseType: 'text',
+ // #endif
+ custom: {},
+ // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
+ timeout: 60000,
+ // #endif
+ // #ifdef APP-PLUS
+ sslVerify: true,
+ // #endif
+ // #ifdef H5
+ withCredentials: false,
+ // #endif
+ // #ifdef APP-PLUS
+ firstIpv4: false,
+ // #endif
+ validateStatus: function validateStatus(status) {
+ return status >= 200 && status < 300
+ }
+}
diff --git a/js_sdk/luch-request/luch-request/core/dispatchRequest.js b/js_sdk/luch-request/luch-request/core/dispatchRequest.js
new file mode 100644
index 0000000..c5f2c85
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/core/dispatchRequest.js
@@ -0,0 +1,6 @@
+import adapter from '../adapters/index'
+
+
+export default (config) => {
+ return adapter(config)
+}
diff --git a/js_sdk/luch-request/luch-request/core/mergeConfig.js b/js_sdk/luch-request/luch-request/core/mergeConfig.js
new file mode 100644
index 0000000..ca3f10c
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/core/mergeConfig.js
@@ -0,0 +1,103 @@
+import {deepMerge, isUndefined} from '../utils'
+
+/**
+ * 合并局部配置优先的配置,如果局部有该配置项则用局部,如果全局有该配置项则用全局
+ * @param {Array} keys - 配置项
+ * @param {Object} globalsConfig - 当前的全局配置
+ * @param {Object} config2 - 局部配置
+ * @return {{}}
+ */
+const mergeKeys = (keys, globalsConfig, config2) => {
+ let config = {}
+ keys.forEach(prop => {
+ if (!isUndefined(config2[prop])) {
+ config[prop] = config2[prop]
+ } else if (!isUndefined(globalsConfig[prop])) {
+ config[prop] = globalsConfig[prop]
+ }
+ })
+ return config
+}
+/**
+ *
+ * @param globalsConfig - 当前实例的全局配置
+ * @param config2 - 当前的局部配置
+ * @return - 合并后的配置
+ */
+export default (globalsConfig, config2 = {}) => {
+ const method = config2.method || globalsConfig.method || 'GET'
+ let config = {
+ baseURL: config2.baseURL || globalsConfig.baseURL || '',
+ method: method,
+ url: config2.url || '',
+ params: config2.params || {},
+ custom: {...(globalsConfig.custom || {}), ...(config2.custom || {})},
+ header: deepMerge(globalsConfig.header || {}, config2.header || {})
+ }
+ const defaultToConfig2Keys = ['getTask', 'validateStatus', 'paramsSerializer']
+ config = {...config, ...mergeKeys(defaultToConfig2Keys, globalsConfig, config2)}
+
+ // eslint-disable-next-line no-empty
+ if (method === 'DOWNLOAD') {
+ // #ifdef H5 || APP-PLUS
+ if (!isUndefined(config2.timeout)) {
+ config['timeout'] = config2['timeout']
+ } else if (!isUndefined(globalsConfig.timeout)) {
+ config['timeout'] = globalsConfig['timeout']
+ }
+ // #endif
+ } else if (method === 'UPLOAD') {
+ delete config.header['content-type']
+ delete config.header['Content-Type']
+ const uploadKeys = [
+ // #ifdef APP-PLUS || H5
+ 'files',
+ // #endif
+ // #ifdef MP-ALIPAY
+ 'fileType',
+ // #endif
+ // #ifdef H5
+ 'file',
+ // #endif
+ 'filePath',
+ 'name',
+ // #ifdef H5 || APP-PLUS
+ 'timeout',
+ // #endif
+ 'formData',
+ ]
+ uploadKeys.forEach(prop => {
+ if (!isUndefined(config2[prop])) {
+ config[prop] = config2[prop]
+ }
+ })
+ // #ifdef H5 || APP-PLUS
+ if (isUndefined(config.timeout) && !isUndefined(globalsConfig.timeout)) {
+ config['timeout'] = globalsConfig['timeout']
+ }
+ // #endif
+ } else {
+ const defaultsKeys = [
+ 'data',
+ // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
+ 'timeout',
+ // #endif
+ 'dataType',
+ // #ifndef MP-ALIPAY
+ 'responseType',
+ // #endif
+ // #ifdef APP-PLUS
+ 'sslVerify',
+ // #endif
+ // #ifdef H5
+ 'withCredentials',
+ // #endif
+ // #ifdef APP-PLUS
+ 'firstIpv4',
+ // #endif
+ ]
+ config = {...config, ...mergeKeys(defaultsKeys, globalsConfig, config2)}
+ }
+
+ return config
+}
diff --git a/js_sdk/luch-request/luch-request/core/settle.js b/js_sdk/luch-request/luch-request/core/settle.js
new file mode 100644
index 0000000..b2f1659
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/core/settle.js
@@ -0,0 +1,16 @@
+/**
+ * Resolve or reject a Promise based on response status.
+ *
+ * @param {Function} resolve A function that resolves the promise.
+ * @param {Function} reject A function that rejects the promise.
+ * @param {object} response The response.
+ */
+export default function settle(resolve, reject, response) {
+ const validateStatus = response.config.validateStatus
+ const status = response.statusCode
+ if (status && (!validateStatus || validateStatus(status))) {
+ resolve(response)
+ } else {
+ reject(response)
+ }
+}
diff --git a/js_sdk/luch-request/luch-request/helpers/buildURL.js b/js_sdk/luch-request/luch-request/helpers/buildURL.js
new file mode 100644
index 0000000..e90b908
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/helpers/buildURL.js
@@ -0,0 +1,64 @@
+'use strict'
+
+import * as utils from './../utils'
+
+function encode(val) {
+ return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']')
+}
+
+/**
+ * Build a URL by appending params to the end
+ *
+ * @param {string} url The base of the url (e.g., http://www.google.com)
+ * @param {object} [params] The params to be appended
+ * @returns {string} The formatted url
+ */
+export default function buildURL(url, params, paramsSerializer) {
+ /*eslint no-param-reassign:0*/
+ if (!params) {
+ return url
+ }
+
+ var serializedParams
+ if (paramsSerializer) {
+ serializedParams = paramsSerializer(params)
+ } else if (utils.isURLSearchParams(params)) {
+ serializedParams = params.toString()
+ } else {
+ var parts = []
+
+ utils.forEach(params, function serialize(val, key) {
+ if (val === null || typeof val === 'undefined') {
+ return
+ }
+
+ if (utils.isArray(val)) {
+ key = key + '[]'
+ } else {
+ val = [val]
+ }
+
+ utils.forEach(val, function parseValue(v) {
+ if (utils.isDate(v)) {
+ v = v.toISOString()
+ } else if (utils.isObject(v)) {
+ v = JSON.stringify(v)
+ }
+ parts.push(encode(key) + '=' + encode(v))
+ })
+ })
+
+ serializedParams = parts.join('&')
+ }
+
+ if (serializedParams) {
+ var hashmarkIndex = url.indexOf('#')
+ if (hashmarkIndex !== -1) {
+ url = url.slice(0, hashmarkIndex)
+ }
+
+ url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
+ }
+
+ return url
+}
diff --git a/js_sdk/luch-request/luch-request/helpers/combineURLs.js b/js_sdk/luch-request/luch-request/helpers/combineURLs.js
new file mode 100644
index 0000000..7b9d1ef
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/helpers/combineURLs.js
@@ -0,0 +1,14 @@
+'use strict'
+
+/**
+ * Creates a new URL by combining the specified URLs
+ *
+ * @param {string} baseURL The base URL
+ * @param {string} relativeURL The relative URL
+ * @returns {string} The combined URL
+ */
+export default function combineURLs(baseURL, relativeURL) {
+ return relativeURL
+ ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
+ : baseURL
+}
diff --git a/js_sdk/luch-request/luch-request/helpers/isAbsoluteURL.js b/js_sdk/luch-request/luch-request/helpers/isAbsoluteURL.js
new file mode 100644
index 0000000..2a82517
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/helpers/isAbsoluteURL.js
@@ -0,0 +1,14 @@
+'use strict'
+
+/**
+ * Determines whether the specified URL is absolute
+ *
+ * @param {string} url The URL to test
+ * @returns {boolean} True if the specified URL is absolute, otherwise false
+ */
+export default function isAbsoluteURL(url) {
+ // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL).
+ // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
+ // by any combination of letters, digits, plus, period, or hyphen.
+ return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url)
+}
diff --git a/js_sdk/luch-request/luch-request/index.d.ts b/js_sdk/luch-request/luch-request/index.d.ts
new file mode 100644
index 0000000..e56ee41
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/index.d.ts
@@ -0,0 +1,120 @@
+type AnyObject = Record
+type HttpPromise = Promise>;
+type Tasks = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask
+export interface RequestTask {
+ abort: () => void;
+ offHeadersReceived: () => void;
+ onHeadersReceived: () => void;
+}
+export interface HttpRequestConfig {
+ /** 请求基地址 */
+ baseURL?: string;
+ /** 请求服务器接口地址 */
+ url?: string;
+
+ /** 请求查询参数,自动拼接为查询字符串 */
+ params?: AnyObject;
+ /** 请求体参数 */
+ data?: AnyObject;
+
+ /** 文件对应的 key */
+ name?: string;
+ /** HTTP 请求中其他额外的 form data */
+ formData?: AnyObject;
+ /** 要上传文件资源的路径。 */
+ filePath?: string;
+ /** 需要上传的文件列表。使用 files 时,filePath 和 name 不生效,App、H5( 2.6.15+) */
+ files?: Array<{
+ name?: string;
+ file?: File;
+ uri: string;
+ }>;
+ /** 要上传的文件对象,仅H5(2.6.15+)支持 */
+ file?: File;
+
+ /** 请求头信息 */
+ header?: AnyObject;
+ /** 请求方式 */
+ method?: "GET" | "POST" | "PUT" | "DELETE" | "CONNECT" | "HEAD" | "OPTIONS" | "TRACE" | "UPLOAD" | "DOWNLOAD";
+ /** 如果设为 json,会尝试对返回的数据做一次 JSON.parse */
+ dataType?: string;
+ /** 设置响应的数据类型,支付宝小程序不支持 */
+ responseType?: "text" | "arraybuffer";
+ /** 自定义参数 */
+ custom?: AnyObject;
+ /** 超时时间,仅微信小程序(2.10.0)、支付宝小程序支持 */
+ timeout?: number;
+ /** DNS解析时优先使用ipv4,仅 App-Android 支持 (HBuilderX 2.8.0+) */
+ firstIpv4?: boolean;
+ /** 验证 ssl 证书 仅5+App安卓端支持(HBuilderX 2.3.3+) */
+ sslVerify?: boolean;
+ /** 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+) */
+ withCredentials?: boolean;
+
+ /** 返回当前请求的task, options。请勿在此处修改options。 */
+ getTask?: (task: T, options: HttpRequestConfig) => void;
+ /** 全局自定义验证器 */
+ validateStatus?: (statusCode: number) => boolean | void;
+ /** params 参数自定义处理 */
+ paramsSerializer?: (params: AnyObject) => string | void;
+}
+export interface HttpResponse {
+ config: HttpRequestConfig;
+ statusCode: number;
+ cookies: Array;
+ data: T;
+ errMsg: string;
+ header: AnyObject;
+ rawData: T;
+}
+export interface HttpUploadResponse {
+ config: HttpRequestConfig;
+ statusCode: number;
+ data: T;
+ errMsg: string;
+ rawData: T;
+}
+export interface HttpDownloadResponse extends HttpResponse {
+ tempFilePath: string;
+}
+export interface HttpError {
+ config: HttpRequestConfig;
+ statusCode?: number;
+ cookies?: Array;
+ data?: any;
+ errMsg: string;
+ header?: AnyObject;
+}
+export interface HttpInterceptorManager {
+ use(
+ onFulfilled?: (config: V) => Promise | V,
+ onRejected?: (config: E) => Promise | E
+ ): void;
+ eject(id: number): void;
+}
+export abstract class HttpRequestAbstract {
+ constructor(config?: HttpRequestConfig);
+ config: HttpRequestConfig;
+ interceptors: {
+ request: HttpInterceptorManager;
+ response: HttpInterceptorManager;
+ }
+ middleware(config: HttpRequestConfig): HttpPromise;
+ request(config: HttpRequestConfig): HttpPromise;
+ get(url: string, config?: HttpRequestConfig): HttpPromise;
+ upload(url: string, config?: HttpRequestConfig): HttpPromise;
+ delete(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise;
+ head(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise;
+ post(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise;
+ put(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise;
+ connect(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise;
+ options(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise;
+ trace(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise;
+
+ download(url: string, config?: HttpRequestConfig): Promise;
+
+ setConfig(onSend: (config: HttpRequestConfig) => HttpRequestConfig): void;
+}
+
+declare class HttpRequest extends HttpRequestAbstract { }
+export default HttpRequest;
diff --git a/js_sdk/luch-request/luch-request/index.js b/js_sdk/luch-request/luch-request/index.js
new file mode 100644
index 0000000..d8fe348
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/index.js
@@ -0,0 +1,2 @@
+import Request from './core/Request'
+export default Request
diff --git a/js_sdk/luch-request/luch-request/utils.js b/js_sdk/luch-request/luch-request/utils.js
new file mode 100644
index 0000000..0b5bf21
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/utils.js
@@ -0,0 +1,135 @@
+'use strict'
+
+// utils is a library of generic helper functions non-specific to axios
+
+var toString = Object.prototype.toString
+
+/**
+ * Determine if a value is an Array
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is an Array, otherwise false
+ */
+export function isArray (val) {
+ return toString.call(val) === '[object Array]'
+}
+
+
+/**
+ * Determine if a value is an Object
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is an Object, otherwise false
+ */
+export function isObject (val) {
+ return val !== null && typeof val === 'object'
+}
+
+/**
+ * Determine if a value is a Date
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is a Date, otherwise false
+ */
+export function isDate (val) {
+ return toString.call(val) === '[object Date]'
+}
+
+/**
+ * Determine if a value is a URLSearchParams object
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is a URLSearchParams object, otherwise false
+ */
+export function isURLSearchParams (val) {
+ return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams
+}
+
+
+/**
+ * Iterate over an Array or an Object invoking a function for each item.
+ *
+ * If `obj` is an Array callback will be called passing
+ * the value, index, and complete array for each item.
+ *
+ * If 'obj' is an Object callback will be called passing
+ * the value, key, and complete object for each property.
+ *
+ * @param {Object|Array} obj The object to iterate
+ * @param {Function} fn The callback to invoke for each item
+ */
+export function forEach (obj, fn) {
+ // Don't bother if no value provided
+ if (obj === null || typeof obj === 'undefined') {
+ return
+ }
+
+ // Force an array if not already something iterable
+ if (typeof obj !== 'object') {
+ /*eslint no-param-reassign:0*/
+ obj = [obj]
+ }
+
+ if (isArray(obj)) {
+ // Iterate over array values
+ for (var i = 0, l = obj.length; i < l; i++) {
+ fn.call(null, obj[i], i, obj)
+ }
+ } else {
+ // Iterate over object keys
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
+ fn.call(null, obj[key], key, obj)
+ }
+ }
+ }
+}
+
+/**
+ * 是否为boolean 值
+ * @param val
+ * @returns {boolean}
+ */
+export function isBoolean(val) {
+ return typeof val === 'boolean'
+}
+
+/**
+ * 是否为真正的对象{} new Object
+ * @param {any} obj - 检测的对象
+ * @returns {boolean}
+ */
+export function isPlainObject(obj) {
+ return Object.prototype.toString.call(obj) === '[object Object]'
+}
+
+
+
+/**
+ * Function equal to merge with the difference being that no reference
+ * to original objects is kept.
+ *
+ * @see merge
+ * @param {Object} obj1 Object to merge
+ * @returns {Object} Result of all merge properties
+ */
+export function deepMerge(/* obj1, obj2, obj3, ... */) {
+ let result = {}
+ function assignValue(val, key) {
+ if (typeof result[key] === 'object' && typeof val === 'object') {
+ result[key] = deepMerge(result[key], val)
+ } else if (typeof val === 'object') {
+ result[key] = deepMerge({}, val)
+ } else {
+ result[key] = val
+ }
+ }
+ for (let i = 0, l = arguments.length; i < l; i++) {
+ forEach(arguments[i], assignValue)
+ }
+ return result
+}
+
+export function isUndefined (val) {
+ return typeof val === 'undefined'
+}
diff --git a/js_sdk/luch-request/luch-request/utils/clone.js b/js_sdk/luch-request/luch-request/utils/clone.js
new file mode 100644
index 0000000..2fee704
--- /dev/null
+++ b/js_sdk/luch-request/luch-request/utils/clone.js
@@ -0,0 +1,264 @@
+/* eslint-disable */
+var clone = (function() {
+ 'use strict';
+
+ function _instanceof(obj, type) {
+ return type != null && obj instanceof type;
+ }
+
+ var nativeMap;
+ try {
+ nativeMap = Map;
+ } catch(_) {
+ // maybe a reference error because no `Map`. Give it a dummy value that no
+ // value will ever be an instanceof.
+ nativeMap = function() {};
+ }
+
+ var nativeSet;
+ try {
+ nativeSet = Set;
+ } catch(_) {
+ nativeSet = function() {};
+ }
+
+ var nativePromise;
+ try {
+ nativePromise = Promise;
+ } catch(_) {
+ nativePromise = function() {};
+ }
+
+ /**
+ * Clones (copies) an Object using deep copying.
+ *
+ * This function supports circular references by default, but if you are certain
+ * there are no circular references in your object, you can save some CPU time
+ * by calling clone(obj, false).
+ *
+ * Caution: if `circular` is false and `parent` contains circular references,
+ * your program may enter an infinite loop and crash.
+ *
+ * @param `parent` - the object to be cloned
+ * @param `circular` - set to true if the object to be cloned may contain
+ * circular references. (optional - true by default)
+ * @param `depth` - set to a number if the object is only to be cloned to
+ * a particular depth. (optional - defaults to Infinity)
+ * @param `prototype` - sets the prototype to be used when cloning an object.
+ * (optional - defaults to parent prototype).
+ * @param `includeNonEnumerable` - set to true if the non-enumerable properties
+ * should be cloned as well. Non-enumerable properties on the prototype
+ * chain will be ignored. (optional - false by default)
+ */
+ function clone(parent, circular, depth, prototype, includeNonEnumerable) {
+ if (typeof circular === 'object') {
+ depth = circular.depth;
+ prototype = circular.prototype;
+ includeNonEnumerable = circular.includeNonEnumerable;
+ circular = circular.circular;
+ }
+ // maintain two arrays for circular references, where corresponding parents
+ // and children have the same index
+ var allParents = [];
+ var allChildren = [];
+
+ var useBuffer = typeof Buffer != 'undefined';
+
+ if (typeof circular == 'undefined')
+ circular = true;
+
+ if (typeof depth == 'undefined')
+ depth = Infinity;
+
+ // recurse this function so we don't reset allParents and allChildren
+ function _clone(parent, depth) {
+ // cloning null always returns null
+ if (parent === null)
+ return null;
+
+ if (depth === 0)
+ return parent;
+
+ var child;
+ var proto;
+ if (typeof parent != 'object') {
+ return parent;
+ }
+
+ if (_instanceof(parent, nativeMap)) {
+ child = new nativeMap();
+ } else if (_instanceof(parent, nativeSet)) {
+ child = new nativeSet();
+ } else if (_instanceof(parent, nativePromise)) {
+ child = new nativePromise(function (resolve, reject) {
+ parent.then(function(value) {
+ resolve(_clone(value, depth - 1));
+ }, function(err) {
+ reject(_clone(err, depth - 1));
+ });
+ });
+ } else if (clone.__isArray(parent)) {
+ child = [];
+ } else if (clone.__isRegExp(parent)) {
+ child = new RegExp(parent.source, __getRegExpFlags(parent));
+ if (parent.lastIndex) child.lastIndex = parent.lastIndex;
+ } else if (clone.__isDate(parent)) {
+ child = new Date(parent.getTime());
+ } else if (useBuffer && Buffer.isBuffer(parent)) {
+ if (Buffer.from) {
+ // Node.js >= 5.10.0
+ child = Buffer.from(parent);
+ } else {
+ // Older Node.js versions
+ child = new Buffer(parent.length);
+ parent.copy(child);
+ }
+ return child;
+ } else if (_instanceof(parent, Error)) {
+ child = Object.create(parent);
+ } else {
+ if (typeof prototype == 'undefined') {
+ proto = Object.getPrototypeOf(parent);
+ child = Object.create(proto);
+ }
+ else {
+ child = Object.create(prototype);
+ proto = prototype;
+ }
+ }
+
+ if (circular) {
+ var index = allParents.indexOf(parent);
+
+ if (index != -1) {
+ return allChildren[index];
+ }
+ allParents.push(parent);
+ allChildren.push(child);
+ }
+
+ if (_instanceof(parent, nativeMap)) {
+ parent.forEach(function(value, key) {
+ var keyChild = _clone(key, depth - 1);
+ var valueChild = _clone(value, depth - 1);
+ child.set(keyChild, valueChild);
+ });
+ }
+ if (_instanceof(parent, nativeSet)) {
+ parent.forEach(function(value) {
+ var entryChild = _clone(value, depth - 1);
+ child.add(entryChild);
+ });
+ }
+
+ for (var i in parent) {
+ var attrs = Object.getOwnPropertyDescriptor(parent, i);
+ if (attrs) {
+ child[i] = _clone(parent[i], depth - 1);
+ }
+
+ try {
+ var objProperty = Object.getOwnPropertyDescriptor(parent, i);
+ if (objProperty.set === 'undefined') {
+ // no setter defined. Skip cloning this property
+ continue;
+ }
+ child[i] = _clone(parent[i], depth - 1);
+ } catch(e){
+ if (e instanceof TypeError) {
+ // when in strict mode, TypeError will be thrown if child[i] property only has a getter
+ // we can't do anything about this, other than inform the user that this property cannot be set.
+ continue
+ } else if (e instanceof ReferenceError) {
+ //this may happen in non strict mode
+ continue
+ }
+ }
+
+ }
+
+ if (Object.getOwnPropertySymbols) {
+ var symbols = Object.getOwnPropertySymbols(parent);
+ for (var i = 0; i < symbols.length; i++) {
+ // Don't need to worry about cloning a symbol because it is a primitive,
+ // like a number or string.
+ var symbol = symbols[i];
+ var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
+ if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {
+ continue;
+ }
+ child[symbol] = _clone(parent[symbol], depth - 1);
+ Object.defineProperty(child, symbol, descriptor);
+ }
+ }
+
+ if (includeNonEnumerable) {
+ var allPropertyNames = Object.getOwnPropertyNames(parent);
+ for (var i = 0; i < allPropertyNames.length; i++) {
+ var propertyName = allPropertyNames[i];
+ var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);
+ if (descriptor && descriptor.enumerable) {
+ continue;
+ }
+ child[propertyName] = _clone(parent[propertyName], depth - 1);
+ Object.defineProperty(child, propertyName, descriptor);
+ }
+ }
+
+ return child;
+ }
+
+ return _clone(parent, depth);
+ }
+
+ /**
+ * Simple flat clone using prototype, accepts only objects, usefull for property
+ * override on FLAT configuration object (no nested props).
+ *
+ * USE WITH CAUTION! This may not behave as you wish if you do not know how this
+ * works.
+ */
+ clone.clonePrototype = function clonePrototype(parent) {
+ if (parent === null)
+ return null;
+
+ var c = function () {};
+ c.prototype = parent;
+ return new c();
+ };
+
+// private utility functions
+
+ function __objToStr(o) {
+ return Object.prototype.toString.call(o);
+ }
+ clone.__objToStr = __objToStr;
+
+ function __isDate(o) {
+ return typeof o === 'object' && __objToStr(o) === '[object Date]';
+ }
+ clone.__isDate = __isDate;
+
+ function __isArray(o) {
+ return typeof o === 'object' && __objToStr(o) === '[object Array]';
+ }
+ clone.__isArray = __isArray;
+
+ function __isRegExp(o) {
+ return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
+ }
+ clone.__isRegExp = __isRegExp;
+
+ function __getRegExpFlags(re) {
+ var flags = '';
+ if (re.global) flags += 'g';
+ if (re.ignoreCase) flags += 'i';
+ if (re.multiline) flags += 'm';
+ return flags;
+ }
+ clone.__getRegExpFlags = __getRegExpFlags;
+
+ return clone;
+})();
+
+export default clone
diff --git a/js_sdk/luch-request/package.json b/js_sdk/luch-request/package.json
new file mode 100644
index 0000000..78ad4eb
--- /dev/null
+++ b/js_sdk/luch-request/package.json
@@ -0,0 +1,19 @@
+{
+ "id": "luch-request",
+ "displayName": "luch-request",
+ "version": "3.0.8",
+ "description": "基于Promise开发的跨平台、项目级别的请求库,它有更小的体积,易用的api,方便简单的自定义能力",
+ "keywords": [
+ "request",
+ "axios",
+ "网络请求",
+ "拦截器",
+ "promise"
+ ],
+ "dcloudext": {
+ "category": [
+ "JS SDK",
+ "通用 SDK"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/js_sdk/qqmap-wx-jssdk/qqmap-wx-jssdk.js b/js_sdk/qqmap-wx-jssdk/qqmap-wx-jssdk.js
new file mode 100644
index 0000000..595b65b
--- /dev/null
+++ b/js_sdk/qqmap-wx-jssdk/qqmap-wx-jssdk.js
@@ -0,0 +1,1122 @@
+/**
+ * 微信小程序JavaScriptSDK
+ *
+ * @version 1.2
+ * @date 2019-03-06
+ */
+
+var ERROR_CONF = {
+ KEY_ERR: 311,
+ KEY_ERR_MSG: 'key格式错误',
+ PARAM_ERR: 310,
+ PARAM_ERR_MSG: '请求参数信息有误',
+ SYSTEM_ERR: 600,
+ SYSTEM_ERR_MSG: '系统错误',
+ WX_ERR_CODE: 1000,
+ WX_OK_CODE: 200
+};
+var BASE_URL = 'https://apis.map.qq.com/ws/';
+var URL_SEARCH = BASE_URL + 'place/v1/search';
+var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion';
+var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/';
+var URL_CITY_LIST = BASE_URL + 'district/v1/list';
+var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren';
+var URL_DISTANCE = BASE_URL + 'distance/v1/';
+var URL_DIRECTION = BASE_URL + 'direction/v1/';
+var MODE = {
+ driving: 'driving',
+ transit: 'transit'
+};
+var EARTH_RADIUS = 6378136.49;
+var Utils = {
+ /**
+ * md5加密方法
+ * 版权所有©2011 Sebastian Tschan,https://blueimp.net
+ */
+ safeAdd(x, y) {
+ var lsw = (x & 0xffff) + (y & 0xffff);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xffff);
+ },
+ bitRotateLeft(num, cnt) {
+ return (num << cnt) | (num >>> (32 - cnt));
+ },
+ md5cmn(q, a, b, x, s, t) {
+ return this.safeAdd(this.bitRotateLeft(this.safeAdd(this.safeAdd(a, q), this.safeAdd(x, t)), s), b);
+ },
+ md5ff(a, b, c, d, x, s, t) {
+ return this.md5cmn((b & c) | (~b & d), a, b, x, s, t);
+ },
+ md5gg(a, b, c, d, x, s, t) {
+ return this.md5cmn((b & d) | (c & ~d), a, b, x, s, t);
+ },
+ md5hh(a, b, c, d, x, s, t) {
+ return this.md5cmn(b ^ c ^ d, a, b, x, s, t);
+ },
+ md5ii(a, b, c, d, x, s, t) {
+ return this.md5cmn(c ^ (b | ~d), a, b, x, s, t);
+ },
+ binlMD5(x, len) {
+ /* append padding */
+ x[len >> 5] |= 0x80 << (len % 32);
+ x[((len + 64) >>> 9 << 4) + 14] = len;
+
+ var i;
+ var olda;
+ var oldb;
+ var oldc;
+ var oldd;
+ var a = 1732584193;
+ var b = -271733879;
+ var c = -1732584194;
+ var d = 271733878;
+
+ for (i = 0; i < x.length; i += 16) {
+ olda = a;
+ oldb = b;
+ oldc = c;
+ oldd = d;
+
+ a = this.md5ff(a, b, c, d, x[i], 7, -680876936);
+ d = this.md5ff(d, a, b, c, x[i + 1], 12, -389564586);
+ c = this.md5ff(c, d, a, b, x[i + 2], 17, 606105819);
+ b = this.md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
+ a = this.md5ff(a, b, c, d, x[i + 4], 7, -176418897);
+ d = this.md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
+ c = this.md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
+ b = this.md5ff(b, c, d, a, x[i + 7], 22, -45705983);
+ a = this.md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
+ d = this.md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
+ c = this.md5ff(c, d, a, b, x[i + 10], 17, -42063);
+ b = this.md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
+ a = this.md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
+ d = this.md5ff(d, a, b, c, x[i + 13], 12, -40341101);
+ c = this.md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
+ b = this.md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
+
+ a = this.md5gg(a, b, c, d, x[i + 1], 5, -165796510);
+ d = this.md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
+ c = this.md5gg(c, d, a, b, x[i + 11], 14, 643717713);
+ b = this.md5gg(b, c, d, a, x[i], 20, -373897302);
+ a = this.md5gg(a, b, c, d, x[i + 5], 5, -701558691);
+ d = this.md5gg(d, a, b, c, x[i + 10], 9, 38016083);
+ c = this.md5gg(c, d, a, b, x[i + 15], 14, -660478335);
+ b = this.md5gg(b, c, d, a, x[i + 4], 20, -405537848);
+ a = this.md5gg(a, b, c, d, x[i + 9], 5, 568446438);
+ d = this.md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
+ c = this.md5gg(c, d, a, b, x[i + 3], 14, -187363961);
+ b = this.md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
+ a = this.md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
+ d = this.md5gg(d, a, b, c, x[i + 2], 9, -51403784);
+ c = this.md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
+ b = this.md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
+
+ a = this.md5hh(a, b, c, d, x[i + 5], 4, -378558);
+ d = this.md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
+ c = this.md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
+ b = this.md5hh(b, c, d, a, x[i + 14], 23, -35309556);
+ a = this.md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
+ d = this.md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
+ c = this.md5hh(c, d, a, b, x[i + 7], 16, -155497632);
+ b = this.md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
+ a = this.md5hh(a, b, c, d, x[i + 13], 4, 681279174);
+ d = this.md5hh(d, a, b, c, x[i], 11, -358537222);
+ c = this.md5hh(c, d, a, b, x[i + 3], 16, -722521979);
+ b = this.md5hh(b, c, d, a, x[i + 6], 23, 76029189);
+ a = this.md5hh(a, b, c, d, x[i + 9], 4, -640364487);
+ d = this.md5hh(d, a, b, c, x[i + 12], 11, -421815835);
+ c = this.md5hh(c, d, a, b, x[i + 15], 16, 530742520);
+ b = this.md5hh(b, c, d, a, x[i + 2], 23, -995338651);
+
+ a = this.md5ii(a, b, c, d, x[i], 6, -198630844);
+ d = this.md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
+ c = this.md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
+ b = this.md5ii(b, c, d, a, x[i + 5], 21, -57434055);
+ a = this.md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
+ d = this.md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
+ c = this.md5ii(c, d, a, b, x[i + 10], 15, -1051523);
+ b = this.md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
+ a = this.md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
+ d = this.md5ii(d, a, b, c, x[i + 15], 10, -30611744);
+ c = this.md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
+ b = this.md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
+ a = this.md5ii(a, b, c, d, x[i + 4], 6, -145523070);
+ d = this.md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
+ c = this.md5ii(c, d, a, b, x[i + 2], 15, 718787259);
+ b = this.md5ii(b, c, d, a, x[i + 9], 21, -343485551);
+
+ a = this.safeAdd(a, olda);
+ b = this.safeAdd(b, oldb);
+ c = this.safeAdd(c, oldc);
+ d = this.safeAdd(d, oldd);
+ }
+ return [a, b, c, d];
+ },
+ binl2rstr(input) {
+ var i;
+ var output = '';
+ var length32 = input.length * 32;
+ for (i = 0; i < length32; i += 8) {
+ output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff);
+ }
+ return output;
+ },
+ rstr2binl(input) {
+ var i;
+ var output = [];
+ output[(input.length >> 2) - 1] = undefined;
+ for (i = 0; i < output.length; i += 1) {
+ output[i] = 0;
+ }
+ var length8 = input.length * 8;
+ for (i = 0; i < length8; i += 8) {
+ output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32);
+ }
+ return output;
+ },
+ rstrMD5(s) {
+ return this.binl2rstr(this.binlMD5(this.rstr2binl(s), s.length * 8));
+ },
+ rstrHMACMD5(key, data) {
+ var i;
+ var bkey = this.rstr2binl(key);
+ var ipad = [];
+ var opad = [];
+ var hash;
+ ipad[15] = opad[15] = undefined;
+ if (bkey.length > 16) {
+ bkey = this.binlMD5(bkey, key.length * 8);
+ }
+ for (i = 0; i < 16; i += 1) {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5c5c5c5c;
+ }
+ hash = this.binlMD5(ipad.concat(this.rstr2binl(data)), 512 + data.length * 8);
+ return this.binl2rstr(this.binlMD5(opad.concat(hash), 512 + 128));
+ },
+ rstr2hex(input) {
+ var hexTab = '0123456789abcdef';
+ var output = '';
+ var x;
+ var i;
+ for (i = 0; i < input.length; i += 1) {
+ x = input.charCodeAt(i);
+ output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f);
+ }
+ return output;
+ },
+ str2rstrUTF8(input) {
+ return unescape(encodeURIComponent(input));
+ },
+ rawMD5(s) {
+ return this.rstrMD5(this.str2rstrUTF8(s));
+ },
+ hexMD5(s) {
+ return this.rstr2hex(this.rawMD5(s));
+ },
+ rawHMACMD5(k, d) {
+ return this.rstrHMACMD5(this.str2rstrUTF8(k), str2rstrUTF8(d));
+ },
+ hexHMACMD5(k, d) {
+ return this.rstr2hex(this.rawHMACMD5(k, d));
+ },
+
+ md5(string, key, raw) {
+ if (!key) {
+ if (!raw) {
+ return this.hexMD5(string);
+ }
+ return this.rawMD5(string);
+ }
+ if (!raw) {
+ return this.hexHMACMD5(key, string);
+ }
+ return this.rawHMACMD5(key, string);
+ },
+ /**
+ * 得到md5加密后的sig参数
+ * @param {Object} requestParam 接口参数
+ * @param {String} sk签名字符串
+ * @param {String} featrue 方法名
+ * @return 返回加密后的sig参数
+ */
+ getSig(requestParam, sk, feature, mode) {
+ var sig = null;
+ var requestArr = [];
+ Object.keys(requestParam).sort().forEach(function(key){
+ requestArr.push(key + '=' + requestParam[key]);
+ });
+ if (feature == 'search') {
+ sig = '/ws/place/v1/search?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'suggest') {
+ sig = '/ws/place/v1/suggestion?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'reverseGeocoder') {
+ sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'geocoder') {
+ sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'getCityList') {
+ sig = '/ws/district/v1/list?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'getDistrictByCityId') {
+ sig = '/ws/district/v1/getchildren?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'calculateDistance') {
+ sig = '/ws/distance/v1/?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'direction') {
+ sig = '/ws/direction/v1/' + mode + '?' + requestArr.join('&') + sk;
+ }
+ sig = this.md5(sig);
+ return sig;
+ },
+ /**
+ * 得到终点query字符串
+ * @param {Array|String} 检索数据
+ */
+ location2query(data) {
+ if (typeof data == 'string') {
+ return data;
+ }
+ var query = '';
+ for (var i = 0; i < data.length; i++) {
+ var d = data[i];
+ if (!!query) {
+ query += ';';
+ }
+ if (d.location) {
+ query = query + d.location.lat + ',' + d.location.lng;
+ }
+ if (d.latitude && d.longitude) {
+ query = query + d.latitude + ',' + d.longitude;
+ }
+ }
+ return query;
+ },
+
+ /**
+ * 计算角度
+ */
+ rad(d) {
+ return d * Math.PI / 180.0;
+ },
+ /**
+ * 处理终点location数组
+ * @return 返回终点数组
+ */
+ getEndLocation(location){
+ var to = location.split(';');
+ var endLocation = [];
+ for (var i = 0; i < to.length; i++) {
+ endLocation.push({
+ lat: parseFloat(to[i].split(',')[0]),
+ lng: parseFloat(to[i].split(',')[1])
+ })
+ }
+ return endLocation;
+ },
+
+ /**
+ * 计算两点间直线距离
+ * @param a 表示纬度差
+ * @param b 表示经度差
+ * @return 返回的是距离,单位m
+ */
+ getDistance(latFrom, lngFrom, latTo, lngTo) {
+ var radLatFrom = this.rad(latFrom);
+ var radLatTo = this.rad(latTo);
+ var a = radLatFrom - radLatTo;
+ var b = this.rad(lngFrom) - this.rad(lngTo);
+ var distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLatFrom) * Math.cos(radLatTo) * Math.pow(Math.sin(b / 2), 2)));
+ distance = distance * EARTH_RADIUS;
+ distance = Math.round(distance * 10000) / 10000;
+ return parseFloat(distance.toFixed(0));
+ },
+ /**
+ * 使用微信接口进行定位
+ */
+ getWXLocation(success, fail, complete) {
+ wx.getLocation({
+ type: 'gcj02',
+ success: success,
+ fail: fail,
+ complete: complete
+ });
+ },
+
+ /**
+ * 获取location参数
+ */
+ getLocationParam(location) {
+ if (typeof location == 'string') {
+ var locationArr = location.split(',');
+ if (locationArr.length === 2) {
+ location = {
+ latitude: location.split(',')[0],
+ longitude: location.split(',')[1]
+ };
+ } else {
+ location = {};
+ }
+ }
+ return location;
+ },
+
+ /**
+ * 回调函数默认处理
+ */
+ polyfillParam(param) {
+ param.success = param.success || function () { };
+ param.fail = param.fail || function () { };
+ param.complete = param.complete || function () { };
+ },
+
+ /**
+ * 验证param对应的key值是否为空
+ *
+ * @param {Object} param 接口参数
+ * @param {String} key 对应参数的key
+ */
+ checkParamKeyEmpty(param, key) {
+ if (!param[key]) {
+ var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key +'参数格式有误');
+ param.fail(errconf);
+ param.complete(errconf);
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * 验证参数中是否存在检索词keyword
+ *
+ * @param {Object} param 接口参数
+ */
+ checkKeyword(param){
+ return !this.checkParamKeyEmpty(param, 'keyword');
+ },
+
+ /**
+ * 验证location值
+ *
+ * @param {Object} param 接口参数
+ */
+ checkLocation(param) {
+ var location = this.getLocationParam(param.location);
+ if (!location || !location.latitude || !location.longitude) {
+ var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误');
+ param.fail(errconf);
+ param.complete(errconf);
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * 构造错误数据结构
+ * @param {Number} errCode 错误码
+ * @param {Number} errMsg 错误描述
+ */
+ buildErrorConfig(errCode, errMsg) {
+ return {
+ status: errCode,
+ message: errMsg
+ };
+ },
+
+ /**
+ *
+ * 数据处理函数
+ * 根据传入参数不同处理不同数据
+ * @param {String} feature 功能名称
+ * search 地点搜索
+ * suggest关键词提示
+ * reverseGeocoder逆地址解析
+ * geocoder地址解析
+ * getCityList获取城市列表:父集
+ * getDistrictByCityId获取区县列表:子集
+ * calculateDistance距离计算
+ * @param {Object} param 接口参数
+ * @param {Object} data 数据
+ */
+ handleData(param,data,feature){
+ if (feature == 'search') {
+ var searchResult = data.data;
+ var searchSimplify = [];
+ for (var i = 0; i < searchResult.length; i++) {
+ searchSimplify.push({
+ id: searchResult[i].id || null,
+ title: searchResult[i].title || null,
+ latitude: searchResult[i].location && searchResult[i].location.lat || null,
+ longitude: searchResult[i].location && searchResult[i].location.lng || null,
+ address: searchResult[i].address || null,
+ category: searchResult[i].category || null,
+ tel: searchResult[i].tel || null,
+ adcode: searchResult[i].ad_info && searchResult[i].ad_info.adcode || null,
+ city: searchResult[i].ad_info && searchResult[i].ad_info.city || null,
+ district: searchResult[i].ad_info && searchResult[i].ad_info.district || null,
+ province: searchResult[i].ad_info && searchResult[i].ad_info.province || null
+ })
+ }
+ param.success(data, {
+ searchResult: searchResult,
+ searchSimplify: searchSimplify
+ })
+ } else if (feature == 'suggest') {
+ var suggestResult = data.data;
+ var suggestSimplify = [];
+ for (var i = 0; i < suggestResult.length; i++) {
+ suggestSimplify.push({
+ adcode: suggestResult[i].adcode || null,
+ address: suggestResult[i].address || null,
+ category: suggestResult[i].category || null,
+ city: suggestResult[i].city || null,
+ district: suggestResult[i].district || null,
+ id: suggestResult[i].id || null,
+ latitude: suggestResult[i].location && suggestResult[i].location.lat || null,
+ longitude: suggestResult[i].location && suggestResult[i].location.lng || null,
+ province: suggestResult[i].province || null,
+ title: suggestResult[i].title || null,
+ type: suggestResult[i].type || null
+ })
+ }
+ param.success(data, {
+ suggestResult: suggestResult,
+ suggestSimplify: suggestSimplify
+ })
+ } else if (feature == 'reverseGeocoder') {
+ var reverseGeocoderResult = data.result;
+ var reverseGeocoderSimplify = {
+ address: reverseGeocoderResult.address || null,
+ latitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lat || null,
+ longitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lng || null,
+ adcode: reverseGeocoderResult.ad_info && reverseGeocoderResult.ad_info.adcode || null,
+ city: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.city || null,
+ district: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.district || null,
+ nation: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.nation || null,
+ province: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.province || null,
+ street: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street || null,
+ street_number: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street_number || null,
+ recommend: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.recommend || null,
+ rough: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.rough || null
+ };
+ if (reverseGeocoderResult.pois) {//判断是否返回周边poi
+ var pois = reverseGeocoderResult.pois;
+ var poisSimplify = [];
+ for (var i = 0;i < pois.length;i++) {
+ poisSimplify.push({
+ id: pois[i].id || null,
+ title: pois[i].title || null,
+ latitude: pois[i].location && pois[i].location.lat || null,
+ longitude: pois[i].location && pois[i].location.lng || null,
+ address: pois[i].address || null,
+ category: pois[i].category || null,
+ adcode: pois[i].ad_info && pois[i].ad_info.adcode || null,
+ city: pois[i].ad_info && pois[i].ad_info.city || null,
+ district: pois[i].ad_info && pois[i].ad_info.district || null,
+ province: pois[i].ad_info && pois[i].ad_info.province || null
+ })
+ }
+ param.success(data,{
+ reverseGeocoderResult: reverseGeocoderResult,
+ reverseGeocoderSimplify: reverseGeocoderSimplify,
+ pois: pois,
+ poisSimplify: poisSimplify
+ })
+ } else {
+ param.success(data, {
+ reverseGeocoderResult: reverseGeocoderResult,
+ reverseGeocoderSimplify: reverseGeocoderSimplify
+ })
+ }
+ } else if (feature == 'geocoder') {
+ var geocoderResult = data.result;
+ var geocoderSimplify = {
+ title: geocoderResult.title || null,
+ latitude: geocoderResult.location && geocoderResult.location.lat || null,
+ longitude: geocoderResult.location && geocoderResult.location.lng || null,
+ adcode: geocoderResult.ad_info && geocoderResult.ad_info.adcode || null,
+ province: geocoderResult.address_components && geocoderResult.address_components.province || null,
+ city: geocoderResult.address_components && geocoderResult.address_components.city || null,
+ district: geocoderResult.address_components && geocoderResult.address_components.district || null,
+ street: geocoderResult.address_components && geocoderResult.address_components.street || null,
+ street_number: geocoderResult.address_components && geocoderResult.address_components.street_number || null,
+ level: geocoderResult.level || null
+ };
+ param.success(data,{
+ geocoderResult: geocoderResult,
+ geocoderSimplify: geocoderSimplify
+ });
+ } else if (feature == 'getCityList') {
+ var provinceResult = data.result[0];
+ var cityResult = data.result[1];
+ var districtResult = data.result[2];
+ param.success(data,{
+ provinceResult: provinceResult,
+ cityResult: cityResult,
+ districtResult: districtResult
+ });
+ } else if (feature == 'getDistrictByCityId') {
+ var districtByCity = data.result[0];
+ param.success(data, districtByCity);
+ } else if (feature == 'calculateDistance') {
+ var calculateDistanceResult = data.result.elements;
+ var distance = [];
+ for (var i = 0; i < calculateDistanceResult.length; i++){
+ distance.push(calculateDistanceResult[i].distance);
+ }
+ param.success(data, {
+ calculateDistanceResult: calculateDistanceResult,
+ distance: distance
+ });
+ } else if (feature == 'direction') {
+ var direction = data.result.routes;
+ param.success(data,direction);
+ } else {
+ param.success(data);
+ }
+ },
+
+ /**
+ * 构造微信请求参数,公共属性处理
+ *
+ * @param {Object} param 接口参数
+ * @param {Object} param 配置项
+ * @param {String} feature 方法名
+ */
+ buildWxRequestConfig(param, options, feature) {
+ var that = this;
+ options.header = { "content-type": "application/json" };
+ options.method = 'GET';
+ options.success = function (res) {
+ var data = res.data;
+ if (data.status === 0) {
+ that.handleData(param, data, feature);
+ } else {
+ param.fail(data);
+ }
+ };
+ options.fail = function (res) {
+ res.statusCode = ERROR_CONF.WX_ERR_CODE;
+ param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ };
+ options.complete = function (res) {
+ var statusCode = +res.statusCode;
+ switch(statusCode) {
+ case ERROR_CONF.WX_ERR_CODE: {
+ param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ break;
+ }
+ case ERROR_CONF.WX_OK_CODE: {
+ var data = res.data;
+ if (data.status === 0) {
+ param.complete(data);
+ } else {
+ param.complete(that.buildErrorConfig(data.status, data.message));
+ }
+ break;
+ }
+ default:{
+ param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG));
+ }
+
+ }
+ };
+ return options;
+ },
+
+ /**
+ * 处理用户参数是否传入坐标进行不同的处理
+ */
+ locationProcess(param, locationsuccess, locationfail, locationcomplete) {
+ var that = this;
+ locationfail = locationfail || function (res) {
+ res.statusCode = ERROR_CONF.WX_ERR_CODE;
+ param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ };
+ locationcomplete = locationcomplete || function (res) {
+ if (res.statusCode == ERROR_CONF.WX_ERR_CODE) {
+ param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ }
+ };
+ if (!param.location) {
+ that.getWXLocation(locationsuccess, locationfail, locationcomplete);
+ } else if (that.checkLocation(param)) {
+ var location = Utils.getLocationParam(param.location);
+ locationsuccess(location);
+ }
+ }
+};
+
+
+class QQMapWX {
+
+ /**
+ * 构造函数
+ *
+ * @param {Object} options 接口参数,key 为必选参数
+ */
+ constructor(options) {
+ if (!options.key) {
+ throw Error('key值不能为空');
+ }
+ this.key = options.key;
+ };
+
+ /**
+ * POI周边检索
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 参数对象结构可以参考
+ * @see http://lbs.qq.com/webservice_v1/guide-search.html
+ */
+ search(options) {
+ var that = this;
+ options = options || {};
+
+ Utils.polyfillParam(options);
+
+ if (!Utils.checkKeyword(options)) {
+ return;
+ }
+
+ var requestParam = {
+ keyword: options.keyword,
+ orderby: options.orderby || '_distance',
+ page_size: options.page_size || 10,
+ page_index: options.page_index || 1,
+ output: 'json',
+ key: that.key
+ };
+
+ if (options.address_format) {
+ requestParam.address_format = options.address_format;
+ }
+
+ if (options.filter) {
+ requestParam.filter = options.filter;
+ }
+
+ var distance = options.distance || "1000";
+ var auto_extend = options.auto_extend || 1;
+ var region = null;
+ var rectangle = null;
+
+ //判断城市限定参数
+ if (options.region) {
+ region = options.region;
+ }
+
+ //矩形限定坐标(暂时只支持字符串格式)
+ if (options.rectangle) {
+ rectangle = options.rectangle;
+ }
+
+ var locationsuccess = function (result) {
+ if (region && !rectangle) {
+ //城市限定参数拼接
+ requestParam.boundary = "region(" + region + "," + auto_extend + "," + result.latitude + "," + result.longitude + ")";
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+ }
+ } else if (rectangle && !region) {
+ //矩形搜索
+ requestParam.boundary = "rectangle(" + rectangle + ")";
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+ }
+ } else {
+ requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend + ")";
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+ }
+ }
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_SEARCH,
+ data: requestParam
+ }, 'search'));
+ };
+ Utils.locationProcess(options, locationsuccess);
+ };
+
+ /**
+ * sug模糊检索
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 参数对象结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-suggestion.html
+ */
+ getSuggestion(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (!Utils.checkKeyword(options)) {
+ return;
+ }
+
+ var requestParam = {
+ keyword: options.keyword,
+ region: options.region || '全国',
+ region_fix: options.region_fix || 0,
+ policy: options.policy || 0,
+ page_size: options.page_size || 10,//控制显示条数
+ page_index: options.page_index || 1,//控制页数
+ get_subpois : options.get_subpois || 0,//返回子地点
+ output: 'json',
+ key: that.key
+ };
+ //长地址
+ if (options.address_format) {
+ requestParam.address_format = options.address_format;
+ }
+ //过滤
+ if (options.filter) {
+ requestParam.filter = options.filter;
+ }
+ //排序
+ if (options.location) {
+ var locationsuccess = function (result) {
+ requestParam.location = result.latitude + ',' + result.longitude;
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest');
+ }
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_SUGGESTION,
+ data: requestParam
+ }, "suggest"));
+ };
+ Utils.locationProcess(options, locationsuccess);
+ } else {
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest');
+ }
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_SUGGESTION,
+ data: requestParam
+ }, "suggest"));
+ }
+ };
+
+ /**
+ * 逆地址解析
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-gcoder.html
+ */
+ reverseGeocoder(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+ var requestParam = {
+ coord_type: options.coord_type || 5,
+ get_poi: options.get_poi || 0,
+ output: 'json',
+ key: that.key
+ };
+ if (options.poi_options) {
+ requestParam.poi_options = options.poi_options
+ }
+
+ var locationsuccess = function (result) {
+ requestParam.location = result.latitude + ',' + result.longitude;
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'reverseGeocoder');
+ }
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_GET_GEOCODER,
+ data: requestParam
+ }, 'reverseGeocoder'));
+ };
+ Utils.locationProcess(options, locationsuccess);
+ };
+
+ /**
+ * 地址解析
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-geocoder.html
+ */
+ geocoder(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'address')) {
+ return;
+ }
+
+ var requestParam = {
+ address: options.address,
+ output: 'json',
+ key: that.key
+ };
+
+ //城市限定
+ if (options.region) {
+ requestParam.region = options.region;
+ }
+
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'geocoder');
+ }
+
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_GET_GEOCODER,
+ data: requestParam
+ },'geocoder'));
+ };
+
+
+ /**
+ * 获取城市列表
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-region.html
+ */
+ getCityList(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+ var requestParam = {
+ output: 'json',
+ key: that.key
+ };
+
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'getCityList');
+ }
+
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_CITY_LIST,
+ data: requestParam
+ },'getCityList'));
+ };
+
+ /**
+ * 获取对应城市ID的区县列表
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-region.html
+ */
+ getDistrictByCityId(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'id')) {
+ return;
+ }
+
+ var requestParam = {
+ id: options.id || '',
+ output: 'json',
+ key: that.key
+ };
+
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'getDistrictByCityId');
+ }
+
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_AREA_LIST,
+ data: requestParam
+ },'getDistrictByCityId'));
+ };
+
+ /**
+ * 用于单起点到多终点的路线距离(非直线距离)计算:
+ * 支持两种距离计算方式:步行和驾车。
+ * 起点到终点最大限制直线距离10公里。
+ *
+ * 新增直线距离计算。
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-distance.html
+ */
+ calculateDistance(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'to')) {
+ return;
+ }
+
+ var requestParam = {
+ mode: options.mode || 'walking',
+ to: Utils.location2query(options.to),
+ output: 'json',
+ key: that.key
+ };
+
+ if (options.from) {
+ options.location = options.from;
+ }
+
+ //计算直线距离
+ if(requestParam.mode == 'straight'){
+ var locationsuccess = function (result) {
+ var locationTo = Utils.getEndLocation(requestParam.to);//处理终点坐标
+ var data = {
+ message:"query ok",
+ result:{
+ elements:[]
+ },
+ status:0
+ };
+ for (var i = 0; i < locationTo.length; i++) {
+ data.result.elements.push({//将坐标存入
+ distance: Utils.getDistance(result.latitude, result.longitude, locationTo[i].lat, locationTo[i].lng),
+ duration:0,
+ from:{
+ lat: result.latitude,
+ lng:result.longitude
+ },
+ to:{
+ lat: locationTo[i].lat,
+ lng: locationTo[i].lng
+ }
+ });
+ }
+ var calculateResult = data.result.elements;
+ var distanceResult = [];
+ for (var i = 0; i < calculateResult.length; i++) {
+ distanceResult.push(calculateResult[i].distance);
+ }
+ return options.success(data,{
+ calculateResult: calculateResult,
+ distanceResult: distanceResult
+ });
+ };
+
+ Utils.locationProcess(options, locationsuccess);
+ } else {
+ var locationsuccess = function (result) {
+ requestParam.from = result.latitude + ',' + result.longitude;
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'calculateDistance');
+ }
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_DISTANCE,
+ data: requestParam
+ },'calculateDistance'));
+ };
+
+ Utils.locationProcess(options, locationsuccess);
+ }
+ };
+
+ /**
+ * 路线规划:
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * https://lbs.qq.com/webservice_v1/guide-road.html
+ */
+ direction(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'to')) {
+ return;
+ }
+
+ var requestParam = {
+ output: 'json',
+ key: that.key
+ };
+
+ //to格式处理
+ if (typeof options.to == 'string') {
+ requestParam.to = options.to;
+ } else {
+ requestParam.to = options.to.latitude + ',' + options.to.longitude;
+ }
+ //初始化局部请求域名
+ var SET_URL_DIRECTION = null;
+ //设置默认mode属性
+ options.mode = options.mode || MODE.driving;
+
+ //设置请求域名
+ SET_URL_DIRECTION = URL_DIRECTION + options.mode;
+
+ if (options.from) {
+ options.location = options.from;
+ }
+
+ if (options.mode == MODE.driving) {
+ if (options.from_poi) {
+ requestParam.from_poi = options.from_poi;
+ }
+ if (options.heading) {
+ requestParam.heading = options.heading;
+ }
+ if (options.speed) {
+ requestParam.speed = options.speed;
+ }
+ if (options.accuracy) {
+ requestParam.accuracy = options.accuracy;
+ }
+ if (options.road_type) {
+ requestParam.road_type = options.road_type;
+ }
+ if (options.to_poi) {
+ requestParam.to_poi = options.to_poi;
+ }
+ if (options.from_track) {
+ requestParam.from_track = options.from_track;
+ }
+ if (options.waypoints) {
+ requestParam.waypoints = options.waypoints;
+ }
+ if (options.policy) {
+ requestParam.policy = options.policy;
+ }
+ if (options.plate_number) {
+ requestParam.plate_number = options.plate_number;
+ }
+ }
+
+ if (options.mode == MODE.transit) {
+ if (options.departure_time) {
+ requestParam.departure_time = options.departure_time;
+ }
+ if (options.policy) {
+ requestParam.policy = options.policy;
+ }
+ }
+
+ var locationsuccess = function (result) {
+ requestParam.from = result.latitude + ',' + result.longitude;
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'direction',options.mode);
+ }
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: SET_URL_DIRECTION,
+ data: requestParam
+ }, 'direction'));
+ };
+
+ Utils.locationProcess(options, locationsuccess);
+ }
+};
+
+module.exports = QQMapWX;
\ No newline at end of file
diff --git a/js_sdk/qqmap-wx-jssdk/qqmap-wx-jssdk.min.js b/js_sdk/qqmap-wx-jssdk/qqmap-wx-jssdk.min.js
new file mode 100644
index 0000000..8fa1477
--- /dev/null
+++ b/js_sdk/qqmap-wx-jssdk/qqmap-wx-jssdk.min.js
@@ -0,0 +1 @@
+var ERROR_CONF = { KEY_ERR: 311, KEY_ERR_MSG: 'key格式错误', PARAM_ERR: 310, PARAM_ERR_MSG: '请求参数信息有误', SYSTEM_ERR: 600, SYSTEM_ERR_MSG: '系统错误', WX_ERR_CODE: 1000, WX_OK_CODE: 200 }; var BASE_URL = 'https://apis.map.qq.com/ws/'; var URL_SEARCH = BASE_URL + 'place/v1/search'; var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion'; var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/'; var URL_CITY_LIST = BASE_URL + 'district/v1/list'; var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren'; var URL_DISTANCE = BASE_URL + 'distance/v1/'; var URL_DIRECTION = BASE_URL + 'direction/v1/'; var MODE = { driving: 'driving', transit: 'transit' }; var EARTH_RADIUS = 6378136.49; var Utils = { safeAdd(x, y) { var lsw = (x & 0xffff) + (y & 0xffff); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xffff) }, bitRotateLeft(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)) }, md5cmn(q, a, b, x, s, t) { return this.safeAdd(this.bitRotateLeft(this.safeAdd(this.safeAdd(a, q), this.safeAdd(x, t)), s), b) }, md5ff(a, b, c, d, x, s, t) { return this.md5cmn((b & c) | (~b & d), a, b, x, s, t) }, md5gg(a, b, c, d, x, s, t) { return this.md5cmn((b & d) | (c & ~d), a, b, x, s, t) }, md5hh(a, b, c, d, x, s, t) { return this.md5cmn(b ^ c ^ d, a, b, x, s, t) }, md5ii(a, b, c, d, x, s, t) { return this.md5cmn(c ^ (b | ~d), a, b, x, s, t) }, binlMD5(x, len) { x[len >> 5] |= 0x80 << (len % 32); x[((len + 64) >>> 9 << 4) + 14] = len; var i; var olda; var oldb; var oldc; var oldd; var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; for (i = 0; i < x.length; i += 16) { olda = a; oldb = b; oldc = c; oldd = d; a = this.md5ff(a, b, c, d, x[i], 7, -680876936); d = this.md5ff(d, a, b, c, x[i + 1], 12, -389564586); c = this.md5ff(c, d, a, b, x[i + 2], 17, 606105819); b = this.md5ff(b, c, d, a, x[i + 3], 22, -1044525330); a = this.md5ff(a, b, c, d, x[i + 4], 7, -176418897); d = this.md5ff(d, a, b, c, x[i + 5], 12, 1200080426); c = this.md5ff(c, d, a, b, x[i + 6], 17, -1473231341); b = this.md5ff(b, c, d, a, x[i + 7], 22, -45705983); a = this.md5ff(a, b, c, d, x[i + 8], 7, 1770035416); d = this.md5ff(d, a, b, c, x[i + 9], 12, -1958414417); c = this.md5ff(c, d, a, b, x[i + 10], 17, -42063); b = this.md5ff(b, c, d, a, x[i + 11], 22, -1990404162); a = this.md5ff(a, b, c, d, x[i + 12], 7, 1804603682); d = this.md5ff(d, a, b, c, x[i + 13], 12, -40341101); c = this.md5ff(c, d, a, b, x[i + 14], 17, -1502002290); b = this.md5ff(b, c, d, a, x[i + 15], 22, 1236535329); a = this.md5gg(a, b, c, d, x[i + 1], 5, -165796510); d = this.md5gg(d, a, b, c, x[i + 6], 9, -1069501632); c = this.md5gg(c, d, a, b, x[i + 11], 14, 643717713); b = this.md5gg(b, c, d, a, x[i], 20, -373897302); a = this.md5gg(a, b, c, d, x[i + 5], 5, -701558691); d = this.md5gg(d, a, b, c, x[i + 10], 9, 38016083); c = this.md5gg(c, d, a, b, x[i + 15], 14, -660478335); b = this.md5gg(b, c, d, a, x[i + 4], 20, -405537848); a = this.md5gg(a, b, c, d, x[i + 9], 5, 568446438); d = this.md5gg(d, a, b, c, x[i + 14], 9, -1019803690); c = this.md5gg(c, d, a, b, x[i + 3], 14, -187363961); b = this.md5gg(b, c, d, a, x[i + 8], 20, 1163531501); a = this.md5gg(a, b, c, d, x[i + 13], 5, -1444681467); d = this.md5gg(d, a, b, c, x[i + 2], 9, -51403784); c = this.md5gg(c, d, a, b, x[i + 7], 14, 1735328473); b = this.md5gg(b, c, d, a, x[i + 12], 20, -1926607734); a = this.md5hh(a, b, c, d, x[i + 5], 4, -378558); d = this.md5hh(d, a, b, c, x[i + 8], 11, -2022574463); c = this.md5hh(c, d, a, b, x[i + 11], 16, 1839030562); b = this.md5hh(b, c, d, a, x[i + 14], 23, -35309556); a = this.md5hh(a, b, c, d, x[i + 1], 4, -1530992060); d = this.md5hh(d, a, b, c, x[i + 4], 11, 1272893353); c = this.md5hh(c, d, a, b, x[i + 7], 16, -155497632); b = this.md5hh(b, c, d, a, x[i + 10], 23, -1094730640); a = this.md5hh(a, b, c, d, x[i + 13], 4, 681279174); d = this.md5hh(d, a, b, c, x[i], 11, -358537222); c = this.md5hh(c, d, a, b, x[i + 3], 16, -722521979); b = this.md5hh(b, c, d, a, x[i + 6], 23, 76029189); a = this.md5hh(a, b, c, d, x[i + 9], 4, -640364487); d = this.md5hh(d, a, b, c, x[i + 12], 11, -421815835); c = this.md5hh(c, d, a, b, x[i + 15], 16, 530742520); b = this.md5hh(b, c, d, a, x[i + 2], 23, -995338651); a = this.md5ii(a, b, c, d, x[i], 6, -198630844); d = this.md5ii(d, a, b, c, x[i + 7], 10, 1126891415); c = this.md5ii(c, d, a, b, x[i + 14], 15, -1416354905); b = this.md5ii(b, c, d, a, x[i + 5], 21, -57434055); a = this.md5ii(a, b, c, d, x[i + 12], 6, 1700485571); d = this.md5ii(d, a, b, c, x[i + 3], 10, -1894986606); c = this.md5ii(c, d, a, b, x[i + 10], 15, -1051523); b = this.md5ii(b, c, d, a, x[i + 1], 21, -2054922799); a = this.md5ii(a, b, c, d, x[i + 8], 6, 1873313359); d = this.md5ii(d, a, b, c, x[i + 15], 10, -30611744); c = this.md5ii(c, d, a, b, x[i + 6], 15, -1560198380); b = this.md5ii(b, c, d, a, x[i + 13], 21, 1309151649); a = this.md5ii(a, b, c, d, x[i + 4], 6, -145523070); d = this.md5ii(d, a, b, c, x[i + 11], 10, -1120210379); c = this.md5ii(c, d, a, b, x[i + 2], 15, 718787259); b = this.md5ii(b, c, d, a, x[i + 9], 21, -343485551); a = this.safeAdd(a, olda); b = this.safeAdd(b, oldb); c = this.safeAdd(c, oldc); d = this.safeAdd(d, oldd) } return [a, b, c, d] }, binl2rstr(input) { var i; var output = ''; var length32 = input.length * 32; for (i = 0; i < length32; i += 8) { output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff) } return output }, rstr2binl(input) { var i; var output = []; output[(input.length >> 2) - 1] = undefined; for (i = 0; i < output.length; i += 1) { output[i] = 0 } var length8 = input.length * 8; for (i = 0; i < length8; i += 8) { output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32) } return output }, rstrMD5(s) { return this.binl2rstr(this.binlMD5(this.rstr2binl(s), s.length * 8)) }, rstrHMACMD5(key, data) { var i; var bkey = this.rstr2binl(key); var ipad = []; var opad = []; var hash; ipad[15] = opad[15] = undefined; if (bkey.length > 16) { bkey = this.binlMD5(bkey, key.length * 8) } for (i = 0; i < 16; i += 1) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5c5c5c5c } hash = this.binlMD5(ipad.concat(this.rstr2binl(data)), 512 + data.length * 8); return this.binl2rstr(this.binlMD5(opad.concat(hash), 512 + 128)) }, rstr2hex(input) { var hexTab = '0123456789abcdef'; var output = ''; var x; var i; for (i = 0; i < input.length; i += 1) { x = input.charCodeAt(i); output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f) } return output }, str2rstrUTF8(input) { return unescape(encodeURIComponent(input)) }, rawMD5(s) { return this.rstrMD5(this.str2rstrUTF8(s)) }, hexMD5(s) { return this.rstr2hex(this.rawMD5(s)) }, rawHMACMD5(k, d) { return this.rstrHMACMD5(this.str2rstrUTF8(k), str2rstrUTF8(d)) }, hexHMACMD5(k, d) { return this.rstr2hex(this.rawHMACMD5(k, d)) }, md5(string, key, raw) { if (!key) { if (!raw) { return this.hexMD5(string) } return this.rawMD5(string) } if (!raw) { return this.hexHMACMD5(key, string) } return this.rawHMACMD5(key, string) }, getSig(requestParam, sk, feature, mode) { var sig = null; var requestArr = []; Object.keys(requestParam).sort().forEach(function (key) { requestArr.push(key + '=' + requestParam[key]) }); if (feature == 'search') { sig = '/ws/place/v1/search?' + requestArr.join('&') + sk } if (feature == 'suggest') { sig = '/ws/place/v1/suggestion?' + requestArr.join('&') + sk } if (feature == 'reverseGeocoder') { sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk } if (feature == 'geocoder') { sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk } if (feature == 'getCityList') { sig = '/ws/district/v1/list?' + requestArr.join('&') + sk } if (feature == 'getDistrictByCityId') { sig = '/ws/district/v1/getchildren?' + requestArr.join('&') + sk } if (feature == 'calculateDistance') { sig = '/ws/distance/v1/?' + requestArr.join('&') + sk } if (feature == 'direction') { sig = '/ws/direction/v1/' + mode + '?' + requestArr.join('&') + sk } sig = this.md5(sig); return sig }, location2query(data) { if (typeof data == 'string') { return data } var query = ''; for (var i = 0; i < data.length; i++) { var d = data[i]; if (!!query) { query += ';' } if (d.location) { query = query + d.location.lat + ',' + d.location.lng } if (d.latitude && d.longitude) { query = query + d.latitude + ',' + d.longitude } } return query }, rad(d) { return d * Math.PI / 180.0 }, getEndLocation(location) { var to = location.split(';'); var endLocation = []; for (var i = 0; i < to.length; i++) { endLocation.push({ lat: parseFloat(to[i].split(',')[0]), lng: parseFloat(to[i].split(',')[1]) }) } return endLocation }, getDistance(latFrom, lngFrom, latTo, lngTo) { var radLatFrom = this.rad(latFrom); var radLatTo = this.rad(latTo); var a = radLatFrom - radLatTo; var b = this.rad(lngFrom) - this.rad(lngTo); var distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLatFrom) * Math.cos(radLatTo) * Math.pow(Math.sin(b / 2), 2))); distance = distance * EARTH_RADIUS; distance = Math.round(distance * 10000) / 10000; return parseFloat(distance.toFixed(0)) }, getWXLocation(success, fail, complete) { wx.getLocation({ type: 'gcj02', success: success, fail: fail, complete: complete }) }, getLocationParam(location) { if (typeof location == 'string') { var locationArr = location.split(','); if (locationArr.length === 2) { location = { latitude: location.split(',')[0], longitude: location.split(',')[1] } } else { location = {} } } return location }, polyfillParam(param) { param.success = param.success || function () { }; param.fail = param.fail || function () { }; param.complete = param.complete || function () { } }, checkParamKeyEmpty(param, key) { if (!param[key]) { var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key + '参数格式有误'); param.fail(errconf); param.complete(errconf); return true } return false }, checkKeyword(param) { return !this.checkParamKeyEmpty(param, 'keyword') }, checkLocation(param) { var location = this.getLocationParam(param.location); if (!location || !location.latitude || !location.longitude) { var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误'); param.fail(errconf); param.complete(errconf); return false } return true }, buildErrorConfig(errCode, errMsg) { return { status: errCode, message: errMsg } }, handleData(param, data, feature) { if (feature == 'search') { var searchResult = data.data; var searchSimplify = []; for (var i = 0; i < searchResult.length; i++) { searchSimplify.push({ id: searchResult[i].id || null, title: searchResult[i].title || null, latitude: searchResult[i].location && searchResult[i].location.lat || null, longitude: searchResult[i].location && searchResult[i].location.lng || null, address: searchResult[i].address || null, category: searchResult[i].category || null, tel: searchResult[i].tel || null, adcode: searchResult[i].ad_info && searchResult[i].ad_info.adcode || null, city: searchResult[i].ad_info && searchResult[i].ad_info.city || null, district: searchResult[i].ad_info && searchResult[i].ad_info.district || null, province: searchResult[i].ad_info && searchResult[i].ad_info.province || null }) } param.success(data, { searchResult: searchResult, searchSimplify: searchSimplify }) } else if (feature == 'suggest') { var suggestResult = data.data; var suggestSimplify = []; for (var i = 0; i < suggestResult.length; i++) { suggestSimplify.push({ adcode: suggestResult[i].adcode || null, address: suggestResult[i].address || null, category: suggestResult[i].category || null, city: suggestResult[i].city || null, district: suggestResult[i].district || null, id: suggestResult[i].id || null, latitude: suggestResult[i].location && suggestResult[i].location.lat || null, longitude: suggestResult[i].location && suggestResult[i].location.lng || null, province: suggestResult[i].province || null, title: suggestResult[i].title || null, type: suggestResult[i].type || null }) } param.success(data, { suggestResult: suggestResult, suggestSimplify: suggestSimplify }) } else if (feature == 'reverseGeocoder') { var reverseGeocoderResult = data.result; var reverseGeocoderSimplify = { address: reverseGeocoderResult.address || null, latitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lat || null, longitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lng || null, adcode: reverseGeocoderResult.ad_info && reverseGeocoderResult.ad_info.adcode || null, city: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.city || null, district: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.district || null, nation: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.nation || null, province: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.province || null, street: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street || null, street_number: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street_number || null, recommend: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.recommend || null, rough: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.rough || null }; if (reverseGeocoderResult.pois) { var pois = reverseGeocoderResult.pois; var poisSimplify = []; for (var i = 0; i < pois.length; i++) { poisSimplify.push({ id: pois[i].id || null, title: pois[i].title || null, latitude: pois[i].location && pois[i].location.lat || null, longitude: pois[i].location && pois[i].location.lng || null, address: pois[i].address || null, category: pois[i].category || null, adcode: pois[i].ad_info && pois[i].ad_info.adcode || null, city: pois[i].ad_info && pois[i].ad_info.city || null, district: pois[i].ad_info && pois[i].ad_info.district || null, province: pois[i].ad_info && pois[i].ad_info.province || null }) } param.success(data, { reverseGeocoderResult: reverseGeocoderResult, reverseGeocoderSimplify: reverseGeocoderSimplify, pois: pois, poisSimplify: poisSimplify }) } else { param.success(data, { reverseGeocoderResult: reverseGeocoderResult, reverseGeocoderSimplify: reverseGeocoderSimplify }) } } else if (feature == 'geocoder') { var geocoderResult = data.result; var geocoderSimplify = { title: geocoderResult.title || null, latitude: geocoderResult.location && geocoderResult.location.lat || null, longitude: geocoderResult.location && geocoderResult.location.lng || null, adcode: geocoderResult.ad_info && geocoderResult.ad_info.adcode || null, province: geocoderResult.address_components && geocoderResult.address_components.province || null, city: geocoderResult.address_components && geocoderResult.address_components.city || null, district: geocoderResult.address_components && geocoderResult.address_components.district || null, street: geocoderResult.address_components && geocoderResult.address_components.street || null, street_number: geocoderResult.address_components && geocoderResult.address_components.street_number || null, level: geocoderResult.level || null }; param.success(data, { geocoderResult: geocoderResult, geocoderSimplify: geocoderSimplify }) } else if (feature == 'getCityList') { var provinceResult = data.result[0]; var cityResult = data.result[1]; var districtResult = data.result[2]; param.success(data, { provinceResult: provinceResult, cityResult: cityResult, districtResult: districtResult }) } else if (feature == 'getDistrictByCityId') { var districtByCity = data.result[0]; param.success(data, districtByCity) } else if (feature == 'calculateDistance') { var calculateDistanceResult = data.result.elements; var distance = []; for (var i = 0; i < calculateDistanceResult.length; i++) { distance.push(calculateDistanceResult[i].distance) } param.success(data, { calculateDistanceResult: calculateDistanceResult, distance: distance }) } else if (feature == 'direction') { var direction = data.result.routes; param.success(data, direction) } else { param.success(data) } }, buildWxRequestConfig(param, options, feature) { var that = this; options.header = { "content-type": "application/json" }; options.method = 'GET'; options.success = function (res) { var data = res.data; if (data.status === 0) { that.handleData(param, data, feature) } else { param.fail(data) } }; options.fail = function (res) { res.statusCode = ERROR_CONF.WX_ERR_CODE; param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)) }; options.complete = function (res) { var statusCode = +res.statusCode; switch (statusCode) { case ERROR_CONF.WX_ERR_CODE: { param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)); break } case ERROR_CONF.WX_OK_CODE: { var data = res.data; if (data.status === 0) { param.complete(data) } else { param.complete(that.buildErrorConfig(data.status, data.message)) } break } default: { param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG)) } } }; return options }, locationProcess(param, locationsuccess, locationfail, locationcomplete) { var that = this; locationfail = locationfail || function (res) { res.statusCode = ERROR_CONF.WX_ERR_CODE; param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)) }; locationcomplete = locationcomplete || function (res) { if (res.statusCode == ERROR_CONF.WX_ERR_CODE) { param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg)) } }; if (!param.location) { that.getWXLocation(locationsuccess, locationfail, locationcomplete) } else if (that.checkLocation(param)) { var location = Utils.getLocationParam(param.location); locationsuccess(location) } } }; class QQMapWX { constructor(options) { if (!options.key) { throw Error('key值不能为空') } this.key = options.key }; search(options) { var that = this; options = options || {}; Utils.polyfillParam(options); if (!Utils.checkKeyword(options)) { return } var requestParam = { keyword: options.keyword, orderby: options.orderby || '_distance', page_size: options.page_size || 10, page_index: options.page_index || 1, output: 'json', key: that.key }; if (options.address_format) { requestParam.address_format = options.address_format } if (options.filter) { requestParam.filter = options.filter } var distance = options.distance || "1000"; var auto_extend = options.auto_extend || 1; var region = null; var rectangle = null; if (options.region) { region = options.region } if (options.rectangle) { rectangle = options.rectangle } var locationsuccess = function (result) { if (region && !rectangle) { requestParam.boundary = "region(" + region + "," + auto_extend + "," + result.latitude + "," + result.longitude + ")"; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'search') } } else if (rectangle && !region) { requestParam.boundary = "rectangle(" + rectangle + ")"; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'search') } } else { requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend + ")"; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'search') } } wx.request(Utils.buildWxRequestConfig(options, { url: URL_SEARCH, data: requestParam }, 'search')) }; Utils.locationProcess(options, locationsuccess) }; getSuggestion(options) { var that = this; options = options || {}; Utils.polyfillParam(options); if (!Utils.checkKeyword(options)) { return } var requestParam = { keyword: options.keyword, region: options.region || '全国', region_fix: options.region_fix || 0, policy: options.policy || 0, page_size: options.page_size || 10, page_index: options.page_index || 1, get_subpois: options.get_subpois || 0, output: 'json', key: that.key }; if (options.address_format) { requestParam.address_format = options.address_format } if (options.filter) { requestParam.filter = options.filter } if (options.location) { var locationsuccess = function (result) { requestParam.location = result.latitude + ',' + result.longitude; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_SUGGESTION, data: requestParam }, "suggest")) }; Utils.locationProcess(options, locationsuccess) } else { if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_SUGGESTION, data: requestParam }, "suggest")) } }; reverseGeocoder(options) { var that = this; options = options || {}; Utils.polyfillParam(options); var requestParam = { coord_type: options.coord_type || 5, get_poi: options.get_poi || 0, output: 'json', key: that.key }; if (options.poi_options) { requestParam.poi_options = options.poi_options } var locationsuccess = function (result) { requestParam.location = result.latitude + ',' + result.longitude; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'reverseGeocoder') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_GET_GEOCODER, data: requestParam }, 'reverseGeocoder')) }; Utils.locationProcess(options, locationsuccess) }; geocoder(options) { var that = this; options = options || {}; Utils.polyfillParam(options); if (Utils.checkParamKeyEmpty(options, 'address')) { return } var requestParam = { address: options.address, output: 'json', key: that.key }; if (options.region) { requestParam.region = options.region } if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'geocoder') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_GET_GEOCODER, data: requestParam }, 'geocoder')) }; getCityList(options) { var that = this; options = options || {}; Utils.polyfillParam(options); var requestParam = { output: 'json', key: that.key }; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'getCityList') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_CITY_LIST, data: requestParam }, 'getCityList')) }; getDistrictByCityId(options) { var that = this; options = options || {}; Utils.polyfillParam(options); if (Utils.checkParamKeyEmpty(options, 'id')) { return } var requestParam = { id: options.id || '', output: 'json', key: that.key }; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'getDistrictByCityId') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_AREA_LIST, data: requestParam }, 'getDistrictByCityId')) }; calculateDistance(options) { var that = this; options = options || {}; Utils.polyfillParam(options); if (Utils.checkParamKeyEmpty(options, 'to')) { return } var requestParam = { mode: options.mode || 'walking', to: Utils.location2query(options.to), output: 'json', key: that.key }; if (options.from) { options.location = options.from } if (requestParam.mode == 'straight') { var locationsuccess = function (result) { var locationTo = Utils.getEndLocation(requestParam.to); var data = { message: "query ok", result: { elements: [] }, status: 0 }; for (var i = 0; i < locationTo.length; i++) { data.result.elements.push({ distance: Utils.getDistance(result.latitude, result.longitude, locationTo[i].lat, locationTo[i].lng), duration: 0, from: { lat: result.latitude, lng: result.longitude }, to: { lat: locationTo[i].lat, lng: locationTo[i].lng } }) } var calculateResult = data.result.elements; var distanceResult = []; for (var i = 0; i < calculateResult.length; i++) { distanceResult.push(calculateResult[i].distance) } return options.success(data, { calculateResult: calculateResult, distanceResult: distanceResult }) }; Utils.locationProcess(options, locationsuccess) } else { var locationsuccess = function (result) { requestParam.from = result.latitude + ',' + result.longitude; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'calculateDistance') } wx.request(Utils.buildWxRequestConfig(options, { url: URL_DISTANCE, data: requestParam }, 'calculateDistance')) }; Utils.locationProcess(options, locationsuccess) } }; direction(options) { var that = this; options = options || {}; Utils.polyfillParam(options); if (Utils.checkParamKeyEmpty(options, 'to')) { return } var requestParam = { output: 'json', key: that.key }; if (typeof options.to == 'string') { requestParam.to = options.to } else { requestParam.to = options.to.latitude + ',' + options.to.longitude } var SET_URL_DIRECTION = null; options.mode = options.mode || MODE.driving; SET_URL_DIRECTION = URL_DIRECTION + options.mode; if (options.from) { options.location = options.from } if (options.mode == MODE.driving) { if (options.from_poi) { requestParam.from_poi = options.from_poi } if (options.heading) { requestParam.heading = options.heading } if (options.speed) { requestParam.speed = options.speed } if (options.accuracy) { requestParam.accuracy = options.accuracy } if (options.road_type) { requestParam.road_type = options.road_type } if (options.to_poi) { requestParam.to_poi = options.to_poi } if (options.from_track) { requestParam.from_track = options.from_track } if (options.waypoints) { requestParam.waypoints = options.waypoints } if (options.policy) { requestParam.policy = options.policy } if (options.plate_number) { requestParam.plate_number = options.plate_number } } if (options.mode == MODE.transit) { if (options.departure_time) { requestParam.departure_time = options.departure_time } if (options.policy) { requestParam.policy = options.policy } } var locationsuccess = function (result) { requestParam.from = result.latitude + ',' + result.longitude; if (options.sig) { requestParam.sig = Utils.getSig(requestParam, options.sig, 'direction', options.mode) } wx.request(Utils.buildWxRequestConfig(options, { url: SET_URL_DIRECTION, data: requestParam }, 'direction')) }; Utils.locationProcess(options, locationsuccess) } }; module.exports = QQMapWX;
\ No newline at end of file
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..6d9045e
--- /dev/null
+++ b/main.js
@@ -0,0 +1,40 @@
+import App from './App'
+import uView from '@/uni_modules/uview-ui'
+Vue.use(uView)
+
+// #ifndef VUE3
+import Vue from 'vue'
+import './uni.promisify.adaptor'
+Vue.config.productionTip = false
+
+Vue.prototype.$toast = (title, back = false) => {
+ uni.showToast({
+ icon: 'none',
+ title
+ })
+ if (back) {
+ setTimeout(() => {
+ uni.navigateBack()
+ }, 1500)
+ }
+}
+Vue.prototype.$jump = (url) => {
+ uni.navigateTo({url})
+}
+
+App.mpType = 'app'
+const app = new Vue({
+ ...App
+})
+app.$mount()
+// #endif
+
+// #ifdef VUE3
+import { createSSRApp } from 'vue'
+export function createApp() {
+ const app = createSSRApp(App)
+ return {
+ app
+ }
+}
+// #endif
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..9dd0055
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,72 @@
+{
+ "name" : "guoxue",
+ "appid" : "__UNI__DFFC3F0",
+ "description" : "",
+ "versionName" : "1.0.0",
+ "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" : [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ ]
+ },
+ /* ios打包配置 */
+ "ios" : {},
+ /* SDK配置 */
+ "sdkConfigs" : {}
+ }
+ },
+ /* 快应用特有相关 */
+ "quickapp" : {},
+ /* 小程序特有相关 */
+ "mp-weixin" : {
+ "appid" : "wx79d17ac6147366fd",
+ "setting" : {
+ "urlCheck" : false
+ },
+ "usingComponents" : true
+ },
+ "mp-alipay" : {
+ "usingComponents" : true
+ },
+ "mp-baidu" : {
+ "usingComponents" : true
+ },
+ "mp-toutiao" : {
+ "usingComponents" : true
+ },
+ "uniStatistics" : {
+ "enable" : false
+ },
+ "vueVersion" : "2"
+}
diff --git a/pages.json b/pages.json
new file mode 100644
index 0000000..218aaf1
--- /dev/null
+++ b/pages.json
@@ -0,0 +1,150 @@
+{
+ "pages": [
+ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+ {
+ "path": "pages/index/index",
+ "style": {
+ "navigationBarTitleText": "发现",
+ "backgroundColor": "#f5f5f5",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/index/detail",
+ "style": {
+ "navigationBarTitleText": "详情",
+ "navigationStyle": "custom",
+ "disableScroll": true,
+ "backgroundColor": "#f5f5f5"
+ }
+ },
+ {
+ "path": "pages/msg/index",
+ "style": {
+ "navigationBarTitleText": "消息",
+ "navigationStyle": "custom",
+ "backgroundColor": "#f5f5f5"
+ }
+ },
+ {
+ "path": "pages/ai/index",
+ "style": {
+ "navigationBarTitleText": "AI",
+ "navigationBarBackgroundColor": "#ffffff",
+ "navigationBarTextStyle": "black",
+ "backgroundColor": "#f5f5f5",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/user/index",
+ "style": {
+ "navigationBarTitleText": "我的",
+ "navigationBarBackgroundColor": "#667eea",
+ "navigationBarTextStyle": "white",
+ "backgroundColor": "#f5f5f5",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/user/feedback",
+ "style": {
+ "navigationBarTitleText": "意见反馈",
+ "navigationBarTextStyle": "black",
+ "backgroundColor": "#f5f5f5",
+ "navigationBarBackgroundColor": "#f5f5f5",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/user/setting",
+ "style": {
+ "navigationBarTitleText": "设置",
+ "navigationBarTextStyle": "white",
+ "navigationBarBackgroundColor": "#667eea",
+ "backgroundColor": "#f5f5f5",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/user/collect",
+ "style": {
+ "navigationBarTitleText": "我的收藏",
+ "navigationBarBackgroundColor": "#f5f5f5",
+ "backgroundColor": "#f5f5f5",
+ "navigationBarTextStyle": "black",
+ "enablePullDownRefresh": true
+ }
+ },
+ {
+ "path": "pages/user/profile",
+ "style": {
+ "navigationBarTitleText": "我的资料",
+ "navigationBarBackgroundColor": "#f5f5f5",
+ "backgroundColor": "#f5f5f5",
+ "navigationBarTextStyle": "black",
+ "enablePullDownRefresh": true
+ }
+ },
+ {
+ "path": "pages/user/coin",
+ "style": {
+ "navigationBarTitleText": "金币中心",
+ "navigationBarTextStyle": "black",
+ "navigationBarBackgroundColor": "#f5f5f5",
+ "backgroundColor": "#f5f5f5",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/chat/index",
+ "style": {
+ "navigationBarTitleText": "我是玄衡",
+ "backgroundColor": "#f5f5f5",
+ "navigationBarBackgroundColor": "#f7f7fb",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/chat/select",
+ "style": {
+ "navigationBarTitleText": "选择对话",
+ "navigationStyle": "custom",
+ "backgroundColor": "#f5f5f5"
+ }
+ }
+ ],
+ "tabBar": {
+ "color": "#999999",
+ "selectedColor": "#3C4DA5",
+ "backgroundColor": "#ffffff",
+ "borderStyle": "black",
+ "list": [
+ {
+ "pagePath": "pages/index/index",
+ "text": "发现",
+ "iconPath": "static/home.png",
+ "selectedIconPath": "static/home-active.png"
+ },
+ {
+ "pagePath": "pages/msg/index",
+ "text": "消息",
+ "iconPath": "static/msg.png",
+ "selectedIconPath": "static/msg-active.png"
+ },
+ {
+ "pagePath": "pages/user/index",
+ "text": "我的",
+ "iconPath": "static/user.png",
+ "selectedIconPath": "static/user-active.png"
+ }
+ ]
+ },
+ "globalStyle": {
+ "navigationBarTextStyle": "black",
+ "navigationBarTitleText": "uni-app",
+ "navigationBarBackgroundColor": "#F8F8F8",
+ "backgroundColor": "#F8F8F8"
+ },
+ "uniIdRouter": {}
+}
diff --git a/pages/ai/index.vue b/pages/ai/index.vue
new file mode 100644
index 0000000..01d111e
--- /dev/null
+++ b/pages/ai/index.vue
@@ -0,0 +1,265 @@
+
+
+
+
+ 该内容由人工智能生成
+
+
+
+
+
+
+
+
+
+
+ {{
+ item.content
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/chat/index.vue b/pages/chat/index.vue
new file mode 100644
index 0000000..33112c0
--- /dev/null
+++ b/pages/chat/index.vue
@@ -0,0 +1,1012 @@
+
+
+
+
+
+
+
+
+
+
+
+ 该内容由人工智能生成
+
+
+
+ {{ mentor.roleName }}
+
+
+
+ 简介: {{ mentor.roleDesc }}
+
+
+
+
+ {{ article.title }}
+ {{ article.source }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ msg.voice }}"
+
+
+ 本回答由AI生成,仅供参考,请仔细甄别
+
+
+
+
+
+
+
+
+
+
+
+ {{ msg.content }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ recording ? '录音中...' : recordBtnText }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 分享可得金币{{ shareGetCoin }}个,是否立即分享?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/chat/select.vue b/pages/chat/select.vue
new file mode 100644
index 0000000..c8d937f
--- /dev/null
+++ b/pages/chat/select.vue
@@ -0,0 +1,579 @@
+
+
+
+
+
+
+
+ 我是玄衡
+ 知五行 破内卷 助你关键决策
+
+
+
+
+ {{
+ item
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ recording ? '录音中...' : recordBtnText }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/index/detail.vue b/pages/index/detail.vue
new file mode 100644
index 0000000..d93f872
--- /dev/null
+++ b/pages/index/detail.vue
@@ -0,0 +1,645 @@
+
+
+
+
+
+
+
+
+ {{ detailInfo.category }}
+ {{ detailInfo.title }}
+ {{ detailInfo.source }}
+
+
+
+
+
+ {{ dayjs(detailInfo.createTime).format('YYYY-MM-DD') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 评论
+
+
+
+ 收藏
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/index/index.vue b/pages/index/index.vue
new file mode 100644
index 0000000..ed46dd5
--- /dev/null
+++ b/pages/index/index.vue
@@ -0,0 +1,326 @@
+
+
+
+
+
+
+
+
+
+ {{ card.title }}
+ {{ card.source }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/msg/index.vue b/pages/msg/index.vue
new file mode 100644
index 0000000..a4058e0
--- /dev/null
+++ b/pages/msg/index.vue
@@ -0,0 +1,285 @@
+
+
+
+
+
+
+
+
+
+
+ {{ item.title ? `${item.title}·` : '' }}{{ item.role.roleName }}
+ {{ item.lastMessage.reply }}
+
+ {{ item.createTime.replace('T', ' ') }}
+
+
+
+
+
+
+
+
+
diff --git a/pages/user/coin.vue b/pages/user/coin.vue
new file mode 100644
index 0000000..5788d32
--- /dev/null
+++ b/pages/user/coin.vue
@@ -0,0 +1,542 @@
+
+
+
+
+
+
+
+
+ 金币购买
+
+
+ {{ todaySigned ? '今日已签到' : '签到领金币' }}
+
+
+
+ 金币数量
+
+
+ 最少购买 1 枚金币,步长 1,可自由增减。
+
+ 立即购买
+
+
+
+
+
+
+ 正在加载记录...
+ 暂无金币记录
+
+
+
+
+
+ {{ item.desc || item.title || '金币变动' }}
+
+
+
+
+
+
+ {{ formatTime(item.createTime || item.createdAt || item.updateTime) }}
+
+
+
+ {{ formatCoinChange(item) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/user/collect.vue b/pages/user/collect.vue
new file mode 100644
index 0000000..0b610b0
--- /dev/null
+++ b/pages/user/collect.vue
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+ {{ item.article.title }}
+ {{ item.article.source }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/user/feedback.vue b/pages/user/feedback.vue
new file mode 100644
index 0000000..f35f3b8
--- /dev/null
+++ b/pages/user/feedback.vue
@@ -0,0 +1,259 @@
+
+
+
+
+
+
+
+
+ {{ group.title }}
+
+
+
+
+ {{ option.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/user/index.vue b/pages/user/index.vue
new file mode 100644
index 0000000..a7a9ccb
--- /dev/null
+++ b/pages/user/index.vue
@@ -0,0 +1,490 @@
+
+
+
+
+
+
+
+
+
+
+ {{ user.nickname }}
+
+
+
+
+
+
+
+
+
+
+ {{ stat.value }}
+ {{ stat.label }}
+
+
+
+
+
+
+ 剩余金币:
+ {{ user.coin }}
+
+ ,赠送金币:
+ {{ user.sendCoin }}
+
+
+
+ 立即续费
+
+
+
+
+
+
+ 退出
+
+
+
+
+
+
+ 账户余额
+ ¥{{ user.balance.toFixed(2) }}
+
+
+ 充值金额
+
+
+
+ 支付方式
+
+
+ 微信支付
+
+ 购买协议
+
+
+
+ 充值说明
+ 1. 账户充值仅限微信在线方式支付,充值金额实时到账;
+ 2. 账户充值套餐赠送的金额即时到账;
+ 3. 账户余额有效期:自充值日起至用完即止;
+ 4. 若有其它疑问,可拨打客服电话400-000-1234。
+
+
+
+
+
+
+
+
+ 关闭
+
+
+
+
+
+
+
+
diff --git a/pages/user/profile.vue b/pages/user/profile.vue
new file mode 100644
index 0000000..fdb5087
--- /dev/null
+++ b/pages/user/profile.vue
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存修改
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/user/setting.vue b/pages/user/setting.vue
new file mode 100644
index 0000000..ad86a96
--- /dev/null
+++ b/pages/user/setting.vue
@@ -0,0 +1,679 @@
+
+
+
+
+
+
+
+ 请完善您的信息
+
+
+ {{ item.label }}
+
+
+
+
+ {{ displayValue(item.key, item.placeholder) }}
+
+
+
+
+
+
+
+
+
+
+
+ 我们会根据你的选择,提供更精准的推荐
+ 您还可以选择其他人物进行聊天
+
+
+
+ {{ mentor.roleName }}
+
+
+
+
+
+
+ 简介:{{ currentMentorItem.roleDesc }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/static/home-active.png b/static/home-active.png
new file mode 100644
index 0000000000000000000000000000000000000000..18c09f7c2eccd3bda8d2a1783e15754e5e5e02f8
GIT binary patch
literal 23517
zcmYhjcRZZk^FGdIu|!#fh~9$ey_eOZmxN`Bu)63ZdR;xyiQYn@w~gp^5z$5TULw(n
z5j;YHZaJ(hYS3U1@eLD5`g{5
zVaSU(hABm?{|!SXV1Wjay8QSc35YK4KabV21Y_)bb2FK4MF7Jf>R2cbF|^}`fEeX;ezN~2*8xKjxdq{s&|nxb=q)xN>76*BjN51Zf29V)
zT!0~M%F>Y?|9pL`4@MCLsfhHRf&6dc;Nbh9)LkW{(Hq?QTSaaafC3Y7DN(tBfIt70
z{DV0dGoYO0{?C&C5rYC$#0m+5_Q?ke{`)DghQfP@{~H2(4Eh2#c>I-v;6H^S!hjfi
zaIXD7%f^smYldSK0CmDKGj#tqMj9}U@8hVw|C<~3jtdx5)fM~cKci1D24l+PB~u``SXnCkILDdoQlM>PW4#aj%D
z{%-}qY-nH`9B_n*|DCy(6}ET^h}rFh-2KmOTpwehesUwz?_xuKFv1?(+Gl_ahD`aX
zvGt#=UI9y-G#`E0sQJ&=x4W~z9*k-J8o~45kaK3_7h`a0hAtBFpT183?<-Iule-=M
zKglpkKwoaEN8tb4sBB=2Hn%s=OTa{vZl?m&y!VrYr>O2hI^V9>`u
zhkH9N&HjI`j~j{y8~(a5Y;fxgj9reT31yYt$yWeE;npKm^1tXq5KON3v^Y(cAce^s
z)SkZrO}VdD2j2~%gXE;2M`XzT_t+9aV<8SXdk|)x1%E<(2VhS%fd)99Ldq6GfIX*wB*}%a2;u%6z447jZ7g!Y$M@0yX53Eo7
z;itONa|j0owF>Fv-3-4#(|-nUb70=C)kd8+8xrg=VWG}}{XevfiG-?xlM<4muV3ts
zH?+M8tz|4Adp{iX&q(UxSK
zRn)b^(QH*h@vRQbe5HV)1DvrX!Tf*-v{?cPvaRzU{
z;G78cAP^W$fEq8=J~Dt~psE(?yj?C4m%lA?z$v7P0+viD#iAW!*VnG52xtqC-Ebi>
zpuu3K^nZLRK?y#f9Uv!j%J}+G6UVY#3{Mrlsv}%@&|M~NuT9)jgz8`6f2VSWy^{pexW^B3&fTd*H3U;xvlA#lyvm5ji0$KKNKkUgSTs==r|UbnJyDcUzOuoNDD#vtGqRf!oEj^R41WSjMl0w)AcERVK4esI
z@b{H|S+^ZhEE*3;pno4R+=IXQ{L+Pi#H?cI!^!v7QVb<(W6ES?(zjjC5B5$Dh`Vcx
zxLz-a=4_cTVTso^q+IF)f(Ru9a6}mWT&4B{MT>INbS;)9qzcg8$5t$IIhO$l|XTxC*
zMiboAH2J6j3s2?dtay=i8~6j8XTUI}wU2*nm^q5yurXAG-sBl;gS1fU(QLN_K~|JmsC8RXl*bo^85S
zJOI5o+TCCLii!-)e2pIgLy}^LO);CCdVVQz0F33p-0G#gl3tfIGMlnW1?02^HpUIX
z2bJ@7h@EI4Tn$^%r?3@{iaukysDrOk*t;Ff?-Vo`_71L=e^u8XP=ao)WfF$Z@)iH!
z_sL7@R$vAYb4^ik7v3q^bO_*`I7E(04X<)ji0Kw`Z7IH4`iEeF$*@U{efJ$05|)nf
zK*WFqT5zcsd3-l&tp9Wbbi*_%g1vPIYW%zb%W#ANCzY#Qpq>V_6_?^;fLd$wdk`Tt
z=zQ*w{%Jux2ozqnfs83)Yoc%}CoaW{+MeSF0mbJ`(G
zXgjzQ|FvcOXsdfCUTRP-ucLj$XrC@`DsTG4$E$X2K{g=gbNU>;j4bcp7N^=b74gfb
zkji;)#C$Fms62oWy%K}rsA#{LcwK2*?(-rd_)S80LDvt)Y}5FHEymQ5@NXSK?X9^y
zJkKTO+??~;wJkKA7;ucpEVh?x88OBYdv1%Iwb$pTCx_aO;jjR}`j;tYV
zbdod%)snw+qn?twBlOd0!^X=v2^rporC*Bi*n)N|&joi?`HD*Wn6oA|Y8TI6W8BHh
z8YAdG8H}lYIT@?5#S`#IjD5pbF!lIH<#}`BiTZ=;IuX|ed(c?q2b#J`99Ks05h)BQ
zW7|)Uga2V9p#m=7HLWZM)sz49WE!mA)&VtrwC0h1>_Kb84Hx=p3e`Gsi+LR^7Iv*;B%GE!jGjEkMmMk^H2WTI&K_}2m-0_=O(x=
zwgTRd*;al=`Cy-hJ(s0Keauwv^e{P5FLj5baq8_Cfq4Ag<>Q5l-mn?tIKaHL&(z!H
z83Tr67mSu>K9@~`AIldeSDTG1KT}GvDlxb}{S8HFB7Ibn~Pd*(3bC-GzSv6t#par}eQU{l!*c3(#J~mTM;uX&|uuyfW
zw7t)vx^5zY@;34wHd&XlC!_Q2{VOwh-s#&t&$v)Z5P=uR>QBU&3
zH`PeJLP4>VKIIo=2GXXhFD7O>*-%gH0xlB-jaydvvJ6CP)IS*w4cdd3UFsm*9Use`
zeaH;QzUf!bIEF*GKIM0!C&5XhNrbyx-H~a8g}*ccR(={U$*=GN3HrIPfmrQFuHl9x
z;v%iRDSKsvQ8eWAEmOj0N`)P;;U!FI3LmeU9ypC<*2n)E$p92-YkH~3^$!dUnh?AF$dNyxSEk%fTeSG2ID0fH<@_@YJ
zsr^8r74U*?V!|RDaCz@w`}8#WZbmxA*yh~{H>d$2-W)!DY8Y@naV`JhRGmeyBn1!+j>+d>OA)-;*#|pbNN?u#ekSQUk8q6?T?LOF$2A0
z&(;3EE?1l?>t2O<#gd0Al5XnRG1VxDe5V*;L>s`OT~)olzo~$S*+i3!01>?HFau5e
z+1l?c$bb^LYgUnSNoLq`pRPca&aZ<1I}zA~Z1m-mul<2xl+1(Hio-}@5Z4_gKIKir
zY$z6e^`LEsIU)_
z2Ky;+s<#$W^Eiq9IpOSjqqh5aEz}4q4kYfAxp77HLK5wO!_J`V9=2f28@lCWFL#T)
zC2(Nf&569!9)|wAu_@@SO)yN-_UD(r;732THVgT9b;kUOAl%1HbIvQ`8}@z@^%~+s
zb>F|;t?v%=04hwFvH{<0h3w@IDb&852#CuY-AnFcwl85wdETG%tDF$um>-7*D9N1w
z{d@AVdOn{yRetXM2H|FKGq$$&ck@W^8+lo2P)9->5)22aS@pZ#@b^i`D*ctWN{Msa
zIU+?=vgnpvAAH|VsIy@9%g0sv2({CMecgMTk@~Xj<0G7M6)TFc`Bpoy!7=oQ7-MT=
zlGOaG$SelBhrp#-1tebS~)oyt&dz3t{c%XNg67quI
zR2T+iE6y+}_FEOUOUX&8JE{N`d0fD0W^&^kiCN8k$9z~*Xn==k;vz`YF&M@QDkVv1
zXH3#jG5hdKJK)?6hp!cgSD*Nm&g)ke1Ngq)G&^~(N__EX1|PKoci$sAwhX!KBn4pyUo9Mxt8pE*P
zKTCBQY#&haum)p{AwzTfTS{-q$1xOTgy}KJ{yHXKS(V#h0
zeZeEcXMMBOn*WJNTGQs{>}%R=B%0+G)Zha3`WWTsrqu;897SAmdXg?PqqCJowEP!T
ze5Zgsm?I)T6dvpYTBFr&auagdGP$E{RY}TUoBqN5>4lLy5pv9L9Ku~ji>iYdX620IKV&z^n!7u}NoTr!PH;~v@fHgh
z!T-?y_%i$0qsr{KUqNhD5$OYgf6z%(RY{X
z&f=gQiT6c*AM!hy`q**Lq$BcQSQfZLUTHF>_RRr;@SHBxkrL=e7V_lAH-f??-{17|
zznbuMqX3;kSQ8%xB+3j
zE(8}#G-u4{YMKINW~=mZ3LCq2dlz*oE1l8yD0L=m^4~?ss$CWxdpMg3Z7n)(LJ_!%
zIQaH4m?Jbzt+B^YFx#n
z=_@y8cMU>KN`v2HGp#>Y!%LAY`}Xkq7Bq8JWITC37TF|lo|`|^+pJP_>3e%Cb>X5N
zZysS_D8?33ax;=cc_{GMt+*IkKY_YO1
z0EHP1fo&gu_~r1#D^)ThJ_ToOOaY3}c8mos}&W7|$taC6huBpeGI0;RfY
zUyRoAqT+NU6$2YMZ39*99_R4{`}ghMViKQ$f_t|p*fnHxI+)0`qd~VyhLD079^`np
zqKsp}P}HV+U|O#r;-lrGCxX`h?2!`Y_>59eA5oXjgyvk;{;s~y$O%ttp#JqWv|l51
z3@~3D{)b+%-JpPj*TMN+nQn^6$$~w&$zDXq)5xdMVd&$`;VLaakwGQrKF*hfQPln$FPBG?5~>he~0tnfY|g#kVdsGNTt
zsITMlT}3XU)8be>7%w!6lx`Qo1c?dw(5pi^pu74jsDp$Q+^x-sR>vz&XykM{opF0x
z6@GN<5$A0DfmnU{eRFMV4zCErWWWaUm`8qa^dAdlq0%-gV}b}QFo?|cvcF4Vx+ECe
zbb}1!K-W;LQW&u#;8&;^dUJhoG$HT#4|c
z9h_Cy7k?(xz9H_SkYLx|hbZAng-czpFG8zrh(0I+XS8S+j&dKQY+7@09RL-*0>FK7
z6l=|b%vQk7(uT-jprrybB`UFdcT)VxCveQR^;4!>|Fi*{oE8#S8x4b6-&ugCK!}%~
z9zN_V0+llCRJ(ToSo0kYb|k~S%e^%(S$KL=Wh(_DgKM+2QP^m7J|{S;T%dAM@52EF
zkl|nwAX)adL0zV=Uk2tlpa==KcE63?PN$)kfd_#Dz(s$6>_Gq0du@C70-@>sb?)<$
zHBaSQ*VyR0hTW8L+lE&QL#_ajexQVT&Y(fbWqYiE{8_N2WwJHO__bw#B7prTk`2tL
zn;bltuTX=S&4d7T)4x)^hvCQV0mTnHJoUuh4Jt_b_&Y$;Pe*Qh@{g
zwZF~nCz5;M)n4O?vJpfK-0sjt>d{gRjCEo!-@YZyrgMz%i?KStccLe;YpKjN^
z&$2%w^nUj}&C%7M?y5}@q@og17dmVFxN=R|B(bdwC(D-+nTMfyk^-JoZ>i&ZYfbiy
zO9S68z2gEQsIThjuIHzObi!=xITN|nG0o6YXTemKtSR7UjZC%9Ne`}&D)G*Y(H=r^
zFAbT|>q*UXe6P8-l&TEo1Gr|nTE3V+01T9bQPU5&$%weAw<=4e;ta6b=1QX_4=^*l
zeYCDnf*D;udhA{iRem^9n%;Sj5F0|plAx4Ac(~bG1^{vr@Dw6=qDT6Bc#}=?WMO_6
ziaWJ`#Y&U_RR^+bW=Ynz?8(<6mNyaU)GmbDDKO%5{WWb`Y-ye?vt3fp%eWk|z4AaW
zP8Soj*?yc8;Q$**oqE`(?!t54l;D7%cFIWL!rS@hZKb{SaHub-5xaQqrOmoU&iDEi
z3XlUf_oB!mN{v0gdYI20l-wrB@Q^SJ!wITWn&e!gr(^wVyRE{oH{MzQ(d87d7o~$%
zvJ$c~fBi@LA=uM`+Xl!gI{2(l3Q5khBd{E_41(-uyXc@sEc`m;OZ^tH0?!Waqw25>
zns<`o%sZL(JX3bzEd!+&O2LNE8Er=Vay9)z*^*AHlRamXRK~y(vox+N-!!(?maX!B
z3m&H&NJZi2>|LGH0kwDhAp5b(|?H
zyPX@WYGak)OD1R@?0&&Eb4(INBGcDsxJ0_V8aGVs#0he%0A9
z*enhx7T+!}DfNXZJhOrxX*#K1HDK{G-;J0hnu0wQPX~&?gOc2|`E9T~qS^s>9U1OLg?G1E7
zhS>ODmyIS*+Kx9iu)Oqp8Z131ZUtj}Hu(aotPC3n2NWhE-=`b=lfQ9ZzxU4ZoA~7bo(i2wZu7;8)B>^$b3)jpu#wDSg4?PZ(%{dNR4(FZuc%~vK+(il
zV+d%6^nAidcCHg6s>UAgC5`LY35L8%9_33+P}nw~)u_n?TgO>fJ>A81t~kV*+o<4(;rwC5WHF6}#?E&P>F?SEjF)4`G_>QX^%KF!&NlaB}&PE|09
zl+peBE^`#19m3b17+V*oc2+-YAzp-a5{%4XytVAr@nCuf6Mujq3
zMKqgPv|RxiOS^vU)Xwm-Ix`aMP7FDqH-cDUfzz(ok)rhz)sFuf`3om^L;)
zYi`DL%W$9>q0TBgcepb>_=T*C{#rWPy3<4O^TrbxlFqJ?ie7qVKo01YP-z#ui41=H
zg5-Tv)ORgxIa;fazgxLing*Fk5qdL2a`N71T?Z@oxUbLDVN$j)%RHM0(j{^RzDV~Ga(CDXx&Wc$?Wa#GKFx*b_Jdn+zj!4
z7#WVh?LGn={^!rFBH_zM>wH1E0&~ZjE5YX3(|uE^y-cv3
z?i1Vx7EjH<(kA4;Tlcv*UE20ck!{KrjznIbUqB%eO%OXg|9kL9(L>K&c1nos$bR2UiCB-s+w!)^ev#vcD%ozuUI`=x(X+MeG?{(&VGsA@L1%x42r;e11$$OV
z{wW^BSW+zXR2OwxZHbN6=k{#>$w1J9ry{1#e&|NvSxzOAs
zBuS!X)0q-w94NAavXahw&RJN0O;XQem?zyS%a_f&cyUrMRy(B51I8;Z5e8?xz{
z@b(}A%ji-}b*h>_w`VNSs_kW9{O(hv5y|wQxZY;=nT?cS&nQW7x-52jP21n4@XI&(
zR)V)ZgJy(i_AY#CGsdW*LV2C1VqAy(^bvXthsEWp-+-DR8WJwm3svA$
zQ{-;=iq*ID?=o#06kvDgs5XyvWsI5k%k%9HLQ(@j-Hqev!hnzyS!dmEn{ui)GF0=?
zwM?HVPpxNUP?Ps@?kG|j
zx}tbw%R3~;h-gvGNyfU8np%ER3=&hI&H(cLMIJ0hoY}_N6L7jjY+upr^yS|12xL-XgPu1iMu)6FCebj6|$ySmfj7Y
z@3J-U<=45H4H{L%Mc`kNA|e=CReC>t6k0uy2hdxBx(Vor(&ULEOe5okG2(9g(?C65
za17a|3ex(@uKAm)g+T*Y`+M0l@MGHhq=|y?6ZZ0X2Kt2?TUOQQ=>j%tg)*7H>+^a=
zUNNCHy<`bVGIv3(R4H?!0NN9w!D|t#G#Ne~A@tjx-N?64*F2v<4-8=5MNyW7U_nyV
z?*qTlx@;=L6f6bmE-^`H>J50EnA=Tz8<7{cu7Q{6$7V+Cb#sa^sp?HxaO!G{)c)?e
zi2i9aYj9)pkHoFTWD6yPR)KwwA}sG-yYEZ;yXEogm=f?8^RAMmi-U3!l(ok-g_o!7
z2$`ipk%XaD6{oT_8T@1eKI}Q_{cMHJ-IMk1F2`O2taLtFINNP;f8k@;0f_5)Ox*ra
z0S7h#pEhHi?YarYI`{p;x21yIWyIj8e&Vg77x7tr_2vT7ns)7bHc=+tD3Mk_TTf?@
zm*)dxR~Kc*DgtF7br#ZtjQch_-ERzrYzgAz-yPL8;naHZa8?=@uU;6!C3G|VKwC@&
z`)%kSn0;$1E4A4&x0>b_A1;7sfjo}{rs#Yy|Ecz{-e#eyE!5$qKdR?X`Fw0vT@@sT
zJmV_8L06XFy)#1zUKtro>1yvtjziFH^y5tmAxTy6)Hu`O)u&NVd8EKnu6D0!fY$w|
zYZ(MrA2XCv{`$aAjYet@rmNF3{A!-5frh#{)y~Xk^KnvtUI1M=hWbHQ8Zn951{uQI
z{)PfPy!-Gk^F89yaAC|n*-$LEbnMbm-j6s2Om_3pDRDu5Om9cAQE%I}F<82bu~M
z^~RwqKo9Z<*Sxmc`h55o3^6bFx26cnN8p?9w(KAW>%keCw&Uf)HWMzExk>XaX8Ss#
ztmrTZPy|2lg_KBWrVuhKn&Asirn5nxAu}GwyFtAbu-s0-qd@VKZD`%(^gFf9cT8Q&
zQB;bA>s09s4H`TGd+qOQzLF@4Rh{J;r>qyOvV7tJ)1DU(UNM7!QmZGQVMkIRQrR0_
zh^TwLU>NrZX1?nOg|P(#i;6H??|S?DYhOveFBCFq=;i3*MuqZlmfG94@~E@WVsq{Q1l0Us?jXyE%Wm{1qLk%f-vxq&Gx9=oox9
zPq|Fn`^FpGJYt&jnzNS#n`eqc>fATcV%L{%W>>nR5%ro2T_M|<6Zxx0CQHzJ%J$Tr
z3{IzQU^ZtH6YUa#mxe2RdVSm~l%1Hffmv)*AgBO6qM=&1d$Sz)^9$d*3oPcc
z)EZ&F_6PJP)MI5=&)QEB?KUp>PgPOYULh?e`t?fDmWt&3LD-9$W^)~;VPDtbPP~Gz
zut&04q<%3X-H9d9f^S|6;G|A&9t1xrPyA?ZIJ2AbYCE~)JJY+J`OL#pa|y*7dPx-n
zCg>|?CQ!NhPJR+4SbFjSpP$HU;K2Q97r8zkX~XtXT>XJHJ|bt6{gmpV@-NDM
zAaXp8d(TCR_9J?8q1NRJ;@U1I<;)4v9}f<`Sk24Q{81n|Tn^|bhX2#}MSDPP`m@Zt
z&S^jUnjA)dMNRL!0;Iu~2U-?!U45ty7kuxmAXm1ECCTp0U2seTNd(>}m26NbG>RP^
z5=hOY>en5c1uiS@bum8lFI>1NYfOrnJPw#;VZiR*3#IAxH?M*xO~zPa9K57a@bbi`
zBw#@(zucdfzunG`1`MZZUrhL}76(i)E68NwADEX9LpCU(I><@Y;;)5%?F_M(*|^p0
zpdxlYhM2e9;cv>jrLHGgk*xvz(uhw2;OfEcI=?%o-XMoNF-ehge}6w#tA2Dvip`KL
z`S9h**Ny7y9$HLNM}gQ$|mcInEQ2qdo{G+>gQYj
zW0AW(ITqbe$V2o{(L`mSJ&UH$=|)s!|DXwMzK-j7Pw}&tl;i|$O7N`1x%x^zcnYQ-
zU@g?=MfDJe348aUNO!2#v%7om
zA6;K_Zp`URuR|)nN0nlM@IaliA^rz%f|?+svhIl$ro<
zK6=wa5rw4VQ5xh$e`vvW#S$D}ctTG}#p=BcVqmnW$-_V47L}nP$E0Z4KgYlF_%5;w
zKlFf4yVH7l^`(RH^bEqZ;O3Ceq=?6g3cXgs{1n3$=f%v9k??P_w75jc8)S%fvv*eb
zAP1jw2@ohB!rvsLFaAkN@v1LwLJ76-CynF|s9f68elsU{Yn35)eWBGy)}CQF_I-db
ziM$IgRnW|Sk}Dt{6;i_*yz7t^{C73)Z%{q{m-@In@yna@{J`XXb+N}+bT^+NK)@WU1~F@(uF=H>6OO-RIt<&hwHpaX4sXtQlt|UBF~tBDZ6@+ZS-yVFecw9J7mu)@JR612WSBw2;`JwM;=jI9~cLY
zICk#9Kn|$sT>?}t{-4W}u}@d$*I`(DYxs=ESpuUFK&eC+@-ZXmYBl<~izlByp3&Oo
zs4O*J@HUffBwzz#Tl=jrzIf4$MU}_-gt1{N-H`e2_
ze|n)LyMW5Gua)ml+Tz5;??AXSjaN02-$slhusG
zTWe<2omK-IJYSli%)kVm$qnuc{23RQyxog;zL1HB07rN*Yc7P0s^jwW!SORHddIn=
zg4*~ZXeljd1VAjZaR^_=lC6~M#Nd93GO8tEL173X6D&|w
zgXYtm5b=;aqwQ6nIms;p`UD>cGimPXz@4q8$K%Oqk*L+qFR{s|-^8)>Z(^{-ZoWdC
zmg!ZHPPX#+O!z;%2K;+JA0V&a@o^-ce#D||QCP`@-A4M3WMgY2MhNt4sV%7f?z|Km
z>}pf|JkF#zhmvHf#a09zz=BPE_&6As#P+-wsY{rlbj5#5|W5Ig??0BhJC9D-lr{?7TW^vjghVu`Q6gBSgwE3<~O-zNst=Tx|k
z40h_go!+Fd$|H@Ou4b&`gMY3vur)Ne@YTkj3SdI+U|$;nYSLD%*7Xfgpb%u=3O1R8FUn5s|aNR%ePnl*T;rDQ4R2JaKu!E%Y
z4nG&Hlp{cc+bRh!hH$c6FA92FWTKBLh}(svy|KQn=Uwbl?7i3OemAv`|CtP7(EURC
zDv{wCnvArs6O=hiw>DcowDgn~JV1)hWHs7y<3RNY1sl|Zi2XD%=QwXy^LkggnkM~E
z)w7EOAmBhge5$ssYImXz)+fK8bD-dF?}dA*VgB3>wAm9RqNBOLd}r^y(bYQ(2>2d?
zGVi^)_cieb(1YrHx?L6W@hZq{Xg;eWAl>W1oee13TdT%TB;!VJypJik8-ytgy8+5c
z=j%pl+__#%JRiuQdXa|X3ps)Y>B<3S1L70!>_)5psDl=p!r+lZ%4c|!Z%rDlYvV(y
z_q#Zfk4AsTz9)|m8YW~%?`m)V7O3F=wD@^>*!xT3YM#3m05aba<;e`LN1o5AG@Z)#
zTSI2rJgd*dvN6<8W;Ej+dS&K%&91RTvj8}@#!p0@
z)}G%f+4a{&!84dA!PI$lRFo%O7&`U>hCkX5#?IxCp)bwL--+Se7R(oT
z$_$#Dzrz~r>JKFd2yYx6guf|M>{&j$TCs!tV20`;asCJ^R0ZpeSb}^H16ozqD&>Fu
zR@a+sw6}Ts37#(muZi4>+Tu;3$s-L?|2RVqujp6Mtr&Xbj#K_Q@3d@@Y)sgJx
zg(SF>67WYt53Xog{U#kW@^%`&oiYeNA_IV^YvB;j^Org}rw%a2=V3GxQlHd$-+h(e
zk|@e3gB_RUN>%zLv^^!@_JVBsxY_C*Po`GSK3fU9hhTwb<+0K_tyL?7B*Uz}RlV0T
zfyHxFnQivG*LdQA3pxzI4NY^wPahuXZ8N~5M7YeSy%y1YRm~8=A%d&*zMAOkZSUxT
zujwQ$Eb5oU+nHWw>~aS6K@4XVX6|O$?7_LNk`9m}NcK$&ioT@@e`GCNk_Jy~wkAD{
zb6QB-oqQZDL+jie6#XDr0>o9cG2A-WF&(Y+X}k2C4g0D)G$2SME>{SE)&${_=8MB#
zpe09VAH$@!fx+alZ8Au91_>9salYCwPWPD+NXCYP?aAb#)k(NkX>Yxo!sl`cF!wU-
zak~L#VaDybQcKDc+x&a_KecAq5&1LYD7u|`L7m
zL*#vAusX-5>&H&_jhLRyps=R1??jc|Slq4n&M|HH?ta>d%1bL=(E1v5msrQgq3Ded
zoaUJ;+Vf)~ZloL|Qc{t@JESFowH6~NbF1sz^&FoKL;Ezn7Vljsyh)XQ;8u-oOi0if
zzW9vAC3OzU%nl`TBp~@MKsc_W5+Asqu!7j10Km#IXsL~{>WGZUEOSqvT_l)Sbz)97GZ(M#e=nn5On8{p{`%EehtmtHRh-lJwUk>-aDBj!yAs+|6`nS7NlpS@r#%T<2g=}BP-)Hq}B
zY|6r5I6$iFxp@8yXixV(e%+2wMZce9oxH@|zhhFvSK|RRe(%@Rg)mY_d^i*V2-0W$rwVOC_Te#0y%RU;5
zsabRr&_wL%^DiC#pr_aDvd^p-QG}I?d{U-(G4f8cZ7z2tqQ;Cs4=H%`x4`)-|I{Nu7f2co#E~XMo#AH{?oF^wIq(hj7&x
z__#hDc!<46&O1Hh+fW<-$@;ImLo*q|vY5>)eo$gk!eWQtoQ~`HltrL>i;4F}$fWjf
zj;XkE)P1@nhzxZkUOv(=uowt!I+yQ!3TwK4@k(E}T&7mARD*%Y5lA>7v1YkUe
z(E^*;D?&VDLQTyqz?|iAKQk@ur#fgNPT0|!U%M^R4<6GDe;RP_6;kzF`x5$)6z-#7
z*6|j|d`kkfh`hjR5&NKT<-ZL6?rS4syTc5+nLGtFIiN?^bGL}Am`_E{2jZKpuGX^G
zZ_;j((U-rOg5=i1u{}jukpAB2h6}?v;%0Kh_HV`qp`E)V$1jE=ir$(FN{i!{Czlk^
zz3s|rSWweXtQ;6j8KWdeXBV3B_rChL96_?Fhs>a7qs48Tp>`I!)|@9X)1;{+!J4#&
z>1V`^e-kH#`*w;CRWd*G0Cz_}1`h$g<@VyaQyOT{KeCVCy#6>Oj-5uGU~K4&wd|HF
z;xDK08My1h;=4oN1Qub&p1`5gS5Hzi&`jRHb
zU9Na`X_)wu`<)re+CSYD=-gezSd@4Ob!p#)={FJhZ+uBAY?#Mtra+vIUk&xn`p;3_
z=nvc6a4@oxkfsU3hPID0M|U4rO=P9IgWIx>Rn$M4R}-E&!GD
z=X;m-&YT^*K)Pv+v~GIFL+#Gia=%AomF|DNIVl2Pf5TYYEkAnti7(T2n5S5w#H54~
zK|rI7SNw}qu7|eUgdixY%(``Eo*X4%bXj!$N>;jLmlQD-iSKj%p?+LB`XbIYQEaz0
zCOC?7Z>E?DL$iF?SRs8H5&Q(SphQhH)L*fWlls@Z%N)j^P0d}+=$aLL3z%B_K{od?
z0cy_FZ6nW@fqp`CtPS%N5_)3Z^>;t$j@&W6tF2gG%8m?>&09IA%|D<21XrB7Wh$HQ
z!y8$k2$845TJqz`Q#Vc!o}s5ax%`1__&4x~{aNldQZ
z%TqmkEjYXAXvbe6j4dH%eI5^_o^{O&UPwB_x0$w>Y5j5Ga;iv7CVz5Irt0~12SfY0
zC)SP%h`H?5rfJyZ&Z-go)f~%%>r)Nnkm-Y))cD2gjzE@ITN0ohOtkF{YZJWe>A<%M?xP!Mbqwgz(n6d^Rrc>
z;7$Lwr)8Km8wBxnRH*51K?Wmw#4VkH?Ve@71wQz!L)?}2T2cQS6(fHnMqFClR_FAi
z0`LkkNV?w6{pX{cb
z_a3~1iC>*OLXXh)T_XB9y-c?2}vU1;#%-SKUwBk+8M@%Vrak#(+U=@?`JJA_kB*!7bIplTXt*4`Fhxf_#1?
z-u5!HM^a*Rl`EIgM10fs_Ee#?(K>7+cTH|9SZrWGrT
zmMjOW_o<;6UjkEJX`QndZJ|~lfw!3I>L^6F&!BuXA0BgsP5;wojSB04+Nm;HS5r^P
zwb-{YWwpJ`lVV2a_AK^TdAW7<)5RlCkoA~=)0CN
z;>Nf4dbBHaTbmVPAKV3asY#7TNo_}=bxnnkiVP+yiWZa4Hv7x3#A*=T;@IPAtp;M0
zhkVv$^&{oRPFQ#VQ%M5iO={@ACV5&ZksW7-3vy74k+J^h?HKyLVlC-$REe=dbN~}F
z2R2}8Bt~{+002om7*D?Fx_42&Edz8|bS|eFwPN90cD0
z1|)KV+47jFrxQ;B$R+&qQv)Tr!n%V-(UxD!FF_jJ}?aB4*d;`b?Q^KW9jiCop
ztPBTLhufOfg!rDFMvlTG$j--B6sXHC837oTZ$Yyh75<3T-2hlKnt
zQ5|nHjfNSwxhJjH=dCm!#yJf77el=GLW%iwj?1q99$Vkrxg!U#gxG=Y0QmcoZVe7%
zqzJBVIa8{Wkfxg8xk!Q4zafnTmA=dxbN&A~sxqzj9n?O=o6OLiCG&D1L7wy1J&?m)
zOBW;V+*l7%r#rZS?daO?FZnmOez2K*(1Bo|tDw2ZJ*`<&QA||)Ao+PQ_rMy@V
zu7$bRwBe}>9~b9rmn4-YrL}h{P*}3uEI>~9-8mR%-*{Hkj?Q0kaejblnld=LuMPJMt}wsZBU6UGf2`wxrkgRKdKp8HHUn;mu;#fFuM4!w0mqs6LH6
zieDxIkQK2fWC~
zeQH)@n9~?+5Ye}(?5#Q*+u8p$7cW8b^}So-TsuCiTiw}7Y3E_)dR7b04#3#Bd%){>
zAga&7E`9uwm${GTmKAFRP^Aqn=PJTed1H3rqFs;*O%4y$7p^Hi)Db8ZF~UE$oZLRm
z75(f6S%c3Mv*mi{^#D7_>7jREYXf(xZ17tZv22xu>08cu4OCSzbgb9rQH23hM_}7T
zSy`kn6!GBwu3&T>L;D9|&&R~~a8O!caVpRVpxwiOaxO7pzaBi#ng~Kv3dIKhrpk%X
zeWP}9`bFJb0TE#4zt97=Dpo;4B7(4?4oJliOwY}oJ>k0H;!~Lc{UVxx22UPPuaR-3
zhR?%$xH;JQHxZ~DhWsLh9UyLv>WZf5e^2u!zYq!VUhjecV*7k6*Xtqg;iUULL04s1
zC^+ZRK3nTuh?+w@U0Cb-eSr3g1-2nq4JiJd|A_=$!!lcL0YJ+X3RwWd%&~Dyo`0)N
z_x(Er0Ip(IMFGp{U211d$)MG%o>*1WAIvu5qv}Xk-ghsGnz(#*_PGbHzg3Sz3$uk6
zzF_)Zy;n%@0x&S+FUn6hC#(CSpJ+~hJ=dP_A4sPA=bsxqOo+ferZg(9T|6+%d2?Bb
zgMy2n0wlqC@+ER|QX}aw;lx{(9Tw^t5Dyl12b9!P_$XzN#_5I^5q3QJ(xlFo_*1-s
zYNK0euoYFtlh`p8dP8yF&QW9z5+G%}Y8!D^Zy~l|W8e{j?2_Ams)11l!AUd%3Vz4J
zxrX5x(+*E~Z@7RXp$zQTYI$(#SaBzNu_domQKI!H!|l|-i}ZP$V?m^b|F4QOkB92}
z|2Wf>u}vc(Wtp)hOGL877+YdwH-@r?GL$7sWgF{QKGy6?Q%3eRYiP11dlFLiN`p`l
z$tT}4NbKd9udd^mNQr4DY&)L6a%NQYRI=3BXP0{?YzaQLV
z1yv1VfO#oMw!OQlY45D{s}VV(72f*5h#P(I)LrmhiOjJxgzX7ROj47#YwhL7Amctn
z@!7p^@D`deIa&&BrF3?95l}(eKyF_(R`AQ4$K&08U%$CFSr&2NrG@5h=Xjkb#OX2PS^H3E3p&0Qep=wh)-_rlV+q>wxfip
zlwH?efo(Fq#`k1p;P(5uu>J_ICj=OVie_A&(MJfELN#0Mpg66K0z&_fiXq~7)fFe2
zp%lGSZ6VJ0|NA4m-gGFbX)s9YD+u|IRTwEe%ZaDhA}i_9IV7kCkRCp%zo|nXX1p9y
zjjSMhNS<}~)u3MnFannaFd`I9Q7nzrn(Id>;XMZ{%ib{yyF7^gqWIo!*
zpdfT`1eA;MfsnVb0cooa6ZenK{k*d-6!9-iO4y6-lzF}sB~+h3rP+l}^q2|{UbV3`
zXmWeP#y&CL5it)Yqqm8ZWwPvC=ae)yCR%=LpeI}0z$j8?Y(nuphdil2@t!TgO}8P!
z9SAAp!4ZISSjOZ0Z%{9^AUH6V2HDebl1!XC+!A9TN_cGgxr?^WDnOQ9o+q^ou=Yc`
z5gk2w+UfC>^SQJ7{OP;zVNcr8qsTc863o(XRUfr^y^jO0^Q}};wfE)N_GbCg)yuki
zOsOhzmt7p-AoE*>ICNZZ(mW2+o^;Ef%TQ-5rcl#fy2Zj{PNectw$flC1zsY6CV*sh
zq-Qc_J|@?wq5k!I{rYpUZ}b~^CnB3*QmtMBMtsXZD&WBsEv%iImtVI!OjU?_26hh_
zTqmKCBDV}2^|x&nsVQnIGFQMkp7~^vR#(A$c4p}}ScdAyb_hqyk&4#8A#6+qAy%2gzK9V>z
zaz4kbJi0+=p|L1v+rQwVYsZ+11Pk$#$S9D~MSW`fFz2$wd(s~sr3QwVG*mOXCASnrNzyl{20g$
zKZji7AB;RL|IoO7mfe@!a-v3@NP!gPpE``r!DOxq(2~QG7w(EZHxl0fs?nYuugd@9
z=gp^i$qF=F1X}~>*YMy
z{7F;WwgEl2p6xy5HC>AL-TPX?t!KB?U%9-E60OEiSwZhQKPihWZ44{Mp5?%6v{w_fWkgbN*sGJIozueN$GMFLue^E&d?>r1?WJ@kmV=kS8*iME
zlnS94znl(+IGc%pu?B|2zFZkkhecCi3SDzJI6FEi1>XGKK(V~Ls)n!{X*Iib`nHu*
zRUdifC`dVu{ZZ2VRSV9X_k}BP*rG60y&51c2%KfclN%rIEnI38@H7gW7AQSDqvA8jmN#>3!qL#JdCRsO#@g!J_Q2FZKL)&dZ+Cxg^S_
zu?+w}2XNyoGL@^G+TK^PmOS4&fQbePCHfe4*Yn>xZ`>MIXUdYu1I2y(673E8IXE(@mt4qQX5HIMM79XgD&Vsr%6XG721J%(aHJF
z=*7Y#BXqsnriI=t0xwFlmUx!7{M3{j-dQ>Hy?j4N_s@=i<}A$zMcQsUZYPc{GD6(s
zH3j$QEs1|qT>;s=a9YCEb55?EYW@Sn~iVKe%7tqySSUJj@FUY
zo|HK4)M@wOtf_Jc1~Izc1BJy>sCV
z_Cz`6Aun+$Vjrh#n?=h2O>hoU^d{fg`x!P-^j6;;ru)pOb}(tn!*XwwW=&I>VKW4w
z*9$>VTv?*}#`yhC)8`6V;RB|Jq!8lz5BrN#gvOg1^9qh^W>PG{n%!17=<}^ZRzL??
zWf9P5PHq?G-y|v6;zT_U|VRyYr2BZiMZJK*SN#%DfU7|B#&p~)H?vl>&X$LDtrQhY4#9b}A$#yN5Z@(NmoG3>2x*h?nTJo}e5?g_0a
zphsT-`9{l!&bzK4g%(PaZzv+4eok^!2RsLyV#x6T`-bVpiYN<29ca=9v6kP@pa?6=
zt9@bIH=dS`t_({9gZBpt>IUcbPrU0Pz%Fs(QRSsEQvpEZYNhx{T2r$3H5i)5H5U#D
z;_8vX<#!Nb_dUYv?l6!p)PiNgbrXkiEg-1Yi*2Y9~#Pj62
zrvzTr@?eS3xDIc*^KAH(SXG(mOD|#I8bEfJBy+Aix6lH*NuEr}2>E?Bb2NnG1+zg*
zwENp+3^phAIx=Um!v#1=AgThH991x6rHlO`a4)3y2=b}Ries8PRLq2O?Vy9gz9KlY
z+$7V0_OW}MZ*Tm~=c;V<+)9(VFbG-x_2%3Dm$CVablVSo+#iH`9Ij+!(
zOmnJdjNwG8FzBngKBG06!8h?`Y`mqjk)zfxOTL)YusoM8+z^?n6z8V{D5}|x-R%b-
zI`f}s{t<+qbEhYJ&6`t}jtftTmQ5VHN%L+s^Yj=~34tlII;lAd^}=FR>8coLTm$39
zng_uyRY&A5^)LJ7l1fg8ZFu=76u?CVYQG7IfP8jzU>bS0btQ*Q_(xBnG+E58I$Yr8
zNsy;v-4WAdc?ih=3$-E^6GlQA7+7(1cA)oMT_p^D_BhgU!7*e@aI*P<$LDGzh@LTj
zrMX1jEAvmW!Uy5Kdh*6r?Uyv{xwNn^YGL^ULRr2sJrTZhjxmeF2NJHqLAXH5!fM0&
z^16gph_fWw2X+ZKMw{>_GWbf
zUo~8ZYkdYeX>>^8N!eJg$7^&%)M7yRcv3A)3j6xYKop!
z96rhTG~r{Z^P+=>|C*D5BXwPI$&hwj6u(|-yBsMK8l7{cyJ_~#CNakodIZkKGx!jW
z0;_^ENf#w5R}HzyTqg=QAVe;x>2UNkmFuHYE`U_w_I;@?jKv+)l(g3V#ss;+{AJ{W
z|Aecc>^kgcD25K98s>QTryXi~{Mq&zF?QI|hmWq}hwlI}JYAGNqs0c=aZntOL)=`h
zq5B0*H^nWk{{VLQcJ9VhgT?xetWl0s9
zcpbR6U^8I%kZ$;BlnjXek?nbuB{`98wRAdMD=cjn8`Iinf;~OLbE~hxeA(S|A;0RSnasw#I
zm%v7QoUxSv%jP_
zr>0BmY56H0qTDBBd6y?;s1GJmA=-L;^OSD{;w)<*?ACDyof-*kC9f7Js6dpgz4l><
z%00R0l2-ZZBbu>?#)1P49ue-=NFezxg-~5UAMJ&mV1U#zi;#WMVWiOp_ULLZW@Mp6
zOI~3gSZS+xFx1&aQZH9nygWdlr7%1y9O<0BbrC#QvsKWf1tFEdLv6>MwJm%ki8|(7yIz$^Lh8{F28y{t3}n
zuixC9eG~a~#mDy;S=s7EQ5?NsIJ)$`nCHp5!N-DwBDd@F$IcvEh~^j=?euYk
z7bS%NR^xw3qVpU|QPREU+3FC@lXYu7`F3U_3Ium&4h@~u!i9+7ABMnY_5pa+Z?Tng
zo;00wwzMDTP>%YS#Vh<%P%|S{4(gTWeOfWU=$oQ;_}K|xO^ggx&xaCI=~VYoDBvh=
z5gH
zGEdUY%6zr!d*%#TtErNdK8UaPX1a_@2*+#zI>BGc^Pojo@(Qm;<7Q)}1L+HWK
zNPTMgP82N)Y!ZcD1c5EqSw^noFLm~J|MEWRa=m#t_I0*S+d%JZ|FF@T0Q8NM+0Dok
z2zr=~NF@+`l^z7qqe(mAJqCy+m@O8L)llz;0vbJ_IO7()9GV
z{or)sFYVVI%pzm436Q@wfMu|49u|$~Tc$&3cZ?JFx;@yI14~T^YJVmuO2O5PXRl}*
zP>?T&OE#cRcq1MH044*N{K1k9tc&TtckIZ5q*6CA@tfWMqw)rT$JRKmG}2)eJ0VH|
zB2f6^_dhfRJ7f9<21o$l@2v3$HAaG4{sL8m;#L@D1@?+w11&Qz|KuF~j$Om{
z=^)?M(^HmCcHL=;y@`LXTo4sPfEuC75AU&Pfs(lffM*M)mG{gd{4ijqWPoSwREa9g
z=pKQ&3&tTxz=Z6*ObGB&`&q@8FvvZMFd#S~@b5RgPXEu07BF)_FOKWK1Y=A;xJOM_
zaB`<*9?C%cE&{%5(NTf~J(Naot%p3IAX}k-azHTXFYno&8}uV7gT+05F#}MM0({$*
z_6Pr`QUGUJ3=fHo*=tW#v4p#l5J^RouFyTp^eQZ6F)+}}*~R@*m4Rhtc3V1DWw(Q}
zf%oG@0@t|L`4A*f380MkqX*RJw*_-Rh+tFkD4mX?reDCUgJ;GS85wr}nLrLtfR2w#
yb9m{x*I4?8HnstqdwW~uMm9V6ae%(U-p4TSbS3d?*SbHr!l0*Ps9maQAMzhZ_sHu2
literal 0
HcmV?d00001
diff --git a/static/home.png b/static/home.png
new file mode 100644
index 0000000000000000000000000000000000000000..6bb2339885cd33a44e429d74a584e05411dbcb65
GIT binary patch
literal 23462
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