├── .browserslistrc ├── .editorconfig ├── .env.development ├── .env.production ├── .env.test ├── .eslintrc.js ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── .prettierignore ├── .prettierrc ├── README.md ├── babel.config.js ├── commit.config.js ├── commitlint.config.js ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── assets │ ├── css │ │ ├── base.less │ │ └── index.less │ └── img │ │ ├── login-bg.svg │ │ └── logo.svg ├── base-ui │ ├── breadcrumb │ │ ├── index.ts │ │ ├── src │ │ │ └── breadcrumb.vue │ │ └── types │ │ │ └── index.ts │ ├── card │ │ ├── index.ts │ │ └── src │ │ │ └── card.vue │ ├── echart │ │ ├── data │ │ │ └── china.json │ │ ├── hooks │ │ │ └── useEchart.ts │ │ ├── index.ts │ │ └── src │ │ │ └── base-echart.vue │ ├── form │ │ ├── index.ts │ │ ├── src │ │ │ └── form.vue │ │ └── types │ │ │ └── index.ts │ └── table │ │ ├── index.ts │ │ └── src │ │ └── table.vue ├── components │ ├── nav-header │ │ ├── index.ts │ │ └── src │ │ │ ├── nav-header.vue │ │ │ └── user-info.vue │ ├── nav-menu │ │ ├── index.ts │ │ └── src │ │ │ └── nav-menu.vue │ ├── page-content │ │ ├── index.ts │ │ └── src │ │ │ └── page-content.vue │ ├── page-echarts │ │ ├── index.ts │ │ ├── src │ │ │ ├── bar-echart.vue │ │ │ ├── line-echart.vue │ │ │ ├── map-echart.vue │ │ │ ├── pie-echart.vue │ │ │ └── rose-echart.vue │ │ ├── types │ │ │ └── index.ts │ │ └── utils │ │ │ ├── convert-data.ts │ │ │ └── coordinate-data.ts │ ├── page-modal │ │ ├── index.ts │ │ └── src │ │ │ └── page-modal.vue │ └── page-search │ │ ├── index.ts │ │ └── src │ │ └── page-search.vue ├── global │ ├── index.ts │ ├── register-element.ts │ └── register-properties.ts ├── hooks │ ├── use-page-modal.ts │ ├── use-page-search.ts │ └── use-permission.ts ├── main.ts ├── router │ ├── index.ts │ ├── login │ │ └── index.ts │ └── main │ │ ├── analysis │ │ ├── dashboard │ │ │ └── dashboard.ts │ │ └── overview │ │ │ └── overview.ts │ │ ├── product │ │ ├── category │ │ │ └── category.ts │ │ └── goods │ │ │ └── goods.ts │ │ ├── story │ │ ├── chat │ │ │ └── chat.ts │ │ └── list │ │ │ └── list.ts │ │ └── system │ │ ├── department │ │ └── department.ts │ │ ├── menu │ │ └── menu.ts │ │ ├── role │ │ └── role.ts │ │ └── user │ │ └── user.ts ├── service │ ├── axios_demo.ts │ ├── index.ts │ ├── login │ │ ├── login.ts │ │ └── type.ts │ ├── main │ │ ├── analysis │ │ │ └── dashboard.ts │ │ └── system │ │ │ └── system.ts │ ├── request │ │ ├── config.ts │ │ ├── index.ts │ │ └── type.ts │ └── types.ts ├── shims-vue.d.ts ├── store │ ├── index.ts │ ├── login │ │ ├── login.ts │ │ └── types.ts │ ├── main │ │ ├── analysis │ │ │ ├── dashboard.ts │ │ │ └── types.ts │ │ └── system │ │ │ ├── system.ts │ │ │ └── types.ts │ └── types.ts ├── utils │ ├── cache.ts │ ├── date-format.ts │ └── map-menus.ts └── views │ ├── login │ ├── config │ │ └── account-config.ts │ ├── cpns │ │ ├── login-account.vue │ │ ├── login-panel.vue │ │ └── login-phone.vue │ └── login.vue │ ├── main │ ├── analysis │ │ ├── dashboard │ │ │ └── dashboard.vue │ │ └── overview │ │ │ └── overview.vue │ ├── main.vue │ ├── product │ │ ├── category │ │ │ └── category.vue │ │ └── goods │ │ │ ├── config │ │ │ └── content.config.ts │ │ │ └── goods.vue │ ├── story │ │ ├── chat │ │ │ └── chat.vue │ │ └── list │ │ │ └── list.vue │ └── system │ │ ├── department │ │ └── department.vue │ │ ├── menu │ │ ├── config │ │ │ └── content.config.ts │ │ └── menu.vue │ │ ├── role │ │ ├── config │ │ │ ├── content.config.ts │ │ │ ├── modal.config.ts │ │ │ └── search.config.ts │ │ └── role.vue │ │ └── user │ │ ├── config │ │ ├── content.config.ts │ │ ├── modal.config.ts │ │ └── search.config.ts │ │ └── user.vue │ └── not-found │ └── not-found.vue ├── tsconfig.json └── vue.config.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] # 表示所有文件适用 6 | charset = utf-8 # 设置文件字符集为 utf-8 7 | indent_style = space # 缩进风格(tab | space) 8 | indent_size = 2 # 缩进大小 9 | end_of_line = lf # 控制换行类型(lf | cr | crlf) 10 | trim_trailing_whitespace = true # 去除行首的任意空白字符 11 | insert_final_newline = true # 始终在文件末尾插入一个新行 12 | 13 | [*.md] # 表示仅 md 文件适用以下规则 14 | max_line_length = off 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.env.development: -------------------------------------------------------------------------------- 1 | VUE_APP_BASE_URL=https://coderwhy.org/dev 2 | VUE_APP_BASE_NAME=coderwhy 3 | -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | VUE_APP_BASE_URL=https://coderwhy.org/prod 2 | VUE_APP_BASE_NAME=kobe 3 | -------------------------------------------------------------------------------- /.env.test: -------------------------------------------------------------------------------- 1 | VUE_APP_BASE_URL=https://coderwhy.org/test 2 | VUE_APP_BASE_NAME=james 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: [ 7 | 'plugin:vue/vue3-essential', 8 | 'eslint:recommended', 9 | '@vue/typescript/recommended', 10 | '@vue/prettier', 11 | '@vue/prettier/@typescript-eslint', 12 | 'plugin:prettier/recommended' 13 | ], 14 | parserOptions: { 15 | ecmaVersion: 2020 16 | }, 17 | rules: { 18 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 19 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 20 | '@typescript-eslint/no-var-requires': 'off', 21 | '@typescript-eslint/no-explicit-any': 'off', 22 | '@typescript-eslint/explicit-module-boundary-types': 'off', 23 | '@typescript-eslint/no-non-null-assertion': 'off' 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no-install commitlint --edit 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run lint 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /dist/* 2 | .local 3 | .output.js 4 | /node_modules/** 5 | 6 | **/*.svg 7 | **/*.sh 8 | 9 | /public/* 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": false, 3 | "tabWidth": 2, 4 | "printWidth": 80, 5 | "singleQuote": true, 6 | "trailingComma": "none", 7 | "semi": false 8 | } 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue3-ts-cms 2 | 3 | ## Project setup 4 | 5 | ``` 6 | npm install 7 | ``` 8 | 9 | ### Compiles and hot-reloads for development 10 | 11 | ``` 12 | npm run serve 13 | ``` 14 | 15 | ### Compiles and minifies for production 16 | 17 | ``` 18 | npm run build 19 | ``` 20 | 21 | ### Lints and fixes files 22 | 23 | ``` 24 | npm run lint 25 | ``` 26 | 27 | ### Customize configuration 28 | 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | [ 4 | 'import', 5 | { 6 | libraryName: 'element-plus', 7 | customStyleName: (name) => { 8 | return `element-plus/lib/theme-chalk/${name}.css` 9 | } 10 | } 11 | ] 12 | ], 13 | presets: ['@vue/cli-plugin-babel/preset'] 14 | } 15 | -------------------------------------------------------------------------------- /commit.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'] 3 | } 4 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'] 3 | } 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue3-ts-cms", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint", 9 | "prettier": "prettier --write .", 10 | "prepare": "husky install", 11 | "commit": "cz" 12 | }, 13 | "dependencies": { 14 | "axios": "^0.21.1", 15 | "core-js": "^3.6.5", 16 | "dayjs": "^1.10.6", 17 | "echarts": "^5.1.2", 18 | "element-plus": "^1.0.2-beta.62", 19 | "normalize.css": "^8.0.1", 20 | "vue": "^3.2.4", 21 | "vue-router": "^4.0.10", 22 | "vuex": "^4.0.2" 23 | }, 24 | "devDependencies": { 25 | "@commitlint/cli": "^12.1.4", 26 | "@commitlint/config-conventional": "^12.1.4", 27 | "@typescript-eslint/eslint-plugin": "^4.18.0", 28 | "@typescript-eslint/parser": "^4.18.0", 29 | "@vue/cli-plugin-babel": "~4.5.0", 30 | "@vue/cli-plugin-eslint": "~4.5.0", 31 | "@vue/cli-plugin-typescript": "~4.5.0", 32 | "@vue/cli-service": "~4.5.0", 33 | "@vue/compiler-sfc": "^3.2.4", 34 | "@vue/eslint-config-prettier": "^6.0.0", 35 | "@vue/eslint-config-typescript": "^7.0.0", 36 | "babel-plugin-import": "^1.13.3", 37 | "commitizen": "^4.2.4", 38 | "cz-conventional-changelog": "^3.3.0", 39 | "eslint": "^6.7.2", 40 | "eslint-plugin-prettier": "^3.3.1", 41 | "eslint-plugin-vue": "^7.0.0", 42 | "husky": "^7.0.0", 43 | "less": "^3.0.4", 44 | "less-loader": "^5.0.0", 45 | "prettier": "^2.3.2", 46 | "typescript": "~4.1.5" 47 | }, 48 | "config": { 49 | "commitizen": { 50 | "path": "./node_modules/cz-conventional-changelog" 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/July107/Vue3-TS-CMS/e5a4960e2724e3010dfe85d362acc41b91bcd39d/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 32 | 33 | 38 | -------------------------------------------------------------------------------- /src/assets/css/base.less: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0; 3 | margin: 0; 4 | } 5 | 6 | html, body, #app { 7 | width: 100%; 8 | height: 100%; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/assets/css/index.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | -------------------------------------------------------------------------------- /src/assets/img/login-bg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 21 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/assets/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/base-ui/breadcrumb/index.ts: -------------------------------------------------------------------------------- 1 | import HyBreadcrumb from './src/breadcrumb.vue' 2 | 3 | export * from './types' 4 | 5 | export default HyBreadcrumb 6 | -------------------------------------------------------------------------------- /src/base-ui/breadcrumb/src/breadcrumb.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/base-ui/breadcrumb/types/index.ts: -------------------------------------------------------------------------------- 1 | export interface IBreadcrumb { 2 | name: string 3 | path?: string 4 | } 5 | -------------------------------------------------------------------------------- /src/base-ui/card/index.ts: -------------------------------------------------------------------------------- 1 | import HyCard from './src/card.vue' 2 | 3 | export default HyCard 4 | -------------------------------------------------------------------------------- /src/base-ui/card/src/card.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 32 | 33 | 52 | -------------------------------------------------------------------------------- /src/base-ui/echart/data/china.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FeatureCollection", 3 | "features": [ 4 | { 5 | "type": "Feature", 6 | "id": "710000", 7 | "properties": { 8 | "id": "710000", 9 | "cp": [121.509062, 24.044332], 10 | "name": "台湾", 11 | "childNum": 6 12 | }, 13 | "geometry": { 14 | "type": "MultiPolygon", 15 | "coordinates": [ 16 | ["@@°Ü¯Û"], 17 | [ 18 | "@@ƛĴÕƊÉɼģºðʀ\\ƎsÆNŌÔĚäœnÜƤɊĂǀĆĴžĤNJŨxĚĮǂƺòƌ‚–âÔ®ĮXŦţƸZûЋƕƑGđ¨ĭMó·ęcëƝɉlÝƯֹÅŃ^Ó·śŃNjƏďíåɛGɉ™¿@ăƑŽ¥ĘWǬÏĶŁâ" 19 | ], 20 | ["@@\\p|WoYG¿¥I†j@¢"], 21 | ["@@…¡‰@ˆV^RqˆBbAŒnTXeRz¤Lž«³I"], 22 | ["@@ÆEE—„kWqë @œ"], 23 | ["@@fced"], 24 | ["@@„¯ɜÄèaì¯ØǓIġĽ"], 25 | ["@@çûĖ롖hòř "] 26 | ], 27 | "encodeOffsets": [ 28 | [[122886, 24033]], 29 | [[123335, 22980]], 30 | [[122375, 24193]], 31 | [[122518, 24117]], 32 | [[124427, 22618]], 33 | [[124862, 26043]], 34 | [[126259, 26318]], 35 | [[127671, 26683]] 36 | ] 37 | } 38 | }, 39 | { 40 | "type": "Feature", 41 | "id": "130000", 42 | "properties": { 43 | "id": "130000", 44 | "cp": [114.502461, 38.045474], 45 | "name": "河北", 46 | "childNum": 3 47 | }, 48 | "geometry": { 49 | "type": "MultiPolygon", 50 | "coordinates": [ 51 | ["@@o~†Z]‚ªr‰ºc_ħ²G¼s`jΟnüsœłNX_“M`ǽÓnUK…Ĝēs¤­©yrý§uģŒc†JŠ›e"], 52 | ["@@U`Ts¿m‚"], 53 | [ 54 | "@@oºƋÄd–eVŽDJj£€J|Ådz•Ft~žKŨ¸IÆv|”‡¢r}膎onb˜}`RÎÄn°ÒdÞ²„^®’lnÐèĄlðӜ×]ªÆ}LiĂ±Ö`^°Ç¶p®đDcœŋ`–ZÔ’¶êqvFƚ†N®ĆTH®¦O’¾ŠIbÐã´BĐɢŴÆíȦp–ĐÞXR€·nndOž¤’OÀĈƒ­Qg˜µFo|gȒęSWb©osx|hYh•gŃfmÖĩnº€T̒Sp›¢dYĤ¶UĈjl’ǐpäìë|³kÛfw²Xjz~ÂqbTŠÑ„ěŨ@|oM‡’zv¢ZrÃVw¬ŧˏfŒ°ÐT€ªqŽs{Sž¯r æÝlNd®²Ğ džiGʂJ™¼lr}~K¨ŸƐÌWö€™ÆŠzRš¤lêmĞL΄’@¡|q]SvK€ÑcwpÏρ†ĿćènĪWlĄkT}ˆJ”¤~ƒÈT„d„™pddʾĬŠ”ŽBVt„EÀ¢ôPĎƗè@~‚k–ü\\rÊĔÖæW_§¼F˜†´©òDòj’ˆYÈrbĞāøŀG{ƀ|¦ðrb|ÀH`pʞkv‚GpuARhÞÆǶgƊTǼƹS£¨¡ù³ŘÍ]¿Ây™ôEP xX¶¹܇O¡“gÚ¡IwÃ鑦ÅB‡Ï|ǰ…N«úmH¯‹âŸDùŽyŜžŲIÄuШDž•¸dɂ‡‚FŸƒ•›Oh‡đ©OŸ›iÃ`ww^ƒÌkŸ‘ÑH«ƇǤŗĺtFu…{Z}Ö@U‡´…ʚLg®¯Oı°ÃwŸ ^˜—€VbÉs‡ˆmA…ê]]w„§›RRl£‡ȭµu¯b{ÍDěïÿȧŽuT£ġƒěŗƃĝ“Q¨fV†Ƌ•ƅn­a@‘³@šď„yýIĹÊKšŭfċŰóŒxV@tˆƯŒJ”]eƒR¾fe|rHA˜|h~Ėƍl§ÏŠlTíb ØoˆÅbbx³^zÃ͚¶Sj®A”yÂhðk`š«P€”ˈµEF†Û¬Y¨Ļrõqi¼‰Wi°§’б´°^[ˆÀ|ĠO@ÆxO\\tŽa\\tĕtû{ġŒȧXýĪÓjùÎRb›š^ΛfK[ݏděYfíÙTyŽuUSyŌŏů@Oi½’éŅ­aVcř§ax¹XŻác‡žWU£ôãºQ¨÷Ñws¥qEH‰Ù|‰›šYQoŕÇyáĂ£MðoťÊ‰P¡mšWO¡€v†{ôvîēÜISpÌhp¨ ‘j†deŔQÖj˜X³à™Ĉ[n`Yp@Už–cM`’RKhŒEbœ”pŞlNut®Etq‚nsÁŠgA‹iú‹oH‡qCX‡”hfgu“~ϋWP½¢G^}¯ÅīGCŸÑ^ãziMáļMTÃƘrMc|O_ž¯Ŏ´|‡morDkO\\mĆJfl@c̬¢aĦtRıҙ¾ùƀ^juųœK­ƒUFy™—Ɲ…›īÛ÷ąV×qƥV¿aȉd³B›qPBm›aËđŻģm“Å®Vйd^K‡KoŸnYg“¯Xhqa”Ldu¥•ÍpDž¡KąÅƒkĝęěhq‡}HyÓ]¹ǧ£…Í÷¿qáµ§š™g‘¤o^á¾ZE‡¤i`ij{n•ƒOl»ŸWÝĔįhg›F[¿¡—ßkOüš_‰€ū‹i„DZàUtėGylƒ}ŒÓM}€jpEC~¡FtoQi‘šHkk{Ãmï‚" 55 | ] 56 | ], 57 | "encodeOffsets": [[[119712, 40641]], [[121616, 39981]], [[116462, 37237]]] 58 | } 59 | }, 60 | { 61 | "type": "Feature", 62 | "id": "140000", 63 | "properties": { 64 | "id": "140000", 65 | "cp": [111.849248, 36.857014], 66 | "name": "山西", 67 | "childNum": 1 68 | }, 69 | "geometry": { 70 | "type": "Polygon", 71 | "coordinates": [ 72 | "@@Þĩ҃S‰ra}Á€yWix±Üe´lè“ßÓǏok‘ćiµVZģ¡coœ‘TS˹ĪmnÕńe–hZg{gtwªpXaĚThȑp{¶Eh—®RćƑP¿£‘Pmc¸mQÝW•ďȥoÅîɡųAďä³aωJ‘½¥PG­ąSM­™…EÅruµé€‘Yӎ•Ō_d›ĒCo­Èµ]¯_²ÕjāŽK~©ÅØ^ԛkïçămϑk]­±ƒcݯÑÃmQÍ~_a—pm…~ç¡q“ˆu{JÅŧ·Ls}–EyÁÆcI{¤IiCfUc•ƌÃp§]웫vD@¡SÀ‘µM‚ÅwuŽYY‡¡DbÑc¡hƒ×]nkoQdaMç~eD•ÛtT‰©±@¥ù@É¡‰ZcW|WqOJmĩl«ħşvOÓ«IqăV—¥ŸD[mI~Ó¢cehiÍ]Ɠ~ĥqXŠ·eƷœn±“}v•[ěďŽŕ]_‘œ•`‰¹ƒ§ÕōI™o©b­s^}Ét±ū«³p£ÿ·Wµ|¡¥ăFÏs׌¥ŅxŸÊdÒ{ºvĴÎêÌɊ²¶€ü¨|ÞƸµȲ‘LLúÉƎ¤ϊęĔV`„_bª‹S^|ŸdŠzY|dz¥p†ZbÆ£¶ÒK}tĦÔņƠ‚PYzn€ÍvX¶Ěn ĠÔ„zý¦ª˜÷žÑĸَUȌ¸‚dòÜJð´’ìúNM¬ŒXZ´‘¤ŊǸ_tldIš{¦ƀðĠȤ¥NehXnYG‚‡R° ƬDj¬¸|CĞ„Kq‚ºfƐiĺ©ª~ĆOQª ¤@ìǦɌ²æBŒÊ”TœŸ˜ʂōĖ’šĴŞ–ȀœÆÿȄlŤĒö„t”νî¼ĨXhŒ‘˜|ªM¤Ðz" 73 | ], 74 | "encodeOffsets": [[116874, 41716]] 75 | } 76 | }, 77 | { 78 | "type": "Feature", 79 | "id": "150000", 80 | "properties": { 81 | "id": "150000", 82 | "cp": [111.670801, 41.818311], 83 | "name": "内蒙古", 84 | "childNum": 2 85 | }, 86 | "geometry": { 87 | "type": "MultiPolygon", 88 | "coordinates": [ 89 | [ 90 | "@@¯PqƒFB…‰|S•³C|kñ•H‹d‘iÄ¥sˆʼnő…PóÑÑE^‘ÅPpy_YtS™hQ·aHwsOnʼnÚs©iqj›‰€USiº]ïWš‰«gW¡A–Rë¥_ŽsgÁnUI«m‰…„‹]j‡vV¼euhwqA„aW˜ƒ_µj…»çjioQR¹ēÃßt@r³[ÛlćË^ÍÉáG“›OUۗOB±•XŸkŇ¹£k|e]ol™ŸkVͼÕqtaÏõjgÁ£§U^Œ”RLˆËnX°Ç’Bz†^~wfvˆypV ¯„ƫĉ˭ȫƗŷɿÿĿƑ˃ĝÿÃǃßËőó©ǐȍŒĖM×ÍEyx‹þp]Évïè‘vƀnÂĴÖ@‚‰†V~Ĉv¦wĖt—ējyÄDXÄxGQuv_›i¦aBçw‘˛wD™©{ŸtāmQ€{EJ§KPśƘƿ¥@‰sCT•É}ɃwˆƇy±ŸgÑ“}T[÷kÐ禫…SÒ¥¸ëBX½‰HáŵÀğtSÝÂa[ƣ°¯¦P]£ġ“–“Òk®G²„èQ°óMq}EŠóƐÇ\\ƒ‡@áügQ͋u¥Fƒ“T՛¿Jû‡]|mvāÎYua^WoÀa·­ząÒot×¶CLƗi¯¤mƎHNJ¤îìɾŊìTdåwsRÖgĒųúÍġäÕ}Q¶—ˆ¿A•†‹[¡Œ{d×uQAƒ›M•xV‹vMOmăl«ct[wº_šÇʊŽŸjb£ĦS_é“QZ“_lwgOiýe`YYLq§IÁˆdz£ÙË[ÕªuƏ³ÍT—s·bÁĽäė[›b[ˆŗfãcn¥îC¿÷µ[ŏÀQ­ōšĉm¿Á^£mJVm‡—L[{Ï_£›F¥Ö{ŹA}…×Wu©ÅaųijƳhB{·TQqÙIķˑZđ©Yc|M¡…L•eVUóK_QWk’_ĥ‘¿ãZ•»X\\ĴuUƒè‡lG®ěłTĠğDєOrÍd‚ÆÍz]‹±…ŭ©ŸÅ’]ŒÅÐ}UË¥©Tċ™ïxgckfWgi\\ÏĒ¥HkµE˜ë{»ÏetcG±ahUiñiWsɁˆ·c–C‚Õk]wȑ|ća}w…VaĚ᠞ŒG°ùnM¬¯†{ÈˆÐÆA’¥ÄêJxÙ¢”hP¢Ûˆº€µwWOŸóFŽšÁz^ÀŗÎú´§¢T¤ǻƺSė‰ǵhÝÅQgvBHouʝl_o¿Ga{ïq{¥|ſĿHĂ÷aĝÇq‡Z‘ñiñC³ª—…»E`¨åXēÕqÉû[l•}ç@čƘóO¿¡ƒFUsA‰“ʽīccšocƒ‚ƒÇS}„“£‡IS~ălkĩXçmĈ…ŀЂoÐdxÒuL^T{r@¢‘žÍƒĝKén£kQ™‰yšÅõËXŷƏL§~}kqš»IHėDžjĝŸ»ÑÞoŸå°qTt|r©ÏS‹¯·eŨĕx«È[eMˆ¿yuˆ‘pN~¹ÏyN£{©’—g‹ħWí»Í¾s“əšDž_ÃĀɗ±ą™ijĉʍŌŷ—S›É“A‹±åǥɋ@럣R©ąP©}ĹªƏj¹erƒLDĝ·{i«ƫC£µsKCš…GS|úþX”gp›{ÁX¿Ÿć{ƱȏñZáĔyoÁhA™}ŅĆfdʼn„_¹„Y°ėǩÑ¡H¯¶oMQqð¡Ë™|‘Ñ`ƭŁX½·óۓxğįÅcQ‡ˆ“ƒs«tȋDžF“Ÿù^i‘t«Č¯[›hAi©á¥ÇĚ×l|¹y¯YȵƓ‹ñǙµï‚ċ™Ļ|Dœ™üȭ¶¡˜›oŽäÕG\\ďT¿Òõr¯œŸLguÏYęRƩšɷŌO\\İТæ^Ŋ IJȶȆbÜGŽĝ¬¿ĚVĎgª^íu½jÿĕęjık@Ľƒ]ėl¥Ë‡ĭûÁ„ƒėéV©±ćn©­ȇžÍq¯½•YÃÔʼn“ÉNѝÅÝy¹NqáʅDǡËñ­ƁYÅy̱os§ȋµʽǘǏƬɱà‘ưN¢ƔÊuľýľώȪƺɂļžxœZĈ}ÌʼnŪ˜ĺœŽĭFЛĽ̅ȣͽÒŵìƩÇϋÿȮǡŏçƑůĕ~Ǎ›¼ȳÐUf†dIxÿ\\G ˆzâɏÙOº·pqy£†@ŒŠqþ@Ǟ˽IBäƣzsÂZ†ÁàĻdñ°ŕzéØűzșCìDȐĴĺf®ŽÀľưø@ɜÖÞKĊŇƄ§‚͑těï͡VAġÑÑ»d³öǍÝXĉĕÖ{þĉu¸ËʅğU̎éhɹƆ̗̮ȘNJ֥ड़ࡰţાíϲäʮW¬®ҌeרūȠkɬɻ̼ãüfƠSצɩςåȈHϚÎKdzͲOðÏȆƘ¼CϚǚ࢚˼ФԂ¤ƌžĞ̪Qʤ´¼mȠJˀŸƲÀɠmǐnǔĎȆÞǠN~€ʢĜ‚¶ƌĆĘźʆȬ˪ĚǏĞGȖƴƀj`ĢçĶāàŃºē̃ĖćšYŒÀŎüôQÐÂŎŞdžŞêƖš˜oˆDĤÕºÑǘÛˤ³̀gńƘĔÀ^žªƂ`ªt¾äƚêĦĀ¼Ð€Ĕǎ¨Ȕ»͠^ˮÊȦƤøxRrŜH¤¸ÂxDĝŒ|ø˂˜ƮÐ¬ɚwɲFjĔ²Äw°dždÀɞ_ĸdîàŎjʜêTĞªŌ‡ŜWÈ|tqĢUB~´°ÎFC•ŽU¼pĀēƄN¦¾O¶ŠłKĊOj“Ě”j´ĜYp˜{¦„ˆSĚÍ\\Tš×ªV–÷Ší¨ÅDK°ßtŇĔKš¨ǵÂcḷ̌ĚǣȄĽF‡lġUĵœŇ‹ȣFʉɁƒMğįʏƶɷØŭOǽ«ƽū¹Ʊő̝Ȩ§ȞʘĖiɜɶʦ}¨֪ࠜ̀ƇǬ¹ǨE˦ĥªÔêFŽxúQ„Er´W„rh¤Ɛ \\talĈDJ˜Ü|[Pll̚¸ƎGú´Pž¬W¦†^¦–H]prR“n|or¾wLVnÇIujkmon£cX^Bh`¥V”„¦U¤¸}€xRj–[^xN[~ªŠxQ„‚[`ªHÆÂExx^wšN¶Ê˜|¨ì†˜€MrœdYp‚oRzNy˜ÀDs~€bcfÌ`L–¾n‹|¾T‚°c¨È¢a‚r¤–`[|òDŞĔöxElÖdH„ÀI`„Ď\\Àì~ƎR¼tf•¦^¢ķ¶e”ÐÚMŒptgj–„ɡČÅyġLû™ŇV®ŠÄÈƀ†Ď°P|ªVV†ªj–¬ĚÒêp¬–E|ŬÂc|ÀtƐK fˆ{ĘFǜƌXƲąo½Ę‘\\¥–o}›Ûu£ç­kX‘{uĩ«āíÓUŅßŢq€Ť¥lyň[€oi{¦‹L‡ń‡ðFȪȖ”ĒL„¿Ì‹ˆfŒ£K£ʺ™oqNŸƒwğc`ue—tOj×°KJ±qƒÆġm‰Ěŗos¬…qehqsuœƒH{¸kH¡Š…ÊRǪÇƌbȆ¢´ä܍¢NìÉʖ¦â©Ġu¦öČ^â£Ăh–šĖMÈÄw‚\\fŦ°W ¢¾luŸD„wŠ\\̀ʉÌÛM…Ā[bӞEn}¶Vc…ê“sƒ" 91 | ] 92 | ], 93 | "encodeOffsets": [[[129102, 52189]]] 94 | } 95 | }, 96 | { 97 | "type": "Feature", 98 | "id": "210000", 99 | "properties": { 100 | "id": "210000", 101 | "cp": [123.429096, 41.796767], 102 | "name": "辽宁", 103 | "childNum": 16 104 | }, 105 | "geometry": { 106 | "type": "MultiPolygon", 107 | "coordinates": [ 108 | ["@@L–Ž@@s™a"], 109 | ["@@MnNm"], 110 | ["@@d‚c"], 111 | ["@@eÀ‚C@b‚“‰"], 112 | ["@@f‡…Xwkbr–Ä`qg"], 113 | ["@@^jtW‘Q"], 114 | ["@@~ Y]c"], 115 | ["@@G`ĔN^_¿Z‚ÃM"], 116 | ["@@iX¶B‹Y"], 117 | ["@@„YƒZ"], 118 | ["@@L_{Epf"], 119 | ["@@^WqCT\\"], 120 | ["@@\\[“‹§t|”¤_"], 121 | ["@@m`n_"], 122 | ["@@Ïxnj{q_×^Giip"], 123 | [ 124 | "@@@œé^B†‡ntˆaÊU—˜Ÿ]x ¯ÄPIJ­°h€ʙK³†VˆÕ@Y~†|EvĹsDŽ¦­L^p²ŸÒG ’Ël]„xxÄ_˜fT¤Ď¤cŽœP„–C¨¸TVjbgH²sdÎdHt`Bˆ—²¬GJję¶[ÐhjeXdlwhšðSȦªVÊπ‹Æ‘Z˜ÆŶ®²†^ŒÎyÅÎcPqń“ĚDMħĜŁH­ˆk„çvV[ij¼W–‚YÀäĦ’‘`XlžR`žôLUVžfK–¢†{NZdĒª’YĸÌÚJRr¸SA|ƴgŴĴÆbvªØX~†źBŽ|¦ÕœEž¤Ð`\\|Kˆ˜UnnI]¤ÀÂĊnŎ™R®Ő¿¶\\ÀøíDm¦ÎbŨab‰œaĘ\\ľã‚¸a˜tÎSƐ´©v\\ÖÚÌǴ¤Â‡¨JKr€Z_Z€fjþhPkx€`Y”’RIŒjJcVf~sCN¤ ˆE‚œhæm‰–sHy¨SðÑÌ\\\\ŸĐRZk°IS§fqŒßýáЍÙÉÖ[^¯ǤŲ„ê´\\¦¬ĆPM¯£Ÿˆ»uïpùzEx€žanµyoluqe¦W^£ÊL}ñrkqWňûP™‰UP¡ôJŠoo·ŒU}£Œ„[·¨@XŒĸŸ“‹‹DXm­Ûݏº‡›GU‹CÁª½{íĂ^cj‡k“¶Ã[q¤“LÉö³cux«zZfƒ²BWÇ®Yß½ve±ÃC•ý£W{Ú^’q^sÑ·¨‹ÍOt“¹·C¥‡GD›rí@wÕKţ݋˜Ÿ«V·i}xËÍ÷‘i©ĝ‡ɝǡ]ƒˆ{c™±OW‹³Ya±Ÿ‰_穂Hžĕoƫ€Ňqƒr³‰Lys[„ñ³¯OS–ďOMisZ†±ÅFC¥Pq{‚Ã[Pg}\\—¿ghćO…•k^ģÁFıĉĥM­oEqqZûěʼn³F‘¦oĵ—hŸÕP{¯~TÍlª‰N‰ßY“Ð{Ps{ÃVU™™eĎwk±ʼnVÓ½ŽJãÇÇ»Jm°dhcÀff‘dF~ˆ€ĀeĖ€d`sx² šƒ®EżĀdQ‹Âd^~ăÔHˆ¦\\›LKpĄVez¤NP ǹӗR™ÆąJSh­a[¦´Âghwm€BÐ¨źhI|žVVŽ—Ž|p] Â¼èNä¶ÜBÖ¼“L`‚¼bØæŒKV”ŸpoœúNZÞÒKxpw|ÊEMnzEQšŽIZ”ŽZ‡NBˆčÚFÜçmĩ‚WĪñt‘ÞĵÇñZ«uD‚±|Əlij¥ãn·±PmÍa‰–da‡ CL‡Ǒkùó¡³Ï«QaċϑOÃ¥ÕđQȥċƭy‹³ÃA" 125 | ] 126 | ], 127 | "encodeOffsets": [ 128 | [[123686, 41445]], 129 | [[126019, 40435]], 130 | [[124393, 40128]], 131 | [[126117, 39963]], 132 | [[125322, 40140]], 133 | [[126686, 40700]], 134 | [[126041, 40374]], 135 | [[125584, 40168]], 136 | [[125453, 40165]], 137 | [[125362, 40214]], 138 | [[125280, 40291]], 139 | [[125774, 39997]], 140 | [[125976, 40496]], 141 | [[125822, 39993]], 142 | [[125509, 40217]], 143 | [[122731, 40949]] 144 | ] 145 | } 146 | }, 147 | { 148 | "type": "Feature", 149 | "id": "220000", 150 | "properties": { "id": "220000", "cp": [125.3245, 43.886841], "name": "吉林", "childNum": 1 }, 151 | "geometry": { 152 | "type": "Polygon", 153 | "coordinates": [ 154 | "@@‘p䔳PClƒFbbÍzš€wBG’ĭ€Z„Åi“»ƒlY­ċ²SgŽkÇ£—^S‰“qd¯•‹R…©éŽ£¯S†\\cZ¹iűƏCuƍÓX‡oR}“M^o•£…R}oªU­F…uuXHlEŕ‡€Ï©¤ÛmTŽþ¤D–²ÄufàÀ­XXȱAe„yYw¬dvõ´KÊ£”\\rµÄl”iˆdā]|DÂVŒœH¹ˆÞ®ÜWnŒC”Œķ W‹§@\\¸‹ƒ~¤‹Vp¸‰póIO¢ŠVOšŇürXql~òÉK]¤¥Xrfkvzpm¶bwyFoúvð‡¼¤ N°ąO¥«³[ƒéǡű_°Õ\\ÚÊĝŽþâőàerR¨­JYlďQ[ ÏYëЧTGz•tnŠß¡gFkMŸāGÁ¤ia É‰™È¹`\\xs€¬dĆkNnuNUŠ–užP@‚vRY¾•–\\¢…ŒGªóĄ~RãÖÎĢù‚đŴÕhQŽxtcæëSɽʼníëlj£ƍG£nj°KƘµDsØÑpyƸ®¿bXp‚]vbÍZuĂ{nˆ^IüœÀSք”¦EŒvRÎûh@℈[‚Əȉô~FNr¯ôçR±ƒ­HÑl•’Ģ–^¤¢‚OðŸŒævxsŒ]ÞÁTĠs¶¿âƊGW¾ìA¦·TѬ†è¥€ÏÐJ¨¼ÒÖ¼ƒƦɄxÊ~S–tD@ŠĂ¼Ŵ¡jlºWžvЉˆzƦZЎ²CH— „Axiukd‹ŒGgetqmcžÛ£Ozy¥cE}|…¾cZ…k‚‰¿uŐã[oxGikfeäT@…šSUwpiÚFM©’£è^ڟ‚`@v¶eň†f h˜eP¶žt“äOlÔUgƒÞzŸU`lœ}ÔÆUvØ_Ō¬Öi^ĉi§²ÃŠB~¡Ĉ™ÚEgc|DC_Ȧm²rBx¼MÔ¦ŮdĨÃâYx‘ƘDVÇĺĿg¿cwÅ\\¹˜¥Yĭlœ¤žOv†šLjM_a W`zļMž·\\swqÝSA‡š—q‰Śij¯Š‘°kŠRē°wx^Đkǂғ„œž“œŽ„‹\\]˜nrĂ}²ĊŲÒøãh·M{yMzysěnĒġV·°“G³¼XÀ““™¤¹i´o¤ŃšŸÈ`̃DzÄUĞd\\i֚ŒˆmÈBĤÜɲDEh LG¾ƀľ{WaŒYÍȏĢĘÔRîĐj‹}Ǟ“ccj‡oUb½š{“h§Ǿ{K‹ƖµÎ÷žGĀÖŠåưÎs­l›•yiē«‹`姝H¥Ae^§„GK}iã\\c]v©ģZ“mÃ|“[M}ģTɟĵ‘Â`À–çm‰‘FK¥ÚíÁbXš³ÌQґHof{‰]e€pt·GŋĜYünĎųVY^’˜ydõkÅZW„«WUa~U·Sb•wGçǑ‚“iW^q‹F‚“›uNĝ—·Ew„‹UtW·Ýďæ©PuqEzwAV•—XR‰ãQ`­©GŒM‡ehc›c”ďϝd‡©ÑW_ϗYƅŒ»…é\\ƒɹ~ǙG³mØ©BšuT§Ĥ½¢Ã_ý‘L¡‘ýŸqT^rme™\\Pp•ZZbƒyŸ’uybQ—efµ]UhĿDCmûvašÙNSkCwn‰cćfv~…Y‹„ÇG" 155 | ], 156 | "encodeOffsets": [[130196, 42528]] 157 | } 158 | }, 159 | { 160 | "type": "Feature", 161 | "id": "230000", 162 | "properties": { 163 | "id": "230000", 164 | "cp": [128.642464, 46.756967], 165 | "name": "黑龙江", 166 | "childNum": 2 167 | }, 168 | "geometry": { 169 | "type": "MultiPolygon", 170 | "coordinates": [ 171 | [ 172 | "@@UƒµNÿ¥īè灋•HÍøƕ¶LŒǽ|g¨|”™Ža¾pViˆdd”~ÈiŒíďÓQġėǐZ΋ŽXb½|ſÃH½ŸKFgɱCģÛÇA‡n™‹jÕc[VĝDZÃ˄Ç_™ £ń³pŽj£º”š¿”»WH´¯”U¸đĢmžtĜyzzNN|g¸÷äűѱĉā~mq^—Œ[ƒ”››”ƒǁÑďlw]¯xQĔ‰¯l‰’€°řĴrŠ™˜BˆÞTxr[tޏĻN_yŸX`biN™Ku…P›£k‚ZĮ—¦[ºxÆÀdhŽĹŀUÈƗCw’áZħÄŭcÓ¥»NAw±qȥnD`{ChdÙFćš}¢‰A±Äj¨]ĊÕjŋ«×`VuÓś~_kŷVÝyh„“VkÄãPs”Oµ—fŸge‚Ň…µf@u_Ù ÙcŸªNªÙEojVx™T@†ãSefjlwH\\pŏäÀvŠŽlY†½d{†F~¦dyz¤PÜndsrhf‹HcŒvlwjFœ£G˜±DύƥY‡yϊu¹XikĿ¦ÏqƗǀOŜ¨LI|FRĂn sª|Cš˜zxAè¥bœfudTrFWÁ¹Am|˜ĔĕsķÆF‡´Nš‰}ć…UŠÕ@Áijſmužç’uð^ÊýowŒFzØÎĕNőžǏȎôªÌŒDŽàĀÄ˄ĞŀƒʀĀƘŸˮȬƬĊ°ƒUŸzou‡xe]}Ž…AyȑW¯ÌmK‡“Q]‹Īºif¸ÄX|sZt|½ÚUΠlkš^p{f¤lˆºlÆW –€A²˜PVܜPH”Êâ]ÎĈÌÜk´\\@qàsĔÄQºpRij¼èi†`¶—„bXƒrBgxfv»ŽuUiˆŒ^v~”J¬mVp´£Œ´VWrnP½ì¢BX‚¬h™ŠðX¹^TjVœŠriªj™tŊÄm€tPGx¸bgRšŽsT`ZozÆO]’ÒFô҆Oƒ‡ŊŒvŞ”p’cGŒêŠsx´DR–Œ{A†„EOr°Œ•žx|íœbˆ³Wm~DVjºéNN†Ëܲɶ­GƒxŷCStŸ}]ûō•SmtuÇÃĕN•™āg»šíT«u}ç½BĵÞʣ¥ëÊ¡Mێ³ãȅ¡ƋaǩÈÉQ‰†G¢·lG|›„tvgrrf«†ptęŘnŠÅĢr„I²¯LiØsPf˜_vĠd„xM prʹšL¤‹¤‡eˌƒÀđK“žïÙVY§]I‡óáĥ]ķ†Kˆ¥Œj|pŇ\\kzţ¦šnņäÔVĂîά|vW’®l¤èØr‚˜•xm¶ă~lÄƯĄ̈́öȄEÔ¤ØQĄ–Ą»ƢjȦOǺ¨ìSŖÆƬy”Qœv`–cwƒZSÌ®ü±DŽ]ŀç¬B¬©ńzƺŷɄeeOĨS’Œfm Ċ‚ƀP̎ēz©Ċ‚ÄÕÊmgŸÇsJ¥ƔˆŊśæ’΁Ñqv¿íUOµª‰ÂnĦÁ_½ä@ê텣P}Ġ[@gġ}g“ɊדûÏWXá¢užƻÌsNͽƎÁ§č՛AēeL³àydl›¦ĘVçŁpśdžĽĺſʃQíÜçÛġԏsĕ¬—Ǹ¯YßċġHµ ¡eå`ļƒrĉŘóƢFì“ĎWøxÊk†”ƈdƬv|–I|·©NqńRŀƒ¤é”eŊœŀ›ˆàŀU²ŕƀB‚Q£Ď}L¹Îk@©ĈuǰųǨ”Ú§ƈnTËÇéƟÊcfčŤ^Xm‡—HĊĕË«W·ċëx³ǔķÐċJā‚wİ_ĸ˜Ȁ^ôWr­°oú¬Ħ…ŨK~”ȰCĐ´Ƕ£’fNÎèâw¢XnŮeÂÆĶŽ¾¾xäLĴĘlļO¤ÒĨA¢Êɚ¨®‚ØCÔ ŬGƠ”ƦYĜ‡ĘÜƬDJ—g_ͥœ@čŅĻA“¶¯@wÎqC½Ĉ»NŸăëK™ďÍQ“Ùƫ[«Ãí•gßÔÇOÝáW‘ñuZ“¯ĥ€Ÿŕā¡ÑķJu¤E Ÿå¯°WKɱ_d_}}vyŸõu¬ï¹ÓU±½@gÏ¿rýD‰†g…Cd‰µ—°MFYxw¿CG£‹Rƛ½Õ{]L§{qqąš¿BÇƻğëšܭNJË|c²}Fµ}›ÙRsÓpg±ŠQNqǫŋRwŕnéÑÉKŸ†«SeYR…ŋ‹@{¤SJ}šD Ûǖ֍Ÿ]gr¡µŷjqWÛham³~S«“„›Þ]" 173 | ] 174 | ], 175 | "encodeOffsets": [[[134456, 44547]]] 176 | } 177 | }, 178 | { 179 | "type": "Feature", 180 | "id": "320000", 181 | "properties": { 182 | "id": "320000", 183 | "cp": [119.767413, 33.041544], 184 | "name": "江苏", 185 | "childNum": 1 186 | }, 187 | "geometry": { 188 | "type": "Polygon", 189 | "coordinates": [ 190 | "@@cþÅPiŠ`ZŸRu¥É\\]~°ŽY`µ†Óƒ^phÁbnÀşúŽòa–ĬºTÖŒb‚˜e¦¦€{¸ZâćNpŒ©žHr|^ˆmjhŠSEb\\afv`sz^lkŽlj‹Ätg‹¤D˜­¾Xš¿À’|ДiZ„ȀåB·î}GL¢õcßjaŸyBFµÏC^ĭ•cÙt¿sğH]j{s©HM¢ƒQnDÀ©DaÜތ·jgàiDbPufjDk`dPOîƒhw¡ĥ‡¥šG˜ŸP²ĐobºrY†„î¶aHŢ´ ]´‚rılw³r_{£DB_Ûdåuk|ˆŨ¯F Cºyr{XFy™e³Þċ‡¿Â™kĭB¿„MvÛpm`rÚã”@ƹhågËÖƿxnlč¶Åì½Ot¾dJlŠVJʜǀœŞqvnOŠ^ŸJ”Z‘ż·Q}ê͎ÅmµÒ]Žƍ¦Dq}¬R^èĂ´ŀĻĊIԒtžIJyQŐĠMNtœR®òLh‰›Ěs©»œ}OӌGZz¶A\\jĨFˆäOĤ˜HYš†JvÞHNiÜaϚɖnFQlšNM¤ˆB´ĄNöɂtp–Ŭdf先‹qm¿QûŠùއÚb¤uŃJŴu»¹Ą•lȖħŴw̌ŵ²ǹǠ͛hĭłƕrçü±Y™xci‡tğ®jű¢KOķ•Coy`å®VTa­_Ā]ŐÝɞï²ʯÊ^]afYǸÃĆēĪȣJđ͍ôƋĝÄ͎ī‰çÛɈǥ£­ÛmY`ó£Z«§°Ó³QafusNıDž_k}¢m[ÝóDµ—¡RLčiXy‡ÅNïă¡¸iĔϑNÌŕoēdōîåŤûHcs}~Ûwbù¹£¦ÓCt‹OPrƒE^ÒoŠg™ĉIµžÛÅʹK…¤½phMŠü`o怆ŀ" 191 | ], 192 | "encodeOffsets": [[121740, 32276]] 193 | } 194 | }, 195 | { 196 | "type": "Feature", 197 | "id": "330000", 198 | "properties": { 199 | "id": "330000", 200 | "cp": [120.153576, 29.287459], 201 | "name": "浙江", 202 | "childNum": 45 203 | }, 204 | "geometry": { 205 | "type": "MultiPolygon", 206 | "coordinates": [ 207 | ["@@E^dQ]K"], 208 | ["@@jX^j‡"], 209 | ["@@sfŠbU‡"], 210 | ["@@qP\\xz[ck"], 211 | ["@@‘Rƒ¢‚FX}°[s_"], 212 | ["@@Cbœ\\—}"], 213 | ["@@e|v\\la{u"], 214 | ["@@v~u}"], 215 | ["@@QxÂF¯}"], 216 | ["@@¹nŒvÞs¯o"], 217 | ["@@rSkUEj"], 218 | ["@@bi­ZŒP"], 219 | ["@@p[}INf"], 220 | ["@@À¿€"], 221 | ["@@¹dnbŒ…"], 222 | ["@@rSŸBnR"], 223 | ["@@g~h}"], 224 | ["@@FlEk"], 225 | ["@@OdPc"], 226 | ["@@v[u\\"], 227 | ["@@FjâL~wyoo~›sµL–\\"], 228 | ["@@¬e¹aNˆ"], 229 | ["@@\\nÔ¡q]L³ë\\ÿ®ŒQ֎"], 230 | ["@@ÊA­©[¬"], 231 | ["@@KxŒv­"], 232 | ["@@@hlIk]"], 233 | ["@@pW{o||j"], 234 | ["@@Md|_mC"], 235 | ["@@¢…X£ÏylD¼XˆtH"], 236 | ["@@hlÜ[LykAvyfw^Ež›¤"], 237 | ["@@fp¤Mus“R"], 238 | ["@@®_ma~•LÁ¬šZ"], 239 | ["@@iM„xZ"], 240 | ["@@ZcYd"], 241 | ["@@Z~dOSo|A¿qZv"], 242 | ["@@@`”EN¡v"], 243 | ["@@|–TY{"], 244 | ["@@@n@m"], 245 | ["@@XWkCT\\"], 246 | ["@@ºwšZRkĕWO¢"], 247 | ["@@™X®±Grƪ\\ÔáXq{‹"], 248 | ["@@ůTG°ĄLHm°UC‹"], 249 | [ 250 | "@@¤Ž€aÜx~}dtüGæţŎíĔcŖpMËВj碷ðĄÆMzˆjWKĎ¢Q¶˜À_꒔_Bı€i«pZ€gf€¤Nrq]§ĂN®«H±‡yƳí¾×ŸīàLłčŴǝĂíÀBŖÕªˆŠÁŖHŗʼnåqûõi¨hÜ·ƒñt»¹ýv_[«¸m‰YL¯‰Qª…mĉÅdMˆ•gÇjcº«•ęœ¬­K­´ƒB«Âącoċ\\xKd¡gěŧ«®á’[~ıxu·Å”KsËɏc¢Ù\\ĭƛëbf¹­ģSƒĜkáƉÔ­ĈZB{ŠaM‘µ‰fzʼnfåÂŧįƋǝÊĕġć£g³ne­ą»@­¦S®‚\\ßðCšh™iqªĭiAu‡A­µ”_W¥ƣO\\lċĢttC¨£t`ˆ™PZäuXßBs‡Ļyek€OđġĵHuXBšµ]׌‡­­\\›°®¬F¢¾pµ¼kŘó¬Wät’¸|@ž•L¨¸µr“ºù³Ù~§WI‹ŸZWŽ®’±Ð¨ÒÉx€`‰²pĜ•rOògtÁZ}þÙ]„’¡ŒŸFK‚wsPlU[}¦Rvn`hq¬\\”nQ´ĘRWb”‚_ rtČFI֊kŠŠĦPJ¶ÖÀÖJĈĄTĚòžC ²@Pú…Øzœ©PœCÈÚœĒ±„hŖ‡l¬â~nm¨f©–iļ«m‡nt–u†ÖZÜÄj“ŠLŽ®E̜Fª²iÊxبžIÈhhst" 251 | ], 252 | ["@@o\\V’zRZ}y"], 253 | ["@@†@°¡mۛGĕ¨§Ianá[ýƤjfæ‡ØL–•äGr™"] 254 | ], 255 | "encodeOffsets": [ 256 | [[125592, 31553]], 257 | [[125785, 31436]], 258 | [[125729, 31431]], 259 | [[125513, 31380]], 260 | [[125223, 30438]], 261 | [[125115, 30114]], 262 | [[124815, 29155]], 263 | [[124419, 28746]], 264 | [[124095, 28635]], 265 | [[124005, 28609]], 266 | [[125000, 30713]], 267 | [[125111, 30698]], 268 | [[125078, 30682]], 269 | [[125150, 30684]], 270 | [[124014, 28103]], 271 | [[125008, 31331]], 272 | [[125411, 31468]], 273 | [[125329, 31479]], 274 | [[125626, 30916]], 275 | [[125417, 30956]], 276 | [[125254, 30976]], 277 | [[125199, 30997]], 278 | [[125095, 31058]], 279 | [[125083, 30915]], 280 | [[124885, 31015]], 281 | [[125218, 30798]], 282 | [[124867, 30838]], 283 | [[124755, 30788]], 284 | [[124802, 30809]], 285 | [[125267, 30657]], 286 | [[125218, 30578]], 287 | [[125200, 30562]], 288 | [[124968, 30474]], 289 | [[125167, 30396]], 290 | [[124955, 29879]], 291 | [[124714, 29781]], 292 | [[124762, 29462]], 293 | [[124325, 28754]], 294 | [[123990, 28459]], 295 | [[125366, 31477]], 296 | [[125115, 30363]], 297 | [[125369, 31139]], 298 | [[122495, 31878]], 299 | [[125329, 30690]], 300 | [[125192, 30787]] 301 | ] 302 | } 303 | }, 304 | { 305 | "type": "Feature", 306 | "id": "340000", 307 | "properties": { "id": "340000", "cp": [117.283042, 31.26119], "name": "安徽", "childNum": 3 }, 308 | "geometry": { 309 | "type": "MultiPolygon", 310 | "coordinates": [ 311 | ["@@^iuLX^"], 312 | ["@@‚e©Ehl"], 313 | [ 314 | "@@°ZÆëϵmkǀwÌÕæhºgBĝâqÙĊz›ÖgņtÀÁÊÆá’hEz|WzqD¹€Ÿ°E‡ŧl{ævÜcA`¤C`|´qžxIJkq^³³ŸGšµbƒíZ…¹qpa±ď OH—¦™Ħˆx¢„gPícOl_iCveaOjCh߸i݋bÛªCC¿€m„RV§¢A|t^iĠGÀtÚs–d]ĮÐDE¶zAb àiödK¡~H¸íæAžǿYƒ“j{ď¿‘™À½W—®£ChŒÃsiŒkkly]_teu[bFa‰Tig‡n{]Gqªo‹ĈMYá|·¥f¥—őaSÕė™NµñĞ«ImŒ_m¿Âa]uĜp …Z_§{Cƒäg¤°r[_Yj‰ÆOdý“[ŽI[á·¥“Q_n‡ùgL¾mv™ˊBÜÆ¶ĊJhšp“c¹˜O]iŠ]œ¥ jtsggJǧw×jÉ©±›EFˍ­‰Ki”ÛÃÕYv…s•ˆm¬njĻª•§emná}k«ŕˆƒgđ²Ù›DǤ›í¡ªOy›†×Où±@DŸñSęćăÕIÕ¿IµĥO‰‰jNÕËT¡¿tNæŇàåyķrĕq§ÄĩsWÆßŽF¶žX®¿‰mŒ™w…RIޓfßoG‘³¾©uyH‘į{Ɓħ¯AFnuP…ÍÔzšŒV—dàôº^Ðæd´€‡oG¤{S‰¬ćxã}›ŧ×Kǥĩ«žÕOEзÖdÖsƘѨ[’Û^Xr¢¼˜§xvěƵ`K”§ tÒ´Cvlo¸fzŨð¾NY´ı~ÉĔē…ßúLÃϖ_ÈÏ|]ÂÏFl”g`bšežž€n¾¢pU‚h~ƴ˶_‚r sĄ~cž”ƈ]|r c~`¼{À{ȒiJjz`îÀT¥Û³…]’u}›f…ïQl{skl“oNdŸjŸäËzDvčoQŠďHI¦rb“tHĔ~BmlRš—V_„ħTLnñH±’DžœL‘¼L˜ªl§Ťa¸ŒĚlK²€\\RòvDcÎJbt[¤€D@®hh~kt°ǾzÖ@¾ªdb„YhüóZ ň¶vHrľ\\ʗJuxAT|dmÀO„‹[ÃԋG·ĚąĐlŪÚpSJ¨ĸˆLvÞcPæķŨŽ®mАˆálŸwKhïgA¢ųƩޖ¤OȜm’°ŒK´" 315 | ] 316 | ], 317 | "encodeOffsets": [[[121722, 32278]], [[119475, 30423]], [[119168, 35472]]] 318 | } 319 | }, 320 | { 321 | "type": "Feature", 322 | "id": "350000", 323 | "properties": { 324 | "id": "350000", 325 | "cp": [118.306239, 26.075302], 326 | "name": "福建", 327 | "childNum": 18 328 | }, 329 | "geometry": { 330 | "type": "MultiPolygon", 331 | "coordinates": [ 332 | ["@@“zht´‡]"], 333 | ["@@aj^~ĆG—©O"], 334 | ["@@ed¨„C}}i"], 335 | ["@@@vˆPGsQ"], 336 | ["@@‰sBz‚ddW]Q"], 337 | ["@@SލQ“{"], 338 | ["@@NŽVucW"], 339 | ["@@qptBAq"], 340 | ["@@‰’¸[mu"], 341 | ["@@Q\\pD]_"], 342 | ["@@jSwUadpF"], 343 | ["@@eXª~ƒ•"], 344 | ["@@AjvFso"], 345 | ["@@fT–›_Çí\\Ÿ™—v|ba¦jZÆy€°"], 346 | ["@@IjJi"], 347 | ["@@wJI€ˆxš«¼AoNe{M­"], 348 | ["@@K‰±¡Óˆ”ČäeZ"], 349 | [ 350 | "@@k¡¹Eh~c®wBk‹UplÀ¡I•~Māe£bN¨gZý¡a±Öcp©PhžI”Ÿ¢Qq…ÇGj‹|¥U™ g[Ky¬ŏ–v@OpˆtÉEŸF„\\@ åA¬ˆV{Xģ‰ĐBy…cpě…¼³Ăp·¤ƒ¥o“hqqÚ¡ŅLsƒ^ᗞ§qlŸÀhH¨MCe»åÇGD¥zPO£čÙkJA¼ß–ėu›ĕeûҍiÁŧSW¥˜QŠûŗ½ùěcݧSùĩąSWó«íęACµ›eR—åǃRCÒÇZÍ¢‹ź±^dlsŒtjD¸•‚ZpužÔâÒH¾oLUêÃÔjjēò´ĄW‚ƛ…^Ñ¥‹ĦŸ@Çò–ŠmŒƒOw¡õyJ†yD}¢ďÑÈġfŠZd–a©º²z£šN–ƒjD°Ötj¶¬ZSÎ~¾c°¶Ðm˜x‚O¸¢Pl´žSL|¥žA†ȪĖM’ņIJg®áIJČĒü` ŽQF‡¬h|ÓJ@zµ |ê³È ¸UÖŬŬÀEttĸr‚]€˜ðŽM¤ĶIJHtÏ A’†žĬkvsq‡^aÎbvŒd–™fÊòSD€´Z^’xPsÞrv‹ƞŀ˜jJd×ŘÉ ®A–ΦĤd€xĆqAŒ†ZR”ÀMźŒnĊ»ŒİÐZ— YX–æJŠyĊ²ˆ·¶q§·–K@·{s‘Xãô«lŗ¶»o½E¡­«¢±¨Yˆ®Ø‹¶^A™vWĶGĒĢžPlzfˆļŽtàAvWYãšO_‡¤sD§ssČġ[kƤPX¦Ž`¶“ž®ˆBBvĪjv©šjx[L¥àï[F…¼ÍË»ğV`«•Ip™}ccÅĥZE‹ãoP…´B@ŠD—¸m±“z«Ƴ—¿å³BRضˆœWlâþäą`“]Z£Tc— ĹGµ¶H™m@_©—kŒ‰¾xĨ‡ôȉðX«½đCIbćqK³Á‹Äš¬OAwã»aLʼn‡ËĥW[“ÂGI—ÂNxij¤D¢ŽîĎÎB§°_JœGsƒ¥E@…¤uć…P‘å†cuMuw¢BI¿‡]zG¹guĮck\\_" 351 | ] 352 | ], 353 | "encodeOffsets": [ 354 | [[123250, 27563]], 355 | [[122541, 27268]], 356 | [[123020, 27189]], 357 | [[122916, 27125]], 358 | [[122887, 26845]], 359 | [[122808, 26762]], 360 | [[122568, 25912]], 361 | [[122778, 26197]], 362 | [[122515, 26757]], 363 | [[122816, 26587]], 364 | [[123388, 27005]], 365 | [[122450, 26243]], 366 | [[122578, 25962]], 367 | [[121255, 25103]], 368 | [[120987, 24903]], 369 | [[122339, 25802]], 370 | [[121042, 25093]], 371 | [[122439, 26024]] 372 | ] 373 | } 374 | }, 375 | { 376 | "type": "Feature", 377 | "id": "360000", 378 | "properties": { 379 | "id": "360000", 380 | "cp": [115.592151, 27.676493], 381 | "name": "江西", 382 | "childNum": 1 383 | }, 384 | "geometry": { 385 | "type": "Polygon", 386 | "coordinates": [ 387 | "@@ĢĨƐgÂMD~ņªe^\\^§„ý©j׍cZ†Ø¨zdÒa¶ˆlҍJŒìõ`oz÷@¤u޸´†ôęöY¼‰HČƶajlÞƩ¥éZ[”|h}^U Œ ¥p„ĄžƦO lt¸Æ €Q\\€ŠaÆ|CnÂOjt­ĚĤd’ÈŒF`’¶„@Ð딠¦ōҞ¨Sêv†HĢûXD®…QgėWiØPÞìºr¤dž€NĠ¢l–•ĄtZoœCƞÔºCxrpĠV®Ê{f_Y`_ƒeq’’®Aot`@o‚DXfkp¨|Šs¬\\D‘ÄSfè©Hn¬…^DhÆyøJh“ØxĢĀLʈ„ƠPżċĄwȠ̦G®ǒĤäTŠÆ~ĦwŠ«|TF¡Šn€c³Ïå¹]ĉđxe{ÎӐ†vOEm°BƂĨİ|G’vz½ª´€H’àp”eJ݆Qšxn‹ÀŠW­žEµàXÅĪt¨ÃĖrÄwÀFÎ|ňÓMå¼ibµ¯»åDT±m[“r«_gŽmQu~¥V\\OkxtL E¢‹ƒ‘Ú^~ýê‹Pó–qo슱_Êw§ÑªåƗ⼋mĉŹ‹¿NQ“…YB‹ąrwģcÍ¥B•Ÿ­ŗÊcØiI—žƝĿuŒqtāwO]‘³YCñTeɕš‹caub͈]trlu€ī…B‘ПGsĵıN£ï—^ķqss¿FūūV՟·´Ç{éĈý‰ÿ›OEˆR_ŸđûIċâJh­ŅıN‘ȩĕB…¦K{Tk³¡OP·wn—µÏd¯}½TÍ«YiµÕsC¯„iM•¤™­•¦¯P|ÿUHv“he¥oFTu‰õ\\ŽOSs‹MòđƇiaºćXŸĊĵà·çhƃ÷ǜ{‘ígu^›đg’m[×zkKN‘¶Õ»lčÓ{XSƉv©_ÈëJbVk„ĔVÀ¤P¾ºÈMÖxlò~ªÚàGĂ¢B„±’ÌŒK˜y’áV‡¼Ã~­…`g›ŸsÙfI›Ƌlę¹e|–~udjˆuTlXµf`¿JdŠ[\\˜„L‚‘²" 388 | ], 389 | "encodeOffsets": [[116689, 26234]] 390 | } 391 | }, 392 | { 393 | "type": "Feature", 394 | "id": "370000", 395 | "properties": { 396 | "id": "370000", 397 | "cp": [118.000923, 36.275807], 398 | "name": "山东", 399 | "childNum": 13 400 | }, 401 | "geometry": { 402 | "type": "MultiPolygon", 403 | "coordinates": [ 404 | ["@@Xjd]{K"], 405 | ["@@itbFHy"], 406 | ["@@HlGk"], 407 | ["@@T‚ŒGŸy"], 408 | ["@@K¬˜•‹U"], 409 | ["@@WdXc"], 410 | ["@@PtOs"], 411 | ["@@•LnXhc"], 412 | ["@@ppVƒu]Or"], 413 | ["@@cdzAUa"], 414 | ["@@udRhnCI‡"], 415 | ["@@ˆoIƒpR„"], 416 | [ 417 | "@@Ľč{fzƤî’Kš–ÎMĮ]†—ZFˆ½Y]â£ph’™š¶¨râøÀ†ÎǨ¤^ºÄ”Gzˆ~grĚĜlĞÆ„LĆdž¢Îo¦–cv“Kb€gr°Wh”mZp ˆL]LºcU‰Æ­n”żĤÌǜbAnrOAœ´žȊcÀbƦUØrĆUÜøœĬƞ†š˜Ez„VL®öØBkŖÝĐ˹ŧ̄±ÀbÎɜnb²ĦhņBĖ›žįĦåXćì@L¯´ywƕCéõė ƿ¸‘lµ¾Z|†ZWyFYŸ¨Mf~C¿`€à_RÇzwƌfQnny´INoƬˆèôº|sT„JUš›‚L„îVj„ǎ¾Ē؍‚Dz²XPn±ŴPè¸ŔLƔÜƺ_T‘üÃĤBBċȉöA´fa„˜M¨{«M`‡¶d¡ô‰Ö°šmȰBÔjjŒ´PM|”c^d¤u•ƒ¤Û´Œä«ƢfPk¶Môlˆ]Lb„}su^ke{lC‘…M•rDŠÇ­]NÑFsmoõľH‰yGă{{çrnÓE‰‹ƕZGª¹Fj¢ïW…uøCǷ돡ąuhÛ¡^Kx•C`C\\bÅxì²ĝÝ¿_N‰īCȽĿåB¥¢·IŖÕy\\‡¹kx‡Ã£Č×GDyÕ¤ÁçFQ¡„KtŵƋ]CgÏAùSed‡cÚź—ŠuYfƒyMmhUWpSyGwMPqŀ—›Á¼zK›¶†G•­Y§Ëƒ@–´śÇµƕBmœ@Io‚g——Z¯u‹TMx}C‘‰VK‚ï{éƵP—™_K«™pÛÙqċtkkù]gŽ‹Tğwo•ɁsMõ³ă‡AN£™MRkmEʕč™ÛbMjÝGu…IZ™—GPģ‡ãħE[iµBEuŸDPԛ~ª¼ętŠœ]ŒûG§€¡QMsğNPŏįzs£Ug{đJĿļā³]ç«Qr~¥CƎÑ^n¶ÆéÎR~ݏY’I“] P‰umŝrƿ›‰›Iā‹[x‰edz‹L‘¯v¯s¬ÁY…~}…ťuٌg›ƋpÝĄ_ņī¶ÏSR´ÁP~ž¿Cyžċßdwk´Ss•X|t‰`Ä Èð€AªìÎT°¦Dd–€a^lĎDĶÚY°Ž`ĪŴǒˆ”àŠv\\ebŒZH„ŖR¬ŢƱùęO•ÑM­³FۃWp[ƒ" 418 | ] 419 | ], 420 | "encodeOffsets": [ 421 | [[123806, 39303]], 422 | [[123821, 39266]], 423 | [[123742, 39256]], 424 | [[123702, 39203]], 425 | [[123649, 39066]], 426 | [[123847, 38933]], 427 | [[123580, 38839]], 428 | [[123894, 37288]], 429 | [[123043, 36624]], 430 | [[123344, 38676]], 431 | [[123522, 38857]], 432 | [[123628, 38858]], 433 | [[118260, 36742]] 434 | ] 435 | } 436 | }, 437 | { 438 | "type": "Feature", 439 | "id": "410000", 440 | "properties": { 441 | "id": "410000", 442 | "cp": [113.665412, 33.757975], 443 | "name": "河南", 444 | "childNum": 1 445 | }, 446 | "geometry": { 447 | "type": "Polygon", 448 | "coordinates": [ 449 | "@@•ýL™ùµP³swIÓxcŢĞð†´E®žÚPt†ĴXØx¶˜@«ŕŕQGƒ‹Yfa[şu“ßǩ™đš_X³ijÕčC]kbc•¥CS¯ëÍB©÷‹–³­Siˆ_}m˜YTtž³xlàcȂzÀD}ÂOQ³ÐTĨ¯†ƗòËŖ[hœł‹Ŧv~††}ÂZž«¤lPǕ£ªÝŴÅR§ØnhcŒtâk‡nύ­ľŹUÓÝdKuķ‡I§oTũÙďkęĆH¸ÓŒ\\ăŒ¿PcnS{wBIvɘĽ[GqµuŸŇôYgûƒZcaŽ©@½Õǽys¯}lgg@­C\\£as€IdÍuCQñ[L±ęk·‹ţb¨©kK—’»›KC²‘òGKmĨS`ƒ˜UQ™nk}AGē”sqaJ¥ĐGR‰ĎpCuÌy ã iMc”plk|tRk†ðœev~^‘´†¦ÜŽSí¿_iyjI|ȑ|¿_»d}qŸ^{“Ƈdă}Ÿtqµ`Ƴĕg}V¡om½fa™Ço³TTj¥„tĠ—Ry”K{ùÓjuµ{t}uËR‘iŸvGŠçJFjµŠÍyqΘàQÂFewixGw½Yŷpµú³XU›½ġy™łå‰kÚwZXˆ·l„¢Á¢K”zO„Λ΀jc¼htoDHr…|­J“½}JZ_¯iPq{tę½ĕ¦Zpĵø«kQ…Ťƒ]MÛfaQpě±ǽ¾]u­Fu‹÷nƒ™čįADp}AjmcEǒaª³o³ÆÍSƇĈÙDIzˑ赟^ˆKLœ—i—Þñ€[œƒaA²zz‰Ì÷Dœ|[šíijgf‚ÕÞd®|`ƒĆ~„oĠƑô³Ŋ‘D×°¯CsŠøÀ«ì‰UMhTº¨¸ǡîS–Ô„DruÂÇZ•ÖEŽ’vPZ„žW”~؋ÐtĄE¢¦Ðy¸bŠô´oŬ¬Ž²Ês~€€]®tªašpŎJ¨Öº„_ŠŔ–`’Ŗ^Ѝ\\Ĝu–”~m²Ƹ›¸fW‰ĦrƔ}Î^gjdfÔ¡J}\\n C˜¦þWxªJRÔŠu¬ĨĨmF†dM{\\d\\ŠYÊ¢ú@@¦ª²SŠÜsC–}fNècbpRmlØ^g„d¢aÒ¢CZˆZxvÆ¶N¿’¢T@€uCœ¬^ĊðÄn|žlGl’™Rjsp¢ED}€Fio~ÔNŽ‹„~zkĘHVsDzßjƒŬŒŠŢ`Pûàl¢˜\\ÀœEhŽİgÞē X¼Pk–„|m" 450 | ], 451 | "encodeOffsets": [[118256, 37017]] 452 | } 453 | }, 454 | { 455 | "type": "Feature", 456 | "id": "420000", 457 | "properties": { 458 | "id": "420000", 459 | "cp": [113.298572, 30.684355], 460 | "name": "湖北", 461 | "childNum": 3 462 | }, 463 | "geometry": { 464 | "type": "MultiPolygon", 465 | "coordinates": [ 466 | ["@@AB‚"], 467 | ["@@lskt"], 468 | [ 469 | "@@¾«}{ra®pîÃ\\™›{øCŠËyyB±„b\\›ò˜Ý˜jK›‡L ]ĎĽÌ’JyÚCƈćÎT´Å´pb©È‘dFin~BCo°BĎĚømvŒ®E^vǾ½Ĝ²Ro‚bÜeNŽ„^ĺ£R†¬lĶ÷YoĖ¥Ě¾|sOr°jY`~I”¾®I†{GqpCgyl{‡£œÍƒÍyPL“¡ƒ¡¸kW‡xYlÙæŠšŁĢzœ¾žV´W¶ùŸo¾ZHxjwfx„GNÁ•³Xéæl¶‰EièIH‰ u’jÌQ~v|sv¶Ôi|ú¢Fh˜Qsğ¦ƒSiŠBg™ÐE^ÁÐ{–čnOÂȞUÎóĔ†ÊēIJ}Z³½Mŧïeyp·uk³DsѨŸL“¶_œÅuèw»—€¡WqÜ]\\‘Ò§tƗcÕ¸ÕFÏǝĉăxŻČƟO‡ƒKÉġÿ×wg”÷IÅzCg†]m«ªGeçÃTC’«[‰t§{loWeC@ps_Bp‘­r‘„f_``Z|ei¡—oċMqow€¹DƝӛDYpûs•–‹Ykıǃ}s¥ç³[§ŸcYЧHK„«Qy‰]¢“wwö€¸ïx¼ņ¾Xv®ÇÀµRĠЋžHMž±cÏd„ƒǍũȅȷ±DSyúĝ£ŤĀàtÖÿï[îb\\}pĭÉI±Ñy…¿³x¯N‰o‰|¹H™ÏÛm‹júË~Tš•u˜ęjCöAwě¬R’đl¯ Ñb­‰ŇT†Ŀ_[Œ‘IčĄʿnM¦ğ\\É[T·™k¹œ©oĕ@A¾w•ya¥Y\\¥Âaz¯ãÁ¡k¥ne£Ûw†E©Êō¶˓uoj_Uƒ¡cF¹­[Wv“P©w—huÕyBF“ƒ`R‹qJUw\\i¡{jŸŸEPïÿ½fć…QÑÀQ{ž‚°‡fLԁ~wXg—ītêݾ–ĺ‘Hdˆ³fJd]‹HJ²…E€ƒoU¥†HhwQsƐ»Xmg±çve›]Dm͂PˆoCc¾‹_h”–høYrŊU¶eD°Č_N~øĹĚ·`z’]Äþp¼…äÌQŒv\\rCŒé¾TnkžŐڀÜa‡“¼ÝƆ̶Ûo…d…ĔňТJq’Pb ¾|JŒ¾fXŠƐîĨ_Z¯À}úƲ‹N_ĒĊ^„‘ĈaŐyp»CÇĕKŠšñL³ŠġMŒ²wrIÒŭxjb[œžn«øœ˜—æˆàƒ ^²­h¯Ú€ŐªÞ¸€Y²ĒVø}Ā^İ™´‚LŠÚm„¥ÀJÞ{JVŒųÞŃx×sxxƈē ģMř–ÚðòIf–Ċ“Œ\\Ʈ±ŒdʧĘD†vČ_Àæ~DŒċ´A®µ†¨ØLV¦êHÒ¤" 470 | ] 471 | ], 472 | "encodeOffsets": [[[113712, 34000]], [[115612, 30507]], [[113649, 34054]]] 473 | } 474 | }, 475 | { 476 | "type": "Feature", 477 | "id": "430000", 478 | "properties": { "id": "430000", "cp": [111.782279, 28.09409], "name": "湖南", "childNum": 3 }, 479 | "geometry": { 480 | "type": "MultiPolygon", 481 | "coordinates": [ 482 | ["@@—n„FTs"], 483 | ["@@ßÅÆá‰½ÔXr—†CO™“…ËR‘ïÿĩ­TooQyšÓ[‹ŅBE¬–ÎÓXa„į§Ã¸G °ITxp‰úxÚij¥Ïš–̾ŠedžÄ©ĸG…œàGh‚€M¤–Â_U}Ċ}¢pczfŠþg¤€”ÇòAV‘‹M"], 484 | [ 485 | "@@©K—ƒA·³CQ±Á«³BUŠƑ¹AŠtćOw™D]ŒJiØSm¯b£‘ylƒ›X…HËѱH•«–‘C^õľA–Å§¤É¥„ïyuǙuA¢^{ÌC´­¦ŷJ£^[†“ª¿‡ĕ~•Ƈ…•N… skóā‡¹¿€ï]ă~÷O§­@—Vm¡‹Qđ¦¢Ĥ{ºjԏŽŒª¥nf´•~ÕoŸž×Ûą‹MąıuZœmZcÒ IJβSÊDŽŶ¨ƚƒ’CÖŎªQؼrŭŽ­«}NÏürʬŒmjr€@ĘrTW ­SsdHzƓ^ÇÂyUi¯DÅYlŹu{hTœ}mĉ–¹¥ě‰Dÿë©ıÓ[Oº£ž“¥ót€ł¹MՄžƪƒ`Pš…Di–ÛUоÅ‌ìˆU’ñB“È£ýhe‰dy¡oċ€`pfmjP~‚kZa…ZsÐd°wj§ƒ@€Ĵ®w~^‚kÀÅKvNmX\\¨a“”сqvíó¿F„¤¡@ũÑVw}S@j}¾«pĂr–ªg àÀ²NJ¶¶Dô…K‚|^ª†Ž°LX¾ŴäPᜣEXd›”^¶›IJÞܓ~‘u¸ǔ˜Ž›MRhsR…e†`ÄofIÔ\\Ø  i”ćymnú¨cj ¢»–GČìƊÿШXeĈ¾Oð Fi ¢|[jVxrIQŒ„_E”zAN¦zLU`œcªx”OTu RLÄ¢dV„i`p˔vŎµªÉžF~ƒØ€d¢ºgİàw¸Áb[¦Zb¦–z½xBĖ@ªpº›šlS¸Ö\\Ĕ[N¥ˀmĎă’J\\‹ŀ`€…ňSڊĖÁĐiO“Ĝ«BxDõĚiv—ž–S™Ì}iùŒžÜnšÐºGŠ{Šp°M´w†ÀÒzJ²ò¨ oTçüöoÛÿñŽőФ‚ùTz²CȆȸǎۃƑÐc°dPÎŸğ˶[Ƚu¯½WM¡­Éž“’B·rížnZŸÒ `‡¨GA¾\\pē˜XhÆRC­üWGġu…T靧Ŏѝ©ò³I±³}_‘‹EÃħg®ęisÁPDmÅ{‰b[Rşs·€kPŸŽƥƒóRo”O‹ŸVŸ~]{g\\“êYƪ¦kÝbiċƵŠGZ»Ěõ…ó·³vŝž£ø@pyö_‹ëŽIkѵ‡bcѧy…×dY؎ªiþž¨ƒ[]f]Ņ©C}ÁN‡»hĻħƏ’ĩ" 486 | ] 487 | ], 488 | "encodeOffsets": [[[115640, 30489]], [[112543, 27312]], [[116690, 26230]]] 489 | } 490 | }, 491 | { 492 | "type": "Feature", 493 | "id": "440000", 494 | "properties": { 495 | "id": "440000", 496 | "cp": [113.280637, 23.125178], 497 | "name": "广东", 498 | "childNum": 24 499 | }, 500 | "geometry": { 501 | "type": "MultiPolygon", 502 | "coordinates": [ 503 | ["@@QdˆAua"], 504 | ["@@ƒlxDLo"], 505 | ["@@sbhNLo"], 506 | ["@@Ă āŸ"], 507 | ["@@WltO[["], 508 | ["@@Krœ]S"], 509 | ["@@e„„I]y"], 510 | ["@@I|„Mym"], 511 | ["@@ƒÛ³LSŒž¼Y"], 512 | ["@@nvºB–ëui©`¾"], 513 | ["@@zdšÛ›Jw®"], 514 | ["@@†°…¯"], 515 | ["@@a yAª¸ËJIx،@€ĀHAmßV¡o•fu•o"], 516 | ["@@šs‰ŗÃÔėAƁ›ZšÄ ~°ČP‚‹äh"], 517 | ["@@‹¶Ý’Ì‚vmĞh­ı‡Q"], 518 | ["@@HœŠdSjĒ¢D}war…“u«ZqadYM"], 519 | ["@@elŒ\\LqqU"], 520 | ["@@~rMo\\"], 521 | ["@@f„^ƒC"], 522 | ["@@øPªoj÷ÍÝħXČx”°Q¨ıXNv"], 523 | ["@@gÇƳˆŽˆ”oˆŠˆ[~tly"], 524 | ["@@E–ÆC¿‘"], 525 | ["@@OŽP"], 526 | [ 527 | "@@w‹†đóg‰™ĝ—[³‹¡VÙæÅöM̳¹pÁaËýý©D©Ü“JŹƕģGą¤{Ùū…ǘO²«BƱéA—Ò‰ĥ‡¡«BhlmtÃPµyU¯uc“d·w_bŝcīímGOŽ|KP’ȏ‡ŹãŝIŕŭŕ@Óoo¿ē‹±ß}Ž…ŭ‚ŸIJWÈCőâUâǙI›ğʼn©I›ijEׅÁ”³Aó›wXJþ±ÌŒÜӔĨ£L]ĈÙƺZǾĆĖMĸĤfŒÎĵl•ŨnȈ‘ĐtF”Š–FĤ–‚êk¶œ^k°f¶gŠŽœ}®Fa˜f`vXŲxl˜„¦–ÔÁ²¬ÐŸ¦pqÊ̲ˆi€XŸØRDÎ}†Ä@ZĠ’s„x®AR~®ETtĄZ†–ƈfŠŠHâÒÐA†µ\\S¸„^wĖkRzŠalŽŜ|E¨ÈNĀňZTŒ’pBh£\\ŒĎƀuXĖtKL–¶G|Ž»ĺEļĞ~ÜĢÛĊrˆO˜Ùîvd]nˆ¬VœÊĜ°R֟pM††–‚ƂªFbwžEÀˆ˜©Œž\\…¤]ŸI®¥D³|ˎ]CöAŤ¦…æ’´¥¸Lv¼€•¢ĽBaô–F~—š®²GÌҐEY„„œzk¤’°ahlV՞I^‹šCxĈPŽsB‰ƒºV‰¸@¾ªR²ĨN]´_eavSi‡vc•}p}Đ¼ƌkJœÚe thœ†_¸ ºx±ò_xN›Ë‹²‘@ƒă¡ßH©Ùñ}wkNÕ¹ÇO½¿£ĕ]ly_WìIžÇª`ŠuTÅxYĒÖ¼k֞’µ‚MžjJÚwn\\h‘œĒv]îh|’È›Ƅøègž¸Ķß ĉĈWb¹ƀdéƌNTtP[ŠöSvrCZžžaGuœbo´ŖÒÇА~¡zCI…özx¢„Pn‹•‰Èñ @ŒĥÒ¦†]ƞŠV}³ăĔñiiÄÓVépKG½Ä‘ÓávYo–C·sit‹iaÀy„ŧΡÈYDÑům}‰ý|m[węõĉZÅxUO}÷N¹³ĉo_qtă“qwµŁYلǝŕ¹tïÛUïmRCº…ˆĭ|µ›ÕÊK™½R‘ē ó]‘–GªęAx–»HO£|ām‡¡diď×YïYWªʼnOeÚtĐ«zđ¹T…ā‡úE™á²\\‹ķÍ}jYàÙÆſ¿Çdğ·ùTßÇţʄ¡XgWÀLJğ·¿ÃˆOj YÇ÷Qě‹i" 528 | ] 529 | ], 530 | "encodeOffsets": [ 531 | [[117381, 22988]], 532 | [[116552, 22934]], 533 | [[116790, 22617]], 534 | [[116973, 22545]], 535 | [[116444, 22536]], 536 | [[116931, 22515]], 537 | [[116496, 22490]], 538 | [[116453, 22449]], 539 | [[113301, 21439]], 540 | [[118726, 21604]], 541 | [[118709, 21486]], 542 | [[113210, 20816]], 543 | [[115482, 22082]], 544 | [[113171, 21585]], 545 | [[113199, 21590]], 546 | [[115232, 22102]], 547 | [[115739, 22373]], 548 | [[115134, 22184]], 549 | [[113056, 21175]], 550 | [[119573, 21271]], 551 | [[119957, 24020]], 552 | [[115859, 22356]], 553 | [[116561, 22649]], 554 | [[116285, 22746]] 555 | ] 556 | } 557 | }, 558 | { 559 | "type": "Feature", 560 | "id": "450000", 561 | "properties": { "id": "450000", "cp": [108.320004, 22.82402], "name": "广西", "childNum": 2 }, 562 | "geometry": { 563 | "type": "MultiPolygon", 564 | "coordinates": [ 565 | ["@@H– TQ§•A"], 566 | [ 567 | "@@ĨʪƒLƒƊDÎĹĐCǦė¸zÚGn£¾›rªŀÜt¬@֛ڈSx~øOŒ˜ŶÐÂæȠ\\„ÈÜObĖw^oބLf¬°bI lTØB̈F£Ć¹gñĤaY“t¿¤VSñœK¸¤nM†¼‚JE±„½¸šŠño‹ÜCƆæĪ^ŠĚQÖ¦^‡ˆˆf´Q†üÜʝz¯šlzUĺš@쇀p¶n]sxtx¶@„~ÒĂJb©gk‚{°‚~c°`ԙ¬rV\\“la¼¤ôá`¯¹LC†ÆbŒxEræO‚v[H­˜„[~|aB£ÖsºdAĐzNÂðsŽÞƔ…Ĥªbƒ–ab`ho¡³F«èVloޤ™ÔRzpp®SŽĪº¨ÖƒºN…ij„d`’a”¦¤F³ºDÎńĀìŠCžĜº¦Ċ•~nS›|gźvZkCÆj°zVÈÁƔ]LÊFZg…čP­kini«‹qǀcz͔Y®¬Ů»qR×ō©DՄ‘§ƙǃŵTÉĩ±ŸıdÑnYY›IJvNĆÌØÜ Öp–}e³¦m‹©iÓ|¹Ÿħņ›|ª¦QF¢Â¬ʖovg¿em‡^ucà÷gՎuŒíÙćĝ}FϼĹ{µHK•sLSđƃr‹č¤[Ag‘oS‹ŇYMÿ§Ç{Fśbky‰lQxĕƒ]T·¶[B…ÑÏGáşşƇe€…•ăYSs­FQ}­Bƒw‘tYğÃ@~…C̀Q ×W‡j˱rÉ¥oÏ ±«ÓÂ¥•ƒ€k—ŽwWűŒmcih³K›~‰µh¯e]lµ›él•E쉕E“ďs‡’mǖŧē`ãògK_ÛsUʝ“ćğ¶hŒöŒO¤Ǜn³Žc‘`¡y‹¦C‘ez€YŠwa™–‘[ďĵűMę§]X˜Î_‚훘Û]é’ÛUćİÕBƣ±…dƒy¹T^džûÅÑŦ·‡PĻþÙ`K€¦˜…¢ÍeœĥR¿Œ³£[~Œäu¼dl‰t‚†W¸oRM¢ď\\zœ}Æzdvň–{ÎXF¶°Â_„ÒÂÏL©Ö•TmuŸ¼ãl‰›īkiqéfA„·Êµ\\őDc¥ÝF“y›Ôć˜c€űH_hL܋êĺШc}rn`½„Ì@¸¶ªVLŒŠhŒ‹\\•Ţĺk~ŽĠið°|gŒtTĭĸ^x‘vK˜VGréAé‘bUu›MJ‰VÃO¡…qĂXËS‰ģãlýàŸ_ju‡YÛÒB†œG^˜é֊¶§ŽƒEG”ÅzěƒƯ¤Ek‡N[kdåucé¬dnYpAyČ{`]þ¯T’bÜÈk‚¡Ġ•vŒàh„ÂƄ¢Jî¶²" 568 | ] 569 | ], 570 | "encodeOffsets": [[[111707, 21520]], [[107619, 25527]]] 571 | } 572 | }, 573 | { 574 | "type": "Feature", 575 | "id": "460000", 576 | "properties": { "id": "460000", "cp": [109.83119, 19.031971], "name": "海南", "childNum": 1 }, 577 | "geometry": { 578 | "type": "Polygon", 579 | "coordinates": [ 580 | "@@š¦Ŝil¢”XƦ‘ƞò–ïè§ŞCêɕrŧůÇąĻõ™·ĉ³œ̅kÇm@ċȧƒŧĥ‰Ľʉ­ƅſ“ȓÒ˦ŝE}ºƑ[ÍĜȋ gÎfǐÏĤ¨êƺ\\Ɔ¸ĠĎvʄȀœÐ¾jNðĀÒRŒšZdž™zÐŘΰH¨Ƣb²_Ġ " 581 | ], 582 | "encodeOffsets": [[112750, 20508]] 583 | } 584 | }, 585 | { 586 | "type": "Feature", 587 | "id": "510000", 588 | "properties": { 589 | "id": "510000", 590 | "cp": [104.065735, 30.659462], 591 | "name": "四川", 592 | "childNum": 2 593 | }, 594 | "geometry": { 595 | "type": "MultiPolygon", 596 | "coordinates": [ 597 | ["@@LqKr"], 598 | [ 599 | "@@Š[ĻéV£ž_ţġñpG •réÏ·~ąSfy×͂·ºſƽiÍıƣıĻmHH}siaX@iǰÁÃ×t«ƒ­Tƒ¤J–JJŒyJ•ÈŠ`Ohߦ¡uËhIyCjmÿw…ZG……Ti‹SˆsO‰žB²ŸfNmsPaˆ{M{ŠõE‘^Hj}gYpaeuž¯‘oáwHjÁ½M¡pM“–uå‡mni{fk”\\oƒÎqCw†EZ¼K›ĝŠƒAy{m÷L‡wO×SimRI¯rK™õBS«sFe‡]fµ¢óY_ÆPRcue°Cbo׌bd£ŌIHgtrnyPt¦foaXďx›lBowz‹_{ÊéWiêE„GhܸºuFĈIxf®Ž•Y½ĀǙ]¤EyŸF²ċ’w¸¿@g¢§RGv»–áŸW`ÃĵJwi]t¥wO­½a[׈]`Ãi­üL€¦LabbTÀå’c}Íh™Æhˆ‹®BH€î|Ék­¤S†y£„ia©taį·Ɖ`ō¥Uh“O…ƒĝLk}©Fos‰´›Jm„µlŁu—…ø–nÑJWΪ–YÀïAetTžŅ‚ӍG™Ë«bo‰{ıwodƟ½ƒžOġܑµxàNÖ¾P²§HKv¾–]|•B‡ÆåoZ`¡Ø`ÀmºĠ~ÌЧnDž¿¤]wğ@sƒ‰rğu‰~‘Io”[é±¹ ¿žſđӉ@q‹gˆ¹zƱřaí°KtǤV»Ã[ĩǭƑ^ÇÓ@ỗs›Zϕ‹œÅĭ€Ƌ•ěpwDóÖሯneQˌq·•GCœýS]xŸ·ý‹q³•O՜Œ¶Qzßti{ř‰áÍÇWŝŭñzÇW‹pç¿JŒ™‚Xœĩè½cŒF–ÂLiVjx}\\N†ŇĖ¥Ge–“JA¼ÄHfÈu~¸Æ«dE³ÉMA|b˜Ò…˜ćhG¬CM‚õŠ„ƤąAvƒüV€éŀ‰_V̳ĐwQj´·ZeÈÁ¨X´Æ¡Qu·»Ÿ“˜ÕZ³ġqDo‰y`L¬gdp°şŠp¦ėìÅĮZްIä”h‚‘ˆzŠĵœf²å ›ĚрKp‹IN|‹„Ñz]ń……·FU×é»R³™MƒÉ»GM«€ki€™ér™}Ã`¹ăÞmȝnÁîRǀ³ĜoİzŔwǶVÚ£À]ɜ»ĆlƂ²Ġ…þTº·àUȞÏʦ¶†I’«dĽĢdĬ¿–»Ĕ׊h\\c¬†ä²GêëĤł¥ÀǿżÃÆMº}BÕĢyFVvw–ˆxBèĻĒ©Ĉ“tCĢɽŠȣ¦āæ·HĽî“ôNԓ~^¤Ɗœu„œ^s¼{TA¼ø°¢İªDè¾Ň¶ÝJ‘®Z´ğ~Sn|ªWÚ©òzPOȸ‚bð¢|‹øĞŠŒœŒQìÛÐ@Ğ™ǎRS¤Á§d…i“´ezÝúØã]Hq„kIŸþËQǦÃsǤ[E¬ÉŪÍxXƒ·ÖƁİlƞ¹ª¹|XÊwn‘ÆƄmÀêErĒtD®ċæcQƒ”E®³^ĭ¥©l}äQto˜ŖÜqƎkµ–„ªÔĻĴ¡@Ċ°B²Èw^^RsºT£ڿœQP‘JvÄz„^Đ¹Æ¯fLà´GC²‘dt˜­ĀRt¼¤ĦOðğfÔðDŨŁĞƘïžPȆ®âbMüÀXZ ¸£@Ś›»»QÉ­™]d“sÖ×_͖_ÌêŮPrĔĐÕGĂeZÜîĘqBhtO ¤tE[h|Y‹Ô‚ZśÎs´xº±UŒ’ñˆt|O’ĩĠºNbgþŠJy^dÂY Į„]Řz¦gC‚³€R`Šz’¢AjŒ¸CL„¤RÆ»@­Ŏk\\Ç´£YW}z@Z}‰Ã¶“oû¶]´^N‡Ò}èN‚ª–P˜Íy¹`S°´†ATe€VamdUĐwʄvĮÕ\\ƒu‹Æŗ¨Yp¹àZÂm™Wh{á„}WØǍ•Éüw™ga§áCNęÎ[ĀÕĪgÖɪX˜øx¬½Ů¦¦[€—„NΆL€ÜUÖ´òrÙŠxR^–†J˜k„ijnDX{Uƒ~ET{ļº¦PZc”jF²Ė@Žp˜g€ˆ¨“B{ƒu¨ŦyhoÚD®¯¢˜ WòàFΤ¨GDäz¦kŮPœġq˚¥À]€Ÿ˜eŽâÚ´ªKxī„Pˆ—Ö|æ[xäJÞĥ‚s’NÖ½ž€I†¬nĨY´®Ð—ƐŠ€mD™ŝuäđđEb…e’e_™v¡}ìęNJē}q”É埁T¯µRs¡M@}ůa†a­¯wvƉåZwž\\Z{åû^›" 600 | ] 601 | ], 602 | "encodeOffsets": [[[108815, 30935]], [[110617, 31811]]] 603 | } 604 | }, 605 | { 606 | "type": "Feature", 607 | "id": "520000", 608 | "properties": { 609 | "id": "520000", 610 | "cp": [106.713478, 26.578343], 611 | "name": "贵州", 612 | "childNum": 3 613 | }, 614 | "geometry": { 615 | "type": "MultiPolygon", 616 | "coordinates": [ 617 | ["@@†G\\†lY£‘in"], 618 | ["@@q‚|ˆ‚mc¯tχVSÎ"], 619 | [ 620 | "@@hÑ£Is‡NgßH†›HªķÃh_¹ƒ¡ĝħń¦uيùŽgS¯JHŸ|sÝÅtÁïyMDč»eÕtA¤{b\\}—ƒG®u\\åPFq‹wÅaD…žK°ºâ_£ùbµ”mÁ‹ÛœĹM[q|hlaªāI}тƒµ@swtwm^oµˆD鼊yV™ky°ÉžûÛR…³‚‡eˆ‡¥]RՋěħ[ƅåÛDpŒ”J„iV™™‰ÂF²I…»mN·£›LbÒYb—WsÀbŽ™pki™TZĄă¶HŒq`……ĥ_JŸ¯ae«ƒKpÝx]aĕÛPƒÇȟ[ÁåŵÏő—÷Pw}‡TœÙ@Õs«ĿÛq©½œm¤ÙH·yǥĘĉBµĨÕnđ]K„©„œá‹ŸG纍§Õßg‡ǗĦTèƤƺ{¶ÉHÎd¾ŚÊ·OÐjXWrãLyzÉAL¾ę¢bĶėy_qMĔąro¼hĊžw¶øV¤w”²Ĉ]ʚKx|`ź¦ÂÈdr„cȁbe¸›`I¼čTF´¼Óýȃr¹ÍJ©k_șl³´_pН`oÒh޶pa‚^ÓĔ}D»^Xyœ`d˜[Kv…JPhèhCrĂĚÂ^Êƌ wˆZL­Ġ£šÁbrzOIl’MM”ĪŐžËr×ÎeŦŽtw|Œ¢mKjSǘňĂStÎŦEtqFT†¾†E쬬ôxÌO¢Ÿ KгŀºäY†„”PVgŎ¦Ŋm޼VZwVlŒ„z¤…ž£Tl®ctĽÚó{G­A‡ŒÇgeš~Αd¿æaSba¥KKûj®_ć^\\ؾbP®¦x^sxjĶI_Ä X‚⼕Hu¨Qh¡À@Ëô}ޱžGNìĎlT¸ˆ…`V~R°tbÕĊ`¸úÛtπFDu€[ƒMfqGH·¥yA‰ztMFe|R‚_Gk†ChZeÚ°to˜v`x‹b„ŒDnÐ{E}šZ˜è€x—†NEފREn˜[Pv@{~rĆAB§‚EO¿|UZ~ì„Uf¨J²ĂÝÆ€‚sª–B`„s¶œfvö¦ŠÕ~dÔq¨¸º»uù[[§´sb¤¢zþFœ¢Æ…Àhˆ™ÂˆW\\ıŽËI݊o±ĭŠ£þˆÊs}¡R]ŒěƒD‚g´VG¢‚j±®è†ºÃmpU[Á›‘Œëº°r›ÜbNu¸}Žº¼‡`ni”ºÔXĄ¤¼Ôdaµ€Á_À…†ftQQgœR—‘·Ǔ’v”}Ýלĵ]µœ“Wc¤F²›OĩųãW½¯K‚©…]€{†LóµCIµ±Mß¿hŸ•©āq¬o‚½ž~@i~TUxŪÒ¢@ƒ£ÀEîôruń‚”“‚b[§nWuMÆLl¿]x}ij­€½" 621 | ] 622 | ], 623 | "encodeOffsets": [[[112158, 27383]], [[112105, 27474]], [[112095, 27476]]] 624 | } 625 | }, 626 | { 627 | "type": "Feature", 628 | "id": "530000", 629 | "properties": { 630 | "id": "530000", 631 | "cp": [101.512251, 24.740609], 632 | "name": "云南", 633 | "childNum": 1 634 | }, 635 | "geometry": { 636 | "type": "Polygon", 637 | "coordinates": [ 638 | "@@[„ùx½}ÑRH‘YīĺûsÍn‘iEoã½Ya²ė{c¬ĝg•ĂsA•ØÅwď‚õzFjw}—«Dx¿}UũlŸê™@•HÅ­F‰¨ÇoJ´Ónũuą¡Ã¢pÒŌ“Ø TF²‚xa²ËX€‚cʋlHîAßËŁkŻƑŷÉ©h™W­æßU‡“Ës¡¦}•teèÆ¶StǀÇ}Fd£j‹ĈZĆÆ‹¤T‚č\\Dƒ}O÷š£Uˆ§~ŃG™‚åŃDĝ¸œTsd¶¶Bªš¤u¢ŌĎo~t¾ÍŶÒtD¦Ú„iôö‰€z›ØX²ghįh½Û±¯€ÿm·zR¦Ɵ`ªŊÃh¢rOԍ´£Ym¼èêf¯ŪĽn„†cÚbŒw\\zlvWžªâˆ ¦g–mĿBş£¢ƹřbĥkǫßeeZkÙIKueT»sVesb‘aĕ  ¶®dNœĄÄpªyސ¼—„³BE˜®l‡ŽGœŭCœǶwêżĔÂe„pÍÀQƞpC„–¼ŲÈ­AÎô¶R„ä’Q^Øu¬°š_Èôc´¹ò¨P΢hlϦ´Ħ“Æ´sâDŽŲPnÊD^¯°’Upv†}®BP̪–jǬx–Söwlfòªv€qĸ|`H€­viļ€ndĜ­Ćhň•‚em·FyށqóžSᝑ³X_ĞçêtryvL¤§z„¦c¦¥jnŞk˜ˆlD¤øz½ĜàžĂŧMÅ|áƆàÊcðÂF܎‚áŢ¥\\\\º™İøÒÐJĴ‡„îD¦zK²ǏÎEh~’CD­hMn^ÌöÄ©ČZÀžaü„fɭyœpį´ěFűk]Ôě¢qlÅĆÙa¶~Äqššê€ljN¬¼H„ÊšNQ´ê¼VظE††^ŃÒyŒƒM{ŒJLoÒœęæŸe±Ķ›y‰’‡gã“¯JYÆĭĘëo¥Š‰o¯hcK«z_pŠrC´ĢÖY”—¼ v¸¢RŽÅW³Â§fǸYi³xR´ďUˊ`êĿU„û€uĆBƒƣö‰N€DH«Ĉg†——Ñ‚aB{ÊNF´¬c·Åv}eÇÃGB»”If•¦HňĕM…~[iwjUÁKE•Ž‹¾dĪçW›šI‹èÀŒoÈXòyŞŮÈXâÎŚŠj|àsRy‹µÖ›–Pr´þŒ ¸^wþTDŔ–Hr¸‹žRÌmf‡żÕâCôox–ĜƌÆĮŒ›Ð–œY˜tâŦÔ@]ÈǮƒ\\μģUsȯLbîƲŚºyh‡rŒŠ@ĒԝƀŸÀ²º\\êp“’JŠ}ĠvŠqt„Ġ@^xÀ£È†¨mËÏğ}n¹_¿¢×Y_æpˆÅ–A^{½•Lu¨GO±Õ½ßM¶w’ÁĢۂP‚›Ƣ¼pcIJxŠ|ap̬HšÐŒŊSfsðBZ¿©“XÏÒK•k†÷Eû¿‰S…rEFsÕūk”óVǥʼniTL‚¡n{‹uxţÏh™ôŝ¬ğōN“‘NJkyPaq™Âğ¤K®‡YŸxÉƋÁ]āęDqçgOg†ILu—\\_gz—]W¼ž~CÔē]bµogpў_oď`´³Țkl`IªºÎȄqÔþž»E³ĎSJ»œ_f·‚adÇqƒÇc¥Á_Źw{™L^ɱćx“U£µ÷xgĉp»ĆqNē`rĘzaĵĚ¡K½ÊBzyäKXqiWPÏɸ½řÍcÊG|µƕƣG˛÷Ÿk°_^ý|_zċBZocmø¯hhcæ\\lˆMFlư£Ĝ„ÆyH“„F¨‰µêÕ]—›HA…àӄ^it `þßäkŠĤÎT~Wlÿ¨„ÔPzUC–NVv [jâôDôď[}ž‰z¿–msSh‹¯{jïğl}šĹ[–őŒ‰gK‹©U·µË@¾ƒm_~q¡f¹…ÅË^»‘f³ø}Q•„¡Ö˳gͱ^ǁ…\\ëÃA_—¿bW›Ï[¶ƛ鏝£F{īZgm@|kHǭƁć¦UĔťƒ×ë}ǝƒeďºȡȘÏíBə£āĘPªij¶“ʼnÿ‡y©n‰ď£G¹¡I›Š±LÉĺÑdĉ܇W¥˜‰}g˜Á†{aqÃ¥aŠıęÏZ—ï`" 639 | ], 640 | "encodeOffsets": [[104636, 22969]] 641 | } 642 | }, 643 | { 644 | "type": "Feature", 645 | "id": "540000", 646 | "properties": { "id": "540000", "cp": [89.132212, 30.860361], "name": "西藏", "childNum": 1 }, 647 | "geometry": { 648 | "type": "Polygon", 649 | "coordinates": [ 650 | "@@hžľxŽŖ‰xƒÒVކºÅâAĪÝȆµę¯Ňa±r_w~uSÕň‘qOj]ɄQ…£Z……UDûoY’»©M[‹L¼qãË{V͕çWViŽ]ë©Ä÷àyƛh›ÚU°ŒŒa”d„cQƒ~Mx¥™cc¡ÙaSyF—ցk­ŒuRýq¿Ôµ•QĽ³aG{¿FµëªéĜÿª@¬·–K‰·àariĕĀ«V»Ŷ™Ĵū˜gèLǴŇƶaf‹tŒèBŚ£^Šâ†ǐÝ®–šM¦ÁǞÿ¬LhŸŽJ¾óƾƺcxw‹f]Y…´ƒ¦|œQLn°aœdĊ…œ\\¨o’œǀÍŎœ´ĩĀd`tÊQŞŕ|‚¨C^©œĈ¦„¦ÎJĊ{ŽëĎjª²rЉšl`¼Ą[t|¦St辉PŒÜK¸€d˜Ƅı]s¤—î_v¹ÎVòŦj˜£Əsc—¬_Ğ´|٘¦Avަw`ăaÝaa­¢e¤ı²©ªSªšÈMĄwžÉØŔì@T‘¤—Ę™\\õª@”þo´­xA s”ÂtŎKzó´ÇĊµ¢rž^nĊ­Æ¬×üGž¢‚³ {âĊ]š™G‚~bÀgVjzlhǶf€žOšfdЉªB]pj„•TO–tĊ‚n¤}®¦ƒČ¥d¢¼»ddš”Y¼Žt—¢eȤJ¤}Ǿ¡°§¤AГlc@ĝ”sªćļđAç‡wx•UuzEÖġ~AN¹ÄÅȀݦ¿ģŁéì±H…ãd«g[؉¼ēÀ•cīľġ¬cJ‘µ…ÐʥVȝ¸ßS¹†ý±ğkƁ¼ą^ɛ¤Ûÿ‰b[}¬ōõÃ]ËNm®g@•Bg}ÍF±ǐyL¥íCˆƒIij€Ï÷њį[¹¦[⚍EÛïÁÉdƅß{âNÆāŨߝ¾ě÷yC£‡k­´ÓH@¹†TZ¥¢įƒ·ÌAЧ®—Zc…v½ŸZ­¹|ŕWZqgW“|ieZÅYVӁqdq•bc²R@†c‡¥Rã»Ge†ŸeƃīQ•}J[ғK…¬Ə|o’ėjġĠÑN¡ð¯EBčnwôɍėªƒ²•CλŹġǝʅįĭạ̃ūȹ]ΓͧgšsgȽóϧµǛ†ęgſ¶ҍć`ĘąŌJޚä¤rÅň¥ÖÁUětęuůÞiĊÄÀ\\Æs¦ÓRb|Â^řÌkÄŷ¶½÷‡f±iMݑ›‰@ĥ°G¬ÃM¥n£Øą‚ğ¯ß”§aëbéüÑOčœk£{\\‘eµª×M‘šÉfm«Ƒ{Å׃Gŏǩãy³©WÑăû‚··‘Q—òı}¯ã‰I•éÕÂZ¨īès¶ZÈsŽæĔTŘvŽgÌsN@îá¾ó@‰˜ÙwU±ÉT廣TđŸWxq¹Zo‘b‹s[׌¯cĩv‡Œėŧ³BM|¹k‰ªħ—¥TzNYnݍßpęrñĠĉRS~½ŠěVVе‚õ‡«ŒM££µB•ĉ¥áºae~³AuĐh`Ü³ç@BۘïĿa©|z²Ý¼D”£à貋ŸƒIƒû›I ā€óK¥}rÝ_Á´éMaň¨€~ªSĈ½Ž½KÙóĿeƃÆBŽ·¬ën×W|Uº}LJrƳ˜lŒµ`bÔ`QˆˆÐÓ@s¬ñIŒÍ@ûws¡åQÑßÁ`ŋĴ{Ī“T•ÚÅTSij‚‹Yo|Ç[ǾµMW¢ĭiÕØ¿@˜šMh…pÕ]j†éò¿OƇĆƇp€êĉâlØw–ěsˆǩ‚ĵ¸c…bU¹ř¨WavquSMzeo_^gsÏ·¥Ó@~¯¿RiīB™Š\\”qTGªÇĜçPoŠÿfñòą¦óQīÈáP•œābß{ƒZŗĸIæÅ„hnszÁCËìñšÏ·ąĚÝUm®ó­L·ăU›Èíoù´Êj°ŁŤ_uµ^‘°Œìǖ@tĶĒ¡Æ‡M³Ģ«˜İĨÅ®ğ†RŽāð“ggheÆ¢z‚Ê©Ô\\°ÝĎz~ź¤Pn–MĪÖB£Ÿk™n鄧żćŠ˜ĆK„ǰ¼L¶è‰âz¨u¦¥LDĘz¬ýÎmĘd¾ß”Fz“hg²™Fy¦ĝ¤ċņbΛ@y‚Ąæm°NĮZRÖíŽJ²öLĸÒ¨Y®ƌÐV‰à˜tt_ڀÂyĠzž]Ţh€zĎ{†ĢX”ˆc|šÐqŽšfO¢¤ög‚ÌHNŽ„PKŖœŽ˜Uú´xx[xˆvĐCûŠìÖT¬¸^}Ìsòd´_އKgžLĴ…ÀBon|H@–Êx˜—¦BpŰˆŌ¿fµƌA¾zLjRxжF”œkĄźRzŀˆ~¶[”´Hnª–VƞuĒ­È¨ƎcƽÌm¸ÁÈM¦x͊ëÀxdžB’šú^´W†£–d„kɾĬpœw‚˂ØɦļĬIŚœÊ•n›Ŕa¸™~J°î”lɌxĤÊÈðhÌ®‚g˜T´øŽàCˆŽÀ^ªerrƘdž¢İP|Ė ŸWœªĦ^¶´ÂL„aT±üWƜ˜ǀRšŶUńšĖ[QhlLüA†‹Ü\\†qR›Ą©" 651 | ], 652 | "encodeOffsets": [[90849, 37210]] 653 | } 654 | }, 655 | { 656 | "type": "Feature", 657 | "id": "610000", 658 | "properties": { 659 | "id": "610000", 660 | "cp": [108.948024, 34.263161], 661 | "name": "陕西", 662 | "childNum": 1 663 | }, 664 | "geometry": { 665 | "type": "Polygon", 666 | "coordinates": [ 667 | "@@˜p¢—ȮµšûG™Ħ}Ħšðǚ¶òƄ€jɂz°{ºØkÈęâ¦jª‚Bg‚\\œċ°s¬Ž’]jžú ‚E”Ȍdž¬s„t‡”RˆÆdĠݎwܔ¸ôW¾ƮłÒ_{’Ìšû¼„jº¹¢GǪÒ¯ĘƒZ`ºŊƒecņąš~BÂgzpâēòYǠȰÌTΨÂWœ|fcŸă§uF—Œ@NŸ¢XLƒŠRMº[ğȣſï|¥J™kc`sʼnǷ’Y¹‹W@µ÷K…ãï³ÛIcñ·VȋڍÒķø©—þ¥ƒy‚ÓŸğęmWµÎumZyOŅƟĥÓ~sÑL¤µaŅY¦ocyZ{‰y c]{ŒTa©ƒ`U_Ěē£ωÊƍKù’K¶ȱÝƷ§{û»ÅÁȹÍéuij|¹cÑd‘ŠìUYƒŽO‘uF–ÕÈYvÁCqӃT•Ǣí§·S¹NgŠV¬ë÷Át‡°Dد’C´ʼnƒópģ}„ċcE˅FŸŸéGU¥×K…§­¶³B‹Č}C¿åċ`wġB·¤őcƭ²ő[Å^axwQO…ÿEËߌ•ĤNĔŸwƇˆÄŠńwĪ­Šo[„_KÓª³“ÙnK‰Çƒěœÿ]ď€ă_d©·©Ýŏ°Ù®g]±„Ÿ‡ß˜å›—¬÷m\\›iaǑkěX{¢|ZKlçhLt€Ňîŵ€œè[€É@ƉĄEœ‡tƇÏ˜³­ħZ«mJ…›×¾‘MtÝĦ£IwÄå\\Õ{‡˜ƒOwĬ©LÙ³ÙgBƕŀr̛ĢŭO¥lãyC§HÍ£ßEñŸX¡—­°ÙCgpťz‘ˆb`wI„vA|§”‡—hoĕ@E±“iYd¥OϹS|}F@¾oAO²{tfžÜ—¢Fǂ҈W²°BĤh^Wx{@„¬‚­F¸¡„ķn£P|ŸªĴ@^ĠĈæb–Ôc¶l˜Yi…–^Mi˜cϰÂ[ä€vï¶gv@À“Ĭ·lJ¸sn|¼u~a]’ÆÈtŌºJp’ƒþ£KKf~ЦUbyäIšĺãn‡Ô¿^­žŵMT–hĠܤko¼Ŏìąǜh`[tŒRd²IJ_œXPrɲ‰l‘‚XžiL§àƒ–¹ŽH˜°Ȧqº®QC—bA†„ŌJ¸ĕÚ³ĺ§ `d¨YjžiZvRĺ±öVKkjGȊĐePОZmļKÀ€‚[ŠŽ`ösìh†ïÎoĬdtKÞ{¬èÒÒBŒÔpIJÇĬJŊ¦±J«ˆY§‹@·pH€µàåVKe›pW†ftsAÅqC·¬ko«pHÆuK@oŸHĆۄķhx“e‘n›S³àǍrqƶRbzy€¸ËАl›¼EºpĤ¼Œx¼½~Ğ’”à@†ÚüdK^ˆmÌSj" 668 | ], 669 | "encodeOffsets": [[110234, 38774]] 670 | } 671 | }, 672 | { 673 | "type": "Feature", 674 | "id": "620000", 675 | "properties": { 676 | "id": "620000", 677 | "cp": [103.823557, 36.058039], 678 | "name": "甘肃", 679 | "childNum": 2 680 | }, 681 | "geometry": { 682 | "type": "MultiPolygon", 683 | "coordinates": [ 684 | ["@@VuUv"], 685 | [ 686 | "@@ũ‹EĠtt~nkh`Q‰¦ÅÄÜdw˜Ab×ĠąJˆ¤DüègĺqBqœj°lI¡ĨÒ¤úSHbš‡ŠjΑBаaZˆ¢KJŽ’O[|A£žDx}Nì•HUnrk„ kp€¼Y kMJn[aG‚áÚÏ[½rc†}aQxOgsPMnUs‡nc‹Z…ž–sKúvA›t„Þġ’£®ĀYKdnFwš¢JE°”Latf`¼h¬we|€Æ‡šbj}GA€·~WŽ”—`†¢MC¤tL©IJ°qdf”O‚“bÞĬ¹ttu`^ZúE`Œ[@„Æsîz®¡’C„ƳƜG²“R‘¢R’m”fŽwĸg܃‚ą G@pzJM½mŠhVy¸uÈÔO±¨{LfæU¶ßGĂq\\ª¬‡²I‚¥IʼnÈīoı‹ÓÑAçÑ|«LÝcspīðÍg…të_õ‰\\ĉñLYnĝg’ŸRǡÁiHLlõUĹ²uQjYi§Z_c¨Ÿ´ĹĖÙ·ŋI…ƒaBD˜­R¹ȥr—¯G•ºß„K¨jWk’ɱŠOq›Wij\\a­‹Q\\sg_ĆǛōëp»£lğۀgS•ŶN®À]ˆÓäm™ĹãJaz¥V}‰Le¤L„ýo‘¹IsŋÅÇ^‘Žbz…³tmEÁ´aйcčecÇN•ĊãÁ\\蝗dNj•]j†—ZµkÓda•ćå]ğij@ ©O{¤ĸm¢ƒE·®ƒ«|@Xwg]A챝‡XǁÑdzªc›wQÚŝñsÕ³ÛV_ýƒ˜¥\\ů¥©¾÷w—Ž©WÕÊĩhÿÖÁRo¸V¬âDb¨šhûx–Ê×nj~Zâƒg|šXÁnßYoº§ZÅŘvŒ[„ĭÖʃuďxcVbnUSf…B¯³_Tzº—ΕO©çMÑ~Mˆ³]µ^püµ”ŠÄY~y@X~¤Z³€[Èōl@®Å¼£QKƒ·Di‹¡By‘ÿ‰Q_´D¥hŗyƒ^ŸĭÁZ]cIzý‰ah¹MĪğP‘s{ò‡‹‘²Vw¹t³Ŝˁ[ŽÑ}X\\gsFŸ£sPAgěp×ëfYHāďÖqēŭOÏë“dLü•\\iŒ”t^c®šRʺ¶—¢H°mˆ‘rYŸ£BŸ¹čIoľu¶uI]vģSQ{ƒUŻ”Å}QÂ|̋°ƅ¤ĩŪU ęĄžÌZҞ\\v˜²PĔ»ƢNHƒĂyAmƂwVmž`”]ȏb•”H`‰Ì¢²ILvĜ—H®¤Dlt_„¢JJÄämèÔDëþgºƫ™”aʎÌrêYi~ ÎݤNpÀA¾Ĕ¼b…ð÷’Žˆ‡®‚”üs”zMzÖĖQdȨý†v§Tè|ªH’þa¸|šÐ ƒwKĢx¦ivr^ÿ ¸l öæfƟĴ·PJv}n\\h¹¶v†·À|\\ƁĚN´Ĝ€çèÁz]ġ¤²¨QÒŨTIl‡ªťØ}¼˗ƦvÄùØE‹’«Fï˛Iq”ōŒTvāÜŏ‚íÛߜÛV—j³âwGăÂíNOŠˆŠPìyV³ʼnĖýZso§HіiYw[߆\\X¦¥c]ÔƩÜ·«j‡ÐqvÁ¦m^ċ±R™¦΋ƈťĚgÀ»IïĨʗƮްƝ˜ĻþÍAƉſ±tÍEÕÞāNU͗¡\\ſčåÒʻĘm ƭÌŹöʥ’ëQ¤µ­ÇcƕªoIýˆ‰Iɐ_mkl³ă‰Ɠ¦j—¡Yz•Ňi–}Msßõ–īʋ —}ƒÁVmŸ_[n}eı­Uĥ¼‘ª•I{ΧDӜƻėoj‘qYhĹT©oūĶ£]ďxĩ‹ǑMĝ‰q`B´ƃ˺Ч—ç~™²ņj@”¥@đ´ί}ĥtPńǾV¬ufӃÉC‹tÓ̻‰…¹£G³€]ƖƾŎĪŪĘ̖¨ʈĢƂlɘ۪üºňUðǜȢƢż̌ȦǼ‚ĤŊɲĖ­Kq´ï¦—ºĒDzņɾªǀÞĈĂD†½ĄĎÌŗĞrôñnŽœN¼â¾ʄľԆ|DŽŽ֦ज़ȗlj̘̭ɺƅêgV̍ʆĠ·ÌĊv|ýĖÕWĊǎÞ´õ¼cÒÒBĢ͢UĜð͒s¨ňƃLĉÕÝ@ɛƯ÷¿Ľ­ĹeȏijëCȚDŲyê×Ŗyò¯ļcÂßY…tÁƤyAã˾J@ǝrý‹‰@¤…rz¸oP¹ɐÚyᐇHŸĀ[Jw…cVeȴϜ»ÈŽĖ}ƒŰŐèȭǢόĀƪÈŶë;Ñ̆ȤМľĮEŔ—ĹŊũ~ËUă{ŸĻƹɁύȩþĽvĽƓÉ@ē„ĽɲßǐƫʾǗĒpäWÐxnsÀ^ƆwW©¦cÅ¡Ji§vúF¶Ž¨c~c¼īŒeXǚ‹\\đ¾JŽwÀďksãA‹fÕ¦L}wa‚o”Z’‹D½†Ml«]eÒÅaɲáo½FõÛ]ĻÒ¡wYR£¢rvÓ®y®LF‹LzĈ„ôe]gx}•|KK}xklL]c¦£fRtív¦†PĤoH{tK" 687 | ] 688 | ], 689 | "encodeOffsets": [[[108619, 36299]], [[108589, 36341]]] 690 | } 691 | }, 692 | { 693 | "type": "Feature", 694 | "id": "630000", 695 | "properties": { "id": "630000", "cp": [96.778916, 35.623178], "name": "青海", "childNum": 2 }, 696 | "geometry": { 697 | "type": "MultiPolygon", 698 | "coordinates": [ 699 | ["@@InJm"], 700 | [ 701 | "@@CƒÆ½OŃĦsΰ~dz¦@@“Ņiš±è}ؘƄ˹A³r_ĞŠǒNΌĐw¤^ŬĵªpĺSZg’rpiƼĘԛ¨C|͖J’©Ħ»®VIJ~f\\m `Un„˜~ʌŸ•ĬàöNt•~ňjy–¢Zi˜Ɣ¥ĄŠk´nl`JʇŠJþ©pdƖ®È£¶ìRʦ‘źõƮËnŸʼėæÑƀĎ[‚˜¢VÎĂMÖÝÎF²sƊƀÎBļýƞ—¯ʘƭðħ¼Jh¿ŦęΌƇš¥²Q]Č¥nuÂÏriˆ¸¬ƪÛ^Ó¦d€¥[Wà…x\\ZŽjҕ¨GtpþYŊĕ´€zUO뇉P‰îMĄÁxH´á˜iÜUà›îÜՁĂÛSuŎ‹r“œJð̬EŒ‘FÁú×uÃÎkr“Ē{V}İ«O_ÌËĬ©ŽÓŧSRѱ§Ģ£^ÂyèçěM³Ƃę{[¸¿u…ºµ[gt£¸OƤĿéYŸõ·kŸq]juw¥Dĩƍ€õÇPéĽG‘ž©ã‡¤G…uȧþRcÕĕNy“yût“ˆ­‡ø‘†ï»a½ē¿BMoᣟÍj}éZËqbʍš“Ƭh¹ìÿÓAçãnIáI`ƒks£CG­ě˜Uy×Cy•…’Ÿ@¶ʡÊBnāzG„ơMē¼±O÷õJËĚăVŸĪũƆ£Œ¯{ËL½Ìzż“„VR|ĠTbuvJvµhĻĖH”Aëáa…­OÇðñęNw‡…œľ·L›mI±íĠĩPÉ×®ÿs—’cB³±JKßĊ«`…ađ»·QAmO’‘Vţéÿ¤¹SQt]]Çx€±¯A@ĉij¢Ó祖•ƒl¶ÅÛr—ŕspãRk~¦ª]Į­´“FR„åd­ČsCqđéFn¿Åƃm’Éx{W©ºƝºįkÕƂƑ¸wWūЩÈFž£\\tÈ¥ÄRÈýÌJ ƒlGr^×äùyÞ³fj”c†€¨£ÂZ|ǓMĝšÏ@ëÜőR‹›ĝ‰Œ÷¡{aïȷPu°ËXÙ{©TmĠ}Y³’­ÞIňµç½©C¡į÷¯B»|St»›]vƒųƒs»”}MÓ ÿʪƟǭA¡fs˜»PY¼c¡»¦c„ċ­¥£~msĉP•–Siƒ^o©A‰Šec‚™PeǵŽkg‚yUi¿h}aH™šĉ^|ᴟ¡HØûÅ«ĉ®]m€¡qĉ¶³ÈyôōLÁst“BŸ®wn±ă¥HSò뚣˜S’ë@לÊăxÇN©™©T±ª£IJ¡fb®ÞbŽb_Ą¥xu¥B—ž{łĝ³«`d˜Ɛt—¤ťiñžÍUuºí`£˜^tƃIJc—·ÛLO‹½Šsç¥Ts{ă\\_»™kϊ±q©čiìĉ|ÍIƒ¥ć¥›€]ª§D{ŝŖÉR_sÿc³Īō›ƿΑ›§p›[ĉ†›c¯bKm›R¥{³„Z†e^ŽŒwx¹dƽŽôIg §Mĕ ƹĴ¿—ǣÜ̓]‹Ý–]snåA{‹eŒƭ`ǻŊĿ\\ijŬű”YÂÿ¬jĖqŽßbЏ•L«¸©@ěĀ©ê¶ìÀEH|´bRľž–Ó¶rÀQþ‹vl®Õ‚E˜TzÜdb ˜hw¤{LR„ƒd“c‹b¯‹ÙVgœ‚ƜßzÃô쮍^jUèXΖ|UäÌ»rKŽ\\ŒªN‘¼pZCü†VY††¤ɃRi^rPҒTÖ}|br°qňb̰ªiƶGQ¾²„x¦PœmlŜ‘[Ĥ¡ΞsĦŸÔÏâ\\ªÚŒU\\f…¢N²§x|¤§„xĔsZPòʛ²SÐqF`ª„VƒÞŜĶƨVZŒÌL`ˆ¢dŐIqr\\oäõ–F礻Ŷ×h¹]Clـ\\¦ďÌį¬řtTӺƙgQÇÓHţĒ”´ÃbEÄlbʔC”|CˆŮˆk„Ʈ[ʼ¬ňœ´KŮÈΰÌζƶlð”ļA†TUvdTŠG†º̼ŠÔ€ŒsÊDԄveOg" 702 | ] 703 | ], 704 | "encodeOffsets": [[[105308, 37219]], [[95370, 40081]]] 705 | } 706 | }, 707 | { 708 | "type": "Feature", 709 | "id": "640000", 710 | "properties": { "id": "640000", "cp": [106.278179, 37.26637], "name": "宁夏", "childNum": 2 }, 711 | "geometry": { 712 | "type": "MultiPolygon", 713 | "coordinates": [ 714 | [ 715 | "@@KëÀęĞ«OęȿȕŸı]ʼn¡åįÕÔ«Ǵõƪ™ĚQÐZhv K°›öqÀѐS[ÃÖHƖčË‡nL]ûc…Ùß@‚“ĝ‘¾}w»»‹oģF¹œ»kÌÏ·{zPƒ§B­¢íyÅt@ƒ@áš]Yv_ssģ¼i߁”ĻL¾ġsKD£¡N_…“˜X¸}B~Haiˆ™Åf{«x»ge_bs“KF¯¡Ix™mELcÿZ¤­Ģ‘ƒÝœsuBLù•t†ŒYdˆmVtNmtOPhRw~bd…¾qÐ\\âÙH\\bImlNZŸ»loƒŸqlVm–Gā§~QCw¤™{A\\‘PKŸNY‡¯bF‡kC¥’sk‹Šs_Ã\\ă«¢ħkJi¯r›rAhĹûç£CU‡ĕĊ_ԗBixÅُĄnªÑaM~ħpOu¥sîeQ¥¤^dkKwlL~{L~–hw^‚ófćƒKyEŒ­K­zuÔ¡qQ¤xZÑ¢^ļöܾEpž±âbÊÑÆ^fk¬…NC¾‘Œ“YpxbK~¥Že֎ŒäBlt¿Đx½I[ĒǙŒWž‹f»Ĭ}d§dµùEuj¨‚IÆ¢¥dXªƅx¿]mtÏwßR͌X¢͎vÆzƂZò®ǢÌʆCrâºMÞzžÆMҔÊÓŊZľ–r°Î®Ȉmª²ĈUªĚøºˆĮ¦ÌĘk„^FłĬhĚiĀ˾iİbjÕ" 716 | ], 717 | ["@@mfwěwMrŢªv@G‰"] 718 | ], 719 | "encodeOffsets": [[[109366, 40242]], [[108600, 36303]]] 720 | } 721 | }, 722 | { 723 | "type": "Feature", 724 | "id": "650000", 725 | "properties": { "id": "650000", "cp": [85.617733, 40.792818], "name": "新疆", "childNum": 1 }, 726 | "geometry": { 727 | "type": "Polygon", 728 | "coordinates": [ 729 | "@@QØĔ²X¨”~ǘBºjʐߨvK”ƔX¨vĊOžÃƒ·¢i@~c—‡ĝe_«”Eš“}QxgɪëÏÃ@sÅyXoŖ{ô«ŸuX…ê•Îf`œC‚¹ÂÿÐGĮÕĞXŪōŸMźÈƺQèĽôe|¿ƸJR¤ĘEjcUóº¯Ĩ_ŘÁMª÷Ð¥Oéȇ¿ÖğǤǷÂF҇zÉx[]­Ĥĝ‰œ¦EP}ûƥé¿İƷTėƫœŕƅ™ƱB»Đ±’ēO…¦E–•}‘`cȺrĦáŖuҞª«IJ‡πdƺÏØZƴwʄ¤ĖGЙǂZ̓èH¶}ÚZצʥĪï|ÇĦMŔ»İĝLj‹ì¥Βœba­¯¥ǕǚkĆŵĦɑĺƯxūД̵nơʃĽá½M»›òmqóŘĝč˾ăC…ćāƿÝɽ©DZŅ¹đ¥˜³ðLrÁ®ɱĕģʼnǻ̋ȥơŻǛȡVï¹Ň۩ûkɗġƁ§ʇė̕ĩũƽō^ƕŠUv£ƁQï“Ƶkŏ½ΉÃŭdzLқʻ«ƭ\\lƒ‡ŭD‡“{ʓDkaFÃÄa“³ŤđÔGRÈƚhSӹŚsİ«ĐË[¥ÚDkº^Øg¼ŵ¸£EÍö•€ůʼnT¡c_‡ËKY‹ƧUśĵ„݃U_©rETÏʜ±OñtYw獃{£¨uM³x½şL©Ùá[ÓÐĥ Νtģ¢\\‚ś’nkO›w¥±ƒT»ƷFɯàĩÞáB¹Æ…ÑUw„੍žĽw[“mG½Èå~‡Æ÷QyŠěCFmĭZī—ŵVÁ™ƿQƛ—ûXS²‰b½KϽĉS›©ŷXĕŸ{ŽĕK·¥Ɨcqq©f¿]‡ßDõU³h—­gËÇïģÉɋw“k¯í}I·šœbmœÉ–ř›īJɥĻˁ×xo›ɹī‡l•c…¤³Xù]‘™DžA¿w͉ì¥wÇN·ÂËnƾƍdǧđ®Ɲv•Um©³G\\“}µĿ‡QyŹl㓛µEw‰LJQ½yƋBe¶ŋÀů‡ož¥A—˜Éw@•{Gpm¿Aij†ŽKLhˆ³`ñcËtW‚±»ÕS‰ëüÿďD‡u\\wwwù³—V›LŕƒOMËGh£õP¡™er™Ïd{“‡ġWÁ…č|yšg^ğyÁzÙs`—s|ÉåªÇ}m¢Ń¨`x¥’ù^•}ƒÌ¥H«‰Yªƅ”Aйn~Ꝛf¤áÀz„gŠÇDIԝ´AňĀ҄¶ûEYospõD[{ù°]u›Jq•U•|Soċxţ[õÔĥkŋÞŭZ˺óYËüċrw €ÞkrťË¿XGÉbřaDü·Ē÷Aê[Ää€I®BÕИÞ_¢āĠpŠÛÄȉĖġDKwbm‡ÄNô‡ŠfœƫVÉvi†dz—H‘‹QµâFšù­Âœ³¦{YGžƒd¢ĚÜO „€{Ö¦ÞÍÀPŒ^b–ƾŠlŽ[„vt×ĈÍE˨¡Đ~´î¸ùÎh€uè`¸ŸHÕŔVºwĠââWò‡@{œÙNÝ´ə²ȕn{¿¥{l—÷eé^e’ďˆXj©î\\ªÑò˜Üìc\\üqˆÕ[Č¡xoÂċªbØ­Œø|€¶ȴZdÆÂšońéŒGš\\”¼C°ÌƁn´nxšÊOĨ’ہƴĸ¢¸òTxÊǪMīИÖŲÃɎOvˆʦƢ~FއRěò—¿ġ~åŊœú‰Nšžš¸qŽ’Ę[Ĕ¶ÂćnÒPĒÜvúĀÊbÖ{Äî¸~Ŕünp¤ÂH¾œĄYÒ©ÊfºmԈĘcDoĬMŬ’˜S¤„s²‚”ʘچžȂVŦ –ŽèW°ªB|IJXŔþÈJĦÆæFĚêŠYĂªĂ]øªŖNÞüA€’fɨJ€˜¯ÎrDDšĤ€`€mz\\„§~D¬{vJÂ˜«lµĂb–¤p€ŌŰNĄ¨ĊXW|ų ¿¾ɄĦƐMT”‡òP˜÷fØĶK¢ȝ˔Sô¹òEð­”`Ɩ½ǒÂň×äı–§ĤƝ§C~¡‚hlå‚ǺŦŞkâ’~}ŽFøàIJaĞ‚fƠ¥Ž„Ŕdž˜®U¸ˆźXœv¢aƆúŪtŠųƠjd•ƺŠƺÅìnrh\\ĺ¯äɝĦ]èpĄ¦´LƞĬŠ´ƤǬ˼Ēɸ¤rºǼ²¨zÌPðŀbþ¹ļD¢¹œ\\ĜÑŚŸ¶ZƄ³àjĨoâŠȴLʉȮŒĐ­ĚăŽÀêZǚŐ¤qȂ\\L¢ŌİfÆs|zºeªÙæ§΢{Ā´ƐÚ¬¨Ĵà²łhʺKÞºÖTŠiƢ¾ªì°`öøu®Ê¾ãØ" 730 | ], 731 | "encodeOffsets": [[88824, 50096]] 732 | } 733 | }, 734 | { 735 | "type": "Feature", 736 | "id": "110000", 737 | "properties": { 738 | "id": "110000", 739 | "cp": [116.405285, 39.904989], 740 | "name": "北京", 741 | "childNum": 1 742 | }, 743 | "geometry": { 744 | "type": "Polygon", 745 | "coordinates": [ 746 | "@@ĽOÁ›ûtŷmiÍt_H»Ĩ±d`й­{bw…Yr“³S]§§o¹€qGtm_Sŧ€“oa›‹FLg‘QN_•dV€@Zom_ć\\ߚc±x¯oœRcfe…£’o§ËgToÛJíĔóu…|wP¤™XnO¢ÉˆŦ¯rNÄā¤zâŖÈRpŢZŠœÚ{GŠrFt¦Òx§ø¹RóäV¤XdˆżâºWbwڍUd®bêņ¾‘jnŎGŃŶŠnzÚSeîĜZczî¾i]͜™QaúÍÔiþĩȨWĢ‹ü|Ėu[qb[swP@ÅğP¿{\\‡¥A¨Ï‘Ѩj¯ŠX\\¯œMK‘pA³[H…īu}}" 747 | ], 748 | "encodeOffsets": [[120023, 41045]] 749 | } 750 | }, 751 | { 752 | "type": "Feature", 753 | "id": "120000", 754 | "properties": { 755 | "id": "120000", 756 | "cp": [117.190182, 39.125596], 757 | "name": "天津", 758 | "childNum": 1 759 | }, 760 | "geometry": { 761 | "type": "Polygon", 762 | "coordinates": [ 763 | "@@ŬgX§Ü«E…¶Ḟ“¬O_™ïlÁg“z±AXe™µÄĵ{¶]gitgšIj·›¥îakS€‰¨ÐƎk}ĕ{gB—qGf{¿a†U^fI“ư‹³õ{YƒıëNĿžk©ïËZŏ‘R§òoY×Ógc…ĥs¡bġ«@dekąI[nlPqCnp{ˆō³°`{PNdƗqSÄĻNNâyj]äžÒD ĬH°Æ]~¡HO¾ŒX}ÐxŒgp“gWˆrDGˆŒpù‚Š^L‚ˆrzWxˆZ^¨´T\\|~@I‰zƒ–bĤ‹œjeĊªz£®Ĕvě€L†mV¾Ô_ȔNW~zbĬvG†²ZmDM~”~" 764 | ], 765 | "encodeOffsets": [[120237, 41215]] 766 | } 767 | }, 768 | { 769 | "type": "Feature", 770 | "id": "310000", 771 | "properties": { 772 | "id": "310000", 773 | "cp": [121.472644, 31.231706], 774 | "name": "上海", 775 | "childNum": 6 776 | }, 777 | "geometry": { 778 | "type": "MultiPolygon", 779 | "coordinates": [ 780 | ["@@ɧư¬EpƸÁxc‡"], 781 | ["@@©„ªƒ"], 782 | ["@@”MA‹‘š"], 783 | ["@@Qp݁E§ÉC¾"], 784 | ["@@bŝՕÕEȣÚƥêImɇǦèÜĠŒÚžÃƌÃ͎ó"], 785 | ["@@ǜûȬɋŠŭ™×^‰sYŒɍDŋ‘ŽąñCG²«ªč@h–_p¯A{‡oloY€¬j@IJ`•gQڛhr|ǀ^MIJvtbe´R¯Ô¬¨YŽô¤r]ì†Ƭį"] 786 | ], 787 | "encodeOffsets": [ 788 | [[124702, 32062]], 789 | [[124547, 32200]], 790 | [[124808, 31991]], 791 | [[124726, 32110]], 792 | [[124903, 32376]], 793 | [[124438, 32149]] 794 | ] 795 | } 796 | }, 797 | { 798 | "type": "Feature", 799 | "id": "500000", 800 | "properties": { 801 | "id": "500000", 802 | "cp": [107.304962, 29.533155], 803 | "name": "重庆", 804 | "childNum": 2 805 | }, 806 | "geometry": { 807 | "type": "MultiPolygon", 808 | "coordinates": [ 809 | [ 810 | "@@vjG~nGŘŬĶȂƀƾ¹¸ØÎezĆT¸}êЖqHŸðqĖ䒊¥^CƒIj–²p…\\_ æüY|[YxƊæuž°xb®…Űb@~¢NQt°¶‚S栓Ê~rljĔëĚ¢~šuf`‘‚†fa‚ĔJåĊ„nÖ]„jƎćÊ@Š£¾a®£Ű{ŶĕF‹ègLk{Y|¡ĜWƔtƬJÑxq‹±ĢN´‰òK‰™–LÈüD|s`ŋ’ć]ƒÃ‰`đŒMûƱ½~Y°ħ`ƏíW‰½eI‹½{aŸ‘OIrÏ¡ĕŇa†p†µÜƅġ‘œ^ÖÛbÙŽŏml½S‹êqDu[R‹ãË»†ÿw`»y‘¸_ĺę}÷`M¯ċfCVµqʼn÷Z•gg“Œ`d½pDO‡ÎCnœ^uf²ènh¼WtƏxRGg¦…pV„†FI±ŽG^ŒIc´ec‡’G•ĹÞ½sëĬ„h˜xW‚}Kӈe­Xsbk”F¦›L‘ØgTkïƵNï¶}Gy“w\\oñ¡nmĈzjŸ•@™Óc£»Wă¹Ój“_m»ˆ¹·~MvÛaqœ»­‰êœ’\\ÂoVnŽÓØÍ™²«‹bq¿efE „€‹Ĝ^Qž~ Évý‡ş¤²Į‰pEİ}zcĺƒL‹½‡š¿gņ›¡ýE¡ya£³t\\¨\\vú»¼§·Ñr_oÒý¥u‚•_n»_ƒ•At©Þűā§IVeëƒY}{VPÀFA¨ąB}q@|Ou—\\Fm‰QF݅Mw˜å}]•€|FmϋCaƒwŒu_p—¯sfÙgY…DHl`{QEfNysBЦzG¸rHe‚„N\\CvEsÐùÜ_·ÖĉsaQ¯€}_U‡†xÃđŠq›NH¬•Äd^ÝŰR¬ã°wećJEž·vÝ·Hgƒ‚éFXjÉê`|yŒpxkAwœWĐpb¥eOsmzwqChóUQl¥F^laf‹anòsr›EvfQdÁUVf—ÎvÜ^efˆtET¬ôA\\œ¢sJŽnQTjP؈xøK|nBz‰„œĞ»LY‚…FDxӄvr“[ehľš•vN”¢o¾NiÂxGp⬐z›bfZo~hGi’]öF|‰|Nb‡tOMn eA±ŠtPT‡LjpYQ|†SH††YĀxinzDJ€Ìg¢và¥Pg‰_–ÇzII‹€II•„£®S¬„Øs쐣ŒN" 811 | ], 812 | ["@@ifjN@s"] 813 | ], 814 | "encodeOffsets": [[[109628, 30765]], [[111725, 31320]]] 815 | } 816 | }, 817 | { 818 | "type": "Feature", 819 | "id": "810000", 820 | "properties": { 821 | "id": "810000", 822 | "cp": [114.173355, 22.320048], 823 | "name": "香港", 824 | "childNum": 5 825 | }, 826 | "geometry": { 827 | "type": "MultiPolygon", 828 | "coordinates": [ 829 | ["@@AlBk"], 830 | ["@@mŽn"], 831 | ["@@EpFo"], 832 | ["@@ea¢pl¸Eõ¹‡hj[ƒ]ÔCΖ@lj˜¡uBXŸ…•´‹AI¹…[‹yDUˆ]W`çwZkmc–…M›žp€Åv›}I‹oJlcaƒfёKްä¬XJmРđhI®æÔtSHn€Eˆ„ÒrÈc"], 833 | ["@@rMUw‡AS®€e"] 834 | ], 835 | "encodeOffsets": [ 836 | [[117111, 23002]], 837 | [[117072, 22876]], 838 | [[117045, 22887]], 839 | [[116975, 23082]], 840 | [[116882, 22747]] 841 | ] 842 | } 843 | }, 844 | { 845 | "type": "Feature", 846 | "id": "820000", 847 | "properties": { "id": "820000", "cp": [113.54909, 22.198951], "name": "澳门", "childNum": 1 }, 848 | "geometry": { 849 | "type": "Polygon", 850 | "coordinates": ["@@kÊd°å§s"], 851 | "encodeOffsets": [[116279, 22639]] 852 | } 853 | } 854 | ], 855 | "UTF8Encoding": true 856 | } 857 | -------------------------------------------------------------------------------- /src/base-ui/echart/hooks/useEchart.ts: -------------------------------------------------------------------------------- 1 | import * as echarts from 'echarts' 2 | 3 | import chinaMapData from '../data/china.json' 4 | 5 | echarts.registerMap('china', chinaMapData) 6 | 7 | export default function (el: HTMLElement) { 8 | const echartInstance = echarts.init(el) 9 | 10 | const setOptions = (options: echarts.EChartsOption) => { 11 | echartInstance.setOption(options) 12 | } 13 | 14 | const updateSize = () => { 15 | echartInstance.resize() 16 | } 17 | 18 | window.addEventListener('resize', () => { 19 | echartInstance.resize() 20 | }) 21 | 22 | return { 23 | echartInstance, 24 | setOptions, 25 | updateSize 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/base-ui/echart/index.ts: -------------------------------------------------------------------------------- 1 | import BaseEchart from './src/base-echart.vue' 2 | 3 | export default BaseEchart 4 | -------------------------------------------------------------------------------- /src/base-ui/echart/src/base-echart.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/base-ui/form/index.ts: -------------------------------------------------------------------------------- 1 | import HyForm from './src/form.vue' 2 | 3 | export * from './types' 4 | 5 | export default HyForm 6 | -------------------------------------------------------------------------------- /src/base-ui/form/src/form.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 120 | 121 | 126 | -------------------------------------------------------------------------------- /src/base-ui/form/types/index.ts: -------------------------------------------------------------------------------- 1 | type IFormType = 'input' | 'password' | 'select' | 'datepicker' 2 | 3 | export interface IFormItem { 4 | field: string 5 | type: IFormType 6 | label: string 7 | rules?: any[] 8 | placeholder?: any 9 | // 针对select 10 | options?: any[] 11 | // 针对特殊的属性 12 | otherOptions?: any 13 | isHidden?: boolean 14 | } 15 | 16 | export interface IForm { 17 | formItems: IFormItem[] 18 | labelWidth?: string 19 | colLayout?: any 20 | itemStyle?: any 21 | } 22 | -------------------------------------------------------------------------------- /src/base-ui/table/index.ts: -------------------------------------------------------------------------------- 1 | import HyTable from './src/table.vue' 2 | 3 | export default HyTable 4 | -------------------------------------------------------------------------------- /src/base-ui/table/src/table.vue: -------------------------------------------------------------------------------- 1 | 57 | 58 | 122 | 123 | 149 | -------------------------------------------------------------------------------- /src/components/nav-header/index.ts: -------------------------------------------------------------------------------- 1 | import NavHeader from './src/nav-header.vue' 2 | 3 | export default NavHeader 4 | -------------------------------------------------------------------------------- /src/components/nav-header/src/nav-header.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 54 | 55 | 74 | -------------------------------------------------------------------------------- /src/components/nav-header/src/user-info.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 48 | 49 | 56 | -------------------------------------------------------------------------------- /src/components/nav-menu/index.ts: -------------------------------------------------------------------------------- 1 | import NavMenu from './src/nav-menu.vue' 2 | 3 | export default NavMenu 4 | -------------------------------------------------------------------------------- /src/components/nav-menu/src/nav-menu.vue: -------------------------------------------------------------------------------- 1 | 47 | 48 | 93 | 94 | 153 | -------------------------------------------------------------------------------- /src/components/page-content/index.ts: -------------------------------------------------------------------------------- 1 | import PageContent from './src/page-content.vue' 2 | 3 | export default PageContent 4 | -------------------------------------------------------------------------------- /src/components/page-content/src/page-content.vue: -------------------------------------------------------------------------------- 1 | 72 | 73 | 172 | 173 | 179 | -------------------------------------------------------------------------------- /src/components/page-echarts/index.ts: -------------------------------------------------------------------------------- 1 | import PieEchart from './src/pie-echart.vue' 2 | import RoseEchart from './src/rose-echart.vue' 3 | import LineEchart from './src/line-echart.vue' 4 | import BarEchart from './src/bar-echart.vue' 5 | import MapEchart from './src/map-echart.vue' 6 | 7 | export { PieEchart, RoseEchart, LineEchart, BarEchart, MapEchart } 8 | -------------------------------------------------------------------------------- /src/components/page-echarts/src/bar-echart.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /src/components/page-echarts/src/line-echart.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/components/page-echarts/src/map-echart.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /src/components/page-echarts/src/pie-echart.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/components/page-echarts/src/rose-echart.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/components/page-echarts/types/index.ts: -------------------------------------------------------------------------------- 1 | export interface IDataType { 2 | name: string 3 | value: any 4 | } 5 | -------------------------------------------------------------------------------- /src/components/page-echarts/utils/convert-data.ts: -------------------------------------------------------------------------------- 1 | import { coordinateData } from './coordinate-data' 2 | 3 | export const convertData = function (data: any) { 4 | const res = [] 5 | for (let i = 0; i < data.length; i++) { 6 | const geoCoord = coordinateData[data[i].name] 7 | if (geoCoord) { 8 | res.push({ 9 | name: data[i].name, 10 | value: geoCoord.concat(data[i].value) 11 | }) 12 | } 13 | } 14 | return res 15 | } 16 | -------------------------------------------------------------------------------- /src/components/page-echarts/utils/coordinate-data.ts: -------------------------------------------------------------------------------- 1 | export const coordinateData: any = { 2 | 海门: [121.15, 31.89], 3 | 鄂尔多斯: [109.781327, 39.608266], 4 | 招远: [120.38, 37.35], 5 | 舟山: [122.207216, 29.985295], 6 | 齐齐哈尔: [123.97, 47.33], 7 | 盐城: [120.13, 33.38], 8 | 赤峰: [118.87, 42.28], 9 | 青岛: [120.33, 36.07], 10 | 乳山: [121.52, 36.89], 11 | 金昌: [102.188043, 38.520089], 12 | 泉州: [118.58, 24.93], 13 | 莱西: [120.53, 36.86], 14 | 日照: [119.46, 35.42], 15 | 胶南: [119.97, 35.88], 16 | 南通: [121.05, 32.08], 17 | 拉萨: [91.11, 29.97], 18 | 云浮: [112.02, 22.93], 19 | 梅州: [116.1, 24.55], 20 | 文登: [122.05, 37.2], 21 | 上海: [121.48, 31.22], 22 | 攀枝花: [101.718637, 26.582347], 23 | 威海: [122.1, 37.5], 24 | 承德: [117.93, 40.97], 25 | 厦门: [118.1, 24.46], 26 | 汕尾: [115.375279, 22.786211], 27 | 潮州: [116.63, 23.68], 28 | 丹东: [124.37, 40.13], 29 | 太仓: [121.1, 31.45], 30 | 曲靖: [103.79, 25.51], 31 | 烟台: [121.39, 37.52], 32 | 福州: [119.3, 26.08], 33 | 瓦房店: [121.979603, 39.627114], 34 | 即墨: [120.45, 36.38], 35 | 抚顺: [123.97, 41.97], 36 | 玉溪: [102.52, 24.35], 37 | 张家口: [114.87, 40.82], 38 | 阳泉: [113.57, 37.85], 39 | 莱州: [119.942327, 37.177017], 40 | 湖州: [120.1, 30.86], 41 | 汕头: [116.69, 23.39], 42 | 昆山: [120.95, 31.39], 43 | 宁波: [121.56, 29.86], 44 | 湛江: [110.359377, 21.270708], 45 | 揭阳: [116.35, 23.55], 46 | 荣成: [122.41, 37.16], 47 | 连云港: [119.16, 34.59], 48 | 葫芦岛: [120.836932, 40.711052], 49 | 常熟: [120.74, 31.64], 50 | 东莞: [113.75, 23.04], 51 | 河源: [114.68, 23.73], 52 | 淮安: [119.15, 33.5], 53 | 泰州: [119.9, 32.49], 54 | 南宁: [108.33, 22.84], 55 | 营口: [122.18, 40.65], 56 | 惠州: [114.4, 23.09], 57 | 江阴: [120.26, 31.91], 58 | 蓬莱: [120.75, 37.8], 59 | 韶关: [113.62, 24.84], 60 | 嘉峪关: [98.289152, 39.77313], 61 | 广州: [113.23, 23.16], 62 | 延安: [109.47, 36.6], 63 | 太原: [112.53, 37.87], 64 | 清远: [113.01, 23.7], 65 | 中山: [113.38, 22.52], 66 | 昆明: [102.73, 25.04], 67 | 寿光: [118.73, 36.86], 68 | 盘锦: [122.070714, 41.119997], 69 | 长治: [113.08, 36.18], 70 | 深圳: [114.07, 22.62], 71 | 珠海: [113.52, 22.3], 72 | 宿迁: [118.3, 33.96], 73 | 咸阳: [108.72, 34.36], 74 | 铜川: [109.11, 35.09], 75 | 平度: [119.97, 36.77], 76 | 佛山: [113.11, 23.05], 77 | 海口: [110.35, 20.02], 78 | 江门: [113.06, 22.61], 79 | 章丘: [117.53, 36.72], 80 | 肇庆: [112.44, 23.05], 81 | 大连: [121.62, 38.92], 82 | 临汾: [111.5, 36.08], 83 | 吴江: [120.63, 31.16], 84 | 石嘴山: [106.39, 39.04], 85 | 沈阳: [123.38, 41.8], 86 | 苏州: [120.62, 31.32], 87 | 茂名: [110.88, 21.68], 88 | 嘉兴: [120.76, 30.77], 89 | 长春: [125.35, 43.88], 90 | 胶州: [120.03336, 36.264622], 91 | 银川: [106.27, 38.47], 92 | 张家港: [120.555821, 31.875428], 93 | 三门峡: [111.19, 34.76], 94 | 锦州: [121.15, 41.13], 95 | 南昌: [115.89, 28.68], 96 | 柳州: [109.4, 24.33], 97 | 三亚: [109.511909, 18.252847], 98 | 自贡: [104.778442, 29.33903], 99 | 吉林: [126.57, 43.87], 100 | 阳江: [111.95, 21.85], 101 | 泸州: [105.39, 28.91], 102 | 西宁: [101.74, 36.56], 103 | 宜宾: [104.56, 29.77], 104 | 呼和浩特: [111.65, 40.82], 105 | 成都: [104.06, 30.67], 106 | 大同: [113.3, 40.12], 107 | 镇江: [119.44, 32.2], 108 | 桂林: [110.28, 25.29], 109 | 张家界: [110.479191, 29.117096], 110 | 宜兴: [119.82, 31.36], 111 | 北海: [109.12, 21.49], 112 | 西安: [108.95, 34.27], 113 | 金坛: [119.56, 31.74], 114 | 东营: [118.49, 37.46], 115 | 牡丹江: [129.58, 44.6], 116 | 遵义: [106.9, 27.7], 117 | 绍兴: [120.58, 30.01], 118 | 扬州: [119.42, 32.39], 119 | 常州: [119.95, 31.79], 120 | 潍坊: [119.1, 36.62], 121 | 重庆: [106.54, 29.59], 122 | 台州: [121.420757, 28.656386], 123 | 南京: [118.78, 32.04], 124 | 滨州: [118.03, 37.36], 125 | 贵阳: [106.71, 26.57], 126 | 无锡: [120.29, 31.59], 127 | 本溪: [123.73, 41.3], 128 | 克拉玛依: [84.77, 45.59], 129 | 渭南: [109.5, 34.52], 130 | 马鞍山: [118.48, 31.56], 131 | 宝鸡: [107.15, 34.38], 132 | 焦作: [113.21, 35.24], 133 | 句容: [119.16, 31.95], 134 | 北京: [116.46, 39.92], 135 | 徐州: [117.2, 34.26], 136 | 衡水: [115.72, 37.72], 137 | 包头: [110, 40.58], 138 | 绵阳: [104.73, 31.48], 139 | 乌鲁木齐: [87.68, 43.77], 140 | 枣庄: [117.57, 34.86], 141 | 杭州: [120.19, 30.26], 142 | 淄博: [118.05, 36.78], 143 | 鞍山: [122.85, 41.12], 144 | 溧阳: [119.48, 31.43], 145 | 库尔勒: [86.06, 41.68], 146 | 安阳: [114.35, 36.1], 147 | 开封: [114.35, 34.79], 148 | 济南: [117, 36.65], 149 | 德阳: [104.37, 31.13], 150 | 温州: [120.65, 28.01], 151 | 九江: [115.97, 29.71], 152 | 邯郸: [114.47, 36.6], 153 | 临安: [119.72, 30.23], 154 | 兰州: [103.73, 36.03], 155 | 沧州: [116.83, 38.33], 156 | 临沂: [118.35, 35.05], 157 | 南充: [106.110698, 30.837793], 158 | 天津: [117.2, 39.13], 159 | 富阳: [119.95, 30.07], 160 | 泰安: [117.13, 36.18], 161 | 诸暨: [120.23, 29.71], 162 | 郑州: [113.65, 34.76], 163 | 哈尔滨: [126.63, 45.75], 164 | 聊城: [115.97, 36.45], 165 | 芜湖: [118.38, 31.33], 166 | 唐山: [118.02, 39.63], 167 | 平顶山: [113.29, 33.75], 168 | 邢台: [114.48, 37.05], 169 | 德州: [116.29, 37.45], 170 | 济宁: [116.59, 35.38], 171 | 荆州: [112.239741, 30.335165], 172 | 宜昌: [111.3, 30.7], 173 | 义乌: [120.06, 29.32], 174 | 丽水: [119.92, 28.45], 175 | 洛阳: [112.44, 34.7], 176 | 秦皇岛: [119.57, 39.95], 177 | 株洲: [113.16, 27.83], 178 | 石家庄: [114.48, 38.03], 179 | 莱芜: [117.67, 36.19], 180 | 常德: [111.69, 29.05], 181 | 保定: [115.48, 38.85], 182 | 湘潭: [112.91, 27.87], 183 | 金华: [119.64, 29.12], 184 | 岳阳: [113.09, 29.37], 185 | 长沙: [113, 28.21], 186 | 衢州: [118.88, 28.97], 187 | 廊坊: [116.7, 39.53], 188 | 菏泽: [115.480656, 35.23375], 189 | 合肥: [117.27, 31.86], 190 | 武汉: [114.31, 30.52], 191 | 大庆: [125.03, 46.58] 192 | } 193 | -------------------------------------------------------------------------------- /src/components/page-modal/index.ts: -------------------------------------------------------------------------------- 1 | import PageModal from './src/page-modal.vue' 2 | 3 | export default PageModal 4 | -------------------------------------------------------------------------------- /src/components/page-modal/src/page-modal.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/components/page-search/index.ts: -------------------------------------------------------------------------------- 1 | import PageSearch from './src/page-search.vue' 2 | 3 | export default PageSearch 4 | -------------------------------------------------------------------------------- /src/components/page-search/src/page-search.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 71 | 72 | 81 | -------------------------------------------------------------------------------- /src/global/index.ts: -------------------------------------------------------------------------------- 1 | import { App } from 'vue' 2 | import registerElement from './register-element' 3 | import registerProperties from './register-properties' 4 | 5 | export function globalRegister(app: App): void { 6 | app.use(registerElement) 7 | app.use(registerProperties) 8 | } 9 | -------------------------------------------------------------------------------- /src/global/register-element.ts: -------------------------------------------------------------------------------- 1 | import { App } from 'vue' 2 | import 'element-plus/lib/theme-chalk/base.css' 3 | import { 4 | ElAside, 5 | ElAvatar, 6 | ElButton, 7 | ElCheckbox, 8 | ElContainer, 9 | ElDatePicker, 10 | ElDropdown, 11 | ElDropdownItem, 12 | ElDropdownMenu, 13 | ElForm, 14 | ElFormItem, 15 | ElHeader, 16 | ElInput, 17 | ElLink, 18 | ElMain, 19 | ElMenu, 20 | ElMenuItem, 21 | ElMenuItemGroup, 22 | ElOption, 23 | ElRadio, 24 | ElRow, 25 | ElCol, 26 | ElSelect, 27 | ElSubmenu, 28 | ElTabPane, 29 | ElTabs, 30 | ElBreadcrumb, 31 | ElBreadcrumbItem, 32 | ElTable, 33 | ElTableColumn, 34 | ElPagination, 35 | ElImage, 36 | ElDialog, 37 | ElTree, 38 | ElCard 39 | } from 'element-plus' 40 | 41 | const components = [ 42 | ElButton, 43 | ElForm, 44 | ElFormItem, 45 | ElInput, 46 | ElRadio, 47 | ElTabs, 48 | ElTabPane, 49 | ElCheckbox, 50 | ElLink, 51 | ElContainer, 52 | ElHeader, 53 | ElMain, 54 | ElAside, 55 | ElMenu, 56 | ElMenuItem, 57 | ElMenuItemGroup, 58 | ElSubmenu, 59 | ElDropdown, 60 | ElDropdownMenu, 61 | ElDropdownItem, 62 | ElAvatar, 63 | ElCol, 64 | ElRow, 65 | ElSelect, 66 | ElOption, 67 | ElDatePicker, 68 | ElBreadcrumb, 69 | ElBreadcrumbItem, 70 | ElTable, 71 | ElTableColumn, 72 | ElPagination, 73 | ElImage, 74 | ElDialog, 75 | ElTree, 76 | ElCard 77 | ] 78 | 79 | export default function (app: App): void { 80 | for (const component of components) { 81 | app.component(component.name, component) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/global/register-properties.ts: -------------------------------------------------------------------------------- 1 | import { App } from 'vue' 2 | 3 | import { formatUtcString } from '@/utils/date-format' 4 | 5 | export default function registerProperties(app: App) { 6 | app.config.globalProperties.$filters = { 7 | foo() { 8 | console.log('foo') 9 | }, 10 | formatTime(value: string) { 11 | return formatUtcString(value) 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/hooks/use-page-modal.ts: -------------------------------------------------------------------------------- 1 | import { ref } from 'vue' 2 | import PageModal from '@/components/page-modal' 3 | 4 | type CallbackFn = (item?: any) => void 5 | 6 | export function usePageModal(newCb?: CallbackFn, editCb?: CallbackFn) { 7 | const pageModalRef = ref>() 8 | const defaultInfo = ref({}) 9 | const handleNewData = () => { 10 | defaultInfo.value = {} 11 | if (pageModalRef.value) { 12 | pageModalRef.value.dialogVisible = true 13 | } 14 | newCb && newCb() 15 | } 16 | const handleEditData = (item: any) => { 17 | defaultInfo.value = { ...item } 18 | if (pageModalRef.value) { 19 | pageModalRef.value.dialogVisible = true 20 | } 21 | editCb && editCb(item) 22 | } 23 | return [pageModalRef, defaultInfo, handleNewData, handleEditData] 24 | } 25 | -------------------------------------------------------------------------------- /src/hooks/use-page-search.ts: -------------------------------------------------------------------------------- 1 | import { ref } from 'vue' 2 | import PageContent from '@/components/page-content' 3 | 4 | export function usePageSearch() { 5 | const pageContentRef = ref>() 6 | const handleResetClick = () => { 7 | pageContentRef.value?.getPageData() 8 | } 9 | const handleQueryClick = (queryInfo: any) => { 10 | pageContentRef.value?.getPageData(queryInfo) 11 | } 12 | return [pageContentRef, handleResetClick, handleQueryClick] 13 | } 14 | -------------------------------------------------------------------------------- /src/hooks/use-permission.ts: -------------------------------------------------------------------------------- 1 | import { useStore } from '@/store' 2 | 3 | export function usePermission(pageName: string, hanldeName: string) { 4 | const store = useStore() 5 | const permissions = store.state.login.permissions 6 | const verifyPermission = `system:${pageName}:${hanldeName}` 7 | 8 | // name = "coderwhy" 9 | // !name -> false 10 | // !!name -> true 11 | return !!permissions.find((item) => item === verifyPermission) 12 | } 13 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import { globalRegister } from './global' 3 | import 'normalize.css' 4 | import './assets/css/index.less' 5 | 6 | import App from './App.vue' 7 | 8 | import router from './router' 9 | import store from './store' 10 | import { setupStore } from './store' 11 | 12 | const app = createApp(App) 13 | 14 | // 注册element-plus/其他 15 | app.use(globalRegister) 16 | app.use(store) 17 | setupStore() 18 | // path: /user => user 19 | app.use(router) 20 | 21 | app.mount('#app') 22 | -------------------------------------------------------------------------------- /src/router/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHashHistory } from 'vue-router' 2 | import type { RouteRecordRaw } from 'vue-router' 3 | 4 | import localCache from '@/utils/cache' 5 | import { firstMenu } from '@/utils/map-menus' 6 | 7 | const routes: RouteRecordRaw[] = [ 8 | { 9 | path: '/', 10 | redirect: '/main' 11 | }, 12 | { 13 | path: '/login', 14 | name: 'login', 15 | component: () => import('@/views/login/login.vue') 16 | }, 17 | { 18 | path: '/main', 19 | name: 'main', 20 | component: () => import('@/views/main/main.vue') 21 | // children: [] -> 根据userMenus来决定 -> children 22 | }, 23 | { 24 | path: '/:pathMatch(.*)*', 25 | name: 'notFound', 26 | component: () => import('@/views/not-found/not-found.vue') 27 | } 28 | ] 29 | 30 | const router = createRouter({ 31 | routes, 32 | history: createWebHashHistory() 33 | }) 34 | 35 | // 导航守卫 36 | router.beforeEach((to) => { 37 | if (to.path !== '/login') { 38 | const token = localCache.getCache('token') 39 | if (!token) { 40 | return '/login' 41 | } 42 | } 43 | 44 | // console.log(router.getRoutes()) 45 | // console.log(to) // route对象 46 | 47 | if (to.path === '/main') { 48 | console.log(firstMenu) 49 | return firstMenu.url 50 | } 51 | }) 52 | 53 | export default router 54 | -------------------------------------------------------------------------------- /src/router/login/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/July107/Vue3-TS-CMS/e5a4960e2724e3010dfe85d362acc41b91bcd39d/src/router/login/index.ts -------------------------------------------------------------------------------- /src/router/main/analysis/dashboard/dashboard.ts: -------------------------------------------------------------------------------- 1 | const dashboard = () => import('@/views/main/analysis/dashboard/dashboard.vue') 2 | export default { 3 | path: '/main/analysis/dashboard', 4 | name: 'dashboard', 5 | component: dashboard, 6 | children: [] 7 | } 8 | -------------------------------------------------------------------------------- /src/router/main/analysis/overview/overview.ts: -------------------------------------------------------------------------------- 1 | const overview = () => import('@/views/main/analysis/overview/overview.vue') 2 | export default { 3 | path: '/main/analysis/overview', 4 | name: 'overview', 5 | component: overview, 6 | children: [] 7 | } 8 | -------------------------------------------------------------------------------- /src/router/main/product/category/category.ts: -------------------------------------------------------------------------------- 1 | const category = () => import('@/views/main/product/category/category.vue') 2 | export default { 3 | path: '/main/product/category', 4 | name: 'category', 5 | component: category, 6 | children: [] 7 | } 8 | -------------------------------------------------------------------------------- /src/router/main/product/goods/goods.ts: -------------------------------------------------------------------------------- 1 | const goods = () => import('@/views/main/product/goods/goods.vue') 2 | export default { 3 | path: '/main/product/goods', 4 | name: 'goods', 5 | component: goods, 6 | children: [] 7 | } 8 | -------------------------------------------------------------------------------- /src/router/main/story/chat/chat.ts: -------------------------------------------------------------------------------- 1 | const chat = () => import('@/views/main/story/chat/chat.vue') 2 | export default { 3 | path: '/main/story/chat', 4 | name: 'chat', 5 | component: chat, 6 | children: [] 7 | } 8 | -------------------------------------------------------------------------------- /src/router/main/story/list/list.ts: -------------------------------------------------------------------------------- 1 | const list = () => import('@/views/main/story/list/list.vue') 2 | export default { 3 | path: '/main/story/list', 4 | name: 'list', 5 | component: list, 6 | children: [] 7 | } 8 | -------------------------------------------------------------------------------- /src/router/main/system/department/department.ts: -------------------------------------------------------------------------------- 1 | const department = () => import('@/views/main/system/department/department.vue') 2 | export default { 3 | path: '/main/system/department', 4 | name: 'department', 5 | component: department, 6 | children: [] 7 | } 8 | -------------------------------------------------------------------------------- /src/router/main/system/menu/menu.ts: -------------------------------------------------------------------------------- 1 | const menu = () => import('@/views/main/system/menu/menu.vue') 2 | export default { 3 | path: '/main/system/menu', 4 | name: 'menu', 5 | component: menu, 6 | children: [] 7 | } 8 | -------------------------------------------------------------------------------- /src/router/main/system/role/role.ts: -------------------------------------------------------------------------------- 1 | const role = () => import('@/views/main/system/role/role.vue') 2 | export default { 3 | path: '/main/system/role', 4 | name: 'role', 5 | component: role, 6 | children: [] 7 | } 8 | -------------------------------------------------------------------------------- /src/router/main/system/user/user.ts: -------------------------------------------------------------------------------- 1 | const user = () => import('@/views/main/system/user/user.vue') 2 | export default { 3 | path: '/main/system/user', 4 | name: 'user', 5 | component: user, 6 | children: [] 7 | } 8 | -------------------------------------------------------------------------------- /src/service/axios_demo.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | // axios的实例对象 4 | // 1.模拟get请求 5 | axios.get('http://123.207.32.32:8000/home/multidata').then((res) => { 6 | console.log(res.data) 7 | }) 8 | 9 | // 2.get请求,并且传入参数 10 | // axios 11 | // .get('http://httpbin.org/get', { 12 | // params: { 13 | // name: 'coderwhy', 14 | // age: 18 15 | // } 16 | // }) 17 | // .then((res) => { 18 | // console.log(res.data) 19 | // }) 20 | 21 | // // 3.post请求 22 | // axios 23 | // .post('http://httpbin.org/post', { 24 | // data: { 25 | // name: 'why', 26 | // age: 18 27 | // } 28 | // }) 29 | // .then((res) => { 30 | // console.log(res.data) 31 | // }) 32 | 33 | // 额外补充的Promise中类型的使用 34 | // Promise本身是可以有类型 35 | // new Promise((resolve) => { 36 | // resolve('abc') 37 | // }).then((res) => { 38 | // console.log(res.length) 39 | // }) 40 | 41 | // 4.axios的配置选项 42 | // 4.1. 全局的配置 43 | axios.defaults.baseURL = 'http://httpbin.org' 44 | axios.defaults.timeout = 10000 45 | // axios.defaults.headers = {} 46 | 47 | // 4.2. 每一个请求单独的配置 48 | // axios 49 | // .get('/get', { 50 | // params: { 51 | // name: 'coderwhy', 52 | // age: 18 53 | // }, 54 | // timeout: 5000, 55 | // headers: {} 56 | // }) 57 | // .then((res) => { 58 | // console.log(res.data) 59 | // }) 60 | 61 | // 3.post请求 62 | // axios 63 | // .post('/post', { 64 | // data: { 65 | // name: 'why', 66 | // age: 18 67 | // } 68 | // }) 69 | // .then((res) => { 70 | // console.log(res.data) 71 | // }) 72 | 73 | // 5.axios.all -> 多个请求, 一起返回 74 | axios 75 | .all([ 76 | axios.get('/get', { params: { name: 'why', age: 18 } }), 77 | axios.post('/post', { data: { name: 'why', age: 18 } }) 78 | ]) 79 | .then((res) => { 80 | console.log(res[0].data) 81 | console.log(res[1].data) 82 | }) 83 | 84 | // 6.axios的拦截器 85 | // fn1: 请求发送成功会执行的函数 86 | // fn2: 请求发送失败会执行的函数 87 | axios.interceptors.request.use( 88 | (config) => { 89 | // 想做的一些操作 90 | // 1.给请求添加token 91 | // 2.isLoading动画 92 | console.log('请求成功的拦截') 93 | return config 94 | }, 95 | (err) => { 96 | console.log('请求发送错误') 97 | return err 98 | } 99 | ) 100 | 101 | // fn1: 数据响应成功(服务器正常的返回了数据 20x) 102 | axios.interceptors.response.use( 103 | (res) => { 104 | console.log('响应成功的拦截') 105 | return res 106 | }, 107 | (err) => { 108 | console.log('服务器响应失败') 109 | return err 110 | } 111 | ) 112 | -------------------------------------------------------------------------------- /src/service/index.ts: -------------------------------------------------------------------------------- 1 | // service统一出口 2 | import HYRequest from './request' 3 | import { BASE_URL, TIME_OUT } from './request/config' 4 | 5 | import localCache from '@/utils/cache' 6 | 7 | const hyRequest = new HYRequest({ 8 | baseURL: BASE_URL, 9 | timeout: TIME_OUT, 10 | interceptors: { 11 | requestInterceptor: (config) => { 12 | // 携带token的拦截 13 | const token = localCache.getCache('token') 14 | if (token) { 15 | config.headers.Authorization = `Bearer ${token}` 16 | } 17 | return config 18 | }, 19 | requestInterceptorCatch: (err) => { 20 | return err 21 | }, 22 | responseInterceptor: (res) => { 23 | return res 24 | }, 25 | responseInterceptorCatch: (err) => { 26 | return err 27 | } 28 | } 29 | }) 30 | 31 | export default hyRequest 32 | -------------------------------------------------------------------------------- /src/service/login/login.ts: -------------------------------------------------------------------------------- 1 | import hyRequest from '../index' 2 | 3 | import { IAccount, ILoginResult } from './type' 4 | import { IDataType } from '../types' 5 | 6 | enum LoginAPI { 7 | AccountLogin = '/login', 8 | LoginUserInfo = '/users/', // 用法: /users/1 9 | UserMenus = '/role/' // 用法: role/1/menu 10 | } 11 | 12 | export function accountLoginRequest(account: IAccount) { 13 | return hyRequest.post>({ 14 | url: LoginAPI.AccountLogin, 15 | data: account 16 | }) 17 | } 18 | 19 | export function requestUserInfoById(id: number) { 20 | return hyRequest.get({ 21 | url: LoginAPI.LoginUserInfo + id, 22 | showLoading: false 23 | }) 24 | } 25 | 26 | export function requestUserMenusByRoleId(id: number) { 27 | return hyRequest.get({ 28 | url: LoginAPI.UserMenus + id + '/menu', 29 | showLoading: false 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /src/service/login/type.ts: -------------------------------------------------------------------------------- 1 | export interface IAccount { 2 | name: string 3 | password: string 4 | } 5 | 6 | export interface ILoginResult { 7 | id: number 8 | name: string 9 | token: string 10 | } 11 | -------------------------------------------------------------------------------- /src/service/main/analysis/dashboard.ts: -------------------------------------------------------------------------------- 1 | import hyRequest from '../../index' 2 | 3 | enum DashboardAPI { 4 | categoryGoodsCount = '/goods/category/count', 5 | categoryGoodsSale = '/goods/category/sale', 6 | categoryGoodsFavor = '/goods/category/favor', 7 | addressGoodsSale = '/goods/address/sale' 8 | } 9 | 10 | export function getCategoryGoodsCount() { 11 | return hyRequest.get({ 12 | url: DashboardAPI.categoryGoodsCount 13 | }) 14 | } 15 | 16 | export function getCategoryGoodsSale() { 17 | return hyRequest.get({ 18 | url: DashboardAPI.categoryGoodsSale 19 | }) 20 | } 21 | 22 | export function getCategoryGoodsFavor() { 23 | return hyRequest.get({ 24 | url: DashboardAPI.categoryGoodsFavor 25 | }) 26 | } 27 | 28 | export function getAddressGoodsSale() { 29 | return hyRequest.get({ 30 | url: DashboardAPI.addressGoodsSale 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /src/service/main/system/system.ts: -------------------------------------------------------------------------------- 1 | import hyRequest from '../../index' 2 | 3 | import { IDataType } from '../../types' 4 | 5 | export function getPageListData(url: string, queryInfo: any) { 6 | return hyRequest.post({ 7 | url: url, 8 | data: queryInfo 9 | }) 10 | } 11 | 12 | // url: /users/id 13 | export function deletePageData(url: string) { 14 | return hyRequest.delete({ 15 | url: url 16 | }) 17 | } 18 | 19 | export function createPageData(url: string, newData: any) { 20 | return hyRequest.post({ 21 | url: url, 22 | data: newData 23 | }) 24 | } 25 | 26 | export function editPageData(url: string, editData: any) { 27 | return hyRequest.patch({ 28 | url: url, 29 | data: editData 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /src/service/request/config.ts: -------------------------------------------------------------------------------- 1 | // 1.方式一: 手动的切换不同的环境(不推荐) 2 | // const BASE_URL = 'http://coderwhy.org/dev' 3 | // const BASE_NAME = 'coderwhy' 4 | 5 | // const BASE_URL = 'http://coderwhy.org/prod' 6 | // const BASE_NAME = 'kobe' 7 | 8 | // const BASE_URL = 'http://coderwhy.org/test' 9 | // const BASE_NAME = 'james' 10 | 11 | // 2.根据process.env.NODE_ENV区分 12 | // 开发环境: development 13 | // 生成环境: production 14 | // 测试环境: test 15 | 16 | let BASE_URL = '' 17 | const TIME_OUT = 10000 18 | 19 | if (process.env.NODE_ENV === 'development') { 20 | BASE_URL = '/api' 21 | } else if (process.env.NODE_ENV === 'production') { 22 | BASE_URL = 'http://coderwhy.org/prod' 23 | } else { 24 | BASE_URL = 'http://coderwhy.org/test' 25 | } 26 | 27 | export { BASE_URL, TIME_OUT } 28 | -------------------------------------------------------------------------------- /src/service/request/index.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import type { AxiosInstance } from 'axios' 3 | import type { HYRequestInterceptors, HYRequestConfig } from './type' 4 | 5 | import { ElLoading } from 'element-plus' 6 | import { ILoadingInstance } from 'element-plus/lib/el-loading/src/loading.type' 7 | 8 | const DEAFULT_LOADING = true 9 | 10 | class HYRequest { 11 | instance: AxiosInstance 12 | interceptors?: HYRequestInterceptors 13 | showLoading: boolean 14 | loading?: ILoadingInstance 15 | 16 | constructor(config: HYRequestConfig) { 17 | // 创建axios实例 18 | this.instance = axios.create(config) 19 | 20 | // 保存基本信息 21 | this.showLoading = config.showLoading ?? DEAFULT_LOADING 22 | this.interceptors = config.interceptors 23 | 24 | // 使用拦截器 25 | // 1.从config中取出的拦截器是对应的实例的拦截器 26 | this.instance.interceptors.request.use( 27 | this.interceptors?.requestInterceptor, 28 | this.interceptors?.requestInterceptorCatch 29 | ) 30 | this.instance.interceptors.response.use( 31 | this.interceptors?.responseInterceptor, 32 | this.interceptors?.responseInterceptorCatch 33 | ) 34 | 35 | // 2.添加所有的实例都有的拦截器 36 | this.instance.interceptors.request.use( 37 | (config) => { 38 | if (this.showLoading) { 39 | this.loading = ElLoading.service({ 40 | lock: true, 41 | text: '正在请求数据....', 42 | background: 'rgba(0, 0, 0, 0.5)' 43 | }) 44 | } 45 | return config 46 | }, 47 | (err) => { 48 | return err 49 | } 50 | ) 51 | 52 | this.instance.interceptors.response.use( 53 | (res) => { 54 | // 将loading移除 55 | this.loading?.close() 56 | 57 | const data = res.data 58 | if (data.returnCode === '-1001') { 59 | console.log('请求失败~, 错误信息') 60 | } else { 61 | return data 62 | } 63 | }, 64 | (err) => { 65 | // 将loading移除 66 | this.loading?.close() 67 | 68 | // 例子: 判断不同的HttpErrorCode显示不同的错误信息 69 | if (err.response.status === 404) { 70 | console.log('404的错误~') 71 | } 72 | return err 73 | } 74 | ) 75 | } 76 | 77 | request(config: HYRequestConfig): Promise { 78 | return new Promise((resolve, reject) => { 79 | // 1.单个请求对请求config的处理 80 | if (config.interceptors?.requestInterceptor) { 81 | config = config.interceptors.requestInterceptor(config) 82 | } 83 | 84 | // 2.判断是否需要显示loading 85 | if (config.showLoading === false) { 86 | this.showLoading = config.showLoading 87 | } 88 | 89 | this.instance 90 | .request(config) 91 | .then((res) => { 92 | // 1.单个请求对数据的处理 93 | if (config.interceptors?.responseInterceptor) { 94 | res = config.interceptors.responseInterceptor(res) 95 | } 96 | // 2.将showLoading设置true, 这样不会影响下一个请求 97 | this.showLoading = DEAFULT_LOADING 98 | 99 | // 3.将结果resolve返回出去 100 | resolve(res) 101 | }) 102 | .catch((err) => { 103 | // 将showLoading设置true, 这样不会影响下一个请求 104 | this.showLoading = DEAFULT_LOADING 105 | reject(err) 106 | return err 107 | }) 108 | }) 109 | } 110 | 111 | get(config: HYRequestConfig): Promise { 112 | return this.request({ ...config, method: 'GET' }) 113 | } 114 | 115 | post(config: HYRequestConfig): Promise { 116 | return this.request({ ...config, method: 'POST' }) 117 | } 118 | 119 | delete(config: HYRequestConfig): Promise { 120 | return this.request({ ...config, method: 'DELETE' }) 121 | } 122 | 123 | patch(config: HYRequestConfig): Promise { 124 | return this.request({ ...config, method: 'PATCH' }) 125 | } 126 | } 127 | 128 | export default HYRequest 129 | -------------------------------------------------------------------------------- /src/service/request/type.ts: -------------------------------------------------------------------------------- 1 | import type { AxiosRequestConfig, AxiosResponse } from 'axios' 2 | 3 | export interface HYRequestInterceptors { 4 | requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig 5 | requestInterceptorCatch?: (error: any) => any 6 | responseInterceptor?: (res: T) => T 7 | responseInterceptorCatch?: (error: any) => any 8 | } 9 | 10 | export interface HYRequestConfig extends AxiosRequestConfig { 11 | interceptors?: HYRequestInterceptors 12 | showLoading?: boolean 13 | } 14 | -------------------------------------------------------------------------------- /src/service/types.ts: -------------------------------------------------------------------------------- 1 | export interface IDataType { 2 | code: number 3 | data: T 4 | } 5 | -------------------------------------------------------------------------------- /src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | declare module '*.vue' { 3 | import type { DefineComponent } from 'vue' 4 | const component: DefineComponent<{}, {}, any> 5 | export default component 6 | } 7 | 8 | declare let $store: any 9 | declare module '*.json' 10 | -------------------------------------------------------------------------------- /src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { createStore, Store, useStore as useVuexStore } from 'vuex' 2 | 3 | import login from './login/login' 4 | import system from './main/system/system' 5 | import dashboard from './main/analysis/dashboard' 6 | 7 | import { getPageListData } from '@/service/main/system/system' 8 | 9 | import { IRootState, IStoreType } from './types' 10 | 11 | const store = createStore({ 12 | state() { 13 | return { 14 | name: 'coderwhy', 15 | age: 18, 16 | entireDepartment: [], 17 | entireRole: [], 18 | entireMenu: [] 19 | } 20 | }, 21 | mutations: { 22 | changeEntireDepartment(state, list) { 23 | state.entireDepartment = list 24 | }, 25 | changeEntireRole(state, list) { 26 | state.entireRole = list 27 | }, 28 | changeEntireMenu(state, list) { 29 | state.entireMenu = list 30 | } 31 | }, 32 | getters: {}, 33 | actions: { 34 | async getInitialDataAction({ commit }) { 35 | // 1.请求部门和角色数据 36 | const departmentResult = await getPageListData('/department/list', { 37 | offset: 0, 38 | size: 1000 39 | }) 40 | const { list: departmentList } = departmentResult.data 41 | const roleResult = await getPageListData('/role/list', { 42 | offset: 0, 43 | size: 1000 44 | }) 45 | const { list: roleList } = roleResult.data 46 | const menuResult = await getPageListData('/menu/list', {}) 47 | const { list: menuList } = menuResult.data 48 | 49 | // 2.保存数据 50 | commit('changeEntireDepartment', departmentList) 51 | commit('changeEntireRole', roleList) 52 | commit('changeEntireMenu', menuList) 53 | } 54 | }, 55 | modules: { 56 | login, 57 | system, 58 | dashboard 59 | } 60 | }) 61 | 62 | export function setupStore() { 63 | store.dispatch('login/loadLocalLogin') 64 | // store.dispatch('getInitialDataAction') 65 | } 66 | 67 | export function useStore(): Store { 68 | return useVuexStore() 69 | } 70 | 71 | export default store 72 | -------------------------------------------------------------------------------- /src/store/login/login.ts: -------------------------------------------------------------------------------- 1 | import { Module } from 'vuex' 2 | 3 | import { 4 | accountLoginRequest, 5 | requestUserInfoById, 6 | requestUserMenusByRoleId 7 | } from '@/service/login/login' 8 | import localCache from '@/utils/cache' 9 | import { mapMenusToRoutes, mapMenusToPermissions } from '@/utils/map-menus' 10 | import router from '@/router' 11 | 12 | import { IAccount } from '@/service/login/type' 13 | import { ILoginState } from './types' 14 | import { IRootState } from '../types' 15 | 16 | const loginModule: Module = { 17 | namespaced: true, 18 | state() { 19 | return { 20 | token: '', 21 | userInfo: {}, 22 | userMenus: [], 23 | permissions: [] 24 | } 25 | }, 26 | getters: {}, 27 | mutations: { 28 | changeToken(state, token: string) { 29 | state.token = token 30 | }, 31 | changeUserInfo(state, userInfo: any) { 32 | state.userInfo = userInfo 33 | }, 34 | changeUserMenus(state, userMenus: any) { 35 | state.userMenus = userMenus 36 | 37 | console.log('注册动态路由') 38 | 39 | // userMenus => routes 40 | const routes = mapMenusToRoutes(userMenus) 41 | 42 | // 将routes => router.main.children 43 | routes.forEach((route) => { 44 | router.addRoute('main', route) 45 | }) 46 | 47 | // 获取用户按钮的权限 48 | const permissions = mapMenusToPermissions(userMenus) 49 | state.permissions = permissions 50 | } 51 | }, 52 | actions: { 53 | async accountLoginAction({ commit, dispatch }, payload: IAccount) { 54 | // 1.实现登录逻辑 55 | const loginResult = await accountLoginRequest(payload) 56 | const { id, token } = loginResult.data 57 | commit('changeToken', token) 58 | localCache.setCache('token', token) 59 | 60 | // 发送初始化的请求(完整的role/department) 61 | dispatch('getInitialDataAction', null, { root: true }) 62 | 63 | // 2.请求用户信息 64 | const userInfoResult = await requestUserInfoById(id) 65 | const userInfo = userInfoResult.data 66 | commit('changeUserInfo', userInfo) 67 | localCache.setCache('userInfo', userInfo) 68 | 69 | // 3.请求用户菜单 70 | const userMenusResult = await requestUserMenusByRoleId(userInfo.role.id) 71 | const userMenus = userMenusResult.data 72 | commit('changeUserMenus', userMenus) 73 | localCache.setCache('userMenus', userMenus) 74 | 75 | // 4.跳到首页 76 | router.push('/main') 77 | }, 78 | loadLocalLogin({ commit, dispatch }) { 79 | const token = localCache.getCache('token') 80 | if (token) { 81 | commit('changeToken', token) 82 | // 发送初始化的请求(完整的role/department) 83 | dispatch('getInitialDataAction', null, { root: true }) 84 | } 85 | const userInfo = localCache.getCache('userInfo') 86 | if (userInfo) { 87 | commit('changeUserInfo', userInfo) 88 | } 89 | const userMenus = localCache.getCache('userMenus') 90 | if (userMenus) { 91 | commit('changeUserMenus', userMenus) 92 | } 93 | } 94 | } 95 | } 96 | 97 | export default loginModule 98 | -------------------------------------------------------------------------------- /src/store/login/types.ts: -------------------------------------------------------------------------------- 1 | export interface ILoginState { 2 | token: string 3 | userInfo: any 4 | userMenus: any 5 | permissions: string[] 6 | } 7 | -------------------------------------------------------------------------------- /src/store/main/analysis/dashboard.ts: -------------------------------------------------------------------------------- 1 | import { Module } from 'vuex' 2 | 3 | import { 4 | getCategoryGoodsCount, 5 | getCategoryGoodsSale, 6 | getCategoryGoodsFavor, 7 | getAddressGoodsSale 8 | } from '@/service/main/analysis/dashboard' 9 | 10 | import { IDashboardState } from './types' 11 | import { IRootState } from '../../types' 12 | 13 | const dashboardModule: Module = { 14 | namespaced: true, 15 | state() { 16 | return { 17 | categoryGoodsCount: [], 18 | categoryGoodsSale: [], 19 | categoryGoodsFavor: [], 20 | addressGoodsSale: [] 21 | } 22 | }, 23 | mutations: { 24 | changeCategoryGoodsCount(state, list) { 25 | state.categoryGoodsCount = list 26 | }, 27 | changeCategoryGoodsSale(state, list) { 28 | state.categoryGoodsSale = list 29 | }, 30 | changeCategoryGoodsFavor(state, list) { 31 | state.categoryGoodsFavor = list 32 | }, 33 | changeAddressGoodsSale(state, list) { 34 | state.addressGoodsSale = list 35 | } 36 | }, 37 | actions: { 38 | async getDashboardDataAction({ commit }) { 39 | const categoryCountResult = await getCategoryGoodsCount() 40 | commit('changeCategoryGoodsCount', categoryCountResult.data) 41 | const categorySaleResult = await getCategoryGoodsSale() 42 | commit('changeCategoryGoodsSale', categorySaleResult.data) 43 | const categoryFavorResult = await getCategoryGoodsFavor() 44 | commit('changeCategoryGoodsFavor', categoryFavorResult.data) 45 | const addressGoodsResult = await getAddressGoodsSale() 46 | commit('changeAddressGoodsSale', addressGoodsResult.data) 47 | } 48 | } 49 | } 50 | 51 | export default dashboardModule 52 | -------------------------------------------------------------------------------- /src/store/main/analysis/types.ts: -------------------------------------------------------------------------------- 1 | export interface IDashboardState { 2 | categoryGoodsCount: any[] 3 | categoryGoodsSale: any[] 4 | categoryGoodsFavor: any[] 5 | addressGoodsSale: any[] 6 | } 7 | -------------------------------------------------------------------------------- /src/store/main/system/system.ts: -------------------------------------------------------------------------------- 1 | import { Module } from 'vuex' 2 | import { IRootState } from '@/store/types' 3 | import { ISystemState } from './types' 4 | 5 | import { 6 | getPageListData, 7 | deletePageData, 8 | createPageData, 9 | editPageData 10 | } from '@/service/main/system/system' 11 | 12 | const systemModule: Module = { 13 | namespaced: true, 14 | state() { 15 | return { 16 | usersList: [], 17 | usersCount: 0, 18 | roleList: [], 19 | roleCount: 0, 20 | goodsList: [], 21 | goodsCount: 0, 22 | menuList: [], 23 | menuCount: 0 24 | } 25 | }, 26 | mutations: { 27 | changeUsersList(state, userList: any[]) { 28 | state.usersList = userList 29 | }, 30 | changeUsersCount(state, userCount: number) { 31 | state.usersCount = userCount 32 | }, 33 | changeRoleList(state, list: any[]) { 34 | state.roleList = list 35 | }, 36 | changeRoleCount(state, count: number) { 37 | state.roleCount = count 38 | }, 39 | changeGoodsList(state, list: any[]) { 40 | state.goodsList = list 41 | }, 42 | changeGoodsCount(state, count: number) { 43 | state.goodsCount = count 44 | }, 45 | changeMenuList(state, list: any[]) { 46 | state.menuList = list 47 | }, 48 | changeMenuCount(state, count: number) { 49 | state.menuCount = count 50 | } 51 | }, 52 | getters: { 53 | pageListData(state) { 54 | return (pageName: string) => { 55 | return (state as any)[`${pageName}List`] 56 | } 57 | }, 58 | pageListCount(state) { 59 | return (pageName: string) => { 60 | return (state as any)[`${pageName}Count`] 61 | } 62 | } 63 | }, 64 | actions: { 65 | async getPageListAction({ commit }, payload: any) { 66 | // 1.获取pageUrl 67 | const pageName = payload.pageName 68 | const pageUrl = `/${pageName}/list` 69 | 70 | // 2.对页面发送请求 71 | const pageResult = await getPageListData(pageUrl, payload.queryInfo) 72 | 73 | // 3.将数据存储到state中 74 | const { list, totalCount } = pageResult.data 75 | 76 | const changePageName = 77 | pageName.slice(0, 1).toUpperCase() + pageName.slice(1) 78 | commit(`change${changePageName}List`, list) 79 | commit(`change${changePageName}Count`, totalCount) 80 | }, 81 | 82 | async deletePageDataAction({ dispatch }, payload: any) { 83 | // 1.获取pageName和id 84 | // pageName -> /users 85 | // id -> /users/id 86 | const { pageName, id } = payload 87 | const pageUrl = `/${pageName}/${id}` 88 | 89 | // 2.调用删除网络请求 90 | await deletePageData(pageUrl) 91 | 92 | // 3.重新请求最新的数据 93 | dispatch('getPageListAction', { 94 | pageName, 95 | queryInfo: { 96 | offset: 0, 97 | size: 10 98 | } 99 | }) 100 | }, 101 | 102 | async createPageDataAction({ dispatch }, payload: any) { 103 | // 1.创建数据的请求 104 | const { pageName, newData } = payload 105 | const pageUrl = `/${pageName}` 106 | await createPageData(pageUrl, newData) 107 | 108 | // 2.请求最新的数据 109 | dispatch('getPageListAction', { 110 | pageName, 111 | queryInfo: { 112 | offset: 0, 113 | size: 10 114 | } 115 | }) 116 | }, 117 | 118 | async editPageDataAction({ dispatch }, payload: any) { 119 | // 1.编辑数据的请求 120 | const { pageName, editData, id } = payload 121 | console.log(editData) 122 | const pageUrl = `/${pageName}/${id}` 123 | await editPageData(pageUrl, editData) 124 | 125 | // 2.请求最新的数据 126 | dispatch('getPageListAction', { 127 | pageName, 128 | queryInfo: { 129 | offset: 0, 130 | size: 10 131 | } 132 | }) 133 | } 134 | } 135 | } 136 | 137 | export default systemModule 138 | -------------------------------------------------------------------------------- /src/store/main/system/types.ts: -------------------------------------------------------------------------------- 1 | export interface ISystemState { 2 | usersList: any[] 3 | usersCount: number 4 | roleList: any[] 5 | roleCount: number 6 | goodsList: any[] 7 | goodsCount: number 8 | menuList: any[] 9 | menuCount: number 10 | } 11 | -------------------------------------------------------------------------------- /src/store/types.ts: -------------------------------------------------------------------------------- 1 | import { ILoginState } from './login/types' 2 | import { ISystemState } from './main/system/types' 3 | import { IDashboardState } from './main/analysis/types' 4 | 5 | export interface IRootState { 6 | name: string 7 | age: number 8 | entireDepartment: any[] 9 | entireRole: any[] 10 | entireMenu: any[] 11 | } 12 | 13 | export interface IRootWithModule { 14 | login: ILoginState 15 | system: ISystemState 16 | dashboard: IDashboardState 17 | } 18 | 19 | export type IStoreType = IRootState & IRootWithModule 20 | -------------------------------------------------------------------------------- /src/utils/cache.ts: -------------------------------------------------------------------------------- 1 | class LocalCache { 2 | setCache(key: string, value: any) { 3 | window.localStorage.setItem(key, JSON.stringify(value)) 4 | } 5 | 6 | getCache(key: string) { 7 | // obj => string => obj 8 | const value = window.localStorage.getItem(key) 9 | if (value) { 10 | return JSON.parse(value) 11 | } 12 | } 13 | 14 | deleteCache(key: string) { 15 | window.localStorage.removeItem(key) 16 | } 17 | 18 | clearCache() { 19 | window.localStorage.clear() 20 | } 21 | } 22 | 23 | export default new LocalCache() 24 | -------------------------------------------------------------------------------- /src/utils/date-format.ts: -------------------------------------------------------------------------------- 1 | import dayjs from 'dayjs' 2 | import utc from 'dayjs/plugin/utc' 3 | 4 | dayjs.extend(utc) 5 | 6 | const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss' 7 | 8 | export function formatUtcString( 9 | utcString: string, 10 | format: string = DATE_TIME_FORMAT 11 | ) { 12 | return dayjs.utc(utcString).utcOffset(8).format(format) 13 | } 14 | 15 | // export function formatTimestamp( 16 | // timestamp: number, 17 | // format: string = DATE_TIME_FORMAT 18 | // ) { 19 | // return '' 20 | // } 21 | -------------------------------------------------------------------------------- /src/utils/map-menus.ts: -------------------------------------------------------------------------------- 1 | import { IBreadcrumb } from '@/base-ui/breadcrumb' 2 | import { RouteRecordRaw } from 'vue-router' 3 | 4 | let firstMenu: any = null 5 | 6 | export function mapMenusToRoutes(userMenus: any[]): RouteRecordRaw[] { 7 | const routes: RouteRecordRaw[] = [] 8 | 9 | // 1.先去加载默认所有的routes 10 | const allRoutes: RouteRecordRaw[] = [] 11 | const routeFiles = require.context('../router/main', true, /\.ts/) 12 | routeFiles.keys().forEach((key) => { 13 | const route = require('../router/main' + key.split('.')[1]) 14 | allRoutes.push(route.default) 15 | }) 16 | 17 | // 2.根据菜单获取需要添加的routes 18 | // userMenus: 19 | // type === 1 -> children -> type === 1 20 | // type === 2 -> url -> route 21 | const _recurseGetRoute = (menus: any[]) => { 22 | for (const menu of menus) { 23 | if (menu.type === 2) { 24 | const route = allRoutes.find((route) => route.path === menu.url) 25 | if (route) routes.push(route) 26 | if (!firstMenu) { 27 | firstMenu = menu 28 | } 29 | } else { 30 | _recurseGetRoute(menu.children) 31 | } 32 | } 33 | } 34 | 35 | _recurseGetRoute(userMenus) 36 | 37 | return routes 38 | } 39 | 40 | export function pathMapBreadcrumbs(userMenus: any[], currentPath: string) { 41 | const breadcrumbs: IBreadcrumb[] = [] 42 | pathMapToMenu(userMenus, currentPath, breadcrumbs) 43 | return breadcrumbs 44 | } 45 | 46 | // /main/system/role -> type === 2 对应menu 47 | export function pathMapToMenu( 48 | userMenus: any[], 49 | currentPath: string, 50 | breadcrumbs?: IBreadcrumb[] 51 | ): any { 52 | for (const menu of userMenus) { 53 | if (menu.type === 1) { 54 | const findMenu = pathMapToMenu(menu.children ?? [], currentPath) 55 | if (findMenu) { 56 | breadcrumbs?.push({ name: menu.name }) 57 | breadcrumbs?.push({ name: findMenu.name }) 58 | return findMenu 59 | } 60 | } else if (menu.type === 2 && menu.url === currentPath) { 61 | return menu 62 | } 63 | } 64 | } 65 | 66 | // export function pathMapBreadcrumbs(userMenus: any[], currentPath: string) { 67 | // const breadcrumbs: IBreadcrumb[] = [] 68 | 69 | // for (const menu of userMenus) { 70 | // if (menu.type === 1) { 71 | // const findMenu = pathMapToMenu(menu.children ?? [], currentPath) 72 | // if (findMenu) { 73 | // breadcrumbs.push({ name: menu.name, path: menu.url }) 74 | // breadcrumbs.push({ name: findMenu.name, path: findMenu.url }) 75 | // return findMenu 76 | // } 77 | // } else if (menu.type === 2 && menu.url === currentPath) { 78 | // return menu 79 | // } 80 | // } 81 | 82 | // return breadcrumbs 83 | // } 84 | 85 | // // /main/system/role -> type === 2 对应menu 86 | // export function pathMapToMenu(userMenus: any[], currentPath: string): any { 87 | // for (const menu of userMenus) { 88 | // if (menu.type === 1) { 89 | // const findMenu = pathMapToMenu(menu.children ?? [], currentPath) 90 | // if (findMenu) { 91 | // return findMenu 92 | // } 93 | // } else if (menu.type === 2 && menu.url === currentPath) { 94 | // return menu 95 | // } 96 | // } 97 | // } 98 | 99 | export function mapMenusToPermissions(userMenus: any[]) { 100 | const permissions: string[] = [] 101 | 102 | const _recurseGetPermission = (menus: any[]) => { 103 | for (const menu of menus) { 104 | if (menu.type === 1 || menu.type === 2) { 105 | _recurseGetPermission(menu.children ?? []) 106 | } else if (menu.type === 3) { 107 | permissions.push(menu.permission) 108 | } 109 | } 110 | } 111 | _recurseGetPermission(userMenus) 112 | 113 | return permissions 114 | } 115 | 116 | export function menuMapLeafKeys(menuList: any[]) { 117 | const leftKeys: number[] = [] 118 | 119 | const _recurseGetLeaf = (menuList: any[]) => { 120 | for (const menu of menuList) { 121 | if (menu.children) { 122 | _recurseGetLeaf(menu.children) 123 | } else { 124 | leftKeys.push(menu.id) 125 | } 126 | } 127 | } 128 | _recurseGetLeaf(menuList) 129 | 130 | return leftKeys 131 | } 132 | 133 | export { firstMenu } 134 | -------------------------------------------------------------------------------- /src/views/login/config/account-config.ts: -------------------------------------------------------------------------------- 1 | // 编写好规则 2 | export const rules = { 3 | name: [ 4 | { 5 | required: true, 6 | message: '用户名是必传内容~', 7 | trigger: 'blur' 8 | }, 9 | { 10 | pattern: /^[a-z0-9]{5,10}$/, 11 | message: '用户名必须是5~10个字母或者数字~', 12 | trigger: 'blur' 13 | } 14 | ], 15 | password: [ 16 | { 17 | required: true, 18 | message: '密码是必传内容~', 19 | trigger: 'blur' 20 | }, 21 | { 22 | pattern: /^[a-z0-9]{3,}$/, 23 | message: '用户名必须是3位以上的字母或者数字~', 24 | trigger: 'blur' 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /src/views/login/cpns/login-account.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/views/login/cpns/login-panel.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 66 | 67 | 88 | -------------------------------------------------------------------------------- /src/views/login/cpns/login-phone.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 31 | 32 | 41 | -------------------------------------------------------------------------------- /src/views/login/login.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | 21 | 31 | -------------------------------------------------------------------------------- /src/views/main/analysis/dashboard/dashboard.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 105 | 106 | 111 | -------------------------------------------------------------------------------- /src/views/main/analysis/overview/overview.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/views/main/main.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 44 | 45 | 102 | -------------------------------------------------------------------------------- /src/views/main/product/category/category.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/views/main/product/goods/config/content.config.ts: -------------------------------------------------------------------------------- 1 | export const contentTableConfig = { 2 | title: '商品列表', 3 | propList: [ 4 | { prop: 'name', label: '商品名称', minWidth: '80' }, 5 | { prop: 'oldPrice', label: '原价格', minWidth: '80', slotName: 'oldPrice' }, 6 | { prop: 'newPrice', label: '现价格', minWidth: '80' }, 7 | { prop: 'imgUrl', label: '商品图片', minWidth: '100', slotName: 'image' }, 8 | { prop: 'status', label: '状态', minWidth: '100', slotName: 'status' }, 9 | { 10 | prop: 'createAt', 11 | label: '创建时间', 12 | minWidth: '250', 13 | slotName: 'createAt' 14 | }, 15 | { 16 | prop: 'updateAt', 17 | label: '更新时间', 18 | minWidth: '250', 19 | slotName: 'updateAt' 20 | }, 21 | { label: '操作', minWidth: '120', slotName: 'handler' } 22 | ], 23 | showIndexColumn: true, 24 | showSelectColumn: true 25 | } 26 | -------------------------------------------------------------------------------- /src/views/main/product/goods/goods.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/views/main/story/chat/chat.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/views/main/story/list/list.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/views/main/system/department/department.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/views/main/system/menu/config/content.config.ts: -------------------------------------------------------------------------------- 1 | export const contentTableConfig = { 2 | title: '菜单列表', 3 | propList: [ 4 | { prop: 'name', label: '菜单名称', minWidth: '100' }, 5 | { prop: 'type', label: '类型', minWidth: '60' }, 6 | { prop: 'url', label: '菜单url', minWidth: '100' }, 7 | { prop: 'icon', label: '菜单icon', minWidth: '100' }, 8 | { prop: 'permission', label: '按钮权限', minWidth: '100' }, 9 | { 10 | prop: 'createAt', 11 | label: '创建时间', 12 | minWidth: '220', 13 | slotName: 'createAt' 14 | }, 15 | { 16 | prop: 'updateAt', 17 | label: '更新时间', 18 | minWidth: '220', 19 | slotName: 'updateAt' 20 | }, 21 | { label: '操作', minWidth: '120', slotName: 'handler' } 22 | ], 23 | showIndexColumn: false, 24 | showSelectColumn: false, 25 | childrenProps: { 26 | rowKey: 'id', 27 | treeProp: { 28 | children: 'children' 29 | } 30 | }, 31 | showFooter: false 32 | } 33 | -------------------------------------------------------------------------------- /src/views/main/system/menu/menu.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/views/main/system/role/config/content.config.ts: -------------------------------------------------------------------------------- 1 | export const contentTableConfig = { 2 | title: '用户列表', 3 | propList: [ 4 | { prop: 'name', label: '角色名', minWidth: '100' }, 5 | { prop: 'intro', label: '权限介绍', minWidth: '100' }, 6 | { 7 | prop: 'createAt', 8 | label: '创建时间', 9 | minWidth: '250', 10 | slotName: 'createAt' 11 | }, 12 | { 13 | prop: 'updateAt', 14 | label: '更新时间', 15 | minWidth: '250', 16 | slotName: 'updateAt' 17 | }, 18 | { label: '操作', minWidth: '120', slotName: 'handler' } 19 | ], 20 | showIndexColumn: true, 21 | showSelectColumn: true 22 | } 23 | -------------------------------------------------------------------------------- /src/views/main/system/role/config/modal.config.ts: -------------------------------------------------------------------------------- 1 | import { IForm } from '@/base-ui/form' 2 | 3 | export const modalConfig: IForm = { 4 | formItems: [ 5 | { 6 | field: 'name', 7 | type: 'input', 8 | label: '角色名', 9 | placeholder: '请输入角色名' 10 | }, 11 | { 12 | field: 'intro', 13 | type: 'input', 14 | label: '角色介绍', 15 | placeholder: '请输入角色介绍' 16 | } 17 | ], 18 | colLayout: { span: 24 }, 19 | itemStyle: {} 20 | } 21 | -------------------------------------------------------------------------------- /src/views/main/system/role/config/search.config.ts: -------------------------------------------------------------------------------- 1 | import { IForm } from '@/base-ui/form' 2 | 3 | export const searchFormConfig: IForm = { 4 | labelWidth: '120px', 5 | formItems: [ 6 | { 7 | field: 'name', 8 | type: 'input', 9 | label: '角色名称', 10 | placeholder: '请输入角色名称' 11 | }, 12 | { 13 | field: 'intro', 14 | type: 'input', 15 | label: '权限介绍', 16 | placeholder: '请输入权限介绍' 17 | }, 18 | { 19 | field: 'createTime', 20 | type: 'datepicker', 21 | label: '创建时间', 22 | otherOptions: { 23 | startPlaceholder: '开始时间', 24 | endPlaceholder: '结束时间', 25 | type: 'daterange' 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /src/views/main/system/role/role.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 95 | 96 | 101 | -------------------------------------------------------------------------------- /src/views/main/system/user/config/content.config.ts: -------------------------------------------------------------------------------- 1 | export const contentTableConfig = { 2 | title: '用户列表', 3 | propList: [ 4 | { prop: 'name', label: '用户名', minWidth: '100' }, 5 | { prop: 'realname', label: '真实姓名', minWidth: '100' }, 6 | { prop: 'cellphone', label: '手机号码', minWidth: '100' }, 7 | { prop: 'enable', label: '状态', minWidth: '100', slotName: 'status' }, 8 | { 9 | prop: 'createAt', 10 | label: '创建时间', 11 | minWidth: '250', 12 | slotName: 'createAt' 13 | }, 14 | { 15 | prop: 'updateAt', 16 | label: '更新时间', 17 | minWidth: '250', 18 | slotName: 'updateAt' 19 | }, 20 | { label: '操作', minWidth: '120', slotName: 'handler' } 21 | ], 22 | showIndexColumn: true, 23 | showSelectColumn: true 24 | } 25 | -------------------------------------------------------------------------------- /src/views/main/system/user/config/modal.config.ts: -------------------------------------------------------------------------------- 1 | import { IForm } from '@/base-ui/form' 2 | 3 | export const modalConfig: IForm = { 4 | formItems: [ 5 | { 6 | field: 'name', 7 | type: 'input', 8 | label: '用户名', 9 | placeholder: '请输入用户名' 10 | }, 11 | { 12 | field: 'realname', 13 | type: 'input', 14 | label: '真实姓名', 15 | placeholder: '请输入真实姓名' 16 | }, 17 | { 18 | field: 'password', 19 | type: 'password', 20 | label: '用户密码', 21 | placeholder: '请输入密码', 22 | isHidden: false 23 | }, 24 | { 25 | field: 'cellphone', 26 | type: 'input', 27 | label: '电话号码', 28 | placeholder: '请输入电话号码' 29 | }, 30 | { 31 | field: 'departmentId', 32 | type: 'select', 33 | label: '选择部门', 34 | placeholder: '请选择部门', 35 | options: [] 36 | }, 37 | { 38 | field: 'roleId', 39 | type: 'select', 40 | label: '选择角色', 41 | placeholder: '请选择角色', 42 | options: [] 43 | } 44 | ], 45 | colLayout: { span: 24 }, 46 | itemStyle: {} 47 | } 48 | -------------------------------------------------------------------------------- /src/views/main/system/user/config/search.config.ts: -------------------------------------------------------------------------------- 1 | import { IForm } from '@/base-ui/form' 2 | 3 | export const searchFormConfig: IForm = { 4 | labelWidth: '120px', 5 | itemStyle: { 6 | padding: '10px 40px' 7 | }, 8 | colLayout: { 9 | span: 8 10 | }, 11 | formItems: [ 12 | { 13 | field: 'id', 14 | type: 'input', 15 | label: 'id', 16 | placeholder: '请输入id' 17 | }, 18 | { 19 | field: 'name', 20 | type: 'input', 21 | label: '用户名', 22 | placeholder: '请输入用户名' 23 | }, 24 | { 25 | field: 'realname', 26 | type: 'input', 27 | label: '真实姓名', 28 | placeholder: '请输入真实姓名' 29 | }, 30 | { 31 | field: 'cellphone', 32 | type: 'input', 33 | label: '电话号码', 34 | placeholder: '请输入电话号码' 35 | }, 36 | { 37 | field: 'enable', 38 | type: 'select', 39 | label: '用户状态', 40 | placeholder: '请选择用户状态', 41 | options: [ 42 | { title: '启用', value: 1 }, 43 | { title: '禁用', value: 0 } 44 | ] 45 | }, 46 | { 47 | field: 'createAt', 48 | type: 'datepicker', 49 | label: '创建时间', 50 | otherOptions: { 51 | startPlaceholder: '开始时间', 52 | endPlaceholder: '结束时间', 53 | type: 'daterange' 54 | } 55 | } 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /src/views/main/system/user/user.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /src/views/not-found/not-found.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // 目标代码(ts -> js(es5/6/7)) 4 | "target": "esnext", 5 | // 目标代码需要使用的模块化方案(commonjs require/module.exports/es module import/export) 6 | "module": "esnext", 7 | // 严格一些严格的检查(any) 8 | "strict": true, 9 | // 对jsx进行怎么样的处理 10 | "jsx": "preserve", 11 | // 辅助的导入功能 12 | "importHelpers": true, 13 | // 按照node的方式去解析模块 import "/index.node" 14 | "moduleResolution": "node", 15 | // 跳过一些库的类型检测 (axios -> 类型/ lodash -> @types/lodash / 其他的第三方) 16 | // import { Person } from 'axios' 17 | "skipLibCheck": true, 18 | // export default/module.exports = {} 19 | // es module 和 commonjs 20 | "esModuleInterop": true, 21 | "allowSyntheticDefaultImports": true, 22 | // 要不要生成映射文件(ts -> js) 23 | "sourceMap": true, 24 | // 文件路径在解析时, 基本url 25 | "baseUrl": ".", 26 | // 指定具体要解析使用的类型 27 | "types": ["webpack-env"], 28 | // 路径解析(类似于webpack alias) 29 | "paths": { 30 | "@/*": ["src/*"], 31 | "components/*": ["src/components/*"] 32 | }, 33 | // 可以指定在项目中可以使用哪里库的类型(Proxy/Window/Document) 34 | "lib": ["esnext", "dom", "dom.iterable", "scripthost"] 35 | }, 36 | "include": [ 37 | "src/**/*.ts", 38 | "src/**/*.tsx", 39 | "src/**/*.vue", 40 | "tests/**/*.ts", 41 | "tests/**/*.tsx" 42 | ], 43 | "exclude": ["node_modules"] 44 | } 45 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | // 1.配置方式一: CLI提供的属性 5 | outputDir: './build', 6 | // publicPath: './', 7 | devServer: { 8 | proxy: { 9 | '^/api': { 10 | target: 'http://152.136.185.210:4000', 11 | pathRewrite: { 12 | '^/api': '' 13 | }, 14 | changeOrigin: true 15 | } 16 | } 17 | }, 18 | // 2.配置方式二: 和webpack属性完全一致, 最后会进行合并 19 | configureWebpack: { 20 | resolve: { 21 | alias: { 22 | components: '@/components' 23 | } 24 | } 25 | } 26 | // configureWebpack: (config) => { 27 | // config.resolve.alias = { 28 | // '@': path.resolve(__dirname, 'src'), 29 | // components: '@/components' 30 | // } 31 | // } 32 | // 3.配置方式三: 33 | // chainWebpack: (config) => { 34 | // config.resolve.alias 35 | // .set('@', path.resolve(__dirname, 'src')) 36 | // .set('components', '@/components') 37 | // } 38 | } 39 | --------------------------------------------------------------------------------