refactor: 删除无用的组件,增加新的menu列表和组件

master
钟良源 6 months ago
parent ab9124247f
commit c2f606078b

@ -16,7 +16,6 @@
"@arco-design/web-react": "^2.32.2", "@arco-design/web-react": "^2.32.2",
"@arco-themes/react-arco-pro": "^0.0.7", "@arco-themes/react-arco-pro": "^0.0.7",
"@loadable/component": "^5.13.2", "@loadable/component": "^5.13.2",
"@tinyflow-ai/react": "^1.1.0",
"@turf/turf": "^6.5.0", "@turf/turf": "^6.5.0",
"@xyflow/react": "^12.8.2", "@xyflow/react": "^12.8.2",
"axios": "^0.24.0", "axios": "^0.24.0",
@ -37,7 +36,6 @@
"redux": "^4.1.2" "redux": "^4.1.2"
}, },
"devDependencies": { "devDependencies": {
"@arco-design/web-react": "^2.0.0",
"@svgr/webpack": "^5.5.0", "@svgr/webpack": "^5.5.0",
"@types/node": "16.11.7", "@types/node": "16.11.7",
"@types/react": "17.0.2", "@types/react": "17.0.2",

@ -23,9 +23,6 @@ importers:
'@loadable/component': '@loadable/component':
specifier: ^5.13.2 specifier: ^5.13.2
version: 5.16.7(react@17.0.2) version: 5.16.7(react@17.0.2)
'@tinyflow-ai/react':
specifier: ^1.1.0
version: 1.1.0(react-dom@17.0.2(react@17.0.2))(react@17.0.2)(svelte@5.38.1)
'@turf/turf': '@turf/turf':
specifier: ^6.5.0 specifier: ^6.5.0
version: 6.5.0 version: 6.5.0
@ -815,15 +812,6 @@ packages:
resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==} resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==}
engines: {node: ^10.12.0 || >=12.0.0} engines: {node: ^10.12.0 || >=12.0.0}
'@floating-ui/core@1.7.3':
resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==}
'@floating-ui/dom@1.7.3':
resolution: {integrity: sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag==}
'@floating-ui/utils@0.2.10':
resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
'@hapi/accept@5.0.2': '@hapi/accept@5.0.2':
resolution: {integrity: sha512-CmzBx/bXUR8451fnZRuZAJRlzgm0Jgu5dltTX/bszmR2lheb9BpyN47Q1RbaGTsvFzn0PXAEs+lXDKfshccYZw==} resolution: {integrity: sha512-CmzBx/bXUR8451fnZRuZAJRlzgm0Jgu5dltTX/bszmR2lheb9BpyN47Q1RbaGTsvFzn0PXAEs+lXDKfshccYZw==}
@ -850,9 +838,6 @@ packages:
'@jridgewell/gen-mapping@0.3.13': '@jridgewell/gen-mapping@0.3.13':
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
'@jridgewell/remapping@2.3.5':
resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
'@jridgewell/resolve-uri@3.1.2': '@jridgewell/resolve-uri@3.1.2':
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
@ -989,16 +974,6 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
'@svelte-put/shortcut@4.1.0':
resolution: {integrity: sha512-wImNEIkbxAIWFqlfuhcbC+jRPDeRa/uJGIXHMEVVD+jqL9xCwWNnkGQJ6Qb2XVszuRLHlb8SGZDL3Io/h3vs8w==}
peerDependencies:
svelte: ^5.1.0
'@sveltejs/acorn-typescript@1.0.5':
resolution: {integrity: sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==}
peerDependencies:
acorn: ^8.9.0
'@svgr/babel-plugin-add-jsx-attribute@5.4.0': '@svgr/babel-plugin-add-jsx-attribute@5.4.0':
resolution: {integrity: sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==} resolution: {integrity: sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -1055,15 +1030,6 @@ packages:
resolution: {integrity: sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==} resolution: {integrity: sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==}
engines: {node: '>=10'} engines: {node: '>=10'}
'@tinyflow-ai/react@1.1.0':
resolution: {integrity: sha512-Dj7iW9f+BVNhaEQ+6Sft293qP7XPCZyQjR5i6oGtE+MyaHknyXz4M6HocXxToiQYK5GGdZOh5K8C1w1WsyxzvA==}
peerDependencies:
react: ^18.2.0
react-dom: ^18.2.0
'@tinyflow-ai/ui@1.1.0':
resolution: {integrity: sha512-FOnyzO/7VGTO7BvAhryDqf0irqlQMGqOPgTZ8t3kCUPDlZ/iNk3sHl0zeLCM1jbZZTlEovw0TraClaWxJGyJ0g==}
'@turf/along@6.5.0': '@turf/along@6.5.0':
resolution: {integrity: sha512-LLyWQ0AARqJCmMcIEAXF4GEu8usmd4Kbz3qk1Oy5HoRNpZX47+i5exQtmIWKdqJ1MMhW26fCTXgpsEs5zgJ5gw==} resolution: {integrity: sha512-LLyWQ0AARqJCmMcIEAXF4GEu8usmd4Kbz3qk1Oy5HoRNpZX47+i5exQtmIWKdqJ1MMhW26fCTXgpsEs5zgJ5gw==}
@ -1574,11 +1540,6 @@ packages:
react: '>=17' react: '>=17'
react-dom: '>=17' react-dom: '>=17'
'@xyflow/svelte@1.2.3':
resolution: {integrity: sha512-Fglx+QQATKd/k55PBQMESNtokj7y+LXRFsukVr3DwlIsemJ4W7cF7gTKP2+TIfnviXIlBtzFPx6iJATV+dx0Iw==}
peerDependencies:
svelte: ^5.25.0
'@xyflow/system@0.0.67': '@xyflow/system@0.0.67':
resolution: {integrity: sha512-hYsmbj+8JDei0jmupBmxNLaeJEcf9kKmMl6IziGe02i0TOCsHwjIdP+qz+f4rI1/FR2CQiCZJrw4dkHOLC6tEQ==} resolution: {integrity: sha512-hYsmbj+8JDei0jmupBmxNLaeJEcf9kKmMl6IziGe02i0TOCsHwjIdP+qz+f4rI1/FR2CQiCZJrw4dkHOLC6tEQ==}
@ -1672,10 +1633,6 @@ packages:
argparse@1.0.10: argparse@1.0.10:
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
aria-query@5.3.2:
resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
engines: {node: '>= 0.4'}
array-buffer-byte-length@1.0.2: array-buffer-byte-length@1.0.2:
resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -1737,10 +1694,6 @@ packages:
axios@0.24.0: axios@0.24.0:
resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==} resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==}
axobject-query@4.1.0:
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
engines: {node: '>= 0.4'}
b-tween@0.3.3: b-tween@0.3.3:
resolution: {integrity: sha512-oEHegcRpA7fAuc9KC4nktucuZn2aS8htymCPcP3qkEGPqiBH+GfqtqoG2l7LxHngg6O0HFM7hOeOYExl1Oz4ZA==} resolution: {integrity: sha512-oEHegcRpA7fAuc9KC4nktucuZn2aS8htymCPcP3qkEGPqiBH+GfqtqoG2l7LxHngg6O0HFM7hOeOYExl1Oz4ZA==}
@ -1934,10 +1887,6 @@ packages:
resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==}
engines: {node: '>=6'} engines: {node: '>=6'}
clsx@2.1.1:
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
engines: {node: '>=6'}
coa@2.0.2: coa@2.0.2:
resolution: {integrity: sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==} resolution: {integrity: sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==}
engines: {node: '>= 4.0'} engines: {node: '>= 4.0'}
@ -2483,9 +2432,6 @@ packages:
deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
hasBin: true hasBin: true
esm-env@1.2.2:
resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==}
espree@7.3.1: espree@7.3.1:
resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==} resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==}
engines: {node: ^10.12.0 || >=12.0.0} engines: {node: ^10.12.0 || >=12.0.0}
@ -2499,9 +2445,6 @@ packages:
resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
engines: {node: '>=0.10'} engines: {node: '>=0.10'}
esrap@2.1.0:
resolution: {integrity: sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==}
esrecurse@4.3.0: esrecurse@4.3.0:
resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
engines: {node: '>=4.0'} engines: {node: '>=4.0'}
@ -2965,9 +2908,6 @@ packages:
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
is-reference@3.0.3:
resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==}
is-regex@1.1.4: is-regex@1.1.4:
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -3145,9 +3085,6 @@ packages:
resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==}
engines: {node: '>=8.9.0'} engines: {node: '>=8.9.0'}
locate-character@3.0.0:
resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==}
locate-path@5.0.0: locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -3185,9 +3122,6 @@ packages:
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
engines: {node: '>=10'} engines: {node: '>=10'}
magic-string@0.30.17:
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
make-dir@2.1.0: make-dir@2.1.0:
resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -4213,10 +4147,6 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
svelte@5.38.1:
resolution: {integrity: sha512-fO6CLDfJYWHgfo6lQwkQU2vhCiHc2MBl6s3vEhK+sSZru17YL4R5s1v14ndRpqKAIkq8nCz6MTk1yZbESZWeyQ==}
engines: {node: '>=18'}
svg-parser@2.0.4: svg-parser@2.0.4:
resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==}
@ -4570,9 +4500,6 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'} engines: {node: '>=10'}
zimmerframe@1.1.2:
resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==}
zustand@4.5.7: zustand@4.5.7:
resolution: {integrity: sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==} resolution: {integrity: sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==}
engines: {node: '>=12.7.0'} engines: {node: '>=12.7.0'}
@ -5548,17 +5475,6 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@floating-ui/core@1.7.3':
dependencies:
'@floating-ui/utils': 0.2.10
'@floating-ui/dom@1.7.3':
dependencies:
'@floating-ui/core': 1.7.3
'@floating-ui/utils': 0.2.10
'@floating-ui/utils@0.2.10': {}
'@hapi/accept@5.0.2': '@hapi/accept@5.0.2':
dependencies: dependencies:
'@hapi/boom': 9.1.4 '@hapi/boom': 9.1.4
@ -5589,11 +5505,6 @@ snapshots:
'@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/sourcemap-codec': 1.5.5
'@jridgewell/trace-mapping': 0.3.30 '@jridgewell/trace-mapping': 0.3.30
'@jridgewell/remapping@2.3.5':
dependencies:
'@jridgewell/gen-mapping': 0.3.13
'@jridgewell/trace-mapping': 0.3.30
'@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/resolve-uri@3.1.2': {}
'@jridgewell/source-map@0.3.11': '@jridgewell/source-map@0.3.11':
@ -5700,14 +5611,6 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5 '@nodelib/fs.scandir': 2.1.5
fastq: 1.19.1 fastq: 1.19.1
'@svelte-put/shortcut@4.1.0(svelte@5.38.1)':
dependencies:
svelte: 5.38.1
'@sveltejs/acorn-typescript@1.0.5(acorn@8.15.0)':
dependencies:
acorn: 8.15.0
'@svgr/babel-plugin-add-jsx-attribute@5.4.0': {} '@svgr/babel-plugin-add-jsx-attribute@5.4.0': {}
'@svgr/babel-plugin-remove-jsx-attribute@5.4.0': {} '@svgr/babel-plugin-remove-jsx-attribute@5.4.0': {}
@ -5775,21 +5678,6 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@tinyflow-ai/react@1.1.0(react-dom@17.0.2(react@17.0.2))(react@17.0.2)(svelte@5.38.1)':
dependencies:
'@tinyflow-ai/ui': 1.1.0(svelte@5.38.1)
react: 17.0.2
react-dom: 17.0.2(react@17.0.2)
transitivePeerDependencies:
- svelte
'@tinyflow-ai/ui@1.1.0(svelte@5.38.1)':
dependencies:
'@floating-ui/dom': 1.7.3
'@xyflow/svelte': 1.2.3(svelte@5.38.1)
transitivePeerDependencies:
- svelte
'@turf/along@6.5.0': '@turf/along@6.5.0':
dependencies: dependencies:
'@turf/bearing': 6.5.0 '@turf/bearing': 6.5.0
@ -6857,12 +6745,6 @@ snapshots:
- '@types/react' - '@types/react'
- immer - immer
'@xyflow/svelte@1.2.3(svelte@5.38.1)':
dependencies:
'@svelte-put/shortcut': 4.1.0(svelte@5.38.1)
'@xyflow/system': 0.0.67
svelte: 5.38.1
'@xyflow/system@0.0.67': '@xyflow/system@0.0.67':
dependencies: dependencies:
'@types/d3-drag': 3.0.7 '@types/d3-drag': 3.0.7
@ -6949,8 +6831,6 @@ snapshots:
dependencies: dependencies:
sprintf-js: 1.0.3 sprintf-js: 1.0.3
aria-query@5.3.2: {}
array-buffer-byte-length@1.0.2: array-buffer-byte-length@1.0.2:
dependencies: dependencies:
call-bound: 1.0.4 call-bound: 1.0.4
@ -7050,8 +6930,6 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- debug - debug
axobject-query@4.1.0: {}
b-tween@0.3.3: {} b-tween@0.3.3: {}
b-validate@1.5.3: {} b-validate@1.5.3: {}
@ -7305,8 +7183,6 @@ snapshots:
kind-of: 6.0.3 kind-of: 6.0.3
shallow-clone: 3.0.1 shallow-clone: 3.0.1
clsx@2.1.1: {}
coa@2.0.2: coa@2.0.2:
dependencies: dependencies:
'@types/q': 1.5.8 '@types/q': 1.5.8
@ -7988,8 +7864,6 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
esm-env@1.2.2: {}
espree@7.3.1: espree@7.3.1:
dependencies: dependencies:
acorn: 7.4.1 acorn: 7.4.1
@ -8002,10 +7876,6 @@ snapshots:
dependencies: dependencies:
estraverse: 5.3.0 estraverse: 5.3.0
esrap@2.1.0:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
esrecurse@4.3.0: esrecurse@4.3.0:
dependencies: dependencies:
estraverse: 5.3.0 estraverse: 5.3.0
@ -8468,10 +8338,6 @@ snapshots:
is-plain-object@5.0.0: {} is-plain-object@5.0.0: {}
is-reference@3.0.3:
dependencies:
'@types/estree': 1.0.8
is-regex@1.1.4: is-regex@1.1.4:
dependencies: dependencies:
call-bind: 1.0.8 call-bind: 1.0.8
@ -8646,8 +8512,6 @@ snapshots:
emojis-list: 3.0.0 emojis-list: 3.0.0
json5: 2.2.3 json5: 2.2.3
locate-character@3.0.0: {}
locate-path@5.0.0: locate-path@5.0.0:
dependencies: dependencies:
p-locate: 4.1.0 p-locate: 4.1.0
@ -8678,10 +8542,6 @@ snapshots:
dependencies: dependencies:
yallist: 4.0.0 yallist: 4.0.0
magic-string@0.30.17:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
make-dir@2.1.0: make-dir@2.1.0:
dependencies: dependencies:
pify: 4.0.1 pify: 4.0.1
@ -9874,23 +9734,6 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {} supports-preserve-symlinks-flag@1.0.0: {}
svelte@5.38.1:
dependencies:
'@jridgewell/remapping': 2.3.5
'@jridgewell/sourcemap-codec': 1.5.5
'@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0)
'@types/estree': 1.0.8
acorn: 8.15.0
aria-query: 5.3.2
axobject-query: 4.1.0
clsx: 2.1.1
esm-env: 1.2.2
esrap: 2.1.0
is-reference: 3.0.3
locate-character: 3.0.0
magic-string: 0.30.17
zimmerframe: 1.1.2
svg-parser@2.0.4: {} svg-parser@2.0.4: {}
svg-tags@1.0.0: {} svg-tags@1.0.0: {}
@ -10295,8 +10138,6 @@ snapshots:
yocto-queue@0.1.0: {} yocto-queue@0.1.0: {}
zimmerframe@1.1.2: {}
zustand@4.5.7(@types/react@17.0.2)(react@17.0.2): zustand@4.5.7(@types/react@17.0.2)(react@17.0.2):
dependencies: dependencies:
use-sync-external-store: 1.5.0(react@17.0.2) use-sync-external-store: 1.5.0(react@17.0.2)

