对接关于我们 ,正则法规,帮助中心 ,用户提问模块
This commit is contained in:
@ -1,45 +0,0 @@
|
||||
import { defineConfig } from 'umi';
|
||||
import proxy from './proxy';
|
||||
export default defineConfig({
|
||||
proxy: proxy['UAT'],
|
||||
define:{
|
||||
//商城2.0跳转地址
|
||||
REACT_APP_MALL_V2_URL:'http://111.198.162.67/zglt/index_hzf.jsp?id=dev',
|
||||
|
||||
//各系统跳转参数
|
||||
REACT_APP_CLIENT_KEY : 'KgPEkttG',
|
||||
// REACT_APP_CLIENT_SECRET :'ae5bdb183c502355d2055b3de73300aa73cbfdf3',
|
||||
|
||||
//密码加密参数
|
||||
REACT_APP_PASSWORD_CIPHERMODE:'1',
|
||||
REACT_APP_PASSWORD_PUBLICKEY:'0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B',
|
||||
|
||||
//当前环境
|
||||
START_ENV:'UAT',
|
||||
|
||||
//询价查看报价跳转地址
|
||||
// REACT_APP_XUNJIA_REDIRECT: 'http://10.0.204.215:8280/provider_uat',
|
||||
//询价-查看报价详情-虚拟用户uid
|
||||
REACT_APP_XUNJIA_UID: 'admin_entrance',
|
||||
|
||||
// //智慧客服ws地址
|
||||
// REACT_APP_CUSTOMERSERVICE_WS_REDIRECT: 'ws://10.242.31.158:18022/api/api/biz-customer-service',
|
||||
|
||||
//智慧客服用户中心地址
|
||||
REACT_APP_CUSTOMERSERVICE_USERCENTER: 'http://10.242.31.158:18022/auth/oauth/authorize?response_type=code',
|
||||
|
||||
//智慧客服client_id
|
||||
REACT_APP_CUSTOMERSERVICE_CLIENT_ID: 'COsHJydx',
|
||||
|
||||
//智慧客服地址
|
||||
REACT_APP_CUSTOMERSERVICE_REDIRECT: 'http://10.242.31.158:8632',
|
||||
|
||||
// //智慧客服文档中心查看图片地址
|
||||
// REACT_APP_CUSTOMERSERVICE_DOC_REDIRECT: 'http://cos.gz-tst.cos.tg.unicom.local/349553515466:mall/',
|
||||
|
||||
// //智慧客服加密公钥私钥ciphercode
|
||||
// REACT_APP_CUSTOMERSERVICE_PUBLICKEY : '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B',
|
||||
// REACT_APP_CUSTOMERSERVICE_PRIVATEKEY : '4F7144028D4DCF88FA50F0E2B3FFDDCF63BBE17D1700537DCE037687D3AA3DA7',
|
||||
// REACT_APP_CUSTOMERSERVICE_CIPHERCODE : 1,
|
||||
},
|
||||
});
|
@ -1,43 +0,0 @@
|
||||
import { defineConfig } from 'umi';
|
||||
import proxy from './proxy';
|
||||
export default defineConfig({
|
||||
proxy: proxy['sim'],
|
||||
define: {
|
||||
//商城2.0跳转地址
|
||||
REACT_APP_MALL_V2_URL: 'http://111.198.162.67/zglt/index_hzf.jsp?id=dev',
|
||||
|
||||
//各系统跳转参数
|
||||
REACT_APP_CLIENT_KEY: 'KgPEkttG',
|
||||
// REACT_APP_CLIENT_SECRET: 'ae5bdb183c502355d2055b3de73300aa73cbfdf3',
|
||||
|
||||
//密码加密参数
|
||||
REACT_APP_PASSWORD_CIPHERMODE: '1',
|
||||
REACT_APP_PASSWORD_PUBLICKEY: '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B',
|
||||
|
||||
//当前环境
|
||||
START_ENV: 'sim',
|
||||
|
||||
//询价查看报价跳转地址
|
||||
// REACT_APP_XUNJIA_REDIRECT: 'http://10.0.204.215:8080/provider',
|
||||
//询价-查看报价详情-虚拟用户uid
|
||||
REACT_APP_XUNJIA_UID: 'admin_entrance',
|
||||
//智慧客服用户中心地址
|
||||
REACT_APP_CUSTOMERSERVICE_USERCENTER: 'http://10.242.31.158:8100/auth/oauth/authorize?response_type=code',
|
||||
|
||||
//智慧客服client_id
|
||||
REACT_APP_CUSTOMERSERVICE_CLIENT_ID: 'COsHJydx',
|
||||
|
||||
//智慧客服地址
|
||||
REACT_APP_CUSTOMERSERVICE_REDIRECT: 'http://10.242.31.158:8632',
|
||||
// //智慧客服ws地址
|
||||
// REACT_APP_CUSTOMERSERVICE_WS_REDIRECT: 'ws://10.242.31.54:18022/api/api/biz-customer-service',
|
||||
|
||||
// //智慧客服文档中心查看图片地址
|
||||
// REACT_APP_CUSTOMERSERVICE_DOC_REDIRECT: 'http://cos.xx-pbc.cos.tg.unicom.local/349553515466:mall/',
|
||||
|
||||
// //智慧客服加密公钥私钥ciphercode
|
||||
// REACT_APP_CUSTOMERSERVICE_PUBLICKEY : '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B',
|
||||
// REACT_APP_CUSTOMERSERVICE_PRIVATEKEY : '4F7144028D4DCF88FA50F0E2B3FFDDCF63BBE17D1700537DCE037687D3AA3DA7',
|
||||
// REACT_APP_CUSTOMERSERVICE_CIPHERCODE : 1,
|
||||
},
|
||||
});
|
@ -7,87 +7,11 @@ export default {
|
||||
// },
|
||||
'/api': {
|
||||
// target: 'http://10.242.37.148:18022',//连接天宫的ng
|
||||
target: 'http://10.0.0.14:18012',//连接天宫的ng
|
||||
target: 'http://10.0.0.10:18013',//连接天宫的ng
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '^/api': '' },
|
||||
},
|
||||
},
|
||||
UAT: {
|
||||
'/api/core-service-ebtp-userinfo': {
|
||||
target: 'http://localhost:18023',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/core-service-ebtp-userinfo': '' },
|
||||
},
|
||||
'/api/biz-service-ebtp-bid': {
|
||||
target: 'http://localhost:18003',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { 'biz-service-ebtp-bid': '' },
|
||||
},
|
||||
'/api/biz-service-ebtp-extend': {
|
||||
target: 'http://localhost:18018',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/biz-service-ebtp-extend': '' },
|
||||
},
|
||||
'/api/biz-service-ebtp-project': {
|
||||
target: 'http://localhost:18012',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/biz-service-ebtp-project': '' },
|
||||
},
|
||||
'/api/sys-manager-ebtp-project': {
|
||||
target: 'http://localhost:18030',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/sys-manager-ebtp-project': '' },
|
||||
},
|
||||
'/api/biz-service-ebtp-rsms': {
|
||||
target: 'http://localhost:18014',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/biz-service-ebtp-rsms': '' },
|
||||
},
|
||||
'/api/biz-service-ebtp-agency': {
|
||||
target: 'http://localhost:18099',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/biz-service-ebtp-agency': '' },
|
||||
},
|
||||
'/api/biz-supplier-manage': {
|
||||
target: 'http://localhost:18096',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/biz-supplier-manage': '' },
|
||||
}
|
||||
|
||||
// '/api/wfap/v1/audit/bill/find/by/procid': {
|
||||
// target: 'http://10.242.31.158:8891/',//审批单 uat环境自动审批,暂时用不到
|
||||
// changeOrigin: true,
|
||||
// pathRewrite: { '^': '' },
|
||||
// },
|
||||
// '/living/api/*': {
|
||||
// // target: 'https://ai.cubigdata.cn:5001',//连接天宫的ng
|
||||
// target: 'http://localhost:3000',//连接天宫的ng
|
||||
// changeOrigin: true,
|
||||
// pathRewrite: { '/living/api': '' },
|
||||
// },
|
||||
// '/api/*': {
|
||||
// target: 'http://10.242.31.158:18022',//连接天宫的ng
|
||||
// changeOrigin: true,
|
||||
// pathRewrite: { '^': '' },
|
||||
// },
|
||||
// '/doc/v1.0/*': {
|
||||
// target: 'http://10.242.31.158:8806',//连接天宫的ng
|
||||
// changeOrigin: true,
|
||||
// pathRewrite: { '^': '' },
|
||||
// },
|
||||
},
|
||||
sim: {
|
||||
// '/api/wfap/v1/audit/bill/find/by/procid': {
|
||||
// target: 'http://10.242.31.158:8891/',//审批单 uat环境自动审批,暂时用不到
|
||||
// changeOrigin: true,
|
||||
// pathRewrite: { '^': '' },
|
||||
// },
|
||||
'/api/*': {
|
||||
target: 'http://10.242.31.54:18022',//连接天宫的ng
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '^': '' },
|
||||
},
|
||||
},
|
||||
prod: {
|
||||
'/api/*': {
|
||||
target: 'http://uscm.unicom.local:18022',//连接天宫的ng
|
||||
|
@ -69,6 +69,21 @@ export default [
|
||||
name: 'about',
|
||||
path: '/about',
|
||||
component: '@/pages/about/about',
|
||||
},
|
||||
{
|
||||
name: 'help',
|
||||
path: '/help',
|
||||
component: '@/pages/help/help',
|
||||
},
|
||||
{
|
||||
name: 'helpInfo',
|
||||
path: '/help/helpInfo',
|
||||
component: '@/pages/help/helpInfo',
|
||||
},
|
||||
{
|
||||
name: 'helpQuestion',
|
||||
path: '/help/helpQuestion',
|
||||
component: '@/pages/help/helpQuestion',
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -5,12 +5,8 @@
|
||||
"description": "An out-of-box UI solution for enterprise applications",
|
||||
"scripts": {
|
||||
"start-dev": "cross-env UMI_UI=none UMI_ENV=dev LOGIN_PATH=ebtp-frontend umi dev --port=3000",
|
||||
"start-UAT": "cross-env NODE_OPTIONS=--openssl-legacy-provider UMI_UI=none UMI_ENV=UAT LOGIN_PATH=ebtp-frontend umi dev --port=3000",
|
||||
"start-sim": "cross-env UMI_UI=none UMI_ENV=sim LOGIN_PATH=ebtp-frontend umi dev --port=3000",
|
||||
"start-prod": "cross-env UMI_UI=none UMI_ENV=prod LOGIN_PATH=prod/ebtp-frontend umi dev --port=3000",
|
||||
"build-dev": "cross-env UMI_ENV=dev LOGIN_PATH=ebtp-frontend umi build",
|
||||
"build-UAT": "cross-env UMI_ENV=UAT LOGIN_PATH=ebtp-frontend umi build",
|
||||
"build-sim": "cross-env UMI_ENV=sim LOGIN_PATH=ebtp-frontend umi build",
|
||||
"build-prod": "cross-env UMI_ENV=prod LOGIN_PATH=prod/ebtp-frontend umi build",
|
||||
"analyze": "cross-env ANALYZE=1 umi build",
|
||||
"build": "umi build",
|
||||
@ -68,6 +64,8 @@
|
||||
"@material-ui/core": "4.11.3",
|
||||
"@types/react-cookies": "0.1.0",
|
||||
"@umijs/route-utils": "1.0.37",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-react": "^1.0.6",
|
||||
"antd": "4.15.1",
|
||||
"array-move": "3.0.1",
|
||||
"axios": "0.21.1",
|
||||
|
409
pnpm-lock.yaml
generated
409
pnpm-lock.yaml
generated
@ -32,6 +32,12 @@ dependencies:
|
||||
'@umijs/route-utils':
|
||||
specifier: 1.0.37
|
||||
version: 1.0.37
|
||||
'@wangeditor/editor':
|
||||
specifier: ^5.1.23
|
||||
version: 5.1.23
|
||||
'@wangeditor/editor-for-react':
|
||||
specifier: ^1.0.6
|
||||
version: 1.0.6(@wangeditor/core@1.1.19)(@wangeditor/editor@5.1.23)(react-dom@16.14.0)(react@16.14.0)
|
||||
antd:
|
||||
specifier: 4.15.1
|
||||
version: 4.15.1(react-dom@16.14.0)(react@16.14.0)
|
||||
@ -2659,6 +2665,10 @@ packages:
|
||||
engines: {node: '>= 6'}
|
||||
dev: true
|
||||
|
||||
/@transloadit/prettier-bytes@0.0.7:
|
||||
resolution: {integrity: sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==}
|
||||
dev: false
|
||||
|
||||
/@types/babel__core@7.20.5:
|
||||
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
|
||||
dependencies:
|
||||
@ -2724,6 +2734,10 @@ packages:
|
||||
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
||||
dev: true
|
||||
|
||||
/@types/event-emitter@0.3.5:
|
||||
resolution: {integrity: sha512-zx2/Gg0Eg7gwEiOIIh5w9TrhKKTeQh7CPCOPNc0el4pLSwzebA8SmnHwZs2dWlLONvyulykSwGSQxQHLhjGLvQ==}
|
||||
dev: false
|
||||
|
||||
/@types/express-serve-static-core@4.19.6:
|
||||
resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==}
|
||||
dependencies:
|
||||
@ -3973,6 +3987,237 @@ packages:
|
||||
strip-indent: 2.0.0
|
||||
dev: true
|
||||
|
||||
/@uppy/companion-client@2.2.2:
|
||||
resolution: {integrity: sha512-5mTp2iq97/mYSisMaBtFRry6PTgZA6SIL7LePteOV5x0/DxKfrZW3DEiQERJmYpHzy7k8johpm2gHnEKto56Og==}
|
||||
dependencies:
|
||||
'@uppy/utils': 4.1.3
|
||||
namespace-emitter: 2.0.1
|
||||
dev: false
|
||||
|
||||
/@uppy/core@2.3.4:
|
||||
resolution: {integrity: sha512-iWAqppC8FD8mMVqewavCz+TNaet6HPXitmGXpGGREGrakZ4FeuWytVdrelydzTdXx6vVKkOmI2FLztGg73sENQ==}
|
||||
dependencies:
|
||||
'@transloadit/prettier-bytes': 0.0.7
|
||||
'@uppy/store-default': 2.1.1
|
||||
'@uppy/utils': 4.1.3
|
||||
lodash.throttle: 4.1.1
|
||||
mime-match: 1.0.2
|
||||
namespace-emitter: 2.0.1
|
||||
nanoid: 3.3.11
|
||||
preact: 10.26.9
|
||||
dev: false
|
||||
|
||||
/@uppy/store-default@2.1.1:
|
||||
resolution: {integrity: sha512-xnpTxvot2SeAwGwbvmJ899ASk5tYXhmZzD/aCFsXePh/v8rNvR2pKlcQUH7cF/y4baUGq3FHO/daKCok/mpKqQ==}
|
||||
dev: false
|
||||
|
||||
/@uppy/utils@4.1.3:
|
||||
resolution: {integrity: sha512-nTuMvwWYobnJcytDO3t+D6IkVq/Qs4Xv3vyoEZ+Iaf8gegZP+rEyoaFT2CK5XLRMienPyqRqNbIfRuFaOWSIFw==}
|
||||
dependencies:
|
||||
lodash.throttle: 4.1.1
|
||||
dev: false
|
||||
|
||||
/@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4):
|
||||
resolution: {integrity: sha512-YWOQ6myBVPs+mhNjfdWsQyMRWUlrDLMoaG7nvf/G6Y3GKZf8AyjFDjvvJ49XWQ+DaZOftGkHmF1uh/DBeGivJQ==}
|
||||
peerDependencies:
|
||||
'@uppy/core': ^2.3.3
|
||||
dependencies:
|
||||
'@uppy/companion-client': 2.2.2
|
||||
'@uppy/core': 2.3.4
|
||||
'@uppy/utils': 4.1.3
|
||||
nanoid: 3.3.11
|
||||
dev: false
|
||||
|
||||
/@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2):
|
||||
resolution: {integrity: sha512-cY9CPkLJaqF05STqfpZKWG4LpxTMeGSIIF1fHvfm/mz+JXatCagjdkbxdikOuKYlxDdeqvOeBmsUBItufDLXZg==}
|
||||
peerDependencies:
|
||||
'@wangeditor/core': 1.x
|
||||
dom7: ^3.0.0
|
||||
lodash.throttle: ^4.1.1
|
||||
nanoid: ^3.2.0
|
||||
slate: ^0.72.0
|
||||
snabbdom: ^3.1.0
|
||||
dependencies:
|
||||
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
dom7: 3.0.0
|
||||
is-url: 1.2.4
|
||||
lodash.throttle: 4.1.1
|
||||
nanoid: 3.3.11
|
||||
slate: 0.72.8
|
||||
snabbdom: 3.6.2
|
||||
dev: false
|
||||
|
||||
/@wangeditor/code-highlight@1.0.3(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2):
|
||||
resolution: {integrity: sha512-iazHwO14XpCuIWJNTQTikqUhGKyqj+dUNWJ9288Oym9M2xMVHvnsOmDU2sgUDWVy+pOLojReMPgXCsvvNlOOhw==}
|
||||
peerDependencies:
|
||||
'@wangeditor/core': 1.x
|
||||
dom7: ^3.0.0
|
||||
slate: ^0.72.0
|
||||
snabbdom: ^3.1.0
|
||||
dependencies:
|
||||
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
dom7: 3.0.0
|
||||
prismjs: 1.30.0
|
||||
slate: 0.72.8
|
||||
snabbdom: 3.6.2
|
||||
dev: false
|
||||
|
||||
/@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2):
|
||||
resolution: {integrity: sha512-KevkB47+7GhVszyYF2pKGKtCSj/YzmClsD03C3zTt+9SR2XWT5T0e3yQqg8baZpcMvkjs1D8Dv4fk8ok/UaS2Q==}
|
||||
peerDependencies:
|
||||
'@uppy/core': ^2.1.1
|
||||
'@uppy/xhr-upload': ^2.0.3
|
||||
dom7: ^3.0.0
|
||||
is-hotkey: ^0.2.0
|
||||
lodash.camelcase: ^4.3.0
|
||||
lodash.clonedeep: ^4.5.0
|
||||
lodash.debounce: ^4.0.8
|
||||
lodash.foreach: ^4.5.0
|
||||
lodash.isequal: ^4.5.0
|
||||
lodash.throttle: ^4.1.1
|
||||
lodash.toarray: ^4.4.0
|
||||
nanoid: ^3.2.0
|
||||
slate: ^0.72.0
|
||||
snabbdom: ^3.1.0
|
||||
dependencies:
|
||||
'@types/event-emitter': 0.3.5
|
||||
'@uppy/core': 2.3.4
|
||||
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
|
||||
dom7: 3.0.0
|
||||
event-emitter: 0.3.5
|
||||
html-void-elements: 2.0.1
|
||||
i18next: 20.6.1
|
||||
is-hotkey: 0.2.0
|
||||
lodash.camelcase: 4.3.0
|
||||
lodash.clonedeep: 4.5.0
|
||||
lodash.debounce: 4.0.8
|
||||
lodash.foreach: 4.5.0
|
||||
lodash.isequal: 4.5.0
|
||||
lodash.throttle: 4.1.1
|
||||
lodash.toarray: 4.4.0
|
||||
nanoid: 3.3.11
|
||||
scroll-into-view-if-needed: 2.2.31
|
||||
slate: 0.72.8
|
||||
slate-history: 0.66.0(slate@0.72.8)
|
||||
snabbdom: 3.6.2
|
||||
dev: false
|
||||
|
||||
/@wangeditor/editor-for-react@1.0.6(@wangeditor/core@1.1.19)(@wangeditor/editor@5.1.23)(react-dom@16.14.0)(react@16.14.0):
|
||||
resolution: {integrity: sha512-KJNSfgMr5Blzae3oyaiz20flMKHZHnvsz4bCYQKDCUs/qkvC+xNTnwedlCmhGP187oPWPEypCIYI8Zg6sz0psQ==}
|
||||
peerDependencies:
|
||||
'@wangeditor/core': '>=1.1.0'
|
||||
'@wangeditor/editor': '>=5.1.0'
|
||||
react: '>=17.0.2'
|
||||
react-dom: '>=17.0.2'
|
||||
dependencies:
|
||||
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
'@wangeditor/editor': 5.1.23
|
||||
react: 16.14.0
|
||||
react-dom: 16.14.0(react@16.14.0)
|
||||
dev: false
|
||||
|
||||
/@wangeditor/editor@5.1.23:
|
||||
resolution: {integrity: sha512-0RxfeVTuK1tktUaPROnCoFfaHVJpRAIE2zdS0mpP+vq1axVQpLjM8+fCvKzqYIkH0Pg+C+44hJpe3VVroSkEuQ==}
|
||||
dependencies:
|
||||
'@uppy/core': 2.3.4
|
||||
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
|
||||
'@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
'@wangeditor/code-highlight': 1.0.3(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
'@wangeditor/list-module': 1.0.5(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
'@wangeditor/table-module': 1.1.4(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
'@wangeditor/upload-image-module': 1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/basic-modules@1.1.7)(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
'@wangeditor/video-module': 1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/core@1.1.19)(dom7@3.0.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
dom7: 3.0.0
|
||||
is-hotkey: 0.2.0
|
||||
lodash.camelcase: 4.3.0
|
||||
lodash.clonedeep: 4.5.0
|
||||
lodash.debounce: 4.0.8
|
||||
lodash.foreach: 4.5.0
|
||||
lodash.isequal: 4.5.0
|
||||
lodash.throttle: 4.1.1
|
||||
lodash.toarray: 4.4.0
|
||||
nanoid: 3.3.11
|
||||
slate: 0.72.8
|
||||
snabbdom: 3.6.2
|
||||
dev: false
|
||||
|
||||
/@wangeditor/list-module@1.0.5(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2):
|
||||
resolution: {integrity: sha512-uDuYTP6DVhcYf7mF1pTlmNn5jOb4QtcVhYwSSAkyg09zqxI1qBqsfUnveeDeDqIuptSJhkh81cyxi+MF8sEPOQ==}
|
||||
peerDependencies:
|
||||
'@wangeditor/core': 1.x
|
||||
dom7: ^3.0.0
|
||||
slate: ^0.72.0
|
||||
snabbdom: ^3.1.0
|
||||
dependencies:
|
||||
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
dom7: 3.0.0
|
||||
slate: 0.72.8
|
||||
snabbdom: 3.6.2
|
||||
dev: false
|
||||
|
||||
/@wangeditor/table-module@1.1.4(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2):
|
||||
resolution: {integrity: sha512-5saanU9xuEocxaemGdNi9t8MCDSucnykEC6jtuiT72kt+/Hhh4nERYx1J20OPsTCCdVr7hIyQenFD1iSRkIQ6w==}
|
||||
peerDependencies:
|
||||
'@wangeditor/core': 1.x
|
||||
dom7: ^3.0.0
|
||||
lodash.isequal: ^4.5.0
|
||||
lodash.throttle: ^4.1.1
|
||||
nanoid: ^3.2.0
|
||||
slate: ^0.72.0
|
||||
snabbdom: ^3.1.0
|
||||
dependencies:
|
||||
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
dom7: 3.0.0
|
||||
lodash.isequal: 4.5.0
|
||||
lodash.throttle: 4.1.1
|
||||
nanoid: 3.3.11
|
||||
slate: 0.72.8
|
||||
snabbdom: 3.6.2
|
||||
dev: false
|
||||
|
||||
/@wangeditor/upload-image-module@1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/basic-modules@1.1.7)(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.2):
|
||||
resolution: {integrity: sha512-z81lk/v71OwPDYeQDxj6cVr81aDP90aFuywb8nPD6eQeECtOymrqRODjpO6VGvCVxVck8nUxBHtbxKtjgcwyiA==}
|
||||
peerDependencies:
|
||||
'@uppy/core': ^2.0.3
|
||||
'@uppy/xhr-upload': ^2.0.3
|
||||
'@wangeditor/basic-modules': 1.x
|
||||
'@wangeditor/core': 1.x
|
||||
dom7: ^3.0.0
|
||||
lodash.foreach: ^4.5.0
|
||||
slate: ^0.72.0
|
||||
snabbdom: ^3.1.0
|
||||
dependencies:
|
||||
'@uppy/core': 2.3.4
|
||||
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
|
||||
'@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
dom7: 3.0.0
|
||||
lodash.foreach: 4.5.0
|
||||
slate: 0.72.8
|
||||
snabbdom: 3.6.2
|
||||
dev: false
|
||||
|
||||
/@wangeditor/video-module@1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/core@1.1.19)(dom7@3.0.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2):
|
||||
resolution: {integrity: sha512-ZdodDPqKQrgx3IwWu4ZiQmXI8EXZ3hm2/fM6E3t5dB8tCaIGWQZhmqd6P5knfkRAd3z2+YRSRbxOGfoRSp/rLg==}
|
||||
peerDependencies:
|
||||
'@uppy/core': ^2.1.4
|
||||
'@uppy/xhr-upload': ^2.0.7
|
||||
'@wangeditor/core': 1.x
|
||||
dom7: ^3.0.0
|
||||
nanoid: ^3.2.0
|
||||
slate: ^0.72.0
|
||||
snabbdom: ^3.1.0
|
||||
dependencies:
|
||||
'@uppy/core': 2.3.4
|
||||
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
|
||||
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.2)
|
||||
dom7: 3.0.0
|
||||
nanoid: 3.3.11
|
||||
slate: 0.72.8
|
||||
snabbdom: 3.6.2
|
||||
dev: false
|
||||
|
||||
/@webassemblyjs/ast@1.9.0:
|
||||
resolution: {integrity: sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==}
|
||||
dependencies:
|
||||
@ -6065,6 +6310,14 @@ packages:
|
||||
resolution: {integrity: sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA==}
|
||||
dev: true
|
||||
|
||||
/d@1.0.2:
|
||||
resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==}
|
||||
engines: {node: '>=0.12'}
|
||||
dependencies:
|
||||
es5-ext: 0.10.64
|
||||
type: 2.7.3
|
||||
dev: false
|
||||
|
||||
/dashdash@1.14.1:
|
||||
resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==}
|
||||
engines: {node: '>=0.10'}
|
||||
@ -6396,6 +6649,12 @@ packages:
|
||||
/dom-walk@0.1.2:
|
||||
resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==}
|
||||
|
||||
/dom7@3.0.0:
|
||||
resolution: {integrity: sha512-oNlcUdHsC4zb7Msx7JN3K0Nro1dzJ48knvBOnDPKJ2GV9wl1i5vydJZUSyOfrkKFDZEud/jBsTk92S/VGSAe/g==}
|
||||
dependencies:
|
||||
ssr-window: 3.0.0
|
||||
dev: false
|
||||
|
||||
/domain-browser@1.2.0:
|
||||
resolution: {integrity: sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==}
|
||||
engines: {node: '>=0.4', npm: '>=1.2'}
|
||||
@ -6912,9 +7171,28 @@ packages:
|
||||
is-symbol: 1.1.1
|
||||
dev: true
|
||||
|
||||
/es5-ext@0.10.64:
|
||||
resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==}
|
||||
engines: {node: '>=0.10'}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
es6-iterator: 2.0.3
|
||||
es6-symbol: 3.1.4
|
||||
esniff: 2.0.1
|
||||
next-tick: 1.1.0
|
||||
dev: false
|
||||
|
||||
/es5-imcompatible-versions@0.1.90:
|
||||
resolution: {integrity: sha512-2MPI0t/VV4j/oz1qbMekb4gCW81dewTpM2XJHKnPpZiPGu+1rVWmhTnwcq1vt8AFwWrkNF4RE7OZ9ibnKFYKwg==}
|
||||
|
||||
/es6-iterator@2.0.3:
|
||||
resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==}
|
||||
dependencies:
|
||||
d: 1.0.2
|
||||
es5-ext: 0.10.64
|
||||
es6-symbol: 3.1.4
|
||||
dev: false
|
||||
|
||||
/es6-promise@4.2.8:
|
||||
resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==}
|
||||
dev: true
|
||||
@ -6925,6 +7203,14 @@ packages:
|
||||
es6-promise: 4.2.8
|
||||
dev: true
|
||||
|
||||
/es6-symbol@3.1.4:
|
||||
resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==}
|
||||
engines: {node: '>=0.12'}
|
||||
dependencies:
|
||||
d: 1.0.2
|
||||
ext: 1.7.0
|
||||
dev: false
|
||||
|
||||
/esbuild@0.12.15:
|
||||
resolution: {integrity: sha512-72V4JNd2+48eOVCXx49xoSWHgC3/cCy96e7mbXKY+WOWghN00cCmlGnwVLRhRHorvv0dgCyuMYBZlM2xDM5OQw==}
|
||||
hasBin: true
|
||||
@ -7214,6 +7500,16 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/esniff@2.0.1:
|
||||
resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==}
|
||||
engines: {node: '>=0.10'}
|
||||
dependencies:
|
||||
d: 1.0.2
|
||||
es5-ext: 0.10.64
|
||||
event-emitter: 0.3.5
|
||||
type: 2.7.3
|
||||
dev: false
|
||||
|
||||
/espree@7.3.1:
|
||||
resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==}
|
||||
engines: {node: ^10.12.0 || >=12.0.0}
|
||||
@ -7262,6 +7558,13 @@ packages:
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: true
|
||||
|
||||
/event-emitter@0.3.5:
|
||||
resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==}
|
||||
dependencies:
|
||||
d: 1.0.2
|
||||
es5-ext: 0.10.64
|
||||
dev: false
|
||||
|
||||
/events@3.3.0:
|
||||
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
|
||||
engines: {node: '>=0.8.x'}
|
||||
@ -7441,6 +7744,12 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/ext@1.7.0:
|
||||
resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==}
|
||||
dependencies:
|
||||
type: 2.7.3
|
||||
dev: false
|
||||
|
||||
/extend-shallow@2.0.1:
|
||||
resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -8455,6 +8764,10 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/html-void-elements@2.0.1:
|
||||
resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==}
|
||||
dev: false
|
||||
|
||||
/htmlparser2@10.0.0:
|
||||
resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==}
|
||||
dependencies:
|
||||
@ -8594,6 +8907,12 @@ packages:
|
||||
resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==}
|
||||
dev: false
|
||||
|
||||
/i18next@20.6.1:
|
||||
resolution: {integrity: sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.27.6
|
||||
dev: false
|
||||
|
||||
/iconv-lite@0.4.24:
|
||||
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -8647,6 +8966,10 @@ packages:
|
||||
resolution: {integrity: sha512-yM7jo9+hvYgvdCQdqvhCNRRio0SCXc8xDPzA25SvKWa7b1WVPjLwQs1VYU5JPXjcJPTqAa5NP5dqpORGYBQ2AA==}
|
||||
dev: true
|
||||
|
||||
/immer@9.0.21:
|
||||
resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==}
|
||||
dev: false
|
||||
|
||||
/immutable@3.8.2:
|
||||
resolution: {integrity: sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -9029,6 +9352,10 @@ packages:
|
||||
resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==}
|
||||
dev: true
|
||||
|
||||
/is-hotkey@0.2.0:
|
||||
resolution: {integrity: sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==}
|
||||
dev: false
|
||||
|
||||
/is-in-browser@1.1.3:
|
||||
resolution: {integrity: sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==}
|
||||
dev: false
|
||||
@ -9091,6 +9418,11 @@ packages:
|
||||
dependencies:
|
||||
isobject: 3.0.1
|
||||
|
||||
/is-plain-object@5.0.0:
|
||||
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/is-potential-custom-element-name@1.0.1:
|
||||
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
|
||||
dev: true
|
||||
@ -9194,7 +9526,6 @@ packages:
|
||||
|
||||
/is-url@1.2.4:
|
||||
resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==}
|
||||
dev: true
|
||||
|
||||
/is-utf8@0.2.1:
|
||||
resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==}
|
||||
@ -10213,9 +10544,16 @@ packages:
|
||||
/lodash-es@4.17.21:
|
||||
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
|
||||
|
||||
/lodash.camelcase@4.3.0:
|
||||
resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
|
||||
dev: false
|
||||
|
||||
/lodash.clonedeep@4.5.0:
|
||||
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
|
||||
dev: false
|
||||
|
||||
/lodash.debounce@4.0.8:
|
||||
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
|
||||
dev: true
|
||||
|
||||
/lodash.escape@4.0.1:
|
||||
resolution: {integrity: sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==}
|
||||
@ -10225,6 +10563,10 @@ packages:
|
||||
resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==}
|
||||
dev: true
|
||||
|
||||
/lodash.foreach@4.5.0:
|
||||
resolution: {integrity: sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==}
|
||||
dev: false
|
||||
|
||||
/lodash.get@4.4.2:
|
||||
resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
|
||||
deprecated: This package is deprecated. Use the optional chaining (?.) operator instead.
|
||||
@ -10244,7 +10586,10 @@ packages:
|
||||
|
||||
/lodash.throttle@4.1.1:
|
||||
resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==}
|
||||
dev: true
|
||||
|
||||
/lodash.toarray@4.4.0:
|
||||
resolution: {integrity: sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw==}
|
||||
dev: false
|
||||
|
||||
/lodash.tonumber@4.0.3:
|
||||
resolution: {integrity: sha512-SY0SwuPOHRwKcCNTdsntPYb+Zddz5mDUIVFABzRMqmAiL41pMeyoQFGxYAw5zdc9NnH4pbJqiqqp5ckfxa+zSA==}
|
||||
@ -10590,6 +10935,12 @@ packages:
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: true
|
||||
|
||||
/mime-match@1.0.2:
|
||||
resolution: {integrity: sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==}
|
||||
dependencies:
|
||||
wildcard: 1.1.2
|
||||
dev: false
|
||||
|
||||
/mime-types@2.1.35:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@ -10805,6 +11156,10 @@ packages:
|
||||
resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
|
||||
dev: true
|
||||
|
||||
/namespace-emitter@2.0.1:
|
||||
resolution: {integrity: sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==}
|
||||
dev: false
|
||||
|
||||
/nan@2.22.2:
|
||||
resolution: {integrity: sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==}
|
||||
requiresBuild: true
|
||||
@ -10815,7 +11170,6 @@ packages:
|
||||
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
|
||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/nanomatch@1.2.13:
|
||||
resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==}
|
||||
@ -10863,6 +11217,10 @@ packages:
|
||||
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
|
||||
dev: true
|
||||
|
||||
/next-tick@1.1.0:
|
||||
resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==}
|
||||
dev: false
|
||||
|
||||
/nice-try@1.0.5:
|
||||
resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==}
|
||||
|
||||
@ -12055,6 +12413,10 @@ packages:
|
||||
source-map-js: 1.2.1
|
||||
dev: true
|
||||
|
||||
/preact@10.26.9:
|
||||
resolution: {integrity: sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA==}
|
||||
dev: false
|
||||
|
||||
/preceptor-core@0.10.1:
|
||||
resolution: {integrity: sha512-WLDk+UowEESixvlhiamGOj/iqWrp8IWeCCHvBZrLh0g4/A1Fa77fDQWqQUd5S5rScT+9u49aDfa45xYRkxqmiA==}
|
||||
dependencies:
|
||||
@ -12129,6 +12491,11 @@ packages:
|
||||
react-is: 17.0.2
|
||||
dev: true
|
||||
|
||||
/prismjs@1.30.0:
|
||||
resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/pro-download@1.0.1:
|
||||
resolution: {integrity: sha512-gGqxmwI95zQw4DAdCnis45hR6XFvqBWEYBm7Wp7KFMIPE7raSNYK+I1Nh0O/15GKH4GC77I+KV0uR9CoG3Fkdw==}
|
||||
dev: true
|
||||
@ -14507,6 +14874,23 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/slate-history@0.66.0(slate@0.72.8):
|
||||
resolution: {integrity: sha512-6MWpxGQZiMvSINlCbMW43E2YBSVMCMCIwQfBzGssjWw4kb0qfvj0pIdblWNRQZD0hR6WHP+dHHgGSeVdMWzfng==}
|
||||
peerDependencies:
|
||||
slate: '>=0.65.3'
|
||||
dependencies:
|
||||
is-plain-object: 5.0.0
|
||||
slate: 0.72.8
|
||||
dev: false
|
||||
|
||||
/slate@0.72.8:
|
||||
resolution: {integrity: sha512-/nJwTswQgnRurpK+bGJFH1oM7naD5qDmHd89JyiKNT2oOKD8marW0QSBtuFnwEbL5aGCS8AmrhXQgNOsn4osAw==}
|
||||
dependencies:
|
||||
immer: 9.0.21
|
||||
is-plain-object: 5.0.0
|
||||
tiny-warning: 1.0.3
|
||||
dev: false
|
||||
|
||||
/slice-ansi@3.0.0:
|
||||
resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==}
|
||||
engines: {node: '>=8'}
|
||||
@ -14531,6 +14915,11 @@ packages:
|
||||
jsbn: 1.1.0
|
||||
dev: false
|
||||
|
||||
/snabbdom@3.6.2:
|
||||
resolution: {integrity: sha512-ig5qOnCDbugFntKi6c7Xlib8bA6xiJVk8O+WdFrV3wxbMqeHO0hXFQC4nAhPVWfZfi8255lcZkNhtIBINCc4+Q==}
|
||||
engines: {node: '>=12.17.0'}
|
||||
dev: false
|
||||
|
||||
/snapdragon-node@2.1.1:
|
||||
resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -14718,6 +15107,10 @@ packages:
|
||||
tweetnacl: 0.14.5
|
||||
dev: true
|
||||
|
||||
/ssr-window@3.0.0:
|
||||
resolution: {integrity: sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==}
|
||||
dev: false
|
||||
|
||||
/ssri@6.0.2:
|
||||
resolution: {integrity: sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==}
|
||||
dependencies:
|
||||
@ -15642,6 +16035,10 @@ packages:
|
||||
mime-types: 2.1.35
|
||||
dev: true
|
||||
|
||||
/type@2.7.3:
|
||||
resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==}
|
||||
dev: false
|
||||
|
||||
/typed-array-buffer@1.0.3:
|
||||
resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -16418,6 +16815,10 @@ packages:
|
||||
isexe: 2.0.0
|
||||
dev: true
|
||||
|
||||
/wildcard@1.1.2:
|
||||
resolution: {integrity: sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==}
|
||||
dev: false
|
||||
|
||||
/word-wrap@1.2.5:
|
||||
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
82
src/components/RichTextEditor/index.tsx
Normal file
82
src/components/RichTextEditor/index.tsx
Normal file
@ -0,0 +1,82 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import '@wangeditor/editor/dist/css/style.css';
|
||||
import { Editor, Toolbar } from '@wangeditor/editor-for-react';
|
||||
import { IDomEditor, IEditorConfig, IToolbarConfig } from '@wangeditor/editor';
|
||||
|
||||
interface RichTextEditorProps {
|
||||
value?: string;
|
||||
onChange?: (html: string) => void;
|
||||
placeholder?: string;
|
||||
height?: number;
|
||||
}
|
||||
|
||||
const RichTextEditor: React.FC<RichTextEditorProps> = ({
|
||||
value = '',
|
||||
onChange,
|
||||
placeholder = '请输入内容...',
|
||||
height = 300,
|
||||
}) => {
|
||||
// 编辑器实例
|
||||
const [editor, setEditor] = useState<IDomEditor | null>(null);
|
||||
// 编辑器内容
|
||||
const [html, setHtml] = useState<string>(value);
|
||||
|
||||
// 工具栏配置
|
||||
const toolbarConfig: Partial<IToolbarConfig> = {
|
||||
excludeKeys: [
|
||||
'insertTable',
|
||||
'codeBlock',
|
||||
'insertVideo',
|
||||
],
|
||||
};
|
||||
|
||||
// 编辑器配置
|
||||
const editorConfig: Partial<IEditorConfig> = {
|
||||
placeholder,
|
||||
autoFocus: false,
|
||||
scroll: true,
|
||||
maxLength: 2000,
|
||||
};
|
||||
|
||||
// 及时销毁编辑器
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (editor == null) return;
|
||||
editor.destroy();
|
||||
setEditor(null);
|
||||
};
|
||||
}, [editor]);
|
||||
|
||||
// 初始化默认值
|
||||
useEffect(() => {
|
||||
if (value && value !== html) {
|
||||
setHtml(value);
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
// 编辑器内容变化时的回调函数
|
||||
const handleChange = (editor: IDomEditor) => {
|
||||
const htmlContent = editor.getHtml();
|
||||
setHtml(htmlContent);
|
||||
onChange && onChange(htmlContent);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ border: '1px solid #d9d9d9', borderRadius: '4px', zIndex: 100 }}>
|
||||
<Toolbar
|
||||
editor={editor}
|
||||
defaultConfig={toolbarConfig}
|
||||
style={{ borderBottom: '1px solid #d9d9d9' }}
|
||||
/>
|
||||
<Editor
|
||||
defaultConfig={editorConfig}
|
||||
value={html}
|
||||
onCreated={setEditor}
|
||||
onChange={handleChange}
|
||||
style={{ height: `${height}px`, overflowY: 'hidden' }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default RichTextEditor;
|
39
src/dicts/help.ts
Normal file
39
src/dicts/help.ts
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* 帮助中心字典
|
||||
*/
|
||||
|
||||
// 问题分类
|
||||
export const QUESTION_TYPES = [
|
||||
{
|
||||
label: '账号问题',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '系统操作',
|
||||
value: '2',
|
||||
},
|
||||
{
|
||||
label: '投标问题',
|
||||
value: '3',
|
||||
},
|
||||
{
|
||||
label: '资质审核',
|
||||
value: '4',
|
||||
},
|
||||
{
|
||||
label: '其他问题',
|
||||
value: '5',
|
||||
},
|
||||
];
|
||||
|
||||
// 问题状态
|
||||
export const QUESTION_STATUS = {
|
||||
PENDING: '0', // 待处理
|
||||
PROCESSED: '1', // 已处理
|
||||
};
|
||||
|
||||
// 是否置顶
|
||||
export const IS_TOP = {
|
||||
NO: '0', // 不置顶
|
||||
YES: '1', // 置顶
|
||||
};
|
@ -40,6 +40,11 @@ const items: IMenuItem[] = [
|
||||
key: 'about',
|
||||
path: '/about',
|
||||
},
|
||||
{
|
||||
label: 'menu.帮助中心',
|
||||
key: 'help',
|
||||
path: '/help',
|
||||
},
|
||||
];
|
||||
|
||||
const HeaderMenu: React.FC = (props) => {
|
||||
|
@ -1,3 +1,6 @@
|
||||
import help from './en-US/help';
|
||||
import policy from './en-US/policy';
|
||||
|
||||
export default {
|
||||
'menu.首页': 'Home',
|
||||
'menu.公告公示': 'Public Announcement',
|
||||
@ -94,5 +97,11 @@ export default {
|
||||
"register.expert.idType.required": "Please select ID type",
|
||||
"register.expert.idCard.label": "ID Number",
|
||||
"register.expert.idCard.placeholder": "Please enter ID number",
|
||||
"register.expert.idCard.required": "Please enter ID number"
|
||||
"register.expert.idCard.required": "Please enter ID number",
|
||||
|
||||
// Help Center module
|
||||
...help,
|
||||
|
||||
// Policy and Regulations module
|
||||
...policy,
|
||||
};
|
||||
|
67
src/locales/en-US/help.ts
Normal file
67
src/locales/en-US/help.ts
Normal file
@ -0,0 +1,67 @@
|
||||
export default {
|
||||
// Help Center Page
|
||||
'menu.帮助中心': 'Help Center',
|
||||
'help.title': 'Help Center',
|
||||
'help.ask': 'Ask a Question',
|
||||
'help.back': 'Back to List',
|
||||
'help.submit': 'Submit Question',
|
||||
'help.cancel': 'Cancel',
|
||||
'help.total': 'Total {total} records',
|
||||
|
||||
// Table Column Titles
|
||||
'help.column.index': 'No.',
|
||||
'help.column.title': 'Title',
|
||||
'help.column.type': 'Category',
|
||||
'help.column.time': 'Published Time',
|
||||
'help.column.views': 'Views',
|
||||
|
||||
// Help Center Detail Page
|
||||
'help.info.notFound': 'Help information not found',
|
||||
'help.info.publishTime': 'Published Time',
|
||||
'help.info.questionType': 'Category',
|
||||
'help.info.publisher': 'Publisher',
|
||||
|
||||
// Help Center Question Page
|
||||
'help.question.title': 'Submit a Question',
|
||||
'help.question.subtitle': 'Please describe your question in detail, we will respond as soon as possible',
|
||||
|
||||
// Form Fields
|
||||
'help.form.type': 'Question Category',
|
||||
'help.form.type.placeholder': 'Please select a category',
|
||||
'help.form.type.required': 'Please select a category',
|
||||
'help.form.title': 'Question Title',
|
||||
'help.form.title.placeholder': 'Please briefly describe your question',
|
||||
'help.form.title.required': 'Please enter a question title',
|
||||
'help.form.content': 'Question Content',
|
||||
'help.form.content.placeholder': 'Please describe your question in detail so we can better assist you',
|
||||
'help.form.content.required': 'Please describe your question',
|
||||
'help.form.name': 'Name',
|
||||
'help.form.name.placeholder': 'Please enter your name',
|
||||
'help.form.name.required': 'Please enter your name',
|
||||
'help.form.company': 'Company',
|
||||
'help.form.company.placeholder': 'Please enter your company name',
|
||||
'help.form.company.required': 'Please enter your company name',
|
||||
'help.form.account': 'Account',
|
||||
'help.form.account.placeholder': 'Please enter your platform account',
|
||||
'help.form.account.required': 'Please enter your account',
|
||||
'help.form.email': 'Email',
|
||||
'help.form.email.placeholder': 'Please enter your email address',
|
||||
'help.form.email.required': 'Please enter your email',
|
||||
'help.form.email.invalid': 'Please enter a valid email address',
|
||||
'help.form.phone': 'Contact Number',
|
||||
'help.form.phone.placeholder': 'Please enter your phone number (optional)',
|
||||
'help.form.phone.invalid': 'Please enter a valid phone number',
|
||||
|
||||
// Messages
|
||||
'help.message.submitSuccess': 'Your question has been submitted successfully. We will process it as soon as possible!',
|
||||
'help.message.submitFailed': 'Submission failed, please try again later',
|
||||
'help.message.loadFailed': 'Failed to get help information, please try again later',
|
||||
'help.message.idNotFound': 'Parameter error, question ID not found',
|
||||
|
||||
// Question Categories
|
||||
'help.type.account': 'Account Issues',
|
||||
'help.type.system': 'System Operations',
|
||||
'help.type.bid': 'Bidding Questions',
|
||||
'help.type.qualification': 'Qualification Review',
|
||||
'help.type.other': 'Other Questions',
|
||||
};
|
18
src/locales/en-US/policy.ts
Normal file
18
src/locales/en-US/policy.ts
Normal file
@ -0,0 +1,18 @@
|
||||
export default {
|
||||
'policy.title': 'Policies & Regulations',
|
||||
'policy.list.column.index': 'No.',
|
||||
'policy.list.column.title': 'Title',
|
||||
'policy.list.column.publishTime': 'Publish Time',
|
||||
'policy.list.empty': 'No Data',
|
||||
'policy.list.total': 'Total {total} Records',
|
||||
|
||||
'policy.detail.back': 'Back to List',
|
||||
'policy.detail.publisher': 'Publisher',
|
||||
'policy.detail.publishTime': 'Publish Time',
|
||||
'policy.detail.notFound': 'Policy Not Found',
|
||||
'policy.detail.loading': 'Loading...',
|
||||
|
||||
'policy.message.getListFailed': 'Failed to get policy list',
|
||||
'policy.message.getDetailFailed': 'Failed to get policy detail',
|
||||
'policy.message.idNotExist': 'Policy ID does not exist',
|
||||
};
|
@ -1,3 +1,6 @@
|
||||
import help from './zh-CN/help';
|
||||
import policy from './zh-CN/policy';
|
||||
|
||||
export default {
|
||||
'menu.首页': '首页',
|
||||
'menu.公告公示': '公告公示',
|
||||
@ -94,5 +97,11 @@ export default {
|
||||
"register.expert.idType.required": "请选择证件类型",
|
||||
"register.expert.idCard.label": "证件号",
|
||||
"register.expert.idCard.placeholder": "请输入证件号",
|
||||
"register.expert.idCard.required": "请输入证件号"
|
||||
"register.expert.idCard.required": "请输入证件号",
|
||||
|
||||
// 帮助中心模块
|
||||
...help,
|
||||
|
||||
// 政策法规模块
|
||||
...policy,
|
||||
};
|
||||
|
67
src/locales/zh-CN/help.ts
Normal file
67
src/locales/zh-CN/help.ts
Normal file
@ -0,0 +1,67 @@
|
||||
export default {
|
||||
// 帮助中心页面
|
||||
'menu.帮助中心': '帮助中心',
|
||||
'help.title': '帮助中心',
|
||||
'help.ask': '我要提问',
|
||||
'help.back': '返回列表',
|
||||
'help.submit': '提交问题',
|
||||
'help.cancel': '取消',
|
||||
'help.total': '共 {total} 条记录',
|
||||
|
||||
// 表格列标题
|
||||
'help.column.index': '序号',
|
||||
'help.column.title': '标题',
|
||||
'help.column.type': '问题分类',
|
||||
'help.column.time': '发布时间',
|
||||
'help.column.views': '浏览量',
|
||||
|
||||
// 帮助中心详情页
|
||||
'help.info.notFound': '未找到相关帮助信息',
|
||||
'help.info.publishTime': '发布时间',
|
||||
'help.info.questionType': '问题分类',
|
||||
'help.info.publisher': '发布人',
|
||||
|
||||
// 帮助中心提问页
|
||||
'help.question.title': '提交问题',
|
||||
'help.question.subtitle': '请详细描述您的问题,我们会尽快为您解答',
|
||||
|
||||
// 表单字段
|
||||
'help.form.type': '问题分类',
|
||||
'help.form.type.placeholder': '请选择问题分类',
|
||||
'help.form.type.required': '请选择问题分类',
|
||||
'help.form.title': '问题标题',
|
||||
'help.form.title.placeholder': '请简短描述您的问题',
|
||||
'help.form.title.required': '请输入问题标题',
|
||||
'help.form.content': '问题内容',
|
||||
'help.form.content.placeholder': '请详细描述您遇到的问题,以便我们更好地为您解答',
|
||||
'help.form.content.required': '请详细描述您的问题',
|
||||
'help.form.name': '姓名',
|
||||
'help.form.name.placeholder': '请输入您的姓名',
|
||||
'help.form.name.required': '请输入您的姓名',
|
||||
'help.form.company': '公司',
|
||||
'help.form.company.placeholder': '请输入您的公司名称',
|
||||
'help.form.company.required': '请输入您的公司名称',
|
||||
'help.form.account': '账号',
|
||||
'help.form.account.placeholder': '请输入您的平台账号',
|
||||
'help.form.account.required': '请输入您的账号',
|
||||
'help.form.email': '邮箱',
|
||||
'help.form.email.placeholder': '请输入您的邮箱地址',
|
||||
'help.form.email.required': '请输入您的邮箱',
|
||||
'help.form.email.invalid': '请输入有效的邮箱地址',
|
||||
'help.form.phone': '联系方式',
|
||||
'help.form.phone.placeholder': '请输入您的手机号码(选填)',
|
||||
'help.form.phone.invalid': '请输入有效的手机号码',
|
||||
|
||||
// 提示消息
|
||||
'help.message.submitSuccess': '您的问题已提交成功,我们将尽快处理!',
|
||||
'help.message.submitFailed': '提交失败,请稍后再试',
|
||||
'help.message.loadFailed': '获取帮助信息失败,请稍后再试',
|
||||
'help.message.idNotFound': '参数错误,未找到问题ID',
|
||||
|
||||
// 问题分类
|
||||
'help.type.account': '账号问题',
|
||||
'help.type.system': '系统操作',
|
||||
'help.type.bid': '投标问题',
|
||||
'help.type.qualification': '资质审核',
|
||||
'help.type.other': '其他问题',
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
export default {
|
||||
'menu.下载中心': '下载中心',
|
||||
};
|
18
src/locales/zh-CN/policy.ts
Normal file
18
src/locales/zh-CN/policy.ts
Normal file
@ -0,0 +1,18 @@
|
||||
export default {
|
||||
'policy.title': '政策法规',
|
||||
'policy.list.column.index': '序号',
|
||||
'policy.list.column.title': '标题',
|
||||
'policy.list.column.publishTime': '发布时间',
|
||||
'policy.list.empty': '暂无数据',
|
||||
'policy.list.total': '共 {total} 条记录',
|
||||
|
||||
'policy.detail.back': '返回列表',
|
||||
'policy.detail.publisher': '发布人',
|
||||
'policy.detail.publishTime': '发布时间',
|
||||
'policy.detail.notFound': '未找到相关政策法规',
|
||||
'policy.detail.loading': '加载中...',
|
||||
|
||||
'policy.message.getListFailed': '获取政策法规列表失败',
|
||||
'policy.message.getDetailFailed': '获取政策法规详情失败',
|
||||
'policy.message.idNotExist': '政策法规ID不存在',
|
||||
};
|
@ -1,78 +1,162 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
.aboutContainer {
|
||||
padding: 24px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
min-height: calc(100vh - 250px);
|
||||
}
|
||||
|
||||
.aboutContent {
|
||||
max-width: 1000px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.aboutTitle {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
|
||||
h2 {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.aboutSection {
|
||||
margin-bottom: 48px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.sectionTitle {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
position: relative;
|
||||
margin-bottom: 24px;
|
||||
padding-left: 12px;
|
||||
padding-left: 15px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 4px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 5px;
|
||||
height: 20px;
|
||||
width: 4px;
|
||||
background-color: #1890ff;
|
||||
}
|
||||
}
|
||||
|
||||
.sectionContent {
|
||||
color: #333;
|
||||
line-height: 2;
|
||||
font-size: 15px;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.imageWrapper {
|
||||
margin: 24px 0;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.aboutImage {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
border-radius: 4px;
|
||||
max-height: 400px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.companyInfo {
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
padding: 24px;
|
||||
border-radius: 4px;
|
||||
margin-top: 24px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.infoItem {
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
line-height: 24px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
font-weight: 500;
|
||||
margin-right: 8px;
|
||||
min-width: 80px;
|
||||
}
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.aboutFooter {
|
||||
text-align: center;
|
||||
margin-top: 48px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
margin-top: 40px;
|
||||
color: #999;
|
||||
border-top: 1px solid #eee;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
// 加载状态
|
||||
.loadingContainer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: calc(100vh - 250px);
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
// 错误状态
|
||||
.errorContainer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: calc(100vh - 250px);
|
||||
background-color: #fff;
|
||||
flex-direction: column;
|
||||
|
||||
h4 {
|
||||
margin-bottom: 20px;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
|
||||
// 富文本内容样式
|
||||
.contentHtml {
|
||||
line-height: 1.8;
|
||||
color: #333;
|
||||
|
||||
p {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin: 16px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #1890ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
padding-left: 20px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0;
|
||||
|
||||
th, td {
|
||||
border: 1px solid #e8e8e8;
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #f5f5f5;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,61 @@
|
||||
import React from 'react';
|
||||
import { Typography, Divider, Row, Col } from 'antd';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Typography, Divider, Spin, message } from 'antd';
|
||||
import { useIntl } from 'umi';
|
||||
import { getAboutUs } from '@/servers/api/about';
|
||||
import styles from './about.less';
|
||||
|
||||
const { Title, Paragraph } = Typography;
|
||||
|
||||
const AboutPage: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const [aboutData, setAboutData] = useState<API.AboutUsData | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const isEnglish = intl.locale === 'en-US';
|
||||
|
||||
// 获取关于我们数据
|
||||
useEffect(() => {
|
||||
const fetchAboutData = async () => {
|
||||
try {
|
||||
const response = await getAboutUs();
|
||||
if (response.success) {
|
||||
setAboutData(response.data);
|
||||
} else {
|
||||
message.error(response.message || '获取关于我们信息失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取关于我们信息失败:', error);
|
||||
message.error('获取关于我们信息失败,请稍后再试');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchAboutData();
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className={styles.loadingContainer}>
|
||||
<Spin size="large" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!aboutData) {
|
||||
return (
|
||||
<div className={styles.errorContainer}>
|
||||
<Title level={4}>暂无相关信息</Title>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 根据当前语言获取对应内容
|
||||
const title = isEnglish ? aboutData.titleEn : aboutData.title;
|
||||
const content = isEnglish ? aboutData.contentEn : aboutData.content;
|
||||
const address = isEnglish ? aboutData.addressEn : aboutData.address;
|
||||
const contactsConsult = isEnglish ? aboutData.contactsConsultEn : aboutData.contactsConsult;
|
||||
const contactsPhone = isEnglish ? aboutData.contactsPhoneEn : aboutData.contactsPhone;
|
||||
const contactsEmail = isEnglish ? aboutData.contactsEmailEn : aboutData.contactsEmail;
|
||||
|
||||
return (
|
||||
<div className={styles.aboutContainer}>
|
||||
@ -20,133 +69,7 @@ const AboutPage: React.FC = () => {
|
||||
{intl.formatMessage({ id: 'about.company.title' })}
|
||||
</Title>
|
||||
<div className={styles.sectionContent}>
|
||||
<Paragraph>
|
||||
中远海运电子招投标平台是中国远洋海运集团有限公司旗下专业的采购与招标管理平台,
|
||||
致力于为集团内外部用户提供高效、透明、规范的电子化招投标服务。平台依托集团强大的资源优势,
|
||||
结合现代信息技术,构建了覆盖招标、采购、供应商管理等全流程的电子化解决方案。
|
||||
</Paragraph>
|
||||
|
||||
<div className={styles.imageWrapper}>
|
||||
<img
|
||||
src="/home_bg.png"
|
||||
alt="公司总部"
|
||||
className={styles.aboutImage}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Paragraph>
|
||||
作为国内领先的航运物流企业集团的电子招投标平台,我们秉承“公开、公平、公正”的原则,
|
||||
通过标准化、信息化、智能化手段,持续优化招投标流程,提升采购效率,降低采购成本,
|
||||
为集团战略实施和业务发展提供有力支撑。
|
||||
</Paragraph>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Divider />
|
||||
|
||||
<div className={styles.aboutSection}>
|
||||
<Title level={3} className={styles.sectionTitle}>
|
||||
{intl.formatMessage({ id: 'about.advantages.title' })}
|
||||
</Title>
|
||||
<div className={styles.sectionContent}>
|
||||
<Row gutter={[24, 24]}>
|
||||
<Col xs={24} md={8}>
|
||||
<div>
|
||||
<Title level={4}>全流程电子化</Title>
|
||||
<Paragraph>
|
||||
从招标公告发布到开标评标,再到结果公示,全流程在线操作,
|
||||
减少纸质文档,提高工作效率,降低运营成本。
|
||||
</Paragraph>
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs={24} md={8}>
|
||||
<div>
|
||||
<Title level={4}>安全可靠</Title>
|
||||
<Paragraph>
|
||||
采用先进的加密技术和安全措施,确保招投标过程的安全性和数据的保密性,
|
||||
有效防范信息泄露和网络攻击风险。
|
||||
</Paragraph>
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs={24} md={8}>
|
||||
<div>
|
||||
<Title level={4}>公开透明</Title>
|
||||
<Paragraph>
|
||||
严格遵循国家招投标法律法规,确保招投标过程公开、透明、可追溯,
|
||||
有效防范舞弊行为,维护各方合法权益。
|
||||
</Paragraph>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<div className={styles.imageWrapper}>
|
||||
<img
|
||||
src="/home_bg.png"
|
||||
alt="平台功能展示"
|
||||
className={styles.aboutImage}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Row gutter={[24, 24]}>
|
||||
<Col xs={24} md={8}>
|
||||
<div>
|
||||
<Title level={4}>智能化服务</Title>
|
||||
<Paragraph>
|
||||
引入人工智能和大数据分析技术,为招标采购决策提供数据支持,
|
||||
实现精准匹配和智能推荐,提升用户体验。
|
||||
</Paragraph>
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs={24} md={8}>
|
||||
<div>
|
||||
<Title level={4}>供应商管理</Title>
|
||||
<Paragraph>
|
||||
建立完善的供应商库和评价体系,实现供应商全生命周期管理,
|
||||
促进供应商良性竞争,提升供应链质量。
|
||||
</Paragraph>
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs={24} md={8}>
|
||||
<div>
|
||||
<Title level={4}>合规监管</Title>
|
||||
<Paragraph>
|
||||
内置合规检查机制,确保招投标活动符合国家法律法规和集团规章制度,
|
||||
降低合规风险,提升管理水平。
|
||||
</Paragraph>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Divider />
|
||||
|
||||
<div className={styles.aboutSection}>
|
||||
<Title level={3} className={styles.sectionTitle}>
|
||||
{intl.formatMessage({ id: 'about.history.title' })}
|
||||
</Title>
|
||||
<div className={styles.sectionContent}>
|
||||
<Paragraph>
|
||||
<strong>2018年</strong> - 中远海运电子招投标平台正式启动建设,完成顶层设计和技术选型。
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<strong>2019年</strong> - 平台一期建设完成并上线试运行,实现基础招投标功能。
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<strong>2020年</strong> - 平台功能全面升级,增加供应商管理、合同管理等模块,用户规模快速增长。
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<strong>2021年</strong> - 平台二期建设完成,引入大数据分析和人工智能技术,提升平台智能化水平。
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<strong>2022年</strong> - 平台实现与集团ERP系统的深度集成,构建完整的采购管理生态。
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<strong>2023年</strong> - 平台进行全面技术改造,采用微服务架构,提升系统性能和可扩展性。
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<strong>2024年</strong> - 平台3.0版本发布,引入区块链技术,进一步提升数据安全性和业务透明度。
|
||||
</Paragraph>
|
||||
<div className={styles.contentHtml} dangerouslySetInnerHTML={{ __html: content }} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -160,23 +83,19 @@ const AboutPage: React.FC = () => {
|
||||
<div className={styles.companyInfo}>
|
||||
<div className={styles.infoItem}>
|
||||
<span className={styles.label}>{intl.formatMessage({ id: 'about.address' })}:</span>
|
||||
<span>上海市虹口区东大名路666号中远海运大厦</span>
|
||||
<span>{address}</span>
|
||||
</div>
|
||||
<div className={styles.infoItem}>
|
||||
<span className={styles.label}>{intl.formatMessage({ id: 'about.phone' })}:</span>
|
||||
<span>021-65966666</span>
|
||||
<span>{contactsPhone}</span>
|
||||
</div>
|
||||
<div className={styles.infoItem}>
|
||||
<span className={styles.label}>{intl.formatMessage({ id: 'about.hotline' })}:</span>
|
||||
<span>400-888-9999</span>
|
||||
<span>{contactsConsult}</span>
|
||||
</div>
|
||||
<div className={styles.infoItem}>
|
||||
<span className={styles.label}>{intl.formatMessage({ id: 'about.email' })}:</span>
|
||||
<span>service@ebidding.cosco.com</span>
|
||||
</div>
|
||||
<div className={styles.infoItem}>
|
||||
<span className={styles.label}>{intl.formatMessage({ id: 'about.worktime' })}:</span>
|
||||
<span>周一至周五 9:00-17:30(法定节假日除外)</span>
|
||||
<span>{contactsEmail}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
37
src/pages/help/help.less
Normal file
37
src/pages/help/help.less
Normal file
@ -0,0 +1,37 @@
|
||||
.help-container {
|
||||
width: 100%;
|
||||
min-height: calc(100vh - 200px);
|
||||
padding: 40px;
|
||||
background-color: #f5f5f5;
|
||||
|
||||
.help-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
|
||||
h2 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.ask-button {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.help-table {
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
||||
|
||||
.help-title {
|
||||
color: #1890ff;
|
||||
|
||||
&:hover {
|
||||
color: #40a9ff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
143
src/pages/help/help.tsx
Normal file
143
src/pages/help/help.tsx
Normal file
@ -0,0 +1,143 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Table, Typography, Button } from 'antd';
|
||||
import { history, useIntl } from 'umi';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { getHelpCenterList } from '@/servers/api/help';
|
||||
import { QUESTION_TYPES } from '@/dicts/help';
|
||||
import './help.less';
|
||||
|
||||
const { Title } = Typography;
|
||||
|
||||
const HelpPage: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const [helpData, setHelpData] = useState<API.HelpCenterRecord[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
// 获取帮助中心数据
|
||||
const fetchHelpData = async (current = 1, pageSize = 10) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await getHelpCenterList({
|
||||
basePageRequest: {
|
||||
pageNo: current,
|
||||
pageSize: pageSize,
|
||||
},
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
setHelpData(response.data.records || []);
|
||||
setPagination({
|
||||
current: response.data.current,
|
||||
pageSize: response.data.size,
|
||||
total: response.data.total,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取帮助中心列表失败:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 初始加载数据
|
||||
useEffect(() => {
|
||||
fetchHelpData();
|
||||
}, []);
|
||||
|
||||
// 处理表格分页变化
|
||||
const handleTableChange = (newPagination: any) => {
|
||||
fetchHelpData(newPagination.current, newPagination.pageSize);
|
||||
};
|
||||
|
||||
// 处理点击问题标题
|
||||
const handleHelpClick = (id: string) => {
|
||||
history.push(`/help/helpInfo?id=${id}`);
|
||||
};
|
||||
|
||||
// 处理点击提问按钮
|
||||
const handleAskQuestion = () => {
|
||||
history.push('/help/helpQuestion');
|
||||
};
|
||||
|
||||
// 获取问题分类名称
|
||||
const getQuestionTypeName = (type: string) => {
|
||||
const found = QUESTION_TYPES.find(item => item.value === type);
|
||||
return found ? found.label : type;
|
||||
};
|
||||
|
||||
// 定义表格列
|
||||
const columns = [
|
||||
{
|
||||
title: intl.formatMessage({ id: 'help.column.index' }),
|
||||
dataIndex: 'index',
|
||||
key: 'index',
|
||||
width: 80,
|
||||
render: (_: any, __: any, index: number) => {
|
||||
return (pagination.current - 1) * pagination.pageSize + index + 1;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: 'help.column.title' }),
|
||||
dataIndex: 'title',
|
||||
key: 'title',
|
||||
render: (text: string, record: any) => (
|
||||
<a onClick={() => handleHelpClick(record.id)} className="help-title">
|
||||
{text}
|
||||
</a>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: 'help.column.type' }),
|
||||
dataIndex: 'type',
|
||||
key: 'type',
|
||||
width: 120,
|
||||
render: (type: string) => getQuestionTypeName(type),
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: 'help.column.time' }),
|
||||
dataIndex: 'createTime',
|
||||
key: 'createTime',
|
||||
width: 180,
|
||||
align: 'center' as 'center',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="help-container">
|
||||
<div className="help-header">
|
||||
<Title level={2}>{intl.formatMessage({ id: 'help.title' })}</Title>
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={handleAskQuestion}
|
||||
className="ask-button"
|
||||
>
|
||||
{intl.formatMessage({ id: 'help.ask' })}
|
||||
</Button>
|
||||
</div>
|
||||
<div className="help-table">
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={helpData}
|
||||
rowKey="id"
|
||||
pagination={{
|
||||
...pagination,
|
||||
showTotal: (total) => `${intl.formatMessage({ id: 'help.total' }, { total })}`,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
}}
|
||||
loading={loading}
|
||||
onChange={handleTableChange}
|
||||
bordered
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default HelpPage;
|
88
src/pages/help/helpInfo.less
Normal file
88
src/pages/help/helpInfo.less
Normal file
@ -0,0 +1,88 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
.helpInfoContainer {
|
||||
padding: 24px;
|
||||
background-color: #fff;
|
||||
min-height: calc(100vh - 200px);
|
||||
}
|
||||
|
||||
.helpInfoHeader {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.backButton {
|
||||
color: rgb(0, 79, 142);
|
||||
padding: 0;
|
||||
|
||||
&:hover {
|
||||
color: lighten(rgb(0, 79, 142), 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.helpInfoContent {
|
||||
width: 100%;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.titleContainer {
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: rgb(0, 79, 142);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.metaInfo {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 24px;
|
||||
color: #999;
|
||||
|
||||
.metaLeft, .metaRight {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.metaRight {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
margin: 16px 0;
|
||||
border-top: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
.contentBody {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
|
||||
p {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 500;
|
||||
color: rgb(0, 79, 142);
|
||||
margin-top: 24px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.loadingContainer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.notFoundContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 400px;
|
||||
gap: 24px;
|
||||
}
|
121
src/pages/help/helpInfo.tsx
Normal file
121
src/pages/help/helpInfo.tsx
Normal file
@ -0,0 +1,121 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Typography, Button, Divider, Spin, message } from 'antd';
|
||||
import { ArrowLeftOutlined } from '@ant-design/icons';
|
||||
import { history, useIntl } from 'umi';
|
||||
import { getHelpCenterDetail } from '@/servers/api/help';
|
||||
import { QUESTION_TYPES } from '@/dicts/help';
|
||||
import styles from './helpInfo.less';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
|
||||
const HelpInfoPage: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const [helpDetail, setHelpDetail] = useState<API.HelpCenterDetailResponse | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
// 获取URL中的id参数
|
||||
const query = new URLSearchParams(window.location.search);
|
||||
const id = query.get('id');
|
||||
|
||||
if (!id) {
|
||||
message.error(intl.formatMessage({ id: 'help.message.idNotFound' }));
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 请求详情数据
|
||||
const fetchHelpDetail = async () => {
|
||||
try {
|
||||
const response = await getHelpCenterDetail({ id });
|
||||
if (response.success) {
|
||||
setHelpDetail(response.data);
|
||||
} else {
|
||||
message.error(response.message || intl.formatMessage({ id: 'help.message.loadFailed' }));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取帮助中心详情失败:', error);
|
||||
message.error(intl.formatMessage({ id: 'help.message.loadFailed' }));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchHelpDetail();
|
||||
}, [intl]);
|
||||
|
||||
// 返回列表页
|
||||
const handleBack = () => {
|
||||
history.push('/help');
|
||||
};
|
||||
|
||||
// 获取问题分类名称
|
||||
const getQuestionTypeName = (type: string) => {
|
||||
const found = QUESTION_TYPES.find(item => item.value === type);
|
||||
return found ? found.label : type;
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className={styles.loadingContainer}>
|
||||
<Spin size="large" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!helpDetail) {
|
||||
return (
|
||||
<div className={styles.notFoundContainer}>
|
||||
<Title level={4}>{intl.formatMessage({ id: 'help.info.notFound' })}</Title>
|
||||
<Button type="primary" onClick={handleBack}>
|
||||
{intl.formatMessage({ id: 'help.back' })}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.helpInfoContainer}>
|
||||
<div className={styles.helpInfoHeader}>
|
||||
<Button
|
||||
type="link"
|
||||
icon={<ArrowLeftOutlined />}
|
||||
onClick={handleBack}
|
||||
className={styles.backButton}
|
||||
>
|
||||
{intl.formatMessage({ id: 'help.back' })}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className={styles.helpInfoContent}>
|
||||
<div className={styles.titleContainer}>
|
||||
<Title level={2} className={styles.title}>
|
||||
{helpDetail.title}
|
||||
</Title>
|
||||
</div>
|
||||
|
||||
<div className={styles.metaInfo}>
|
||||
<div className={styles.metaLeft}>
|
||||
<Text type="secondary">
|
||||
{intl.formatMessage({ id: 'help.info.publishTime' })}: {helpDetail.createTime}
|
||||
</Text>
|
||||
</div>
|
||||
<div className={styles.metaRight}>
|
||||
<Text type="secondary">
|
||||
{intl.formatMessage({ id: 'help.info.questionType' })}: {getQuestionTypeName(helpDetail.type)} |
|
||||
{intl.formatMessage({ id: 'help.info.publisher' })}: {helpDetail.createBy || '系统管理员'}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Divider className={styles.divider} />
|
||||
|
||||
<div className={styles.contentBody}>
|
||||
<div dangerouslySetInnerHTML={{ __html: helpDetail.answerContent || helpDetail.content || '暂无内容' }} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default HelpInfoPage;
|
92
src/pages/help/helpQuestion.less
Normal file
92
src/pages/help/helpQuestion.less
Normal file
@ -0,0 +1,92 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
.helpQuestionContainer {
|
||||
padding: 24px;
|
||||
background-color: #fff;
|
||||
min-height: calc(100vh - 200px);
|
||||
}
|
||||
|
||||
.helpQuestionHeader {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.backButton {
|
||||
color: rgb(0, 79, 142);
|
||||
padding: 0;
|
||||
|
||||
&:hover {
|
||||
color: lighten(rgb(0, 79, 142), 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.helpQuestionContent {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.titleContainer {
|
||||
text-align: center;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.title {
|
||||
color: rgb(0, 79, 142);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.titleDesc {
|
||||
display: block;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
margin: 16px 0 24px;
|
||||
border-top: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
.questionForm {
|
||||
.ant-form-item-label > label {
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.ant-form-item {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.ant-input-affix-wrapper,
|
||||
.ant-input,
|
||||
.ant-select-selector {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ant-input:focus,
|
||||
.ant-input-focused,
|
||||
.ant-select-focused .ant-select-selector {
|
||||
border-color: rgb(0, 79, 142);
|
||||
box-shadow: 0 0 0 2px rgba(0, 79, 142, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.formButtons {
|
||||
text-align: center;
|
||||
margin-top: 40px;
|
||||
|
||||
.cancelButton {
|
||||
margin-right: 16px;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.submitButton {
|
||||
background-color: rgb(0, 79, 142);
|
||||
border-color: rgb(0, 79, 142);
|
||||
min-width: 100px;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: lighten(rgb(0, 79, 142), 10%);
|
||||
border-color: lighten(rgb(0, 79, 142), 10%);
|
||||
}
|
||||
}
|
||||
}
|
257
src/pages/help/helpQuestion.tsx
Normal file
257
src/pages/help/helpQuestion.tsx
Normal file
@ -0,0 +1,257 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Form, Input, Button, Typography, Select, Row, Col, Divider, message } from 'antd';
|
||||
import { ArrowLeftOutlined } from '@ant-design/icons';
|
||||
import { history, useIntl } from 'umi';
|
||||
import WangEditor from 'wangeditor';
|
||||
import { QUESTION_TYPES } from '@/dicts/help';
|
||||
import { addHelpQuestion } from '@/servers/api/help';
|
||||
import styles from './helpQuestion.less';
|
||||
|
||||
const { Title } = Typography;
|
||||
const { Option } = Select;
|
||||
|
||||
// 表单字段接口定义
|
||||
interface FormValues {
|
||||
title: string;
|
||||
content: string;
|
||||
type: string;
|
||||
name: string;
|
||||
company: string;
|
||||
account: string;
|
||||
email: string;
|
||||
phone?: string; // 可选字段
|
||||
}
|
||||
|
||||
const HelpQuestionPage: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const [form] = Form.useForm();
|
||||
const [editor, setEditor] = useState<WangEditor | null>(null);
|
||||
const [content, setContent] = useState<string>('');
|
||||
const [submitting, setSubmitting] = useState<boolean>(false);
|
||||
|
||||
// 初始化编辑器
|
||||
useEffect(() => {
|
||||
const editorInstance = new WangEditor('#editor');
|
||||
|
||||
// 配置编辑器
|
||||
editorInstance.config.height = 300;
|
||||
editorInstance.config.placeholder = intl.formatMessage({ id: 'help.form.content.placeholder' });
|
||||
editorInstance.config.zIndex = 10;
|
||||
|
||||
// 上传图片相关配置
|
||||
editorInstance.config.uploadImgShowBase64 = true;
|
||||
|
||||
// 设置编辑器内容变化回调
|
||||
editorInstance.config.onchange = (html: string) => {
|
||||
setContent(html);
|
||||
form.setFieldsValue({ content: html });
|
||||
};
|
||||
|
||||
// 创建编辑器
|
||||
editorInstance.create();
|
||||
setEditor(editorInstance);
|
||||
|
||||
// 组件销毁时销毁编辑器实例
|
||||
return () => {
|
||||
if (editorInstance) {
|
||||
editorInstance.destroy();
|
||||
}
|
||||
};
|
||||
}, [form, intl]);
|
||||
|
||||
// 表单提交处理
|
||||
const handleSubmit = async (values: FormValues) => {
|
||||
// 确保内容非空
|
||||
if (!content.trim()) {
|
||||
message.error(intl.formatMessage({ id: 'help.form.content.required' }));
|
||||
return;
|
||||
}
|
||||
|
||||
setSubmitting(true);
|
||||
|
||||
try {
|
||||
const response = await addHelpQuestion({
|
||||
...values,
|
||||
content: content,
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
message.success(intl.formatMessage({ id: 'help.message.submitSuccess' }));
|
||||
// 提交成功后返回帮助中心列表页
|
||||
setTimeout(() => {
|
||||
history.push('/help');
|
||||
}, 1500);
|
||||
} else {
|
||||
message.error(response.message || intl.formatMessage({ id: 'help.message.submitFailed' }));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('提交问题失败:', error);
|
||||
message.error(intl.formatMessage({ id: 'help.message.submitFailed' }));
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 处理取消按钮点击
|
||||
const handleCancel = () => {
|
||||
history.push('/help');
|
||||
};
|
||||
|
||||
// 处理返回列表按钮点击
|
||||
const handleBack = () => {
|
||||
history.push('/help');
|
||||
};
|
||||
|
||||
// 邮箱验证规则
|
||||
const emailValidator = (rule: any, value: string) => {
|
||||
if (!value || /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(intl.formatMessage({ id: 'help.form.email.invalid' }));
|
||||
};
|
||||
|
||||
// 手机号验证规则 (可选字段)
|
||||
const phoneValidator = (rule: any, value: string) => {
|
||||
if (!value || /^1[3-9]\d{9}$/.test(value)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(intl.formatMessage({ id: 'help.form.phone.invalid' }));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.helpQuestionContainer}>
|
||||
<div className={styles.header}>
|
||||
<Button
|
||||
type="link"
|
||||
icon={<ArrowLeftOutlined />}
|
||||
onClick={handleBack}
|
||||
className={styles.backButton}
|
||||
>
|
||||
{intl.formatMessage({ id: 'help.back' })}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className={styles.contentWrapper}>
|
||||
<div className={styles.titleContainer}>
|
||||
<Title level={2}>{intl.formatMessage({ id: 'help.question.title' })}</Title>
|
||||
<p className={styles.subtitle}>
|
||||
{intl.formatMessage({ id: 'help.question.subtitle' })}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Divider className={styles.divider} />
|
||||
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
onFinish={handleSubmit}
|
||||
initialValues={{ type: QUESTION_TYPES[0]?.value }}
|
||||
className={styles.questionForm}
|
||||
>
|
||||
<Row gutter={24}>
|
||||
<Col span={24} md={12}>
|
||||
<Form.Item
|
||||
name="type"
|
||||
label={intl.formatMessage({ id: 'help.form.type' })}
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'help.form.type.required' }) }]}
|
||||
>
|
||||
<Select placeholder={intl.formatMessage({ id: 'help.form.type.placeholder' })}>
|
||||
{QUESTION_TYPES.map(type => (
|
||||
<Option key={type.value} value={type.value}>
|
||||
{type.label}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={24} md={12}>
|
||||
<Form.Item
|
||||
name="title"
|
||||
label={intl.formatMessage({ id: 'help.form.title' })}
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'help.form.title.required' }) }]}
|
||||
>
|
||||
<Input placeholder={intl.formatMessage({ id: 'help.form.title.placeholder' })} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Form.Item
|
||||
name="content"
|
||||
label={intl.formatMessage({ id: 'help.form.content' })}
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'help.form.content.required' }) }]}
|
||||
>
|
||||
<div id="editor" className={styles.editor}></div>
|
||||
</Form.Item>
|
||||
|
||||
<Row gutter={24}>
|
||||
<Col span={24} md={12}>
|
||||
<Form.Item
|
||||
name="name"
|
||||
label={intl.formatMessage({ id: 'help.form.name' })}
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'help.form.name.required' }) }]}
|
||||
>
|
||||
<Input placeholder={intl.formatMessage({ id: 'help.form.name.placeholder' })} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={24} md={12}>
|
||||
<Form.Item
|
||||
name="company"
|
||||
label={intl.formatMessage({ id: 'help.form.company' })}
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'help.form.company.required' }) }]}
|
||||
>
|
||||
<Input placeholder={intl.formatMessage({ id: 'help.form.company.placeholder' })} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={24}>
|
||||
<Col span={24} md={12}>
|
||||
<Form.Item
|
||||
name="account"
|
||||
label={intl.formatMessage({ id: 'help.form.account' })}
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'help.form.account.required' }) }]}
|
||||
>
|
||||
<Input placeholder={intl.formatMessage({ id: 'help.form.account.placeholder' })} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={24} md={12}>
|
||||
<Form.Item
|
||||
name="email"
|
||||
label={intl.formatMessage({ id: 'help.form.email' })}
|
||||
rules={[
|
||||
{ required: true, message: intl.formatMessage({ id: 'help.form.email.required' }) },
|
||||
{ validator: emailValidator }
|
||||
]}
|
||||
>
|
||||
<Input placeholder={intl.formatMessage({ id: 'help.form.email.placeholder' })} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={24}>
|
||||
<Col span={24} md={12}>
|
||||
<Form.Item
|
||||
name="phone"
|
||||
label={intl.formatMessage({ id: 'help.form.phone' })}
|
||||
rules={[{ validator: phoneValidator }]}
|
||||
>
|
||||
<Input placeholder={intl.formatMessage({ id: 'help.form.phone.placeholder' })} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Form.Item className={styles.buttonGroup}>
|
||||
<Button type="primary" htmlType="submit" loading={submitting} className={styles.submitButton}>
|
||||
{intl.formatMessage({ id: 'help.submit' })}
|
||||
</Button>
|
||||
<Button onClick={handleCancel} className={styles.cancelButton}>
|
||||
{intl.formatMessage({ id: 'help.cancel' })}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default HelpQuestionPage;
|
@ -180,13 +180,19 @@ const IndexPage: React.FC = () => {
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
<div style={{ backgroundColor: '#fff', marginTop: '20px', padding: '20px' }}>
|
||||
<Tabs onChange={tabChange}>
|
||||
{tabList.map((item) => (
|
||||
<Tabs.TabPane tab={item.label} key={item.key} />
|
||||
))}
|
||||
</Tabs>
|
||||
|
||||
<Table loading={tableLoading} dataSource={dataSource} columns={columns} pagination={false} />
|
||||
<Table
|
||||
loading={tableLoading}
|
||||
dataSource={dataSource}
|
||||
columns={columns}
|
||||
pagination={false}
|
||||
/>
|
||||
|
||||
<div className="tableLoadMore">
|
||||
<Link
|
||||
@ -198,7 +204,7 @@ const IndexPage: React.FC = () => {
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<Row style={{ marginTop: '20px', backgroundColor: '#fff' }}>
|
||||
<Row style={{ marginTop: '20px' }}>
|
||||
<Col span={12}>
|
||||
<div className="blockTitle">紧急问题咨询</div>
|
||||
<img src="" alt="" />
|
||||
@ -233,6 +239,7 @@ const IndexPage: React.FC = () => {
|
||||
<p>客服1: 400-300-9989</p>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<LinkComponent />
|
||||
|
@ -1,66 +1,14 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Table, Typography } from 'antd';
|
||||
import { history } from 'umi';
|
||||
import { Table, Typography, message, ConfigProvider } from 'antd';
|
||||
import { history, useIntl, formatMessage } from 'umi';
|
||||
import styles from './policy.less';
|
||||
import { getRegulationsList, RegulationsRecord } from '@/servers/api/policy';
|
||||
|
||||
const { Title } = Typography;
|
||||
|
||||
// 模拟政策法规数据
|
||||
const mockPolicyData = [
|
||||
{
|
||||
id: '1',
|
||||
title: '关于进一步规范招标采购活动的管理办法',
|
||||
publishDate: '2023-08-15',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: '中远海运集团供应商管理实施细则(2023年修订版)',
|
||||
publishDate: '2023-07-20',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
title: '关于加强采购合同履约管理的通知',
|
||||
publishDate: '2023-06-10',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
title: '中远海运集团招标采购管理办法',
|
||||
publishDate: '2023-05-25',
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
title: '关于优化招标采购流程提高采购效率的实施意见',
|
||||
publishDate: '2023-04-18',
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
title: '中远海运集团电子招标采购平台操作指南',
|
||||
publishDate: '2023-03-30',
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
title: '关于进一步加强采购风险防控的指导意见',
|
||||
publishDate: '2023-02-15',
|
||||
},
|
||||
{
|
||||
id: '8',
|
||||
title: '中远海运集团采购评审专家管理办法',
|
||||
publishDate: '2023-01-10',
|
||||
},
|
||||
{
|
||||
id: '9',
|
||||
title: '关于推进绿色采购的实施方案',
|
||||
publishDate: '2022-12-20',
|
||||
},
|
||||
{
|
||||
id: '10',
|
||||
title: '中远海运集团采购人员职业道德规范',
|
||||
publishDate: '2022-11-05',
|
||||
},
|
||||
];
|
||||
|
||||
const PolicyPage: React.FC = () => {
|
||||
const [policyData, setPolicyData] = useState<any[]>([]);
|
||||
const intl = useIntl();
|
||||
const [policyData, setPolicyData] = useState<RegulationsRecord[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
@ -68,33 +16,56 @@ const PolicyPage: React.FC = () => {
|
||||
total: 0,
|
||||
});
|
||||
|
||||
// 模拟获取政策法规数据
|
||||
useEffect(() => {
|
||||
// 实际项目中应该通过API获取数据
|
||||
setTimeout(() => {
|
||||
setPolicyData(mockPolicyData);
|
||||
setPagination((prevPagination) => ({
|
||||
...prevPagination,
|
||||
total: mockPolicyData.length,
|
||||
}));
|
||||
// 获取政策法规数据
|
||||
const fetchPolicyData = async (pageNo: number = 1, pageSize: number = 10) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await getRegulationsList({
|
||||
basePageRequest: {
|
||||
pageNo,
|
||||
pageSize,
|
||||
}
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
setPolicyData(response.data.records || []);
|
||||
setPagination({
|
||||
current: response.data.current,
|
||||
pageSize: response.data.size,
|
||||
total: response.data.total,
|
||||
});
|
||||
} else {
|
||||
message.error(response.message || intl.formatMessage({ id: 'policy.message.getListFailed' }));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取政策法规列表出错:', error);
|
||||
message.error(intl.formatMessage({ id: 'policy.message.getListFailed' }));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchPolicyData();
|
||||
}, []);
|
||||
|
||||
// 处理表格分页变化
|
||||
const handleTableChange = (newPagination: any) => {
|
||||
fetchPolicyData(newPagination.current, newPagination.pageSize);
|
||||
setPagination(newPagination);
|
||||
};
|
||||
|
||||
// 处理点击政策标题
|
||||
const handlePolicyClick = (id: string) => {
|
||||
const handlePolicyClick = (id: string | undefined) => {
|
||||
if (id) {
|
||||
history.push(`/policy/policyInfo?id=${id}`);
|
||||
}
|
||||
};
|
||||
|
||||
// 定义表格列
|
||||
const columns = [
|
||||
{
|
||||
title: '序号',
|
||||
title: intl.formatMessage({ id: 'policy.list.column.index' }),
|
||||
dataIndex: 'index',
|
||||
key: 'index',
|
||||
width: 80,
|
||||
@ -103,20 +74,20 @@ const PolicyPage: React.FC = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '标题',
|
||||
title: intl.formatMessage({ id: 'policy.list.column.title' }),
|
||||
dataIndex: 'title',
|
||||
key: 'title',
|
||||
render: (text: string, record: any) => (
|
||||
render: (text: string, record: RegulationsRecord) => (
|
||||
<a onClick={() => handlePolicyClick(record.id)} className={styles.policyTitle}>
|
||||
{text}
|
||||
</a>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '发布时间',
|
||||
dataIndex: 'publishDate',
|
||||
key: 'publishDate',
|
||||
width: 150,
|
||||
title: intl.formatMessage({ id: 'policy.list.column.publishTime' }),
|
||||
dataIndex: 'createTime',
|
||||
key: 'createTime',
|
||||
width: 250,
|
||||
align: 'center' as 'center',
|
||||
},
|
||||
];
|
||||
@ -124,13 +95,21 @@ const PolicyPage: React.FC = () => {
|
||||
return (
|
||||
<div className={styles.policyContainer}>
|
||||
<div className={styles.policyTable}>
|
||||
<ConfigProvider
|
||||
renderEmpty={() => (
|
||||
<div className={styles.emptyData}>{intl.formatMessage({ id: 'policy.list.empty' })}</div>
|
||||
)}
|
||||
>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={policyData}
|
||||
rowKey="id"
|
||||
pagination={{
|
||||
...pagination,
|
||||
showTotal: (total) => `共 ${total} 条记录`,
|
||||
showTotal: (total) => intl.formatMessage(
|
||||
{ id: 'policy.list.total' },
|
||||
{ total }
|
||||
),
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
}}
|
||||
@ -138,6 +117,7 @@ const PolicyPage: React.FC = () => {
|
||||
onChange={handleTableChange}
|
||||
bordered
|
||||
/>
|
||||
</ConfigProvider>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,8 +1,9 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useLocation } from 'umi';
|
||||
import { useLocation, history, useIntl } from 'umi';
|
||||
import { Typography, Button, Space, Divider, Row, Col, Spin, message } from 'antd';
|
||||
import { DownloadOutlined, ArrowLeftOutlined, FilePdfOutlined, FileWordOutlined, FileExcelOutlined } from '@ant-design/icons';
|
||||
import styles from './policyInfo.less';
|
||||
import { getRegulationsInfo, RegulationsRecord } from '@/servers/api/policy';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
|
||||
@ -167,28 +168,43 @@ const mockPolicyDetails: PolicyDetails = {
|
||||
};
|
||||
|
||||
const PolicyInfo: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const location = useLocation();
|
||||
const id = new URLSearchParams(location.search).get("id");
|
||||
const [policyDetail, setPolicyDetail] = useState<PolicyDetail | null>(null);
|
||||
const [policyDetail, setPolicyDetail] = useState<RegulationsRecord | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
|
||||
// 模拟获取政策法规详情数据
|
||||
// 获取政策法规详情数据
|
||||
useEffect(() => {
|
||||
// 实际项目中应该通过API获取数据
|
||||
setTimeout(() => {
|
||||
if (id && mockPolicyDetails[id]) {
|
||||
setPolicyDetail(mockPolicyDetails[id]);
|
||||
} else {
|
||||
// 处理ID不存在的情况
|
||||
message.error('政策法规不存在');
|
||||
}
|
||||
const fetchPolicyDetail = async () => {
|
||||
if (!id) {
|
||||
message.error(intl.formatMessage({ id: 'policy.message.idNotExist' }));
|
||||
setLoading(false);
|
||||
}, 500);
|
||||
}, [id]);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await getRegulationsInfo({ id });
|
||||
|
||||
if (response.success) {
|
||||
setPolicyDetail(response.data);
|
||||
} else {
|
||||
message.error(response.message || intl.formatMessage({ id: 'policy.message.getDetailFailed' }));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取政策法规详情出错:', error);
|
||||
message.error(intl.formatMessage({ id: 'policy.message.getDetailFailed' }));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchPolicyDetail();
|
||||
}, [id, intl]);
|
||||
|
||||
// 处理返回列表
|
||||
const handleBack = () => {
|
||||
window.history.back();
|
||||
history.push('/policy');
|
||||
};
|
||||
|
||||
// 处理下载附件
|
||||
@ -216,7 +232,7 @@ const PolicyInfo: React.FC = () => {
|
||||
if (loading) {
|
||||
return (
|
||||
<div className={styles.loadingContainer}>
|
||||
<Spin size="large" />
|
||||
<Spin size="large" tip={intl.formatMessage({ id: 'policy.detail.loading' })} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -224,8 +240,10 @@ const PolicyInfo: React.FC = () => {
|
||||
if (!policyDetail) {
|
||||
return (
|
||||
<div className={styles.notFoundContainer}>
|
||||
<Title level={4}>未找到相关政策法规</Title>
|
||||
<Button type="primary" onClick={handleBack}>返回列表</Button>
|
||||
<Title level={4}>{intl.formatMessage({ id: 'policy.detail.notFound' })}</Title>
|
||||
<Button type="primary" onClick={handleBack}>
|
||||
{intl.formatMessage({ id: 'policy.detail.back' })}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -239,7 +257,7 @@ const PolicyInfo: React.FC = () => {
|
||||
onClick={handleBack}
|
||||
className={styles.backButton}
|
||||
>
|
||||
返回列表
|
||||
{intl.formatMessage({ id: 'policy.detail.back' })}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@ -250,19 +268,28 @@ const PolicyInfo: React.FC = () => {
|
||||
</Title>
|
||||
</div>
|
||||
|
||||
<div className={styles.metaInfo}>
|
||||
<div className={styles.metaLeft}>
|
||||
<Text type="secondary">发布时间: {policyDetail.publishDate}</Text>
|
||||
</div>
|
||||
<div className={styles.metaRight}>
|
||||
<Text type="secondary">发布人: {policyDetail.publisher}</Text>
|
||||
</div>
|
||||
<div className={styles.metaContainer}>
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<Text type="secondary">
|
||||
{intl.formatMessage({ id: 'policy.detail.publishTime' })}: {policyDetail.createTime}
|
||||
</Text>
|
||||
</Col>
|
||||
<Col span={12} style={{ textAlign: 'right' }}>
|
||||
<Text type="secondary">
|
||||
{intl.formatMessage({ id: 'policy.detail.publisher' })}: {policyDetail.createBy}
|
||||
</Text>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
<Divider className={styles.divider} />
|
||||
<Divider />
|
||||
|
||||
<div className={styles.contentBody}>
|
||||
<div dangerouslySetInnerHTML={{ __html: policyDetail.content }} />
|
||||
<div className={styles.contentContainer}>
|
||||
<div
|
||||
className={styles.content}
|
||||
dangerouslySetInnerHTML={{ __html: policyDetail.content || '' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{policyDetail.attachments && policyDetail.attachments.length > 0 && (
|
||||
|
8
src/servers/api/about.ts
Normal file
8
src/servers/api/about.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 获取关于我们信息
|
||||
*/
|
||||
export async function getAboutUs(): Promise<API.Response<API.AboutUsData>> {
|
||||
return request('/homePage/getAboutUs');
|
||||
}
|
37
src/servers/api/help.ts
Normal file
37
src/servers/api/help.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 获取帮助中心列表
|
||||
* @param params 分页参数
|
||||
* @returns 帮助中心列表数据
|
||||
*/
|
||||
export async function getHelpCenterList(params: API.HelpCenterListRequest) {
|
||||
return request<API.APIResponse<API.HelpCenterListResponse>>('/homePage/getHelpCenterList', {
|
||||
method: 'POST',
|
||||
data: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取帮助中心详情
|
||||
* @param params 详情请求参数
|
||||
* @returns 帮助中心详情数据
|
||||
*/
|
||||
export async function getHelpCenterDetail(params: API.HelpCenterDetailRequest) {
|
||||
return request<API.APIResponse<API.HelpCenterDetailResponse>>('/homePage/getHelpCenterInfo', {
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交用户问题
|
||||
* @param params 问题数据
|
||||
* @returns 提交结果
|
||||
*/
|
||||
export async function addHelpCenterQuestion(params: API.HelpCenterQuestionAddRequest) {
|
||||
return request<API.APIResponse<any>>('/homePage/getCustomerQandaAdd', {
|
||||
method: 'POST',
|
||||
data: params,
|
||||
});
|
||||
}
|
88
src/servers/api/policy.ts
Normal file
88
src/servers/api/policy.ts
Normal file
@ -0,0 +1,88 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
export type BasePageRequest = {
|
||||
pageNo: number;
|
||||
pageSize: number;
|
||||
[property: string]: any;
|
||||
};
|
||||
|
||||
export type RegulationsListParams = {
|
||||
basePageRequest: BasePageRequest;
|
||||
[property: string]: any;
|
||||
};
|
||||
|
||||
export type RegulationsRecord = {
|
||||
basePageRequest?: null;
|
||||
content?: string;
|
||||
contentEn?: string;
|
||||
createBy?: string;
|
||||
createDate?: null;
|
||||
createTime?: string;
|
||||
deleteFlag?: null;
|
||||
delFlag?: string;
|
||||
id?: string;
|
||||
isTop?: string;
|
||||
lastUpdateTime?: null;
|
||||
publishBy?: string;
|
||||
publishTime?: null;
|
||||
settingEn?: string;
|
||||
status?: string;
|
||||
tenantId?: null;
|
||||
tenantName?: null;
|
||||
title?: string;
|
||||
titleEn?: string;
|
||||
updateBy?: string;
|
||||
updateDate?: null;
|
||||
updateTime?: string;
|
||||
[property: string]: any;
|
||||
};
|
||||
|
||||
export type RegulationsListResponse = {
|
||||
code: number;
|
||||
data: {
|
||||
countId: null;
|
||||
current: number;
|
||||
hitCount: boolean;
|
||||
maxLimit: null;
|
||||
optimizeCountSql: boolean;
|
||||
orders: any[];
|
||||
pages: number;
|
||||
records: RegulationsRecord[];
|
||||
searchCount: boolean;
|
||||
size: number;
|
||||
total: number;
|
||||
[property: string]: any;
|
||||
};
|
||||
message: string;
|
||||
success: boolean;
|
||||
[property: string]: any;
|
||||
};
|
||||
|
||||
export type RegulationsInfoParams = {
|
||||
id: string;
|
||||
[property: string]: any;
|
||||
};
|
||||
|
||||
export type RegulationsInfoResponse = {
|
||||
code: number;
|
||||
data: RegulationsRecord;
|
||||
message: string;
|
||||
success: boolean;
|
||||
[property: string]: any;
|
||||
};
|
||||
|
||||
// 获取政策法规列表
|
||||
export async function getRegulationsList(params: RegulationsListParams) {
|
||||
return request<RegulationsListResponse>('/homePage/getRegulationsList', {
|
||||
method: 'POST',
|
||||
data: params,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取政策法规详情
|
||||
export async function getRegulationsInfo(params: RegulationsInfoParams) {
|
||||
return request<RegulationsInfoResponse>('/homePage/getRegulationsInfo', {
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
138
src/servers/api/typings.d.ts
vendored
138
src/servers/api/typings.d.ts
vendored
@ -112,4 +112,142 @@ declare namespace API {
|
||||
optionName: string;
|
||||
}[];
|
||||
}[]
|
||||
|
||||
// 基础分页请求参数
|
||||
export type BasePageRequest = {
|
||||
pageNo: number;
|
||||
pageSize: number;
|
||||
[property: string]: any;
|
||||
}
|
||||
|
||||
// 帮助中心列表请求参数
|
||||
export type HelpCenterListRequest = {
|
||||
basePageRequest: BasePageRequest;
|
||||
[property: string]: any;
|
||||
}
|
||||
|
||||
// 帮助中心列表响应数据中的记录
|
||||
export type HelpCenterRecord = {
|
||||
answerContent?: string;
|
||||
answerContentNe?: string;
|
||||
basePageRequest?: null;
|
||||
content?: string;
|
||||
contentEn?: string;
|
||||
createBy?: string;
|
||||
createDate?: null;
|
||||
createTime?: string;
|
||||
deleteFlag?: null;
|
||||
delFlag?: string;
|
||||
id?: string;
|
||||
isTop?: string;
|
||||
lastUpdateTime?: null;
|
||||
publishBy?: null;
|
||||
publishTime?: null;
|
||||
settingEn?: string;
|
||||
status?: string;
|
||||
tenantId?: null;
|
||||
tenantName?: null;
|
||||
title?: string;
|
||||
titleEn?: string;
|
||||
type?: string;
|
||||
updateBy?: string;
|
||||
updateDate?: null;
|
||||
updateTime?: string;
|
||||
[property: string]: any;
|
||||
}
|
||||
|
||||
// 帮助中心列表响应数据
|
||||
export type HelpCenterListResponse = {
|
||||
countId: null;
|
||||
current: number;
|
||||
hitCount: boolean;
|
||||
maxLimit: null;
|
||||
optimizeCountSql: boolean;
|
||||
orders: any[];
|
||||
pages: number;
|
||||
records: HelpCenterRecord[];
|
||||
searchCount: boolean;
|
||||
size: number;
|
||||
total: number;
|
||||
[property: string]: any;
|
||||
}
|
||||
|
||||
// 帮助中心详情请求参数
|
||||
export type HelpCenterDetailRequest = {
|
||||
id: string;
|
||||
[property: string]: any;
|
||||
}
|
||||
|
||||
// 帮助中心详情响应数据
|
||||
export type HelpCenterDetailResponse = {
|
||||
answerContent: string;
|
||||
answerContentNe: string;
|
||||
basePageRequest: null;
|
||||
content: string;
|
||||
contentEn: string;
|
||||
createBy: string;
|
||||
createDate: null;
|
||||
createTime: string;
|
||||
deleteFlag: null;
|
||||
delFlag: string;
|
||||
id: string;
|
||||
isTop: string;
|
||||
lastUpdateTime: null;
|
||||
publishBy: null;
|
||||
publishTime: null;
|
||||
settingEn: string;
|
||||
status: string;
|
||||
tenantId: null;
|
||||
tenantName: null;
|
||||
title: string;
|
||||
titleEn: string;
|
||||
type: string;
|
||||
updateBy: string;
|
||||
updateDate: null;
|
||||
updateTime: string;
|
||||
[property: string]: any;
|
||||
}
|
||||
|
||||
// 用户提问添加请求参数
|
||||
export type HelpCenterQuestionAddRequest = {
|
||||
companyName: string;
|
||||
contactDetails: string;
|
||||
content: string;
|
||||
email: string;
|
||||
fullName: string;
|
||||
title: string;
|
||||
type: string;
|
||||
userName: string;
|
||||
[property: string]: any;
|
||||
}
|
||||
|
||||
// 关于我们响应数据类型
|
||||
export interface AboutUsData {
|
||||
address: string;
|
||||
addressEn: string;
|
||||
addressImg: string;
|
||||
contactsConsult: string;
|
||||
contactsConsultEn: string;
|
||||
contactsEmail: string;
|
||||
contactsEmailEn: string;
|
||||
contactsPhone: string;
|
||||
contactsPhoneEn: string;
|
||||
content: string;
|
||||
contentEn: string;
|
||||
createBy: string;
|
||||
createDate: null;
|
||||
createTime: string;
|
||||
deleteFlag: null;
|
||||
delFlag: string;
|
||||
id: string;
|
||||
lastUpdateTime: null;
|
||||
tenantId: null;
|
||||
tenantName: null;
|
||||
title: string;
|
||||
titleEn: string;
|
||||
updateBy: string;
|
||||
updateDate: null;
|
||||
updateTime: string;
|
||||
[property: string]: any;
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ const codeMessage = {
|
||||
*/
|
||||
const request = extend({
|
||||
// errorHandler, // 默认错误处理
|
||||
prefix: '/api',
|
||||
credentials: 'include' // 默认请求是否带上cookie
|
||||
});
|
||||
// request拦截器, 改变url 或 options.
|
||||
|
Reference in New Issue
Block a user