V1.2.0需求 4个页面新增及功能 待处理编辑器锚点定位、编辑器发布的文章UI优化、中英文翻译

This commit is contained in:
yaoqin 2025-07-25 16:39:37 +08:00
parent 9fa026f267
commit 22dad92ef9
27 changed files with 3374 additions and 1269 deletions

View File

@ -1328,6 +1328,64 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
"@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"requires": {
"string-width": "^5.1.2",
"string-width-cjs": "npm:string-width@^4.2.0",
"strip-ansi": "^7.0.1",
"strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
"wrap-ansi": "^8.1.0",
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
},
"dependencies": {
"ansi-regex": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="
},
"ansi-styles": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="
},
"emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
},
"string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"requires": {
"eastasianwidth": "^0.2.0",
"emoji-regex": "^9.2.2",
"strip-ansi": "^7.0.1"
}
},
"strip-ansi": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"requires": {
"ansi-regex": "^6.0.1"
}
},
"wrap-ansi": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"requires": {
"ansi-styles": "^6.1.0",
"string-width": "^5.0.1",
"strip-ansi": "^7.0.1"
}
}
}
},
"@jridgewell/gen-mapping": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
@ -1472,6 +1530,11 @@
}
}
},
"@one-ini/wasm": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
"integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw=="
},
"@parcel/watcher": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
@ -1639,6 +1702,12 @@
"dev": true,
"optional": true
},
"@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
"optional": true
},
"@polka/url": {
"version": "1.0.0-next.28",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz",
@ -2929,6 +2998,11 @@
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
"dev": true
},
"abbrev": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
"integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ=="
},
"accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@ -3910,7 +3984,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
@ -3918,8 +3991,7 @@
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"colord": {
"version": "2.9.3",
@ -4061,6 +4133,15 @@
"typedarray": "^0.0.6"
}
},
"config-chain": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
"integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
"requires": {
"ini": "^1.3.4",
"proto-list": "~1.2.1"
}
},
"connect-history-api-fallback": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz",
@ -4789,6 +4870,11 @@
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
"dev": true
},
"eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
},
"easy-stack": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.1.tgz",
@ -4804,6 +4890,45 @@
"zrender": "5.6.1"
}
},
"editorconfig": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz",
"integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==",
"requires": {
"@one-ini/wasm": "0.1.1",
"commander": "^10.0.0",
"minimatch": "9.0.1",
"semver": "^7.5.3"
},
"dependencies": {
"brace-expansion": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"requires": {
"balanced-match": "^1.0.0"
}
},
"commander": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug=="
},
"minimatch": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
"integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
"requires": {
"brace-expansion": "^2.0.1"
}
},
"semver": {
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="
}
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@ -4831,8 +4956,7 @@
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"emojis-list": {
"version": "3.0.0",
@ -5932,6 +6056,58 @@
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
"integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ=="
},
"foreground-child": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
"integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
"requires": {
"cross-spawn": "^7.0.6",
"signal-exit": "^4.0.1"
},
"dependencies": {
"cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
}
},
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
},
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"requires": {
"shebang-regex": "^3.0.0"
}
},
"shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
},
"signal-exit": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"requires": {
"isexe": "^2.0.0"
}
}
}
},
"form-data": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
@ -6552,6 +6728,11 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
},
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@ -6665,8 +6846,7 @@
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
"is-glob": {
"version": "4.0.3",
@ -6780,14 +6960,22 @@
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
},
"isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
"integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg=="
},
"jackspeak": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
"requires": {
"@isaacs/cliui": "^8.0.2",
"@pkgjs/parseargs": "^0.11.0"
}
},
"javascript-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz",
@ -6829,6 +7017,59 @@
"@sideway/pinpoint": "^2.0.0"
}
},
"js-beautify": {
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz",
"integrity": "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==",
"requires": {
"config-chain": "^1.1.13",
"editorconfig": "^1.0.4",
"glob": "^10.4.2",
"js-cookie": "^3.0.5",
"nopt": "^7.2.1"
},
"dependencies": {
"brace-expansion": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"requires": {
"balanced-match": "^1.0.0"
}
},
"glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"requires": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
}
},
"minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"requires": {
"brace-expansion": "^2.0.1"
}
},
"minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="
}
}
},
"js-cookie": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
"integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw=="
},
"js-message": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz",
@ -7740,6 +7981,14 @@
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"dev": true
},
"nopt": {
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
"integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
"requires": {
"abbrev": "^2.0.0"
}
},
"normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
@ -8067,6 +8316,11 @@
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
"package-json-from-dist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="
},
"param-case": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
@ -8193,6 +8447,27 @@
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
"path-scurry": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"requires": {
"lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"dependencies": {
"lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
},
"minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="
}
}
},
"path-to-regexp": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
@ -8732,6 +9007,11 @@
"resolved": "https://registry.npmjs.org/promise-limit/-/promise-limit-2.7.0.tgz",
"integrity": "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw=="
},
"proto-list": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
"integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA=="
},
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@ -10051,7 +10331,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@ -10061,14 +10340,37 @@
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"requires": {
"ansi-regex": "^5.0.1"
}
}
}
},
"string-width-cjs": {
"version": "npm:string-width@4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"dependencies": {
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.1"
}
@ -10098,6 +10400,21 @@
"ansi-regex": "^2.0.0"
}
},
"strip-ansi-cjs": {
"version": "npm:strip-ansi@6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"requires": {
"ansi-regex": "^5.0.1"
},
"dependencies": {
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
}
}
},
"strip-eof": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
@ -11464,6 +11781,39 @@
}
}
},
"wrap-ansi-cjs": {
"version": "npm:wrap-ansi@7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"requires": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"dependencies": {
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"requires": {
"color-convert": "^2.0.1"
}
},
"strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"requires": {
"ansi-regex": "^5.0.1"
}
}
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",

View File

@ -19,6 +19,7 @@
"core-js": "^3.8.3",
"echarts": "^5.5.1",
"element-ui": "^2.15.14",
"js-beautify": "^1.15.4",
"jsencrypt": "^3.3.2",
"quill": "^2.0.3",
"vue": "^2.6.14",

View File

