提交 81f68bb5 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 824af8e1
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab
VITE_API_URL_WORD = https://zijingebook.ezijing.com/file/ VITE_API_URL_WORD = https://zijingebook.ezijing.com/file/
# VITE_API_URL_WORD = http://ebook-pc.ezijing.com:7419
VITE_API_BASE_API_PREFFIX = /api VITE_API_BASE_API_PREFFIX = /api
VITE_API_WEBSOCKET_URL = wss://zijingebook.ezijing.com VITE_API_WEBSOCKET_URL = wss://zijingebook.ezijing.com
VITE_API_OPENAI_URL = https://model-platform-skyagents.tiangong.cn VITE_API_OPENAI_URL = https://model-platform-skyagents.tiangong.cn
\ No newline at end of file
...@@ -8,15 +8,16 @@ ...@@ -8,15 +8,16 @@
"name": "center-book", "name": "center-book",
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"@ant-design/icons": "^5.2.6", "@ant-design/icons": "^5.3.7",
"@fortaine/fetch-event-source": "^3.0.6",
"@reduxjs/toolkit": "^1.9.7", "@reduxjs/toolkit": "^1.9.7",
"@wangeditor/editor": "^5.1.23", "@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-react": "^1.0.6", "@wangeditor/editor-for-react": "^1.0.6",
"@wangeditor/plugin-link-card": "^1.0.0", "@wangeditor/plugin-link-card": "^1.0.0",
"ali-oss": "^6.20.0", "ali-oss": "^6.20.0",
"antd": "^5.17.0", "antd": "^5.18.0",
"axios": "^1.6.2", "axios": "^1.6.2",
"dayjs": "^1.11.10", "dayjs": "^1.11.11",
"easy-formula-editor": "^0.0.2-alpha.1", "easy-formula-editor": "^0.0.2-alpha.1",
"echarts": "^5.4.3", "echarts": "^5.4.3",
"highlight.js": "^11.9.0", "highlight.js": "^11.9.0",
...@@ -27,6 +28,7 @@ ...@@ -27,6 +28,7 @@
"rc-slider-captcha": "^1.3.0", "rc-slider-captcha": "^1.3.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-error-boundary": "^4.0.13",
"react-redux": "^8.1.3", "react-redux": "^8.1.3",
"react-router-dom": "^6.18.0", "react-router-dom": "^6.18.0",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
...@@ -34,18 +36,18 @@ ...@@ -34,18 +36,18 @@
"xml-formatter": "^3.6.2" "xml-formatter": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^18.2.15", "@types/react": "^18.3.3",
"@types/react-dom": "^18.2.7", "@types/react-dom": "^18.3.0",
"@umijs/fabric": "^4.0.1", "@umijs/fabric": "^4.0.1",
"@umijs/lint": "^4.0.88", "@umijs/lint": "^4.0.88",
"@vitejs/plugin-react-swc": "^3.6.0", "@vitejs/plugin-react-swc": "^3.7.0",
"eslint": "^8.53.0", "eslint": "^8.53.0",
"husky": "^8.0.3", "husky": "^8.0.3",
"less": "^4.2.0", "less": "^4.2.0",
"lint-staged": "^15.1.0", "lint-staged": "^15.1.0",
"prettier": "^3.1.0", "prettier": "^3.1.0",
"stylelint-config-standard": "^34.0.0", "stylelint-config-standard": "^34.0.0",
"vite": "^5.2.11", "vite": "^5.2.12",
"vite-plugin-mkcert": "^1.17.5" "vite-plugin-mkcert": "^1.17.5"
} }
}, },
...@@ -2681,6 +2683,14 @@ ...@@ -2681,6 +2683,14 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
} }
}, },
"node_modules/@fortaine/fetch-event-source": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@fortaine/fetch-event-source/-/fetch-event-source-3.0.6.tgz",
"integrity": "sha512-621GAuLMvKtyZQ3IA6nlDWhV1V/7PGOTNIGLUifxt0KzM+dZIweJ6F3XvQF3QnqeNfS1N7WQ0Kil1Di/lhChEw==",
"engines": {
"node": ">=16.15"
}
},
"node_modules/@humanwhocodes/config-array": { "node_modules/@humanwhocodes/config-array": {
"version": "0.11.14", "version": "0.11.14",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
...@@ -3068,9 +3078,9 @@ ...@@ -3068,9 +3078,9 @@
} }
}, },
"node_modules/@rc-component/tour": { "node_modules/@rc-component/tour": {
"version": "1.14.2", "version": "1.15.0",
"resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.14.2.tgz", "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.15.0.tgz",
"integrity": "sha512-A75DZ8LVvahBIvxooj3Gvf2sxe+CGOkmzPNX7ek0i0AJHyKZ1HXe5ieIGo3m0FMdZfVOlbCJ952Duq8VKAHk6g==", "integrity": "sha512-h6hyILDwL+In9GAgRobwRWihLqqsD7Uft3fZGrJ7L4EiyCoxbnNYwzPXDfz7vNDhWeVyvAWQJj9fJCzpI4+b4g==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.18.0", "@babel/runtime": "^7.18.0",
"@rc-component/portal": "^1.0.0-9", "@rc-component/portal": "^1.0.0-9",
...@@ -3087,9 +3097,9 @@ ...@@ -3087,9 +3097,9 @@
} }
}, },
"node_modules/@rc-component/trigger": { "node_modules/@rc-component/trigger": {
"version": "2.1.1", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.1.1.tgz", "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.2.0.tgz",
"integrity": "sha512-UjHkedkgtEcgQu87w1VuWug1idoDJV7VUt0swxHXRcmei2uu1AuUzGBPEUlmOmXGJ+YtTgZfVLi7kuAUKoZTMA==", "integrity": "sha512-QarBCji02YE9aRFhZgRZmOpXBj0IZutRippsVBv85sxvG4FGk/vRxwAlkn3MS9zK5mwbETd86mAVg2tKqTkdJA==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.23.2", "@babel/runtime": "^7.23.2",
"@rc-component/portal": "^1.1.0", "@rc-component/portal": "^1.1.0",
...@@ -3299,9 +3309,9 @@ ...@@ -3299,9 +3309,9 @@
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q=="
}, },
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "18.3.2", "version": "18.3.3",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.2.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz",
"integrity": "sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==", "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==",
"dependencies": { "dependencies": {
"@types/prop-types": "*", "@types/prop-types": "*",
"csstype": "^3.0.2" "csstype": "^3.0.2"
...@@ -4305,12 +4315,12 @@ ...@@ -4305,12 +4315,12 @@
} }
}, },
"node_modules/@vitejs/plugin-react-swc": { "node_modules/@vitejs/plugin-react-swc": {
"version": "3.6.0", "version": "3.7.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.6.0.tgz", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.0.tgz",
"integrity": "sha512-XFRbsGgpGxGzEV5i5+vRiro1bwcIaZDIdBRP16qwm+jP68ue/S8FJTBEgOeojtVDYrbSua3XFp71kC8VJE6v+g==", "integrity": "sha512-yrknSb3Dci6svCd/qhHqhFPDSw0QtjumcqdKMoNNzmOl5lMXTTiqzjWtG4Qask2HdvvzaNgSunbQGet8/GrKdA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@swc/core": "^1.3.107" "@swc/core": "^1.5.7"
}, },
"peerDependencies": { "peerDependencies": {
"vite": "^4 || ^5" "vite": "^4 || ^5"
...@@ -4620,9 +4630,9 @@ ...@@ -4620,9 +4630,9 @@
} }
}, },
"node_modules/antd": { "node_modules/antd": {
"version": "5.17.2", "version": "5.18.0",
"resolved": "https://registry.npmjs.org/antd/-/antd-5.17.2.tgz", "resolved": "https://registry.npmjs.org/antd/-/antd-5.18.0.tgz",
"integrity": "sha512-LVCR4kKWoNwaOEfYuWuXqwrK24W6YY6jlzROB4dTEEFvb2ovPi/5h9GcEB8U7ZJY/Yuvm1ehvRm9vohxVJzC3A==", "integrity": "sha512-xAvqvioW34npeZb8/JLZmCh5mcHU5MLiA0IYWAlpLAVmSgjs3p0tNzbU6a7Yx+y7o7E8PHtlchWfO3yBLQ15FQ==",
"dependencies": { "dependencies": {
"@ant-design/colors": "^7.0.2", "@ant-design/colors": "^7.0.2",
"@ant-design/cssinjs": "^1.19.1", "@ant-design/cssinjs": "^1.19.1",
...@@ -4632,44 +4642,44 @@ ...@@ -4632,44 +4642,44 @@
"@ctrl/tinycolor": "^3.6.1", "@ctrl/tinycolor": "^3.6.1",
"@rc-component/color-picker": "~1.5.3", "@rc-component/color-picker": "~1.5.3",
"@rc-component/mutate-observer": "^1.1.0", "@rc-component/mutate-observer": "^1.1.0",
"@rc-component/tour": "~1.14.2", "@rc-component/tour": "~1.15.0",
"@rc-component/trigger": "^2.1.1", "@rc-component/trigger": "^2.2.0",
"classnames": "^2.5.1", "classnames": "^2.5.1",
"copy-to-clipboard": "^3.3.3", "copy-to-clipboard": "^3.3.3",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"qrcode.react": "^3.1.0", "qrcode.react": "^3.1.0",
"rc-cascader": "~3.25.0", "rc-cascader": "~3.26.0",
"rc-checkbox": "~3.2.0", "rc-checkbox": "~3.3.0",
"rc-collapse": "~3.7.3", "rc-collapse": "~3.7.3",
"rc-dialog": "~9.4.0", "rc-dialog": "~9.4.0",
"rc-drawer": "~7.1.0", "rc-drawer": "~7.2.0",
"rc-dropdown": "~4.2.0", "rc-dropdown": "~4.2.0",
"rc-field-form": "~2.0.1", "rc-field-form": "~2.2.0",
"rc-image": "~7.6.0", "rc-image": "~7.8.0",
"rc-input": "~1.4.5", "rc-input": "~1.5.1",
"rc-input-number": "~9.0.0", "rc-input-number": "~9.1.0",
"rc-mentions": "~2.11.1", "rc-mentions": "~2.13.1",
"rc-menu": "~9.13.0", "rc-menu": "~9.14.0",
"rc-motion": "^2.9.0", "rc-motion": "^2.9.1",
"rc-notification": "~5.4.0", "rc-notification": "~5.6.0",
"rc-pagination": "~4.0.4", "rc-pagination": "~4.0.4",
"rc-picker": "~4.5.0", "rc-picker": "~4.5.0",
"rc-progress": "~4.0.0", "rc-progress": "~4.0.0",
"rc-rate": "~2.12.0", "rc-rate": "~2.13.0",
"rc-resize-observer": "^1.4.0", "rc-resize-observer": "^1.4.0",
"rc-segmented": "~2.3.0", "rc-segmented": "~2.3.0",
"rc-select": "~14.13.3", "rc-select": "~14.14.0",
"rc-slider": "~10.6.2", "rc-slider": "~10.6.2",
"rc-steps": "~6.0.1", "rc-steps": "~6.0.1",
"rc-switch": "~4.1.0", "rc-switch": "~4.1.0",
"rc-table": "~7.45.5", "rc-table": "~7.45.7",
"rc-tabs": "~15.0.0 ", "rc-tabs": "~15.1.0",
"rc-textarea": "~1.6.3", "rc-textarea": "~1.7.0",
"rc-tooltip": "~6.2.0", "rc-tooltip": "~6.2.0",
"rc-tree": "~5.8.7", "rc-tree": "~5.8.7",
"rc-tree-select": "~5.20.0", "rc-tree-select": "~5.21.0",
"rc-upload": "~4.5.2", "rc-upload": "~4.5.2",
"rc-util": "^5.39.3", "rc-util": "^5.41.0",
"scroll-into-view-if-needed": "^3.1.0", "scroll-into-view-if-needed": "^3.1.0",
"throttle-debounce": "^5.0.0" "throttle-debounce": "^5.0.0"
}, },
...@@ -4920,9 +4930,9 @@ ...@@ -4920,9 +4930,9 @@
} }
}, },
"node_modules/axios": { "node_modules/axios": {
"version": "1.6.8", "version": "1.7.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
"integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
"dependencies": { "dependencies": {
"follow-redirects": "^1.15.6", "follow-redirects": "^1.15.6",
"form-data": "^4.0.0", "form-data": "^4.0.0",
...@@ -10088,14 +10098,14 @@ ...@@ -10088,14 +10098,14 @@
} }
}, },
"node_modules/rc-cascader": { "node_modules/rc-cascader": {
"version": "3.25.0", "version": "3.26.0",
"resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.25.0.tgz", "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.26.0.tgz",
"integrity": "sha512-mBY6/CykOvzAYnIye0rpt5JkMAXJaX8zZawOwSndbKuFakYE+leqBQWIZoN9HIgAptPpTi2Aty3RvbaBmk8SKQ==", "integrity": "sha512-L1dml383TPSJD1I11YwxuVbmqaJY64psZqFp1ETlgl3LEOwDu76Cyl11fw5dmjJhMlUWwM5dECQfqJgfebhUjg==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.12.5", "@babel/runtime": "^7.12.5",
"array-tree-filter": "^2.1.0", "array-tree-filter": "^2.1.0",
"classnames": "^2.3.1", "classnames": "^2.3.1",
"rc-select": "~14.13.0", "rc-select": "~14.14.0",
"rc-tree": "~5.8.1", "rc-tree": "~5.8.1",
"rc-util": "^5.37.0" "rc-util": "^5.37.0"
}, },
...@@ -10105,9 +10115,9 @@ ...@@ -10105,9 +10115,9 @@
} }
}, },
"node_modules/rc-checkbox": { "node_modules/rc-checkbox": {
"version": "3.2.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-3.2.0.tgz", "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-3.3.0.tgz",
"integrity": "sha512-8inzw4y9dAhZmv/Ydl59Qdy5tdp9CKg4oPVcRigi+ga/yKPZS5m5SyyQPtYSgbcqHRYOdUhiPSeKfktc76du1A==", "integrity": "sha512-Ih3ZaAcoAiFKJjifzwsGiT/f/quIkxJoklW4yKGho14Olulwn8gN7hOBve0/WGDg5o/l/5mL0w7ff7/YGvefVw==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.10.1", "@babel/runtime": "^7.10.1",
"classnames": "^2.3.2", "classnames": "^2.3.2",
...@@ -10150,9 +10160,9 @@ ...@@ -10150,9 +10160,9 @@
} }
}, },
"node_modules/rc-drawer": { "node_modules/rc-drawer": {
"version": "7.1.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-7.1.0.tgz", "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-7.2.0.tgz",
"integrity": "sha512-nBE1rF5iZvpavoyqhSSz2mk/yANltA7g3aF0U45xkx381n3we/RKs9cJfNKp9mSWCedOKWt9FLEwZDaAaOGn2w==", "integrity": "sha512-9lOQ7kBekEJRdEpScHvtmEtXnAsy+NGDXiRWc2ZVC7QXAazNVbeT4EraQKYwCME8BJLa8Bxqxvs5swwyOepRwg==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.23.9", "@babel/runtime": "^7.23.9",
"@rc-component/portal": "^1.1.1", "@rc-component/portal": "^1.1.1",
...@@ -10181,9 +10191,9 @@ ...@@ -10181,9 +10191,9 @@
} }
}, },
"node_modules/rc-field-form": { "node_modules/rc-field-form": {
"version": "2.0.1", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-2.0.1.tgz", "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-2.2.1.tgz",
"integrity": "sha512-3WK/POHBcfMFKrzScrkmgMIXqoVQ0KgVwcVnej/ukwuQG4ZHCJaTi2KhM+tWTK4WODBXbmjKg5pKHj2IVmSg4A==", "integrity": "sha512-uoNqDoR7A4tn4QTSqoWPAzrR7ZwOK5I+vuZ/qdcHtbKx+ZjEsTg7QXm2wk/jalDiSksAQmATxL0T5LJkRREdIA==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.18.0", "@babel/runtime": "^7.18.0",
"@rc-component/async-validator": "^5.0.3", "@rc-component/async-validator": "^5.0.3",
...@@ -10216,9 +10226,9 @@ ...@@ -10216,9 +10226,9 @@
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
}, },
"node_modules/rc-image": { "node_modules/rc-image": {
"version": "7.6.0", "version": "7.8.1",
"resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.6.0.tgz", "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.8.1.tgz",
"integrity": "sha512-tL3Rvd1sS+frZQ01i+tkeUPaOeFz2iG9/scAt/Cfs0hyCRVA/w0Pu1J/JxIX8blalvmHE0bZQRYdOmRAzWu4Hg==", "integrity": "sha512-Y7/ALO8kgAddl9WBHUQDcff7Yfcd1T2ALS/JPlRqkau8wcua48k99glv/CcgChy4xwUXCUdO1cM2l1NqtoZZHw==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.11.2", "@babel/runtime": "^7.11.2",
"@rc-component/portal": "^1.0.2", "@rc-component/portal": "^1.0.2",
...@@ -10233,9 +10243,9 @@ ...@@ -10233,9 +10243,9 @@
} }
}, },
"node_modules/rc-input": { "node_modules/rc-input": {
"version": "1.4.5", "version": "1.5.1",
"resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.4.5.tgz", "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.5.1.tgz",
"integrity": "sha512-AjzykhwnwYTRSwwgCu70CGKBIAv6bP2nqnFptnNTprph/TF1BAs0Qxl91mie/BR6n827WIJB6ZjaRf9iiMwAfw==", "integrity": "sha512-+nOzQJDeIfIpNP/SgY45LXSKbuMlp4Yap2y8c+ZpU7XbLmNzUd6+d5/S75sA/52jsVE6S/AkhkkDEAOjIu7i6g==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.11.1", "@babel/runtime": "^7.11.1",
"classnames": "^2.2.1", "classnames": "^2.2.1",
...@@ -10247,15 +10257,15 @@ ...@@ -10247,15 +10257,15 @@
} }
}, },
"node_modules/rc-input-number": { "node_modules/rc-input-number": {
"version": "9.0.0", "version": "9.1.0",
"resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-9.0.0.tgz", "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-9.1.0.tgz",
"integrity": "sha512-RfcDBDdWFFetouWFXBA+WPEC8LzBXyngr9b+yTLVIygfFu7HiLRGn/s/v9wwno94X7KFvnb28FNynMGj9XJlDQ==", "integrity": "sha512-NqJ6i25Xn/AgYfVxynlevIhX3FuKlMwIFpucGG1h98SlK32wQwDK0zhN9VY32McOmuaqzftduNYWWooWz8pXQA==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.10.1", "@babel/runtime": "^7.10.1",
"@rc-component/mini-decimal": "^1.0.1", "@rc-component/mini-decimal": "^1.0.1",
"classnames": "^2.2.5", "classnames": "^2.2.5",
"rc-input": "~1.4.0", "rc-input": "~1.5.0",
"rc-util": "^5.28.0" "rc-util": "^5.40.1"
}, },
"peerDependencies": { "peerDependencies": {
"react": ">=16.9.0", "react": ">=16.9.0",
...@@ -10263,16 +10273,16 @@ ...@@ -10263,16 +10273,16 @@
} }
}, },
"node_modules/rc-mentions": { "node_modules/rc-mentions": {
"version": "2.11.1", "version": "2.13.2",
"resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.11.1.tgz", "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.13.2.tgz",
"integrity": "sha512-upb4AK1SRFql7qGnbLEvJqLMugVVIyjmwBJW9L0eLoN9po4JmJZaBzmKA4089fNtsU8k6l/tdZiVafyooeKnLw==", "integrity": "sha512-gJCF6MDax/2wl2CzvJEN9yyQKYDzGKA2hmmymQiEPiYUNUOk6UKvQFSB3TBfAi57vxntPMJZGfxNtda1BDb4kA==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.22.5", "@babel/runtime": "^7.22.5",
"@rc-component/trigger": "^2.0.0", "@rc-component/trigger": "^2.0.0",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"rc-input": "~1.4.0", "rc-input": "~1.5.0",
"rc-menu": "~9.13.0", "rc-menu": "~9.14.0",
"rc-textarea": "~1.6.1", "rc-textarea": "~1.7.0",
"rc-util": "^5.34.1" "rc-util": "^5.34.1"
}, },
"peerDependencies": { "peerDependencies": {
...@@ -10281,9 +10291,9 @@ ...@@ -10281,9 +10291,9 @@
} }
}, },
"node_modules/rc-menu": { "node_modules/rc-menu": {
"version": "9.13.0", "version": "9.14.0",
"resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.13.0.tgz", "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.14.0.tgz",
"integrity": "sha512-1l8ooCB3HcYJKCltC/s7OxRKRjgymdl9htrCeGZcXNaMct0RxZRK6OPV3lPhVksIvAGMgzPd54ClpZ5J4b8cZA==", "integrity": "sha512-La3LBCDMLMs9Q/8mTGbnscb+ZeJ26ebkLz9xJFHd2SD8vfsCKl1Z/k3mwbxyKL01lB40fel1s9Nn9LAv/nmVJQ==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.10.1", "@babel/runtime": "^7.10.1",
"@rc-component/trigger": "^2.0.0", "@rc-component/trigger": "^2.0.0",
...@@ -10298,13 +10308,13 @@ ...@@ -10298,13 +10308,13 @@
} }
}, },
"node_modules/rc-motion": { "node_modules/rc-motion": {
"version": "2.9.0", "version": "2.9.1",
"resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.0.tgz", "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.1.tgz",
"integrity": "sha512-XIU2+xLkdIr1/h6ohPZXyPBMvOmuyFZQ/T0xnawz+Rh+gh4FINcnZmMT5UTIj6hgI0VLDjTaPeRd+smJeSPqiQ==", "integrity": "sha512-QD4bUqByjVQs7PhUT1d4bNxvtTcK9ETwtg7psbDfo6TmYalH/1hhjj4r2hbhW7g5OOEqYHhfwfj4noIvuOVRtQ==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.11.1", "@babel/runtime": "^7.11.1",
"classnames": "^2.2.1", "classnames": "^2.2.1",
"rc-util": "^5.21.0" "rc-util": "^5.39.3"
}, },
"peerDependencies": { "peerDependencies": {
"react": ">=16.9.0", "react": ">=16.9.0",
...@@ -10312,9 +10322,9 @@ ...@@ -10312,9 +10322,9 @@
} }
}, },
"node_modules/rc-notification": { "node_modules/rc-notification": {
"version": "5.4.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.4.0.tgz", "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.6.0.tgz",
"integrity": "sha512-li19y9RoYJciF3WRFvD+DvWS70jdL8Fr+Gfb/OshK+iY6iTkwzoigmSIp76/kWh5tF5i/i9im12X3nsF85GYdA==", "integrity": "sha512-TGQW5T7waOxLwgJG7fXcw8l7AQiFOjaZ7ISF5PrU526nunHRNcTMuzKihQHaF4E/h/KfOCDk3Mv8eqzbu2e28w==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.10.1", "@babel/runtime": "^7.10.1",
"classnames": "2.x", "classnames": "2.x",
...@@ -10411,9 +10421,9 @@ ...@@ -10411,9 +10421,9 @@
} }
}, },
"node_modules/rc-rate": { "node_modules/rc-rate": {
"version": "2.12.0", "version": "2.13.0",
"resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.12.0.tgz", "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.13.0.tgz",
"integrity": "sha512-g092v5iZCdVzbjdn28FzvWebK2IutoVoiTeqoLTj9WM7SjA/gOJIw5/JFZMRyJYYVe1jLAU2UhAfstIpCNRozg==", "integrity": "sha512-oxvx1Q5k5wD30sjN5tqAyWTvJfLNNJn7Oq3IeS4HxWfAiC4BOXMITNAsw7u/fzdtO4MS8Ki8uRLOzcnEuoQiAw==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.10.1", "@babel/runtime": "^7.10.1",
"classnames": "^2.2.5", "classnames": "^2.2.5",
...@@ -10458,9 +10468,9 @@ ...@@ -10458,9 +10468,9 @@
} }
}, },
"node_modules/rc-select": { "node_modules/rc-select": {
"version": "14.13.3", "version": "14.14.0",
"resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.13.3.tgz", "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.14.0.tgz",
"integrity": "sha512-AMEfdE40RhlqahMGN3Q7OKVd1txNph0zIn2Xpvn0ZJiUYafCsqoGv+Rj6v1umgm8ZOEAJ3LefnkznAYNMMzACg==", "integrity": "sha512-Uo2wulrjoPPRLCPd7zlK4ZFVJxlTN//yp1xWP/U+TUOQCyXrT+Duvq/Si5OzVcmQyWAUSbsplc2OwNNhvbOeKQ==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.10.1", "@babel/runtime": "^7.10.1",
"@rc-component/trigger": "^2.1.1", "@rc-component/trigger": "^2.1.1",
...@@ -10545,16 +10555,16 @@ ...@@ -10545,16 +10555,16 @@
} }
}, },
"node_modules/rc-table": { "node_modules/rc-table": {
"version": "7.45.5", "version": "7.45.7",
"resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.45.5.tgz", "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.45.7.tgz",
"integrity": "sha512-R5sOfToOk7CalSkebZpqM8lkKWOJR7uXPGEhjjTSoj5egyHBwMxaACoPj2oI+6qLSll9yZrG5K+8HTN57b2Ahg==", "integrity": "sha512-wi9LetBL1t1csxyGkMB2p3mCiMt+NDexMlPbXHvQFmBBAsMxrgNSAPwUci2zDLUq9m8QdWc1Nh8suvrpy9mXrg==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.10.1", "@babel/runtime": "^7.10.1",
"@rc-component/context": "^1.4.0", "@rc-component/context": "^1.4.0",
"classnames": "^2.2.5", "classnames": "^2.2.5",
"rc-resize-observer": "^1.1.0", "rc-resize-observer": "^1.1.0",
"rc-util": "^5.37.0", "rc-util": "^5.37.0",
"rc-virtual-list": "^3.11.1" "rc-virtual-list": "^3.14.2"
}, },
"engines": { "engines": {
"node": ">=8.x" "node": ">=8.x"
...@@ -10565,14 +10575,14 @@ ...@@ -10565,14 +10575,14 @@
} }
}, },
"node_modules/rc-tabs": { "node_modules/rc-tabs": {
"version": "15.0.0", "version": "15.1.0",
"resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-15.0.0.tgz", "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-15.1.0.tgz",
"integrity": "sha512-7m541VcEiJSpHZmosMZNMIhemxtIN+f0WDhZNyXQ1/cZ40aaWsknlbj0FH6HryLoKEQvBnCI89hgQuT7MBSOBA==", "integrity": "sha512-xTNz4Km1025emtkv1q7xKhjPwAtXr/wycuXVTAcFJg+DKhnPDDbnwbA9KRW0SawAVOGvVEj8ZrBlU0u0FGLrbg==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.11.2", "@babel/runtime": "^7.11.2",
"classnames": "2.x", "classnames": "2.x",
"rc-dropdown": "~4.2.0", "rc-dropdown": "~4.2.0",
"rc-menu": "~9.13.0", "rc-menu": "~9.14.0",
"rc-motion": "^2.6.2", "rc-motion": "^2.6.2",
"rc-resize-observer": "^1.0.0", "rc-resize-observer": "^1.0.0",
"rc-util": "^5.34.1" "rc-util": "^5.34.1"
...@@ -10586,13 +10596,13 @@ ...@@ -10586,13 +10596,13 @@
} }
}, },
"node_modules/rc-textarea": { "node_modules/rc-textarea": {
"version": "1.6.3", "version": "1.7.0",
"resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.6.3.tgz", "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.7.0.tgz",
"integrity": "sha512-8k7+8Y2GJ/cQLiClFMg8kUXOOdvcFQrnGeSchOvI2ZMIVvX5a3zQpLxoODL0HTrvU63fPkRmMuqaEcOF9dQemA==", "integrity": "sha512-UxizYJkWkmxP3zofXgc487QiGyDmhhheDLLjIWbFtDmiru1ls30KpO8odDaPyqNUIy9ugj5djxTEuezIn6t3Jg==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.10.1", "@babel/runtime": "^7.10.1",
"classnames": "^2.2.1", "classnames": "^2.2.1",
"rc-input": "~1.4.0", "rc-input": "~1.5.0",
"rc-resize-observer": "^1.0.0", "rc-resize-observer": "^1.0.0",
"rc-util": "^5.27.0" "rc-util": "^5.27.0"
}, },
...@@ -10635,13 +10645,13 @@ ...@@ -10635,13 +10645,13 @@
} }
}, },
"node_modules/rc-tree-select": { "node_modules/rc-tree-select": {
"version": "5.20.0", "version": "5.21.0",
"resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.20.0.tgz", "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.21.0.tgz",
"integrity": "sha512-zFtkHx5/6PnXSi3oSbBSFbIPiJJQdpSU3qz/joLe75URgvxmTHi989O8MtMgpwyZwrCMOJpGi6L1uy+13uzZPw==", "integrity": "sha512-w+9qEu6zh0G3wt9N/hzWNSnqYH1i9mH1Nqxo0caxLRRFXF5yZWYmpCDoDTMdQM1Y4z3Q5yj08qyrPH/d4AtumA==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.10.1", "@babel/runtime": "^7.10.1",
"classnames": "2.x", "classnames": "2.x",
"rc-select": "~14.13.0", "rc-select": "~14.14.0",
"rc-tree": "~5.8.1", "rc-tree": "~5.8.1",
"rc-util": "^5.16.1" "rc-util": "^5.16.1"
}, },
...@@ -10665,9 +10675,9 @@ ...@@ -10665,9 +10675,9 @@
} }
}, },
"node_modules/rc-util": { "node_modules/rc-util": {
"version": "5.39.3", "version": "5.41.0",
"resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.39.3.tgz", "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.41.0.tgz",
"integrity": "sha512-j9wOELkLQ8gC/NkUg3qg9mHZcJf+5mYYv40JrDHqnaf8VSycji4pCf7kJ5fdTXQPDIF0vr5zpb/T2HdrMs9rWA==", "integrity": "sha512-xtlCim9RpmVv0Ar2Nnc3WfJCxjQkTf3xHPWoFdjp1fSs2NirQwqiQrfqdU9HUe0kdfb168M/T8Dq0IaX50xeKg==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.18.3", "@babel/runtime": "^7.18.3",
"react-is": "^18.2.0" "react-is": "^18.2.0"
...@@ -10683,9 +10693,9 @@ ...@@ -10683,9 +10693,9 @@
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
}, },
"node_modules/rc-virtual-list": { "node_modules/rc-virtual-list": {
"version": "3.12.0", "version": "3.14.2",
"resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.12.0.tgz", "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.14.2.tgz",
"integrity": "sha512-43+/lr7bImpvEwTFw1FTYwSg42VHzRgO5PiCEEUROj8D2+M2SCvANqGIa9QyhoFLVQtc+2QXvgTB7VPGG7oOoQ==", "integrity": "sha512-rA+W5xryhklJAcmswNyuKB3ZGeB855io+yOFQK5u/RXhjdshGblfKpNkQr4/9fBhZns0+uiL/0/s6IP2krtSmg==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.0", "@babel/runtime": "^7.20.0",
"classnames": "^2.2.6", "classnames": "^2.2.6",
...@@ -10723,6 +10733,17 @@ ...@@ -10723,6 +10733,17 @@
"react": "^18.2.0" "react": "^18.2.0"
} }
}, },
"node_modules/react-error-boundary": {
"version": "4.0.13",
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.13.tgz",
"integrity": "sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==",
"dependencies": {
"@babel/runtime": "^7.12.5"
},
"peerDependencies": {
"react": ">=16.13.1"
}
},
"node_modules/react-is": { "node_modules/react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
...@@ -12670,9 +12691,9 @@ ...@@ -12670,9 +12691,9 @@
} }
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "5.2.11", "version": "5.2.12",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.12.tgz",
"integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", "integrity": "sha512-/gC8GxzxMK5ntBwb48pR32GGhENnjtY30G4A0jemunsBkiEZFw60s8InGpN8gkhHEkjnRK1aSAxeQgwvFhUHAA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"esbuild": "^0.20.1", "esbuild": "^0.20.1",
......
...@@ -19,15 +19,16 @@ ...@@ -19,15 +19,16 @@
"prettier": "prettier -c --write \"**/**.{js,jsx,tsx,ts,less,md,json}\"" "prettier": "prettier -c --write \"**/**.{js,jsx,tsx,ts,less,md,json}\""
}, },
"dependencies": { "dependencies": {
"@ant-design/icons": "^5.2.6", "@ant-design/icons": "^5.3.7",
"@fortaine/fetch-event-source": "^3.0.6",
"@reduxjs/toolkit": "^1.9.7", "@reduxjs/toolkit": "^1.9.7",
"@wangeditor/editor": "^5.1.23", "@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-react": "^1.0.6", "@wangeditor/editor-for-react": "^1.0.6",
"@wangeditor/plugin-link-card": "^1.0.0", "@wangeditor/plugin-link-card": "^1.0.0",
"ali-oss": "^6.20.0", "ali-oss": "^6.20.0",
"antd": "^5.17.0", "antd": "^5.18.0",
"axios": "^1.6.2", "axios": "^1.6.2",
"dayjs": "^1.11.10", "dayjs": "^1.11.11",
"easy-formula-editor": "^0.0.2-alpha.1", "easy-formula-editor": "^0.0.2-alpha.1",
"echarts": "^5.4.3", "echarts": "^5.4.3",
"highlight.js": "^11.9.0", "highlight.js": "^11.9.0",
...@@ -38,6 +39,7 @@ ...@@ -38,6 +39,7 @@
"rc-slider-captcha": "^1.3.0", "rc-slider-captcha": "^1.3.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-error-boundary": "^4.0.13",
"react-redux": "^8.1.3", "react-redux": "^8.1.3",
"react-router-dom": "^6.18.0", "react-router-dom": "^6.18.0",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
...@@ -45,18 +47,18 @@ ...@@ -45,18 +47,18 @@
"xml-formatter": "^3.6.2" "xml-formatter": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^18.2.15", "@types/react": "^18.3.3",
"@types/react-dom": "^18.2.7", "@types/react-dom": "^18.3.0",
"@umijs/fabric": "^4.0.1", "@umijs/fabric": "^4.0.1",
"@umijs/lint": "^4.0.88", "@umijs/lint": "^4.0.88",
"@vitejs/plugin-react-swc": "^3.6.0", "@vitejs/plugin-react-swc": "^3.7.0",
"eslint": "^8.53.0", "eslint": "^8.53.0",
"husky": "^8.0.3", "husky": "^8.0.3",
"less": "^4.2.0", "less": "^4.2.0",
"lint-staged": "^15.1.0", "lint-staged": "^15.1.0",
"prettier": "^3.1.0", "prettier": "^3.1.0",
"stylelint-config-standard": "^34.0.0", "stylelint-config-standard": "^34.0.0",
"vite": "^5.2.11", "vite": "^5.2.12",
"vite-plugin-mkcert": "^1.17.5" "vite-plugin-mkcert": "^1.17.5"
}, },
"browserslist": [ "browserslist": [
......
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { Button } from 'antd';
import './App.less'; import './App.less';
import { GetroutesDyamic } from '@/routes/index'; import { GetroutesDyamic } from '@/routes/index';
import { ErrorBoundary } from '@/common/errorBoundary';
import { ErrorFallback } from '@/common/errorBoundary/ErrorFallback';
import MakeError from '@/common/errorBoundary/error/MakeError';
function fallbackRender({ error, resetErrorBoundary }) {
return (
<div role='alert'>
<p>出错啦:</p>
<pre style={{ color: 'red' }}>{error.message}</pre>
<Button type='link' onClick={resetErrorBoundary}>
Try again
</Button>
</div>
);
}
function App() { function App() {
const [token, setToken] = useState(''); const [token, setToken] = useState('');
...@@ -17,25 +27,8 @@ function App() { ...@@ -17,25 +27,8 @@ function App() {
setToken(''); setToken('');
} }
}, []); }, []);
const [hasError, setHasError] = useState(false);
const onError = (error) => {
// 日志上報
console.log(error);
setHasError(true);
};
const onReset = () => {
console.log('尝试恢复错误');
setHasError(false);
};
return ( return (
<ErrorBoundary <ErrorBoundary fallbackRender={fallbackRender}>
fallbackRender={(fallbackProps) => <ErrorFallback {...fallbackProps} />}
onError={onError}
onReset={onReset}
>
<GetroutesDyamic /> <GetroutesDyamic />
</ErrorBoundary> </ErrorBoundary>
); );
......
import axios from '@/utils/axios';
import fetchEventSource from '@/utils/fetchEventSource';
// 流式编辑接口
export function aiEdit(options) {
return fetchEventSource('/api/ai/sky3/edit', options);
}
// 流式对话接口
export function aiChat(data) {
return axios.post('/api/ai/sky3/chat', data);
}
// 文本生成图片接口
export function aiGenerateImage(data) {
return axios.post('/api/ai/sky3/generateImage', data);
}
import {Dropdown,Space} from 'antd';
import { DownOutlined } from '@ant-design/icons';
const DropDownCom=(props)=>{
const {items,defaultText=""}=props
return (
<div>
<Dropdown menu={{
items,
}}>
<a onClick={(e) => e.preventDefault()}>
<Space>
{defaultText}
<DownOutlined />
</Space>
</a>
</Dropdown>
</div>
)
}
export default DropDownCom;
\ No newline at end of file
import React from 'react';
import { Button } from 'antd';
/**
* 出错后现时的组件
* @param error
* @param resetErrorBoundary
* @constructor
*/
export const ErrorFallback = ({ error, resetErrorBoundary }) => {
return (
<div role='alert'>
<p>出错啦</p>
<pre>{error.message}</pre>
<Button type='link' onClick={resetErrorBoundary}>
Try again
</Button>
</div>
);
};
import { useEffect, useState } from 'react';
import { useErrorHandler } from '../ErrorBoundary';
const AsyncError = () => {
const handleError = useErrorHandler();
const [number, setNumber] = useState(0);
const randomlyFetchData = async () => {
return Math.random();
};
useEffect(() => {
randomlyFetchData()
.then((number) => {
if (number > 0.5) {
throw new Error('async 大于 0.5');
} else {
setNumber(number);
}
})
.catch(handleError);
}, []);
return <div>{number}</div>;
};
export default AsyncError;
import { useEffect } from 'react';
const MakeError = () => {
useEffect(() => {
const number = Math.random();
if (number > 0.5) {
throw new Error('大于0.5');
}
}, []);
return <div />;
};
export default MakeError;
import React, { useState } from 'react';
import MakeError from '../error/MakeError';
import { ErrorFallback } from '../ErrorFallback';
import { ErrorBoundary } from '../index';
const FallbackComponentExample = () => {
const [hasError, setHasError] = useState(false);
const onError = (error) => {
// 日志上報
console.log(error);
setHasError(true);
};
const onReset = () => {
console.log('尝试恢复错误');
setHasError(false);
};
return (
<ErrorBoundary FallbackComponent={ErrorFallback} onError={onError} onReset={onReset}>
{!hasError ? <MakeError /> : null}
</ErrorBoundary>
);
};
export default FallbackComponentExample;
import React, { useState } from 'react';
import MakeError from '../error/MakeError';
import { ErrorBoundary } from '../index';
const FallbackExample = () => {
const [hasError, setHasError] = useState(false);
const onError = (error) => {
// 日志上報
console.log(error);
setHasError(true);
};
const onReset = () => {
console.log('尝试恢复错误');
setHasError(false);
};
return (
<ErrorBoundary fallback={<div>出错啦</div>} onError={onError} onReset={onReset}>
{!hasError ? <MakeError /> : null}
</ErrorBoundary>
);
};
export default FallbackExample;
import React, { useState } from 'react';
import MakeError from '../error/MakeError';
import { ErrorFallback } from '../ErrorFallback';
import { ErrorBoundary } from '../index';
const FallbackRenderExample = () => {
const [hasError, setHasError] = useState(false);
const onError = (error) => {
// 日志上報
console.log(error);
setHasError(true);
};
const onReset = () => {
console.log('尝试恢复错误');
setHasError(false);
};
return (
<ErrorBoundary
fallbackRender={(fallbackProps) => <ErrorFallback {...fallbackProps} />}
onError={onError}
onReset={onReset}
>
{!hasError ? <MakeError /> : null}
</ErrorBoundary>
);
};
export default FallbackRenderExample;
import React, { useState } from 'react';
import MakeError from '../error/MakeError';
import { ErrorFallback } from '../ErrorFallback';
import { ErrorBoundary } from '../index';
const FallbackExample = () => {
const [retry, setRetry] = useState(0);
return (
<div>
<button onClick={() => setRetry(retry + 1)}>retry</button>
<ErrorBoundary FallbackComponent={ErrorFallback} resetKeys={[retry]}>
<MakeError />
</ErrorBoundary>
</div>
);
};
export default FallbackExample;
import React, { useState } from 'react';
import { ErrorFallback } from '../ErrorFallback';
import { ErrorBoundary } from '../index';
import AsyncError from '../error/AsyncError';
const UseErrorHandlerExample = () => {
const [hasError, setHasError] = useState(false);
const onError = (error) => {
// 日志上報
console.log(error);
setHasError(true);
};
const onReset = () => {
console.log('尝试恢复错误');
setHasError(false);
};
return (
<ErrorBoundary FallbackComponent={ErrorFallback} onError={onError} onReset={onReset}>
{!hasError ? <AsyncError /> : null}
</ErrorBoundary>
);
};
export default UseErrorHandlerExample;
import React from 'react';
import MakeError from '../error/MakeError';
import { ErrorFallback } from '../ErrorFallback';
import { withErrorBoundary } from '../index';
const WithErrorBoundaryExample = withErrorBoundary(MakeError, {
FallbackComponent: ErrorFallback,
onError: (error, info) => console.log(error, info),
});
export default WithErrorBoundaryExample;
import React from 'react';
import FallbackComponentexample from '@/common/errorBoundary/example/FallbackComponentexample';
import FallbackRenderexample from '@/common/errorBoundary/example/FallbackRenderexample';
import Fallbackexample from '@/common/errorBoundary/example/Fallbackexample';
import WithErrorBoundaryexample from '@/common/errorBoundary/example/WithErrorBoundaryexample';
import UseErrorHandlerexample from '@/common/errorBoundary/example/UseErrorHandlerexample';
import ResetKeysexample from '@/common/errorBoundary/example/ResetKeysexample';
const ExampleErrorBox = () => {
return (
<div className='App'>
<h2>fallback 例子</h2>
<Fallbackexample />
<h2>FallbackComponent 例子</h2>
<FallbackComponentexample />
<h2>fallbackRender 例子</h2>
<FallbackRenderexample />
<h2>withErrorBoundary 例子</h2>
<WithErrorBoundaryexample />
<h2>useErrorHandler 例子</h2>
<UseErrorHandlerexample />
<h2>ResetKeys 例子</h2>
<ResetKeysexample />
</div>
);
};
export default ExampleErrorBox;
import * as React from 'react';
const changedArray = (a = [], b = []) => {
return a.length !== b.length || a.some((item, index) => !Object.is(item, b[index]));
};
// 初始状态
const initialState = {
error: null,
};
class ErrorBoundary extends React.Component {
state = initialState;
updatedWithError = false;
static getDerivedStateFromError(error) {
return { error };
}
componentDidCatch(error, errorInfo) {
if (this.props.onError) {
this.props.onError(error, errorInfo.componentStack);
}
}
componentDidUpdate(prevProps) {
const { error } = this.state;
const { resetKeys, onResetKeysChange } = this.props;
if (error !== null && !this.updatedWithError) {
this.updatedWithError = true;
return;
}
if (error !== null && changedArray(prevProps.resetKeys, resetKeys)) {
if (onResetKeysChange) {
onResetKeysChange(prevProps.resetKeys, resetKeys);
}
this.reset();
}
}
reset = () => {
this.updatedWithError = false;
this.setState(initialState);
};
resetErrorBoundary = () => {
if (this.props.onReset) {
this.props.onReset();
}
this.reset();
};
render() {
const { fallback, FallbackComponent, fallbackRender } = this.props;
const { error } = this.state;
if (error !== null) {
const fallbackProps = {
error,
resetErrorBoundary: this.resetErrorBoundary,
};
if (React.isValidElement(fallback)) {
return fallback;
}
if (typeof fallbackRender === 'function') {
return fallbackRender(fallbackProps);
}
if (FallbackComponent) {
return <FallbackComponent {...fallbackProps} />;
}
throw new Error(
'ErrorBoundary 组件需要传入 fallback, fallbackRender, FallbackComponent 其中一个',
);
}
return this.props.children;
}
}
/**
* with 写法
* @param Component 业务组件
* @param errorBoundaryProps error boundary 的 props
*/
function withErrorBoundary(Component, errorBoundaryProps) {
const Wrapped = (props) => {
return (
<ErrorBoundary {...errorBoundaryProps}>
<Component {...props} />
</ErrorBoundary>
);
};
// DevTools 显示的组件名
const name = Component.displayName || Component.name || 'Unknown';
Wrapped.displayName = `withErrorBoundary(${name})`;
return Wrapped;
}
/**
* 自定义错误的 handler
* @param givenError
*/
function useErrorHandler(givenError) {
const [error, setError] = React.useState(null);
if (givenError) throw givenError;
if (error) throw error;
return setError;
}
export { ErrorBoundary, withErrorBoundary, useErrorHandler };
import React from 'react';
const setIcon = (props) => {
const { width = 14, alt = '', src = '' } = props;
return <img src={src} alt={alt} width={width} />;
};
export default setIcon;
window._iconfont_svg_string_4347154='<svg><symbol id="icon-shezhi" viewBox="0 0 1024 1024"><path d="M545.784454 962.539206l-65.943898 0c-29.341259 0-54.624085-25.281803-54.624085-54.615898L425.216471 868.462574c0-9.623171-7.826246-20.911262-16.690124-23.680329l-1.566682-0.611937-55.725162-23.104207-0.880043-0.494257c-8.153704-4.41045-22.017456-2.376117-28.55229 4.187369l-28.17469 28.123524c-9.930163 9.977235-23.239284 15.494902-37.432541 15.494902-14.195304 0-27.507494-5.517667-37.487799-15.541975l-46.682205-46.630017c-20.60427-20.603247-20.6319-54.233182-0.069585-74.974575l28.15013-28.106128c6.637164-6.574742 8.676613-20.599154 4.253884-28.909423l-0.831948-1.768273-23.164582-56.128345-0.26913-0.682545c-2.803859-9.03477-14.279215-17.394159-23.611767-17.394159l-39.631626 0c-29.391401 0-52.861952-24.065092-52.861952-53.193503l0-65.943898c0-28.770254 22.998807-51.754734 52.919257-51.754734l39.575344 0c9.081843 0 20.803815-8.830109 23.666002-18.057261l0.567935-1.476631 23.163559-57.088206 0.505513-0.913812c4.40431-8.220219 2.319835-22.224164-4.2897-28.830629l-28.04166-28.087709c-9.964956-9.921977-15.486716-23.216771-15.502066-37.396725-0.01535-14.201443 5.492084-27.53717 15.507182-37.552268l46.6556-46.614667c9.94142-9.985422 23.248494-15.503089 37.432541-15.503089 0.001023 0 0 0 0.001023 0 14.184047 0 27.490098 5.51869 37.46938 15.540951l28.039613 28.05087c6.557346 6.525624 20.500916 8.596795 28.655643 4.231371l0.893346-0.478907 57.375755-23.64963c8.836249-2.731204 16.634866-14.037714 16.634866-23.719214l0-39.632649c0-28.967752 24.777313-52.095495 54.624085-52.095495L545.784454 64.076364c29.161157 0 52.370765 22.636556 52.370765 52.095495l0 39.632649c0 9.127891 8.709359 20.85498 17.767666 23.674189l1.51654 0.577145 56.639998 23.113417 0.923022 0.509606c8.202822 4.424776 22.184255 2.353604 28.788673-4.254907l28.163433-27.912723c9.895371-9.94142 23.179932-15.33936 37.352723-15.33936 0.019443 0 0.040932 0 0.060375 0 14.18814 0 27.508517 5.375427 37.516452 15.384385l46.709835 46.554292c10.004865 9.960863 15.524578 23.254633 15.524578 37.47552 0 14.18814-5.498224 27.506471-15.479553 37.532825l-28.16855 28.152177c-6.580882 6.610558-8.640798 20.771069-4.204765 29.107945l0.478907 0.896416 23.654746 57.956993c2.902096 9.255805 14.635325 18.114566 23.686469 18.114566l39.132252 0 0-0.573051c27.629267 0 52.188616 22.984481 52.188616 52.327786l0 65.998133c0 29.590945-22.985504 53.138244-51.746548 53.138244l-39.630602 0c-9.337669 0-20.84884 8.372691-23.686469 17.423835l-0.580215 1.51654-23.086811 56.240909-0.468674 0.860601c-4.419659 8.30413-2.393513 22.320355 4.169973 28.855188l28.135804 28.02017c10.031471 10.029424 15.539928 23.350824 15.537881 37.541011-0.004093 14.186094-5.514597 27.505447-15.518438 37.505195l-46.747697 46.682205c-9.920954 9.964956-23.219841 15.506159-37.406958 15.506159-0.019443 0-0.040932 0-0.060375 0-14.192234 0-27.514657-5.514597-37.518498-15.517415l-28.039613-28.095895c-6.490831-6.490831-20.807908-8.575306-28.887934-4.206812l-0.951675 0.514723-57.93755 23.680329c-9.087982 2.859118-17.823947 14.594393-17.823947 23.691585l0 39.460734C598.155219 937.76394 574.45954 962.539206 545.784454 962.539206zM421.86719 806.892287c25.192775 8.370645 44.282552 34.650171 44.282552 61.570287l0 39.460734c0 7.114025 6.569626 13.68365 13.691837 13.68365L545.784454 921.606958c6.496971 0 12.461823-6.043646 12.461823-13.68365L558.246277 868.462574c0-26.273387 19.516496-53.131081 44.901653-61.58052l53.859675-22.062482c23.62814-12.116969 56.342216-7.098675 75.118861 11.6749l28.009937 28.1532c2.432399 2.430352 5.678326 3.837398 9.179057 3.837398 0.00614 0 0.011256 0 0.01535 0 3.482311 0 6.726192-1.39886 9.135054-3.820002l46.780443-46.738487c2.436492-2.436492 3.783163-5.724375 3.78521-9.224082 0-3.495614-1.344624-6.774287-3.787256-9.216919l-28.106128-27.998681c-18.693758-18.609847-23.762193-51.349505-11.773138-75.036997l22.083971-53.603849c8.374738-25.167193 35.224246-44.51382 61.578474-44.51382l39.630602 0c7.745405 0 10.8143-7.086395 10.8143-13.229303l0-65.998133c0-6.862291-5.116531-12.07399-11.256368-12.302187l0 1.479701-39.132252 0c-26.236548 0-53.099359-20.149922-61.585637-45.735647l-22.083971-54.261834c-11.960403-23.654746-6.913457-56.502875 11.728112-75.228355l28.16855-28.192086c2.430352-2.441609 3.78828-5.764284 3.78828-9.295714 0-3.498684-1.334391-6.762007-3.759627-9.17394l-46.741557-46.577828c-2.462075-2.462075-5.736655-3.734044-9.234315-3.734044-0.004093 0-0.010233 0-0.013303 0-3.465938 0-6.700609 1.255597-9.105379 3.671623l-28.198226 28.037567c-18.703991 18.710131-51.417043 23.734564-75.000158 11.69025l-53.865815-22.072715c-25.403576-8.388041-44.934398-35.255968-44.934398-61.60508l0-39.632649c0-7.253194-5.517667-12.186554-12.461823-12.186554l-65.943898 0c-7.517207 0-13.691837 5.51869-13.691837 12.186554l0 39.632649c0 27.027563-19.107173 53.336766-44.325531 61.643965l-53.501518 21.99699c-23.834848 12.168134-55.857169 7.234775-74.878384-11.69639l-28.130687-28.115338c-2.441609-2.451842-5.690606-3.787256-9.152451-3.787256-3.462868-0.001023-6.704702 1.334391-9.117658 3.758604l-46.690392 46.64639c-2.438539 2.438539-3.784186 5.710049-3.781116 9.207709 0.004093 3.474125 1.339508 6.716982 3.762697 9.128915l28.068266 28.121478c18.698874 18.690688 23.782659 51.389414 11.808954 74.973552l-22.124903 54.813397c-8.413624 25.616424-35.281551 45.783743-61.603033 45.783743l-39.575344 0c-6.630001 0-13.010315 3.411703-13.010315 10.822486l0 65.943898c0 6.942109 5.753027 13.284561 12.95301 13.284561l39.631626 0c26.380834 0 53.195549 19.35072 61.524239 44.537356l22.182208 53.629431c12.027941 23.731494 6.918573 56.449663-11.863189 75.05644l-28.022217 27.949562c-5.021364 5.066389-5.048993 13.348006 0.010233 18.409279l46.713928 46.653553c2.452865 2.464121 5.695722 3.794419 9.168824 3.794419 3.472078 0 6.711865-1.336438 9.124821-3.759627l28.181853-28.122501c18.641569-18.730597 51.440579-23.752983 75.011414-11.642155L421.86719 806.892287z" fill="#272636" ></path><path d="M513.734504 731.880873c-120.639614 0-218.786958-98.147344-218.786958-218.786958s98.147344-218.786958 218.786958-218.786958 218.786958 98.147344 218.786958 218.786958S634.375142 731.880873 513.734504 731.880873zM513.734504 334.324368c-98.573039 0-178.769546 80.195483-178.769546 178.769546s80.195483 178.769546 178.769546 178.769546 178.769546-80.195483 178.769546-178.769546S612.308567 334.324368 513.734504 334.324368z" fill="#272636" ></path></symbol><symbol id="icon-yonghu" viewBox="0 0 1024 1024"><path d="M500 128.8c-95.2 5.6-173.6 83.2-180 178.4-7.2 112 80.8 205.6 191.2 205.6 106.4 0 192-86.4 192-192 0.8-110.4-92-198.4-203.2-192zM512 575.2c-128 0-383.2 64-383.2 192v96c0 17.6 14.4 32 32 32h702.4c17.6 0 32-14.4 32-32V766.4c0-127.2-255.2-191.2-383.2-191.2z" ></path></symbol><symbol id="icon-xiangmu" viewBox="0 0 1024 1024"><path d="M410.67 544H133.33A69.33 69.33 0 0 0 64 613.33v277.34A69.33 69.33 0 0 0 133.33 960h277.34A69.33 69.33 0 0 0 480 890.67V613.33A69.33 69.33 0 0 0 410.67 544zM402 842a40 40 0 0 1-40 40H182a40 40 0 0 1-40-40V662a40 40 0 0 1 40-40h180a40 40 0 0 1 40 40zM890.67 544H613.33A69.33 69.33 0 0 0 544 613.33v277.34A69.33 69.33 0 0 0 613.33 960h277.34A69.33 69.33 0 0 0 960 890.67V613.33A69.33 69.33 0 0 0 890.67 544zM882 842a40 40 0 0 1-40 40H662a40 40 0 0 1-40-40V662a40 40 0 0 1 40-40h180a40 40 0 0 1 40 40zM410.67 64H133.33A69.33 69.33 0 0 0 64 133.33v277.34A69.33 69.33 0 0 0 133.33 480h277.34A69.33 69.33 0 0 0 480 410.67V133.33A69.33 69.33 0 0 0 410.67 64zM402 362a40 40 0 0 1-40 40H182a40 40 0 0 1-40-40V182a40 40 0 0 1 40-40h180a40 40 0 0 1 40 40zM694.49 456.18a81.35 81.35 0 0 0 115 0l126.69-126.67a81.35 81.35 0 0 0 0-115L809.51 87.82a81.35 81.35 0 0 0-115 0L567.82 214.49a81.35 81.35 0 0 0 0 115z" fill="#999999" ></path></symbol><symbol id="icon-quanxian" viewBox="0 0 1024 1024"><path d="M898.34 188.81L538.35 74.51l-359.87 114.3c-13.53 4.27-22.67 16.86-22.55 31.1v454.94c0.72 3.09 17.69 77.98 91.27 150.5 56.61 55.78 192.4 127.48 251.63 158.57 9.25 4.87 13.65 6.65 17.56 8.78l17.57 8.78c4.63 2.49 12.94 2.38 17.57 0l17.57-8.78c34.65-16.97 195-102.9 260.4-167.35 73.71-72.52 90.68-147.41 91.39-150.5V219.91c0.23-14.24-9.02-26.83-22.55-31.1zM542.86 930.98l-0.24-0.12h0.59c-0.23 0.12-0.35 0.12-0.35 0.12z m85.81-264.32h-58.16v81.9c0 18.99-15.43 34.42-34.42 34.42-18.99 0-34.42-15.43-34.42-34.42V537.29c0-0.71 0.12-1.3 0.12-1.9-6.29-1.9-12.58-4.16-18.87-7-21.24-9.73-39.4-27.18-51.51-47-12.58-20.65-19.23-46.53-17.21-70.74 2.37-27.65 12.34-51.75 30.03-73.23 30.62-37.15 86.88-52.22 131.98-35.73 25.52 9.38 46.29 25.05 61.96 47.12 13.77 19.35 20.77 43.44 21.37 67.06 0 0.71 0.12 1.3 0 2.02 0 0.83 0 1.66-0.12 2.49-1.66 52.46-37.74 101.95-89.02 115.61v60.41h58.16c18.99 0 34.42 15.43 34.42 34.42v1.42h0.12c-0.01 18.99-15.44 34.42-34.43 34.42z" fill="#040000" ></path><path d="M577.99 449.1c0.35-0.59 0.71-1.07 0.83-1.19a97.38 97.38 0 0 0 5.58-9.74c1.54-4.39 2.73-8.78 3.68-13.41 0.12-2.25 0.24-4.63 0.36-6.89 0-2.26-0.12-4.63-0.36-6.88-0.83-4.51-2.14-9.02-3.68-13.41a108.73 108.73 0 0 0-4.51-8.19c-0.36-0.36-1.19-1.54-2.61-3.8-1.3-1.43-2.61-2.97-4.03-4.27-1.66-1.66-3.44-3.32-5.34-4.87-0.59-0.35-1.06-0.71-1.19-0.83a97.226 97.226 0 0 0-9.73-5.58c-4.39-1.54-8.78-2.73-13.29-3.68-4.63-0.35-9.26-0.35-13.89 0-4.51 0.83-9.02 2.14-13.29 3.68a108.73 108.73 0 0 0-8.19 4.51c-0.36 0.36-1.54 1.19-3.8 2.61-1.43 1.3-2.97 2.61-4.27 4.03-1.66 1.66-3.32 3.44-4.87 5.34-0.35 0.59-0.71 1.07-0.83 1.19a97.226 97.226 0 0 0-5.58 9.73c-1.54 4.39-2.73 8.78-3.68 13.29-0.35 4.63-0.35 9.26 0 13.89 0.83 4.51 2.14 9.02 3.68 13.29 1.42 2.85 2.85 5.46 4.51 8.19 0.36 0.36 1.19 1.54 2.61 3.8 1.3 1.43 2.61 2.97 4.03 4.27 1.66 1.66 3.44 3.32 5.34 4.87 0.59 0.35 1.07 0.71 1.19 0.83 3.08 2.02 6.41 3.92 9.73 5.58 4.39 1.54 8.78 2.73 13.29 3.68 4.63 0.36 9.26 0.36 13.89 0 4.51-0.83 9.02-2.14 13.29-3.68 2.85-1.42 5.46-2.85 8.19-4.51 0.36-0.36 1.54-1.19 3.8-2.61 1.54-1.19 2.97-2.49 4.27-3.92 1.67-1.64 3.33-3.42 4.87-5.32z" fill="#040000" ></path></symbol></svg>',function(l){var c=(c=document.getElementsByTagName("script"))[c.length-1],t=c.getAttribute("data-injectcss"),c=c.getAttribute("data-disable-injectsvg");if(!c){var e,n,i,o,a,d=function(c,t){t.parentNode.insertBefore(c,t)};if(t&&!l.__iconfont__svg__cssinject__){l.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(c){console&&console.log(c)}}e=function(){var c,t=document.createElement("div");t.innerHTML=l._iconfont_svg_string_4347154,(t=t.getElementsByTagName("svg")[0])&&(t.setAttribute("aria-hidden","true"),t.style.position="absolute",t.style.width=0,t.style.height=0,t.style.overflow="hidden",t=t,(c=document.body).firstChild?d(t,c.firstChild):c.appendChild(t))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(e,0):(n=function(){document.removeEventListener("DOMContentLoaded",n,!1),e()},document.addEventListener("DOMContentLoaded",n,!1)):document.attachEvent&&(i=e,o=l.document,a=!1,h(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,s())})}function s(){a||(a=!0,i())}function h(){try{o.documentElement.doScroll("left")}catch(c){return void setTimeout(h,50)}s()}}(window);
\ No newline at end of file
import React from 'react';
import { createFromIconfontCN } from '@ant-design/icons';
import '@/common/iconfont/iconfont.js';
const IconFont = createFromIconfontCN({
scriptUrl: [],
});
const CreateIcon = (props) => {
const { type, style = { color: "#000", fontSize: 16 } } = props;
return <IconFont type={`icon-${type}`} style={style} />
}
export default CreateIcon;
\ No newline at end of file
import React from 'react';
const NotFound = () => {
return <div>404 Not Found</div>;
};
export default NotFound;
import React from 'react';
import { Button, Result } from 'antd';
import { useNavigate } from 'react-router-dom'
const NotFound = () => {
const navigate = useNavigate();
const backHome = () => {
navigate('/');
}
return (
<Result
status="error"
title="NO Permission"
subTitle="没有权限"
extra={<Button type="primary" onClick={ backHome }>回首页</Button>}
/>
);
};
export default NotFound;
...@@ -15,7 +15,6 @@ const auth_key = 'f3846153ba784b6d86bdcd5533259c88'; ...@@ -15,7 +15,6 @@ const auth_key = 'f3846153ba784b6d86bdcd5533259c88';
const auth_secret = 'HO4IyLEwEOHpeOXBxaLQUOqWslJRGs1M'; const auth_secret = 'HO4IyLEwEOHpeOXBxaLQUOqWslJRGs1M';
const AIDrawerComponent = (props) => { const AIDrawerComponent = (props) => {
const { selectText } = props; const { selectText } = props;
const dispatch = useDispatch(); const dispatch = useDispatch();
const { userInfo } = useSelector((state) => state.user); // 用户状态信息 const { userInfo } = useSelector((state) => state.user); // 用户状态信息
...@@ -25,14 +24,14 @@ const AIDrawerComponent = (props) => { ...@@ -25,14 +24,14 @@ const AIDrawerComponent = (props) => {
const [loading, setLoading] = useState(false); // loading const [loading, setLoading] = useState(false); // loading
const [chatId, setChatId] = useState(null); // 对话的id const [chatId, setChatId] = useState(null); // 对话的id
const [chatContentList, setChatContentList] = useState([]); // 对话数据 const [chatContentList, setChatContentList] = useState([]); // 对话数据
const element = document.querySelector("#chat-content"); const element = document.querySelector('#chat-content');
let str = ''; let str = '';
useEffect(() => { useEffect(() => {
if (editorAi && Object.entries(editorAi).length > 0) { if (editorAi && Object.entries(editorAi).length > 0) {
let tempJSON = JSON.parse(JSON.stringify(chatContentList)); let tempJSON = JSON.parse(JSON.stringify(chatContentList));
let conversationId = editorAi.conversationId; let conversationId = editorAi.conversationId;
const item = tempJSON.filter(item => item.conversationId === conversationId); const item = tempJSON.filter((item) => item.conversationId === conversationId);
if (item && item.length > 0) { if (item && item.length > 0) {
tempJSON[tempJSON.length - 1] = editorAi; tempJSON[tempJSON.length - 1] = editorAi;
} else { } else {
...@@ -44,7 +43,7 @@ const AIDrawerComponent = (props) => { ...@@ -44,7 +43,7 @@ const AIDrawerComponent = (props) => {
} else { } else {
setLoading(false); setLoading(false);
} }
}, [editorAi]) }, [editorAi]);
useEffect(() => { useEffect(() => {
if (selectText) { if (selectText) {
...@@ -55,7 +54,7 @@ const AIDrawerComponent = (props) => { ...@@ -55,7 +54,7 @@ const AIDrawerComponent = (props) => {
setValue(''); setValue('');
setChatContentList([]); setChatContentList([]);
setChatId(null); setChatId(null);
} };
}, []); }, []);
let cData = []; let cData = [];
...@@ -72,7 +71,7 @@ const AIDrawerComponent = (props) => { ...@@ -72,7 +71,7 @@ const AIDrawerComponent = (props) => {
processBuffer(buffer); processBuffer(buffer);
return; return;
} }
await sleep(80) await sleep(80);
buffer += decoder.decode(value, { stream: true }); buffer += decoder.decode(value, { stream: true });
// 检查缓冲区中是否有完整的消息 // 检查缓冲区中是否有完整的消息
const messages = buffer.split('\n\n'); // 假设每个消息以换行符结束 const messages = buffer.split('\n\n'); // 假设每个消息以换行符结束
...@@ -84,7 +83,7 @@ const AIDrawerComponent = (props) => { ...@@ -84,7 +83,7 @@ const AIDrawerComponent = (props) => {
buffer = messages[messages.length - 1]; // 更新缓冲区 buffer = messages[messages.length - 1]; // 更新缓冲区
readBuffer(reader, decoder); readBuffer(reader, decoder);
}); });
} };
const processBuffer = (text) => { const processBuffer = (text) => {
let aiContent = {}; let aiContent = {};
...@@ -100,15 +99,13 @@ const AIDrawerComponent = (props) => { ...@@ -100,15 +99,13 @@ const AIDrawerComponent = (props) => {
chatId: itemContent.chatId, chatId: itemContent.chatId,
avatar: itemContent.role.avatar, avatar: itemContent.role.avatar,
conversationId: itemContent.conversationId, conversationId: itemContent.conversationId,
} };
dispatch(setEditorAi(aiContent)); dispatch(setEditorAi(aiContent));
} }
} }
} catch { } catch {}
};
}
}
// 提交对话 // 提交对话
const targetChat = async () => { const targetChat = async () => {
if (value) { if (value) {
...@@ -116,39 +113,41 @@ const AIDrawerComponent = (props) => { ...@@ -116,39 +113,41 @@ const AIDrawerComponent = (props) => {
const timestamp = Date.now(); const timestamp = Date.now();
fetch('/openapi/agent/chat/stream/v1', { fetch('/openapi/agent/chat/stream/v1', {
method: 'POST', method: 'POST',
responseType: 'stream', // 设置响应类型为 'stream' responseType: 'stream', // 设置响应类型为 'stream'
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
authKey: auth_key, authKey: auth_key,
timestamp: timestamp, timestamp: timestamp,
sign: md5(`${auth_key}${auth_secret}${timestamp}`), sign: md5(`${auth_key}${auth_secret}${timestamp}`),
'Content-Type': 'application/json', stream: true, // or change to "false" 不处理流式返回内容
"stream": true // or change to "false" 不处理流式返回内容 },
}, body: JSON.stringify({
body: JSON.stringify({ agentId: UUID,
agentId: UUID, chatId: chatId,
chatId: chatId, userChatInput: value,
userChatInput: value, }),
}), mode: 'cors',
mode: 'cors', })
}).then(response => { .then((response) => {
// response.body 是一个 ReadableStream 对象 // response.body 是一个 ReadableStream 对象
const stream = response.body; const stream = response.body;
// 使用流式数据 // 使用流式数据
const reader = stream.getReader(); const reader = stream.getReader();
const decoder = new TextDecoder(); // 用于解码二进制数据流 const decoder = new TextDecoder(); // 用于解码二进制数据流
let userContent = { let userContent = {
type: 'user', content: value, time: Date.now() type: 'user',
content: value,
time: Date.now(),
}; };
let tempJSON = JSON.parse(JSON.stringify(chatContentList)); let tempJSON = JSON.parse(JSON.stringify(chatContentList));
tempJSON.push(userContent) tempJSON.push(userContent);
setChatContentList(tempJSON); setChatContentList(tempJSON);
// 开始读取流数据 // 开始读取流数据
readBuffer(reader, decoder); readBuffer(reader, decoder);
})
}).catch(error => { .catch((error) => {
// 处理请求错误 // 处理请求错误
console.error('Request failed:', error); console.error('Request failed:', error);
}); });
...@@ -156,12 +155,11 @@ const AIDrawerComponent = (props) => { ...@@ -156,12 +155,11 @@ const AIDrawerComponent = (props) => {
message.error('请输入对话内容!'); message.error('请输入对话内容!');
} }
}; };
return ( return (
<div className='ai-drawer-content'> <div className='ai-drawer-content'>
<div className='ai-chat-container'> <div className='ai-chat-container'>
<div className='chat-content' id="chat-content"> <div className='chat-content' id='chat-content'>
<div className='chat-content-padd'> <div className='chat-content-padd'>
{chatContentList && {chatContentList &&
chatContentList.length > 0 && chatContentList.length > 0 &&
...@@ -175,7 +173,7 @@ const AIDrawerComponent = (props) => { ...@@ -175,7 +173,7 @@ const AIDrawerComponent = (props) => {
<div className='inside'> <div className='inside'>
<div className='ai-in-content'> <div className='ai-in-content'>
<div className='img'> <div className='img'>
<img src={item.avatar} alt="" /> <img src={item.avatar} alt='' />
</div> </div>
<div className='ask-content'>{item.content}</div> <div className='ask-content'>{item.content}</div>
</div> </div>
......
...@@ -21,7 +21,7 @@ class ExpandArticleAuto { ...@@ -21,7 +21,7 @@ class ExpandArticleAuto {
return false; // or true return false; // or true
} }
isDisabled(editor) { isDisabled(editor) {
return true; // or true return false; // or true
} }
exec(editor, value) { exec(editor, value) {
// editor.insertText(value) // value 即 this.getValue(editor) 的返回值 // editor.insertText(value) // value 即 this.getValue(editor) 的返回值
......
// Extend menu // Extend menu
class PolishingAuto { class PolishingAuto {
constructor() { constructor() {
this.title = '润色'; this.title = '缩写';
this.iconSvg = `<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> this.iconSvg = `<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>图标</title> <title>图标</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="图标" transform="translate(-536, -221)" fill="#333333" fill-rule="nonzero"> <g id="图标" transform="translate(-536, -221)" fill="#333333" fill-rule="nonzero">
<g id="润色-(1)" transform="translate(536, 221)"> <g id="缩写-(1)" transform="translate(536, 221)">
<path d="M1.95471575,0 L44.9584623,0 C46.2616061,0 46.913178,0.678713837 46.913178,2.03614151 L46.913178,2.03614151 C46.913178,3.39356919 46.2616061,4.07228302 44.9584623,4.07228302 L1.95471575,4.07228302 C0.651571917,4.07228302 0,3.39356919 0,2.03614151 L0,2.03614151 C0,0.678713837 0.651571917,0 1.95471575,0 Z" id="路径"></path> <path d="M1.95471575,0 L44.9584623,0 C46.2616061,0 46.913178,0.678713837 46.913178,2.03614151 L46.913178,2.03614151 C46.913178,3.39356919 46.2616061,4.07228302 44.9584623,4.07228302 L1.95471575,4.07228302 C0.651571917,4.07228302 0,3.39356919 0,2.03614151 L0,2.03614151 C0,0.678713837 0.651571917,0 1.95471575,0 Z" id="路径"></path>
<path d="M1.95471575,12.2168491 L29.3207363,12.2168491 C30.6238801,12.2168491 31.275452,12.8955629 31.275452,14.2529906 L31.275452,14.2529906 C31.275452,15.6104183 30.6238801,16.2891321 29.3207363,16.2891321 L1.95471575,16.2891321 C0.651571917,16.2891321 0,15.6104183 0,14.2529906 L0,14.2529906 C0,12.8955629 0.651571917,12.2168491 1.95471575,12.2168491 Z" id="路径"></path> <path d="M1.95471575,12.2168491 L29.3207363,12.2168491 C30.6238801,12.2168491 31.275452,12.8955629 31.275452,14.2529906 L31.275452,14.2529906 C31.275452,15.6104183 30.6238801,16.2891321 29.3207363,16.2891321 L1.95471575,16.2891321 C0.651571917,16.2891321 0,15.6104183 0,14.2529906 L0,14.2529906 C0,12.8955629 0.651571917,12.2168491 1.95471575,12.2168491 Z" id="路径"></path>
<path d="M1.95471575,24.4336981 L17.5924418,24.4336981 C18.8955856,24.4336981 19.5471575,25.112412 19.5471575,26.4698397 L19.5471575,26.4698397 C19.5471575,27.8272673 18.8955856,28.5059812 17.5924418,28.5059812 L1.95471575,28.5059812 C0.651571917,28.5059812 0,27.8272673 0,26.4698397 L0,26.4698397 C0,25.112412 0.651571917,24.4336981 1.95471575,24.4336981 Z" id="路径"></path> <path d="M1.95471575,24.4336981 L17.5924418,24.4336981 C18.8955856,24.4336981 19.5471575,25.112412 19.5471575,26.4698397 L19.5471575,26.4698397 C19.5471575,27.8272673 18.8955856,28.5059812 17.5924418,28.5059812 L1.95471575,28.5059812 C0.651571917,28.5059812 0,27.8272673 0,26.4698397 L0,26.4698397 C0,25.112412 0.651571917,24.4336981 1.95471575,24.4336981 Z" id="路径"></path>
...@@ -18,13 +18,13 @@ class PolishingAuto { ...@@ -18,13 +18,13 @@ class PolishingAuto {
this.tag = 'button'; this.tag = 'button';
} }
getValue(editor) { getValue(editor) {
return 'hello, 润色'; return 'hello, 缩写';
} }
isActive(editor) { isActive(editor) {
return false; // or true return false; // or true
} }
isDisabled(editor) { isDisabled(editor) {
return true; // or true return false; // or true
} }
exec(editor, value) { exec(editor, value) {
// editor.insertText(value) // value 即 this.getValue(editor) 的返回值 // editor.insertText(value) // value 即 this.getValue(editor) 的返回值
......
...@@ -3,7 +3,6 @@ class RewriteAuto { ...@@ -3,7 +3,6 @@ class RewriteAuto {
constructor() { constructor() {
this.title = '改写'; this.title = '改写';
this.iconSvg = `<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> this.iconSvg = `<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>图标</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="图标" transform="translate(-731, -218)" fill="#333333" fill-rule="nonzero"> <g id="图标" transform="translate(-731, -218)" fill="#333333" fill-rule="nonzero">
<g id="文稿改写" transform="translate(730.8462, 217.8462)"> <g id="文稿改写" transform="translate(730.8462, 217.8462)">
...@@ -22,7 +21,7 @@ class RewriteAuto { ...@@ -22,7 +21,7 @@ class RewriteAuto {
return false; // or true return false; // or true
} }
isDisabled(editor) { isDisabled(editor) {
return true; // or true return false; // or true
} }
exec(editor, value) { exec(editor, value) {
// editor.insertText(value) // value 即 this.getValue(editor) 的返回值 // editor.insertText(value) // value 即 this.getValue(editor) 的返回值
......
...@@ -23,7 +23,7 @@ class SummaryAuto { ...@@ -23,7 +23,7 @@ class SummaryAuto {
return false; // or true return false; // or true
} }
isDisabled(editor) { isDisabled(editor) {
return true; // or true return false; // or true
} }
exec(editor, value) { exec(editor, value) {
// editor.insertText(value) // value 即 this.getValue(editor) 的返回值 // editor.insertText(value) // value 即 this.getValue(editor) 的返回值
......
import { useEffect, useState } from 'react';
import { Modal, Input, Button, Flex, Spin } from 'antd';
import { useAIEdit } from '@/hooks/useAI';
const { TextArea } = Input;
const actionMap = {
rewrite: '改写',
expand: '扩写',
abbreviate: '缩写',
summary: '总结',
};
export default function AIWrite({ editor, docAction, ...rest }) {
const [content, setContent] = useState('');
const { text, fetch, isLoading } = useAIEdit();
const actionText = actionMap[docAction];
const [selectionText, setSelectionText] = useState('');
useEffect(() => {
if (rest.open) {
const selection = editor.getSelectionText();
if (selection) {
setSelectionText(selection);
setContent(selection);
fetch({ content: selection, doc_action: docAction, full_text: false });
}
}
}, [rest.open]);
useEffect(() => {
setContent(text);
}, [text]);
const handleFetch = () => {
fetch({ content: selectionText, doc_action: docAction, full_text: false });
};
const handlePrimary = () => {
editor.restoreSelection();
editor.insertText(text);
rest.onCancel();
};
return (
<Modal
title={`以下是AI${actionText}结果:`}
{...rest}
footer={null}
classNames={{
header: 'editor-header-customer',
body: 'editor-body-customer',
wrapper: 'editor-wrapper-customer',
}}
>
<Spin spinning={isLoading}>
<TextArea
autoSize={{ minRows: 4 }}
value={content}
onChange={(e) => setContent(e.target.value)}
/>
</Spin>
<br />
<Flex gap='small' justify='center'>
<Button type='primary' onClick={handlePrimary}>
替换内容
</Button>
<Button type='primary' onClick={handleFetch}>
重新{actionText}
</Button>
<Button type='primary' onClick={rest.onCancel}>
取消
</Button>
</Flex>
</Modal>
);
}
...@@ -53,6 +53,7 @@ import TooltipModal from './components/tooltip'; ...@@ -53,6 +53,7 @@ import TooltipModal from './components/tooltip';
import LinkModal from './components/link'; import LinkModal from './components/link';
import ExpandModal from './components/expand'; import ExpandModal from './components/expand';
import AIDrawerComponent from './ai-drawer/index'; import AIDrawerComponent from './ai-drawer/index';
import AIWrite from './components/aiWrite';
import chapterSectionModule from './node/chapterItem'; import chapterSectionModule from './node/chapterItem';
import chapterHeaderModule from './node/chapterTitle'; import chapterHeaderModule from './node/chapterTitle';
...@@ -90,7 +91,7 @@ const menuArr0 = ['重做', '撤销']; ...@@ -90,7 +91,7 @@ const menuArr0 = ['重做', '撤销'];
const menuArr1 = ['字体样式', '字号', '行高']; const menuArr1 = ['字体样式', '字号', '行高'];
const menuArr2 = ['图片', '画廊', '视频', '音频', '表格']; const menuArr2 = ['图片', '画廊', '视频', '音频', '表格'];
const menuArr3 = ['代码块', '引用', '链接', '公式', '章头', '节头', '交互练习', '气泡', '扩展阅读']; const menuArr3 = ['代码块', '引用', '链接', '公式', '章头', '节头', '交互练习', '气泡', '扩展阅读'];
const menuArr4 = ['润色', '扩写', '改写', '总结']; const menuArr4 = ['改写', '扩写', '缩写', '总结'];
const colorList = ['#ab1941', '#2970f6', '#2ad882', '#eb3351']; const colorList = ['#ab1941', '#2970f6', '#2ad882', '#eb3351'];
const bookBucketName = 'zxts-book-file'; const bookBucketName = 'zxts-book-file';
...@@ -394,9 +395,9 @@ const WangEditorCustomer = forwardRef((props, ref) => { ...@@ -394,9 +395,9 @@ const WangEditorCustomer = forwardRef((props, ref) => {
'Practice', 'Practice',
'TooltipAuto', 'TooltipAuto',
'ExpandRead', 'ExpandRead',
'PolishingAuto',
'ExpandArticleAuto',
'RewriteAuto', 'RewriteAuto',
'ExpandArticleAuto',
'PolishingAuto',
'SummaryAuto', 'SummaryAuto',
], ],
}; };
...@@ -433,7 +434,7 @@ const WangEditorCustomer = forwardRef((props, ref) => { ...@@ -433,7 +434,7 @@ const WangEditorCustomer = forwardRef((props, ref) => {
'color', 'color',
'bgColor', 'bgColor',
'clearStyle', 'clearStyle',
'AISelectTextAuto' 'AISelectTextAuto',
], ],
}, },
image: { image: {
...@@ -491,7 +492,6 @@ const WangEditorCustomer = forwardRef((props, ref) => { ...@@ -491,7 +492,6 @@ const WangEditorCustomer = forwardRef((props, ref) => {
setTimeout(() => { setTimeout(() => {
const toolbarElement = toolbarRef.current && toolbarRef.current.children[0].children[0]; const toolbarElement = toolbarRef.current && toolbarRef.current.children[0].children[0];
const allChildren = toolbarElement.children; const allChildren = toolbarElement.children;
const oHDiv_1 = document.createElement('div'); const oHDiv_1 = document.createElement('div');
oHDiv_1.setAttribute('class', 'custom-bar-box two'); oHDiv_1.setAttribute('class', 'custom-bar-box two');
toolbarElement.insertBefore(oHDiv_1, allChildren[0]); toolbarElement.insertBefore(oHDiv_1, allChildren[0]);
...@@ -502,7 +502,6 @@ const WangEditorCustomer = forwardRef((props, ref) => { ...@@ -502,7 +502,6 @@ const WangEditorCustomer = forwardRef((props, ref) => {
oH6_1.setAttribute('class', 'w-auto type-heading'); oH6_1.setAttribute('class', 'w-auto type-heading');
oH6_1.innerHTML = '常用格式'; oH6_1.innerHTML = '常用格式';
toolbarElement.insertBefore(oH6_1, allChildren[2]); toolbarElement.insertBefore(oH6_1, allChildren[2]);
// 行高字体字号设置 // 行高字体字号设置
const itemBox = '<div class="custom-bar-box two"></div>'; const itemBox = '<div class="custom-bar-box two"></div>';
$(itemBox).insertBefore($(allChildren[3])); $(itemBox).insertBefore($(allChildren[3]));
...@@ -737,6 +736,39 @@ const WangEditorCustomer = forwardRef((props, ref) => { ...@@ -737,6 +736,39 @@ const WangEditorCustomer = forwardRef((props, ref) => {
} }
setExpandVisible(true); setExpandVisible(true);
}); });
// 改写
editor.on('RewriteMenuClick', () => {
if (editor.selection) {
listenNodeStyle(editor.selection.anchor.path);
}
setAiWriteOpen(true);
setAiWriteAction('rewrite');
});
// 扩写
editor.on('ExpandArticleMenuClick', () => {
if (editor.selection) {
listenNodeStyle(editor.selection.anchor.path);
}
setAiWriteOpen(true);
setAiWriteAction('expand');
});
// 缩写
editor.on('PolishingMenuClick', () => {
if (editor.selection) {
listenNodeStyle(editor.selection.anchor.path);
}
setAiWriteOpen(true);
setAiWriteAction('abbreviate');
});
// 总结
editor.on('SummaryMenuClick', () => {
if (editor.selection) {
listenNodeStyle(editor.selection.anchor.path);
}
setAiWriteOpen(true);
setAiWriteAction('summary');
});
// ai对话 // ai对话
editor.on('AISelectTextClick', () => { editor.on('AISelectTextClick', () => {
setSelectText(editor.getSelectionText()); setSelectText(editor.getSelectionText());
...@@ -880,6 +912,8 @@ const WangEditorCustomer = forwardRef((props, ref) => { ...@@ -880,6 +912,8 @@ const WangEditorCustomer = forwardRef((props, ref) => {
}); });
}; };
const [aiWriteOpen, setAiWriteOpen] = useState(false);
const [aiWriteAction, setAiWriteAction] = useState('rewrite');
return ( return (
<div className='wangeditor-customer-container'> <div className='wangeditor-customer-container'>
<div className='editor-content-container'> <div className='editor-content-container'>
...@@ -909,12 +943,20 @@ const WangEditorCustomer = forwardRef((props, ref) => { ...@@ -909,12 +943,20 @@ const WangEditorCustomer = forwardRef((props, ref) => {
> >
保存 保存
</Button> </Button>
<Button icon={<EyeOutlined />} className='history' onClick={previewIt} <Button
disabled={bookId && contentId ? false : true}> icon={<EyeOutlined />}
className='history'
onClick={previewIt}
disabled={bookId && contentId ? false : true}
>
预览 预览
</Button> </Button>
<Button icon={<HistoryOutlined />} className='history' onClick={historyIt} <Button
disabled={bookId && contentId ? false : true}> icon={<HistoryOutlined />}
className='history'
onClick={historyIt}
disabled={bookId && contentId ? false : true}
>
历史 历史
</Button> </Button>
</Space> </Space>
...@@ -1299,17 +1341,25 @@ const WangEditorCustomer = forwardRef((props, ref) => { ...@@ -1299,17 +1341,25 @@ const WangEditorCustomer = forwardRef((props, ref) => {
</Modal> </Modal>
{/* ai对话 */} {/* ai对话 */}
<Drawer <Drawer
open={aiVisible} open={aiVisible}
width="600px" width='600px'
title="AI对话" title='AI对话'
destroyOnClose destroyOnClose
onClose={() => setAIVisible(false)} onClose={() => setAIVisible(false)}
rootClassName="ai-drawer-wrapper" rootClassName='ai-drawer-wrapper'
className="ai-drawer-container" className='ai-drawer-container'
> >
<AIDrawerComponent setAIVisible={setAIVisible} selectText={selectText} /> <AIDrawerComponent setAIVisible={setAIVisible} selectText={selectText} />
</Drawer> </Drawer>
<AIWrite
open={aiWriteOpen}
docAction={aiWriteAction}
onCancel={() => setAiWriteOpen(false)}
editor={editor}
chapterId={chapterId}
bookId={bookId}
></AIWrite>
</div> </div>
); );
}); });
......
import { useRef, useState, useEffect } from 'react'; import { useRef, useState } from 'react';
const useWebsocket = ({}) => { const useWebsocket = ({}) => {
const ws = useRef(); const ws = useRef();
...@@ -6,7 +6,7 @@ const useWebsocket = ({}) => { ...@@ -6,7 +6,7 @@ const useWebsocket = ({}) => {
const [wsMessage, setWsMessage] = useState({}); const [wsMessage, setWsMessage] = useState({});
const [wsReadyState, setWsReadyState] = useState({ key: 0, value: '正在连接中' }); const [wsReadyState, setWsReadyState] = useState({ key: 0, value: '正在连接中' });
const creatWebSocket = (url) => { const createWebSocket = (url) => {
const stateArr = [ const stateArr = [
{ key: 0, value: '正在连接中' }, { key: 0, value: '正在连接中' },
{ key: 1, value: '已经连接并且可以通讯' }, { key: 1, value: '已经连接并且可以通讯' },
...@@ -17,15 +17,15 @@ const useWebsocket = ({}) => { ...@@ -17,15 +17,15 @@ const useWebsocket = ({}) => {
try { try {
ws.current = new WebSocket(url); ws.current = new WebSocket(url);
ws.current.onopen = () => { ws.current.onopen = () => {
console.log('webcocket open'); console.log('websocket open');
setWsReadyState(stateArr[ws.current?.readyState ?? 0]); setWsReadyState(stateArr[ws.current?.readyState ?? 0]);
}; };
ws.current.onclose = () => { ws.current.onclose = () => {
console.log('webcocket close'); console.log('websocket close');
setWsReadyState(stateArr[ws.current?.readyState ?? 0]); setWsReadyState(stateArr[ws.current?.readyState ?? 0]);
}; };
ws.current.onerror = () => { ws.current.onerror = () => {
console.log('webcocket error'); console.log('websocket error');
setWsReadyState(stateArr[ws.current?.readyState ?? 0]); setWsReadyState(stateArr[ws.current?.readyState ?? 0]);
}; };
ws.current.onmessage = (e) => { ws.current.onmessage = (e) => {
...@@ -39,7 +39,7 @@ const useWebsocket = ({}) => { ...@@ -39,7 +39,7 @@ const useWebsocket = ({}) => {
const webSocketInit = (url) => { const webSocketInit = (url) => {
if (!ws.current || ws.current.readyState === 3) { if (!ws.current || ws.current.readyState === 3) {
creatWebSocket(url); createWebSocket(url);
} }
}; };
...@@ -58,19 +58,19 @@ const useWebsocket = ({}) => { ...@@ -58,19 +58,19 @@ const useWebsocket = ({}) => {
try { try {
closeWebSocket(); closeWebSocket();
ws.current = null; ws.current = null;
creatWebSocket(); createWebSocket();
} catch (e) { } catch (e) {
console.log(e); console.log(e);
} }
}; };
// useEffect(() => { // useEffect(() => {
// webSocketInit(); // webSocketInit();
// return () => { // return () => {
// ws.current?.close(1000); // ws.current?.close(1000);
// }; // };
// }, [ws]); // }, [ws]);
return { return {
webSocketInit, webSocketInit,
...@@ -83,4 +83,4 @@ const useWebsocket = ({}) => { ...@@ -83,4 +83,4 @@ const useWebsocket = ({}) => {
}; };
}; };
export default useWebsocket; export default useWebsocket;
\ No newline at end of file
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import React, { useState, useEffect } from 'react';
import { Editor, Toolbar } from '@wangeditor/editor-for-react';
function MyEditor() {
// editor 实例
const [editor, setEditor] = useState(null); // JS 语法
// 编辑器内容
const [html, setHtml] = useState('<p>hello</p>');
// 模拟 ajax 请求,异步设置 html
useEffect(() => {
setTimeout(() => {
setHtml('<p>hello world</p>');
}, 1500);
}, []);
// 工具栏配置
const toolbarConfig = {};
// 编辑器配置
const editorConfig = {
placeholder: '请输入内容...',
};
useEffect(() => {
return () => {
if (editor === null) return;
editor.destroy();
setEditor(null);
};
}, [editor]);
return (
<>
<div style={{ border: '1px solid #ccc', zIndex: 100 }}>
<Toolbar
editor={editor}
defaultConfig={toolbarConfig}
mode='default'
style={{ borderBottom: '1px solid #ccc' }}
/>
<Editor
defaultConfig={editorConfig}
value={html}
onCreated={setEditor}
onChange={(editor) => setHtml(editor.getHtml())}
mode='default'
style={{ height: '500px', overflowY: 'hidden' }}
/>
</div>
<div style={{ marginTop: '15px' }}>{html}</div>
</>
);
}
export default MyEditor;
import { useState } from 'react';
import { aiEdit, aiChat, aiGenerateImage } from '@/api/ai';
export function useAIEdit() {
const [messages, setMessages] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const latestMessage = messages[messages.length - 1] || {};
const { text = '' } = latestMessage;
const fetch = async (params) => {
setIsLoading(true);
try {
const res = await aiEdit({
body: JSON.stringify({ params }),
onmessage: (res) => {
let message = JSON.parse(res.data);
message = { ...message.data, request_id: message.request_id };
setMessages((prevMessages) => {
const messageIndex = prevMessages.findIndex((m) => m.request_id === message.request_id);
if (messageIndex === -1) {
return [...prevMessages, message];
} else {
return prevMessages.map((m) => (m.request_id === message.request_id ? message : m));
}
});
},
});
} catch (error) {
console.error('Error fetching AI edit:', error);
} finally {
setIsLoading(false);
}
};
return { messages, text, setMessages, fetch, isLoading };
}
export function useAIChat() {
const [messages, setMessages] = useState([]);
const fetch = async (params) => {
const res = await aiChat({
body: JSON.stringify({ params }),
onmessage: (res) => {
const message = JSON.parse(res.data);
console.log(message);
setMessages((messages) => [...messages, message]);
},
});
};
}
export function useAIGenerateImage() {
const [messages, setMessages] = useState([]);
const fetch = async (params) => {
const res = await aiGenerateImage(params);
setMessages(res);
};
}
import { useEffect, useState } from 'react';
import { fetchEventSource } from '@fortaine/fetch-event-source';
function getToken() {
return window.localStorage.getItem('kiwi.token') || '';
}
const getHeaders = () => {
const token = getToken();
const appId = 'TzEU5jPk2tu80266';
const appSecret = '0a006048a4480481b18fef1405120b83';
const timestamp = Math.floor(Date.now() / 1000);
return {
Authorization: token,
AppId: appId,
AppSecret: appSecret,
Timestamp: timestamp,
'Content-Type': 'application/json',
};
};
const defaultOnOpen = async (response) => {
if (!response.ok) {
throw response;
}
return response;
};
const defaultOnMessage = (setMessages) => (res) => {
const message = JSON.parse(res.data);
setMessages((prevMessages) => [...prevMessages, message]);
};
export function useFetchEventSource(url, options = {}) {
const [isLoading, setLoading] = useState(false);
const [messages, setMessages] = useState([]);
const [error, setError] = useState(null);
const fetch = () => {
setLoading(true);
const headers = getHeaders();
const defaultOptions = {
method: 'POST',
headers,
onopen: defaultOnOpen,
onmessage: defaultOnMessage(setMessages),
onerror: (err) => setError(err),
};
fetchEventSource(url, { ...defaultOptions, ...options }).finally(() => setLoading(false));
};
useEffect(() => {
fetch();
}, [url, options]);
return { isLoading, error, messages };
}
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}
import React, { createContext, useContext, useState } from 'react';
const GlobalContext = createContext();
export const useGlobalContext = () => useContext(GlobalContext);
export const GlobalProvider = ({ children }) => {
const [unreadMessagesNum, setUnreadMessagesNum] = useState(0);
return (
<GlobalContext.Provider value={{ unreadMessagesNum, setUnreadMessagesNum }}>
{children}
</GlobalContext.Provider>
);
};
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Space, Breadcrumb, Button, Row, Col, Menu } from 'antd'; import { Button, Row, Col, Menu } from 'antd';
import { useLocation, useNavigate, Link } from 'react-router-dom'; import { useLocation, useNavigate, Link } from 'react-router-dom';
import { getRouteList, getRouteItem } from '@/utils/breadCrumb';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { LeftOutlined } from '@ant-design/icons'; import { LeftOutlined } from '@ant-design/icons';
import IconFont from '@/common/iconfont';
import UserMenu from './menu';
const BreadCrumbMenu = () => { const BreadCrumbMenu = () => {
const { pathname } = useLocation();
const location = useLocation(); const location = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
const [breadcrumbList, setBreadcrumbList] = useState([]); const [breadcrumbList, setBreadcrumbList] = useState([]);
...@@ -38,7 +34,6 @@ const BreadCrumbMenu = () => { ...@@ -38,7 +34,6 @@ const BreadCrumbMenu = () => {
menuTemp.push({ menuTemp.push({
label: transLinkMenu(cItem), label: transLinkMenu(cItem),
key: cItem.path, key: cItem.path,
icon: cItem.icon ? <IconFont type={cItem.icon} /> : '',
}); });
}); });
setBreadcrumbList(menuTemp); setBreadcrumbList(menuTemp);
...@@ -47,50 +42,6 @@ const BreadCrumbMenu = () => { ...@@ -47,50 +42,6 @@ const BreadCrumbMenu = () => {
} }
}, [location.pathname]); }, [location.pathname]);
// useEffect(() => {
// const routeList = getRouteList(
// [],
// getRouteItem(baseRootRouter, pathname) ? [getRouteItem(baseRootRouter, pathname)] : [],
// pathname,
// );
// if (routeList.length === 0) {
// setBreadcrumbList([
// { path: '/', name: '首页', key: '/', isSubMenu: false },
// { path: '404', name: 'Not Found', key: '/404', isSubMenu: false },
// ]);
// } else {
// setBreadcrumbList([...routeList]);
// }
// }, [pathname]);
// const linkTo = (path) => {
// navigate(path);
// };
// const treeDataToArray = (source) => {
// const res = [];
// // 第二种方式
// source.forEach((item) => {
// res.push(item);
// item.children && res.push(...treeDataToArray(item.children));
// });
// return res;
// };
useEffect(() => {
// const flatRoutes = treeDataToArray(rootRouter);
// const routeMeta = flatRoutes.find((item) => item.path === pathname);
// if (routeMeta.back == true) {
// setIsShowBack(true);
// } else {
// setIsShowBack(false);
// }
// if (arr.includes(location.pathname)) {
// return setisShowMenu(false);
// }
// setisShowMenu(true);
}, [pathname]);
useEffect(() => { useEffect(() => {
if ( if (
window.location.pathname === '/books/management/add-edit' || window.location.pathname === '/books/management/add-edit' ||
......
...@@ -4,8 +4,6 @@ import { Space, Menu } from 'antd'; ...@@ -4,8 +4,6 @@ import { Space, Menu } from 'antd';
import { Link, useLocation, useNavigate } from 'react-router-dom'; import { Link, useLocation, useNavigate } from 'react-router-dom';
import { findTreeElementByKey } from '@/utils/common.js'; import { findTreeElementByKey } from '@/utils/common.js';
import IconFont from '@/common/iconfont';
const UserMenu = (props) => { const UserMenu = (props) => {
const { flag, breadmenu, menuList } = props; const { flag, breadmenu, menuList } = props;
const location = useLocation(); const location = useLocation();
...@@ -28,7 +26,6 @@ const UserMenu = (props) => { ...@@ -28,7 +26,6 @@ const UserMenu = (props) => {
menuItem = { menuItem = {
title: route.meta.title, title: route.meta.title,
key: route.path, key: route.path,
icon: route.icon ? <IconFont type={route.icon} /> : null,
}; };
if (route[children] && route[children].length > 0) { if (route[children] && route[children].length > 0) {
const childrenItems = generateMenuItems(route.children); const childrenItems = generateMenuItems(route.children);
...@@ -74,7 +71,6 @@ const UserMenu = (props) => { ...@@ -74,7 +71,6 @@ const UserMenu = (props) => {
const newItem = { const newItem = {
label: depth === 1 ? transLinkMenu(item, true) : transLinkMenu(item), label: depth === 1 ? transLinkMenu(item, true) : transLinkMenu(item),
key: item.path, key: item.path,
icon: item.icon ? <IconFont type={route.icon} /> : null,
}; };
if (depth < 2 && item.children.length) { if (depth < 2 && item.children.length) {
newItem.children = toAntdMenus(item.children, depth + 1); newItem.children = toAntdMenus(item.children, depth + 1);
......
...@@ -11,8 +11,6 @@ import point1 from '../../assets/images/point1.png'; ...@@ -11,8 +11,6 @@ import point1 from '../../assets/images/point1.png';
import quit from '../../assets/images/quit.png'; import quit from '../../assets/images/quit.png';
import slide from '../../assets/images/slide.png'; import slide from '../../assets/images/slide.png';
import { useGlobalContext } from '../GlobalContext';
const items = [ const items = [
{ {
key: 'userinfo', key: 'userinfo',
...@@ -35,8 +33,7 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -35,8 +33,7 @@ const UserInfo = ({ props, extraSlot }) => {
const [page, setPage] = useState(1); const [page, setPage] = useState(1);
const [page_size, setpage_size] = useState(10); const [page_size, setpage_size] = useState(10);
const [drawerScrolled, setDrawerScrolled] = useState(false); const [drawerScrolled, setDrawerScrolled] = useState(false);
// const [unreadMessagesNum, setUnreadMessagesNum] = useState(0); const [unreadMessagesNum, setUnreadMessagesNum] = useState(0);
const { unreadMessagesNum, setUnreadMessagesNum } = useGlobalContext();
const heartbeatInterval = useRef(null); const heartbeatInterval = useRef(null);
const [isReadSet, setIsReadSet] = useState(false); const [isReadSet, setIsReadSet] = useState(false);
const { const {
...@@ -50,11 +47,10 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -50,11 +47,10 @@ const UserInfo = ({ props, extraSlot }) => {
} = msgWebsocket({}); } = msgWebsocket({});
const [messageListLoaded, setMessageListLoaded] = useState(false); // 新增状态来表示消息列表是否已加载 const [messageListLoaded, setMessageListLoaded] = useState(false); // 新增状态来表示消息列表是否已加载
// const [userInfos]
// 推出登录 // 推出登录
const signOut = () => { const signOut = () => {
localStorage.clear(); localStorage.clear();
navigator('/user/login'); navigator('/login');
}; };
const getInfo = async () => { const getInfo = async () => {
const data = await getUserInfo(); const data = await getUserInfo();
...@@ -106,20 +102,20 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -106,20 +102,20 @@ const UserInfo = ({ props, extraSlot }) => {
}, [showDrawer, unreadMessagesNum, isReadSet]); }, [showDrawer, unreadMessagesNum, isReadSet]);
// 加载消息的websocket // 加载消息的websocket
useEffect(() => { // useEffect(() => {
if (userInfos.id > 0) { // if (userInfos.id > 0) {
const wsUrl = `${import.meta.env.VITE_API_WEBSOCKET_URL}/ws`; // const wsUrl = `${import.meta.env.VITE_API_WEBSOCKET_URL}/ws`;
// 建立websokect链接 // // 建立websokect链接
webSocketInit(wsUrl); // webSocketInit(wsUrl);
// 获取websocket消息 // // 获取websocket消息
if (Object.entries(wsMessage).length > 0) { // if (Object.entries(wsMessage).length > 0) {
console.log('收到消息了'); // console.log('收到消息了');
console.log(wsMessage); // console.log(wsMessage);
// 收到消息一个未读消息 // // 收到消息一个未读消息
setUnreadMessagesNum(unreadMessagesNum + 1); // setUnreadMessagesNum(unreadMessagesNum + 1);
} // }
} // }
}, [userInfos, wsMessage, wsReadyState]); // }, [userInfos, wsMessage, wsReadyState]);
// 重连websocket // 重连websocket
// useEffect(() => { // useEffect(() => {
...@@ -482,7 +478,6 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -482,7 +478,6 @@ const UserInfo = ({ props, extraSlot }) => {
marginTop: '10px', marginTop: '10px',
}} }}
> >
{' '}
<Button <Button
style={{ style={{
border: 'none', border: 'none',
......
...@@ -72,7 +72,7 @@ const LayoutComponent = () => { ...@@ -72,7 +72,7 @@ const LayoutComponent = () => {
<Header className='layout-header'> <Header className='layout-header'>
<div className='header-logo'> <div className='header-logo'>
<Link to='/'> <Link to='/'>
<img src={logo} alt='logo' /> <img src={logo} />
</Link> </Link>
</div> </div>
<UserMenu menuList={menuList} /> <UserMenu menuList={menuList} />
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
height: 50px; height: 50px;
line-height: 50px; line-height: 50px;
background-color: #fff; background-color: #fff;
padding: 0 25px; padding: 0 20px;
.ant-menu-overflow { .ant-menu-overflow {
margin-left: 100px; margin-left: 100px;
...@@ -37,12 +37,6 @@ ...@@ -37,12 +37,6 @@
height: 32px; height: 32px;
vertical-align: middle; vertical-align: middle;
} }
span {
vertical-align: middle;
height: 50px;
width: 0;
display: inline-block;
}
} }
.header-menu { .header-menu {
......
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom/client'; import ReactDOM from 'react-dom/client';
import { BrowserRouter as Router } from 'react-router-dom'; import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react'; import { PersistGate } from 'redux-persist/integration/react';
...@@ -16,24 +16,20 @@ import zhCN from 'antd/locale/zh_CN'; ...@@ -16,24 +16,20 @@ import zhCN from 'antd/locale/zh_CN';
import MyApp from './App.jsx'; import MyApp from './App.jsx';
import { GlobalProvider } from './layout/GlobalContext.jsx';
import 'dayjs/locale/zh-cn'; import 'dayjs/locale/zh-cn';
ReactDOM.createRoot(document.getElementById('root')).render( ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode> // <React.StrictMode>
<Provider store={store}> <Provider store={store}>
<PersistGate loading={null} persistor={persistor}> <PersistGate loading={null} persistor={persistor}>
<ConfigProvider locale={zhCN} theme={{ token: { colorPrimary: '#ab1941' } }}> <ConfigProvider locale={zhCN} theme={{ token: { colorPrimary: '#ab1941' } }}>
<App> <App>
<Router> <BrowserRouter>
<GlobalProvider> <MyApp />
<MyApp /> </BrowserRouter>
</GlobalProvider> </App>
</Router> </ConfigProvider>
</App> </PersistGate>
</ConfigProvider> </Provider>,
</PersistGate> // </React.StrictMode>,
</Provider>
</React.StrictMode>,
); );
...@@ -10,10 +10,8 @@ import userStatus3 from '@/assets/images/user_status3.png'; ...@@ -10,10 +10,8 @@ import userStatus3 from '@/assets/images/user_status3.png';
import defaultUser from '@/assets/images/defaultUser.png'; import defaultUser from '@/assets/images/defaultUser.png';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { useGlobalContext } from '../../../layout/GlobalContext';
const AuditDetail = (props) => { const AuditDetail = (props) => {
const { setUnreadMessagesNum } = useGlobalContext();
const location = useLocation(); const location = useLocation();
const { const {
state: { id }, state: { id },
...@@ -23,7 +21,6 @@ const AuditDetail = (props) => { ...@@ -23,7 +21,6 @@ const AuditDetail = (props) => {
const [examineList, setExamineList] = useState([]); const [examineList, setExamineList] = useState([]);
const [quanXian, setQuanXian] = useState(true); const [quanXian, setQuanXian] = useState(true);
// const [unreadMessagesNum, setUnreadMessagesNum] = useState(0);
// 获取操作权限 // 获取操作权限
const { operationPermissionsList } = useSelector((state) => state.user); const { operationPermissionsList } = useSelector((state) => state.user);
...@@ -222,7 +219,6 @@ const AuditDetail = (props) => { ...@@ -222,7 +219,6 @@ const AuditDetail = (props) => {
bool = false; bool = false;
} else { } else {
message.success(msg); message.success(msg);
setUnreadMessagesNum(1); // 更新全局状态中的 unreadMessagesNum
} }
setLoading(false); setLoading(false);
if (!bool) return; if (!bool) return;
......
import React from 'react'; import React from 'react';
import { Row, Col } from 'antd'; import { Outlet } from 'react-router-dom';
import { Routes, Route, Navigate, Outlet, Link } from 'react-router-dom';
import Login from './login';
import Reg from './reg';
import './index.less'; import './index.less';
import logo from '@/assets/images/logo.png';
import homeBanner from '@/assets/images/home_left_banner.png';
const User = () => { const User = () => {
return ( return (
<div className='user-content'> <div className='user-content'>
<div className='form-container'> <div className='form-container'>
<div className="left-container"></div> <div className='left-container'></div>
<div className='form-field-box'> <div className='form-field-box'>
<div className='form-field'> <div className='form-field'>
<Outlet /> <Outlet />
......
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { Form, Input, Button, Row, Col, Space, Image, message } from 'antd'; import { Form, Input, Button, Row, Col, Space, Image, message } from 'antd';
import { CloseOutlined } from '@ant-design/icons'; import { CloseOutlined, UserOutlined, LockOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { sendSMS, userNameLogin, phoneLogin, checkSSOLogin } from '../request/request'; import { checkSSOLogin } from '../request/request';
import './index.less'; import './index.less';
import SetIcon from '@/common/icon';
import IconUser from '@/assets/images/icon/icon_user.png';
import IconPass from '@/assets/images/icon/icon_password.png';
import loginBtn from '@/assets/images/loginBtn.png'; import loginBtn from '@/assets/images/loginBtn.png';
import loginBtn2 from '@/assets/images/loginBtn2.png'; import loginBtn2 from '@/assets/images/loginBtn2.png';
...@@ -65,18 +62,18 @@ const Login = () => { ...@@ -65,18 +62,18 @@ const Login = () => {
const timer = useRef(); const timer = useRef();
const getSSOInfo = async () => { const getSSOInfo = async () => {
const isSSOData = await checkSSOLogin(); const isSSOData = await checkSSOLogin();
if (isSSOData.run === 'login') { if (isSSOData.run === 'login') {
} else if (isSSOData.token) { } else if (isSSOData.token) {
localStorage.setItem('kiwi.token', isSSOData.token); localStorage.setItem('kiwi.token', isSSOData.token);
navigate('/'); navigate('/');
return; return;
} }
} };
useEffect(() => { useEffect(() => {
getSSOInfo(); getSSOInfo();
}, []) }, []);
// 登录 // 登录
const toLayout = async (obj) => { const toLayout = async (obj) => {
...@@ -88,13 +85,13 @@ const Login = () => { ...@@ -88,13 +85,13 @@ const Login = () => {
code: code, code: code,
disLf: disLf, disLf: disLf,
}); });
if (data.code === 200) { if (data.code === 200) {
localStorage.setItem('kiwi.token', data.token); localStorage.setItem('kiwi.token', data.token);
navigate('/'); navigate('/');
return; return;
} else { } else {
form.setFields([{ name: 'password', errors: [data.msg] }]) form.setFields([{ name: 'password', errors: [data.msg] }]);
} }
} else { } else {
message.error('请先完成按钮验证'); message.error('请先完成按钮验证');
...@@ -223,20 +220,15 @@ const Login = () => { ...@@ -223,20 +220,15 @@ const Login = () => {
> >
<Input <Input
autoComplete='off' autoComplete='off'
prefix={<SetIcon src={IconUser} />} prefix={<UserOutlined />}
size='large' size='large'
placeholder='请输入手机号' placeholder='请输入手机号'
/> />
</Form.Item> </Form.Item>
<Form.Item <Form.Item name='password' rules={[{ required: true, message: '请输入密码!' }]}>
name='password'
rules={[
{ required: true, message: '请输入密码!' },
]}
>
<Input.Password <Input.Password
autoComplete='off' autoComplete='off'
prefix={<SetIcon src={IconPass} />} prefix={<LockOutlined />}
size='large' size='large'
placeholder='请输入密码' placeholder='请输入密码'
/> />
......
import React from 'react';
const Reg = () => {
return <div> Reg </div>;
};
export default Reg;
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Form, Input, Button, Upload, Space, Modal, Row, Col, Drawer, message } from 'antd'; import { Form, Input, Button, Upload, Space, Row, Col, Drawer, message } from 'antd';
import users from '@/assets/images/icon/userinfo.png'; import users from '@/assets/images/icon/userinfo.png';
import { changePass, changeInfo, getUserInfo } from '@/layout/request'; import { changePass, changeInfo, getUserInfo } from '@/layout/request';
import { uploadFiles } from '@/utils/upload';
import AliOSS from 'ali-oss'; import AliOSS from 'ali-oss';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
...@@ -180,20 +179,21 @@ const UserInfo = () => { ...@@ -180,20 +179,21 @@ const UserInfo = () => {
<div style={{ padding: '20px 0' }}> <div style={{ padding: '20px 0' }}>
<Form form={form} labelCol={{ span: 2 }} onFinish={submitForm}> <Form form={form} labelCol={{ span: 2 }} onFinish={submitForm}>
<Form.Item label='头像' className='uploadPar' name='pic'> <Form.Item label='头像' className='uploadPar' name='pic'>
<img
src={imageUrl ? imageUrl : users}
style={{ borderRadius: '50%' }}
width={80}
height={80}
id='avatar'
/>
<div> <div>
<Upload {...props} valuePropName='file'> <img
<Button className='upload'>点击上传</Button> src={imageUrl ? imageUrl : users}
</Upload> style={{ borderRadius: '50%' }}
<span className='desc' style={{ marginLeft: 19, color: '#999', fontSize: '14px' }}> width={80}
尺寸:只能上传jpg/png文件,且不超过1M height={80}
</span> />
<div>
<Upload {...props} valuePropName='file'>
<Button className='upload'>点击上传</Button>
</Upload>
<span className='desc' style={{ marginLeft: 19, color: '#999', fontSize: '14px' }}>
尺寸:只能上传jpg/png文件,且不超过1M
</span>
</div>
</div> </div>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
...@@ -248,13 +248,14 @@ const UserInfo = () => { ...@@ -248,13 +248,14 @@ const UserInfo = () => {
rules={[ rules={[
{ required: true, message: '请输入新密码' }, { required: true, message: '请输入新密码' },
{ {
pattern: /^((?=.*\d)(?=.*[A-Z])(?=.*[a-z]))|((?=.*\d)(?=.*[A-Z])(?=.*[\W_]))|((?=.*\d)(?=.*[a-z])(?=.*[\W_]))|((?=.*[A-Z])(?=.*[a-z])(?=.*[\W_]))[a-zA-Z\d\W_]{8,12}$/, pattern:
/^((?=.*\d)(?=.*[A-Z])(?=.*[a-z]))|((?=.*\d)(?=.*[A-Z])(?=.*[\W_]))|((?=.*\d)(?=.*[a-z])(?=.*[\W_]))|((?=.*[A-Z])(?=.*[a-z])(?=.*[\W_]))[a-zA-Z\d\W_]{8,12}$/,
message: message:
'密码至少满足三种格式(大写字母、小写字母、数字、特殊符号), 长度为8~12位字符!', '密码至少满足三种格式(大写字母、小写字母、数字、特殊符号), 长度为8~12位字符!',
trigger: ['change', 'blur'] trigger: ['change', 'blur'],
}, },
{ {
validator (_, value) { validator(_, value) {
if (!value || form2.getFieldValue('re_password') === value) { if (!value || form2.getFieldValue('re_password') === value) {
form2.setFields([{ name: 're_password', errors: [''] }]); form2.setFields([{ name: 're_password', errors: [''] }]);
return Promise.resolve(); return Promise.resolve();
...@@ -273,13 +274,14 @@ const UserInfo = () => { ...@@ -273,13 +274,14 @@ const UserInfo = () => {
rules={[ rules={[
{ required: true, message: '请确认新密码' }, { required: true, message: '请确认新密码' },
{ {
pattern: /^((?=.*\d)(?=.*[A-Z])(?=.*[a-z]))|((?=.*\d)(?=.*[A-Z])(?=.*[\W_]))|((?=.*\d)(?=.*[a-z])(?=.*[\W_]))|((?=.*[A-Z])(?=.*[a-z])(?=.*[\W_]))[a-zA-Z\d\W_]{8,12}$/, pattern:
/^((?=.*\d)(?=.*[A-Z])(?=.*[a-z]))|((?=.*\d)(?=.*[A-Z])(?=.*[\W_]))|((?=.*\d)(?=.*[a-z])(?=.*[\W_]))|((?=.*[A-Z])(?=.*[a-z])(?=.*[\W_]))[a-zA-Z\d\W_]{8,12}$/,
message: message:
'密码至少满足三种格式(大写字母、小写字母、数字、特殊符号), 长度为8~12位字符!', '密码至少满足三种格式(大写字母、小写字母、数字、特殊符号), 长度为8~12位字符!',
trigger: ['change', 'blur'] trigger: ['change', 'blur'],
}, },
{ {
validator (_, value) { validator(_, value) {
if (!value || form2.getFieldValue('password') === value) { if (!value || form2.getFieldValue('password') === value) {
return Promise.resolve(); return Promise.resolve();
} }
......
import { lazy } from 'react';
import { Navigate } from 'react-router-dom'; import { Navigate } from 'react-router-dom';
import { lazyLoad, authComponent } from './lazyLoadAndDelay'; // 添加一个固定的延迟时间,以便你可以看到加载状态 import { lazyLoad, authComponent } from './lazyLoadAndDelay'; // 添加一个固定的延迟时间,以便你可以看到加载状态
import Layout from '@/layout/index'; import Layout from '@/layout/index';
import UserModule from '@/pages/user-module'; import UserModule from '@/pages/user-module';
import UserLogin from '@/pages/user-module/login';
import UserInfo from '@/pages/user-module/userInfo';
import NotFound from '@/common/notFound';
import notPermission from '@/common/notPermission';
const baseRouter = [ const baseRouter = [
{ {
path: '/', path: '/',
key: 'layout',
element: authComponent(Layout), element: authComponent(Layout),
meta: {
title: '控制台',
},
children: [ children: [
{ path: '/userinfo', element: lazyLoad(UserInfo) }, {
// { path: '*', element: lazyLoad(notPermission) }, path: '/userinfo',
Component: lazy(() => import('@/pages/user-module/userInfo')),
},
], ],
}, },
{ {
path: '/user', path: '/login',
key: 'user',
element: lazyLoad(UserModule), element: lazyLoad(UserModule),
hidden: true, // Component: lazy(() => import('@/pages/user-module')),
meta: {
title: '用户',
},
children: [ children: [
{ {
index: true, index: true,
element: <Navigate to='/user/login' />, Component: lazy(() => import('@/pages/user-module/login')),
},
{
path: '/user/login',
element: lazyLoad(UserLogin),
}, },
], ],
}, },
{ { path: '*', element: <Navigate to='/' /> },
path: '/404',
key: '404',
hidden: true,
element: lazyLoad(NotFound),
meta: {},
},
// { path: '*', hidden: true, element: <Navigate to='/404' /> },
]; ];
export default baseRouter; export default baseRouter;
import { useRoutes, Navigate } from 'react-router-dom';
import { lazyLoad } from './lazyLoadAndDelay'; // 添加一个固定的延迟时间,以便你可以看到加载状态
import Layout from '@/layout/index';
import UserModule from '@/pages/user-module';
import UserLogin from '@/pages/user-module/login';
import AuthGroups from '@/pages/setting';
import UserInfo from '@/pages/user-module/userInfo';
import BookModule from '@/pages/books'
import BookClassify from '@/pages/books/classify'
import BookAudit from '@/pages/books/audit/index.jsx'
import AuditTable from '@/pages/books/audit/table.jsx'
import AuditDetail from '@/pages/books/audit/detail.jsx';
import BookLabel from '@/pages/books/label'
// import BookAuditDetail from '@/pages/books/auditDetail'
import BookManagement from '@/pages/books/management/index.jsx'
import BookManagementList from '@/pages/books/management/list'
import BookAddEdit from '@/pages/books/management/addedit';
import BookSale from '@/pages/books/sale';
import SaleDetail from '@/pages/books/sale/edit.jsx';
import SaleTable from '@/pages/books/sale/table.jsx';
import DiscussList from '@/pages/books/sale/discussList';
import DiscussDetail from '@/pages/books/sale/discussDetail';
import BookSection from '@/pages/books/section'
import OrderManagement from '@/pages/books/order-management'
import OrderTable from '@/pages/books/order-management/tab/table.jsx'
import OrderSalesStatistics from '@/pages/books/order-management/tab/salesStatistics';
import User from '@/pages/member'
import UserHome from '@/pages/member/list/list.jsx'
import UserList from '@/pages/member/list'
import Userlevel from '@/pages/member/userlevel';
import UserDetail from '@/pages/member/detail'
import CouponRecord from '@/pages/member/detail/CouponRecord';
import IntegralRecord from '@/pages/member/detail/IntegralRecord';
import OrderRecord from '@/pages/member/detail/orderRecord';
import AdvertisingModule from '@/pages/advertisement'
import Advert from '@/pages/advertisement/Advert'
import Adsense from '@/pages/advertisement/adsense';
import Jurisdiction from '@/pages/jurisdiction';
import Administrator from '@/pages/jurisdiction/admin';
import RoleList from '@/pages/jurisdiction/role';
import QuestionBank from '@/pages/books/question-bank'
import Applied from '@/pages/setting/applied'
import Personalized from '@/pages/setting/personalized-setting'
import Point from '@/pages/setting/point-management';
import AppVersion from '@/pages/setting/app-version';
import Coupon from '@/pages/setting/coupon';
import Sensitive from '@/pages/setting/sensitive';
import FeedBack from '@/pages/setting/feedback'
import Help from '@/pages/setting/help';
import HelpAddEdit from '@/pages/setting/help/addedit/index'
import HelpTable from '@/pages/setting/help/table.jsx';
import Discuss from '@/pages/books/discussion'
import TeacherModule from '@/pages/teacher';
import NotFound from '@/common/notFound'; //公共
import { getMenuList } from '@/common/request';
const authComponent = (Com) => {
const token = localStorage.getItem('kiwi.token') || true;
return token ? lazyLoad(Com) : <Navigate to='/user' />;
};
const GetRoutes = () => {
const [dynamicRoutes, setDynamicRoutes] = useState(null);
useEffect(() => {
const fetchData = async () => {
// 获取菜单列表
const menuData = await getMenuList();
// 处理菜单数据,生成动态路由配置
const dynamicRoutes = generateDynamicRoutes(menuData);
// 设置动态路由
setDynamicRoutes(dynamicRoutes);
};
fetchData();
}, []);
// 如果动态路由尚未加载完成,可以返回一个加载状态或其他内容
if (!dynamicRoutes) {
return <div>Loading...</div>;
}
// 使用动态路由
const routes = useRoutes(dynamicRoutes);
return routes;
};
// 生成动态路由的函数,根据菜单数据生成路由配置
const generateDynamicRoutes = (menuData) => {
// 这里根据你的菜单数据结构进行处理,生成动态路由配置
// 返回一个类似于 rootRouter 的结构,但基于动态数据
// 示例:假设菜单数据的格式为 [{ path: '/dynamic', title: '动态菜单', children: [...] }]
const dynamicRoutes = menuData.map((menuItem) => {
return {
path: menuItem.path,
key: menuItem.key, // 确保每个路由有唯一的 key
element: lazyLoad(getComponentByType(menuItem.type)), // 根据类型获取组件,你可能需要自己实现这个函数
meta: {
title: menuItem.title,
},
children: generateDynamicRoutes(menuItem.children), // 递归处理子菜单
};
});
return dynamicRoutes;
};
// 根据菜单项的类型返回对应的组件,你可能需要根据实际情况自行实现这个函数
const getComponentByType = (type) => {
// 根据类型返回对应的组件
// 例如:假设你的菜单项有 type 字段,根据不同的 type 返回不同的组件
switch (type) {
case 'book':
return BookModule;
case 'user':
return User;
// 其他类型的组件处理...
default:
return NotFound; // 默认返回 NotFound 组件
}
};
export default GetRoutes;
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useRoutes, Navigate } from 'react-router-dom'; import { useRoutes, Navigate } from 'react-router-dom';
import { filterAsyncRouter } from './lazyLoadAndDelay'; import { filterAsyncRouter } from './lazyLoadAndDelay';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import baseRouter from './baseRouter'; import baseRouter from './baseRouter';
const addDefaultNavigation = (menuRoutes) => { const addDefaultNavigation = (menuRoutes) => {
menuRoutes.forEach(item => { menuRoutes.forEach((item) => {
const children = item.children; const children = item.children;
if (children && children.length > 0) { if (children && children.length > 0) {
...@@ -15,7 +15,7 @@ const addDefaultNavigation = (menuRoutes) => { ...@@ -15,7 +15,7 @@ const addDefaultNavigation = (menuRoutes) => {
// 在 children 数组的开头添加默认导航项 // 在 children 数组的开头添加默认导航项
children.unshift({ children.unshift({
index: true, index: true,
element: <Navigate to={children[0].path} /> element: <Navigate to={children[0].path} />,
}); });
} }
}); });
...@@ -24,8 +24,7 @@ const addDefaultNavigation = (menuRoutes) => { ...@@ -24,8 +24,7 @@ const addDefaultNavigation = (menuRoutes) => {
const GetroutesDyamic = () => { const GetroutesDyamic = () => {
// 合并路由 // 合并路由
const { menuRouter } = useSelector(state => state.user); const { menuRouter } = useSelector((state) => state.user);
// console.log(menuRouter);
useEffect(() => { useEffect(() => {
if (menuRouter?.length) { if (menuRouter?.length) {
const menuRoutes = filterAsyncRouter(menuRouter); const menuRoutes = filterAsyncRouter(menuRouter);
...@@ -33,21 +32,14 @@ const GetroutesDyamic = () => { ...@@ -33,21 +32,14 @@ const GetroutesDyamic = () => {
const newMenus = addDefaultNavigation(menuRoutes); const newMenus = addDefaultNavigation(menuRoutes);
const firstObj = { const firstObj = {
index: true, index: true,
element: <Navigate to={newMenus[0].path} /> element: <Navigate to={newMenus[0].path} />,
} };
baseRouter[0].children = [firstObj, ...newMenus, ...hasRoute]; baseRouter[0].children = [firstObj, ...newMenus, ...hasRoute];
} }
}, [menuRouter]); }, [menuRouter]);
const element = useRoutes(baseRouter); const element = useRoutes(baseRouter);
return ( return <>{element}</>;
<> };
{element}
</>
)
}
export { export { GetroutesDyamic };
GetroutesDyamic
}
...@@ -47,7 +47,7 @@ const filterAsyncRouter = (menuData) => { ...@@ -47,7 +47,7 @@ const filterAsyncRouter = (menuData) => {
const authComponent = (Com) => { const authComponent = (Com) => {
const token = localStorage.getItem('kiwi.token') || true; const token = localStorage.getItem('kiwi.token') || true;
return token ? lazyLoad(Com) : <Navigate to='/user' />; return token ? lazyLoad(Com) : <Navigate to='/login' />;
}; };
export { lazyLoad, lazyLoadModule, delayForDemo, authComponent, filterAsyncRouter }; export { lazyLoad, lazyLoadModule, delayForDemo, authComponent, filterAsyncRouter };
...@@ -12,7 +12,7 @@ function showLoginModal() { ...@@ -12,7 +12,7 @@ function showLoginModal() {
title: '登录状态已过期,请重新登录', title: '登录状态已过期,请重新登录',
onOk() { onOk() {
localStorage.removeItem('kiwi.gpt.token'); localStorage.removeItem('kiwi.gpt.token');
location.href = '/user/login'; location.href = '/login';
}, },
}); });
} }
...@@ -71,7 +71,7 @@ httpRequest.interceptors.response.use( ...@@ -71,7 +71,7 @@ httpRequest.interceptors.response.use(
(response) => { (response) => {
const { data } = response; const { data } = response;
if (data.code === 401 || data.code === 403) { if (data.code === 401 || data.code === 403) {
if (location.pathname !== '/user/login') { if (location.pathname !== '/login') {
showLoginModal(); showLoginModal();
} }
return Promise.reject(data); return Promise.reject(data);
......
/* eslint-disable */
// 取消重复请求的数组
const cancelRequestArr = [];
export default cancelRequestArr;
import $ from 'jquery';
import axios from '@/utils/request.js';
import qs from 'qs';
import { message } from 'antd';
let RotateVerify; // 声明 RotateVerify 变量
(function (undefined) {
'use strict';
var _global;
//判断是否为 数组
function isArray (o) {
return Object.prototype.toString.call(o) == '[object Array]';
}
//随机数
function getRandomNumber (a, b) {
return Math.round(Math.random() * (b - a) + a);
}
//获取随机图片
function getRandomImg (imgArr) {
return imgArr[getRandomNumber(0, imgArr.length - 1)];
}
//判断 是否处于动画状态
function ifAnimate (ele) {
if (ele.is(':animated')) {
return true;
} else {
return false;
}
}
//获取元素的left值
function getEleCssLeft ($ele) {
return parseInt($ele.css('left'));
}
RotateVerify = function (ele, opt) {
this.$ele = $(ele);
//默认参数
this.defaults = {
initText: '滑动将图片转正',
slideImage: '',
slideAreaNum: 10,
initUrl: '',
verifyUrl: '',
verifyParam: {},
getSuccessState: function () {},
};
this.settings = $.extend({}, this.defaults, opt);
this.init();
};
RotateVerify.prototype = {
constructor: this,
init: function () {
this.verifyState = false;
this.disLf = 0;
this.initDom();
this.initCanvasImg();
this.initMouse();
this._touchstart();
this._touchend();
},
initDom: function () {
this.statusBg = this.$ele.find('.statusBg');
this.$slideDragWrap = this.$ele.find('.slideDragWrap');
this.$slideDragBtn = this.$ele.find('.slideDragBtn');
this.rotateCan = this.$ele.find('.rotateCan');
this.cTipsTxt = this.$ele.find('.cTipsTxt');
this.controlBorWrap = this.$ele.find('.controlBorWrap');
this.xPos = this.rotateCan[0].width / 2;
this.yPos = this.rotateCan[0].height / 2;
this.aveRot =
Math.round((360 / (this.$slideDragWrap.width() - this.$slideDragBtn.outerWidth())) * 100) /
100;
this.rotateImgCan = this.rotateCan[0].getContext('2d');
this.slideImage = document.createElement('img');
this.setAttrSrc();
},
initCanvasImg: function () {
axios
.post(
this.settings.initUrl,
qs.stringify({
drag_wrap: this.$slideDragWrap.width(),
drag_btn: this.$slideDragBtn.width(),
}),
)
.then((res) => {
const code = res.data.code;
const data = res.data.data;
const msg = res.data.message;
console.log('initCanvasImg', data);
if (code === 200) {
this.randRot = data.rand_bot;
this.code = data.code;
this.disLf = 0;
this.initImgSrc();
return data;
} else {
message.error(msg);
return false;
}
})
.catch((error) => {
console.error('发生错误:', error);
});
},
// initCanvasImg: function () {
// $.post(
// this.settings.initUrl,
// {
// drag_wrap: this.$slideDragWrap.width(),
// drag_btn: this.$slideDragBtn.width(),
// },
// (res) => {
// if (res.code === 0) {
// this.randRot = res.data.rand_bot;
// this.code = res.data.code;
// this.disLf = 0;
// this.initImgSrc();
// }
// },
// 'json',
// );
// },
initImgSrc: function () {
var _this = this;
_this.slideImage.src = _this.slideImage.getAttribute('data-src');
_this.setAttrSrc();
_this.slideImage.onload = function () {
_this.slideImage.style.width = '200px';
_this.slideImage.style.height = '200px';
_this.drawImgCan();
};
},
drawImgCan: function (val) {
var _this = this;
_this.rotateImgCan.beginPath();
_this.rotateImgCan.arc(100, 100, 100, 0, (360 * Math.PI) / 180, false);
_this.rotateImgCan.closePath();
_this.rotateImgCan.clip();
_this.rotateImgCan.save();
_this.rotateImgCan.clearRect(0, 0, 200, 200);
_this.rotateImgCan.translate(_this.xPos, _this.yPos);
_this.rotateImgCan.rotate(
(this.randRot * Math.PI) / 180 + (_this.disLf * _this.aveRot * Math.PI) / 180,
);
_this.rotateImgCan.translate(-_this.xPos, -_this.yPos);
_this.rotateImgCan.drawImage(
_this.slideImage,
_this.xPos - 200 / 2,
_this.yPos - 200 / 2,
200,
200,
);
_this.rotateImgCan.restore();
},
initMouse: function () {
var _this = this;
var ifThisMousedown = false;
_this.$slideDragBtn.on('mousedown', function (e) {
if (_this.verifyState) {
return false;
}
if (_this.dragTimerState) {
return false;
}
if (ifAnimate(_this.$slideDragBtn)) {
return false;
}
ifThisMousedown = true;
var positionDiv = $(this).offset();
var distenceX = e.pageX - positionDiv.left;
var disPageX = e.pageX;
_this.$slideDragBtn.addClass('control-btn-active');
_this.controlBorWrap.addClass('control-bor-active');
$(document).mousemove(function (e) {
if (!ifThisMousedown) {
return false;
}
var x = e.pageX - disPageX;
if (x < 0) {
x = 0;
} else if (x >= _this.$slideDragWrap.width() - _this.$slideDragBtn.outerWidth()) {
x = _this.$slideDragWrap.width() - _this.$slideDragBtn.outerWidth();
}
_this.$slideDragBtn.css({
left: x + 'px',
});
_this.controlBorWrap.css({
width: x + _this.$slideDragBtn.width() + 'px',
});
_this.disLf = x;
_this.drawImgCan();
e.preventDefault();
});
});
$(document)
.off('mouseup')
.on('mouseup', function () {
if (!ifThisMousedown) {
return false;
}
ifThisMousedown = false;
if (_this.verifyState) {
return false;
}
$(document).off('mousemove');
_this.$slideDragBtn.removeClass('control-btn-active');
_this.controlBorWrap.removeClass('control-bor-active');
_this.settings.verifyParam.disLf = _this.disLf;
axios.post(
_this.settings.verifyUrl,
_this.settings.verifyParam,
function (res) {
console.log('res', res);
if (res.code === 0) {
_this.$slideDragBtn.addClass('control-btn-suc');
_this.controlBorWrap.addClass('control-bor-suc');
_this.statusBg.fadeIn();
_this.statusBg.addClass('suc-bg');
_this.verifyState = true;
_this.cTipsTxt.text('');
if (_this.settings.getSuccessState) {
_this.settings.getSuccessState(res);
}
_this.$slideDragBtn.delay(700).animate(
{
left: '0px',
},
function () {
_this.dragTimerState = false;
_this.$slideDragBtn.removeClass('control-btn-suc');
_this.controlBorWrap.removeClass('control-bor-suc');
_this.statusBg.removeClass('suc-bg');
_this.statusBg.fadeOut();
_this.verifyState = false;
_this.refreshSlide();
},
);
} else {
_this.$slideDragBtn.addClass('control-btn-err');
_this.controlBorWrap.addClass('control-bor-err');
_this.$slideDragWrap.addClass('control-horizontal');
_this.dragTimerState = true;
_this.verifyState = false;
_this.statusBg.fadeIn();
_this.statusBg.addClass('err-bg');
_this.$slideDragBtn.delay(700).animate(
{
left: '0px',
},
function () {
_this.dragTimerState = false;
_this.$slideDragWrap.removeClass('control-horizontal');
_this.$slideDragBtn.removeClass('control-btn-err');
_this.statusBg.removeClass('err-bg');
_this.statusBg.fadeOut();
_this.refreshSlide();
},
);
_this.controlBorWrap.delay(700).animate(
{
width: _this.$slideDragBtn.width() + 'px',
},
function () {
_this.controlBorWrap.removeClass('control-bor-err');
},
);
}
},
'json',
);
// $.post(
// _this.settings.verifyUrl,
// _this.settings.verifyParam,
// function (res) {
// if (res.code === 0) {
// _this.$slideDragBtn.addClass('control-btn-suc');
// _this.controlBorWrap.addClass('control-bor-suc');
// _this.statusBg.fadeIn();
// _this.statusBg.addClass('suc-bg');
// _this.verifyState = true;
// _this.cTipsTxt.text('');
// if (_this.settings.getSuccessState) {
// _this.settings.getSuccessState(res);
// }
// _this.$slideDragBtn.delay(700).animate(
// {
// left: '0px',
// },
// function () {
// _this.dragTimerState = false;
// _this.$slideDragBtn.removeClass('control-btn-suc');
// _this.controlBorWrap.removeClass('control-bor-suc');
// _this.statusBg.removeClass('suc-bg');
// _this.statusBg.fadeOut();
// _this.verifyState = false;
// _this.refreshSlide();
// },
// );
// } else {
// _this.$slideDragBtn.addClass('control-btn-err');
// _this.controlBorWrap.addClass('control-bor-err');
// _this.$slideDragWrap.addClass('control-horizontal');
// _this.dragTimerState = true;
// _this.verifyState = false;
// _this.statusBg.fadeIn();
// _this.statusBg.addClass('err-bg');
// _this.$slideDragBtn.delay(700).animate(
// {
// left: '0px',
// },
// function () {
// _this.dragTimerState = false;
// _this.$slideDragWrap.removeClass('control-horizontal');
// _this.$slideDragBtn.removeClass('control-btn-err');
// _this.statusBg.removeClass('err-bg');
// _this.statusBg.fadeOut();
// _this.refreshSlide();
// },
// );
// _this.controlBorWrap.delay(700).animate(
// {
// width: _this.$slideDragBtn.width() + 'px',
// },
// function () {
// _this.controlBorWrap.removeClass('control-bor-err');
// },
// );
// }
// },
// 'json',
// );
});
},
_touchstart: function () {
var _this = this;
_this.$slideDragBtn.on('touchstart', function (e) {
_this.$slideDragBtn.css('pointer-events', 'none');
setTimeout(function () {
_this.$slideDragBtn.css('pointer-events', 'all');
}, 400);
if (_this.dragTimerState || ifAnimate(_this.$slideDragBtn) || _this.verifyState) {
return false;
}
if (getEleCssLeft(_this.$slideDragBtn) == 0) {
_this.touchX = e.originalEvent.targetTouches[0].pageX;
_this.$slideDragBtn.addClass('control-btn-active');
_this.controlBorWrap.addClass('control-bor-active');
_this._touchmove();
}
});
},
_touchmove: function () {
var _this = this;
_this.$slideDragBtn.on('touchmove', function (e) {
e.preventDefault();
if (_this.dragTimerState || ifAnimate(_this.$slideDragBtn)) {
return false;
} else {
var x = e.originalEvent.targetTouches[0].pageX - _this.touchX;
if (x < 0) {
x = 0;
} else if (x >= _this.$slideDragWrap.width() - _this.$slideDragBtn.outerWidth()) {
x = _this.$slideDragWrap.width() - _this.$slideDragBtn.outerWidth();
}
_this.$slideDragBtn.css({
left: x + 'px',
});
_this.controlBorWrap.css({
width: x + _this.$slideDragBtn.width() + 'px',
});
_this.disLf = x;
_this.drawImgCan();
}
});
},
_touchend: function () {
var _this = this;
_this.$slideDragBtn.off('touchend').on('touchend', function () {
_this.$slideDragBtn.off('touchmove');
_this.$slideDragBtn.removeClass('control-btn-active');
_this.controlBorWrap.removeClass('control-bor-active');
_this.settings.verifyParam.disLf = _this.disLf;
axios.post(
_this.settings.verifyUrl,
_this.settings.verifyParam,
function (res) {
if (res.code === 0) {
_this.verifyState = true;
_this.$slideDragBtn.addClass('control-btn-suc');
_this.controlBorWrap.addClass('control-bor-suc');
_this.statusBg.fadeIn();
_this.statusBg.addClass('suc-bg');
_this.cTipsTxt.text('');
if (_this.settings.getSuccessState) {
_this.settings.getSuccessState(_this.verifyState);
}
_this.$slideDragBtn.delay(700).animate(
{
left: '0px',
},
function () {
_this.$slideDragBtn.removeClass('control-btn-suc');
_this.controlBorWrap.removeClass('control-bor-suc');
_this.statusBg.removeClass('suc-bg');
_this.statusBg.fadeOut();
_this.dragTimerState = false;
_this.verifyState = false;
_this.refreshSlide();
},
);
} else {
if (!ifAnimate(_this.$slideDragBtn)) {
_this.dragTimerState = true;
_this.verifyState = false;
_this.statusBg.fadeIn();
_this.statusBg.addClass('err-bg');
_this.$slideDragBtn.addClass('control-btn-err');
_this.controlBorWrap.addClass('control-bor-err');
_this.$slideDragWrap.addClass('control-horizontal');
_this.$slideDragBtn.delay(700).animate(
{
left: '0px',
},
function () {
_this.$slideDragWrap.removeClass('control-horizontal');
_this.$slideDragBtn.removeClass('control-btn-err');
_this.statusBg.removeClass('err-bg');
_this.statusBg.fadeOut();
_this.dragTimerState = false;
_this.refreshSlide();
},
);
_this.controlBorWrap.delay(700).animate(
{
width: _this.$slideDragBtn.width() + 'px',
},
function () {
_this.controlBorWrap.removeClass('control-bor-err');
},
);
} else {
return false;
}
}
},
'json',
);
});
},
setAttrSrc: function () {
if (isArray(this.settings.slideImage)) {
this.slideImageSrc = getRandomImg(this.settings.slideImage);
} else {
this.slideImageSrc = this.settings.slideImage;
}
this.slideImage.setAttribute('data-src', this.slideImageSrc);
},
refreshSlide: function () {
var _this = this;
_this.initCanvasImg();
},
resetSlide: function () {
var _this = this;
_this.$slideDragBtn.css({
left: '0px',
});
_this.controlBorWrap.css({
width: _this.$slideDragBtn.width() + 'px',
});
_this.controlBorWrap.removeClass('control-bor-suc');
_this.dragTimerState = false;
_this.verifyState = false;
_this.$slideDragBtn.removeClass('control-btn-suc');
_this.$slideDragWrap.removeClass('control-horizontal');
_this.statusBg.fadeOut();
_this.statusBg.removeClass('suc-bg');
_this.cTipsTxt.text(_this.settings.initText);
_this.refreshSlide();
},
};
var inlineCss =
'*{margin:0;padding:0;box-sizing:border-box;}.rotateverify-contaniner{width:200px;margin:0 auto;}@-webkit-keyframes rotateverifyHorizontal{0%{-webkit-transform:translate(0px,0);-ms-transform:translate(0px,0);transform:translate(0px,0)}10%,30%,50%,70%,90%{-webkit-transform:translate(-1px,0);transform:translate(-1px,0)}20%,40%,60%,80%{-webkit-transform:translate(1px,0);transform:translate(1px,0)}100%{-webkit-transform:translate(0px,0);transform:translate(0px,0)}}@-moz-keyframes rotateverifyHorizontal{0%{-webkit-transform:translate(0px,0);-moz-transform:translate(0px,0);transform:translate(0px,0)}10%,30%,50%,70%,90%{-webkit-transform:translate(-1px,0);-moz-transform:translate(-1px,0);transform:translate(-1px,0)}20%,40%,60%,80%{-webkit-transform:translate(1px,0);-moz-transform:translate(1px,0);transform:translate(1px,0)}100%{-webkit-transform:translate(0px,0);-moz-transform:translate(0px,0);transform:translate(0px,0)}}@keyframes rotateverifyHorizontal{0%{-webkit-transform:translate(0px,0);-moz-transform:translate(0px,0);transform:translate(0px,0)}10%,30%,50%,70%,90%{-webkit-transform:translate(-1px,0);-moz-transform:translate(-1px,0);transform:translate(-1px,0)}20%,40%,60%,80%{-webkit-transform:translate(1px,0);-moz-transform:translate(1px,0);transform:translate(1px,0)}100%{-webkit-transform:translate(0px,0);-moz-transform:translate(0px,0);transform:translate(0px,0)}}.rotateverify-contaniner .control-horizontal{-webkit-animation:rotateverifyHorizontal .6s .2s ease both;-moz-animation:rotateverifyHorizontal .6s .2s ease both;animation:rotateverifyHorizontal .6s .2s ease both}.rotateverify-contaniner .rotate-can-wrap{width:200px;height:200px;position:relative;}.rotateverify-contaniner .status-bg{width:100%;height:100%;position:absolute;top:0;left:0;background-color:rgba(0,0,0,.3);background-repeat:no-repeat;background-position:center center;border-radius:100%;display:none;}.rotateverify-contaniner .status-bg.suc-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH4AAABWCAYAAAAJ3CLTAAAAAXNSR0IArs4c6QAABFZJREFUeAHtncuO00AQRWdALFkiXsM0Az/FArGIhPg3EAvEazEL4AdY824eQsBXhNsTW1gmiduu6vct6cp20qmuuiftOMkoc3DAqM6B9Xq9gp5Dvzq5/VV1jbKhjQOAewSdQrvC3XeVflXkAIAeQ593ER/cflpR22230kH/MoA7tbs637Zl5XfvoKOL19DJjG4uEPwMt3IbuhC6a+PiudyaYT1+Dgign01A8H4+ZzVKCh3NvCX4rJBOF6MA3U3yeHomjsjGAQcdmnP1juH/Bd/OZUPUoxDg04DunjTXPabjkBwcUITu3voxSnCA0EugpFwjoSsbWkI6Qi+BknKNStDdFzZ8TVdmEyydIvQbwYpkYl0HCF3XzyKyEXoRmHSLJHRdP4vIRuhFYNItktB1/SwiG6EXgUm3SEA3kPRbNvc+nW/ZdNGEy9ZBt9hKgtDDIdLPDNIGspAkCF0fTbiMIG0gC0mC0MMh0s8M0gaykCQIXR9NuIwgbSALSYLQwyHSzwzSBrKQJAhdH024jCBtIAtJgtDDIdLPDNIGspAkCF0fTbiMIG0gC0mC0MMh0s8M0gaykCTiQ0e1d6CH0KdOj9xt+hbVlxE+GegrJAnne7yPYTHZJejJnordfZfrw6XTEbwxkIUkERe6ax3Vut9ImYp3GMCf0Rg9V+CJgSwkiSTQ786omPAH4OGbgSwkifjQu9X+dGbVhL85Sxr4Zmd6Nx6eBnoH/ue4Go/jpuHDHwNZSBIO+tHgBBJ3F5P/WVh9k/DhlYEsJIm00LsV/1LQQVPw4ZOBLCSJ9NA78A8kXeCx76Hqr/bRo4E03qenO70PX0zQzCH0BpJE1SsfxhjIQpLIY6WP4Bt09EPSFR5b5cpHXwaqZ6UPwXen/NtoUAq/qpUPP25WDb1/EqBJDfhVrPxmoBN+78DZR9htrPR/LW/2Wl75za10wm94pe+A/x2rQBJFvOajwTZP72Po/TEMcRd8VcMn9J72aFszfEIfwR4fwqBbkMbKvzbOneqY0D2drwk+oXtC74fVAJ/Qe5oztyXDV4L+EXny+JZtJjvx8BLhE7oY+yZBSfAJXQl6n6YE+ITe01Le5gyf0JVhj9PlCF8ROv+dxxj48Dgn+IQ+JBNhPwf4hB4B9LYpUsIn9G1EIt6mBP8D8nh/tk/oEQHvmyomfMx1Akn/GtZ9IscLuX1Qfe+LAb+D/g1bSRC6L1TfcaCh8ZXu1tM+cruVTui+MGKPCwGf0GNTXDifJnxCXwgh1cM6+NJTszvta+TghVzMJ4ISfKRZHLyQiwl8OBeQaVyULSFP6EMQKfYTwCf0FKC3zRkRvrsu4Gv6NgipbosAn9BTwZ2aNyB8Qp8yP/X9AeATemqovvMrwid0X9NzGacAn9BzgTm3DgF8Qp9rdm7jF8An9NwgLq1nBnxCX2pyro8D/GPoFbQr3M+yXsm1ftYlcABgD6H70AvoN+R+dfsZdE+QttmH/gVo1WKZD73PfwAAAABJRU5ErkJggg==);}.rotateverify-contaniner .status-bg.err-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGoAAABqCAYAAABUIcSXAAAAAXNSR0IArs4c6QAABOhJREFUeAHt3F1O3DAUBeCZ7qJQUVXdQ6U+tUtBILq79okKUEGwAlaACO0DFV1C+0DPzXBnMpnYiR0nsZ1jyXUm/ok5H8wwBbJYVMrz8/MR6nfU3y9Vjo8qQ3gYOAHke4h6ivqIKrlL5seoy51L4eRr1B+opiJ9+zsTecI7AeS5h3phChznr2TM1gVwwoaka93j4GBrIh94JYAc36DeabCWVrBWX1k4kKe7roVYXjSbSQi6K5KanJSz8UieE10KsTa5Ox0hZFckcTlXKHkBcy3EciJaLBCwD5K4PMmlXjleT4e/w8ENFuFrliZiaQVJ8kJ9bxlm7RKoW+sIcyexzNmsewIglT4C9XW9qvsBsSyZBUCS1Tc+WLDLt+cYZix8zaqBISnf16RqyJtvz2V99OyjSth9CrFesBBiCKRC1qn5l1gH6CDWTjJuJwIivTVeGRchljGd9o5RkHQbxNIk3NpRkXRrxNIkurWTIOnWiKVJ2NtJkXRrxNIkmtsokHRrxNIkttuokHRrxNIkVm2USLpFYiWARKyEkOaOFfXTneLU27k9DSaJpGhzwUoaaS5YWSDljpUVUq5YWSLlhpU1Ui5Ys0BKHWtWSKlizRIpNaxZI6WCRSSVQoswovyFGSJVkPQwNiwiqUxDGwsWkRpw6qemxiJSXcTyeCosIllQTF1jYxHJJNHh/FhYROqA0TZkaCwitQk49A+FRSQHhK5DQ2MRqWvyHuMCYn3AWneofUqByea/T/L4+LKagnBC/HfT3z5CmFugEqntMwshhcDCMl6lwCwitSFpP8KaAotICuDSjoxFJBec+tiRsIhUD97n8cBYRPJBMc0ZCItIpsD7nA+MRaQ+GG1zgSVvZvu+T5L5H9uuxX7PBBBuiNvWYJmy3ONf3sLO08I4DaGGRFpRrW4nRCxj6o4dAyERy9HBOnxgJGJZ0+/YORISsTp6NA4bGYlYjQotJydCih7L9y7NLXH7dQsSZt6get/NGHP/ofqWaO+RGw1UIKQHCH1CLXylMC9arB4fU5ipgZ7uCqxT/tAPbYifZ/FNcZU3NJKuTSxNIkA7FJJujViaRI92aCTdGrE0CY92LCTdGrE0CYd2bCTdGrE0iQ7tVEi6NWJpEpZ2aiTdGrE0iYY2FiTdGrE0iUobG5JujViaBNpYkXSLxEoAiVgJIc0aK/anO8Wpt7N6GkwVSdFmgZU60iywckHKGis3pCyxckXKCit3pCyw5oKUNNbckJLEmitSUlhzR0oCi0jKtGqRR3y/N0ikbSR9FBUWkZSluY0Ci0jNOPWzk2IRqc5hfzwJFpHsKKbeUbGIZGLodn4ULCJ1w2gbNSgWFt9D5e092xQ69gfE2t+6JBa+QO1TCkzmnSMrqSKPEG+KL9dLYsFD1D6lwGQirRPdHCCXEFjH5YpY7BTVtxSYSKSNzc4R8umLdaZQj55KRNphaT7RE+tJVpW/il82L289+4Dez8vl8qd1FDvLBJDTL8kLtShPuP1T+gjUrdu8xQPGE8kxtB5YpY9AfXO45gPGEskhsOpQT6yVD54/l6hXqG2lwAB+41BN3vMYOXb9BuMaYzcvTXggb3htWNInt79hCZQA8txHvUQ1lWt0bL/hlWvjpHxlnaCeoz69VDmWcxvVQBvlMuvMj5Hv2Uvef9BK5l9QmXmKnyT/AS/pCbJI4duRAAAAAElFTkSuQmCC);}.rotateverify-contaniner .control-wrap{width:200px;position:relative;height:42px;border:1px solid #e0e0e0;clear:both;border-radius:42px;margin-top:45px;background-color:#f7f7f7;}.rotateverify-contaniner .control-wrap .control-tips{position:relative;width:100%;height:100%;}.rotateverify-contaniner .c-tips-txt{height:40px;line-height:40px;position:absolute;width:100%;text-align:center;top:0;left:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.rotateverify-contaniner .control-btn{position:absolute;left:0;top:0;width:40px;height:40px;border-radius:40px;border:1px solid #e0e0e0;background-color:#fff;}.rotateverify-contaniner .control-bor-wrap{position:absolute;left:0;top:0;width:40;height:40px;border-radius:40px;border:1px solid transparent;}.rotateverify-contaniner .control-bor-active{border:1px solid #1a91ed;}.rotateverify-contaniner .control-bor-err{border:1px solid #e01116;}.rotateverify-contaniner .control-bor-suc{border:1px solid limegreen;}.rotateverify-contaniner .control-btn-active{background:#1a91ed;}.rotateverify-contaniner .control-btn-err{background:#e01116;}.rotateverify-contaniner .control-btn-suc{background-color:limegreen;}.rotateverify-contaniner .control-btn-ico{display:block;width:20px;height:20px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAAyCAYAAAATIfj2AAAAAXNSR0IArs4c6QAABAdJREFUaAXtWUloU0EYbhaNTQWhItiIBz2kaYkHodWDBxEUa9OFIBHxoOnB3oSCgoqCKdijC3rpQTBCcYsQaUsE0eJBRIXiQZEuehJzUxCa1mIWvxFHpsPMvCUzh8oLlDfzzbxvvn+Zmb9JQ4P38TzgecDzgOeBVeQBn0prKpUKLC0tXa7VagNkns/nu93Y2Hgxl8tVVO9ZjZniJesGVYsvLi6OwJizdA7a54BtRv+PgRR3+jTFS3T4LcSk+XEYle7p6TnJ4w77pngtDRLqrFarN/r6+nYKB+sAdfAqI4Ro3JHoW1epVB5hL2yQjCthU7xkUaVBgUBgGAfBB5E6iNpeKpWyojErzBQvWTegWnxubu5XPB5/jlRIY15IMDcWjUZL8/PzrwRjUsgUL1lQeWxTRYlEIoWIPKR97lmGx/dNTEy85HDLrgleZYSoIkTgY2trazOM2k0x5knStguRHJuZmSkxuGXTBK9yD7GKIpHIGfRfsxhtw9DI8vLyvUwmY5uPvqub11aEyOLT09PV9vb2pxB/HN0wFcQ8txWLxSC8PsVglk3dvLb2EKuqu7u7C/0C/kTv1rCfEthPT9h37LR18dqOEBWFCHzCyUZSay/FmKcPETwUi8Xu4yT7weCWTV28jnOeKOvs7CT30zOJymYc8zlcumsl41JYB68rg7D5q+Fw+BiM+ipShyjtQgF6RTSmwnTwivaBas0VY6jn9pTL5RcAhVW73+8/Ojk5+WDFSzY69fA63kOsntnZ2S+4n0qIyEEWZ9pdbW1tOcz7zmCWzXp4XaUcqwgRuIrUy7MYbcPQ9ShiM7Tv5OmWt26DiEik1hCMqooEw6gdItwO5oZXi0E41a5DuJALhr63I140xw2vUISIXIahwDwNY5KicRizgIs2Ixqzwtzy/nennOsI4eLchA1PjmThkY3o3HRzZNfL68ogUlXj4ryLVNsiSh0Y8xYXL6nOHX108Lq6h5qamoZhzIBILYz5htNpfz6fd3T3EC4dvI73kK6qmHeGLl5HKdff378VERiDGKEjEJkRN/866OS1bdDg4OAa1G05pNpG3rt/+1MdHR2XJGNSWDev7T3U0tJyDcYcFilD1IqhUOjA6OjogmhchenmFaYOLwD5fQSYrGp2/a2PCV7LlEsmk1FE4BZvJO1j7Lybr7BM8Soj1NvbG0Y99QapFqcGcM/HhUJBWPZw81Z0TfGSRYS3PF0dlQDZ5DJjPuPeSNO5Tp6meIkGZcohnU5IhP4MBoMp/PDl6IsQymWK19IgKoB/ooI+NT4+/o7H6+3r4FVGCAKzvEh4N4tDQHpI8PMlfVO86j2EAvMCfmPFmfCvbssSTCLSNmyK17YAb6LnAc8DngdWrQd+A6CJYdIFu4L0AAAAAElFTkSuQmCC) no-repeat center center;background-size:100% 100%;margin:10px;}.rotateverify-contaniner .control-btn-active .control-btn-ico{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAAyCAYAAAATIfj2AAAAAXNSR0IArs4c6QAAAoRJREFUaAXtmb9OVFEQxjcQKGyspIPK2FvrA+gDAC8AL6C+gGIidvx5ABtqeABCDZSEFjtNLLTRwoLo+jvZJcBhvpnrLlPs5kzyhT3z5/vOzM1y757b6zVrE2gTaBNoE5iWCfT7/VnwAXwbonyeHbe/wgHunTfcF6KboLZPYWGQAGEKbyDb6yFcroxl62GxkwBhCq8jOQg5wr+JPQ0JREIWr5C7diP8ESj7TODhdXb3T9Sl8IY7QPgBOAfKDkISIwGyFF5D6q4L8Sfgp+oI/5u7VbEnizdWJgPxZaehS2LPOxFVSVm8lYy9RHzbaeorsQW70vdm8fqqRBGeA8dA2RGBmZCoSqAmhbeSsZeIL4LvQNl7u9L3QpbC66sOo4i/AH9FR8X/shNRlZTFW8nYS8TfioaK+wdYsit9L3UpvL4qUYRnwCFQdkpgPiSqEqhJ4a1k7CXij8AXoGzXrvS9kKXw+qrDKOLPQLkPKVvtRFQlQZbCW8nYS8RfqW7w/wKP7Urfm8Xrqw6jiO8DZXudSIwkCFN4DanbLoSXwB/R0dnt7O6rUXj/+84utrOFX3Gdi5ou7ixerc0UX4srU9zjfIdSeHUnRNhwyn+jLN6omeh+seMSiCDNpPAKuYEb0ZQ7ehav20wJIvwOKCtP46M+y6Xwug2x2el52qaZ6HfLhjsNEcziFXIDN6Lll+UJUHZEQN2LJDc1KbxS8CqA8PScKdDMClBWnrZHPfVJ4b26COZfNjs953I0k3LCmcVrXpGbToS9M+gL4hln2yPz3ty7+ZkNq9ceE/v2QTW0Zk6go9MZ1Fi8oTzCm6C2iX6DV78LLQ1mvGO9F97wCrWENoE2gTaBiZ/AP+8/LMb6T9MeAAAAAElFTkSuQmCC) no-repeat center center;background-size:100% 100%;}.rotateverify-contaniner .control-btn-err .control-btn-ico{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGoAAABqCAYAAABUIcSXAAAAAXNSR0IArs4c6QAABOhJREFUeAHt3F1O3DAUBeCZ7qJQUVXdQ6U+tUtBILq79okKUEGwAlaACO0DFV1C+0DPzXBnMpnYiR0nsZ1jyXUm/ok5H8wwBbJYVMrz8/MR6nfU3y9Vjo8qQ3gYOAHke4h6ivqIKrlL5seoy51L4eRr1B+opiJ9+zsTecI7AeS5h3phChznr2TM1gVwwoaka93j4GBrIh94JYAc36DeabCWVrBWX1k4kKe7roVYXjSbSQi6K5KanJSz8UieE10KsTa5Ox0hZFckcTlXKHkBcy3EciJaLBCwD5K4PMmlXjleT4e/w8ENFuFrliZiaQVJ8kJ9bxlm7RKoW+sIcyexzNmsewIglT4C9XW9qvsBsSyZBUCS1Tc+WLDLt+cYZix8zaqBISnf16RqyJtvz2V99OyjSth9CrFesBBiCKRC1qn5l1gH6CDWTjJuJwIivTVeGRchljGd9o5RkHQbxNIk3NpRkXRrxNIkurWTIOnWiKVJ2NtJkXRrxNIkmtsokHRrxNIkttuokHRrxNIkVm2USLpFYiWARKyEkOaOFfXTneLU27k9DSaJpGhzwUoaaS5YWSDljpUVUq5YWSLlhpU1Ui5Ys0BKHWtWSKlizRIpNaxZI6WCRSSVQoswovyFGSJVkPQwNiwiqUxDGwsWkRpw6qemxiJSXcTyeCosIllQTF1jYxHJJNHh/FhYROqA0TZkaCwitQk49A+FRSQHhK5DQ2MRqWvyHuMCYn3AWneofUqByea/T/L4+LKagnBC/HfT3z5CmFugEqntMwshhcDCMl6lwCwitSFpP8KaAotICuDSjoxFJBec+tiRsIhUD97n8cBYRPJBMc0ZCItIpsD7nA+MRaQ+GG1zgSVvZvu+T5L5H9uuxX7PBBBuiNvWYJmy3ONf3sLO08I4DaGGRFpRrW4nRCxj6o4dAyERy9HBOnxgJGJZ0+/YORISsTp6NA4bGYlYjQotJydCih7L9y7NLXH7dQsSZt6get/NGHP/ofqWaO+RGw1UIKQHCH1CLXylMC9arB4fU5ipgZ7uCqxT/tAPbYifZ/FNcZU3NJKuTSxNIkA7FJJujViaRI92aCTdGrE0CY92LCTdGrE0CYd2bCTdGrE0iQ7tVEi6NWJpEpZ2aiTdGrE0iYY2FiTdGrE0iUobG5JujViaBNpYkXSLxEoAiVgJIc0aK/anO8Wpt7N6GkwVSdFmgZU60iywckHKGis3pCyxckXKCit3pCyw5oKUNNbckJLEmitSUlhzR0oCi0jKtGqRR3y/N0ikbSR9FBUWkZSluY0Ci0jNOPWzk2IRqc5hfzwJFpHsKKbeUbGIZGLodn4ULCJ1w2gbNSgWFt9D5e092xQ69gfE2t+6JBa+QO1TCkzmnSMrqSKPEG+KL9dLYsFD1D6lwGQirRPdHCCXEFjH5YpY7BTVtxSYSKSNzc4R8umLdaZQj55KRNphaT7RE+tJVpW/il82L289+4Dez8vl8qd1FDvLBJDTL8kLtShPuP1T+gjUrdu8xQPGE8kxtB5YpY9AfXO45gPGEskhsOpQT6yVD54/l6hXqG2lwAB+41BN3vMYOXb9BuMaYzcvTXggb3htWNInt79hCZQA8txHvUQ1lWt0bL/hlWvjpHxlnaCeoz69VDmWcxvVQBvlMuvMj5Hv2Uvef9BK5l9QmXmKnyT/AS/pCbJI4duRAAAAAElFTkSuQmCC) no-repeat center center;background-size:100% 100%;}.rotateverify-contaniner .control-btn-suc .control-btn-ico{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH4AAABWCAYAAAAJ3CLTAAAAAXNSR0IArs4c6QAABFZJREFUeAHtncuO00AQRWdALFkiXsM0Az/FArGIhPg3EAvEazEL4AdY824eQsBXhNsTW1gmiduu6vct6cp20qmuuiftOMkoc3DAqM6B9Xq9gp5Dvzq5/VV1jbKhjQOAewSdQrvC3XeVflXkAIAeQ593ER/cflpR22230kH/MoA7tbs637Zl5XfvoKOL19DJjG4uEPwMt3IbuhC6a+PiudyaYT1+Dgign01A8H4+ZzVKCh3NvCX4rJBOF6MA3U3yeHomjsjGAQcdmnP1juH/Bd/OZUPUoxDg04DunjTXPabjkBwcUITu3voxSnCA0EugpFwjoSsbWkI6Qi+BknKNStDdFzZ8TVdmEyydIvQbwYpkYl0HCF3XzyKyEXoRmHSLJHRdP4vIRuhFYNItktB1/SwiG6EXgUm3SEA3kPRbNvc+nW/ZdNGEy9ZBt9hKgtDDIdLPDNIGspAkCF0fTbiMIG0gC0mC0MMh0s8M0gaykCQIXR9NuIwgbSALSYLQwyHSzwzSBrKQJAhdH024jCBtIAtJgtDDIdLPDNIGspAkCF0fTbiMIG0gC0mC0MMh0s8M0gaykCTiQ0e1d6CH0KdOj9xt+hbVlxE+GegrJAnne7yPYTHZJejJnordfZfrw6XTEbwxkIUkERe6ax3Vut9ImYp3GMCf0Rg9V+CJgSwkiSTQ786omPAH4OGbgSwkifjQu9X+dGbVhL85Sxr4Zmd6Nx6eBnoH/ue4Go/jpuHDHwNZSBIO+tHgBBJ3F5P/WVh9k/DhlYEsJIm00LsV/1LQQVPw4ZOBLCSJ9NA78A8kXeCx76Hqr/bRo4E03qenO70PX0zQzCH0BpJE1SsfxhjIQpLIY6WP4Bt09EPSFR5b5cpHXwaqZ6UPwXen/NtoUAq/qpUPP25WDb1/EqBJDfhVrPxmoBN+78DZR9htrPR/LW/2Wl75za10wm94pe+A/x2rQBJFvOajwTZP72Po/TEMcRd8VcMn9J72aFszfEIfwR4fwqBbkMbKvzbOneqY0D2drwk+oXtC74fVAJ/Qe5oztyXDV4L+EXny+JZtJjvx8BLhE7oY+yZBSfAJXQl6n6YE+ITe01Le5gyf0JVhj9PlCF8ROv+dxxj48Dgn+IQ+JBNhPwf4hB4B9LYpUsIn9G1EIt6mBP8D8nh/tk/oEQHvmyomfMx1Akn/GtZ9IscLuX1Qfe+LAb+D/g1bSRC6L1TfcaCh8ZXu1tM+cruVTui+MGKPCwGf0GNTXDifJnxCXwgh1cM6+NJTszvta+TghVzMJ4ISfKRZHLyQiwl8OBeQaVyULSFP6EMQKfYTwCf0FKC3zRkRvrsu4Gv6NgipbosAn9BTwZ2aNyB8Qp8yP/X9AeATemqovvMrwid0X9NzGacAn9BzgTm3DgF8Qp9rdm7jF8An9NwgLq1nBnxCX2pyro8D/GPoFbQr3M+yXsm1ftYlcABgD6H70AvoN+R+dfsZdE+QttmH/gVo1WKZD73PfwAAAABJRU5ErkJggg==) no-repeat center center;background-size:100% 100%;}';
var styleObj = $('<style type="text/css" display="none">' + inlineCss + '</style>');
$('head').prepend(styleObj);
_global = (function () {
return this || (0, eval)('this');
})();
if (typeof module !== 'undefined' && module.exports) {
module.exports = RotateVerify;
} else if (typeof define === 'function' && define.amd) {
define(function () {
return RotateVerify;
});
} else {
!('RotateVerify' in _global) && (_global.RotateVerify = RotateVerify);
}
})();
// export const RotateVerify = RotateVerify;
export { RotateVerify };
import { fetchEventSource } from '@fortaine/fetch-event-source';
function getToken() {
return window.localStorage.getItem('kiwi.token') ? window.localStorage.getItem('kiwi.token') : '';
}
export default async function fetchEventSourceFn(url, options) {
const token = getToken();
// 应用设置
const appId = 'TzEU5jPk2tu80266';
const appSecret = '0a006048a4480481b18fef1405120b83';
const timestamp = Math.floor(Date.now() / 1000);
const defaultHeaders = {
Authorization: token,
AppId: appId,
AppSecret: appSecret,
Timestamp: timestamp,
'Content-Type': 'application/json',
};
const defaultOptions = {
method: 'POST',
headers: { ...defaultHeaders },
async onopen(response) {
if (response.ok) {
return response;
} else {
throw response;
}
},
onmessage(res) {
const message = JSON.parse(res.data);
console.log(res.data);
},
};
await fetchEventSource(url, { ...defaultOptions, ...options });
}
...@@ -3,7 +3,6 @@ import Axios from 'axios'; ...@@ -3,7 +3,6 @@ import Axios from 'axios';
import { message, Modal, notification } from 'antd'; import { message, Modal, notification } from 'antd';
import md5 from 'js-md5'; import md5 from 'js-md5';
import { get } from 'lodash-es'; import { get } from 'lodash-es';
import cancelRequestArr from './cancelRequestArr';
import { sortObjASCII } from '@/utils/common.js'; import { sortObjASCII } from '@/utils/common.js';
import qs from 'qs'; import qs from 'qs';
...@@ -14,10 +13,7 @@ let CancelToken = Axios.CancelToken; ...@@ -14,10 +13,7 @@ let CancelToken = Axios.CancelToken;
// 取消请求 方法 // 取消请求 方法
let cancelPending = (config) => { let cancelPending = (config) => {
pending.forEach((item) => { pending.forEach((item) => {
// cancelRequestArr包含的请求,重复请求 让他取消请求
if (cancelRequestArr.includes(item.url)) {
item.cancel(); // 取消请求 item.cancel(); // 取消请求
}
}); });
pending = []; // 清空数组 pending = []; // 清空数组
}; };
...@@ -121,7 +117,7 @@ axios.interceptors.response.use( ...@@ -121,7 +117,7 @@ axios.interceptors.response.use(
if (code === 401 || code === 403) { if (code === 401 || code === 403) {
if (!axios.errorNotified) { if (!axios.errorNotified) {
axios.errorNotified = true; // 添加标志,表示通知已经弹出 axios.errorNotified = true; // 添加标志,表示通知已经弹出
if (pathname === '/user/login') { if (pathname === '/login') {
return; return;
} }
Modal.warning({ Modal.warning({
...@@ -129,7 +125,7 @@ axios.interceptors.response.use( ...@@ -129,7 +125,7 @@ axios.interceptors.response.use(
// content: '请重新登录', // content: '请重新登录',
onOk() { onOk() {
localStorage.removeItem('kiwi.gpt.token'); localStorage.removeItem('kiwi.gpt.token');
window.location.pathname = '/user/login'; window.location.pathname = '/login';
}, },
}); });
cancelPending(response.config); // 取消后续请求 cancelPending(response.config); // 取消后续请求
...@@ -154,7 +150,7 @@ axios.interceptors.response.use( ...@@ -154,7 +150,7 @@ axios.interceptors.response.use(
content: '请重新登录', content: '请重新登录',
onOk() { onOk() {
localStorage.removeItem('kiwi.gpt.token'); localStorage.removeItem('kiwi.gpt.token');
window.location.href = '/user/login'; window.location.href = '/login';
}, },
}); });
} }
...@@ -169,7 +165,7 @@ axios.interceptors.response.use( ...@@ -169,7 +165,7 @@ axios.interceptors.response.use(
content: '请重新登录', content: '请重新登录',
onOk() { onOk() {
localStorage.removeItem('kiwi.gpt.token'); localStorage.removeItem('kiwi.gpt.token');
window.location.href = '/user/login'; window.location.href = '/login';
}, },
}); });
} }
......
import axios from './request'; import axios from './request';
import qs from 'qs';
import { get } from 'lodash-es'; import { get } from 'lodash-es';
import { message } from 'antd'; import { message } from 'antd';
// 统一上传 // 统一上传
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论