├── .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 |
2 |
3 |
4 |
5 |
6 |
7 |
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 |
--------------------------------------------------------------------------------
/src/assets/img/logo.svg:
--------------------------------------------------------------------------------
1 |
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 |
2 |
3 |
4 |
5 | {{
6 | item.name
7 | }}
8 |
9 |
10 |
11 |
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 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
11 |
12 |
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¿¥Ij@¢"],
21 | ["@@
¡@V^RqBbAnTXeRz¤L«³I"],
22 | ["@@ÆEEkWqë @"],
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ģcJe"],
52 | ["@@U`Ts¿mÂ"],
53 | [
54 | "@@oºƋÄdeVDJj£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|hYhgŃfmÖĩnºTÌSp¢dYĤ¶UĈjlǐpäìë|³kÛfw²Xjz~ÂqbTÑěŨ@|oMzv¢ZrÃVw¬ŧˏf°ÐTªqs{S¯r æÝlNd®²Ğ džiGĘJ¼lr}~K¨ŸƐÌWöÆzR¤lêmĞLÎ@¡|q]SvKÑcwpÏÏĿćènĪWlĄkT}J¤~ÈTdpddʾĬBVtEÀ¢ôPĎƗè@~kü\\rÊĔÖæW_§¼F´©òDòjYÈrbĞāøŀG{ƀ|¦ðrb|ÀH`pʞkvGpuARhÞÆǶgĘTǼƹS£¨¡ù³ŘÍ]¿ÂyôEP xX¶¹ÜO¡gÚ¡IwÃé¦ÅBÏ|ǰ
N«úmH¯âDùyŜŲIÄuШD¸dɂFOhđ©OiÃ`ww^ÌkÑH«ƇǤŗĺtFu
{Z}Ö@U´
ʚLg®¯Oı°Ãw ^VbÉsmA
ê]]w§RRl£ȭµu¯b{ÍDěïÿȧuT£ġěŗƃĝQ¨fVƋƅna@³@ďyýIĹÊKŭfċŰóxV@tƯJ]eR¾fe|rHA|h~Ėƍl§ÏlTíb ØoÅbbx³^zÃͶSj®AyÂhðk`«P˵EFÛ¬Y¨Ļrõqi¼Wi°§Ð±´°^[À|ĠO@ÆxO\\ta\\tĕtû{ġȧXýĪÓjùÎRb^ÎfK[ÝděYfíÙTyuUSyŌŏů@Oi½éŅaVcř§ax¹XŻácWU£ôãºQ¨÷Ñws¥qEHÙ|šYQoŕÇyáĂ£MðoťÊP¡mWO¡v{ôvîēÜISpÌhp¨ jdeŔQÖjX³àĈ[n`Yp@UcM`RKhEbpŞlNut®EtqnsÁgAiúoHqCXhfgu~ÏWP½¢G^}¯ÅīGCÑ^ãziMáļMTÃƘrMc|O_¯Ŏ´|morDkO\\mĆJfl@c̬¢aĦtRıÒ¾ùƀ^juųœKUFyƝ
īÛ÷ąV×qƥV¿aȉd³BqPBmaËđŻģmÅ®V¹d^KKonYg¯XhqaLdu¥ÍpDž¡KąÅkĝęěhq}HyÃ]¹ǧ£
Í÷¿qáµ§g¤o^á¾ZE¤i`ij{nOl»WÝĔįhgF[¿¡ßkOüš_ūiDZàUtėGyl}ÓM}jpEC~¡FtoQiHkk{Ã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 | "@@ÞĩÒSra}ÁyWix±Üe´lèßÓǏokćiµVZģ¡coTS˹ĪmnÕńehZg{gtwªpXaĚThȑp{¶Eh®RćƑP¿£Pmc¸mQÝWďȥoÅîɡųAďä³aÏJ½¥PGąSM
EÅruµéYÓŌ_dĒCoȵ]¯_²ÕjāK~©ÅØ^ÔkïçămÏk]±cݯÑÃmQÍ~_apm
~ç¡qu{JÅŧ·Ls}EyÁÆcI{¤IiCfUcƌÃp§]ě«vD@¡SÀµMÅwuYY¡DbÑc¡h×]nkoQdaMç~eDÛtT©±@¥ù@É¡ZcW|WqOJmĩl«ħşvOÓ«IqăV¥D[mI~Ó¢cehiÍ]Ɠ~ĥqX·eƷn±}v[ěďŕ]_œ`¹§ÕōIo©bs^}Ét±ū«³p£ÿ·Wµ|¡¥ăFÏs×¥ŅxÊdÒ{ºvĴÎêÌɊ²¶ü¨|ÞƸµȲLLúÉƎ¤ϊęĔV`_bªS^|dzY|dz¥pZbÆ£¶ÒK}tĦÔņƠPYznÍvX¶Ěn ĠÔzý¦ª÷ÑĸÙUȌ¸dòÜJð´ìúNM¬XZ´¤ŊǸ_tldI{¦ƀðĠȤ¥NehXnYGR° Ƭ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 | "@@¯PqFB
|S³C|kñHdiÄ¥sʼnÅ
PóÑÑE^ÅPpy_YtShQ·aHwsOnʼnÃs©iqjUSiº]ïW«gW¡ARë¥_sgÁnUI«m
]jvV¼euhwqAaW_µj
»çjioQR¹ēÃßt@r³[ÛlćË^ÍÉáGOUÛOB±XkŹ£k|e]olkVͼÕqtaÏõjgÁ£§U^RLËnX°ÇBz^~wfvypV ¯ƫĉ˭ȫƗŷɿÿĿƑ˃ĝÿÃǃßËőó©ǐȍŒĖ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¥FTÕ¿Jû]|mvāÎYua^WoÀa·ząÒot×¶CLƗi¯¤mƎHNJ¤îìɾŊìTdåwsRÖgĒųúÍġäÕ}Q¶¿A[¡{d×uQAMxVvMOmăl«ct[wº_ÇÊjb£ĦS_éQZ_lwgOiýe`YYLq§IÁdz£ÙË[ÕªuƏ³ÍTs·bÁĽäė[b[ŗfãcn¥îC¿÷µ[ŏÀQōĉm¿Á^£mJVmL[{Ï_£F¥Ö{ŹA}
×Wu©ÅaųijƳhB{·TQqÙIķËZđ©Yc|M¡
LeVUóK_QWk_ĥ¿ãZ»X\\ĴuUèlG®ěłTĠğDŃOrÍdÆÍz]±
ŭ©Å]ÅÐ}UË¥©TċïxgckfWgi\\ÏĒ¥HkµEë{»ÏetcG±ahUiñiWsɁ·cCÕk]wȑ|ća}w
VaĚá G°ùnM¬¯{ÈÐÆA¥ÄêJxÙ¢hP¢ÛºµwWOóFÁz^ÀŗÎú´§¢T¤ǻƺSėǵhÝÅQgvBHouʝl_o¿Ga{ïq{¥|ſĿHĂ÷aĝÇqZñiñC³ª
»E`¨åXēÕqÉû[l}ç@čƘóO¿¡FUsAʽīccocÇS}£IS~ălkĩXçmĈ
ŀÐoÐdxÒuL^T{r@¢ÍĝKén£kQyÅõËXŷƏL§~}kq»IHėDžjĝ»ÑÞoå°qTt|r©ÏS¯·eŨĕx«È[eM¿yupN~¹ÏyN£{©għWí»Í¾səšDž_ÃĀɗ±ąijĉʍŌŷSÉA±åǥɋ@ë£R©ąP©}ĹªƏj¹erLDĝ·{i«ƫC£µsKC
GS|úþXgp{ÁX¿ć{ƱȏñZáĔyoÁhA}ŅĆfdʼn_¹Y°ėǩÑ¡H¯¶oMQqð¡Ë|Ñ`ƭŁX½·óÛxğįÅcQs«tȋDžFù^it«Č¯[hAi©á¥ÇĚ×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ľýľώȪƺɂļxZĈ}ÌʼnŪĺœĭFЛĽ̅ȣͽÒŵìƩÇϋÿȮǡŏçƑůĕ~ǼȳÐUfdIxÿ\\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~´°ÎFCU¼pĀēƄN¦¾O¶łKĊOjĚj´ĜYp{¦SĚÍ\\TתV÷Ší¨ÅDK°ßtŇĔK¨ǵÂcḷ̌ĚǣȄĽFlġUĵŇȣFʉɁMğįʏƶɷØŭOǽ«ƽū¹Ʊő̝Ȩ§ȞʘĖiɜɶʦ}¨֪ࠜ̀ƇǬ¹ǨE˦ĥªÔêFxúQEr´Wrh¤Ɛ \\talĈDJÜ|[Pll̚¸ƎGú´P¬W¦^¦H]prRn|or¾wLVnÇIujkmon£cX^Bh`¥V¦U¤¸}xRj[^xN[~ªxQ[`ªHÆÂExx^wN¶Ê|¨ìMrdYpoRzNyÀDs~bcfÌ`L¾n|¾T°c¨È¢ar¤`[|òDŞĔöxElÖdHÀI`Ď\\Àì~ÆR¼tf¦^¢ķ¶eÐÚMptgjɡČÅ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£ʺoqNwğc`uetOj×°KJ±qÆġmĚŗos¬
qehqsuH{¸kH¡
ÊRǪÇƌbȆ¢´äÜ¢NìÉʖ¦â©Ġu¦öČ^â£ĂhĖMÈÄw\\fŦ°W ¢¾luŸDw\\̀ʉÌÛ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@@sa"],
109 | ["@@MnNm"],
110 | ["@@dc"],
111 | ["@@eÀC@b"],
112 | ["@@f
XwkbrÄ`qg"],
113 | ["@@^jtWQ"],
114 | ["@@~ Y]c"],
115 | ["@@G`ĔN^_¿ZÃM"],
116 | ["@@iX¶BY"],
117 | ["@@YZ"],
118 | ["@@L_{Epf"],
119 | ["@@^WqCT\\"],
120 | ["@@\\[§t|¤_"],
121 | ["@@m`n_"],
122 | ["@@Ïxnj{q_×^Giip"],
123 | [
124 | "@@@é^BntaÊU]x ¯ÄPIJ°hʙK³VÕ@Y~|EvĹsǦL^pòŸÒG Ël]xxÄ_fT¤Ď¤cPC¨¸TVjbgH²sdÎdHt`B²¬GJję¶[ÐhjeXdlwhðSȦªVÊÏÆZÆŶ®²^ÎyÅÎcPqńĚDMħĜŁHkçvV[ij¼WYÀäĦ`XlR`ôLUVfK¢{NZdĒªYĸÌÚJRr¸SA|ƴgŴĴÆbvªØX~źB|¦ÕE¤Ð`\\|KUnnI]¤ÀÂĊnŎR®Ő¿¶\\ÀøíDm¦ÎbŨabaĘ\\ľã¸atÎSƐ´©v\\ÖÚÌǴ¤Â¨JKrZ_ZfjþhPkx`YRIjJcVf~sCN¤ EhæmsHy¨SðÑÌ\\\\ĐRZk°IS§fqŒßýáĞÙÉÖ[^¯ǤŲê´\\¦¬ĆPM¯£»uïpùzExanµyoluqe¦W^£ÊL}ñrkqWňûPUP¡ôJoo·U}£[·¨@XĸDXmÛݺGUCÁª½{íĂ^cjk¶Ã[q¤LÉö³cux«zZf²BWÇ®Yß½ve±ÃCý£W{Ú^q^sÑ·¨ÍOt¹·C¥GDrí@wÕKţëV·i}xËÍ÷i©ĝɝǡ]{c±OW³Ya±_ç©HĕoƫŇqr³Lys[ñ³¯OSďOMisZ±ÅFC¥Pq{Ã[Pg}\\¿ghćO
k^ģÁFıĉĥMoEqqZûěʼn³F¦oĵhÕP{¯~TÍlªNßYÐ{Ps{ÃVUeĎwk±ʼnVÓ½ŽJãÇÇ»Jm°dhcÀffdF~ĀeĖd`sx² ®EżĀdQÂd^~ăÔH¦\\LKpĄVez¤NP ǹÓRÆąJSha[¦´ÂghwmBШźhI|VV|p] ¼èNä¶ÜBÖ¼L`¼bØæKVpoúNZÞÒKxpw|ÊEMnzEQIZZNBčÚFÜçmĩWĪñtÞĵÇñZ«uD±|Əlij¥ãn·±PmÍada 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ä³PClFbbÍzwBGĭZÅi»lYċ²SgkÇ£^Sqd¯R
©é£¯S\\cZ¹iűƏCuƍÓXoR}M^o£
R}oªUF
uuXHlEÅÏ©¤ÛmTþ¤D²ÄufàÀXXȱAeyYw¬dvõ´KÊ£\\rµÄlidā]|DÂVH¹Þ®ÜWnCķ W§@\\¸~¤Vp¸póIO¢VOŇürXql~òÉK]¤¥Xrfkvzpm¶bwyFoúv𼤠N°ąO¥«³[éǡű_°Õ\\ÚÊĝþâőàerR¨JYlďQ[ ÏYëЧTGztnß¡gFkMāGÁ¤ia Éȹ`\\xs¬dĆkNnuNUuP@vRY¾\\¢
GªóĄ~RãÖÎĢùđŴÕhQxtcæëSɽʼníëlj£ƍG£nj°KƘµDsØÑpyƸ®¿bXp]vbÍZuĂ{n^IüÀSÖ¦EvRÎûh@â[ƏÈô~FNr¯ôçR±HÑlĢ^¤¢OðævxsŒ]ÞÁTĠs¶¿âÆGW¾ìA¦·TѬè¥ÏÐJ¨¼ÒÖ¼ƦɄxÊ~StD@Ă¼Ŵ¡jlºWvÐzƦZвCH AxiukdGgetqmcÛ£Ozy¥cE}|
¾cZ
k¿uŐã[oxGikfeäT@
SUwpiÚFM©£è^Ú`@v¶eňf heP¶täOlÃUgÞzŸU`l}ÔÆUvØ_Ō¬Öi^ĉi§²ÃB~¡ĈÚEgc|DC_Ȧm²rBx¼MÔ¦ŮdĨÃâYxƘDVÇĺĿg¿cwÅ\\¹¥Yĭl¤OvLjM_a W`zļMž·\\swqÝSAqŚij¯°kRē°wx^ĐkǂÒ\\]nrĂ}²ĊŲÒøãh·M{yMzysěnĒġV·°G³¼XÀ¤¹i´o¤ŃÈ`ÌDzÄUĞd\\iÖmÈBĤÜɲDEh LG¾ƀľ{WaYÍÈĢĘÔRîĐj}ÇccjoUb½{h§Ǿ{KƖµÎ÷GĀÖŠåưÎslyiē«`å§H¥Ae^§GK}iã\\c]v©ģZmÃ|[M}ģTɟĵÂÂ`ÀçmFK¥ÚíÁbX³ÌQÒHof{]ept·GŋĜYünĎųVY^ydõkÅZW«WUa~U·SbwGçǑiW^qFuNĝ·EwUtW·Ýďæ©PuqEzwAVXRãQ`©GMehccďÏd©ÑW_ÏYƅ»
é\\ɹ~ǙG³mØ©BšuT§Ĥ½¢Ã_ýL¡ýqT^rme\\PpZZbyuybQefµ]UhĿDCmûvaÙNSkCwncć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¾pVidd~ÈiíďÓQġėÇZÎXb½|ſÃH½KFgɱCģÛÇAnjÕc[VĝDZÃËÇ_ £ń³pj£º¿»WH´¯U¸đĢmtĜyzzNN|g¸÷äűѱĉā~mq^[ǁÑďlw]¯xQĔ¯l°řĴrBÞTxr[tޏĻN_yX`biNKu
P£kZĮ¦[ºxÆÀdhĹŀUÈƗCwáZħÄŭcÓ¥»NAw±qȥnD`{ChdÙFć}¢A±Äj¨]ĊÕjŋ«×`VuÓÅ~_kŷVÝyhVkÄãPsOµfgeŇ
µf@u_Ù ÙcªNªÙEojVxT@ãSefjlwH\\pŏäÀvlY½d{F~¦dyz¤PÜndsrhfHcvlwjF£G±DÏƥYyÏu¹XikĿ¦ÏqƗǀOŜ¨LI|FRĂn sª|C˜zxAè¥bfudTrFWÁ¹Am|ĔĕsķÆF´N}ć
UÕ@Áijſmuçuð^ÊýowFzØÎĕNőǏȎôªÌŒDŽàĀÄ˄ĞŀƒʀĀƘŸˮȬƬĊ°Uzouxe]}
AyÈW¯ÌmKQ]Īºif¸ÄX|sZt|½ÚUÎ lk^p{f¤lºlÆW A²PVÜPHÊâ]ÎĈÌÜk´\\@qàsĔÄQºpRij¼èi`¶bXrBgxfv»uUi^v~J¬mVp´£´VWrnP½ì¢BX¬hðX¹^TjVriªjtŊÄmtPGx¸bgRsT`ZozÆO]ÒFôÒOÆŊvÅpcGêsx´DR{AEOr°x|íb³Wm~DVjºéNNËܲɶGxŷCSt}]ûōSmtuÇÃĕNāg»íT«u}ç½BĵÞʣ¥ëÊ¡MÛ³ãȅ¡ƋaǩÈÉQG¢·lG|tvgrrf«ptęŘnÅĢrI²¯LiØsPf_vĠdxM prʹL¤¤eËÀđKïÙVY§]Ióáĥ]ķK¥j|pŇ\\kzţ¦šnņäÔVĂîά|vW®l¤èØrxm¶ă~lÄƯĄ̈́öȄEÔ¤ØQĄĄ»ƢjȦOǺ¨ìSŖÆƬyQv`cwZSÌ®ü±DŽ]ŀç¬B¬©ńzƺŷɄeeOĨSfm Ċƀ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²ŕƀBQ£Ď}L¹Îk@©ĈuǰųǨÚ§ƈnTËÇéƟÊcfčŤ^XmHĊĕË«W·ċëx³ǔķÐċJāwİ_ĸȀ^ôWr°oú¬Ħ
ŨK~ȰCĐ´Ƕ£fNÎèâw¢XnŮeÂÆĶ¾¾xäLĴĘlļO¤ÒĨA¢Êɚ¨®ØCÔ ŬGƠƦYĜĘÜƬDJg_ͥœ@čŅĻA¶¯@wÎqC½Ĉ»NăëKďÍQÙƫ[«ÃígßÔÇOÝáWñuZ¯ĥŕā¡ÑķJu¤E 寰WKɱ_d_}}vyõu¬ï¹ÓU±½@gÏ¿rýDg
Cdµ°MFYxw¿CG£Rƛ½Õ{]L§{qqą¿BÇƻğëܭNJË|c²}Fµ}ÙRsÓpg±QNqǫŋRwŕnéÑÉK«SeYR
ŋ@{¤SJ}D Ûǖ֍]gr¡µŷ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`ZRu¥É\\]~°Y`µÓ^phÁbnÀşúòaĬºTÖŒbe¦¦{¸ZâćNp©Hr|^mjhSEb\\afv`sz^lkljÄtg¤D¾X¿À|ĐiZȀåB·î}GL¢õcßjayBFµÏC^ĭcÙt¿sğH]j{s©HM¢QnDÀ©DaÜÞ·jgàiDbPufjDk`dPOîhw¡ĥ¥GP²ĐobºrYî¶aHŢ´ ]´rılw³r_{£DB_Ûdåuk|Ũ¯F Cºyr{XFye³Þċ¿ÂkĭB¿MvÛpm`rÚã@ƹhågËÖƿxnlč¶Åì½Ot¾dJlVJĂǀŞqvnO^JZż·Q}êÍÅmµÒ]ƍ¦Dq}¬R^èĂ´ŀĻĊIÔtIJyQŐĠMNtR®òLhĚs©»}OÓGZz¶A\\jĨFäOĤHYJvÞHNiÜaĎÉnFQlNM¤B´ĄNöɂtpŬdfå
qm¿QûùŞÚb¤uŃJŴu»¹ĄlȖħŴw̌ŵ²ǹǠ͛hĭłƕrçü±Yxcitğ®jű¢KOķCoy`å®VTa_Ā]ŐÝɞï²ʯÊ^]afYǸÃĆēĪȣJđ͍ôƋÄÄÍīçÛɈǥ£ÛmY`ó£Z«§°Ó³QafusNıDž_k}¢m[ÝóDµ¡RLčiXyÅNïă¡¸iĔÏNÌŕoēdōîåŤûHcs}~Ûwbù¹£¦ÓCtOPrE^Òogĉ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 | ["@@sfbU"],
210 | ["@@qP\\xz[ck"],
211 | ["@@R¢FX}°[s_"],
212 | ["@@Cb\\}"],
213 | ["@@e|v\\la{u"],
214 | ["@@v~u}"],
215 | ["@@QxÂF¯}"],
216 | ["@@¹nvÞs¯o"],
217 | ["@@rSkUEj"],
218 | ["@@biZP"],
219 | ["@@p[}INf"],
220 | ["@@À¿"],
221 | ["@@¹dnb
"],
222 | ["@@rSBnR"],
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 | ["@@Kxv"],
232 | ["@@@hlIk]"],
233 | ["@@pW{o||j"],
234 | ["@@Md|_mC"],
235 | ["@@¢
X£ÏylD¼XtH"],
236 | ["@@hlÜ[LykAvyfw^E¤"],
237 | ["@@fp¤MusR"],
238 | ["@@®_ma~LÁ¬Z"],
239 | ["@@iMxZ"],
240 | ["@@ZcYd"],
241 | ["@@Z~dOSo|A¿qZv"],
242 | ["@@@`EN¡v"],
243 | ["@@|TY{"],
244 | ["@@@n@m"],
245 | ["@@XWkCT\\"],
246 | ["@@ºwZRkĕWO¢"],
247 | ["@@X®±Grƪ\\ÔáXq{"],
248 | ["@@ůTG°ĄLHm°UC"],
249 | [
250 | "@@¤aÜx~}dtüGæţŎíĔcŖpMËÐj碷ðĄÆMzjWKĎ¢Q¶À_ê_Bıi«pZgf¤Nrq]§ĂN®«H±yƳí¾×ŸīàLłčŴǝĂíÀBŖÕªÁŖHŗʼnåqûõi¨hÜ·ñt»¹ýv_[«¸mYL¯Qª
mĉÅdMgÇjcº«ę¬K´B«Âącoċ\\xKd¡gěŧ«®á[~ıxu·ÅKsËÉc¢Ù\\ĭƛëbf¹ģSĜkáƉÔĈZB{aMµfzʼnfåÂŧįƋǝÊĕġć£g³neą»@¦S®\\ßðChiqªĭiAuAµ_W¥ƣO\\lċĢttC¨£t`PZäuXßBsĻyekOđġĵHuXBµ]×\\°®¬F¢¾pµ¼kŘó¬Wät¸|@L¨¸µrºù³Ù~§WIZW®±Ð¨ÒÉx`²pĜrOògtÁZ}þÙ]¡FKwsPlU[}¦Rvn`hq¬\\nQ´ĘRWb_ rtČFIÖkĦPJ¶ÖÀÖJĈĄTĚòC ²@Pú
Øz©PCÈÚDZhŖl¬â~nm¨f©iļ«mntuÖZÜÄjL®EÌFª²iÊxبIÈhhst"
251 | ],
252 | ["@@o\\VzRZ}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`|´qxIJkq^³³GšµbíZ
¹qpa±ď OH¦Ħx¢gPícOl_iCveaOjCh߸iÝbÛªCC¿mRV§¢A|t^iĠGÀtÚsd]ĮÐDE¶zAb àiödK¡~H¸íæAǿYj{ď¿À½W®£ChÃsikkly]_teu[bFaTign{]GqªoĈMYá|·¥f¥őaSÕėNµñĞ«Im_m¿Âa]uĜp
Z_§{Cäg¤°r[_YjÆOdý[I[á·¥Q_nùgL¾mvˊBÜÆ¶ĊJhpc¹O]iŠ]¥ jtsggJǧw×jÉ©±EFËKiÛÃÕYv
sm¬njĻª§emná}k«ŕgđ²ÙDÇ¤í¡ªOy×Où±@DñSęćăÕIÕ¿IµĥOjNÕËT¡¿tNæŇàåyķrĕq§ÄĩsWÆßF¶X®¿mw
RIÞfßoG³¾©uyHį{Ɓħ¯AFnuP
ÍÔzVdàôº^Ðæd´oG¤{S¬ćxã}ŧ×Kǥĩ«ÕOEзÖdÖsƘѨ[Û^Xr¢¼§xvÄÆµ`K§ tÒ´Cvlo¸fzŨð¾NY´ı~ÉĔē
ßúLÃÃ_ÈÏ|]ÂÏFlg`ben¾¢pUh~ƴ˶_r sĄ~cƈ]|r c~`¼{À{ȒiJjz`îÀT¥Û³
]u}f
ïQl{skloNdjäËzDvčoQďHI¦rbtHĔ~BmlRV_ħTLnñH±DL¼Lªl§Ťa¸ĚlK²\\RòvDcÎJbt[¤D@®hh~kt°ǾzÖ@¾ªdbYhüóZ ň¶vHrľ\\ÊJuxAT|dmÀO[ÃÔG·ĚąĐlŪÚpSJ¨ĸLvÞcPæķŨ®mÐálwKhï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 | ["@@@vPGsQ"],
336 | ["@@sBzddW]Q"],
337 | ["@@S¨Q{"],
338 | ["@@NVucW"],
339 | ["@@qptBAq"],
340 | ["@@¸[mu"],
341 | ["@@Q\\pD]_"],
342 | ["@@jSwUadpF"],
343 | ["@@eXª~"],
344 | ["@@AjvFso"],
345 | ["@@fT_Çí\\v|ba¦jZÆy°"],
346 | ["@@IjJi"],
347 | ["@@wJIx«¼AoNe{M"],
348 | ["@@K±¡ÓČäeZ"],
349 | [
350 | "@@k¡¹Eh~c®wBkUplÀ¡I~Māe£bN¨gZý¡a±Öcp©PhI¢Qq
ÇGj|¥U g[Ky¬ŏv@OptÉEF\\@ åA¬V{XģĐBy
cpě
¼³Ăp·¤¥ohqqÚ¡ŅLs^á§qlÀhH¨MCe»åÇGD¥zPO£čÙkJA¼ßėuĕeûÒiÁŧSW¥Qûŗ½ùěcݧSùĩąSWó«íęACµeRåǃRCÒÇZÍ¢ź±^dlstjD¸ZpuÔâÃH¾oLUêÃÔjjēò´ĄWƛ
^Ñ¥Ħ@ÇòmOw¡õyJyD}¢ďÑÈġfZda©º²z£NjD°Ötj¶¬ZSÎ~¾c°¶ÐmxO¸¢Pl´SL|¥AȪĖMņIJg®áIJČĒü` QF¬h|ĂJ@zµ |ê³È ¸UÖŬŬÀEttĸr]ðM¤ĶIJHtÏ AĬkvsq^aÎbvdfÊòSD´Z^xPsĂrvƞŀjJd×ŘÉ ®AΦĤdxĆqAZRÀMźnĊ»İÐZ YXæJyĊ²·¶q§·K@·{sXãô«lŗ¶»o½E¡«¢±¨Y®Ø¶^AvWĶ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£Tc ĹGµ¶Hm@_©k¾xĨôȉðX«½đCIbćqK³ÁÄš¬OAwã»aLʼnËĥW[ÂGIÂNxij¤D¢îĎÎB§°_JGs¥E@
¤uć
PåcuMuw¢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êvHĢûXD®
QgÄWiØPÞìºr¤džNĠ¢lĄtZoCƞÔºCxrpĠV®Ê{f_Y`_eq®Aot`@oDXfkp¨|s¬\\DÄSfè©Hn¬
^DhÆyøJhØxĢĀLÊƠPżċĄwȠ̦G®ǒĤäTŠÆ~Ħw«|TF¡nc³Ïå¹]ĉđxe{ÎÓvOEm°BƂĨİ|Gvz½ª´HàpeJÝQxnÀWEµàXÅĪt¨ÃĖrÄwÀFÎ|ňÓMå¼ibµ¯»åDT±m[r«_gmQu~¥V\\OkxtL E¢Ú^~ýêPóqoě±_Êw§ÑªåƗā¼mĉŹ¿NQ
YBąrwģcÍ¥BŗÊcØiIƝĿuqtāwO]³YCñTeÉcaubÍ]trluī
BÐGsĵıN£ï^ķqss¿FūūVÕ·´Ç{éĈýÿOER_đûIċâJhŅıNȩĕB
¦K{Tk³¡OP·wnµÏd¯}½TÍ«YiµÕsC¯iM¤¦¯P|ÿUHvhe¥oFTuõ\\OSsMòđƇiaºćXĊĵà·çhƃ÷Ç{ígu^đgm[×zkKN¶Õ»lčÓ{XSÆv©_ÈëJbVkĔVÀ¤P¾ºÈMÖxlò~ªÚàGĂ¢B±ÌKyáV¼Ã~
`gsÙfIƋlę¹e|~udjuTlXµ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 | ["@@TGy"],
408 | ["@@K¬U"],
409 | ["@@WdXc"],
410 | ["@@PtOs"],
411 | ["@@LnXhc"],
412 | ["@@ppVu]Or"],
413 | ["@@cdzAUa"],
414 | ["@@udRhnCI"],
415 | ["@@oIpR"],
416 | [
417 | "@@Ľč{fzƤîKÎMĮ]ZF½Y]â£ph¶¨râøÀÎǨ¤^ºÄGz~grĚĜlĞÆLĆdž¢Îo¦cvKbgr°WhmZp L]LºcUÆnżĤÌĒbAnrOA´ȊcÀbƦUØrĆUÜøĬƞEzVL®öØBkŖÝĐ˹ŧ̄±ÀbÎÉnb²ĦhņBĖįĦåXćì@L¯´ywƕCéõė ƿ¸lµ¾Z|ZWyFY¨Mf~C¿`à_RÇzwƌfQnny´INoƬèôº|sTJULîVjǎ¾ĒØDz²XPn±ŴPè¸ŔLƔÜƺ_TüÃĤBBċÈöA´faM¨{«M`¶d¡ôÖ°mȰBÔjj´PM|c^d¤u¤Û´ä«ƢfPk¶Môl]Lb}su^ke{lC
MrDÇ]NÑFsmoõľHyGă{{çrnÓEƕZGª¹Fj¢ïW
uøCǷë¡ąuhÛ¡^KxC`C\\bÅxì²ĝÝ¿_NīCȽĿåB¥¢·IŖÕy\\¹kxãČ×GDyäÁçFQ¡KtŵƋ]CgÏAùSedcÚźuYfyMmhUWpSyGwMPqŀÁ¼zK¶GY§Ë@´śÇµƕBm@IogZ¯uTMx}CVKï{éƵP_K«pÛÙqċtkkù]gTğwoɁsMõ³ăAN£MRkmEÊčÛbMjÝGu
IZGPģãħE[iµBEuDPÔ~ª¼ęt]ûG§¡QMsğNPŏįzs£Ug{đJĿļā³]ç«Qr~¥CƎÑ^n¶ÆéÎR~ݏYI] PumŝrƿIā[xedzL¯v¯s¬ÁY
~}
ťuŁgƋpÝĄ_ņī¶ÏSR´ÁP~¿Cyċßdwk´SsX|t`Ä ÈðAªìÎT°¦Dda^lĎDĶÚY°`ĪŴǒàŠv\\ebZHŖ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¶@«ŕŕQGYfa[şußǩđš_X³ijÕčC]kbc¥CS¯ëÍB©÷³Si_}mYTt³xlàcČzÀD}ÂOQ³ÐTĨ¯ƗòËŖ[hłŦv~}ÂZ«¤lPÇ£ªÝŴÅR§ØnhctâknÏľŹUÓÝdKuķI§oTũÙďkęĆH¸Ó\\Ä¿PcnS{wBIvÉĽ[GqµuŇôYgûZca©@½Õǽys¯}lgg@C\\£asIdÍuCQñ[L±ęk·ţb¨©kK»KC²òGKmĨS`UQnk}AGēsqaJ¥ĐGRĎpCuÌy ã iMcplk|tRkðev~^´¦ÜSí¿_iyjI|ȑ|¿_»d}q^{Ƈdă}tqµ`Ƴĕg}V¡om½faÇo³TTj¥tĠRyK{ùÓjuµ{t}uËRivGçJFjµÍyqÎàQÂFewixGw½Yŷpµú³XU½ġyłåkÚwZX·l¢Á¢KzOÎÎjc¼htoDHr
|J½}JZ_¯iPq{tę½ĕ¦Zpĵø«kQ
Ť]MÛfaQpě±ǽ¾]uFu÷nčįADp}AjmcEÇaª³o³ÆÍSƇĈÙDIzËčľ^KLiÞñ[aA²zzÌ÷D|[íijgfÕÞd®|`Ć~oĠƑô³ŊD×°¯CsøÀ«ìUMhTº¨¸ǡîSÔDruÂÇZÖEvPZW~ØÐtĄE¢¦Ðy¸bô´oŬ¬²Ês~]®tªapŎJ¨Öº_Ŕ`Ŗ^Đ\\Ĝu~m²Ƹ¸fWĦrƔ}Î^gjdfÔ¡J}\\n C¦þWxªJRÔŠu¬ĨĨmFdM{\\d\\YÊ¢ú@@¦ª²SÜsC}fNècbpRmlØ^gd¢aÒ¢CZZxvƶN¿¢T@uC¬^ĊðÄn|lGlRjsp¢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 | ["@@AB"],
467 | ["@@lskt"],
468 | [
469 | "@@¾«}{ra®pîÃ\\{øCËyyB±b\\òÝjKL ]ĎĽÌJyÚCƈćÎT´Å´pb©ÈdFin~BCo°BĎÃømv®E^vǾ½Ĝ²RobÜeN^ĺ£R¬lĶ÷YoĖ¥Ě¾|sOr°jY`~I¾®I{GqpCgyl{£ÍÍyPL¡¡¸kWxYlÙæŁĢz¾V´W¶ùŸo¾ZHxjwfxGNÁ³Xéæl¶EièIH ujÌQ~v|sv¶Ôi|ú¢FhQsğ¦SiŠBgÐE^ÁÐ{čnOÂÈUÎóĔÊēIJ}Z³½Mŧïeyp·uk³DsѨL¶_Åuèw»¡WqÜ]\\Ò§tƗcÕ¸ÕFÏǝĉăxŻČƟOKÉġÿ×wg÷IÅzCg]m«ªGeçÃTC«[t§{loWeC@ps_Bprf_``Z|ei¡oċMqow¹DƝÓDYpûsYkıǃ}s¥ç³[§cY§HK«Qy]¢wwö¸ïx¼ņ¾Xv®ÇÀµRĠÐHM±cÏdƒǍũȅȷ±DSyúĝ£ŤĀàtÖÿï[îb\\}pĭÉI±Ñy
¿³x¯No|¹HÏÛmjúË~TuęjCöAwě¬Rđl¯ ÑbŇTĿ_[IčĄʿnM¦ğ\\É[T·k¹©oĕ@A¾wya¥Y\\¥Âaz¯ãÁ¡k¥ne£ÛwE©Êō¶˓uoj_U¡cF¹[WvP©whuÕyBF`RqJUw\\i¡{jEPïÿ½fć
QÑÀQ{°fLÔ~wXgītêݾĺHd³fJd]HJ²
EoU¥HhwQsƐ»Xmg±çve]DmÍPoCc¾_hhøYrŊU¶eD°Č_N~øĹĚ·`z]Äþp¼
äÌQv\\rCé¾TnkžŐÚÜa¼ÝƆ̶Ûo
d
ĔňТJqPb ¾|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ʧĘDvČ_Àæ~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 | ["@@nFTs"],
483 | ["@@ßÅÆá½ÔXrCO
ËRïÿĩTooQyÓ[ŅBE¬ÎÓXaį§Ã¸G °ITxpúxÚij¥Ï̾edÄ©ĸG
àGhM¤Â_U}Ċ}¢pczfþg¤ÇòAVM"],
484 | [
485 | "@@©KA·³CQ±Á«³BUƑ¹AtćOwD]JiØSm¯b£ylX
HËѱH«C^õľAŧ¤É¥ïyuǙuA¢^{ÌC´¦ŷJ£^[ª¿ĕ~Ƈ
N
skóā¹¿ï]ă~÷O§@Vm¡Qđ¦¢Ĥ{ºjÔª¥nf´~Õo×ÛąMąıuZmZcÒ 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È£ýhedy¡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_EzAN¦zLU`cªxOTu RLÄ¢dVi`p˔vŎµªÉF~Ød¢ºgİàw¸Áb[¦Zb¦z½xBĖ@ªpºlS¸Ö\\Ĕ[N¥ˀmĎăJ\\ŀ`
ňSÚĖÁĐiOĜ«BxDõĚivSÌ}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ŽƥóRoOV~]{g\\êYƪ¦kÝbiċƵGZ»Ěõ
ó·³vŝ£ø@pyö_ëIkѵbcѧ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 | ["@@QdAua"],
504 | ["@@lxDLo"],
505 | ["@@sbhNLo"],
506 | ["@@Ă ā"],
507 | ["@@WltO[["],
508 | ["@@Kr]S"],
509 | ["@@eI]y"],
510 | ["@@I|Mym"],
511 | ["@@Û³LS¼Y"],
512 | ["@@nvºBëui©`¾"],
513 | ["@@zdÛJw®"],
514 | ["@@°
¯"],
515 | ["@@a yAª¸ËJIxØ@ĀHAmÃV¡ofuo"],
516 | ["@@sŗÃÔėAƁZÄ ~°ČPäh"],
517 | ["@@¶ÝÌvmĞhıQ"],
518 | ["@@HdSjǢD}war
u«ZqadYM"],
519 | ["@@el\\LqqU"],
520 | ["@@~rMo\\"],
521 | ["@@f^C"],
522 | ["@@øPªoj÷ÍÝħXČx°Q¨ıXNv"],
523 | ["@@gÇƳo[~tly"],
524 | ["@@EÆC¿"],
525 | ["@@OP"],
526 | [
527 | "@@wđógĝ[³¡VÙæÅöM̳¹pÁaËýý©D©ÜJŹƕģGą¤{Ùū
ÇO²«BƱéAÒĥ¡«BhlmtÃPµyU¯ucd·w_bŝcīímGO|KPȏŹãŝIŕŭŕ@Óoo¿ē±ß}
ŭIJWÈCőâUâǙIğʼn©IijE×
Á³AówXJþ±ÌÜÓĨ£L]ĈÙƺZǾĆĖMĸĤfÎĵlŨnÈĐtFFĤêk¶^k°f¶g}®Faf`vXŲxl¦ÔÁ²¬Ð¦pqÊ̲iXØRDÎ}Ä@ZĠsx®AR~®ETtĄZƈfŠŠHâÒÐAµ\\S¸^wĖkRzalŜ|E¨ÈNĀňZTpBh£\\ĎƀuXĖtKL¶G|»ĺEļĞ~ÜĢÛĊrOÙîvd]n¬VÊĜ°RÖpMƂªFbwEÀ©\\
¤]ŸI®¥D³|Ë]CöAŤ¦
æ´¥¸Lv¼¢ĽBaôF~®²GÌÒEYzk¤°ahlVÕI^CxĈPsBƒºV¸@¾ªR²ĨN]´_eavSivc}p}Đ¼ƌkJÚe th_¸ ºx±ò_xN˲@ă¡ßH©Ùñ}wkNÕ¹ÇO½¿£ĕ]ly_WìIǪ`uTÅxYĒÖ¼kÖµMjJÚwn\\hĒv]îh|ÈƄøèg¸Ķß ĉĈWb¹ƀdéĘNTtP[öSvrCZaGubo´ŖÒÇĐ~¡zCI
özx¢PnÈñ @ĥÒ¦]ƞV}³ăĔñiiÄÓVépKG½ÄÓávYoC·sitiaÀ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ñĤaYt¿¤VSñK¸¤nM¼JE±½¸ñoÜCƆæĪ^ĚQÖ¦^f´QüÜÊz¯lzUĺš@ìp¶n]sxtx¶@~ÒĂJb©gk{°~c°`Ô¬rV\\la¼¤ôá`¯¹LCÆbxEræOv[H[~|aB£ÖsºdAĐzNÂðsÞÆ
Ĥªbab`ho¡³F«èVlo¤ÔRzpp®SĪº¨ÖºN
ijd`a¦¤F³ºDÎńĀìCĜº¦Ċ~nS|gźvZkCÆj°zVÈÁƔ]LÊFZg
čPkini«qÇczÍY®¬Ů»qR×ō©DÕ§ƙǃŵTÉĩ±ıdÑnYYIJvNĆĆØÜ Öp}e³¦m©iÓ|¹ħņ|ª¦QF¢Â¬ʖovg¿em^ucà÷gÕuíÙćĝ}FϼĹ{µHKsLSđƃrč¤[AgoSŇYMÿ§Ç{FśbkylQxĕ]T·¶[B
ÑÏGáşşƇe
ăYSsFQ}BwtYğÃ@~
CÍQ ×Wj˱rÉ¥oÏ ±«ÓÂ¥kwWűmcih³K~µh¯e]lµélEģEďsmÇŧē`ãògK_ÛsUʝćğ¶höO¤Ǜn³c`¡y¦CezYwa[ďĵűMę§]XÎ_íÛ]éÛUćİÕBƣ±
dy¹T^dûÅÑŦ·PĻþÙ`K¦
¢ÍeĥR¿³£[~äu¼dltW¸oRM¢ď\\z}Æzdvň{ÎXF¶°Â_ÒÂÏL©ÖTmu¼ãlīkiqéfA·Êµ\\őDc¥ÝFyÔćcűH_hLÜêĺШc}rn`½Ì@¸¶ªVLhŒ\\Ţĺk~Ġið°|gtTĭĸ^xvKVGréAébUuMJVÃO¡
qĂXËSģãlýà_juYÛÒBG^éÖ¶§EGÅzěƯ¤EkN[kdåucé¬dnYpAyČ{`]þ¯TbÜÈ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ðĀÒRZdž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¤JJJyJÈ`Ohߦ¡uËhIyCjmÿw
ZG
TiSsOB²fNmsPa{M{õE^Hj}gYpaeu¯oáwHjÁ½M¡pMuåmni{fk\\oÎqCwEZ¼KĝAy{m÷LwO×SimRI¯rKõBS«sFe]fµ¢óY_ÆPRcue°Cbo×bd£ŌIHgtrnyPt¦foaXďxlBowz_{ÊéWiêEGhܸºuFĈIxf®Y½ĀǙ]¤EyF²ċw¸¿@g¢§RGv»áW`ÃĵJwi]t¥wO½a[×]`ÃiüL¦LabbTÀåc}ÍhÆh®BHî|îºÉk¤Sy£ia©taį·Ɖ`ō¥UhO
ĝLk}©Fos´JmµlŁu
ønÑJWΪYÀïAetTŅÓGË«bo{ıwodƟ½OġܵxàNÖ¾P²§HKv¾]|BÆåoZ`¡Ø`ÀmºĠ~ÌЧnÇ
¿¤]wğ@srğu~Io[é±¹ ¿ſđÓ@qg¹zƱřaí°KtǤV»Ã[ĩǭƑ^ÇÓ@áťsZÏÅĭƋěpwDóÖáŻneQËq·GCœýS]x·ýq³OÕ¶Qzßti{řáÍÇWŝŭñzÇWpç¿JXĩè½cFÂLiVjx}\\NŇĖ¥GeJA¼ÄHfÈu~¸Æ«dE³ÉMA|bÒ
ćhG¬CMõƤąAvüVéŀ_V̳ĐwQj´·ZeÈÁ¨X´Æ¡Qu·»ÕZ³ġqDoy`L¬gdp°şp¦ėìÅĮZ°Iähzĵf²å ĚÑKpIN|Ñ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ÕĢyFVvwxBèĻĒ©ĈtCĢɽŠȣ¦āæ·HĽîôNÔ~^¤Ɗu^s¼{TA¼ø°¢İªDè¾Ň¶ÝJ®Z´ğ~Sn|ªWÚ©òzPOȸbð¢|øĞŒQìÛÐ@ĞǎRS¤Á§d
i´ezÝúØã]HqkIþËQǦÃsǤ[E¬ÉŪÍxXƒ·ÖƁİlƞ¹ª¹|XÊwnÆƄmÀêErĒtD®ċæcQE®³^ĭ¥©l}äQtoŖÜqÆkµªÔĻĴ¡@Ċ°B²Èw^^RsºT£ڿQPJvÄz^Đ¹Æ¯fLà´GC²dtĀRt¼¤ĦOðğfÔðDŨŁĞƘïPÈ®âbMüÀXZ ¸£@Å»»QÉ]dsÖ×_Í_ÌêŮ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°´ATeVamdUĐwʄvĮÕ\\uÆŗ¨Yp¹àZÂmWh{á}WØǍÉüwga§áCNęÎ[ĀÕĪgÖɪXøx¬½Ů¦¦[NÎLÜUÖ´òrÙŠxR^JkijnDX{U~ET{ļº¦PZcjF²Ė@pg¨B{u¨ŦyhoÚD®¯¢ WòàFΤ¨GDäz¦kŮPġqË¥À]eâÚ´ªKxīPÖ|æ[xäJÞĥsNÖ½I¬nĨY´®ÐƐmDŝuäđđEb
ee_v¡}ìęNJē}qÉåT¯µRs¡M@}ůaa¯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Ñ£IsNgßHHªķÃh_¹¡ĝħń¦uÙùgS¯JH|sÝÅtÁïyMDč»eÕtA¤{b\\}G®u\\åPFqwÅaD
K°ºâ_£ùbµmÁÛĹM[q|hlaªāI}ѵ@swtwm^oµD鼊yVky°ÉûÛR
³e¥]RÕěħ[ƅåÛDpJiVÂF²I
»mN·£LbÒYbWsÀbpkiTZĄă¶Hq`
ĥ_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|`ź¦ÂÈdrcÈbe¸`I¼čTF´¼Óýȃr¹ÍJ©k_șl³´_pĐ`oÒh¶pa^ÓĔ}D»^Xy`d[Kv
JPhèhCrĂĚÂ^Êƌ wZLĠ£ÁbrzOIlMMĪŐžËr×ÎeŦtw|¢mKjSǘňĂStÎŦEtqFT¾E쬬ôxÌO¢ K³ŀºäYPVgŎ¦Ŋm޼VZwVlz¤
£Tl®ctĽÚó{GAÇge~Îd¿æaSba¥KKûj®_Ä^\\ؾbP®¦x^sxjĶI_Ä Xâ¼Hu¨Qh¡À@Ëô}±GNìĎlT¸
`V~R°tbÕĊ`¸úÛtÏFDu[MfqGH·¥yAztMFe|R_GkChZeÚ°tov`xbDnÐ{E}ZèxNEÞREn[Pv@{~rĆAB§EO¿|UZ~ìUf¨J²ĂÝÆsªB`s¶fvö¦Õ~dÔq¨¸º»uù[[§´sb¤¢zþF¢Æ
ÀhÂW\\ıËIÝo±ĭŠ£þÊs}¡R]ěDg´VG¢j±®èºÃmpU[Á뺰rÜbNu¸}º¼`niºÔXĄ¤¼ÔdaµÁ_Ã
ftQQgR·Ǔ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½}ÑRHYīĺûsÍniEoã½Ya²ė{c¬ĝgĂsAØÅwďõzFjw}«Dx¿}Uũlê@HÅF¨ÇoJ´Ónũuą¡Ã¢pÒÅØ TF²xa²ËXcÊlHîAßËŁkŻƑŷÉ©hWæß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¯ŪĽncÚbw\\zlvWªâ ¦gmĿBĹ£¢ƹřbĥkǫßeeZkÙIKueT»sVesbaĕ ¶®dNĄÄpªy¼³BE®lGŭCǶwêżĔÂepÍÀQƞpC¼ŲÈAÎô¶RäQ^Øu¬°_Èôc´¹ò¨P΢hlϦ´ĦÆ´sâÇŲPnÊD^¯°Upv}®BP̪jǬxSöwlfòªvqĸ|`HviļndĜĆhňem·FyÞqóSᝳX_ĞçêtryvL¤§z¦c¦¥jnŞklD¤øz½ĜàĂŧMÅ|áƆàÊcðÂFÜáŢ¥\\\\ºİøÒÐJĴîD¦zK²ǏÎEh~CDhMn^ÌöÄ©ČZÀaüfɭyœpį´ěFűk]Ôě¢qlÅĆÙa¶~ÄqêljN¬¼HÊNQ´ê¼VظE^ŃÒyM{JLoÒęæe±Ķygã¯JYÆĭĘëo¥Šo¯hcK«z_prC´ĢÖY¼ v¸¢RÅW³Â§fǸYi³xR´ďUË`êĿUûuĆBƣöNDH«ĈgÑaB{ÊNF´¬c·Åv}eÇÃGB»If¦HňĕM
~[iwjUÁKE¾dĪçWIèÀoÈXòyŞŮÈXâÎŚj|àsRyµÖPr´þ ¸^wþTDŔHr¸RÌmfżÕâCôoxĜƌÆĮÐYtâŦÔ@]ÈǮƒ\\μģUsȯLbîƲŚºyhr@ĒÔƀÀ²º\\êpJ}ĠvqtĠ@^xÀ£È¨mËÏğ}n¹_¿¢×Y_æpÅA^{½Lu¨GO±Õ½ßM¶wÁĢÛPƢ¼pcIJx|ap̬HÐŊSfsðBZ¿©XÏÒKk÷Eû¿S
rEFsÕūkóVǥʼniTL¡n{uxţÏhôŝ¬ğōNNJkyPaqÂğ¤K®YxÉƋÁ]āęDqçgOgILu\\_gz]W¼~CÔē]bµogpÑ_oď`´³Țkl`IªºÎȄqÔþ»E³ĎSJ»_f·adÇqÇc¥Á_Źw{L^ɱćxU£µ÷xgĉp»ĆqNē`rĘzaĵĚ¡K½ÊBzyäKXqiWPÏɸ½řÍcÊG|µƕƣGË÷k°_^ý|_zċBZocmø¯hhcæ\\lMFlư£ĜÆyHF¨µêÕ]HA
àÓ^it `þßäkĤÎT~Wlÿ¨ÔPzUCNVv [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ÍçWVi]ë©Ä÷àyƛhÚU°adcQ~Mx¥cc¡ÙaSyFÖkuRýq¿ÔµQĽ³aG{¿FµëªéĜÿª@¬·K·àariĕĀ«V»ŶĴūgèLǴŇƶaftèBŚ£^âǐÝ®M¦ÁǞÿ¬LhJ¾óƾƺcxwf]Y
´¦|QLn°adĊ
\\¨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ÀgVjzlhǶfOfdªB]pjTOtĊn¤}®¦Č¥d¢¼»ddY¼t¢eȤJ¤}Ǿ¡°§¤AÐlc@ĝsªćļđAçwxUuzEÖġ~AN¹ÄÅȀݦ¿ģŁéì±H
ãd«g[ؼēÀcīľġ¬cJµ
ÐʥVȝ¸ßS¹ý±ğkƁ¼ą^ɛ¤Ûÿb[}¬ōõÃ]ËNm®g@Bg}ÍF±ǐyL¥íCIijÏ÷Ñį[¹¦[âšEÛïÁÉdƅß{âNÆāŨß¾ě÷yC£k´ÓH@¹TZ¥¢į·ÌAЧ®Zc
v½Z¹|ÅWZqgW|ieZÅYVÓqdqbc²R@c¥Rã»Geeƃī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ŘvgÌsN@îá¾ó@ÙwU±ÉT廣TđWxq¹Zobs[ׯ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ÚÅTSijYo|Ç[ǾµMW¢ĭiÕØ¿@Mh
pÕ]jéò¿OƇĆƇpêĉâlØwěsǩĵ¸c
bU¹ř¨WavquSMzeo_^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~ź¤PnMĪÖB£kné§żćĆKǰ¼L¶èâz¨u¦¥LDĘz¬ýÎmĘd¾ßFzhg²Fy¦ĝ¤ċņbÎ@yĄæm°NĮZRÖíJ²öLĸÒ¨Y®ƌÐVàtt_ÚÂyĠz]ŢhzĎ{ÂĢXc|ÐqfO¢¤ögÌHNPKŖUú´xx[xvĐCûĀìÖT¬¸^}Ìsòd´_KgžLĴ
ÀBon|H@Êx¦BpŰŌ¿fµƌA¾zLjRx¶FkĄźRzŀ~¶[´HnªVƞuĒȨƎcƽÌm¸ÁÈM¦x͊ëÀxdžBú^´W£dkɾĬpw˂ØɦļĬIŚÊnŔa¸~J°îlɌxĤÊÈðhÌ®gT´øàCÀ^ªerrƘd¢İP|Ė ŸWªĦ^¶´ÂLaT±ü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ž¬stRÆdĠİwܸôW¾ƮłÒ_{Ìû¼jº¹¢GǪÒ¯ĘZ`ºŊecņą~BÂgzpâēòYǠȰÌTΨÂW|fcă§uF@N¢XLRMº[ğȣſï|¥Jkc`sʼnǷY¹W@µ÷K
ãï³ÛIcñ·VȋÚÒķø©þ¥yÓğęmWµÎumZyOŅƟĥÓ~sÑL¤µaÅ
Y¦ocyZ{y c]{Ta©`U_Ěē£ωÊƍKùK¶ȱÝƷ§{û»ÅÁȹÍéuij|¹cÑdìUYOuFÕÈYvÁCqÓTǢí§·S¹NgV¬ë÷Á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Ňîŵœè[É@ƉĄEtƇϳħZ«mJ
×¾MtÝĦ£IwÄå\\Õ{OwĬ©LÙ³ÙgBƕŀrÌĢŭO¥lãyC§HÍ£ßEñX¡°ÙCgpťzb`wIvA|§hoĕ@E±iYd¥OϹS|}F@¾oAO²{tfÜ¢FǂÒW²°BĤh^Wx{@¬F¸¡ķn£P|ªĴ@^ĠĈæbÔc¶lYi
^MicϰÂ[ävï¶gv@ÀĬ·lJ¸sn|¼u~a]ÆÈtŌºJpþ£KKf~¦UbyäIĺãnÔ¿^ŵMThĠܤko¼Ŏìąǜh`[tRd²IJ_XPrɲlXiL§à¹H°Ȧqº®QCbAŌJ¸ĕÚ³ĺ§ `d¨YjiZvRĺ±öVKkjGȊÄePĞZmļKÀ[`ösìhïÎoĬdtKÞ{¬èÒÒBÔpIJÇĬJŊ¦±J«Y§@·pHµàåVKepWftsAÅqC·¬ko«pHÆuK@oHĆÛķhxenS³àǍ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¦ÅÄÜdwAb×ĠąJ¤DüègĺqBqj°lI¡ĨÒ¤úSHbjÎB°aZ¢KJO[|A£Dx}NìHUnrk kp¼Y kMJn[aGáÚÏ[½rc}aQxOgsPMnUsncZ
sKúvAtÞġ£®ĀYKdnFw¢JE°Latf`¼h¬we|Æbj}GA·~W`¢MC¤tL©IJ°qdfObÞĬ¹ttu`^ZúE`[@Æsîz®¡CƳƜG²R¢RmfwĸgÜą G@pzJM½mhVy¸uÈÔO±¨{LfæU¶ßGĂq\\ª¬²I¥IʼnÈīoıÓÑAçÑ|«LÝcspīðÍg
të_õ\\ĉñLYnĝgRǡÁiHLlõUĹ²uQjYi§Z_c¨´ĹĖÙ·ŋI
aBDR¹ȥr¯GºßK¨jWkɱOqWij\\aQ\\sg_ĆǛōëp»£lğÛgSŶN®À]ÓämĹãJaz¥V}Le¤Lýo¹IsŋÅÇ^bz
³tmEÁ´a¹cčecÇNĊãÁ\\č¯dNj]jZµkÓdaćå]ğij@ ©O{¤ĸm¢E·®«|@Xwg]A챝XǁÑdzªcwQÚŝñ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ĪğPs{ò²Vw¹t³ŜË[Ñ}X\\gsF£sPAgěp×ëfYHāďÖqēŭOÏëdLü\\it^c®Rʺ¶¢H°mrY£B¹čIoľu¶uI]vģSQ{UŻÅ}QÂ|̰ƅ¤ĩŪU ęĄÌZÒ\\v²PĔ»ƢNHĂyAmƂwVm`]ÈbH`Ì¢²ILvĜH®¤Dlt_¢JJÄämèÔDëþgºƫaʎÌrêYi~ ÎݤNpÀA¾Ĕ¼b
ð÷®üszMzÖĖQdȨýv§Tè|ªHþa¸|Ð ƒwKĢx¦ivr^ÿ ¸l öæfƟĴ·PJv}n\\h¹¶v·À|\\ƁĚN´ĜçèÁz]ġ¤²¨QÒŨTIlªťØ}¼˗ƦvÄùØE«FïËIqōTvāÜŏíÛßÛVj³âwGăÂíNOPìyV³ʼnĖýZso§HÑiYw[ß\\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ÓƻėojqYhĹT©oūĶ£]ďxĩǑMĝq`B´ƃ˺Чç~²ņj@¥@đ´ί}ĥtPńǾV¬ufÓÉCtÓ̻
¹£G³]ƖƾŎĪŪĘ̖¨ʈĢƂlɘ۪üºňUðǜȢƢż̌ȦǼĤŊɲĖÂKq´ï¦ºĒDzņɾªǀÞĈĂD½ĄĎÌŗĞrôñnN¼â¾ʄľԆ|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ǚ\\đ¾JwÀďksãAfÕ¦L}waoZD½Ml«]eÒÅaɲáo½FõÛ]ĻÒ¡wYR£¢rvÓ®y®LFLzĈô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ĺSZgrpiƼĘÔ¨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\\ZjÒ¨GtpþYŊĕ´zUOëPîMĄÁxH´áiÜUàîÜŐĂÛSuŎrJð̬EFÁú×uÃÎkrĒ{V}İ«O_ÌËĬ©ÓŧSRѱ§Ģ£^ÂyèçěM³Ƃę{[¸¿u
ºµ[gt£¸OƤĿéYõ·kĀq]juw¥DĩƍõÇPéĽG©ã¤G
uȧþRcÕĕNyyû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ĻĖHAëáa
OÇðñęNw
œľ·LmI±íĠĩPÉ×®ÿscB³±JKßĊ«`
ađ»·QAmOVţéÿ¤¹SQt]]Çx±¯A@ĉij¢Óļ©l¶ÅÛrŕspãRk~¦ª]Į´FRådČsCqđéFn¿ÅƃmÉx{W©ºƝºįkÕƂƑ¸wWūЩÈF£\\tÈ¥ÄRÈýÌJ lGr^×äùyÞ³fjc¨£ÂZ|ǓMĝÏ@ëÜőRĝ÷¡{aïȷPu°ËXÙ{©TmĠ}Y³ÞIňµç½©C¡į÷¯B»|St»]vųs»}MÓ ÿʪƟǭA¡fs»PY¼c¡»¦cċ¥£~msĉPSi^o©AecPeǵkgyUi¿h}aHĉ^|á´¡HØûÅ«ĉ®]m¡qĉ¶³ÈyôōLÁstB®wn±ă¥HSòė£Së@לÊăxÇN©©T±ª£IJ¡fb®Þbb_Ą¥xu¥B{łĝ³«`dƐt¤ťiñÍUuºí`£^tƃIJc·ÛLO½sç¥Ts{ă\\_»kϱq©čiìĉ|ÍI¥ć¥]ª§D{ŝŖÉR_sÿc³ĪōƿΧp[ĉc¯bKmR¥{³Ze^wx¹dƽŽôIg §Mĕ ƹĴ¿ǣÜÍ]Ý]snåA{eƭ`ǻŊĿ\\ijŬűYÂÿ¬jĖqßb¸L«¸©@ěĀ©ê¶ìÀEH|´bRľÓ¶rÀQþvl®ÕETzÜdb hw¤{LRdcb¯ÙVgƜßzÃôì®^jUèXÎ|UäÌ»rK\\ªN¼pZCüVY¤ɃRi^rPŇTÖ}|br°qňb̰ªiƶGQ¾²x¦PmlŜ[Ĥ¡Ξ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ðļATUvdTGº̼Ô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_bsKF¯¡IxmELcÿZ¤ĢÝsuBLùtYdmVtNmtOPhRw~bd
¾qÐ\\âÙH\\bImlNZ»loqlVmGā§~QCw¤{A\\PKNY¯bFkC¥sks_Ã\\ă«¢ħkJi¯rrAhĹûç£CUĕĊ_ÔBixÅÙĄnªÑaM~ħpOu¥sîeQ¥¤^dkKwlL~{L~hw^ófćKyEKzuÔ¡qQ¤xZÑ¢^ļöܾEp±âbÊÑÆ^fk¬
NC¾YpxbK~¥eÖäBlt¿Đx½I[ĒǙWf»Ĭ}d§dµùEuj¨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ģ¢\\śnkOw¥±T»ƷFɯàĩÞáB¹Æ
ÑUwŕĽw[mG½Èå~Æ÷QyěCFmĭZīŵVÁƿQƛûXS²b½KϽĉS©ŷXĕ{ĕK·¥Ɨcqq©f¿]ßDõU³hgËÇïģÉɋwk¯í}I·œbmÉřīJɥĻˁ×xoɹīlc
¤³Xù]DžA¿w͉ì¥wÇN·ÂËnƾƍdǧđ®ƝvUm©³G\\}µĿQyŹlăµEwLJQ½yƋBe¶ŋÀůo¥AÉw@{Gpm¿AijŽKLh³`ñcËtW±»ÕSëüÿďDu\\wwwù³VLŕOMËGh£õP¡erÏd{ġWÁ
č|yšg^ğyÁzÙs`s|ÉåªÇ}m¢Ń¨`x¥ù^}Ì¥H«YªƅAйn~ź¯f¤áÀzgÇDIÔ´AňĀÒ¶ûEYospõD[{ù°]uJqU|Soċxţ[õÔĥkŋÞŭZ˺óYËüċrw ÞkrťË¿XGÉbřaDü·Ē÷Aê[ÄäI®BÕĐÞ_¢āĠpÛÄȉĖġDKwbmÄNôfƫVÉvidzHQµâFùœ³¦{YGd¢ĚÜO {Ö¦ÞÍÀP^bƾl[vt×ĈÍE˨¡Đ~´î¸ùÎhuè`¸HÕŔVºwĠââWò@{ÙNÝ´ə²ȕn{¿¥{l÷eé^eďXj©î\\ªÑòÜìc\\üqÕ[Č¡xoÂċªbØø|¶ȴZdÆÂońéG\\¼C°ÌÆn´nxÊOĨŪƴĸ¢¸òTxÊǪMīĞÖŲÃɎOvʦƢ~FRěò¿ġ~åŊúN¸qĘ[Ĕ¶ÂćnÒPĒÜvúĀÊbÖ{Äî¸~Ŕünp¤ÂH¾ĄYÒ©ÊfºmÔĘcDoĬMŬS¤s²ʘÚžȂVŦ èW°ªB|IJXŔþÈJĦÆæFĚêYĂªĂ]øªŖNÞüAfɨJ¯ÎrDDĤ`mz\\§~D¬{vJ«lµĂb¤pŌŰNĄ¨ĊXW|ų ¿¾ɄĦƐMTòP÷fØĶK¢ȝ˔Sô¹òEð`Ɩ½ǒÂň×äı§ĤƝ§C~¡hlåǺŦŞkâ~}FøàIJaĞfƠ¥Ŕd®U¸źXv¢aƆúŪtŠųƠjdƺƺÅìnrh\\ĺ¯äɝĦ]èpĄ¦´LƞĬ´ƤǬ˼Ēɸ¤rºǼ²¨zÌPðŀbþ¹ļD¢¹\\ĜÑŚ¶ZƄ³àjĨoâȴLÊȮĐĚăÀêZǚŐ¤qȂ\\L¢ŌİfÆs|zºeªÙæ§{Ā´ƐÚ¬¨Ĵà²łhʺKÞºÖTiƢ¾ªì°`öø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ŧoaFLgQN_dV@Zom_ć\\ßc±x¯oœRcfe
£o§ËgToÛJíĔóu
|wP¤XnO¢ÉŦ¯rNÄā¤zâŖÈRpŢZÚ{GrFt¦Òx§ø¹RóäV¤XdżâºWbwڍUd®bêņ¾jnŎGŃŶnzÚSeîĜZczî¾i]ÍQaúÍÔiþĩȨWĢü|Ėu[qb[swP@ÅğP¿{\\¥A¨ÏѨj¯X\\¯MKpA³[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
¶F̬O_ïlÁgz±AXeµÄĵ{¶]gitgIj·¥îakS¨ÐƎk}ĕ{gBqGf{¿aU^fIư³õ{YıëNĿk©ïËZŏR§òoY×Ógc
ĥs¡bġ«@dekąI[nlPqCnp{ō³°`{PNdƗqSÄĻNNâyj]äÒD ĬH°Æ]~¡HO¾X}ÐxgpgWrDGpù^LrzWxZ^¨´T\\|~@IzbĤjeĊªz£®ĔvěLmV¾Ô_È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ƸÁxc"],
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´òKLÈüD|s`ŋć]Ã`đMûƱ½~Y°ħ`ƏíW½eI½{aOIrÏ¡ĕŇapµÜƅġ^ÖÛbÙŽŏml½SêqDu[RãË»ÿw`»y¸_ĺę}÷`M¯ċfCVµqʼn÷Zgg`d½pDOÎCn^uf²ènh¼WtƏxRGg¦
pVFI±G^Ic´ecGĹÞ½sëĬhxW}KÓeXsbkF¦LØgTkïƵNï¶}Gyw\\oñ¡nmĈzj@Óc£»Wă¹Ój_m»¹·~MvÛaq»ê\\ÂoVnÓØÍ²«bq¿efE Ĝ^Q~ Évýş¤²ĮpEİ}zcĺL½¿gÅ¡ýE¡ya£³t\\¨\\vú»¼§·Ñr_oÒý¥u_n»_At©Þűā§IVeëY}{VPÀFA¨ąB}q@|Ou\\FmQFÝ
Mwå}]|FmÏCawu_p¯sfÙgY
DHl`{QEfNysB¦zG¸rHeN\\CvEsÐùÜ_·ÖĉsaQ¯}_UxÃđqNH¬Äd^ÝŰR¬ã°wećJE·vÝ·HgéFXjÉê`|ypxkAwWĐpb¥eOsmzwqChóUQl¥F^lafanòsrEvfQdÁUVfÎvÜ^eftET¬ôA\\¢sJnQTjPØxøK|nBzĞ»LY
FDxÓvr[ehľvN¢o¾NiÂxGpâ¬zbfZo~hGi]öF||NbtOMn eA±tPTLjpYQ|SHYĀxinzDJÌg¢và¥Pg_ÇzIIII£®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 | ["@@mn"],
831 | ["@@EpFo"],
832 | ["@@ea¢pl¸Eõ¹hj[]ÔCÎ@lj¡uBX
´AI¹
[yDU]W`çwZkmc
MpÅv}IoJlcafŃK°ä¬XJmÐ đhI®æÔtSHnEÒrÈc"],
833 | ["@@rMUwAS®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 |
2 |
5 |
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 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
16 |
19 |
26 |
27 |
28 |
35 | {{ option.title }}
41 |
42 |
43 |
44 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
59 |
60 |
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 |
2 |
3 |
11 |
18 |
24 |
31 |
32 |
33 |
34 |
35 | {{ scope.row[propItem.prop] }}
36 |
37 |
38 |
39 |
40 |
41 |
55 |
56 |
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 |
2 |
13 |
14 |
15 |
54 |
55 |
74 |
--------------------------------------------------------------------------------
/src/components/nav-header/src/user-info.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 | {{ name }}
10 |
11 |
12 |
13 | 退出登录
16 | 用户信息
17 | 系统管理
18 |
19 |
20 |
21 |
22 |
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 |
2 |
46 |
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 |
2 |
3 |
9 |
10 |
11 |
17 | 新建用户
18 |
19 |
20 |
21 |
22 |
23 |
28 | {{ scope.row.enable ? '启用' : '禁用' }}
29 |
30 |
31 |
32 | {{ $filters.formatTime(scope.row.createAt) }}
33 |
34 |
35 | {{ $filters.formatTime(scope.row.updateAt) }}
36 |
37 |
38 |
39 |
46 | 编辑
47 |
48 | 删除
56 |
57 |
58 |
59 |
60 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
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 |
2 |
3 |
4 |
5 |
6 |
7 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/src/components/page-echarts/src/line-echart.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/src/components/page-echarts/src/map-echart.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/src/components/page-echarts/src/pie-echart.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/components/page-echarts/src/rose-echart.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
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 |
2 |
3 |
10 |
11 |
12 |
13 |
19 |
20 |
21 |
22 |
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 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 重置
12 | 搜索
18 |
19 |
20 |
21 |
22 |
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 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/src/views/login/cpns/login-panel.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
后台管理系统
4 |
5 |
6 |
7 | 账号登录
8 |
9 |
10 |
11 |
12 |
13 | 手机登录
14 |
15 |
16 |
17 |
18 |
19 |
20 | 记住密码
21 | 忘记密码
22 |
23 |
24 |
立即登录
27 |
28 |
29 |
30 |
66 |
67 |
88 |
--------------------------------------------------------------------------------
/src/views/login/cpns/login-phone.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 获取验证码
10 |
11 |
12 |
13 |
14 |
15 |
31 |
32 |
41 |
--------------------------------------------------------------------------------
/src/views/login/login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
20 |
21 |
31 |
--------------------------------------------------------------------------------
/src/views/main/analysis/dashboard/dashboard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
105 |
106 |
111 |
--------------------------------------------------------------------------------
/src/views/main/analysis/overview/overview.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
overview
4 |
5 |
6 |
7 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/views/main/main.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
44 |
45 |
102 |
--------------------------------------------------------------------------------
/src/views/main/product/category/category.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
category
4 |
5 |
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 |
2 |
3 |
4 |
5 |
10 |
11 |
12 | {{ '¥' + scope.row.oldPrice }}
13 |
14 |
15 |
16 |
17 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/views/main/story/chat/chat.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
chat
4 |
5 |
6 |
7 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/views/main/story/list/list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
list
4 |
5 |
6 |
7 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/views/main/system/department/department.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
department
4 |
5 |
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 |
2 |
8 |
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 |
2 |
3 |
4 |
10 |
17 |
28 |
29 |
30 |
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 |
2 |
22 |
23 |
24 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/src/views/not-found/not-found.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Not Found
4 |
5 |
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 |
--------------------------------------------------------------------------------