@ -1,6 +1,6 @@
import request from '../utils/request'
//查询文档列表
//查询文档列表 及根据关键搜素接口
export function getListDataByPage(data) {
return request({
url: `manage/documents/getListDataByPage`,

View File

@ -292,10 +292,11 @@ export default {
const coin = this.currencyList.find(item => item.value === this.activeItemCoin.value);
if (!coin) return;
let jumpName = coin.path.charAt(0).toUpperCase() + coin.path.slice(1) //name
console.log(jumpName,1366565,coin);
let url = `/${lang}/AccessMiningPool`
// 使 name
this.$router.push({
name:jumpName,
path:url,
params: {
lang: lang,
coin: this.activeItemCoin.value,
@ -307,8 +308,9 @@ export default {
} else {
//
const cleanPath = path.startsWith('/') ? path.slice(1) : path;
this.$router.push(`/${lang}/${cleanPath}`);
// const cleanPath = path.startsWith('/') ? path.slice(1) : path;
let cleanPath = `/${lang}/AccessMiningPool`
this.$router.push(cleanPath);
}
@ -511,6 +513,7 @@ export default {
// overflow-y: scroll;
position: relative;
overflow-x: hidden;
overflow-y: auto;
}
// .headerBox{

View File

@ -101,6 +101,13 @@ export const backendSystem_zh = {
transferAmount:"转账金额",
updateSuccess:"修改成功",
publishArticle:"发布文章",
pleaseInputKeyword:"请输入搜索内容",
pleaseInputType:"请选择文档类型",
pleaseSelect:"请选择",
miningTutorial:"挖矿教程",
commonProblems:"常见问题",
other:"其他",
announcementCenter:"公告中心",
}
}
@ -208,6 +215,13 @@ export const backendSystem_en = {
transferAmount:"Transfer Amount",
updateSuccess:"Update Success",
publishArticle:"Publish Article",
pleaseInputKeyword:"Please input search content",
pleaseInputType:"Please select document type",
pleaseSelect:"Please select",
miningTutorial:"Mining Tutorial",
commonProblems:"Common Problems",
other:"Other",
announcementCenter:"Announcement Center",
}
}

View File

@ -6,7 +6,7 @@
<MoveHead v-if="$isMobile"></MoveHead>
<comHeard v-else></comHeard>
</el-header>
<el-main>
<el-main class="el-main">
<appMain></appMain>
</el-main>
</el-container>

View File

@ -559,6 +559,49 @@ const childrenRoutes = [
}
}
},
{//公告详情
path: 'announcementDetails',
name: 'AnnouncementDetails',
component: () => import('../views/announcementDetails/index.vue'),
meta: {
title: '公告详情',
// description: i18n.t(`seo.announcements`) || 'M2Pool 矿池公告中心,提供最新的公告、通知和重要信息,让用户及时了解矿池的最新动态和服务变更。',
allAuthority: [`all`],
// keywords: {
// en: 'Announcement Center,Latest Announcements,Mining Pool News,Service Updates,Important Notices',
// zh: 'M2Pool 矿池,公告中心,最新公告,矿池动态,服务更新,重要通知'
// }
}
},
{//常见问题
path: 'commonProblem',
name: 'CommonProblem',
component: () => import('../views/commonProblem/index.vue'),
meta: {
title: '常见问题',
// description: i18n.t(`seo.announcements`) || 'M2Pool 矿池公告中心,提供最新的公告、通知和重要信息,让用户及时了解矿池的最新动态和服务变更。',
allAuthority: [`all`],
// keywords: {
// en: 'Announcement Center,Latest Announcements,Mining Pool News,Service Updates,Important Notices',
// zh: 'M2Pool 矿池,公告中心,最新公告,矿池动态,服务更新,重要通知'
// }
}
},
{//搜索结果页面
path: 'searchResult',
name: 'SearchResult',
component: () => import('../views/searchResult/index.vue'),
meta: {
title: '搜索结果',
// description: i18n.t(`seo.announcements`) || 'M2Pool 矿池公告中心,提供最新的公告、通知和重要信息,让用户及时了解矿池的最新动态和服务变更。',
allAuthority: [`all`],
// keywords: {
// en: 'Announcement Center,Latest Announcements,Mining Pool News,Service Updates,Important Notices',
// zh: 'M2Pool 矿池,公告中心,最新公告,矿池动态,服务更新,重要通知'
// }
}
},
{//警报通知
path: 'alerts',
name: 'Alerts',
@ -827,13 +870,28 @@ const router = new VueRouter({
base: process.env.BASE_URL,
routes,
strict: true, // 启用严格模式,不允许尾部斜杠
scrollBehavior(to, from, savedPosition) { //每次路由跳转时,滚动到顶部
// 如果有保存的滚动位置(比如浏览器前进后退),就用它
if (savedPosition) {
return savedPosition;
} else {
// 否则滚动到顶部,并使用平滑滚动
return { x: 0, y: 0, behavior: 'smooth' };
}
}
})
router.afterEach(() => {
Vue.nextTick(() => {
// 滚动主内容区
const contentMain = document.querySelector('.el-main');
if (contentMain) {
contentMain.scrollTo({ top: 0, left: 0, behavior: 'smooth' });
}
// 兼容其它页面(如登录页等)
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' });
});
});
router.beforeEach((to, from, next) => {
const lang = to.params.lang || (localStorage.getItem('lang') || 'en');

View File

@ -1,5 +1,4 @@
import { findDataInfo ,documentsList} from '../../api/documentManagement'
export default {
data() {
return {
@ -257,6 +256,21 @@ export default {
imgUrl: `${this.$baseApi}img/nexa.png`,
activeName: "1",
currentRoutePath:"",
listParams:{
type:"1",//挖矿教程
lang:this.$i18n.locale,
pageNum:1,
pageSize:50
},
tutorialLoading:false,
navList:[],
DetailsParams:{
id:"",
lang:this.$i18n.locale,
},
info:"",
activeId:""
}
},
@ -280,9 +294,9 @@ export default {
mounted() {
if (this.$route.name =="AccessMiningPool" ) {
this.$router.go(-1);
}
// if (this.$route.name =="AccessMiningPool" ) {
// this.$router.go(-1);
// }
@ -358,11 +372,47 @@ export default {
this.activeItem = this.currencyList[0];
}
this.fetchAllList(this.listParams)
},
methods: {
async fetchAllList(params){
this.setLoading('tutorialLoading', true);
const res = await documentsList(params)
console.log(res,"res");
if (res.code === 200) {
this.navList = res.rows
if (this.$route.query.id) {
this.DetailsParams.id = this.$route.query.id
}else{
this.DetailsParams.id = this.navList[0].id;
}
this.fetchProblemDetails(this.DetailsParams)
}
},
async fetchProblemDetails(params) {
this.setLoading('tutorialLoading', true);
const res = await findDataInfo(params)
if(res && res.code === 200){
this.info = res.data.content || ""
this.activeId = res.data.id
}
this.setLoading('tutorialLoading', false);
},
// isActiveRoute(item) {
// // 直接使用完整的路径进行比较
// return this.currentRoutePath.includes(`AccessMiningPool/${item.path}`);
@ -413,18 +463,21 @@ export default {
clickJump(item) {
if (!item.path) return; // 添加路径检查
this.activeCoin = item.value
this.pageTitle = item.name
this.imgUrl = item.imgUrl
this.$addStorageEvent(1, `activeCoin`, JSON.stringify(item.value))
// this.$router.push(item.url)
const lang = this.$i18n.locale;
this.$router.push(`/${lang}/AccessMiningPool/${item.path}`).catch(err => {
if (err.name !== 'NavigationDuplicated') {
console.error('Navigation failed:', err);
}
});
this.DetailsParams.id = item.id
this.fetchProblemDetails(this.DetailsParams)
// if (!item.path) return; // 添加路径检查
// this.activeCoin = item.value
// this.pageTitle = item.name
// this.imgUrl = item.imgUrl
// this.$addStorageEvent(1, `activeCoin`, JSON.stringify(item.value))
// // this.$router.push(item.url)
// const lang = this.$i18n.locale;
// this.$router.push(`/${lang}/AccessMiningPool/${item.path}`).catch(err => {
// if (err.name !== 'NavigationDuplicated') {
// console.error('Navigation failed:', err);
// }
// });

View File

@ -1,5 +1,5 @@
<template>
<div class="AccessMiningPoolMain">
<div class="AccessMiningPoolMain" v-loading="tutorialLoading">
<section v-if="openAPI" class="openAPI">
<section v-if="$isMobile">
<div class="currencySelect">
@ -16,11 +16,12 @@
>
<i class="arrow"></i>
<div class="dropdown">
<div
class="option"
v-for="item in currencyList"
:key="item.value"
@click.stop="changeMenuName($event, item)"
@click.stop="changeMenuName($event, item)"
:class="{ optionActive: $route.path.includes(item.path) }"
>
@ -49,8 +50,21 @@
<section class="menu">
<ul>
<li
:class="{ active: DetailsParams.id == item.id }"
@click="clickJump(item)"
v-for="item in navList"
:key="item.id"
>
<img :src="item.titleUrl" alt="coin" />
<span>
{{ item.title }}
</span>
</li>
<!-- <li
:class="{ active: currentRoutePath == item.path }"
@click="clickJump(item)"
v-for="item in currencyList"
@ -60,11 +74,31 @@
<span>
{{ $t(item.name) }}
</span>
</li>
</li> -->
</ul>
</section>
<section class="tutorialContent">
<router-view></router-view>
<section class="rightContent">
<div v-if="tutorialLoading" class="loading-container">
<span class="loading-text">正在加载内容...</span>
</div>
<div v-else-if="info && info.trim()" class="dynamic-content" v-html="info"></div>
<div v-else class="no-content">
<p>暂无内容</p>
</div>
</section>
<!-- <router-view></router-view> -->
</section>
</section>
</section>
@ -139,6 +173,8 @@ export default {
padding-top: 30px;
display: flex;
justify-content: center;
overflow-y: auto;
height: 100%;
.mail {
color: #5917c4;
}
@ -473,7 +509,7 @@ export default {
.AccessMiningPoolMain {
width: 100%;
// height: 100vh;
height: 100%;
}
.openAPI {
width: 100%;
@ -504,6 +540,13 @@ export default {
box-shadow: 0px 0px 10px 3px rgba(0, 0, 0, 0.1);
border-radius: 8px;
overflow: hidden;
background: #fff;
padding-top: 30px;
height: 100%;
overflow-y: auto;
padding: 20px;
padding-bottom: 30px;
}
.notOpen {
// background: palegoldenrod;
@ -542,6 +585,9 @@ export default {
align-items:start;
padding: 5px;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: left;
img {
width: 25px;
margin-right: 5px;
@ -736,4 +782,68 @@ export default {
font-size: 0.95rem;
}
}
.rightContent{
flex: 1;
height: 100%;
margin-left: 50px;
overflow-y: auto;
padding-right: 20px;
background: #fff;
.dynamic-content {
width: 100%;
margin: 0 auto;
//
:deep(table) {
border-collapse: collapse;
width: 100%;
margin: 16px 0;
}
:deep(th), :deep(td) {
border: 1px solid #d1d5db;
padding: 8px 12px;
text-align: left;
}
:deep(th) {
background: #f3f4f6;
font-weight: bold;
}
:deep(strong), :deep(b) {
font-weight: bold !important;
color: inherit !important;
font-style: normal !important;
}
:deep(em), :deep(i) {
font-style: italic !important;
color: inherit !important;
}
:deep(a) {
color: #007bff !important;
text-decoration: none !important;
&:hover {
text-decoration: underline !important;
}
}
}
.loading-container {
text-align: center;
padding: 40px 0;
.loading-text {
font-size: 16px;
color: #666;
vertical-align: middle;
}
}
.no-content {
text-align: center;
padding: 40px 0;
p {
font-size: 16px;
color: #999;
margin: 0;
}
}
}
</style>

View File

@ -6,11 +6,12 @@ export default{
return{
params:{
lang:"",
type: 1 // 服务条款类型数字1
type: 0, // 服务条款类型数字1
},
infoParams:{
id:"",
lang:"",
lang:this.$i18n?.locale || 'zh',
childType:"1", //1服务条款、2费率、3API文档
},
// 存储从后端获取的文档内容
info: "",
@ -19,54 +20,50 @@ export default{
}
},
mounted(){
this.params.lang = this.$i18n?.locale || 'zh'
this.fetchDocumentsList(this.params)
// this.fetchDocumentsList(this.params)
this.fetchDocumentsInfo(this.infoParams)
},
methods:{
/**
* 获取文档列表
*/
async fetchDocumentsList(){
try {
this.loading = true
const res = await documentsList(this.params)
console.log('文档列表:', res)
// async fetchDocumentsList(){
// try {
// this.loading = true
// const res = await documentsList(this.params)
// console.log('文档列表:', res)
if (res && res.code === 200 && res.data && res.data.length > 0) {
console.log('请求参数:', res.data)
this.infoParams.id = res.data[0].id
this.infoParams.lang = this.$i18n?.locale || 'zh'
// if (res && res.code === 200 && res.rows && res.rows.length > 0) {
// console.log('请求参数:', res.rows)
// this.infoParams.id = res.rows[0].id
// this.infoParams.lang = this.$i18n?.locale || 'zh'
if (this.infoParams.id && this.infoParams.lang) {
await this.fetchDocumentsInfo()
}
} else {
console.warn('未获取到文档列表数据')
this.info = ""
}
} catch (error) {
console.error('获取文档列表失败:', error)
this.info = ""
} finally {
this.loading = false
}
},
// if (this.infoParams.id && this.infoParams.lang) {
// await this.fetchDocumentsInfo()
// }
// } else {
// console.warn('未获取到文档列表数据')
// this.info = ""
// }
// } catch (error) {
// console.error('获取文档列表失败:', error)
// this.info = ""
// } finally {
// this.loading = false
// }
// },
/**
* 获取具体文档内容
*/
async fetchDocumentsInfo(){
try {
if (!this.infoParams.id) {
console.warn('文档ID为空无法获取文档内容')
return
}
const res = await findDataInfo(this.infoParams)
console.log('文档内容:', res)
async fetchDocumentsInfo(params){
try {
const res = await findDataInfo(params)
if (res && res.code === 200 && res.data) {
if (res && res.code === 200 ) {
// wangeditor 直接输出 HTML直接使用
this.info = res.data.content || ""
} else {

View File

@ -0,0 +1,79 @@
import { documentsList,findDataInfo} from '../../api/documentManagement'
export default {
data() {
return {
problems: [
{
id: 1,
title: "如何开始挖矿?",
content: "详细步骤:注册、配置矿机、连接矿池。",
},
{
id: 2,
title: "如何查看收益?",
content: "登录后在个人中心查看收益统计。",
},
{
id: 3,
title: "如何联系客服?",
content: "可通过在线客服或提交工单联系我们。",
},
],
listParams:{
type:"3",//常见问题
lang:this.$i18n.locale,
pageNum:1,
pageSize:50
},
problemLoading:false,
DetailsParams:{
id:"",
lang:this.$i18n.locale,
},
info:""
};
},
mounted() {
this.DetailsParams.id = this.$route.query.id;
console.log(this.$route.query.id,"this.DetailsParams.id");
if (this.DetailsParams.id) {
this.fetchProblemDetails(this.DetailsParams)
}
this.fetchProblemsList(this.listParams)
},
methods: {
async fetchProblemsList(params) {
this.setLoading('problemLoading', true);
const res = await documentsList(params)
if(res && res.code === 200){
this.problems = res.rows;
// this.DetailsParams.id = this.problems[0].id;
// this.fetchProblemDetails(this.DetailsParams)
}
this.setLoading('problemLoading', false);
},
async fetchProblemDetails(params) {
this.setLoading('problemLoading', true);
const res = await findDataInfo(params)
if(res && res.code === 200){
console.log(res,"res");
this.info = res.data.content || ""
}
this.setLoading('problemLoading', false);
},
/**
* 跳转到问题详情页
* @param {number} id 问题ID
*/
handleClick(id) {
this.DetailsParams.id = id;
this.fetchProblemDetails(this.DetailsParams)
},
},
};

View File

@ -0,0 +1,131 @@
<template>
<div class="announcementDetails">
<section class="container">
<section class="leftNav">
<div class="leftNav-item " :class="{active:DetailsParams.id == item.id}" v-for="item in problems" :key="item.id" @click="handleClick(item.id)">
{{ item.title }}
</div>
</section>
<section class="rightContent">
<div v-if="problemLoading" class="loading-container">
<span class="loading-text">正在加载内容...</span>
</div>
<div v-else-if="info && info.trim()" class="dynamic-content" v-html="info"></div>
<div v-else class="no-content">
<p>暂无内容</p>
</div>
</section>
</section>
</div>
</template>
<script>
import IndexJs from "./index.js";
export default {
mixins: [IndexJs],
}
</script>
<style lang="scss" scoped>
.announcementDetails{
width: 100vw;
height: 100vh;
background: #F8F9FA;
padding-top: 60px;
}
.container{
display: flex;
justify-content: center;
width: 70vw;
height: 80vh;
margin: 0 auto;
background: #fff;
border-radius: 10px;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
padding: 20px;
padding-top: 50px;
.leftNav{
width: 200px;
height: 100%;
overflow-y: auto;
}
.rightContent{
flex: 1;
height: 100%;
margin-left: 50px;
overflow-y: auto;
padding-right: 20px;
.dynamic-content {
width: 100%;
margin: 0 auto;
//
:deep(table) {
border-collapse: collapse;
width: 100%;
margin: 16px 0;
}
:deep(th), :deep(td) {
border: 1px solid #d1d5db;
padding: 8px 12px;
text-align: left;
}
:deep(th) {
background: #f3f4f6;
font-weight: bold;
}
:deep(strong), :deep(b) {
font-weight: bold !important;
color: inherit !important;
font-style: normal !important;
}
:deep(em), :deep(i) {
font-style: italic !important;
color: inherit !important;
}
:deep(a) {
color: #007bff !important;
text-decoration: none !important;
&:hover {
text-decoration: underline !important;
}
}
}
.loading-container {
text-align: center;
padding: 40px 0;
.loading-text {
font-size: 16px;
color: #666;
vertical-align: middle;
}
}
.no-content {
text-align: center;
padding: 40px 0;
p {
font-size: 16px;
color: #999;
margin: 0;
}
}
}
}
.leftNav-item{
cursor: pointer;
padding: 10px;
margin-bottom: 10px;
text-decoration: underline;
text-align: right;
&:hover{
background:rgba(0,0,0,0.02);
color: #651FFF;
}
}
.active{
color: #651FFF;
}
</style>

View File

@ -0,0 +1,243 @@
import { documentsList } from '../../api/documentManagement'
export default {
name: 'Announcements',
data() {
return {
// 加载状态
loading: false,
// 搜索关键词
searchKeyword: '',
// 分页参数
currentPage: 1,
totalCount: 0,
// 公告数据
announcements: [
// {
// id: 1,
// title: 'ZEN挖矿服务即将结束',
// summary: 'ZEN挖矿服务将于近期结束请及时调整您的挖矿设置。',
// type: '重要通知',
// createTime: '2025-01-20T10:00:00.000Z',
// isTop: true
// },
// {
// id: 2,
// title: 'LKY即将减半',
// summary: 'LKY币种将在近期进行减半操作请关注相关通知。',
// type: '系统公告',
// createTime: '2025-01-19T15:30:00.000Z',
// isTop: false
// },
// {
// id: 3,
// title: 'PEP即将减产',
// summary: 'PEP币种挖矿难度调整产量将有所减少。',
// type: '市场动态',
// createTime: '2025-01-18T09:15:00.000Z',
// isTop: false
// },
// {
// id: 4,
// title: 'ETC+ZIL挖矿服务已结束',
// summary: 'ETC+ZIL双挖服务已正式结束感谢您的支持。',
// type: '服务通知',
// createTime: '2025-01-17T14:45:00.000Z',
// isTop: false
// },
// {
// id: 5,
// title: '有关2025年06月19日SCT池异常的说明',
// summary: 'SCT矿池在指定时间出现异常情况现已修复并提供补偿方案。',
// type: '故障说明',
// createTime: '2025-01-16T11:20:00.000Z',
// isTop: false
// },
// {
// id: 6,
// title: 'FB单挖矿池下线公告',
// summary: 'FB单挖矿池将于本月底正式下线请及时转移算力。',
// type: '下线通知',
// createTime: '2025-01-15T16:10:00.000Z',
// isTop: false
// }
],
// 搜索防抖定时器
searchTimer: null,
// Markdown 使用规则指南
showMarkdownGuide: false,
viewMode: 'list', // 'list' or 'editor'0
listParams:{
type:"3",
lang:this.$i18n.locale,
pageNum:1,
pageSize:10
},
announcementsLoading:false
}
},
mounted() {
try {
this.TypeList = JSON.parse(localStorage.getItem('TypeList'))
} catch (error) {
console.log(error);
}
// this.loadAnnouncements();
this.fetchAllList(this.listParams)
},
methods: {
async fetchAllList(params){
this.setLoading('announcementsLoading', true);
const res = await documentsList(params)
console.log(res,"res");
if (res.code === 200) {
this.announcements = res.rows
this.totalCount = res.total
}
this.setLoading('announcementsLoading', false);
},
/**
* 加载公告数据
*/
async loadAnnouncements() {
this.loading = true;
try {
// 这里应该调用API获取公告数据
// const response = await this.$api.getAnnouncements({
// page: this.currentPage,
// pageSize: this.pageSize,
// keyword: this.searchKeyword
// });
// this.announcements = response.data;
// this.totalCount = response.total;
// 模拟API调用延迟
await new Promise(resolve => setTimeout(resolve, 500));
} catch (error) {
console.error('加载公告失败:', error);
this.$message.error(this.$t('announcements.loadError') || '加载公告失败');
} finally {
this.loading = false;
}
},
/**
* 处理搜索输入
*/
handleSearchInput() {
if (this.searchTimer) {
clearTimeout(this.searchTimer);
}
// 防抖处理500ms后执行搜索
this.searchTimer = setTimeout(() => {
this.handleSearch();
}, 500);
},
/**
* 执行搜索
*/
handleSearch() {
this.currentPage = 1;
},
/**
* 处理页码变化
*/
handleCurrentChange(page) {
this.currentPage = page;
this.listParams.pageNum = page
this.fetchAllList(this.listParams)
},
handleSizeChange(size){
this.listParams.pageNum = 1
this.currentPage = 1;
this.listParams.pageSize = size
this.fetchAllList(this.listParams)
},
/**
* 处理公告点击
*/
handleAnnouncementClick(announcement) {
console.log(announcement,"announcement");
let url = `/${this.$i18n.locale}/announcementDetails`
// 跳转到公告详情页
this.$router.push({
path:url,
query:{
id:announcement.id
}
});
},
/**
* 查看所有公告
*/
handleViewAll() {
// 可以跳转到完整的公告列表页面或展开显示更多
this.pageSize = 20;
this.loadAnnouncements();
},
/**
* 切换Markdown使用规则指南的显示状态
*/
toggleMarkdownGuide() {
this.showMarkdownGuide = !this.showMarkdownGuide;
},
/**
* 切换视图模式 (list/editor)
*/
switchMode(mode) {
this.viewMode = mode;
// Markdown指南现在完全独立控制不与视图模式绑定
},
/**
* 返回首页
*/
goHome() {
this.$router.push('/');
},
/**
* 格式化日期
*/
formatDate(dateString) {
try {
return `${dateString.split("T")[0]} ${dateString.split("T")[1]}`
} catch (error) {
return ''
}
},
handelType(type){
try {
let label = this.TypeList.find(item => item.value == type).label
return this.$t(label)
} catch (error) {
return ''
}
},
},
beforeDestroy() {
// 清理定时器
if (this.searchTimer) {
clearTimeout(this.searchTimer);
}
}
}

View File

@ -1,33 +1,16 @@
<template>
<div class="announcements-container">
<div class="announcements-container" >
<!-- 主要内容区域 -->
<div class="main-content" v-loading="loading">
<div class="main-content" v-loading="announcementsLoading">
<!-- 页面标题 -->
<div class="page-header">
<div class="header-left">
<h1 class="page-title">{{ $t('home.announcements') || '公告中心' }}</h1>
</div>
<div class="header-actions">
<el-button-group>
<el-button
:type="viewMode === 'list' ? 'primary' : 'default'"
@click="switchMode('list')"
icon="el-icon-menu"
>
查看公告
</el-button>
<el-button
:type="viewMode === 'editor' ? 'primary' : 'default'"
@click="switchMode('editor')"
icon="el-icon-edit"
>
Markdown编辑器
</el-button>
</el-button-group>
</div>
</div>
<!-- Markdown 使用规则指南 -->
<div class="markdown-guide-section" v-if="showMarkdownGuide">
@ -339,7 +322,7 @@ ___ (三个或更多下划线)</code></pre>
<h3 class="announcement-title">{{ announcement.title }}</h3>
<div class="announcement-meta">
<span class="announcement-date">{{ formatDate(announcement.createTime) }}</span>
<span class="announcement-type" v-if="announcement.type">{{ announcement.type }}</span>
<span class="announcement-type" v-if="announcement.type">{{handelType(announcement.type) }}</span>
</div>
<p class="announcement-summary" v-if="announcement.summary">
{{ announcement.summary }}
@ -361,7 +344,7 @@ ___ (三个或更多下划线)</code></pre>
<!-- 分页信息和查看更多 -->
<div class="pagination-section" v-if="announcements.length > 0">
<div class="view-all-button">
<!-- <div class="view-all-button">
<el-button
type="text"
class="view-all-link"
@ -370,25 +353,17 @@ ___ (三个或更多下划线)</code></pre>
{{ $t('home.viewAll') || '查看所有' }} {{ totalCount }} {{ $t('home.articles') || '篇文章' }}
</el-button>
<!-- 了解使用规则按钮 -->
<el-button
type="text"
class="markdown-guide-btn"
@click="toggleMarkdownGuide"
:icon="showMarkdownGuide ? 'el-icon-arrow-up' : 'el-icon-question'"
>
{{ showMarkdownGuide ? '隐藏' : '了解' }}Markdown使用规则
</el-button>
</div>
</div> -->
<!-- 分页组件 -->
<el-pagination
v-if="totalCount > pageSize"
<el-pagination
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
:current-page="currentPage"
:page-size="pageSize"
:page-sizes="[10, 50, 100, 400]"
:total="totalCount"
layout="prev, pager, next"
layout="total, sizes, prev, pager, next, jumper"
class="pagination"
/>
</div>
@ -401,214 +376,11 @@ ___ (三个或更多下划线)</code></pre>
* 公告中心页面组件
* 提供公告列表展示搜索分页等功能
*/
import Index from './index.js'
export default {
name: 'Announcements',
data() {
return {
//
loading: false,
//
searchKeyword: '',
//
currentPage: 1,
pageSize: 10,
totalCount: 275,
//
announcements: [
{
id: 1,
title: 'ZEN挖矿服务即将结束',
summary: 'ZEN挖矿服务将于近期结束请及时调整您的挖矿设置。',
type: '重要通知',
createTime: '2025-01-20T10:00:00.000Z',
isTop: true
},
{
id: 2,
title: 'LKY即将减半',
summary: 'LKY币种将在近期进行减半操作请关注相关通知。',
type: '系统公告',
createTime: '2025-01-19T15:30:00.000Z',
isTop: false
},
{
id: 3,
title: 'PEP即将减产',
summary: 'PEP币种挖矿难度调整产量将有所减少。',
type: '市场动态',
createTime: '2025-01-18T09:15:00.000Z',
isTop: false
},
{
id: 4,
title: 'ETC+ZIL挖矿服务已结束',
summary: 'ETC+ZIL双挖服务已正式结束感谢您的支持。',
type: '服务通知',
createTime: '2025-01-17T14:45:00.000Z',
isTop: false
},
{
id: 5,
title: '有关2025年06月19日SCT池异常的说明',
summary: 'SCT矿池在指定时间出现异常情况现已修复并提供补偿方案。',
type: '故障说明',
createTime: '2025-01-16T11:20:00.000Z',
isTop: false
},
{
id: 6,
title: 'FB单挖矿池下线公告',
summary: 'FB单挖矿池将于本月底正式下线请及时转移算力。',
type: '下线通知',
createTime: '2025-01-15T16:10:00.000Z',
isTop: false
}
],
//
searchTimer: null,
mixins:[Index],
// Markdown 使
showMarkdownGuide: false,
viewMode: 'list' // 'list' or 'editor'
}
},
mounted() {
this.loadAnnouncements();
},
methods: {
/**
* 加载公告数据
*/
async loadAnnouncements() {
this.loading = true;
try {
// API
// const response = await this.$api.getAnnouncements({
// page: this.currentPage,
// pageSize: this.pageSize,
// keyword: this.searchKeyword
// });
// this.announcements = response.data;
// this.totalCount = response.total;
// API
await new Promise(resolve => setTimeout(resolve, 500));
} catch (error) {
console.error('加载公告失败:', error);
this.$message.error(this.$t('announcements.loadError') || '加载公告失败');
} finally {
this.loading = false;
}
},
/**
* 处理搜索输入
*/
handleSearchInput() {
if (this.searchTimer) {
clearTimeout(this.searchTimer);
}
// 500ms
this.searchTimer = setTimeout(() => {
this.handleSearch();
}, 500);
},
/**
* 执行搜索
*/
handleSearch() {
this.currentPage = 1;
this.loadAnnouncements();
},
/**
* 处理页码变化
*/
handleCurrentChange(page) {
this.currentPage = page;
this.loadAnnouncements();
},
/**
* 处理公告点击
*/
handleAnnouncementClick(announcement) {
//
this.$router.push({
name: 'AnnouncementDetail',
params: { id: announcement.id }
});
},
/**
* 查看所有公告
*/
handleViewAll() {
//
this.pageSize = 20;
this.loadAnnouncements();
},
/**
* 切换Markdown使用规则指南的显示状态
*/
toggleMarkdownGuide() {
this.showMarkdownGuide = !this.showMarkdownGuide;
},
/**
* 切换视图模式 (list/editor)
*/
switchMode(mode) {
this.viewMode = mode;
// Markdown
},
/**
* 返回首页
*/
goHome() {
this.$router.push('/');
},
/**
* 格式化日期
*/
formatDate(dateString) {
if (!dateString) return '';
const date = new Date(dateString);
const now = new Date();
const diffTime = now - date;
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
if (diffDays === 0) {
return '今天';
} else if (diffDays === 1) {
return '昨天';
} else if (diffDays < 7) {
return `${diffDays}天前`;
} else {
return date.toLocaleDateString('zh-CN');
}
}
},
beforeDestroy() {
//
if (this.searchTimer) {
clearTimeout(this.searchTimer);
}
}
}
</script>

View File

@ -0,0 +1,88 @@
import { documentsList,findDataInfo} from '../../api/documentManagement'
export default {
data() {
return {
problems: [
// {
// id: 1,
// title: "如何开始挖矿?",
// content: "详细步骤:注册、配置矿机、连接矿池。",
// },
// {
// id: 2,
// title: "如何查看收益?",
// content: "登录后在个人中心查看收益统计。",
// },
// {
// id: 3,
// title: "如何联系客服?",
// content: "可通过在线客服或提交工单联系我们。",
// },
],
listParams:{
type:"2",//常见问题
lang:this.$i18n.locale,
pageNum:1,
pageSize:50
},
problemLoading:false,
DetailsParams:{
id:"",
lang:this.$i18n.locale,
},
info:""
};
},
mounted() {
this.fetchProblemsList(this.listParams)
if (this.$route.query.id) {
this.DetailsParams.id = this.$route.query.id
}else if(this.problems.length > 0){
this.DetailsParams.id = this.problems[0].id;
}
console.log(this.DetailsParams.id,"this.DetailsPara发发发麻烦你ms.id");
this.fetchProblemDetails(this.DetailsParams)
},
methods: {
async fetchProblemsList(params) {
this.setLoading('problemLoading', true);
const res = await documentsList(params)
if(res && res.code === 200){
this.problems = res.rows;
if (!this.$route.query.id) {
this.DetailsParams.id = this.problems[0].id;
}
// this.DetailsParams.id = this.problems[0].id;
// this.fetchProblemDetails(this.DetailsParams)
}
this.setLoading('problemLoading', false);
},
async fetchProblemDetails(params) {
this.setLoading('problemLoading', true);
const res = await findDataInfo(params)
if(res && res.code === 200){
console.log(res,"res");
this.info = res.data.content || ""
}
this.setLoading('problemLoading', false);
},
/**
* 跳转到问题详情页
* @param {number} id 问题ID
*/
handleClick(id) {
this.DetailsParams.id = id;
this.fetchProblemDetails(this.DetailsParams)
},
},
};

View File

@ -0,0 +1,125 @@
<template>
<div>
<section class="container">
<section class="leftNav">
<div class="leftNav-item " :class="{active:DetailsParams.id == item.id}" v-for="item in problems" :key="item.id" @click="handleClick(item.id)">
{{ item.title }}
</div>
</section>
<section class="rightContent">
<div v-if="problemLoading" class="loading-container">
<span class="loading-text">正在加载内容...</span>
</div>
<div v-else-if="info && info.trim()" class="dynamic-content" v-html="info"></div>
<div v-else class="no-content">
<p>暂无内容</p>
</div>
</section>
</section>
</div>
</template>
<script>
import IndexJs from "./index.js";
export default {
mixins: [IndexJs],
}
</script>
<style lang="scss" scoped>
.container{
display: flex;
justify-content: center;
width: 80vw;
height: 80vh;
margin: 0 auto;
// background: #fff;
border-radius: 10px;
// box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
padding: 20px;
margin-top: 60px;
padding-top: 50px;
.leftNav{
width: 200px;
height: 100%;
overflow-y: auto;
}
.rightContent{
flex: 1;
height: 100%;
margin-left: 50px;
overflow-y: auto;
padding-right: 20px;
.dynamic-content {
width: 100%;
margin: 0 auto;
//
:deep(table) {
border-collapse: collapse;
width: 100%;
margin: 16px 0;
}
:deep(th), :deep(td) {
border: 1px solid #d1d5db;
padding: 8px 12px;
text-align: left;
}
:deep(th) {
background: #f3f4f6;
font-weight: bold;
}
:deep(strong), :deep(b) {
font-weight: bold !important;
color: inherit !important;
font-style: normal !important;
}
:deep(em), :deep(i) {
font-style: italic !important;
color: inherit !important;
}
:deep(a) {
color: #007bff !important;
text-decoration: none !important;
&:hover {
text-decoration: underline !important;
}
}
}
.loading-container {
text-align: center;
padding: 40px 0;
.loading-text {
font-size: 16px;
color: #666;
vertical-align: middle;
}
}
.no-content {
text-align: center;
padding: 40px 0;
p {
font-size: 16px;
color: #999;
margin: 0;
}
}
}
}
.leftNav-item{
cursor: pointer;
padding: 10px;
margin-bottom: 10px;
text-decoration: underline;
text-align: right;
&:hover{
background:rgba(0,0,0,0.02);
color: #651FFF;
}
}
.active{
color: #651FFF;
}
</style>

View File

@ -8,7 +8,7 @@ export default{
},
mounted(){
// this.fetchDataInfo()
if (this.$route.query.id) {
this.fetchDataInfo({id:this.$route.query.id})
@ -21,6 +21,10 @@ export default{
if (res && res.code === 200) {
this.modifyData = res.data
this.addParams.content = this.modifyData.content
this.addParams.type = String(this.addParams.type)
}
}

View File

@ -50,21 +50,40 @@ export default {
pageSizes: [50, 100, 300],
currentPage: 1,
TypeList:[
{
{//挖矿教程
value:"1",
label:"挖矿教程"
label:"backendSystem.miningTutorial",
articleUrl:"AccessMiningPool"
},
{
{//常见问题
value:"2",
label:"常见问题"
label:"backendSystem.commonProblems",
articleUrl:"commonProblem"
},
{
{//公告中心
value:"3",
label:"公告中心"
label:"backendSystem.announcementCenter",
articleUrl:"announcementDetails"
},
{
{//其他
value:"0",
label:"其他"
label:"backendSystem.other",
articleUrl:"",
children:[{
value:"1",
label:"home.serviceTerms",
articleUrl:"serviceTerms"
},{
value:"2",
label:"home.rate",
articleUrl:"rate"
},{
value:"3",
label:"home.APIfile",
articleUrl:"apiFile"
}
]
}
],
queryParams:{
@ -75,7 +94,7 @@ export default {
}
},
mounted() {
this.$addStorageEvent(1, "TypeList", JSON.stringify(this.TypeList));
this.listParams.lang = this.$i18n.locale
let token
try {
@ -343,7 +362,7 @@ export default {
return `${time.split("T")[0]} ${time.split("T")[1]}`
},
handleSizeChange(val) {
console.log(`每页 ${val}`);
this.listParams.pageSize = val
this.listParams.pageNum = 1
this.currentPage = 1
@ -351,7 +370,7 @@ export default {
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
this.listParams.pageNum = val
this.fetchListData(this.listParams);
},
@ -419,7 +438,8 @@ export default {
handelType(type){
try {
return this.TypeList.find(item => item.value == type).label
let label = this.TypeList.find(item => item.value == type).label
return this.$t(label)
} catch (error) {
return ''
}
@ -429,13 +449,18 @@ export default {
this.fetchListData(this.listParams);
},
handelQuery(){
this.listParams.keyword = this.queryParams.keyword
if (!this.listParams.keyword) {
this.$message.warning(this.$t("backendSystem.pleaseInputKeyword"))
return
}
this.fetchListData(this.listParams);
},
handleInputClear(){
// this.queryParams.keyword = ''
// this.queryParams.type = ''
// this.fetchListData(this.listParams);
}
this.listParams.keyword = this.queryParams.keyword
this.fetchListData(this.listParams);
},

View File

@ -1,80 +1,121 @@
<template>
<div v-loading="documentLoading">
<div class="main-title-box">
<div v-loading="documentLoading">
<div class="main-title-box">
<div class="main-title">{{ $t("backendSystem.documentManagement") }}</div>
<el-button class="add-btn" @click="handelAddDocument"
>{{ $t("backendSystem.addDocument") }}
<i class="iconfont icon-youjiantou1 arrow"></i
></el-button>
</div>
<el-form :inline="true" :model="queryParams" class="demo-form-inline" ref="formRef">
<el-form
:inline="true"
:model="queryParams"
class="demo-form-inline"
ref="formRef"
>
<el-form-item label="文档类型" prop="type">
<el-select
class="input"
size="middle"
clearable
size="middle"
ref="screen"
@change="changeScreen(queryParams.type)"
v-model="queryParams.type"
:placeholder="$t(`personal.screen`)"
:placeholder="$t(`backendSystem.pleaseSelect`)"
>
<el-option
v-for="item in TypeList"
:key="item.value"
:label="item.label"
:label="$t(item.label)"
:value="item.value"
>
<div style="display: flex; align-items: center">
<img :src="item.imgUrl" style="float: left; width: 20px" />
<span style="float: left; margin-left: 5px">
{{ item.label }}</span
{{ $t(item.label) }}</span
>
</div>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="搜索" style="margin-left: 5vw" prop="minerUser">
<el-input v-model="queryParams.keyword" :placeholder="$t('backendSystem.pleaseInput')" clearable @clear="handleInputClear"></el-input>
<el-form-item label="搜索" style="margin-left: 5vw" prop="minerUser">
<el-input
v-model="queryParams.keyword"
:placeholder="$t('backendSystem.pleaseInput')"
clearable
@clear="handleInputClear"
></el-input>
</el-form-item>
<el-form-item style="margin-left: 1vw">
<el-button type="primary" @click="handelQuery">{{$t('backendSystem.query')}}</el-button>
<el-button type="primary" @click="handelQuery">{{
$t("backendSystem.query")
}}</el-button>
</el-form-item>
</el-form>
<el-table
:data="tableData"
border
style="width: 100%; margin-bottom: 18px"
:header-cell-style="{ 'text-align': 'center' }"
:cell-style="{ 'text-align': 'center' }"
height="60vh"
<el-table
:data="tableData"
border
style="width: 100%; margin-bottom: 18px"
:header-cell-style="{ 'text-align': 'center' }"
:cell-style="{ 'text-align': 'center' }"
height="60vh"
>
<el-table-column prop="id" label="ID" width="60" />
<el-table-column
prop="createTime"
label="创建时间"
width="160"
show-overflow-tooltip
>
<el-table-column prop="id" label="ID" width="60" />
<el-table-column prop="createTime" label="创建时间" width="160" show-overflow-tooltip >
<template slot-scope="scope">
{{handelTime(scope.row.createTime)}}
</template>
</el-table-column>
<template slot-scope="scope">
{{ handelTime(scope.row.createTime) }}
</template>
</el-table-column>
<el-table-column prop="createUser" label="创建人" width="160" show-overflow-tooltip />
<el-table-column prop="content" label="文档内容" show-overflow-tooltip />
<el-table-column prop="title" label="文档标题" width="200" show-overflow-tooltip />
<el-table-column prop="type" label="文档类型" width="100" show-overflow-tooltip >
<template slot-scope="scope">
{{handelType(scope.row.type)}}
</template>
</el-table-column>
<el-table-column
prop="createUser"
label="创建人"
width="160"
show-overflow-tooltip
/>
<el-table-column prop="content" label="文档内容" show-overflow-tooltip />
<el-table-column
prop="title"
label="文档标题"
width="200"
show-overflow-tooltip
/>
<el-table-column
prop="type"
label="文档类型"
width="100"
show-overflow-tooltip
>
<template slot-scope="scope">
{{ handelType(scope.row.type) }}
</template>
</el-table-column>
<el-table-column prop="updateTime" label="修改时间" width="160" show-overflow-tooltip >
<template slot-scope="scope">
{{handelTime(scope.row.updateTime)}}
</template>
</el-table-column>
<el-table-column prop="updateUser" label="修改人" width="160" show-overflow-tooltip />
<el-table-column :label="$t('backendSystem.operation')" width="160">
<el-table-column
prop="updateTime"
label="修改时间"
width="160"
show-overflow-tooltip
>
<template slot-scope="scope">
{{ handelTime(scope.row.updateTime) }}
</template>
</el-table-column>
<el-table-column
prop="updateUser"
label="修改人"
width="160"
show-overflow-tooltip
/>
<el-table-column :label="$t('backendSystem.operation')" width="160">
<template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.row)">{{
$t("backendSystem.edit")
@ -94,40 +135,34 @@
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<!-- <el-row>
<el-col :span="24" style="display: flex; justify-content: center;">
<el-pagination
style="margin:0 auto;margin-top: 10px;"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="currentPage"
:page-sizes="pageSizes"
:page-size="userListParams.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</el-col>
</el-row> -->
</div>
</template>
</el-table>
<el-row>
<el-col :span="24" style="display: flex; justify-content: center">
<el-pagination
style="margin: 0 auto;"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="currentPage"
:page-sizes="pageSizes"
:page-size="listParams.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
</el-col>
</el-row>
</div>
</template>
<script>
import Index from "./index";
export default {
mixins: [Index],
};
</script>
import Index from "./index";
export default {
mixins: [Index],
};
</script>
<style lang="scss" scoped>
.main-title-box {
.main-title-box {
display: flex;
align-items: center;
margin-bottom: 20px;
@ -148,18 +183,18 @@
transform: scale(1.05);
}
}
.main-title {
font-size: 24px;
font-weight: bold;
color: #333;
margin-bottom: 18px;
}
.main-title {
font-size: 24px;
font-weight: bold;
.elBtn {
color: #333;
margin-bottom: 18px;
}
.elBtn {
background: #e60751;
color: #fff;
border: none;
margin-left: 18px;
}
</style>
</style>

View File

@ -2,13 +2,13 @@ import { findDataInfo } from "../../../api/documentManagement"
export default{
data(){
return{
typeArray:[],
}
},
mounted(){
// this.fetchDataInfo()
if (this.$route.query.id) {
this.fetchDataInfo({id:this.$route.query.id})
@ -20,7 +20,14 @@ export default{
const res = await findDataInfo(params)
if (res && res.code === 200) {
this.modifyData = res.data
this.addParams.content = this.modifyData.content
this.addParams = this.modifyData
// 确保type字段为字符串类型以便与TypeList中的value匹配
this.addParams.type = String(this.addParams.type)
this.addParams.childType = String(this.addParams.childType)
this.typeArray = [this.addParams.type]
// 标记已从后台获取数据,避免被本地存储覆盖
this.hasBackendData = true
}
}

View File

@ -1,3 +1,5 @@
import { documentsList } from '../../api/documentManagement'
export default{
name: 'HelpCenter',
data() {
@ -11,8 +13,9 @@ export default{
{ id: 1, name: 'API文档', route: 'apiFile' },
{ id: 2, name: '挖矿教程', route: 'AccessMiningPool/nexaAccess' },
{ id: 3, name: '服务条款', route: 'ServiceTerms' },
{ id: 3, name: '费率', route: 'rate' },
{ id: 4, name: '公告中心', route: 'announcements' },
{ id: 4, name: '费率', route: 'rate' },
{ id: 5, name: '公告中心', route: 'announcements' },
{ id: 6, name: '常见问题', route: 'commonProblem' },
],
/** 推荐内容数据 */
@ -58,18 +61,63 @@ export default{
author: '文章ID1星期 19发布',
comments: '0'
}
],
activeParams:{
type:"3",//公告中心
lang:this.$i18n.locale,
pageNum:1,
pageSize:10
},
TypeList:[
{
value:"1",
label:"挖矿教程"
},
{
value:"2",
label:"常见问题"
},
{
value:"3",
label:"公告中心"
},
{
value:"0",
label:"其他"
},
]
}
},
mounted(){
try {
this.TypeList = JSON.parse(localStorage.getItem('TypeList'))
} catch (error) {
console.log(error);
}
this.fetchActivityList(this.activeParams)
},
methods: {
async fetchActivityList(params){
const res = await documentsList(params)
console.log(res,"res");
if (res.code === 200) {
this.activities = res.rows
}
},
/**
* 处理搜索功能
*/
handleSearch() {
if (this.searchQuery.trim()) {
console.log('搜索内容:', this.searchQuery);
// 实际项目中这里应该调用搜索API
this.$message.success(`搜索: ${this.searchQuery}`);
let url = `/${this.$i18n.locale}/searchResult`
this.$router.push({
path:url,
query:{
keyword:this.searchQuery
}
})
}
},
@ -85,12 +133,38 @@ export default{
},
/**
* 处理查看更多按钮点击
* 处理查看更多按钮点击 跳转公告中心页面
*/
handleViewMore() {
console.log('查看更多活动');
// 实际项目中这里应该跳转到活动列表页面
this.$message.info('查看更多活动');
this.$router.push(`/${this.$i18n.locale}/announcements`);
},
handelType(type){
try {
let label = this.TypeList.find(item => item.value == type).label
return this.$t(label)
} catch (error) {
return ''
}
},
handelTime(time){
try {
return `${time.split("T")[0]} ${time.split("T")[1]}`
} catch (error) {
return ''
}
},
handleActivityClick(activity){
let url = `/${this.$i18n.locale}/announcementDetails`
// 跳转到公告详情页
this.$router.push({
path:url,
query:{
id:activity.id
}
});
}
}
}

View File

@ -59,14 +59,15 @@
v-for="activity in activities"
:key="activity.id"
class="activity-item"
@click="handleActivityClick(activity)"
>
<div class="activity-header">
<span class="activity-badge">{{ activity.type }}</span>
<span class="activity-badge">{{ handelType(activity.type) }}</span>
</div>
<p class="activity-title">{{ activity.title }}</p>
<div class="activity-meta">
<span class="activity-author">{{ activity.author }}</span>
<span class="activity-comments">{{ activity.comments }}</span>
<span class="activity-author">{{handelTime(activity.createTime) }}</span>
<!-- <span class="activity-comments">{{ activity.comments }}</span> -->
</div>
</div>
</div>
@ -74,14 +75,14 @@
<!-- 查看更多链接 -->
<div class="view-more">
<a href="#" class="view-more-link" @click="handleViewMore">
查看更多活动中的更多
查看更多活动公告
</a>
</div>
</div>
</div>
<!-- 底部帮助中心链接 -->
<div class="bottom-section">
<!-- <div class="bottom-section">
<div class="help-center-link">
<span>帮助中心</span>
<select v-model="selectedLanguage" class="language-select">
@ -89,7 +90,7 @@
<option value="en">English</option>
</select>
</div>
</div>
</div> -->
</div>
</template>

View File

@ -1563,10 +1563,12 @@ export default {
if (url === '/AccessMiningPool') {
const coin = this.currencyList.find(item => item.value === this.params.coin);
if (!coin) return;
let jumpName = coin.path.charAt(0).toUpperCase() + coin.path.slice(1) //name跳转 首字母大写
// let jumpName = coin.path.charAt(0).toUpperCase() + coin.path.slice(1) //name跳转 首字母大写
let url = `/${this.lang}/AccessMiningPool`
// 使用 name 进行导航,避免重复的路由参数
this.$router.push({
name: jumpName,
path:url,
params: {
lang: this.lang,
coin: this.params.coin,
@ -1578,8 +1580,9 @@ export default {
} else {
// 移除开头的斜杠,统一处理路径格式
const cleanPath = url.startsWith('/') ? url.slice(1) : url;
this.$router.push(`/${this.lang}/${cleanPath}`);
// const cleanPath = url.startsWith('/') ? url.slice(1) : url;
let cleanPath = `/${this.lang}/AccessMiningPool`
this.$router.push(cleanPath);
}
},

View File

@ -0,0 +1,176 @@
import { getListDataByPage } from "../../api/documentManagement";
export default {
data() {
return {
searchKeyword: '',
searchResults: [],
currentPage: 1,
pageSize: 10,
totalCount: 0,
previewVisible: false,
previewData: null,
pageNum:1,
// 文档类型映射
documentTypes: {
// '1': '服务条款',
// '2': 'API文档',
// '3': '挖矿教程',
// '0': '其他'
},
searchLoading:false
}
},
mounted() {
try {
this.documentTypes= JSON.parse(localStorage.getItem("TypeList")) || {}
} catch (error) {
console.log(error,"error");
}
// 从URL参数获取搜索关键词和结果数据
this.searchKeyword = this.$route.query.keyword || '';
// 如果有搜索结果数据,直接使用
if (this.$route.query.results) {
try {
const results = JSON.parse(decodeURIComponent(this.$route.query.results));
this.searchResults = results.rows || [];
this.totalCount =results.total || 0;
} catch (error) {
console.error('解析搜索结果数据失败:', error);
}
} else if (this.searchKeyword) {
// 如果没有结果数据但有关键词,则重新搜索
this.fetchSearchResults();
}
},
methods: {
/**
* 获取搜索结果
*/
async fetchSearchResults() {
this.setLoading('searchLoading', true);
try {
const response = await getListDataByPage({
keyword: this.searchKeyword,
pageNum: this.pageNum,
pageSize: this.pageSize,
lang: this.$i18n.locale
});
if (response && response.code === 200) {
this.searchResults = response.rows || [];
this.totalCount = response.total || 0;
}
} catch (error) {
console.error('获取搜索结果失败:', error);
this.$message.error('获取搜索结果失败');
}
this.setLoading('searchLoading', false);
},
/**
* 高亮关键词
*/
highlightKeyword(text) {
if (!this.searchKeyword || !text) return text;
const regex = new RegExp(`(${this.searchKeyword})`, 'gi');
return text.replace(regex, '<mark>$1</mark>');
},
/**
* 获取内容预览
*/
getContentPreview(content) {
if (!content) return '';
// 移除HTML标签获取纯文本
const text = content.replace(/<[^>]*>/g, '');
return text.length > 100 ? text.substring(0, 100) + '...' : text;
},
/**
* 格式化日期
*/
formatDate(dateString) {
if (!dateString) return '';
const date = new Date(dateString);
return date.toLocaleDateString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
});
},
/**
* 获取文档类型名称
*/
getDocumentTypeName(type) {
try {
let label = this.documentTypes.find(item => item.value == type)?.label
return this.$t(label)
} catch (error) {
console.log(error,"error");
return '未知类型';
}
},
/**
* 处理分页变化
*/
handlePageChange(page) {
this.currentPage = page;
this.fetchSearchResults();
},
/**
* 处理搜索结果项点击
*/
handleItemClick(item) {
// this.handlePreview(item);
let url
if (item.articleUrl) {
url = `/${this.$i18n.locale}/${item.articleUrl}`
}
this.$router.push({
path:url,
query:{
id:item.id
}
})
},
/**
* 预览文档
*/
handlePreview(item) {
this.previewData = item;
this.previewVisible = true;
},
/**
* 关闭预览对话框
*/
handlePreviewClose() {
this.previewVisible = false;
this.previewData = null;
},
handleCurrentChange(page){
this.pageNum = page
this.fetchSearchResults()
},
handleSizeChange(size){
this.pageSize = size
this.currentPage = 1
this.pageNum = 1
this.fetchSearchResults()
}
}
}

View File

@ -0,0 +1,463 @@
<template>
<div class="search-result-page" v-loading="searchLoading">
<!-- 搜索结果头部 -->
<div class="result-header">
<div class="header-container">
<div class="header-left">
<h1 class="page-title">搜索结果</h1>
<p class="search-info" v-if="searchResults.length > 0">
关键词 "<strong>{{ searchKeyword }}</strong>" 找到 <strong>{{ totalCount }}</strong> 条相关结果
</p>
</div>
<div class="header-right">
<el-button type="primary" @click="goBack">
<i class="el-icon-arrow-left"></i>
返回搜索
</el-button>
</div>
</div>
</div>
<!-- 搜索结果区域 -->
<div class="search-content">
<div class="result-container">
<!-- 搜索结果列表 -->
<div class="result-list" v-if="searchResults.length > 0">
<div
v-for="item in searchResults"
:key="item.id"
class="result-item"
@click="handleItemClick(item)"
>
<!-- 文档图标 -->
<div class="item-icon">
<img
v-if="item.titleUrl"
:src="item.titleUrl"
alt="fail"
class="doc-icon"
/>
<i v-else class="el-icon-document doc-icon-placeholder"></i>
</div>
<!-- 文档信息 -->
<div class="item-content">
<h3 class="item-title" v-html="highlightKeyword(item.title)"></h3>
<p class="item-subtitle" v-if="item.subTitle">
{{ item.subTitle }}
</p>
<div class="item-meta">
<span class="meta-item">
<i class="el-icon-time"></i>
{{ formatDate(item.createTime) }}
</span>
<span class="meta-item">
<i class="el-icon-user"></i>
{{ item.createUser }}
</span>
<span class="meta-item">
<i class="el-icon-collection-tag"></i>
{{ getDocumentTypeName(item.type) }}
</span>
</div>
<div class="item-preview" v-if="item.content">
<span v-html="getContentPreview(item.content)"></span>
</div>
</div>
<!-- 操作按钮 -->
<div class="item-actions">
<el-button
type="text"
size="small"
@click.stop="handlePreview(item)"
>
<i class="el-icon-view"></i>
预览
</el-button>
</div>
</div>
</div>
<!-- 无搜索结果 -->
<div class="no-result" v-else>
<div class="no-result-icon">
<i class="el-icon-search"></i>
</div>
<h3>未找到相关结果</h3>
<p>关键词 "<strong>{{ searchKeyword }}</strong>" 没有找到匹配的文档</p>
<el-button type="primary" @click="goBack">重新搜索</el-button>
</div>
<!-- 分页组件 -->
<div class="pagination-container" v-if="searchResults.length > 0">
<el-pagination
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
:current-page="currentPage"
:page-sizes="[10, 50, 100, 400]"
:total="totalCount"
layout="total, sizes, prev, pager, next, jumper"
class="pagination"
/>
</div>
</div>
</div>
<!-- 预览对话框 -->
<el-dialog
title="文档预览"
:visible.sync="previewVisible"
width="80%"
:before-close="handlePreviewClose"
class="preview-dialog"
>
<div class="preview-content" v-if="previewData">
<h2>{{ previewData.title }}</h2>
<div class="preview-meta">
<span>类型{{ getDocumentTypeName(previewData.type) }}</span>
<span>创建时间{{ formatDate(previewData.createTime) }}</span>
<span>创建者{{ previewData.createUser }}</span>
</div>
<div class="preview-body" v-html="previewData.content"></div>
</div>
</el-dialog>
</div>
</template>
<script>
import IndexJs from "./index.js";
export default {
mixins: [IndexJs],
methods: {
/**
* 返回搜索页面
*/
goBack() {
this.$router.push(`/${this.$i18n.locale}/helpCenter`)
}
}
}
</script>
<style lang="scss" scoped>
.search-result-page {
min-height: 100vh;
background: #f5f7fa;
}
/* 搜索结果头部 */
.result-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 18px 0;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}
.header-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.header-left {
color: white;
}
.page-title {
margin: 0 0 8px 0;
font-size: 28px;
font-weight: 600;
}
.search-info {
margin: 0;
font-size: 16px;
opacity: 0.9;
strong {
color: #ffd700;
}
}
.header-right {
.el-button {
background: rgba(255, 255, 255, 0.2);
border: 1px solid rgba(255, 255, 255, 0.3);
color: white;
&:hover {
background: rgba(255, 255, 255, 0.3);
}
}
}
/* 搜索内容区域 */
.search-content {
max-width: 1200px;
margin: 0 auto;
padding: 40px 20px;
}
.result-container {
background: white;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
overflow: hidden;
}
/* 搜索结果列表 */
.result-list {
padding: 0;
}
.result-item {
display: flex;
align-items: flex-start;
padding: 24px 30px;
border-bottom: 1px solid #f5f5f5;
cursor: pointer;
transition: all 0.3s ease;
&:hover {
background: #f8f9ff;
transform: translateX(4px);
}
&:last-child {
border-bottom: none;
}
}
.item-icon {
margin-right: 16px;
flex-shrink: 0;
}
.doc-icon {
width: 40px;
height: 40px;
border-radius: 8px;
object-fit: cover;
}
.doc-icon-placeholder {
width: 40px;
height: 40px;
border-radius: 8px;
background: #f0f0f0;
display: flex;
align-items: center;
justify-content: center;
color: #999;
font-size: 20px;
}
.item-content {
flex: 1;
min-width: 0;
}
.item-title {
margin: 0 0 8px 0;
font-size: 18px;
font-weight: 600;
color: #333;
line-height: 1.4;
mark {
background: #fff3cd;
color: #856404;
padding: 2px 4px;
border-radius: 3px;
}
}
.item-subtitle {
margin: 0 0 8px 0;
font-size: 14px;
color: #666;
line-height: 1.4;
}
.item-meta {
display: flex;
flex-wrap: wrap;
gap: 16px;
margin-bottom: 12px;
}
.meta-item {
display: flex;
align-items: center;
font-size: 12px;
color: #999;
i {
margin-right: 4px;
font-size: 14px;
}
}
.item-preview {
font-size: 14px;
color: #666;
line-height: 1.6;
background: #f8f9fa;
padding: 12px;
border-radius: 6px;
border-left: 3px solid #667eea;
}
.item-actions {
display: flex;
flex-direction: column;
gap: 8px;
margin-left: 16px;
flex-shrink: 0;
}
/* 无搜索结果 */
.no-result {
text-align: center;
padding: 80px 20px;
color: #666;
strong {
color: #667eea;
}
}
.no-result-icon {
font-size: 64px;
color: #ddd;
margin-bottom: 20px;
}
.no-result h3 {
margin: 0 0 12px 0;
font-size: 24px;
font-weight: 500;
color: #333;
}
.no-result p {
margin: 0 0 24px 0;
font-size: 16px;
color: #999;
}
/* 分页容器 */
.pagination-container {
padding: 30px;
text-align: center;
border-top: 1px solid #f0f0f0;
background: #fafbfc;
}
/* 预览对话框 */
.preview-dialog {
.preview-content {
h2 {
margin: 0 0 16px 0;
color: #333;
font-size: 24px;
}
}
.preview-meta {
display: flex;
gap: 20px;
margin-bottom: 24px;
padding: 16px;
background: #f8f9fa;
border-radius: 6px;
font-size: 14px;
color: #666;
}
.preview-body {
line-height: 1.8;
color: #333;
:deep(h1), :deep(h2), :deep(h3) {
color: #333;
margin: 20px 0 12px 0;
}
:deep(p) {
margin: 12px 0;
}
:deep(img) {
max-width: 100%;
height: auto;
border-radius: 6px;
}
:deep(table) {
border-collapse: collapse;
width: 100%;
margin: 16px 0;
}
:deep(th), :deep(td) {
border: 1px solid #ddd;
padding: 8px 12px;
text-align: left;
}
:deep(th) {
background: #f5f5f5;
font-weight: bold;
}
}
}
/* 响应式设计 */
@media (max-width: 768px) {
.header-container {
padding: 0 15px;
flex-direction: column;
gap: 20px;
text-align: center;
}
.page-title {
font-size: 24px;
}
.search-content {
padding: 20px 15px;
}
.result-item {
padding: 16px 20px;
flex-direction: column;
}
.item-icon {
margin-right: 0;
margin-bottom: 12px;
}
.item-actions {
margin-left: 0;
margin-top: 12px;
flex-direction: row;
justify-content: flex-end;
}
.item-meta {
gap: 12px;
}
.preview-meta {
flex-direction: column;
gap: 8px;
}
}
</style>