@ -28,6 +28,13 @@ const i18n = {
'menu.user.role.admin': 'Admin', 'menu.user.role.admin': 'Admin',
'menu.user.role.user': 'General User', 'menu.user.role.user': 'General User',
'menu.dashboard.workplace': 'Workplace', 'menu.dashboard.workplace': 'Workplace',
'menu.scene': 'All Engineering',
'menu.application': 'All Applications',
'menu.instance': 'Application Instance',
'menu.componentDevelopment': 'Component Development',
'menu.componentLibrary': 'Component Library',
'menu.compositeCompLibrary': 'Composite Component Library',
'menu.componentMarket': 'Component Market',
'navbar.logout': 'Logout', 'navbar.logout': 'Logout',
'settings.title': 'Settings', 'settings.title': 'Settings',
'settings.themeColor': 'Theme Color', 'settings.themeColor': 'Theme Color',
@ -56,7 +63,7 @@ const i18n = {
'message.empty': 'Empty', 'message.empty': 'Empty',
'message.empty.tips': 'No Content', 'message.empty.tips': 'No Content',
'message.lang.tips': 'Language switch to ', 'message.lang.tips': 'Language switch to ',
'navbar.search.placeholder': 'Please search', 'navbar.search.placeholder': 'Please search'
}, },
'zh-CN': { 'zh-CN': {
'menu.dashboard': '仪表盘', 'menu.dashboard': '仪表盘',
@ -86,6 +93,13 @@ const i18n = {
'menu.user.role.admin': '管理员', 'menu.user.role.admin': '管理员',
'menu.user.role.user': '普通用户', 'menu.user.role.user': '普通用户',
'menu.dashboard.workplace': '工作台', 'menu.dashboard.workplace': '工作台',
'menu.scene': '所有工程',
'menu.application': '所有应用',
'menu.instance': '应用实例',
'menu.componentDevelopment': '组件开发',
'menu.componentLibrary': '组件库',
'menu.compositeCompLibrary': '复合组件库',
'menu.componentMarket': '组件市场',
'navbar.logout': '退出登录', 'navbar.logout': '退出登录',
'settings.title': '页面配置', 'settings.title': '页面配置',
'settings.themeColor': '主题色', 'settings.themeColor': '主题色',
@ -114,8 +128,8 @@ const i18n = {
'message.empty': '清空', 'message.empty': '清空',
'message.empty.tips': '暂无内容', 'message.empty.tips': '暂无内容',
'message.lang.tips': '语言切换至 ', 'message.lang.tips': '语言切换至 ',
'navbar.search.placeholder': '输入内容查询', 'navbar.search.placeholder': '输入内容查询'
}, }
}; };
export default i18n; export default i18n;

@ -0,0 +1,13 @@
import React from 'react';
function Application() {
return (
<>
<div>
</div>
</>
);
}
export default Application;

@ -0,0 +1,13 @@
import React from 'react';
function ComponentDevelopment() {
return (
<>
<div>
</div>
</>
);
}
export default ComponentDevelopment;

@ -0,0 +1,13 @@
import React from 'react';
function ComponentLibrary() {
return (
<>
<div>
</div>
</>
);
}
export default ComponentLibrary;

@ -0,0 +1,13 @@
import React from 'react';
function ComponentMarket() {
return (
<>
<div>
</div>
</>
);
}
export default ComponentMarket;

@ -0,0 +1,13 @@
import React from 'react';
function CompositeCompLibrary() {
return (
<>
<div>
</div>
</>
);
}
export default CompositeCompLibrary;

@ -1,74 +0,0 @@
import React, { useEffect, useState } from 'react';
import {
Space,
Select,
Input,
Button,
Typography,
Spin,
} from '@arco-design/web-react';
import { IconDownload, IconFaceSmileFill } from '@arco-design/web-react/icon';
import axios from 'axios';
import useLocale from '@/utils/useLocale';
import locale from './locale';
import MessageList from './message-list';
import styles from './style/index.module.less';
export default function ChatPanel() {
const t = useLocale(locale);
const [messageList, setMessageList] = useState([]);
const [loading, setLoading] = useState(false);
function fetchMessageList() {
setLoading(true);
axios
.get('/api/chatList')
.then((res) => {
setMessageList(res.data || []);
})
.finally(() => {
setLoading(false);
});
}
useEffect(() => {
fetchMessageList();
}, []);
return (
<div className={styles['chat-panel']}>
<div className={styles['chat-panel-header']}>
<Typography.Title
style={{ marginTop: 0, marginBottom: 16 }}
heading={6}
>
{t['monitor.title.chatPanel']}
</Typography.Title>
<Space size={8}>
<Select style={{ width: 80 }} defaultValue="all">
<Select.Option value="all">
{t['monitor.chat.options.all']}
</Select.Option>
</Select>
<Input.Search
placeholder={t['monitor.chat.placeholder.searchCategory']}
/>
<Button type="text" iconOnly>
<IconDownload />
</Button>
</Space>
</div>
<div className={styles['chat-panel-content']}>
<Spin loading={loading} style={{ width: '100%' }}>
<MessageList data={messageList} />
</Spin>
</div>
<div className={styles['chat-panel-footer']}>
<Space size={8}>
<Input suffix={<IconFaceSmileFill />} />
<Button type="primary">{t['monitor.chat.update']}</Button>
</Space>
</div>
</div>
);
}

