From 3d7240565e55358705a393fde096400733b39796 Mon Sep 17 00:00:00 2001 From: mayiming <1627832236@qq.com> Date: Mon, 6 Oct 2025 01:32:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=95=B4=E6=96=B0=E9=97=BB=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- management/package-lock.json | 430 +++++++ management/package.json | 1 + management/src/components/ArticlePublish.vue | 1019 +++++++++++++++++ management/src/components/HelloWorld.vue | 8 - management/src/views/news/NewsView.vue | 543 ++++++--- management/src/views/publish/QuillEditor.vue | 549 +++++---- server/.idea/dataSources.xml | 17 + server/.idea/data_source_mapping.xml | 7 + server/config/config.yaml | 6 +- server/go.mod | 36 +- server/go.sum | 87 +- .../handler/article/createarticlehandler.go | 23 +- .../handler/article/deletearticlehandler.go | 6 +- .../handler/article/detailarticlehandler.go | 6 +- .../handler/article/listarticlehandler.go | 24 +- .../handler/article/updatearticlehandler.go | 6 +- .../logic/article/createarticlelogic.go | 96 +- .../logic/article/deletearticlelogic.go | 10 +- .../logic/article/detailarticlelogic.go | 10 +- .../logic/article/listarticlelogic.go | 84 +- .../logic/article/updatearticlelogic.go | 10 +- .../article/internal/model/articlemodel.go | 4 +- .../internal/model/articlemodel_gen.go | 131 ++- .../internal/article/internal/types/types.go | 7 +- server/router/router.go | 35 +- 25 files changed, 2692 insertions(+), 463 deletions(-) create mode 100644 management/src/components/ArticlePublish.vue delete mode 100644 management/src/components/HelloWorld.vue create mode 100644 server/.idea/dataSources.xml create mode 100644 server/.idea/data_source_mapping.xml rename server/internal/article/{internal => }/handler/article/createarticlehandler.go (53%) rename server/internal/article/{internal => }/handler/article/deletearticlehandler.go (76%) rename server/internal/article/{internal => }/handler/article/detailarticlehandler.go (76%) rename server/internal/article/{internal => }/handler/article/listarticlehandler.go (53%) rename server/internal/article/{internal => }/handler/article/updatearticlehandler.go (76%) diff --git a/management/package-lock.json b/management/package-lock.json index 40e3d929..7f126397 100644 --- a/management/package-lock.json +++ b/management/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "@element-plus/icons-vue": "^2.3.2", + "axios": "^1.12.2", "echarts": "^6.0.0", "element-plus": "^2.11.4", "pinia": "^3.0.3", @@ -1068,6 +1069,21 @@ "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz", "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.12.2", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/birpc": { "version": "2.6.1", "resolved": "https://registry.npmmirror.com/birpc/-/birpc-2.6.1.tgz", @@ -1095,6 +1111,18 @@ "integrity": "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==", "dev": true }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/chokidar": { "version": "4.0.3", "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz", @@ -1117,6 +1145,17 @@ "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/copy-anything": { "version": "3.0.5", "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-3.0.5.tgz", @@ -1141,6 +1180,14 @@ "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.18.tgz", "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==" }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-libc": { "version": "2.1.1", "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.1.tgz", @@ -1150,6 +1197,19 @@ "node": ">=8" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/echarts": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/echarts/-/echarts-6.0.0.tgz", @@ -1200,6 +1260,47 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz", @@ -1250,6 +1351,40 @@ "node": ">=8" } }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", @@ -1264,6 +1399,60 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", @@ -1273,6 +1462,42 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/hookable": { "version": "5.5.3", "resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz", @@ -1616,6 +1841,14 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/memoize-one": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz", @@ -1648,6 +1881,25 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mitt": { "version": "3.0.1", "resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz", @@ -1776,6 +2028,11 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/quill": { "version": "2.0.3", "resolved": "https://registry.npmmirror.com/quill/-/quill-2.0.3.tgz", @@ -3121,6 +3378,21 @@ "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz", "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "axios": { + "version": "1.12.2", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "requires": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "birpc": { "version": "2.6.1", "resolved": "https://registry.npmmirror.com/birpc/-/birpc-2.6.1.tgz", @@ -3142,6 +3414,15 @@ "integrity": "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==", "dev": true }, + "call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + } + }, "chokidar": { "version": "4.0.3", "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz", @@ -3158,6 +3439,14 @@ "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==", "dev": true }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, "copy-anything": { "version": "3.0.5", "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-3.0.5.tgz", @@ -3176,12 +3465,27 @@ "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.18.tgz", "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==" }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, "detect-libc": { "version": "2.1.1", "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.1.tgz", "integrity": "sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==", "dev": true }, + "dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "requires": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + } + }, "echarts": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/echarts/-/echarts-6.0.0.tgz", @@ -3225,6 +3529,35 @@ "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" }, + "es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, + "es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "requires": { + "es-errors": "^1.3.0" + } + }, + "es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "requires": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + } + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz", @@ -3262,6 +3595,23 @@ "to-regex-range": "^5.0.1" } }, + "follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==" + }, + "form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + } + }, "fsevents": { "version": "2.3.3", "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", @@ -3269,12 +3619,69 @@ "dev": true, "optional": true }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "requires": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + } + }, + "get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "requires": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + } + }, + "gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "requires": { + "function-bind": "^1.1.2" + } + }, "hookable": { "version": "5.5.3", "resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz", @@ -3446,6 +3853,11 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" + }, "memoize-one": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz", @@ -3471,6 +3883,19 @@ } } }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, "mitt": { "version": "3.0.1", "resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz", @@ -3554,6 +3979,11 @@ "source-map-js": "^1.2.1" } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "quill": { "version": "2.0.3", "resolved": "https://registry.npmmirror.com/quill/-/quill-2.0.3.tgz", diff --git a/management/package.json b/management/package.json index f8cca9a5..e748a84e 100644 --- a/management/package.json +++ b/management/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@element-plus/icons-vue": "^2.3.2", + "axios": "^1.12.2", "echarts": "^6.0.0", "element-plus": "^2.11.4", "pinia": "^3.0.3", diff --git a/management/src/components/ArticlePublish.vue b/management/src/components/ArticlePublish.vue new file mode 100644 index 00000000..9f7fc550 --- /dev/null +++ b/management/src/components/ArticlePublish.vue @@ -0,0 +1,1019 @@ + + + + + diff --git a/management/src/components/HelloWorld.vue b/management/src/components/HelloWorld.vue deleted file mode 100644 index c3057bd2..00000000 --- a/management/src/components/HelloWorld.vue +++ /dev/null @@ -1,8 +0,0 @@ - - - - - diff --git a/management/src/views/news/NewsView.vue b/management/src/views/news/NewsView.vue index 44942b98..e124e735 100644 --- a/management/src/views/news/NewsView.vue +++ b/management/src/views/news/NewsView.vue @@ -1,198 +1,403 @@ \ No newline at end of file +/* 表格样式 */ +.el-table .el-table__cell { vertical-align: middle; } +.el-table__header-wrapper th { background-color: #fafafa !important; font-weight: 600; color: #333; } +.action-buttons .el-button { margin-right: 8px; } +.content-preview { color: #666; line-height: 1.5; word-break: break-all; } +.content-full { min-height: 300px; padding: 20px; background-color: #f9fafb; border-radius: 8px; } +.el-dialog__title { font-size: 18px !important; font-weight: 600 !important; } + +/* 分页器样式 */ +.custom-pagination { justify-content: flex-end !important; } +.custom-pagination .el-pagination__total, +.custom-pagination .el-pagination__sizes, +.custom-pagination .el-pagination__jump { margin-right: 16px !important; } +.custom-pagination .el-pagination__jump .el-input { width: 60px !important; } + +/* 抽屉内表单样式 */ +.publish-form-container { padding: 0 20px; } +.form-group { margin-bottom: 24px; } +.form-label { display: block; margin-bottom: 8px; color: #333; font-size: 14px; font-weight: 600; } +.quill-editor { height: 350px; border-radius: 4px; border: 1px solid #dcdfe6; } +.cover-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; } +.cover-uploader .el-upload:hover { border-color: #409EFF; } +.cover-uploader-icon { font-size: 28px; color: #8c939d; width: 178px; height: 178px; text-align: center; } +.cover-preview { width: 178px; height: 178px; display: block; object-fit: cover; } + + diff --git a/management/src/views/publish/QuillEditor.vue b/management/src/views/publish/QuillEditor.vue index c7bc733d..881a9441 100644 --- a/management/src/views/publish/QuillEditor.vue +++ b/management/src/views/publish/QuillEditor.vue @@ -1,22 +1,23 @@ \ No newline at end of file + diff --git a/server/.idea/dataSources.xml b/server/.idea/dataSources.xml new file mode 100644 index 00000000..4c774329 --- /dev/null +++ b/server/.idea/dataSources.xml @@ -0,0 +1,17 @@ + + + + + mysql.8 + true + com.mysql.cj.jdbc.Driver + jdbc:mysql://rm-f8z6oc5a03331500p8o.mysql.rds.aliyuncs.com:3306 + + + + + + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/server/.idea/data_source_mapping.xml b/server/.idea/data_source_mapping.xml new file mode 100644 index 00000000..91e5379e --- /dev/null +++ b/server/.idea/data_source_mapping.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/server/config/config.yaml b/server/config/config.yaml index 951abdae..b0c7fc1c 100644 --- a/server/config/config.yaml +++ b/server/config/config.yaml @@ -10,11 +10,11 @@ oss: object_prefix: "article/" mysql: - host: "localhost" + host: "rm-f8z6oc5a03331500p8o.mysql.rds.aliyuncs.com" port: 3306 username: "root" - password: "your_mysql_password" - database: "article_db" + password: "Root123456" + database: "hldr" charset: "utf8mb4" upload: diff --git a/server/go.mod b/server/go.mod index 3b74961d..e33b1e97 100644 --- a/server/go.mod +++ b/server/go.mod @@ -3,35 +3,63 @@ module github.com/JACKYMYPERSON/hldrCenter go 1.24.0 require ( - github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible // indirect + github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible + github.com/gin-gonic/gin v1.11.0 + github.com/zeromicro/go-zero v1.9.1 + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + filippo.io/edwards25519 v1.1.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect github.com/bytedance/sonic v1.14.0 // indirect github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudwego/base64x v0.1.6 // indirect github.com/fatih/color v1.18.0 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect github.com/gin-contrib/sse v1.1.0 // indirect - github.com/gin-gonic/gin v1.11.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.27.0 // indirect + github.com/go-sql-driver/mysql v1.9.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/goccy/go-yaml v1.18.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/prometheus/client_golang v1.21.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.62.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.5.1 // indirect github.com/quic-go/quic-go v0.54.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.3.0 // indirect - github.com/zeromicro/go-zero v1.9.1 // indirect go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/sdk v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/mock v0.5.0 // indirect golang.org/x/arch v0.20.0 // indirect @@ -43,9 +71,9 @@ require ( golang.org/x/text v0.27.0 // indirect golang.org/x/time v0.13.0 // indirect golang.org/x/tools v0.34.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect google.golang.org/grpc v1.65.0 // indirect google.golang.org/protobuf v1.36.9 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/server/go.sum b/server/go.sum index 9e251c53..4eed1191 100644 --- a/server/go.sum +++ b/server/go.sum @@ -1,12 +1,23 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= +github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g= github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= @@ -16,21 +27,46 @@ github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/go-sql-driver/mysql v1.9.0 h1:Y0zIbQXhQKmQgTp44Y1dp3wTXcn804QoTptLZT1vtvo= +github.com/go-sql-driver/mysql v1.9.0/go.mod h1:pDetrLJeA3oMujJuvXc8RJoasr589B6A9fwzD3QMrqw= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -38,27 +74,48 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= +github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= +github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk= +github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= @@ -67,10 +124,30 @@ github.com/zeromicro/go-zero v1.9.1 h1:GZCl4jun/ZgZHnSvX3SSNDHf+tEGmEQ8x2Z23xjHa github.com/zeromicro/go-zero v1.9.1/go.mod h1:bHOl7Xr7EV/iHZWEqsUNJwFc/9WgAMrPpPagYvOaMtY= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4= +go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0/go.mod h1:iSDOcsnSA5INXzZtwaBPrKp/lWu/V14Dd+llD0oI2EA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 h1:Mw5xcxMwlqoJd97vwPxA8isEaIoxsta9/Q51+TTJLGE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0/go.mod h1:CQNu9bj7o7mC6U7+CA/schKEYakYXWr79ucDHTMGhCM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 h1:Xw8U6u2f8DK2XAkGRFV7BBLENgnTGX9i4rQRxJf+/vs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0/go.mod h1:6KW1Fm6R/s6Z3PGXwSJN2K4eT6wQB3vXX6CVnYX9NmM= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 h1:s0PHtIkN+3xrbDOpt2M8OTG92cWqUESvzh2MxiR5xY8= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0/go.mod h1:hZlFbDbRt++MMPCCfSJfmhkGIWnX1h3XjkfxZUjLrIA= +go.opentelemetry.io/otel/exporters/zipkin v1.24.0 h1:3evrL5poBuh1KF51D9gO/S+N/1msnm4DaBqs/rpXUqY= +go.opentelemetry.io/otel/exporters/zipkin v1.24.0/go.mod h1:0EHgD8R0+8yRhUYJOGR8Hfg2dpiJQxDOszd5smVO9wM= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= +go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= @@ -93,6 +170,8 @@ golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= @@ -100,8 +179,14 @@ google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjr google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= +gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= diff --git a/server/internal/article/internal/handler/article/createarticlehandler.go b/server/internal/article/handler/article/createarticlehandler.go similarity index 53% rename from server/internal/article/internal/handler/article/createarticlehandler.go rename to server/internal/article/handler/article/createarticlehandler.go index 02dee0b9..779623b0 100644 --- a/server/internal/article/internal/handler/article/createarticlehandler.go +++ b/server/internal/article/handler/article/createarticlehandler.go @@ -4,23 +4,40 @@ package article import ( + "fmt" "net/http" + "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/logic/article" - "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc" + "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/model" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types" + "github.com/zeromicro/go-zero/core/stores/sqlx" "github.com/zeromicro/go-zero/rest/httpx" ) -func CreateArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { +func CreateArticleHandler(cfg *config.Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req types.CreateArticleReq if err := httpx.Parse(r, &req); err != nil { httpx.ErrorCtx(r.Context(), w, err) return } + mysqlCfg := cfg.MySQL + dsn := fmt.Sprintf( + "%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=true&loc=Local", + mysqlCfg.Username, + mysqlCfg.Password, + mysqlCfg.Host, + mysqlCfg.Port, + mysqlCfg.Database, + mysqlCfg.Charset, + ) + fmt.Println("接收到articlePost请求") - l := article.NewCreateArticleLogic(r.Context(), svcCtx) + conn := sqlx.NewSqlConn("mysql", dsn) + articleModel := model.NewArticleModel(conn) + + l := article.NewCreateArticleLogic(r.Context(), cfg, articleModel) resp, err := l.CreateArticle(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/server/internal/article/internal/handler/article/deletearticlehandler.go b/server/internal/article/handler/article/deletearticlehandler.go similarity index 76% rename from server/internal/article/internal/handler/article/deletearticlehandler.go rename to server/internal/article/handler/article/deletearticlehandler.go index 35db2136..a2f01a82 100644 --- a/server/internal/article/internal/handler/article/deletearticlehandler.go +++ b/server/internal/article/handler/article/deletearticlehandler.go @@ -6,13 +6,13 @@ package article import ( "net/http" + "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/logic/article" - "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types" "github.com/zeromicro/go-zero/rest/httpx" ) -func DeleteArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { +func DeleteArticleHandler(cfg *config.Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req types.DeleteArticleReq if err := httpx.Parse(r, &req); err != nil { @@ -20,7 +20,7 @@ func DeleteArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - l := article.NewDeleteArticleLogic(r.Context(), svcCtx) + l := article.NewDeleteArticleLogic(r.Context(), cfg) resp, err := l.DeleteArticle(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/server/internal/article/internal/handler/article/detailarticlehandler.go b/server/internal/article/handler/article/detailarticlehandler.go similarity index 76% rename from server/internal/article/internal/handler/article/detailarticlehandler.go rename to server/internal/article/handler/article/detailarticlehandler.go index 2ee3e62d..74007468 100644 --- a/server/internal/article/internal/handler/article/detailarticlehandler.go +++ b/server/internal/article/handler/article/detailarticlehandler.go @@ -6,13 +6,13 @@ package article import ( "net/http" + "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/logic/article" - "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types" "github.com/zeromicro/go-zero/rest/httpx" ) -func DetailArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { +func DetailArticleHandler(cfg *config.Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req types.DetailArticleReq if err := httpx.Parse(r, &req); err != nil { @@ -20,7 +20,7 @@ func DetailArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - l := article.NewDetailArticleLogic(r.Context(), svcCtx) + l := article.NewDetailArticleLogic(r.Context(), cfg) resp, err := l.DetailArticle(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/server/internal/article/internal/handler/article/listarticlehandler.go b/server/internal/article/handler/article/listarticlehandler.go similarity index 53% rename from server/internal/article/internal/handler/article/listarticlehandler.go rename to server/internal/article/handler/article/listarticlehandler.go index f04e7ad6..efc5362d 100644 --- a/server/internal/article/internal/handler/article/listarticlehandler.go +++ b/server/internal/article/handler/article/listarticlehandler.go @@ -4,15 +4,18 @@ package article import ( + "fmt" "net/http" + "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/logic/article" - "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc" + "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/model" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types" + "github.com/zeromicro/go-zero/core/stores/sqlx" "github.com/zeromicro/go-zero/rest/httpx" ) -func ListArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { +func ListArticleHandler(cfg *config.Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req types.ListArticleReq if err := httpx.Parse(r, &req); err != nil { @@ -20,7 +23,22 @@ func ListArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - l := article.NewListArticleLogic(r.Context(), svcCtx) + mysqlCfg := cfg.MySQL + dsn := fmt.Sprintf( + "%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=true&loc=Local", + mysqlCfg.Username, + mysqlCfg.Password, + mysqlCfg.Host, + mysqlCfg.Port, + mysqlCfg.Database, + mysqlCfg.Charset, + ) + fmt.Println("接收到articlePost请求") + + conn := sqlx.NewSqlConn("mysql", dsn) + articleModel := model.NewArticleModel(conn) + + l := article.NewListArticleLogic(r.Context(), cfg, articleModel) resp, err := l.ListArticle(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/server/internal/article/internal/handler/article/updatearticlehandler.go b/server/internal/article/handler/article/updatearticlehandler.go similarity index 76% rename from server/internal/article/internal/handler/article/updatearticlehandler.go rename to server/internal/article/handler/article/updatearticlehandler.go index 8093ee81..05e636c0 100644 --- a/server/internal/article/internal/handler/article/updatearticlehandler.go +++ b/server/internal/article/handler/article/updatearticlehandler.go @@ -6,13 +6,13 @@ package article import ( "net/http" + "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/logic/article" - "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types" "github.com/zeromicro/go-zero/rest/httpx" ) -func UpdateArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { +func UpdateArticleHandler(cfg *config.Config) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req types.UpdateArticleReq if err := httpx.Parse(r, &req); err != nil { @@ -20,7 +20,7 @@ func UpdateArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return } - l := article.NewUpdateArticleLogic(r.Context(), svcCtx) + l := article.NewUpdateArticleLogic(r.Context(), cfg) resp, err := l.UpdateArticle(&req) if err != nil { httpx.ErrorCtx(r.Context(), w, err) diff --git a/server/internal/article/internal/logic/article/createarticlelogic.go b/server/internal/article/internal/logic/article/createarticlelogic.go index 06a788a1..80b61183 100644 --- a/server/internal/article/internal/logic/article/createarticlelogic.go +++ b/server/internal/article/internal/logic/article/createarticlelogic.go @@ -5,8 +5,12 @@ package article import ( "context" + "fmt" + "strings" + "time" - "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc" + "github.com/JACKYMYPERSON/hldrCenter/config" + "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/model" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types" "github.com/zeromicro/go-zero/core/logx" @@ -14,20 +18,98 @@ import ( type CreateArticleLogic struct { logx.Logger - ctx context.Context - svcCtx *svc.ServiceContext + ctx context.Context + cfg *config.Config + model model.ArticleModel } -func NewCreateArticleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateArticleLogic { +func NewCreateArticleLogic(ctx context.Context, cfg *config.Config, model model.ArticleModel) *CreateArticleLogic { return &CreateArticleLogic{ Logger: logx.WithContext(ctx), ctx: ctx, - svcCtx: svcCtx, + cfg: cfg, + model: model, } } func (l *CreateArticleLogic) CreateArticle(req *types.CreateArticleReq) (resp *types.CreateArticleResp, err error) { - // todo: add your logic here and delete this line + ctxLog := logx.WithContext(l.ctx) - return + // 标题不能为空,且长度建议限制(避免过长) + if req.Title == "" { + // 用 Info 替代 Warn,添加 [WARN] 标识 + ctxLog.Info("[WARN] 文章标题不能为空") + return nil, fmt.Errorf("文章标题不能为空") + } + if len(req.Title) > 100 { // 假设标题最大100字符,可根据需求调整 + // 用 Infof 替代 Warnf,添加 [WARN] 标识 + ctxLog.Infof("[WARN] 文章标题过长,当前长度:%d,最大允许:100", len(req.Title)) + return nil, fmt.Errorf("文章标题不能超过100个字符") + } + + // 内容不能为空(核心字段) + if req.Content == "" { + ctxLog.Info("[WARN] 文章内容不能为空") + return nil, fmt.Errorf("文章内容不能为空") + } + + // 可选:封面图、话题字段的基础校验(如封面图URL格式,话题长度) + if req.Cover != "" && !strings.HasPrefix(req.Cover, "http") { + // 直接用 l.Infof(结构体嵌入 logx.Logger,可直接调用) + l.Infof("[WARN] 封面图URL格式非法:%s", req.Cover) + return nil, fmt.Errorf("封面图URL必须以http/https开头") + } + if req.Topic != "" && len(req.Topic) > 50 { + l.Infof("[WARN] 话题过长,当前长度:%d,最大允许:50", len(req.Topic)) + return nil, fmt.Errorf("话题不能超过50个字符") + } + + // 2. 第二步:转换请求参数 → Model层的Article实体(补充缺失字段) + // CreateArticleReq 缺失的字段(Excerpt/IsDelete/CreateAt/UpdateAt/Id)需在Logic层补充 + articleData := &model.Article{ + Title: req.Title, // 直接从请求获取 + Content: req.Content, // 直接从请求获取 + Cover: req.Cover, // 直接从请求获取(为空则存空字符串) + Topic: req.Topic, // 直接从请求获取(为空则存空字符串) + Excerpt: l.getExcerpt(req.Content), // 自动生成摘要(下方实现辅助函数) + IsDelete: 0, // 默认0(未删除,1为已删除,符合数据库设计) + CreateAt: time.Now(), // 创建时间:当前时间(或用数据库默认值,此处显式赋值更可控) + UpdateAt: time.Now(), // 更新时间:初始与创建时间一致 + } + + // 3. 第三步:调用Model层Insert方法,插入数据到数据库 + // 传入上下文(用于超时控制、链路追踪)和Article实体 + insertResult, err := l.model.Insert(l.ctx, articleData) + if err != nil { + // 记录错误日志(包含上下文信息,方便排查) + l.Logger.Errorf("插入文章到数据库失败,标题:%s,错误:%v", req.Title, err) + return nil, fmt.Errorf("创建文章失败,请稍后重试") // 返回用户友好错误,隐藏底层细节 + } + + // 4. 第四步:处理Insert结果,获取自增Id(关键:响应需返回新文章的Id) + // 若数据库Id是自增字段,通过insertResult.LastInsertId()获取新生成的Id + newArticleId, err := insertResult.LastInsertId() + if err != nil { + l.Logger.Errorf("获取新文章Id失败,标题:%s,错误:%v", req.Title, err) + return nil, fmt.Errorf("创建文章成功,但获取文章Id失败") // 特殊场景:插入成功但Id获取失败 + } + + // 5. 第五步:构造响应结果(匹配types.CreateArticleResp结构) + resp = &types.CreateArticleResp{ + Id: newArticleId, // 返回数据库生成的自增Id + Success: true, // 标记创建成功 + // 可选:补充更多响应字段,如"Message": "文章创建成功"(若Resp结构体支持) + } + + l.Logger.Infof("文章创建成功,Id:%d,标题:%s", newArticleId, req.Title) // 记录成功日志 + return resp, nil +} + +func (l *CreateArticleLogic) getExcerpt(content string) string { + // 规则1:内容长度<=200字符,直接返回完整内容作为摘要 + if len(content) <= 30 { + return content + } + // 规则2:内容过长,截取前200字符并加上"..."(避免截断单词,可优化为按句子截断) + return strings.TrimSpace(content[:30]) + "..." } diff --git a/server/internal/article/internal/logic/article/deletearticlelogic.go b/server/internal/article/internal/logic/article/deletearticlelogic.go index 43a2005e..08ee3342 100644 --- a/server/internal/article/internal/logic/article/deletearticlelogic.go +++ b/server/internal/article/internal/logic/article/deletearticlelogic.go @@ -6,7 +6,7 @@ package article import ( "context" - "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc" + "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types" "github.com/zeromicro/go-zero/core/logx" @@ -14,15 +14,15 @@ import ( type DeleteArticleLogic struct { logx.Logger - ctx context.Context - svcCtx *svc.ServiceContext + ctx context.Context + cfg *config.Config } -func NewDeleteArticleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteArticleLogic { +func NewDeleteArticleLogic(ctx context.Context, cfg *config.Config) *DeleteArticleLogic { return &DeleteArticleLogic{ Logger: logx.WithContext(ctx), ctx: ctx, - svcCtx: svcCtx, + cfg: cfg, } } diff --git a/server/internal/article/internal/logic/article/detailarticlelogic.go b/server/internal/article/internal/logic/article/detailarticlelogic.go index e71114e7..fa088007 100644 --- a/server/internal/article/internal/logic/article/detailarticlelogic.go +++ b/server/internal/article/internal/logic/article/detailarticlelogic.go @@ -6,7 +6,7 @@ package article import ( "context" - "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc" + "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types" "github.com/zeromicro/go-zero/core/logx" @@ -14,15 +14,15 @@ import ( type DetailArticleLogic struct { logx.Logger - ctx context.Context - svcCtx *svc.ServiceContext + ctx context.Context + cfg *config.Config } -func NewDetailArticleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DetailArticleLogic { +func NewDetailArticleLogic(ctx context.Context, cfg *config.Config) *DetailArticleLogic { return &DetailArticleLogic{ Logger: logx.WithContext(ctx), ctx: ctx, - svcCtx: svcCtx, + cfg: cfg, } } diff --git a/server/internal/article/internal/logic/article/listarticlelogic.go b/server/internal/article/internal/logic/article/listarticlelogic.go index 4be9c2e9..92ff9510 100644 --- a/server/internal/article/internal/logic/article/listarticlelogic.go +++ b/server/internal/article/internal/logic/article/listarticlelogic.go @@ -5,8 +5,11 @@ package article import ( "context" + "fmt" + "time" - "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc" + "github.com/JACKYMYPERSON/hldrCenter/config" + "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/model" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types" "github.com/zeromicro/go-zero/core/logx" @@ -14,20 +17,87 @@ import ( type ListArticleLogic struct { logx.Logger - ctx context.Context - svcCtx *svc.ServiceContext + ctx context.Context + cfg *config.Config + model model.ArticleModel } -func NewListArticleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListArticleLogic { +func NewListArticleLogic(ctx context.Context, cfg *config.Config, model model.ArticleModel) *ListArticleLogic { return &ListArticleLogic{ Logger: logx.WithContext(ctx), ctx: ctx, - svcCtx: svcCtx, + cfg: cfg, + model: model, } } func (l *ListArticleLogic) ListArticle(req *types.ListArticleReq) (resp *types.ListArticleResp, err error) { - // todo: add your logic here and delete this line + // 1. 处理请求参数默认值 + 合法性校验(原有逻辑保留) + page := req.Page + if page < 1 { + page = 1 + l.Infof("请求页码非法(%d),自动调整为 1", req.Page) + } - return + size := req.Size + switch { + case size < 1: + size = 10 + l.Infof("请求条数非法(%d),自动调整为 10", req.Size) + case size > 100: + size = 100 + l.Infof("请求条数过大(%d),自动限制为 100", req.Size) + } + + topic := req.Topic + + // 2. 修正:按接口定义接收 3 个返回值(列表、总条数、错误) + // 原错误:只接收了 2 个返回值,缺少“总条数” + articleList, total, err := l.model.List(l.ctx, page, size, topic) + if err != nil { + l.Errorf("Model 层查询文章列表失败:topic=%s, page=%d, size=%d, 错误:%v", topic, page, size, err) + return nil, fmt.Errorf("获取文章列表失败,请稍后重试") + } + + // 3. 计算总页数(接口只返回总条数,总页数需在 Logic 层计算) + // 向上取整公式:(总条数 + 每页条数 - 1) / 每页条数(避免浮点数误差) + var totalPage int64 + if total > 0 { + totalPage = (total + int64(size) - 1) / int64(size) + } else { + totalPage = 0 // 总条数为 0 时,总页数也为 0 + } + + // 4. 结构转换:Model.Article → Types.ArticleItem(适配前端) + var articleItems []types.Article + for _, art := range articleList { + // 注意:art 是 *Article 指针,取值时用 *art + articleItems = append(articleItems, types.Article{ + Id: art.Id, + Title: art.Title, + Cover: art.Cover, + Topic: art.Topic, + Excerpt: art.Excerpt, + Content: art.Content, + // 时间格式化:转为本地时间字符串 + CreateAt: art.CreateAt.In(time.Local).Format("2006-01-02 15:04:05"), + UpdateAt: art.UpdateAt.In(time.Local).Format("2006-01-02 15:04:05"), + }) + } + + // 5. 组装前端所需的响应结构 + resp = &types.ListArticleResp{ + Total: total, // 总条数(来自 Model 层返回) + TotalPage: totalPage, // 计算出的总页数 + List: articleItems, // 转换后的前端列表 + Page: page, // 当前页码(处理后的有效值) + Size: size, // 每页条数(处理后的有效值) + } + for i, item := range resp.List { + fmt.Printf("[DEBUG] 响应第 %d 条文章的 Content:%q\n", i+1, item.Content) + } + + l.Infof("文章列表查询成功:topic=%s, page=%d, size=%d, 总条数=%d, 总页数=%d", + topic, page, size, total, totalPage) + return resp, nil } diff --git a/server/internal/article/internal/logic/article/updatearticlelogic.go b/server/internal/article/internal/logic/article/updatearticlelogic.go index 47601a2b..63fca8d9 100644 --- a/server/internal/article/internal/logic/article/updatearticlelogic.go +++ b/server/internal/article/internal/logic/article/updatearticlelogic.go @@ -6,7 +6,7 @@ package article import ( "context" - "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc" + "github.com/JACKYMYPERSON/hldrCenter/config" "github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types" "github.com/zeromicro/go-zero/core/logx" @@ -14,15 +14,15 @@ import ( type UpdateArticleLogic struct { logx.Logger - ctx context.Context - svcCtx *svc.ServiceContext + ctx context.Context + cfg *config.Config } -func NewUpdateArticleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateArticleLogic { +func NewUpdateArticleLogic(ctx context.Context, cfg *config.Config) *UpdateArticleLogic { return &UpdateArticleLogic{ Logger: logx.WithContext(ctx), ctx: ctx, - svcCtx: svcCtx, + cfg: cfg, } } diff --git a/server/internal/article/internal/model/articlemodel.go b/server/internal/article/internal/model/articlemodel.go index c700b687..b0ed4276 100644 --- a/server/internal/article/internal/model/articlemodel.go +++ b/server/internal/article/internal/model/articlemodel.go @@ -13,14 +13,14 @@ type ( } customArticleModel struct { - *defaultArticleModel + *DefaultArticleModel } ) // NewArticleModel returns a model for the database table. func NewArticleModel(conn sqlx.SqlConn) ArticleModel { return &customArticleModel{ - defaultArticleModel: newArticleModel(conn), + DefaultArticleModel: newArticleModel(conn), } } diff --git a/server/internal/article/internal/model/articlemodel_gen.go b/server/internal/article/internal/model/articlemodel_gen.go index 2e9f13e9..0209128a 100644 --- a/server/internal/article/internal/model/articlemodel_gen.go +++ b/server/internal/article/internal/model/articlemodel_gen.go @@ -19,8 +19,22 @@ import ( var ( articleFieldNames = builder.RawFieldNames(&Article{}) articleRows = strings.Join(articleFieldNames, ",") - articleRowsExpectAutoSet = strings.Join(stringx.Remove(articleFieldNames, "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + articleRowsExpectAutoSet = strings.Join(stringx.Remove(articleFieldNames, "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`","`id`"), ",") articleRowsWithPlaceHolder = strings.Join(stringx.Remove(articleFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" + articleListFields = strings.Join( + []string{ + "`id`", // 1. 对应 id + "`title`", // 2. 对应 title + "`content`", // 3. 🔥 新增:查询 content 字段 + "`cover`", // 4. 对应 cover + "`topic`", // 5. 对应 topic + "`excerpt`", // 6. 对应 excerpt + "`create_at`", // 7. 对应 create_at + "`update_at`", // 8. 对应 update_at + "`is_delete`", // 9. 对应 is_delete + }, + ",", +) ) type ( @@ -29,9 +43,10 @@ type ( FindOne(ctx context.Context, id int64) (*Article, error) Update(ctx context.Context, data *Article) error Delete(ctx context.Context, id int64) error + List(ctx context.Context, page, size int, topic string) ([]*Article, int64, error) } - defaultArticleModel struct { + DefaultArticleModel struct { conn sqlx.SqlConn table string } @@ -47,22 +62,35 @@ type ( Excerpt string `db:"excerpt"` Id int64 `db:"id"` } + + articleListItem struct { + Id int64 `db:"id"` // 与 articleListFields 第1个字段对应 + Title string `db:"title"` // 与第2个字段对应 + Content string `db:"content"` // 🔥 新增:与第3个字段(content)对应 + Cover string `db:"cover"` // 与第4个字段对应 + Topic string `db:"topic"` // 与第5个字段对应 + Excerpt string `db:"excerpt"` // 与第6个字段对应 + CreateAt time.Time `db:"create_at"` // 与第7个字段对应 + UpdateAt time.Time `db:"update_at"` // 与第8个字段对应 + IsDelete int64 `db:"is_delete"` // 与第9个字段对应 + } + ) -func newArticleModel(conn sqlx.SqlConn) *defaultArticleModel { - return &defaultArticleModel{ +func newArticleModel(conn sqlx.SqlConn) *DefaultArticleModel { + return &DefaultArticleModel{ conn: conn, table: "`article`", } } -func (m *defaultArticleModel) Delete(ctx context.Context, id int64) error { +func (m *DefaultArticleModel) Delete(ctx context.Context, id int64) error { query := fmt.Sprintf("delete from %s where `id` = ?", m.table) _, err := m.conn.ExecCtx(ctx, query, id) return err } -func (m *defaultArticleModel) FindOne(ctx context.Context, id int64) (*Article, error) { +func (m *DefaultArticleModel) FindOne(ctx context.Context, id int64) (*Article, error) { query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", articleRows, m.table) var resp Article err := m.conn.QueryRowCtx(ctx, &resp, query, id) @@ -76,18 +104,99 @@ func (m *defaultArticleModel) FindOne(ctx context.Context, id int64) (*Article, } } -func (m *defaultArticleModel) Insert(ctx context.Context, data *Article) (sql.Result, error) { - query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?)", m.table, articleRowsExpectAutoSet) - ret, err := m.conn.ExecCtx(ctx, query, data.Title, data.Content, data.Cover, data.IsDelete, data.Topic, data.Excerpt, data.Id) +func (m *DefaultArticleModel) Insert(ctx context.Context, data *Article) (sql.Result, error) { + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?)", m.table, articleRowsExpectAutoSet) + ret, err := m.conn.ExecCtx(ctx, query, data.Title, data.Content, data.Cover, data.IsDelete, data.Topic, data.Excerpt) return ret, err } -func (m *defaultArticleModel) Update(ctx context.Context, data *Article) error { +func (m *DefaultArticleModel) Update(ctx context.Context, data *Article) error { query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, articleRowsWithPlaceHolder) + fmt.Println("Insert SQL 字段列表:", articleRowsExpectAutoSet) _, err := m.conn.ExecCtx(ctx, query, data.Title, data.Content, data.Cover, data.IsDelete, data.Topic, data.Excerpt, data.Id) return err } -func (m *defaultArticleModel) tableName() string { + +func (m *DefaultArticleModel) List(ctx context.Context, page, size int, topic string) ([]*Article, int64, error) { + // 1. 统计符合条件的总条数(只查未删除数据) + var countBuilder strings.Builder + countBuilder.WriteString(fmt.Sprintf("SELECT COUNT(*) FROM %s WHERE `is_delete` = 0", m.table)) + + var args []interface{} + // 动态添加话题筛选条件(topic 非空才加) + if topic != "" { + countBuilder.WriteString(" AND `topic` = ?") + args = append(args, topic) + } + + // 执行总条数查询(go-zero 正确参数顺序:ctx → &total → query → args...) + var total int64 + countSql := countBuilder.String() + err := m.conn.QueryRowCtx(ctx, &total, countSql, args...) + if err != nil { + return nil, 0, fmt.Errorf("统计总条数失败:sql=%s, args=%v, err=%v", countSql, args, err) + } + + // 空数据优化:总条数为 0 时,直接返回空列表(避免后续无效查询) + if total == 0 { + return []*Article{}, 0, nil + } + + // 2. 分页查询列表数据(包含 content 字段) + var listBuilder strings.Builder + // 关键:使用包含 content 的 articleListFields,SQL 会查询 content + listBuilder.WriteString(fmt.Sprintf("SELECT %s FROM %s WHERE `is_delete` = 0", articleListFields, m.table)) + + // 复用话题筛选条件(与总条数查询条件一致,确保数据一致性) + if topic != "" { + listBuilder.WriteString(" AND `topic` = ?") + } + + // 分页计算(页码从 1 开始,OFFSET = (page-1)*size,避免负偏移) + offset := (page - 1) * size + listBuilder.WriteString(" ORDER BY `create_at` DESC LIMIT ? OFFSET ?") + // 追加分页参数(顺序:先 LIMIT size,再 OFFSET offset) + listArgs := append(args, size, offset) + + // 3. 扫描到临时结构体(articleListItem 包含 content,避免直接扫描大字段到 Article) + var tempList []*articleListItem + listSql := listBuilder.String() + // go-zero 正确调用:ctx → &tempList → query → listArgs...(args 需加 ... 展开) + err = m.conn.QueryRowsCtx(ctx, &tempList, listSql, listArgs...) + if err != nil { + return nil, 0, fmt.Errorf("查询列表失败:sql=%s, args=%v, err=%v", listSql, listArgs, err) + } + + // 4. 转换为业务层需要的 Article 切片(关键:赋值 Content 字段) + articleList := make([]*Article, 0, len(tempList)) + for _, item := range tempList { + + fmt.Printf("[DEBUG] 扫描到的文章ID:%d,Content值:%q\n", item.Id, item.Content) + // 打印 SQL 实际查询的字段,确认 content 存在 + fmt.Printf("[DEBUG] SQL 查询字段:%s\n", articleListFields) + articleList = append(articleList, &Article{ + Id: item.Id, // 主键 + Title: item.Title, // 标题 + Content: item.Content, // 🔥 核心:赋值 content(解决为空问题) + Cover: item.Cover, // 封面 + Topic: item.Topic, // 话题 + Excerpt: item.Excerpt, // 摘要 + CreateAt: item.CreateAt, // 创建时间 + UpdateAt: item.UpdateAt, // 更新时间 + IsDelete: item.IsDelete, // 软删除状态 + }) + } + for i, item := range articleList { + fmt.Printf("[DEBUG] 响应第 %d 条文章的 Content:%q\n", i+1, item.Content) + } + + + // 5. 返回结果(Article 切片+总条数+无错误) + return articleList, total, nil +} + + +func (m *DefaultArticleModel) tableName() string { return m.table } diff --git a/server/internal/article/internal/types/types.go b/server/internal/article/internal/types/types.go index c7fb5877..c425c9c5 100644 --- a/server/internal/article/internal/types/types.go +++ b/server/internal/article/internal/types/types.go @@ -51,8 +51,11 @@ type ListArticleReq struct { } type ListArticleResp struct { - Total int64 `json:"total"` // 总条数 - List []Article `json:"list"` // 文章列表 + Total int64 `json:"total"` // 符合条件的总文章数(原字段保留) + TotalPage int64 `json:"total_page"` // 新增:总页数(前端直接显示) + List []Article `json:"Article_list"` // 当前页文章列表(原字段保留) + Page int `json:"page"` // 当前页码(原字段保留) + Size int `json:"size"` // 每页条数(原字段保留) } type UpdateArticleReq struct { diff --git a/server/router/router.go b/server/router/router.go index 3095b123..ab562218 100644 --- a/server/router/router.go +++ b/server/router/router.go @@ -2,6 +2,7 @@ package router import ( "github.com/JACKYMYPERSON/hldrCenter/config" + "github.com/JACKYMYPERSON/hldrCenter/internal/article/handler/article" ping "github.com/JACKYMYPERSON/hldrCenter/internal/ping/handler/ping" uploadimg "github.com/JACKYMYPERSON/hldrCenter/internal/upload/handler/upload" "github.com/JACKYMYPERSON/hldrCenter/middleware" @@ -22,23 +23,23 @@ func SetupRouter(cfg *config.Config) *gin.Engine { api.POST("/upload/cover", uploadimg.UploadImageHandler(cfg)) api.GET("/ping", gin.WrapF(ping.PingHandler())) - //articles := api.Group("/articles") - //{ - // // 1. 创建文章(POST /api/articles) - // articles.POST("", gin.WrapH(article.CreateArticleHandler(svcCtx))) - // - // // 2. 文章列表(GET /api/articles) - // articles.GET("", gin.WrapH(article.ListArticleHandler(svcCtx))) - // - // // 3. 文章详情(GET /api/articles/:id) - // articles.GET("/:id", gin.WrapH(article.DetailArticleHandler(svcCtx))) - // - // // 4. 更新文章(PUT /api/articles/:id) - // articles.PUT("/:id", gin.WrapH(article.UpdateArticleHandler(svcCtx))) - // - // // 5. 删除文章(DELETE /api/articles/:id) - // articles.DELETE("/:id", gin.WrapH(article.DeleteArticleHandler(svcCtx))) - //} + articles := api.Group("/articles") + { + // 1. 创建文章(POST /api/articles) + articles.POST("", gin.WrapH(article.CreateArticleHandler(cfg))) + + // 2. 文章列表(GET /api/articles) + articles.POST("/getarticle", gin.WrapH(article.ListArticleHandler(cfg))) + + // 3. 文章详情(GET /api/articles/:id) + articles.GET("/:id", gin.WrapH(article.DetailArticleHandler(cfg))) + + // 4. 更新文章(PUT /api/articles/:id) + articles.PUT("/:id", gin.WrapH(article.UpdateArticleHandler(cfg))) + + // 5. 删除文章(DELETE /api/articles/:id) + articles.DELETE("/:id", gin.WrapH(article.DeleteArticleHandler(cfg))) + } } return r