@ -1,76 +0,0 @@
import { Table, Tag, Typography } from '@arco-design/web-react';
import React from 'react';
import useLocale from '@/utils/useLocale';
import locale from './locale';
import styles from './style/index.module.less';
export default function QuickOperation() {
const t = useLocale(locale);
const columns = [
{
title: t['monitor.list.title.order'],
render: (_col, _record, index) => <span>{index + 1}</span>,
},
{
title: t['monitor.list.title.cover'],
dataIndex: 'cover',
render: (_col, record) => (
<div className={styles['data-statistic-list-cover-wrapper']}>
<img src={record.cover} />
{record.status === -1 && (
<Tag
color="red"
className={styles['data-statistic-list-cover-tag']}
>
{t['monitor.list.tag.auditFailed']}
</Tag>
)}
</div>
),
},
{
title: t['monitor.list.title.name'],
dataIndex: 'name',
},
{
dataIndex: 'duration',
title: t['monitor.list.title.duration'],
},
{
dataIndex: 'id',
title: t['monitor.list.title.id'],
},
];
const data = [
{
cover:
'http://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/c788fc704d32cf3b1136c7d45afc2669.png~tplv-uwbnlip3yd-webp.webp',
name: '视频直播',
duration: '00:05:19',
id: '54e23ade',
status: -1,
},
];
return (
<div className={styles['']}>
<Table
columns={columns}
data={data}
rowKey="id"
rowSelection={{
type: 'checkbox',
}}
border={false}
pagination={false}
/>
<Typography.Text
type="secondary"
className={styles['data-statistic-list-tip']}
>
{t['monitor.list.tip.rotations']}
{data.length}
{t['monitor.list.tip.rest']}
</Typography.Text>
</div>
);
}

@ -1,42 +0,0 @@
import { Button, Card, Radio, Tabs } from '@arco-design/web-react';
import React from 'react';
import useLocale from '@/utils/useLocale';
import locale from './locale';
import DataStatisticList from './data-statistic-list';
import styles from './style/index.module.less';
export default function DataStatistic() {
const t = useLocale(locale);
return (
<Card>
<Tabs defaultActiveTab="liveMethod">
<Tabs.TabPane
key="liveMethod"
title={t['monitor.tab.title.liveMethod']}
/>
<Tabs.TabPane
key="onlineUsers"
title={t['monitor.tab.title.onlineUsers']}
/>
</Tabs>
<div className={styles['data-statistic-content']}>
<Radio.Group defaultValue="3" type="button">
<Radio value="1">{t['monitor.liveMethod.normal']}</Radio>
<Radio value="2">{t['monitor.liveMethod.flowControl']}</Radio>
<Radio value="3">{t['monitor.liveMethod.video']}</Radio>
<Radio value="4">{t['monitor.liveMethod.web']}</Radio>
</Radio.Group>
<div className={styles['data-statistic-list-wrapper']}>
<div className={styles['data-statistic-list-header']}>
<Button type="text">{t['monitor.editCarousel']}</Button>
<Button disabled>{t['monitor.startCarousel']}</Button>
</div>
<div className={styles['data-statistic-list-content']}>
<DataStatisticList />
</div>
</div>
</div>
</Card>
);
}

@ -1,37 +0,0 @@
import { Space } from '@arco-design/web-react';
import React from 'react';
import { useSelector } from 'react-redux';
import ChatPanel from './chat-panel';
import Studio from './studio';
import DataStatistic from './data-statistic';
import StudioStatus from './studio-status';
import QuickOperation from './quick-operation';
import StudioInformation from './studio-information';
import styles from './style/index.module.less';
import './mock';
export default function Monitor() {
const userInfo = useSelector((state: any) => state.userInfo);
return (
<div>
<div className={styles.layout}>
<div className={styles['layout-left-side']}>
<ChatPanel />
</div>
<div className={styles['layout-content']}>
<Space size={16} direction="vertical" style={{ width: '100%' }}>
<Studio userInfo={userInfo} />
<DataStatistic />
</Space>
</div>
<div className={styles['layout-right-side']}>
<Space size={16} direction="vertical" style={{ width: '100%' }}>
<StudioStatus />
<QuickOperation />
<StudioInformation />
</Space>
</div>
</div>
</div>
);
}

@ -1,99 +0,0 @@
const i18n = {
'en-US': {
'menu.dashboard': 'Dashboard',
'monitor.title.chatPanel': 'Chat Window',
'monitor.title.quickOperation': 'Quick Operation',
'monitor.title.studioInfo': 'Studio Information',
'monitor.title.studioPreview': 'Studio Preview',
'monitor.chat.options.all': 'All',
'monitor.chat.placeholder.searchCategory': 'Search Category',
'monitor.chat.update': 'Update',
'monitor.list.title.order': 'Order',
'monitor.list.title.cover': 'Cover',
'monitor.list.title.name': 'Name',
'monitor.list.title.duration': 'Duration',
'monitor.list.title.id': 'ID',
'monitor.list.tip.rotations': 'Rotations ',
'monitor.list.tip.rest': ', The program list is not visible to viewers',
'monitor.list.tag.auditFailed': 'Audit Failed',
'monitor.tab.title.liveMethod': 'Live Method',
'monitor.tab.title.onlineUsers': 'Online Users',
'monitor.liveMethod.normal': 'Normal Live',
'monitor.liveMethod.flowControl': 'Flow Control Live',
'monitor.liveMethod.video': 'Video Live',
'monitor.liveMethod.web': 'Web Live',
'monitor.editCarousel': 'Edit',
'monitor.startCarousel': 'Start',
'monitor.quickOperation.changeClarity': 'Change the Clarity',
'monitor.quickOperation.switchStream': 'Switch Stream',
'monitor.quickOperation.removeClarity': 'Remove the Clarity',
'monitor.quickOperation.pushFlowGasket': 'Push Flow Gasket',
'monitor.studioInfo.label.studioTitle': 'Studio Title',
'monitor.studioInfo.label.onlineNotification': 'Online Notification',
'monitor.studioInfo.label.studioCategory': 'Studio Category',
'monitor.studioInfo.placeholder.studioTitle': "'s Studio",
'monitor.studioStatus.title.studioStatus': 'Studio Status',
'monitor.studioStatus.title.pictureInfo': 'Picture Information',
'monitor.studioStatus.smooth': 'Smooth',
'monitor.studioStatus.frameRate': 'Frame',
'monitor.studioStatus.bitRate': 'Bit',
'monitor.studioStatus.mainstream': 'Main',
'monitor.studioStatus.hotStandby': 'Hot',
'monitor.studioStatus.coldStandby': 'Cold',
'monitor.studioStatus.line': 'Line',
'monitor.studioStatus.play': 'Format',
'monitor.studioStatus.pictureQuality': 'Quality',
'monitor.studioPreview.studio': 'Studio',
'monitor.studioPreview.watching': 'watching',
},
'zh-CN': {
'menu.dashboard': '仪表盘',
'menu.dashboard.monitor': '实时监控',
'monitor.title.chatPanel': '聊天窗口',
'monitor.title.quickOperation': '快捷操作',
'monitor.title.studioInfo': '直播信息',
'monitor.title.studioPreview': '直播预览',
'monitor.chat.options.all': '全部',
'monitor.chat.placeholder.searchCategory': '搜索类目',
'monitor.chat.update': '更新',
'monitor.list.title.order': '序号',
'monitor.list.title.cover': '封面',
'monitor.list.title.name': '名称',
'monitor.list.title.duration': '视频时长',
'monitor.list.title.id': '视频Id',
'monitor.list.tip.rotations': '轮播次数',
'monitor.list.tip.rest': ',节目单观众不可见',
'monitor.list.tag.auditFailed': '审核未通过',
'monitor.tab.title.liveMethod': '直播方式',
'monitor.tab.title.onlineUsers': '在线人数',
'monitor.liveMethod.normal': '普通直播',
'monitor.liveMethod.flowControl': '控流直播',
'monitor.liveMethod.video': '视频直播',
'monitor.liveMethod.web': '网页开播',
'monitor.editCarousel': '编辑轮播',
'monitor.startCarousel': '开始轮播',
'monitor.quickOperation.changeClarity': '切换清晰度',
'monitor.quickOperation.switchStream': '主备流切换',
'monitor.quickOperation.removeClarity': '摘除清晰度',
'monitor.quickOperation.pushFlowGasket': '推流垫片',
'monitor.studioInfo.label.studioTitle': '直播标题',
'monitor.studioInfo.label.onlineNotification': '上线通知',
'monitor.studioInfo.label.studioCategory': '直播类目',
'monitor.studioInfo.placeholder.studioTitle': '的直播间',
'monitor.studioStatus.title.studioStatus': '直播状态',
'monitor.studioStatus.title.pictureInfo': '画面信息',
'monitor.studioStatus.smooth': '流畅',
'monitor.studioStatus.frameRate': '帧率',
'monitor.studioStatus.bitRate': '码率',
'monitor.studioStatus.mainstream': '主流',
'monitor.studioStatus.hotStandby': '热备',
'monitor.studioStatus.coldStandby': '冷备',
'monitor.studioStatus.line': '线路',
'monitor.studioStatus.play': '播放格式',
'monitor.studioStatus.pictureQuality': '画质',
'monitor.studioPreview.studio': '直播间',
'monitor.studioPreview.watching': '在看',
},
};
export default i18n;

@ -1,22 +0,0 @@
import React from 'react';
import { Result } from '@arco-design/web-react';
import MessageItem, { Message } from './item';
import styles from './style/index.module.less';
interface MessageListProps {
data: Message[];
}
function MessageList(props: MessageListProps) {
const { data = [] } = props;
return (
<div className={styles['message-list']}>
{data.map((item) => (
<MessageItem key={item.id} data={item} />
))}
{!data.length && <Result status="404" />}
</div>
);
}
export default MessageList;

@ -1,52 +0,0 @@
import React from 'react';
import { Space, Typography } from '@arco-design/web-react';
import { IconCommand, IconStar } from '@arco-design/web-react/icon';
import cs from 'classnames';
import styles from './style/index.module.less';
export interface Message {
id?: string;
username?: string;
content?: string;
time?: string;
isCollect?: boolean;
}
export interface MessageItemProps {
data: Message;
}
function MessageItem(props: MessageItemProps) {
const { data = {} } = props;
const classNames = cs(styles['message-item'], {
[styles['message-item-collected']]: data.isCollect,
});
return (
<div className={classNames}>
<Space size={4} direction="vertical" style={{ width: '100%' }}>
<Typography.Text type="warning">{data.username}</Typography.Text>
<Typography.Text>{data.content}</Typography.Text>
<div className={styles['message-item-footer']}>
<div className={styles['message-item-time']}>
<Typography.Text type="secondary">{data.time}</Typography.Text>
</div>
<div className={styles['message-item-actions']}>
<div className={styles['message-item-actions-item']}>
<IconCommand />
</div>
<div
className={cs(
styles['message-item-actions-item'],
styles['message-item-actions-collect']
)}
>
<IconStar />
</div>
</div>
</div>
</Space>
</div>
);
}
export default MessageItem;

@ -1,52 +0,0 @@
.message-item {
font-size: 12px;
line-height: 20px;
padding: 8px;
border-radius: 2px;
&-footer {
display: flex;
justify-content: space-between;
align-items: center;
}
&-actions {
display: flex;
opacity: 0;
&-item {
margin-right: 4px;
font-size: 14px;
color: var(--color-text-3);
width: 20px;
height: 20px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
&:hover {
background-color: rgb(var(--gray-3));
}
&:last-child {
margin-right: 0;
}
}
}
&-collected {
.message-item-actions-collect {
color: rgb(var(--gold-6));
}
}
&:hover {
background-color: rgb(var(--gray-2));
.message-item-actions {
opacity: 1;
}
}
}

@ -1,21 +0,0 @@
import Mock from 'mockjs';
import setupMock from '@/utils/setupMock';
setupMock({
setup: () => {
Mock.mock(new RegExp('/api/chatList'), () => {
const data = Mock.mock({
'data|4-6': [
{
'id|+1': 1,
username: '用户7352772',
content: '马上就开始了,好激动!',
time: '13:09:12',
'isCollect|2': true,
},
],
});
return data.data;
});
},
});

@ -1,35 +0,0 @@
import React from 'react';
import { Button, Card, Typography, Space } from '@arco-design/web-react';
import {
IconArrowRight,
IconStop,
IconSwap,
IconTags,
} from '@arco-design/web-react/icon';
import useLocale from '@/utils/useLocale';
import locale from './locale';
export default function QuickOperation() {
const t = useLocale(locale);
return (
<Card>
<Typography.Title style={{ marginTop: 0, marginBottom: 16 }} heading={6}>
{t['monitor.title.quickOperation']}
</Typography.Title>
<Space direction="vertical" style={{ width: '100%' }} size={10}>
<Button long icon={<IconTags />}>
{t['monitor.quickOperation.changeClarity']}
</Button>
<Button long icon={<IconSwap />}>
{t['monitor.quickOperation.switchStream']}
</Button>
<Button long icon={<IconStop />}>
{t['monitor.quickOperation.removeClarity']}
</Button>
<Button long icon={<IconArrowRight />}>
{t['monitor.quickOperation.pushFlowGasket']}
</Button>
</Space>
</Card>
);
}

@ -1,41 +0,0 @@
import { Card, Typography, Form, Input, Button } from '@arco-design/web-react';
import React from 'react';
import useLocale from '@/utils/useLocale';
import locale from './locale';
export default function StudioInformation() {
const t = useLocale(locale);
return (
<Card>
<Typography.Title style={{ marginTop: 0, marginBottom: 16 }} heading={6}>
{t['monitor.title.studioInfo']}
</Typography.Title>
<Form layout="vertical">
<Form.Item label={t['monitor.studioInfo.label.studioTitle']} required>
<Input
placeholder={`admin${t['monitor.studioInfo.placeholder.studioTitle']}`}
/>
</Form.Item>
<Form.Item
label={t['monitor.studioInfo.label.onlineNotification']}
required
>
<Input.TextArea />
</Form.Item>
<Form.Item
label={t['monitor.studioInfo.label.studioCategory']}
required
>
<Input.Search />
</Form.Item>
<Form.Item
label={t['monitor.studioInfo.label.studioCategory']}
required
>
<Input.Search />
</Form.Item>
</Form>
<Button type="primary"></Button>
</Card>
);
}

@ -1,108 +0,0 @@
import React from 'react';
import {
Card,
Typography,
Tag,
Space,
Descriptions,
} from '@arco-design/web-react';
import useLocale from '@/utils/useLocale';
import locale from './locale';
export default function StudioStatus() {
const t = useLocale(locale);
const dataStatus = [
{
label: (
<span>
<Typography.Text style={{ paddingRight: 8 }}>
{t['monitor.studioStatus.mainstream']}
</Typography.Text>
{t['monitor.studioStatus.bitRate']}
</span>
),
value: '6 Mbps',
},
{
label: t['monitor.studioStatus.frameRate'],
value: '60',
},
{
label: (
<span>
<Typography.Text style={{ paddingRight: 8 }}>
{t['monitor.studioStatus.hotStandby']}
</Typography.Text>
{t['monitor.studioStatus.bitRate']}
</span>
),
value: '6 Mbps',
},
{
label: t['monitor.studioStatus.frameRate'],
value: '60',
},
{
label: (
<span>
<Typography.Text style={{ paddingRight: 8 }}>
{t['monitor.studioStatus.coldStandby']}
</Typography.Text>
{t['monitor.studioStatus.bitRate']}
</span>
),
value: '6 Mbps',
},
{
label: t['monitor.studioStatus.frameRate'],
value: '60',
},
];
const dataPicture = [
{
label: t['monitor.studioStatus.line'],
value: '热备',
},
{
label: 'CDN',
value: 'KS',
},
{
label: t['monitor.studioStatus.play'],
value: 'FLV',
},
{
label: t['monitor.studioStatus.pictureQuality'],
value: '原画',
},
];
return (
<Card>
<Space align="start">
<Typography.Title
style={{ marginTop: 0, marginBottom: 16 }}
heading={6}
>
{t['monitor.studioStatus.title.studioStatus']}
</Typography.Title>
<Tag color="green">{t['monitor.studioStatus.smooth']}</Tag>
</Space>
<Descriptions
colon=": "
layout="horizontal"
data={dataStatus}
column={2}
/>
<Typography.Title style={{ marginBottom: 16 }} heading={6}>
{t['monitor.studioStatus.title.pictureInfo']}
</Typography.Title>
<Descriptions
colon=": "
layout="horizontal"
data={dataPicture}
column={2}
/>
</Card>
);
}

@ -1,59 +0,0 @@
import { Card, Typography, Avatar, Space, Grid } from '@arco-design/web-react';
import { IconMore } from '@arco-design/web-react/icon';
import React from 'react';
import useLocale from '@/utils/useLocale';
import locale from './locale';
import styles from './style/index.module.less';
interface StudioProps {
userInfo: {
name?: string;
avatar?: string;
};
}
export default function Studio(props: StudioProps) {
const t = useLocale(locale);
const { userInfo } = props;
return (
<Card>
<Grid.Row>
<Grid.Col span={16}>
<Typography.Title
style={{ marginTop: 0, marginBottom: 16 }}
heading={6}
>
{t['monitor.title.studioPreview']}
</Typography.Title>
</Grid.Col>
<Grid.Col span={8} style={{ textAlign: 'right' }}>
<IconMore />
</Grid.Col>
</Grid.Row>
<div className={styles['studio-wrapper']}>
<img
src="http://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/c788fc704d32cf3b1136c7d45afc2669.png~tplv-uwbnlip3yd-webp.webp"
className={styles['studio-preview']}
/>
<div className={styles['studio-bar']}>
{userInfo && (
<div>
<Space size={12}>
<Avatar size={24}>
<img src={userInfo.avatar} />
</Avatar>
<Typography.Text>
{userInfo.name}
{t['monitor.studioPreview.studio']}
</Typography.Text>
</Space>
</div>
)}
<Typography.Text type="secondary">
3,6000 {t['monitor.studioPreview.watching']}
</Typography.Text>
</div>
</div>
</Card>
);
}

@ -1,94 +0,0 @@
.layout {
display: flex;
&-left-side {
flex-basis: 300px;
}
&-content {
flex: 1;
padding: 0 16px;
}
&-right-side {
flex-basis: 280px;
}
}
.chat-panel {
height: 100%;
background-color: var(--color-bg-2);
padding: 20px;
box-sizing: border-box;
display: flex;
flex-direction: column;
border-radius: 4px;
&-content {
flex: 1;
margin: 20px 0;
box-sizing: border-box;
}
}
.data-statistic {
&-content {
padding: 20px 0;
}
&-list {
&-header {
margin-top: 16px;
display: flex;
justify-content: space-between;
}
&-content {
margin-top: 16px;
}
&-cover {
&-wrapper {
height: 68px;
position: relative;
img {
height: 100%;
}
}
&-tag {
position: absolute;
top: 6px;
left: 6px;
}
}
&-tip {
display: block;
margin-top: 16px;
text-align: center;
}
}
}
.studio {
&-wrapper {
:global(.arco-card-body) {
padding-top: 0 !important;
}
}
&-preview {
width: 100%;
max-width: 600px;
display: block;
margin: 0 auto;
}
&-bar {
margin-top: 16px;
display: flex;
justify-content: space-between;
}
}

@ -1,111 +0,0 @@
import React, { useRef } from 'react';
import { Tinyflow, TinyflowHandle } from '@tinyflow-ai/react';
import '@tinyflow-ai/react/dist/index.css';
const App = () => {
const tinyflowRef = useRef<TinyflowHandle>(null);
const handleGetData = () => {
if (tinyflowRef.current) {
const data = tinyflowRef.current.getData();
console.log('Flow Data:', data);
}
};
const customNodes = {
'custom-node': {
title: '自定义节点',
description: '这是一个测试的自定义节点',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M20 20C20 20.5523 19.5523 21 19 21H5C4.44772 21 4 20.5523 4 20V11H1L11.3273 1.6115C11.7087 1.26475 12.2913 1.26475 12.6727 1.6115L23 11H20V20ZM18 19V9.15745L12 3.7029L6 9.15745V19H18ZM12 17L8.64124 13.6412C7.76256 12.7625 7.76256 11.3379 8.64124 10.4592C9.51992 9.58056 10.9445 9.58056 11.8232 10.4592L12 10.636L12.1768 10.4592C13.0555 9.58056 14.4801 9.58056 15.3588 10.4592C16.2374 11.3379 16.2374 12.7625 15.3588 13.6412L12 17Z"></path></svg>',
sortNo: 2,
render: (parent, node, flowInstance) => {
parent.innerHTML = `<select style="width: 100%">
<option>test</option>
<option>test1</option>
<option>test2</option>
</select>`;
parent.querySelector('select')
?.addEventListener('change', (e) => {
console.log('select change: ', e);
flowInstance.updateNodeData(node.id, {
test: e.target.value
});
})
;
console.log('render: ', node, flowInstance);
},
onUpdate: (parent, node) => {
console.log('onUpdate: ', node);
}
},
'test-node': {
title: '测试节点',
description: '这是一个测试的自定义节点',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M20 20C20 20.5523 19.5523 21 19 21H5C4.44772 21 4 20.5523 4 20V11H1L11.3273 1.6115C11.7087 1.26475 12.2913 1.26475 12.6727 1.6115L23 11H20V20ZM18 19V9.15745L12 3.7029L6 9.15745V19H18ZM12 17L8.64124 13.6412C7.76256 12.7625 7.76256 11.3379 8.64124 10.4592C9.51992 9.58056 10.9445 9.58056 11.8232 10.4592L12 10.636L12.1768 10.4592C13.0555 9.58056 14.4801 9.58056 15.3588 10.4592C16.2374 11.3379 16.2374 12.7625 15.3588 13.6412L12 17Z"></path></svg>',
sortNo: 310,
group: 'tools',
forms: [
{
type: 'heading',
label: '测试节点'
},
{
type: 'input',
name: 'test',
label: '测试',
placeholder: '请输入测试内容'
},
{
type: 'select',
name: 'test2',
label: '测试2',
placeholder: '请选择测试内容',
defaultValue: '1',
options: [
{
label: '选项1',
value: '1'
},
{
label: '选项2',
value: '2'
},
{
label: '选项3',
value: '3'
}
]
}
]
}
};
return (
<div>
<h1>Tinyflow React Example</h1>
<Tinyflow
ref={tinyflowRef}
data={{
nodes: [
{ id: '1', label: '开始', position: { x: 100, y: 100 } },
{ id: '2', label: '结束', position: { x: 300, y: 100 } },
{ id: '3', label: '结束1', position: { x: 300, y: 150 } }
],
edges: [
{ source: '1', target: '2' }
]
}}
style={{ border: '1px solid #ccc' }}
className="custom-class"
customNodes={customNodes}
/>
<button onClick={handleGetData}></button>
</div>
);
};
export default App;

@ -0,0 +1,13 @@
import React from 'react';
function Instance() {
return (
<>
<div>
</div>
</>
);
}
export default Instance;

@ -2,16 +2,16 @@ import React, { useState, ReactNode, useRef, useEffect } from 'react';
import { Layout, Menu, Breadcrumb, Spin } from '@arco-design/web-react'; import { Layout, Menu, Breadcrumb, Spin } from '@arco-design/web-react';
import cs from 'classnames'; import cs from 'classnames';
import { import {
IconDashboard,
IconList,
IconSettings,
IconFile,
IconApps, IconApps,
IconCheckCircle,
IconExclamationCircle,
IconUser,
IconMenuFold, IconMenuFold,
IconMenuUnfold IconMenuUnfold,
IconArchive,
IconUnorderedList,
IconMindMapping,
IconCommon,
IconCode,
IconHome,
IconStorage
} from '@arco-design/web-react/icon'; } from '@arco-design/web-react/icon';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
@ -34,22 +34,22 @@ const Content = Layout.Content;
function getIconFromKey(key) { function getIconFromKey(key) {
switch (key) { switch (key) {
case 'dashboard': case 'dashboard/workplace':
return <IconDashboard className={styles.icon} />; return <IconHome className={styles.icon} />;
case 'list': case 'scene':
return <IconList className={styles.icon} />; return <IconArchive className={styles.icon} />;
case 'form': case 'application':
return <IconSettings className={styles.icon} />;
case 'profile':
return <IconFile className={styles.icon} />;
case 'visualization':
return <IconApps className={styles.icon} />; return <IconApps className={styles.icon} />;
case 'result': case 'instance':
return <IconCheckCircle className={styles.icon} />; return <IconUnorderedList className={styles.icon} />;
case 'exception': case 'componentDevelopment':
return <IconExclamationCircle className={styles.icon} />; return <IconCode className={styles.icon} />;
case 'user': case 'componentLibrary':
return <IconUser className={styles.icon} />; return <IconMindMapping className={styles.icon} />;
case 'compositeCompLibrary':
return <IconCommon className={styles.icon} />;
case 'componentMarket':
return <IconStorage className={styles.icon} />;
default: default:
return <div className={styles['icon-empty']} />; return <div className={styles['icon-empty']} />;
} }

@ -0,0 +1,13 @@
import React from 'react';
function Scene() {
return (
<>
<div>
</div>
</>
);
}
export default Scene;

@ -1,118 +0,0 @@
import React, { useEffect, useMemo, useState } from 'react';
import { Card, Grid, Table, Space, Typography } from '@arco-design/web-react';
import useLocale from '@/utils/useLocale';
import axios from 'axios';
import locale from './locale';
import PublicOpinion from './public-opinion';
import MultiInterval from '@/components/Chart/multi-stack-interval';
import PeriodLine from '@/components/Chart/period-legend-line';
import './mock';
const { Row, Col } = Grid;
function DataAnalysis() {
const t = useLocale(locale);
const [loading, setLoading] = useState(false);
const [tableLoading, setTableLoading] = useState(false);
const [chartData, setChartData] = useState([]);
const [tableData, setTableData] = useState([]);
const getChartData = async () => {
setLoading(true);
const { data } = await axios
.get('/api/data-analysis/content-publishing')
.finally(() => setLoading(false));
setChartData(data);
};
const getTableData = async () => {
setTableLoading(true);
const { data } = await axios
.get('/api/data-analysis/author-list')
.finally(() => setTableLoading(false));
setTableData(data.list);
};
useEffect(() => {
getChartData();
getTableData();
}, []);
const columns = useMemo(() => {
return [
{
title: t['dataAnalysis.authorTable.rank'],
dataIndex: 'id',
},
{
title: t['dataAnalysis.authorTable.author'],
dataIndex: 'author',
},
{
title: t['dataAnalysis.authorTable.content'],
dataIndex: 'contentCount',
sorter: (a, b) => a.contentCount - b.contentCount,
render(x) {
return Number(x).toLocaleString();
},
},
{
title: t['dataAnalysis.authorTable.click'],
dataIndex: 'clickCount',
sorter: (a, b) => a.clickCount - b.clickCount,
render(x) {
return Number(x).toLocaleString();
},
},
];
}, [t]);
return (
<Space size={16} direction="vertical" style={{ width: '100%' }}>
<Card>
<Typography.Title heading={6}>
{t['dataAnalysis.title.publicOpinion']}
</Typography.Title>
<PublicOpinion />
</Card>
<Row gutter={16}>
<Col span={14}>
<Card>
<Typography.Title heading={6}>
{t['dataAnalysis.title.publishingRate']}
</Typography.Title>
<MultiInterval data={chartData} loading={loading} />
</Card>
</Col>
<Col span={10}>
<Card>
<Typography.Title heading={6}>
{t['dataAnalysis.title.authorsList']}
</Typography.Title>
<div style={{ height: '370px' }}>
<Table
rowKey="id"
loading={tableLoading}
pagination={false}
data={tableData}
columns={columns}
/>
</div>
</Card>
</Col>
</Row>
<Row>
<Col span={24}>
<Card>
<Typography.Title heading={6}>
{t['dataAnalysis.title.publishingTiming']}
</Typography.Title>
<PeriodLine data={chartData} loading={loading} />
</Card>
</Col>
</Row>
</Space>
);
}
export default DataAnalysis;

@ -1,38 +0,0 @@
const i18n = {
'en-US': {
'menu.visualization': 'Data Visualization',
'menu.visualization.analysis': 'Analysis',
'dataAnalysis.yesterday': 'Yesterday',
'dataAnalysis.title.publicOpinion': 'Public Opinion Analysis',
'dataAnalysis.publicOpinion.visitor': 'Total visitors',
'dataAnalysis.publicOpinion.content': 'Total content publishing',
'dataAnalysis.publicOpinion.comment': 'Total comments',
'dataAnalysis.publicOpinion.share': 'Total share',
'dataAnalysis.title.publishingRate': 'Content publishing rate',
'dataAnalysis.title.publishingTiming': 'Content period analysis',
'dataAnalysis.title.authorsList': 'Top authors list',
'dataAnalysis.authorTable.rank': 'Rank ',
'dataAnalysis.authorTable.author': 'Author',
'dataAnalysis.authorTable.content': 'Interval volume',
'dataAnalysis.authorTable.click': 'Click volume',
},
'zh-CN': {
'menu.visualization': '数据可视化',
'menu.visualization.analysis': '分析页',
'dataAnalysis.yesterday': '较昨日',
'dataAnalysis.title.publicOpinion': '舆情分析',
'dataAnalysis.publicOpinion.visitor': '访问总人数',
'dataAnalysis.publicOpinion.content': '内容发布量',
'dataAnalysis.publicOpinion.comment': '评论总量',
'dataAnalysis.publicOpinion.share': '分享总量',
'dataAnalysis.title.publishingRate': '内容发布比例',
'dataAnalysis.title.publishingTiming': '内容时段分析',
'dataAnalysis.title.authorsList': '热门作者榜单',
'dataAnalysis.authorTable.rank': '排名',
'dataAnalysis.authorTable.author': '作者',
'dataAnalysis.authorTable.content': '内容量',
'dataAnalysis.authorTable.click': '点击量',
},
};
export default i18n;

@ -1,91 +0,0 @@
import Mock from 'mockjs';
import qs from 'query-string';
import setupMock from '@/utils/setupMock';
const mockLine = (name) => {
const result = new Array(12).fill(0).map(() => ({
y: Mock.Random.natural(20, 100),
}));
return result.map((item, index) => ({
...item,
x: index,
name,
}));
};
const mockPie = () => {
return new Array(3).fill(0).map((_, index) => ({
name: ['纯文本', '图文类', '视频类'][index],
count: Mock.Random.natural(20, 100),
}));
};
setupMock({
setup: () => {
Mock.mock(new RegExp('/api/data-analysis/overview'), (params) => {
const { type } = qs.parseUrl(params.url).query;
return Mock.mock({
count: () => Mock.Random.natural(1000, 10000),
increment: () => Mock.Random.boolean(),
diff: () => Mock.Random.natural(100, 1000),
chartType: type,
chartData: () => {
if (type === 'pie') {
return mockPie();
} else if (type === 'line') {
return [...mockLine('类目1'), ...mockLine('类目2')];
}
return mockLine('类目1');
},
});
});
const getTimeLine = (name) => {
const timeArr = new Array(12).fill(0).map((_, index) => {
const time = index * 2;
return time < 9 ? `0${time}:00` : `${time}:00`;
});
return new Array(12).fill(0).map((_, index) => ({
name,
time: timeArr[index],
count: Mock.Random.natural(1000, 5000),
rate: Mock.Random.natural(0, 100),
}));
};
Mock.mock(new RegExp('/api/data-analysis/content-publishing'), () => {
return [
...getTimeLine('纯文本'),
...getTimeLine('视频类'),
...getTimeLine('图文类'),
];
});
Mock.mock(new RegExp('/api/data-analysis/author-list'), () => {
return Mock.mock({
'list|8': [
{
'id|+1': 1,
author: () =>
Mock.Random.pick([
'用魔法打败魔法',
'王多鱼',
'Christopher',
'叫我小李好了',
'陈皮话梅糖',
'碳烤小肥羊',
]),
time: function () {
return new Array(12).fill(0).map((_, index) => {
const time = index * 2;
return time < 9 ? `0${time}:00` : `${time}:00`;
})[this.id % 12];
},
contentCount: () => Mock.Random.natural(1000, 5000),
clickCount: () => Mock.Random.natural(5000, 30000),
},
],
});
});
},
});

@ -1,187 +0,0 @@
import React from 'react';
import { Skeleton, Statistic, Typography } from '@arco-design/web-react';
import cs from 'classnames';
import {
Chart,
Line,
Interval,
Coordinate,
Interaction,
Tooltip,
G2,
Legend,
} from 'bizcharts';
import { IconArrowRise, IconArrowFall } from '@arco-design/web-react/icon';
import styles from '../style/public-opinion.module.less';
const { Title, Text } = Typography;
const basicChartProps = {
pure: true,
autoFit: true,
height: 80,
padding: [10, 10, 0, 10],
};
export interface PublicOpinionCardProps {
key: string;
title: string;
chartData?: any[];
chartType: 'line' | 'interval' | 'pie';
count?: number;
increment?: boolean;
diff?: number;
compareTime?: string;
loading?: boolean;
}
function SimpleLine(props: { chartData: any[] }) {
const { chartData } = props;
return (
<Chart data={chartData} {...basicChartProps}>
<Line
position="x*y"
size={3}
shape={'smooth'}
color={['name', ['#165DFF', 'rgba(106,161,255,0.3)']]}
style={{
fields: ['name'],
callback: (name) => {
if (name === '类目2') {
return { lineDash: [8, 10] };
}
return {};
},
}}
/>
</Chart>
);
}
function SimpleInterval(props: { chartData: any[] }) {
const { chartData } = props;
G2.registerShape('interval', 'border-radius', {
draw(cfg, container) {
const points = cfg.points as unknown as { x: string; y: number };
let path = [];
path.push(['M', points[0].x, points[0].y]);
path.push(['L', points[1].x, points[1].y]);
path.push(['L', points[2].x, points[2].y]);
path.push(['L', points[3].x, points[3].y]);
path.push('Z');
path = this.parsePath(path); // 将 0 - 1 转化为画布坐标
const group = container.addGroup();
group.addShape('rect', {
attrs: {
x: path[1][1], // 矩形起始点为左上角
y: path[1][2],
width: path[2][1] - path[1][1],
height: path[0][2] - path[1][2],
fill: cfg.color,
radius: (path[2][1] - path[1][1]) / 2,
},
});
return group;
},
});
return (
<Chart data={chartData} {...basicChartProps}>
<Interval
position="x*y"
color={[
'x',
(xVal) => {
if (Number(xVal) % 2 === 0) {
return '#2CAB40';
}
return '#86DF6C';
},
]}
shape="border-radius"
/>
</Chart>
);
}
function SimplePie(props: { chartData: any[] }) {
const { chartData } = props;
return (
<Chart data={chartData} {...basicChartProps} padding={[0, 20, 0, 0]}>
<Coordinate type="theta" radius={0.8} innerRadius={0.7} />
<Interval
adjust="stack"
position="count"
shape="sliceShape"
color={['name', ['#8D4EDA', '#00B2FF', '#165DFF']]}
label={false}
/>
<Tooltip visible={true} />
<Legend position="right" />
<Interaction type="element-single-selected" />
</Chart>
);
}
function PublicOpinionCard(props: PublicOpinionCardProps) {
const { chartType, title, count, increment, diff, chartData, loading } =
props;
const className = cs(styles.card, styles[`card-${chartType}`]);
return (
<div className={className}>
<div className={styles.statistic}>
<Statistic
title={
<Title heading={6} className={styles.title}>
{title}
</Title>
}
loading={loading}
value={count}
groupSeparator
/>
<div className={styles['compare-yesterday']}>
<Text type="secondary" className={styles['compare-yesterday-text']}>
{props.compareTime}
</Text>
<span
className={cs(styles['diff'], {
[styles['diff-increment']]: increment,
})}
>
{loading ? (
<Skeleton text={{ rows: 1 }} animation />
) : (
<>
{diff}
{increment ? <IconArrowRise /> : <IconArrowFall />}
</>
)}
</span>
</div>
</div>
<div className={styles.chart}>
{loading ? (
<Skeleton
text={{ rows: 3, width: Array(3).fill('100%') }}
animation
/>
) : (
<>
{chartType === 'interval' && (
<SimpleInterval chartData={chartData} />
)}
{chartType === 'line' && <SimpleLine chartData={chartData} />}
{chartType === 'pie' && <SimplePie chartData={chartData} />}
</>
)}
</div>
</div>
);
}
export default PublicOpinionCard;

@ -1,85 +0,0 @@
import React, { useState, useEffect, useMemo } from 'react';
import PublicOpinionCard, { PublicOpinionCardProps } from './card';
import axios from 'axios';
import { Grid } from '@arco-design/web-react';
import useLocale from '@/utils/useLocale';
import locale from '../locale';
const { Row, Col } = Grid;
const cardInfo = [
{
key: 'visitor',
type: 'line',
},
{
key: 'content',
type: 'interval',
},
{
key: 'comment',
type: 'line',
},
{
key: 'share',
type: 'pie',
},
];
function PublicOpinion() {
const t = useLocale(locale);
const [loading, setLoading] = useState(true);
const [data, setData] = useState<PublicOpinionCardProps[]>(
cardInfo.map((item) => ({
...item,
chartType: item.type as 'line' | 'pie' | 'interval',
title: t[`dataAnalysis.publicOpinion.${item.key}`],
}))
);
const getData = async () => {
const requestList = cardInfo.map(async (info) => {
const { data } = await axios
.get(`/api/data-analysis/overview?type=${info.type}`)
.catch(() => ({ data: {} }));
return {
...data,
key: info.key,
chartType: info.type,
};
});
const result = await Promise.all(requestList).finally(() =>
setLoading(false)
);
setData(result);
};
useEffect(() => {
getData();
}, []);
const formatData = useMemo(() => {
return data.map((item) => ({
...item,
title: t[`dataAnalysis.publicOpinion.${item.key}`],
}));
}, [t, data]);
return (
<div>
<Row gutter={20}>
{formatData.map((item, index) => (
<Col span={6} key={index}>
<PublicOpinionCard
{...item}
compareTime={t['dataAnalysis.yesterday']}
loading={loading}
/>
</Col>
))}
</Row>
</div>
);
}
export default PublicOpinion;

@ -1,96 +0,0 @@
@line-card-bg: linear-gradient(180deg, rgb(242 249 254) 0%, #e6f4fe 100%);
@interval-card-bg: linear-gradient(
180deg,
rgb(245 254 242) 0%,
rgb(230 254 238) 100%
);
@pie-card-bg: linear-gradient(
180deg,
rgb(247 247 255) 0%,
rgb(236 236 255) 100%
);
@line-card-dark-bg: linear-gradient(180deg, #284991 0%, #122b62 100%);
@interval-card-dark-bg: linear-gradient(180deg, #3d492e 0%, #263827 100%);
@pie-card-dark-bg: linear-gradient(180deg, #312565 0%, #201936 100%);
.card {
display: flex;
padding: 20px;
padding-top: 16px;
border-radius: 4px;
min-height: 100px;
&-line {
background: @line-card-bg;
}
&-interval {
background: @interval-card-bg;
}
&-pie {
background: @pie-card-bg;
}
.statistic {
white-space: nowrap;
}
.chart {
flex: auto;
display: flex;
flex-direction: column-reverse;
margin-left: 16px;
}
.title {
margin: 0;
}
:global(.arco-statistic-content) {
margin-top: 24px;
margin-bottom: 4px;
:global(.arco-statistic-value) {
font-size: 24px;
line-height: 28px;
}
}
.compare-yesterday {
&-text {
font-size: 12px;
font-weight: 400;
color: var(--color-text-2);
}
}
.diff {
margin-left: 8px;
line-height: 20px;
color: rgb(var(--red-6));
}
.diff-increment {
color: rgb(var(--green-6));
}
}
body[arco-theme='dark'] {
.card {
&-line {
background: @line-card-dark-bg;
}
&-pie {
background: @pie-card-dark-bg;
}
&-interval {
background: @interval-card-dark-bg;
}
}
}

@ -1,208 +0,0 @@
import React, { useEffect, useState, useMemo } from 'react';
import {
Statistic,
Typography,
Spin,
Grid,
Card,
Skeleton,
} from '@arco-design/web-react';
import cs from 'classnames';
import { Chart, Line, Interval, Tooltip, Interaction } from 'bizcharts';
import axios from 'axios';
import useLocale from '@/utils/useLocale';
import locale from './locale';
import { IconArrowRise, IconArrowFall } from '@arco-design/web-react/icon';
import styles from './style/card-block.module.less';
const { Row, Col } = Grid;
const { Title, Text } = Typography;
const basicChartProps = {
pure: true,
autoFit: true,
height: 80,
padding: [0, 10, 0, 10],
};
export interface CardProps {
key: string;
title?: string;
chartData?: any[];
chartType: string;
count?: number;
increment?: boolean;
diff?: number;
loading?: boolean;
}
function CustomTooltip(props: { items: any[] }) {
const { items } = props;
return (
<div className={styles.tooltip}>
{items.map((item, index) => (
<div key={index}>
<Text bold>{Number(item.data.y).toLocaleString()}</Text>
</div>
))}
</div>
);
}
function SimpleLine(props: { chartData: any[] }) {
const { chartData } = props;
return (
<Chart data={chartData} {...basicChartProps}>
<Line
position="x*y"
shape={['name', ['smooth', 'dash']]}
color={['name', ['#165DFF', 'rgba(106,161,255,0.3)']]}
/>
<Tooltip shared={false} showCrosshairs={true}>
{(_, items) => <CustomTooltip items={items} />}
</Tooltip>
</Chart>
);
}
function SimpleInterval(props: { chartData: any[] }) {
const { chartData } = props;
return (
<Chart data={chartData} {...basicChartProps}>
<Interval
position="x*y"
color={[
'x',
(xVal) => {
if (Number(xVal) % 2 === 0) {
return '#86DF6C';
}
return '#468DFF';
},
]}
/>
<Tooltip shared={false}>
{(_, items) => <CustomTooltip items={items} />}
</Tooltip>
<Interaction type="active-region" />
</Chart>
);
}
function CardBlock(props: CardProps) {
const { chartType, title, count, increment, diff, chartData, loading } =
props;
return (
<Card className={styles.card}>
<div className={styles.statistic}>
<Statistic
title={
<Title heading={6} className={styles.title}>
{title}
</Title>
}
loading={loading}
value={count}
extra={
<div className={styles['compare-yesterday']}>
{loading ? (
<Skeleton
text={{ rows: 1 }}
style={{ width: '100px' }}
animation
/>
) : (
<span
className={cs(styles['diff'], {
[styles['diff-increment']]: increment,
})}
>
{diff}
{increment ? <IconArrowRise /> : <IconArrowFall />}
</span>
)}
</div>
}
groupSeparator
/>
</div>
<div className={styles.chart}>
<Spin style={{ width: '100%' }} loading={loading}>
{chartType === 'interval' && <SimpleInterval chartData={chartData} />}
{chartType === 'line' && <SimpleLine chartData={chartData} />}
</Spin>
</div>
</Card>
);
}
const cardInfo = [
{
key: 'userRetentionTrend',
type: 'line',
},
{
key: 'userRetention',
type: 'interval',
},
{
key: 'contentConsumptionTrend',
type: 'line',
},
{
key: 'contentConsumption',
type: 'interval',
},
];
function CardList() {
const t = useLocale(locale);
const [loading, setLoading] = useState(false);
const [data, setData] = useState(
cardInfo.map((item) => ({
...item,
chartType: item.type,
}))
);
const getData = async () => {
const requestList = cardInfo.map(async (info) => {
const { data } = await axios
.get(`/api/multi-dimension/card?type=${info.type}`)
.catch(() => ({ data: {} }));
return {
...data,
key: info.key,
chartType: info.type,
};
});
setLoading(true);
const result = await Promise.all(requestList).finally(() =>
setLoading(false)
);
setData(result);
};
useEffect(() => {
getData();
}, []);
const formatData = useMemo(() => {
return data.map((item) => ({
...item,
title: t[`multiDAnalysis.cardList.${item.key}`],
}));
}, [t, data]);
return (
<Row gutter={16}>
{formatData.map((item, index) => (
<Col span={6} key={index}>
<CardBlock {...item} loading={loading} />
</Col>
))}
</Row>
);
}
export default CardList;

@ -1,108 +0,0 @@
// 数据总览
import React, { useEffect, useState, useMemo } from 'react';
import {
Card,
Typography,
Grid,
Statistic,
Skeleton,
} from '@arco-design/web-react';
import axios from 'axios';
import {
IconUser,
IconEdit,
IconHeart,
IconThumbUp,
} from '@arco-design/web-react/icon';
import useLocale from '@/utils/useLocale';
import locale from './locale';
import styles from './style/data-overview.module.less';
import MultiAreaLine from '@/components/Chart/multi-area-line';
const { Title } = Typography;
export default () => {
const t = useLocale(locale);
const [overview, setOverview] = useState([]);
const [lineData, setLineData] = useState([]);
const [loading, setLoading] = useState(false);
const getData = async () => {
setLoading(true);
const { data } = await axios
.get('/api/multi-dimension/overview')
.finally(() => setLoading(false));
const { overviewData, chartData } = data;
setLineData(chartData);
setOverview(overviewData);
};
useEffect(() => {
getData();
}, []);
const formatedData = useMemo(() => {
return [
{
title: t['multiDAnalysis.dataOverview.contentProduction'],
icon: <IconEdit />,
value: overview[0],
background: 'rgb(var(--orange-2))',
color: 'rgb(var(--orange-6))',
},
{
title: t['multiDAnalysis.dataOverview.contentClicks'],
icon: <IconThumbUp />,
value: overview[1],
background: 'rgb(var(--cyan-2))',
color: 'rgb(var(--cyan-6))',
},
{
title: t['multiDAnalysis.dataOverview.contextExposure'],
value: overview[2],
icon: <IconHeart />,
background: 'rgb(var(--arcoblue-1))',
color: 'rgb(var(--arcoblue-6))',
},
{
title: t['multiDAnalysis.dataOverview.activeUsers'],
value: overview[3],
icon: <IconUser />,
background: 'rgb(var(--purple-1))',
color: 'rgb(var(--purple-6))',
},
];
}, [t, overview]);
return (
<Grid.Row justify="space-between">
{formatedData.map((item, index) => (
<Grid.Col span={24 / formatedData.length} key={`${index}`}>
<Card className={styles.card} title={null}>
<Title heading={6}>{item.title}</Title>
<div className={styles.content}>
<div
style={{ backgroundColor: item.background, color: item.color }}
className={styles['content-icon']}
>
{item.icon}
</div>
{loading ? (
<Skeleton
animation
text={{ rows: 1, className: styles['skeleton'] }}
style={{ width: '120px' }}
/>
) : (
<Statistic value={item.value} groupSeparator />
)}
</div>
</Card>
</Grid.Col>
))}
<Grid.Col span={24}>
<MultiAreaLine data={lineData} loading={loading} />
</Grid.Col>
</Grid.Row>
);
};

@ -1,119 +0,0 @@
import React, { useState, useEffect } from 'react';
import { Typography, Card, Grid, Space } from '@arco-design/web-react';
import axios from 'axios';
import useLocale from '@/utils/useLocale';
import HorizontalInterval from '@/components/Chart/horizontal-interval';
import AreaPolar from '@/components/Chart/area-polar';
import FactMultiPie from '@/components/Chart/fact-multi-pie';
import locale from './locale';
import DataOverview from './data-overview';
import CardList from './card-list';
import './mock';
const { Row, Col } = Grid;
const { Title } = Typography;
function DataAnalysis() {
const t = useLocale(locale);
const [loading, setLoading] = useState(false);
const [interval, setInterval] = useState([]);
const [polarLoading, setPolarLoading] = useState(false);
const [polar, setPolar] = useState({ list: [], fields: [] });
const [multiPieLoading, setMultiPieLoading] = useState(false);
const [multiPie, setMultiPie] = useState([]);
const getInterval = async () => {
setLoading(true);
const { data } = await axios
.get('/api/multi-dimension/activity')
.finally(() => {
setLoading(false);
});
setInterval(data);
};
const getPolar = async () => {
setPolarLoading(true);
const { data } = await axios
.get('/api/multi-dimension/polar')
.finally(() => setPolarLoading(false));
setPolar(data);
};
const getMultiPie = async () => {
setMultiPieLoading(true);
const { data } = await axios
.get('/api/multi-dimension/content-source')
.finally(() => {
setMultiPieLoading(false);
});
setMultiPie(data);
};
useEffect(() => {
getInterval();
getPolar();
getMultiPie();
}, []);
return (
<Space size={16} direction="vertical" style={{ width: '100%' }}>
<Row gutter={20}>
<Col span={16}>
<Card>
<Title heading={6}>
{t['multiDAnalysis.card.title.dataOverview']}
</Title>
<DataOverview />
</Card>
</Col>
<Col span={8}>
<Card>
<Title heading={6}>
{t['multiDAnalysis.card.title.todayActivity']}
</Title>
<HorizontalInterval
data={interval}
loading={loading}
height={160}
/>
</Card>
<Card>
<Title heading={6}>
{t['multiDAnalysis.card.title.contentTheme']}
</Title>
<AreaPolar
data={polar.list}
fields={polar.fields}
height={197}
loading={polarLoading}
/>
</Card>
</Col>
</Row>
<Row>
<Col span={24}>
<CardList />
</Col>
</Row>
<Row>
<Col span={24}>
<Card>
<Title heading={6}>
{t['multiDAnalysis.card.title.contentSource']}
</Title>
<FactMultiPie
loading={multiPieLoading}
data={multiPie}
height={240}
/>
</Card>
</Col>
</Row>
</Space>
);
}
export default DataAnalysis;

@ -1,44 +0,0 @@
const i18n = {
'en-US': {
'menu.visualization': 'Data Visualization',
'menu.visualization.multiDimensionDataAnalysis': 'Multi-D Analysis',
'multiDAnalysis.card.title.activeContributors': 'Active Contributors',
'multiDAnalysis.unit': 'times',
'multiDAnalysis.card.title.officeVisitors': 'Office Visitors',
'multiDAnalysis.card.title.downloads': 'Downloads',
'multiDAnalysis.card.title.dataOverview': 'Overview',
'multiDAnalysis.card.title.todayActivity':
'Today\'s Likes and Comments Statistics',
'multiDAnalysis.card.title.contentTheme': 'Content theme distribution',
'multiDAnalysis.card.title.contentSource': 'Content publishing source',
'multiDAnalysis.dataOverview.contentProduction': 'Content production',
'multiDAnalysis.dataOverview.contentClicks': 'Content clicks',
'multiDAnalysis.dataOverview.contextExposure': 'Content exposure',
'multiDAnalysis.dataOverview.activeUsers': 'Active users',
'multiDAnalysis.cardList.userRetentionTrend': 'User retention trends',
'multiDAnalysis.cardList.userRetention': 'User retention',
'multiDAnalysis.cardList.contentConsumptionTrend':
'Content consumption trends',
'multiDAnalysis.cardList.contentConsumption': 'Content consumption',
},
'zh-CN': {
'menu.visualization': '数据可视化',
'menu.visualization.multiDimensionDataAnalysis': '多维数据分析',
'multiDAnalysis.card.title.officeVisitors': '官网访问量',
'multiDAnalysis.card.title.downloads': '下载量',
'multiDAnalysis.card.title.dataOverview': '数据总览',
'multiDAnalysis.card.title.todayActivity': '今日转赞评统计',
'multiDAnalysis.card.title.contentTheme': '内容题材分布',
'multiDAnalysis.card.title.contentSource': '内容发布来源',
'multiDAnalysis.dataOverview.contentProduction': '内容生产量',
'multiDAnalysis.dataOverview.contentClicks': '内容点击量',
'multiDAnalysis.dataOverview.contextExposure': '内容曝光量',
'multiDAnalysis.dataOverview.activeUsers': '活跃用户数',
'multiDAnalysis.cardList.userRetentionTrend': '用户留存趋势',
'multiDAnalysis.cardList.userRetention': '用户留存量',
'multiDAnalysis.cardList.contentConsumptionTrend': '内容消费趋势',
'multiDAnalysis.cardList.contentConsumption': '内容消费量',
},
};
export default i18n;

@ -1,134 +0,0 @@
import Mock from 'mockjs';
import dayjs from 'dayjs';
import qs from 'query-string';
import setupMock from '@/utils/setupMock';
const legend = ['活跃用户数', '内容生产量', '内容点击量', '内容曝光量'];
const count = [0, 600, 1000, 2000, 4000];
const category = ['纯文本', '图文类', '视频类'];
const getLineData = (name, index) => {
const { list } = Mock.mock({
'list|10': [
{
'id|+1': 1,
time: function () {
return dayjs().subtract(this.id, 'days').format('MM-DD');
},
count: () => Mock.Random.natural(count[index], count[index + 1]),
name: name,
},
],
});
return list.map((item) => {
delete item.id;
return item;
});
};
const mockLine = (name) => {
const result = new Array(12).fill(0).map(() => ({
y: Mock.Random.natural(1000, 10000),
}));
return result
.sort((a, b) => a.y - b.y)
.map((item, index) => ({
...item,
x: index,
name,
}));
};
const getContentSource = (name) => {
const typeList = ['UGC原创', '国外网站', '转载文章', '行业报告', '其他'];
const result = [];
typeList.forEach((type) => {
result.push({
type,
value: Mock.Random.natural(100, 10000),
name,
});
});
const total = result.reduce((a, b) => a + b.value, 0);
return result.map((item) => ({
...item,
value: Number((item.value / total).toFixed(2)),
}));
};
setupMock({
setup: () => {
Mock.mock(new RegExp('/api/multi-dimension/overview'), () => {
const { array: overviewData } = Mock.mock({
'array|4': [
function () {
return Mock.Random.natural(0, 10000);
},
],
});
let list = [];
legend.forEach(
(name, index) => (list = list.concat(getLineData(name, index)))
);
return {
overviewData,
chartData: list,
};
});
Mock.mock(new RegExp('/api/multi-dimension/activity'), () => {
const { list } = Mock.mock({
'list|3': [
{
'name|+1': ['分享量', '评论量', '点赞量'],
count: () => Mock.Random.natural(1000, 10000),
},
],
});
return list;
});
Mock.mock(new RegExp('/api/multi-dimension/polar'), () => {
const items = ['国际', '娱乐', '体育', '财经', '科技', '其他'];
const getCategoryCount = () => {
const result = {};
category.forEach((name) => {
result[name] = Mock.Random.natural(0, 100);
});
return result;
};
return {
list: items.map((item) => ({
item,
...getCategoryCount(),
})),
fields: category,
};
});
Mock.mock(new RegExp('/api/multi-dimension/card'), (params) => {
const { type } = qs.parseUrl(params.url).query;
return Mock.mock({
count: () => Mock.Random.natural(1000, 10000),
increment: () => Mock.Random.boolean(),
diff: () => Mock.Random.natural(100, 1000),
chartType: type,
chartData: () => {
return mockLine('类目1');
},
});
});
Mock.mock(new RegExp('/api/multi-dimension/content-source'), () => {
const allList = category.map((name) => {
return getContentSource(name).map((item) => ({
...item,
category: name,
}));
});
return allList.flat();
});
},
});

@ -1,43 +0,0 @@
.card {
.statistic {
display: flex;
}
.title {
margin: 0;
}
:global(.arco-statistic-content) {
margin-top: 12px;
margin-bottom: 4px;
display: flex;
:global(.arco-statistic-value) {
font-size: 24px;
line-height: 28px;
}
}
.diff {
margin-left: 12px;
line-height: 20px;
color: rgb(var(--red-6));
}
.diff-increment {
color: rgb(var(--green-6));
}
.tooltip {
color: var(--color-text-1);
padding: 10px 0px;
background: var(--color-bg-5);
}
:global(.bizcharts-tooltip) {
background: var(--color-bg-5) !important;
color: var(--color-text-1) !important;
box-shadow: 2px 2px 5px rgba(19, 78, 196, 0.1) !important;
opacity: 1 !important;
}
}

@ -1,39 +0,0 @@
.card {
:global(.arco-spin) {
width: 100%;
}
:global(.arco-card-body) {
padding-top: 6px;
}
h6 {
font-size: 12px;
margin-bottom: 8px;
}
.content {
display: flex;
line-height: 32px;
&-icon {
width: 32px;
height: 32px;
line-height: 32px;
border-radius: 6px;
margin-right: 8px;
text-align: center;
font-size: 18px;
}
:global(.arco-statistic) {
line-height: normal;
}
}
}
.skeleton {
:global(.arco-skeleton-text-row) {
height: 32px;
}
}

@ -1,60 +0,0 @@
import * as turf from '@turf/turf';
export function keepMapRatio(mapData, c) {
if (mapData && turf) {
// 获取数据外接矩形,计算宽高比
const bbox = turf.bbox(mapData);
const width = bbox[2] - bbox[0];
const height = bbox[3] - bbox[1];
const ratio = height / width;
const cWidth = c.width;
const cHeight = c.height;
const cRatio = cHeight / cWidth;
let scale: {
x: {
range: number[];
};
y: {
range: number[];
};
};
if (cRatio >= ratio) {
const halfDisRatio = (cRatio - ratio) / 2 / cRatio;
scale = {
x: {
range: [0, 1],
},
y: {
range: [halfDisRatio, 1 - halfDisRatio],
},
};
} else {
const halfDisRatio = ((1 / cRatio - 1 / ratio) / 2) * cRatio;
scale = {
y: {
range: [0, 1],
},
x: {
range: [halfDisRatio, 1 - halfDisRatio],
},
};
}
const curScaleXRange = c.getScaleByField('x').range;
const curScaleYRange = c.getScaleByField('y').range;
if (
curScaleXRange[0] !== scale.x.range[0] ||
curScaleXRange[1] !== scale.x.range[1] ||
curScaleYRange[0] !== scale.y.range[0] ||
curScaleYRange[1] !== scale.y.range[1]
) {
setTimeout(() => {
c.scale(scale);
c.render(true);
}, 1);
}
}
}

@ -1,29 +0,0 @@
import React from 'react';
import { Button, Tooltip, Message } from '@arco-design/web-react';
import { IconCopy } from '@arco-design/web-react/icon';
import clipboard from '@/utils/clipboard';
import styles from './style/code-block.module.less';
interface CodeBlockProps {
code: string;
}
export default function CodeBlock(props: CodeBlockProps) {
const { code } = props;
return (
<pre className={styles['code-block']}>
<code className={styles['code-block-content']}>{code}</code>
<Tooltip content="点击复制命令">
<Button
type="text"
className={styles['code-block-copy-btn']}
icon={<IconCopy />}
onClick={() => {
clipboard(code);
Message.success('复制成功');
}}
/>
</Tooltip>
</pre>
);
}

@ -1,67 +0,0 @@
import React from 'react';
import { Alert, Card, Link, Typography, Tag } from '@arco-design/web-react';
import { IconDoubleRight } from '@arco-design/web-react/icon';
import { useSelector } from 'react-redux';
import useLocale from '@/utils/useLocale';
import locale from './locale';
import CodeBlock from './code-block';
import styles from './style/index.module.less';
export default function Welcome() {
const t = useLocale(locale);
const userInfo = useSelector((state: any) => state.userInfo) || {};
return (
<div className={styles.container}>
<div className={styles.header}>
<Typography.Title heading={5} style={{ marginTop: 0 }}>
{t['welcome.title.welcome']}
</Typography.Title>
<Typography.Text type="secondary">
{userInfo.name}, {userInfo.email}
</Typography.Text>
</div>
<div>
<Alert type="success" content={t['welcome.invite']} />
<Card style={{ marginTop: 20 }} title={t['welcome.usage']}>
<Typography.Title heading={6} style={{ marginTop: 0 }}>
1. {t['welcome.step.title.pickup']}
</Typography.Title>
<Typography.Text>
{t['welcome.step.content.pickup']}
<Tag style={{ marginLeft: 8 }}>
@arco-design/pro-pages-workplace
</Tag>
</Typography.Text>
<Typography.Title heading={6}>
2. {t['welcome.step.title.install']}
</Typography.Title>
<Typography.Text>{t['welcome.step.content.install']}</Typography.Text>
<CodeBlock code="arco block use @arco-design/pro-pages-workplace" />
<Typography.Title heading={6} style={{ marginTop: 0 }}>
3. {t['welcome.step.title.result']}
</Typography.Title>
<Typography.Text>{t['welcome.step.content.result']}</Typography.Text>
</Card>
<Card style={{ marginTop: 20 }}>
<Typography.Text>{t['welcome.title.material']}</Typography.Text>
<div style={{ marginTop: 8 }}>
<Link
target="_blank"
href="https://arco.design/material?category=arco-design-pro"
suppressHydrationWarning
>
{t['welcome.link.material-pro']} <IconDoubleRight />
</Link>
</div>
<div style={{ marginTop: 8 }}>
<Link target="_blank" href="https://arco.design/material" suppressHydrationWarning>
{t['welcome.link.material-all']} <IconDoubleRight />
</Link>
</div>
</Card>
</div>
</div>
);
}

@ -1,38 +0,0 @@
const i18n = {
'en-US': {
'welcome.title.welcome': 'Welcome',
'welcome.invite':
'Arco Cli commands can be used to install materials from the material market, and we sincerely invite you to experience it.',
'welcome.usage': 'Usage',
'welcome.step.title.pickup': 'Select materials from the material market',
'welcome.step.title.install': 'Install',
'welcome.step.title.result': 'Result',
'welcome.step.content.pickup':
'For example, if you want the workplace page of pro, you can get the package name of the material from the material details',
'welcome.step.content.install':
'After getting the package name, you can install the material through the following command.',
'welcome.step.content.result': 'Then, you get a workplace page easily.',
'welcome.title.material':
'For more materials, please check the following link',
'welcome.link.material-pro': 'Arco Design Pro material collection',
'welcome.link.material-all': 'All materials',
},
'zh-CN': {
'welcome.title.welcome': '欢迎',
'welcome.invite': '通过 Arco Cli 命令可以安装物料市场的物料,诚邀您体验。',
'welcome.usage': '使用方式',
'welcome.step.title.pickup': '从物料市场选择物料',
'welcome.step.title.install': '安装物料',
'welcome.step.title.result': '成果',
'welcome.step.content.pickup':
'例如您看中了 pro 的 workplace 页面,可以从物料详情中获得该物料的包名',
'welcome.step.content.install':
'得到包名后,您就可以通过如下命令安装该物料',
'welcome.step.content.result': '这样您就能轻松获得一个 workplace 页面',
'welcome.title.material': '更多物料请查看以下链接',
'welcome.link.material-pro': 'Arco Design Pro 物料合集',
'welcome.link.material-all': '所有物料',
},
};
export default i18n;

@ -1,14 +0,0 @@
.code-block {
color: var(--color-text-2);
padding: 8px;
background-color: var(--color-fill-1);
width: fit-content;
&-content {
display: inline-block;
}
&-copy-btn {
margin-left: 8px;
}
}

@ -1,4 +0,0 @@
.header {
background: var(--color-bg-2);
padding: 20px;
}

@ -1,5 +1,6 @@
import auth, { AuthParams } from '@/utils/authentication'; import auth, { AuthParams } from '@/utils/authentication';
import { useEffect, useMemo, useState } from 'react'; import { useEffect, useMemo, useState } from 'react';
import Instance from '@/pages/instance';
export type IRoute = AuthParams & { export type IRoute = AuthParams & {
name: string; name: string;
@ -12,152 +13,38 @@ export type IRoute = AuthParams & {
}; };
export const routes: IRoute[] = [ export const routes: IRoute[] = [
{
name: 'menu.dashboard',
key: 'dashboard',
children: [
{ {
name: 'menu.dashboard.workplace', name: 'menu.dashboard.workplace',
key: 'dashboard/workplace', key: 'dashboard/workplace'
},
{
name: 'tinyFlowTest',
key: 'dashboard/tinyFlowTest',
},
{
name: 'reactFlowTest',
key: 'dashboard/reactFlowTest',
},
{
name: 'menu.dashboard.monitor',
key: 'dashboard/monitor',
requiredPermissions: [
{ resource: 'menu.dashboard.monitor', actions: ['write'] },
],
},
],
},
{
name: 'menu.visualization',
key: 'visualization',
children: [
{
name: 'menu.visualization.dataAnalysis',
key: 'visualization/data-analysis',
requiredPermissions: [
{ resource: 'menu.visualization.dataAnalysis', actions: ['read'] },
],
}, },
{ {
name: 'menu.visualization.multiDimensionDataAnalysis', name: 'menu.scene',
key: 'visualization/multi-dimension-data-analysis', key: 'scene'
requiredPermissions: [
{
resource: 'menu.visualization.dataAnalysis',
actions: ['read', 'write'],
}, },
{ {
resource: 'menu.visualization.multiDimensionDataAnalysis', name: 'menu.application',
actions: ['write'], key: 'application'
},
],
oneOfPerm: true,
},
],
}, },
{ {
name: 'menu.list', name: 'menu.instance',
key: 'list', key: 'instance'
children: [
{
name: 'menu.list.searchTable',
key: 'list/search-table',
}, },
{ {
name: 'menu.list.cardList', name: 'menu.componentDevelopment',
key: 'list/card', key: 'componentDevelopment'
},
],
}, },
{ {
name: 'menu.form', name: 'menu.componentLibrary',
key: 'form', key: 'componentLibrary'
children: [
{
name: 'menu.form.group',
key: 'form/group',
requiredPermissions: [
{ resource: 'menu.form.group', actions: ['read', 'write'] },
],
}, },
{ {
name: 'menu.form.step', name: 'menu.compositeCompLibrary',
key: 'form/step', key: 'compositeCompLibrary'
requiredPermissions: [
{ resource: 'menu.form.step', actions: ['read'] },
],
}, },
],
},
{
name: 'menu.profile',
key: 'profile',
children: [
{ {
name: 'menu.profile.basic', name: 'menu.componentMarket',
key: 'profile/basic', key: 'componentMarket'
}, }
],
},
{
name: 'menu.result',
key: 'result',
children: [
{
name: 'menu.result.success',
key: 'result/success',
breadcrumb: false,
},
{
name: 'menu.result.error',
key: 'result/error',
breadcrumb: false,
},
],
},
{
name: 'menu.exception',
key: 'exception',
children: [
{
name: 'menu.exception.403',
key: 'exception/403',
},
{
name: 'menu.exception.404',
key: 'exception/404',
},
{
name: 'menu.exception.500',
key: 'exception/500',
},
],
},
{
name: 'menu.user',
key: 'user',
children: [
{
name: 'menu.user.info',
key: 'user/info',
},
{
name: 'menu.user.setting',
key: 'user/setting',
},
],
},
]; ];
export const getName = (path: string, routes) => { export const getName = (path: string, routes) => {

Loading…
Cancel
Save