zhaogongxue 11 miesięcy temu
rodzic
commit
ca2a177183
51 zmienionych plików z 1414 dodań i 364 usunięć
  1. 0 0
      dist/assets/editor.c0cc37b6.css
  2. 0 0
      dist/assets/follow.9cf9b394.css
  3. 0 1
      dist/assets/index.79ef8e2b.css
  4. 0 0
      dist/assets/index.aaa5ba81.css
  5. 0 1
      dist/assets/more.6a9fb59a.css
  6. 0 1
      dist/assets/topic.006c339c.css
  7. 0 1
      dist/assets/zixun.df0babf5.css
  8. 2 2
      dist/index.html
  9. 344 2
      package-lock.json
  10. 3 0
      package.json
  11. 6 0
      src/api/gather.js
  12. 6 0
      src/api/subscribe.js
  13. 2 2
      src/api/task.js
  14. 14 7
      src/api/user.js
  15. 2 0
      src/components/ActivateMembership/index.vue
  16. 0 1
      src/components/ErrorReport/index.vue
  17. 21 19
      src/components/IndexNews/index.vue
  18. 85 16
      src/components/IndexSection/index.vue
  19. 7 5
      src/components/MomentLayout/index.vue
  20. 8 4
      src/components/TheCharts/Item.vue
  21. 34 31
      src/components/TheCharts/index.vue
  22. 84 17
      src/components/layouts/Header.vue
  23. 16 6
      src/components/layouts/HeaderEditor.vue
  24. 2 1
      src/main.js
  25. 31 1
      src/router/index.js
  26. 3 0
      src/store/user.js
  27. 14 1
      src/useHook/useErrorReport.js
  28. 3 3
      src/useHook/useForum.js
  29. 23 0
      src/utils/constance.js
  30. 1 1
      src/utils/request.js
  31. 12 0
      src/views/articles/index.vue
  32. 29 5
      src/views/forum/index.vue
  33. 3 0
      src/views/forum/topic.vue
  34. 22 5
      src/views/index/components/SigninPrize.vue
  35. 19 1
      src/views/index/content.vue
  36. 1 1
      src/views/more.vue
  37. 0 1
      src/views/personal/address.vue
  38. 1 0
      src/views/personal/components/ExperienceCard.vue
  39. 9 12
      src/views/personal/components/count.vue
  40. 127 7
      src/views/personal/components/sett.vue
  41. 28 53
      src/views/personal/components/wallet.vue
  42. 33 7
      src/views/personal/foot.vue
  43. 8 5
      src/views/personal/index.vue
  44. 20 5
      src/views/personal/make.vue
  45. 130 12
      src/views/postDetail.vue
  46. 2 1
      src/views/reservation/index.vue
  47. 165 109
      src/views/sundry/editor.vue
  48. 69 9
      src/views/tongzhi/components/comment.vue
  49. 13 1
      src/views/video/index.vue
  50. 6 5
      src/views/zixun.vue
  51. 6 2
      src/views/zixun/index.vue

Plik diff jest za duży
+ 0 - 0
dist/assets/editor.c0cc37b6.css


Plik diff jest za duży
+ 0 - 0
dist/assets/follow.9cf9b394.css


+ 0 - 1
dist/assets/index.79ef8e2b.css

@@ -1 +0,0 @@
-.index-news-container[data-v-8f701448]{background-color:#fff;border-radius:6px;overflow:hidden;height:264px}.index-news-container .imgbox[data-v-8f701448]{width:279px;height:155px;background:#eee;border-radius:6px 6px 0 0}.index-news-container .imgbox img[data-v-8f701448]{width:100%;height:155px;object-fit:cover}.index-news-container .content[data-v-8f701448]{padding:16px 10px}.index-news-container .content .title[data-v-8f701448]{width:259px;height:44px;font-size:16px;font-family:PingFangSC,PingFang SC;font-weight:500;color:#333;line-height:22px;margin-bottom:16px}.index-news-container .content .footer[data-v-8f701448]{height:20px;font-size:13px;font-weight:400;color:#777;line-height:15px}.index-news-container .content .footer div[data-v-8f701448]{display:inline-block}

Plik diff jest za duży
+ 0 - 0
dist/assets/index.aaa5ba81.css


+ 0 - 1
dist/assets/more.6a9fb59a.css

@@ -1 +0,0 @@
-.title[data-v-4049cd3d]{font-family:PingFangSC,PingFang SC;font-weight:600;font-size:18px;color:#333;line-height:25px;text-align:left;font-style:normal;margin-bottom:24px}.articles-container .index-title-container[data-v-4049cd3d]{margin-bottom:20px}.articles-container .content-list[data-v-4049cd3d]{margin-bottom:30px;column-gap:20px;flex-wrap:wrap;height:255px;overflow:hidden}.articles-container .article-main[data-v-4049cd3d]{display:grid;grid-template-columns:repeat(4,auto);justify-content:space-between;row-gap:30px}

+ 0 - 1
dist/assets/topic.006c339c.css

@@ -1 +0,0 @@
-.topic-container[data-v-1ec31f26]{column-gap:20px}.topic__header[data-v-1ec31f26]{margin-bottom:20px;background-color:#fff;border-radius:10px}.topic__header .topic-back-btn[data-v-1ec31f26]{font-size:16px;font-weight:400;color:#333;line-height:38px;border-bottom:1px solid #f6f6f6;padding:20px 20px 6px;margin-bottom:18px}.topic__header-main[data-v-1ec31f26]{padding:0 20px 20px}.topic__header .topic-title[data-v-1ec31f26]{font-size:26px;font-weight:600;color:#222}.topic__header .topic-descs[data-v-1ec31f26]{font-size:14px;font-weight:400;color:#777}.topic__left-context[data-v-1ec31f26]{width:0;flex:1}.topic__left-context .context .moment-layout-container[data-v-1ec31f26]{margin-bottom:20px;border-radius:10px}.topic__side[data-v-1ec31f26]{width:400px}.topic__side .see-more[data-v-1ec31f26]{padding:16px 20px;border-radius:10px;background-color:#fff;margin-bottom:20px;font-size:16px;font-weight:500;color:#222}.topic__side .forum-recommend[data-v-1ec31f26]{list-style:none;padding:0 0 13px;margin:0;background-color:#fff;border-radius:10px}.topic__side .forum-recommend dt[data-v-1ec31f26]{font-size:16px;font-weight:500;color:#333;padding:14px 20px 10px;border-bottom:1px solid #f6f6f6}.topic__side .forum-recommend dd[data-v-1ec31f26]{padding:6px 20px;margin:0}

+ 0 - 1
dist/assets/zixun.df0babf5.css

@@ -1 +0,0 @@
-.title[data-v-52734940]{font-family:PingFangSC,PingFang SC;font-weight:600;font-size:18px;color:#333;line-height:25px;text-align:left;font-style:normal;margin-bottom:24px}.articles-container .index-title-container[data-v-52734940]{margin-bottom:20px}.articles-container .content-list[data-v-52734940]{margin-bottom:30px;column-gap:20px;flex-wrap:wrap;height:255px;overflow:hidden}.articles-container .article-main[data-v-52734940]{display:grid;grid-template-columns:repeat(4,auto);justify-content:space-between;row-gap:30px}

+ 2 - 2
dist/index.html

@@ -6,8 +6,8 @@
   <link rel="icon" href="./favicon.ico" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <title>Vite App</title>
-  <script type="module" crossorigin src="./assets/index.4130092b.js"></script>
-  <link rel="stylesheet" href="./assets/index.4e7c1976.css">
+  <script type="module" crossorigin src="./assets/index.fd04c950.js"></script>
+  <link rel="stylesheet" href="./assets/index.05afc744.css">
 </head>
 
 <body>

+ 344 - 2
package-lock.json

@@ -22,7 +22,10 @@
         "normalize.css": "^8.0.1",
         "pinia": "^2.1.7",
         "pinia-plugin-persist": "^1.0.0",
+        "qrcode": "^1.5.3",
+        "qrcodejs2": "^0.0.2",
         "vue": "^3.2.8",
+        "vue-qrcode": "^2.2.2",
         "vue-router": "^4.2.5",
         "vuedraggable": "^4.1.0"
       },
@@ -1210,6 +1213,14 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/camelcase": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/caniuse-lite": {
       "version": "1.0.30001588",
       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz",
@@ -1356,6 +1367,35 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/cliui": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+      "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^6.2.0"
+      }
+    },
+    "node_modules/cliui/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cliui/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/clone": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
@@ -1378,6 +1418,22 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/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=="
+    },
     "node_modules/combined-stream": {
       "version": "1.0.8",
       "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -1618,6 +1674,14 @@
         }
       }
     },
+    "node_modules/decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/decode-uri-component": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
@@ -1647,6 +1711,11 @@
         "node": ">=0.4.0"
       }
     },
+    "node_modules/dijkstrajs": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
+      "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
+    },
     "node_modules/dom-serializer": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
@@ -1796,6 +1865,11 @@
         "url": "https://github.com/sponsors/antfu"
       }
     },
+    "node_modules/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=="
+    },
     "node_modules/emojis-list": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
@@ -1805,6 +1879,11 @@
         "node": ">= 4"
       }
     },
+    "node_modules/encode-utf8": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz",
+      "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
+    },
     "node_modules/enhanced-resolve": {
       "version": "5.15.0",
       "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
@@ -2546,6 +2625,18 @@
         "node": ">=8"
       }
     },
+    "node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/follow-redirects": {
       "version": "1.15.6",
       "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
@@ -2662,6 +2753,14 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "engines": {
+        "node": "6.* || 8.* || >= 10.*"
+      }
+    },
     "node_modules/get-value": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
@@ -3021,6 +3120,14 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/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==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/is-glob": {
       "version": "4.0.3",
       "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
@@ -3294,6 +3401,17 @@
         "url": "https://github.com/sponsors/antfu"
       }
     },
+    "node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/lodash": {
       "version": "4.17.21",
       "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
@@ -3850,6 +3968,39 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/parse-node-version": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
@@ -3868,6 +4019,14 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/path-exists": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/path-parse": {
       "version": "1.0.7",
       "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
@@ -3991,6 +4150,14 @@
         "pathe": "^1.1.0"
       }
     },
+    "node_modules/pngjs": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
+      "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
     "node_modules/posix-character-classes": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@@ -4140,6 +4307,28 @@
         "node": ">=6"
       }
     },
+    "node_modules/qrcode": {
+      "version": "1.5.3",
+      "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.3.tgz",
+      "integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==",
+      "dependencies": {
+        "dijkstrajs": "^1.0.1",
+        "encode-utf8": "^1.0.3",
+        "pngjs": "^5.0.0",
+        "yargs": "^15.3.1"
+      },
+      "bin": {
+        "qrcode": "bin/qrcode"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/qrcodejs2": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/qrcodejs2/-/qrcodejs2-0.0.2.tgz",
+      "integrity": "sha512-+Y4HA+cb6qUzdgvI3KML8GYpMFwB24dFwzMkS/yXq6hwtUGNUnZQdUnksrV1XGMc2mid5ROw5SAuY9XhI3ValA=="
+    },
     "node_modules/qs": {
       "version": "6.5.3",
       "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
@@ -4322,6 +4511,19 @@
         "node": ">= 0.12"
       }
     },
+    "node_modules/require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/require-main-filename": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
+    },
     "node_modules/resolve": {
       "version": "1.22.8",
       "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.8.tgz",
@@ -4550,6 +4752,11 @@
         "randombytes": "^2.1.0"
       }
     },
+    "node_modules/set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
+    },
     "node_modules/set-value": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
@@ -4908,6 +5115,38 @@
         "safe-buffer": "~5.2.0"
       }
     },
+    "node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/string-width/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/string-width/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/strip-ansi": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
@@ -5356,8 +5595,7 @@
     "node_modules/tslib": {
       "version": "2.6.2",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
-      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
-      "dev": true
+      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
     },
     "node_modules/tunnel-agent": {
       "version": "0.6.0",
@@ -5806,6 +6044,21 @@
         }
       }
     },
+    "node_modules/vue-qrcode": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/vue-qrcode/-/vue-qrcode-2.2.2.tgz",
+      "integrity": "sha512-SbrXq/mSb1g2tbDyXPe9gy9KiMYsvxWKRErlpij1BqiFoHwQckheZV63CTw6yRLLUVG2RXAVlX+APkpdCK7SQQ==",
+      "dependencies": {
+        "tslib": "^2.6.2"
+      },
+      "funding": {
+        "url": "https://opencollective.com/rxts"
+      },
+      "peerDependencies": {
+        "qrcode": "^1.0.0",
+        "vue": "^2.7.0 || ^3.0.0"
+      }
+    },
     "node_modules/vue-router": {
       "version": "4.2.5",
       "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.2.5.tgz",
@@ -5929,10 +6182,99 @@
         "node": ">=0.8.0"
       }
     },
+    "node_modules/which-module": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
+      "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
+    },
     "node_modules/wildcard": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-1.1.2.tgz",
       "integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng=="
+    },
+    "node_modules/wrap-ansi": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/y18n": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
+    },
+    "node_modules/yargs": {
+      "version": "15.4.1",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+      "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+      "dependencies": {
+        "cliui": "^6.0.0",
+        "decamelize": "^1.2.0",
+        "find-up": "^4.1.0",
+        "get-caller-file": "^2.0.1",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^4.2.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^18.1.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/yargs-parser": {
+      "version": "18.1.3",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+      "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+      "dependencies": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
     }
   }
 }

+ 3 - 0
package.json

@@ -21,7 +21,10 @@
     "normalize.css": "^8.0.1",
     "pinia": "^2.1.7",
     "pinia-plugin-persist": "^1.0.0",
+    "qrcode": "^1.5.3",
+    "qrcodejs2": "^0.0.2",
     "vue": "^3.2.8",
+    "vue-qrcode": "^2.2.2",
     "vue-router": "^4.2.5",
     "vuedraggable": "^4.1.0"
   },

+ 6 - 0
src/api/gather.js

@@ -31,4 +31,10 @@ export const share = data => (request({
   data,
   method: 'POST',
   url: 'share'
+}))
+// draft
+export const draft = params => (request({
+  params,
+  method: 'GET',
+  url: 'draft'
 }))

+ 6 - 0
src/api/subscribe.js

@@ -9,4 +9,10 @@ export const shoot = data => request({
     method: 'POST',
     url: 'shoot-appointment'
 })
+//
+export const list = params => request({
+    params,
+    method: 'GET',
+    url: 'shoot-appointment'
+})
 

+ 2 - 2
src/api/task.js

@@ -10,8 +10,8 @@ export const list = params => request({
     url: 'task'
 })
 
-export const task = params => request({
-    params,
+export const task = data => request({
+    data,
     method: 'POST',
     url: `task/${data.id}/receive`
 })

+ 14 - 7
src/api/user.js

@@ -49,9 +49,10 @@ export const userfollow = data => request({
   url: `user/${data.id}/follow`
 })
 
-export const finance = () => (request({
+export const finance = params => (request({
   method: 'GET',
-  url: 'finance'
+  url: 'finance',
+  params
 }))
 
 // 奖励
@@ -116,22 +117,28 @@ export const config = () => request({
 })
 
 //设置用户配置
-export const postconfig = params => request({
+export const postconfig = data => request({
   url: 'user/config',
   method: 'POST',
-  params
+  data
 })
 
 //我的足迹
-export const browse = data => request({
+export const browse = params => request({
   url: 'browse',
   method: 'GET',
-  data
+  params
 })
 //勋章列表
-export const badge = data => request({
+export const badge = params => request({
   url: 'badge',
   method: 'GET',
+  params
+})
+//错误反馈
+export const feedback = data => request({
+  url: 'feedback',
+  method: 'POST',
   data
 })
 

+ 2 - 0
src/components/ActivateMembership/index.vue

@@ -55,10 +55,12 @@ const paysuccess = async () => {
       pay_type: "integral",
       platform: "pc",
     });
+    User.getUser()
     ElMessage.success({
       message: "开通成功",
       type: "success",
     });
+
   } catch (error) {}
 };
 

+ 0 - 1
src/components/ErrorReport/index.vue

@@ -4,7 +4,6 @@ import { useErrorReport } from '~/useHook/useErrorReport'
 import { Plus } from '@element-plus/icons-vue'
 import { getSourcesSuffix } from '~/utils/util';
 
-// const visibility = ref(false)
 const Props = defineProps({
   visibility: {
     type: Boolean,

+ 21 - 19
src/components/IndexNews/index.vue

@@ -1,41 +1,40 @@
 <script setup name="IndexNews">
-
 // import {context} from 'vue'
 import * as formatTime from "~/utils/formatTime";
-const handleTimeAgo = formatTime.timeAgo
+const handleTimeAgo = formatTime.timeAgo;
 
-const emit = defineEmits(['todetails'])
+const emit = defineEmits(["todetails"]);
 
-const todetails =()=>{
-  emit('update')
-}
+const todetails = () => {
+  emit("update");
+};
 
 const Props = defineProps({
   image: {
     type: String,
-    default: "https://dummyimage.com/279x155/e3e3e3/fff"
+    default: "https://dummyimage.com/279x155/e3e3e3/fff",
   },
   title: {
-    type: String
+    type: String,
   },
   timeAgo: {
-    type: String
+    type: String,
   },
   likeCount: {
-    type: Number
+    type: Number,
   },
   commentCount: {
-    type: Number
-  }
-
-})
-
+    type: Number,
+  },
+  is_like: String,
+  is_collect: String,
+});
 </script>
 
 <template>
-  <div class="index-news-container" style="cursor: pointer;" @click="todetails">
-    <div class="imgbox">
-      <img :src="image" :alt="title">
+  <div class="index-news-container" style="cursor: pointer" @click="todetails">
+    <div class="imgbox" style="margin-bottom: 10px">
+      <img :src="image" :alt="title" />
     </div>
     <div class="content">
       <div class="title ellipsis-two">
@@ -43,7 +42,9 @@ const Props = defineProps({
       </div>
       <div class="footer flex-row flex-aic flex-jc-sb">
         <span>{{ handleTimeAgo(timeAgo) }}</span>
-        <div><span>{{ likeCount }}喜欢</span>·<span>{{ commentCount }}评论</span></div>
+        <div>
+          <span>{{ likeCount }}喜欢</span>·<span>{{ commentCount }}评论</span>
+        </div>
       </div>
     </div>
   </div>
@@ -56,6 +57,7 @@ const Props = defineProps({
     border-radius: 6px;
     overflow: hidden;
     height: 264px;
+    margin-bottom: 20px;
 
     .imgbox {
       width: 279px;

+ 85 - 16
src/components/IndexSection/index.vue

@@ -1,11 +1,11 @@
 <script setup name="IndexSection">
 // import { type } from "os";
 import SvgIcon from "~/components/SvgIcon/index.vue";
-
+import { useUser } from "~/store/user";
 import * as formatTime from "~/utils/formatTime";
+import * as gatherApi from "~/api/gather";
 
 const handleTimeAgo = formatTime.timeAgo;
-
 const Props = defineProps({
   type: {
     type: String,
@@ -28,21 +28,74 @@ const Props = defineProps({
   like_count: String, //点赞数
   collect_count: String, //收藏数
   share_count: String, //分享数
+  is_like: String,
+  is_collect: String,
+  source_id: String,
+  source_type: String,
 });
-const emit = defineEmits(["todetails"]);
+
+const emit = defineEmits(["link", "todetails"]);
+const link = () => {
+  emit("video");
+  emit("article");
+};
 const todetails = () => {
   emit("update");
 };
+const tolink = (type) => {
+  if (type == 0) {
+    like();
+  } else if (type == 1) {
+    collect();
+  }
+};
+//点赞
+const like = async () => {
+  try {
+    const { msg } = await gatherApi.like({
+      source_type: Props.source_type,
+      source_id: Props.source_id,
+    });
+    link();
+    ElMessage({
+      message: msg,
+      type: "success",
+    });
+    // setTimeout(() => {
+    //   link();
+    // }, 600);
+  } catch (error) {
+    console.log("error", error);
+  }
+};
+//收藏
+const collect = async () => {
+  try {
+    const { msg } = await gatherApi.collect({
+      source_type: Props.source_type,
+      source_id: Props.source_id,
+    });
+    link();
+    ElMessage({
+      message: msg,
+      type: "success",
+    });
+  } catch (error) {}
+};
 
 const shareLink = () => {};
 </script>
 
 <template>
-  <div class="index-section-container" @click="todetails">
-    <div v-if="type === 'common'" class="imgbox">
-      <img :src="image" style="width: 279px; height: 155px;object-fit: cover;" alt=""  />
+  <div class="index-section-container">
+    <div @click="todetails" v-if="type === 'common'" class="imgbox">
+      <img
+        :src="image"
+        style="width: 279px; height: 155px; object-fit: cover"
+        alt=""
+      />
     </div>
-    <div v-else class="article-wrapper">
+    <div @click="todetails" v-else class="article-wrapper">
       <div class="title ellipsis-two">{{ title }}</div>
       <p class="desc">{{ descs }}</p>
     </div>
@@ -69,21 +122,37 @@ const shareLink = () => {};
 
       <div class="footer">
         <ul class="flex-row flex-aic flex-jc-sb">
-          <li class="active">
-            <SvgIcon name="like" :size="16" :rgap="2" color="#00b0b0" />
-            <span>{{ view_count || 0 }}</span>
+          <li
+            @click="tolink(0)"
+            :class="Props.is_like == 1 ? 'active' : 'message'"
+          >
+            <SvgIcon
+              name="like"
+              :size="16"
+              :rgap="2"
+              :color="Props.is_like == 1 ? '#00b0b0' : '#999999'"
+            />
+            <span>{{ Props.like_count || 0 }}</span>
           </li>
-          <li class="active">
-            <SvgIcon name="collect" :size="16" :rgap="2" color="#00b0b0" />
-            <span>{{ comment_count || 0 }}</span>
+          <li
+            @click="tolink(1)"
+            :class="Props.is_collect == 1 ? 'active' : 'message'"
+          >
+            <SvgIcon
+              name="collect"
+              :size="16"
+              :rgap="2"
+              :color="is_collect == 1 ? '#00b0b0' : '#999999'"
+            />
+            <span>{{ Props.collect_count || 0 }}</span>
           </li>
-          <li>
+          <li @click="todetails">
             <SvgIcon name="message" :size="16" :rgap="2" color="#999999" />
-            <span>{{ collect_count || 0 }}</span>
+            <span>{{ Props.comment_count || 0 }}</span>
           </li>
           <li>
             <SvgIcon name="forward" :size="16" :rgap="2" color="#999999" />
-            <span>{{ share_count || 0 }}</span>
+            <span>{{ Props.share_count || 0 }}</span>
           </li>
         </ul>
       </div>

+ 7 - 5
src/components/MomentLayout/index.vue

@@ -50,7 +50,6 @@ const handleOperate = debounce(async function (type) {
     if (type === "message") {
       return;
     }
-
     const fObjs = {
       like: __operate_link__,
       collect: __operate_collect__,
@@ -74,6 +73,9 @@ const handleOperate = debounce(async function (type) {
 const others = (id) => {
   Emits("other", id);
 };
+const todetail = (id) => {
+  Emits("detail", id);
+};
 </script>
 
 <template>
@@ -127,7 +129,7 @@ const others = (id) => {
     </div>
 
     <!-- main -->
-    <div class="main">
+    <div class="main" @click="todetail">
       <!-- 
         放置多种内容
         文章内容
@@ -177,7 +179,7 @@ const others = (id) => {
           <SvgIcon
             name="like"
             :size="20"
-            :color="getSvgCol(Props.detail.is_like)"
+            :color="Props.detail.is_like == 1 ? '#00b0b0' : '#999999'"
           />
           {{ Props.detail.like_count }}
         </span>
@@ -185,12 +187,12 @@ const others = (id) => {
           <SvgIcon
             name="collect"
             :size="20"
-            :color="getSvgCol(Props.detail.is_collect)"
+            :color="Props.detail.is_collect == 1 ? '#00b0b0' : '#999999'"
           />
           {{ Props.detail.collect_count }}
         </span>
       </div>
-      <div class="r">
+      <div class="r"  @click="todetail">
         <span class="btn message" @click="handleOperate('message')">
           <SvgIcon
             name="message"

+ 8 - 4
src/components/TheCharts/Item.vue

@@ -26,7 +26,7 @@ const __score_comp__ = () => {
   return h("img", {
     class: ["score-top"],
     src: getPicUrl(
-      `../../assets/cicons/score-${Props.idx}.png`,
+      `./cicons/score-${Props.idx}.png`,
       import.meta.url
     ),
   });
@@ -58,13 +58,13 @@ const rendeTop = computed(() => {
       return __score_comp__();
     case "essence":
       return __common_comp__({
-        pic: "../../assets/cicons/essence.png",
+        pic: "./cicons/essence.png",
         className: "essence",
         title: "优质作者",
       });
     case "like":
       return __common_comp__({
-        pic: "../../assets/cicons/like.png",
+        pic: "./cicons/like.png",
         className: "like",
         title: "点赞大师",
       });
@@ -75,7 +75,7 @@ const rendeTop = computed(() => {
   <div class="the-charts-item-container flex-row flex-aic flex-jc-sb">
     <div class="main flex-row flex-aic">
       <!-- TODO: Default Avatar https://dummyimage.com/38x38/e3e3e3/fff -->
-      <img :src="avatar" :alt="nickname" class="avatar" />
+      <img :src="avatar" alt="" class="avatar" />
       <div class="info">
         <div class="nickname">{{ nickname }}</div>
         <div class="signature">{{ signature }}</div>
@@ -130,6 +130,10 @@ const rendeTop = computed(() => {
         font-weight: 400;
         color: #999999;
         line-height: 17px;
+        white-space: nowrap; /* 确保文本在一行内显示 */
+        overflow: hidden; /* 隐藏溢出容器的文本 */
+        text-overflow: ellipsis; /* 使用省略号表示溢出的文本 */
+        margin-top: 5px;
       }
     }
   }

+ 34 - 31
src/components/TheCharts/index.vue

@@ -1,50 +1,49 @@
 <script setup name="TheCharts">
 import { computed } from "vue";
-import TheChartItem from "./Item.vue"
+import TheChartItem from "./Item.vue";
 
 const Props = defineProps({
   headerTitle: {
     type: String,
-    default: ''
+    default: "",
   },
   list: {
     type: Array,
-    default: () => ([])
+    default: () => [],
   },
   type: {
     type: String,
-    validator: key => (['score', 'essence', 'like'].includes(key)),
-    required: true
+    validator: (key) => ["score", "essence", "like"].includes(key),
+    required: true,
   },
   isShowMore: {
     type: Boolean,
-    default: false
-  }
-})
+    default: false,
+  },
+});
 
-const Emits = defineEmits(['more'])
+const Emits = defineEmits(["more"]);
 
 // 计算属性的枚举函数
-const enumMapTxt = computed(() => count => {
-  let tempStr = ''
+const enumMapTxt = computed(() => (count) => {
+  let tempStr = "";
   switch (Props.type) {
-    case 'score':
-      tempStr = `累计获得${count}积分`
-      break
-    case 'essence':
-      tempStr = `点赞总数${count}次`
-      break
-    case 'like':
-      tempStr = `精品贴总数${count}篇`
-      break
+    case "score":
+      tempStr = `累计获得${count}积分`;
+      break;
+    case "essence":
+      tempStr = `点赞总数${count}次`;
+      break;
+    case "like":
+      tempStr = `精品贴总数${count}篇`;
+      break;
   }
-  return tempStr
-})
+  return tempStr;
+});
 
 const handleSeeMore = () => {
-  Emits('more')
-}
-
+  Emits("more");
+};
 </script>
 
 <template>
@@ -54,8 +53,13 @@ const handleSeeMore = () => {
     </header>
     <div class="main">
       <template v-for="(item, idx) in list" :key="idx">
-        <TheChartItem :idx="++idx" :type="type" :nickname="item.username"
-          :signature="item.num ? enumMapTxt(item.num) : item.introduction" :avatar="item.avatar" />
+        <TheChartItem
+          :idx="++idx"
+          :type="type"
+          :nickname="item.username"
+          :signature="item.num ? enumMapTxt(item.num) : item.introduction"
+          :avatar="item.avatar"
+        />
       </template>
     </div>
     <div v-show="isShowMore" class="footer" @click="handleSeeMore">
@@ -67,6 +71,7 @@ const handleSeeMore = () => {
 <style lang="scss" scoped>
 @import "~/styles/variable.scss";
 
+
 .the-charts-container {
   width: 100%;
   background-color: #fff;
@@ -77,7 +82,7 @@ const handleSeeMore = () => {
     height: 40px;
     line-height: 40px;
     font-size: 16px;
-    border-bottom: 1px solid #F5F5F5;
+    border-bottom: 1px solid #f5f5f5;
 
     span {
       position: relative;
@@ -92,8 +97,6 @@ const handleSeeMore = () => {
         height: 2px;
         transform: translateX(-50%);
         background-color: $color-primary;
-
-
       }
     }
   }
@@ -107,7 +110,7 @@ const handleSeeMore = () => {
       width: 50%;
       padding: 16px 0;
       text-align: center;
-      background-color: #F7F7F7;
+      background-color: #f7f7f7;
       border-radius: 6px;
       font-size: 14px;
       font-weight: 400;

+ 84 - 17
src/components/layouts/Header.vue

@@ -29,6 +29,7 @@ const collect = (idx) => {
   }
 };
 
+const dialogVisible = ref();
 //关注弹出层
 const attentio = () => {
   dialogVisible.value = true;
@@ -39,6 +40,10 @@ const atten = async (id) => {
     const { data } = await userApi.userfollow({
       id: id,
     });
+    ElMessage({
+      message: "操作成功",
+      type: "success",
+    });
     if (inde.value == 0) {
       __article__();
     } else {
@@ -91,11 +96,11 @@ const tosuccess = (type) => {
 };
 
 // 弹出层
-const dialogVisible = ref(false);
+const dialogs = ref(false);
 //退出
 const clearLocalStorage = () => {
   localStorage.clear();
-  dialogVisible.value = false;
+  dialogs.value = false;
   router.go(0);
 };
 //跳转到个人信息
@@ -169,29 +174,27 @@ const momentList = ref([
   {
     label: "论坛",
     icon: getPicUrl("./cicons/send-01.png", import.meta.url),
-    type: "", // 类型跳转发布时的type
+    type: "forum", // 类型跳转发布时的type
   },
   {
     label: "文章",
     icon: getPicUrl("./cicons/send-02.png", import.meta.url),
-
-    type: "", // 类型跳转发布时的type
+    type: "article", // 类型跳转发布时的type
   },
   {
     label: "资讯",
     icon: getPicUrl("./cicons/send-03.png", import.meta.url),
-
-    type: "", // 类型跳转发布时的type
+    type: "info", // 类型跳转发布时的type
   },
   {
     label: "视频",
     icon: getPicUrl("./cicons/send-04.png", import.meta.url),
-    type: "", // 类型跳转发布时的type
+    type: "video", // 类型跳转发布时的type
   },
   {
     label: "草稿箱",
     icon: getPicUrl("./cicons/send-05.png", import.meta.url),
-    type: "", // 类型跳转发布时的type
+    type: "drafts", // 类型跳转发布时的type
   },
 ]);
 const RankTitleEnum = {
@@ -252,11 +255,19 @@ const userRankList = () => {
 onMounted(userRankList);
 
 const handleClickMoment = (moment) => {
-  console.log(
-    "%c click moment item >>>",
-    "background: blue; color: #fff",
-    moment
-  );
+  if (moment.type == "forum") {
+    router.push({
+      path: "/forum",
+    });
+  } else if (moment.type == "drafts") {
+    router.push({
+      path: "/draft",
+    });
+  } else {
+    router.push({
+      path: "/editor",
+    });
+  }
 };
 const pai = ref(false);
 //兑换
@@ -464,7 +475,7 @@ const attention = (idx) => {
                   </div>
                 </div>
                 <img
-                  @click="dialogVisible = true"
+                  @click="dialogs = true"
                   src="../../assets/vip/clear.png"
                   style="width: 20px; height: 20px; cursor: pointer"
                   alt=""
@@ -639,11 +650,11 @@ const attention = (idx) => {
 
   <Login v-model="visibilityLoginDialog" />
   <!-- 退出意向 -->
-  <el-dialog title="提示" v-model="dialogVisible" width="416px">
+  <el-dialog title="提示" v-model="dialogs" width="416px">
     <div>确定要退出忆象吗?</div>
     <template #footer>
       <span class="dialog-footer">
-        <el-button @click="dialogVisible = false">取 消</el-button>
+        <el-button @click="dialogs = false">取 消</el-button>
         <el-button type="primary" @click="clearLocalStorage">确 定</el-button>
       </span>
     </template>
@@ -737,6 +748,62 @@ const attention = (idx) => {
 
 <style lang="scss" scoped>
 @import "~/styles/variable.scss";
+.atten {
+  width: 92px;
+  height: 38px;
+  background: #c7cbcc;
+  border-radius: 4px;
+  font-family: PingFangSC, PingFang SC;
+  font-weight: 400;
+  font-size: 14px;
+  color: #ffffff;
+  line-height: 38px;
+  text-align: center;
+  font-style: normal;
+  cursor: pointer;
+}
+.attentio {
+  background: #00b0b0;
+  border-radius: 4px;
+  width: 92px;
+  height: 38px;
+  font-family: PingFangSC, PingFang SC;
+  font-weight: 400;
+  font-size: 14px;
+  color: #ffffff;
+  line-height: 38px;
+  text-align: center;
+  font-style: normal;
+  cursor: pointer;
+}
+.name {
+  font-family: PingFangSC, PingFang SC;
+  font-weight: 500;
+  font-size: 14px;
+  color: #333333;
+  line-height: 20px;
+  text-align: justify;
+  font-style: normal;
+}
+.info {
+  font-family: PingFangSC, PingFang SC;
+  font-weight: 400;
+  font-size: 10px;
+  color: #777777;
+  line-height: 14px;
+  text-align: justify;
+  font-style: normal;
+  margin-top: 4px;
+  width: 280px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.boxa {
+  display: flex;
+  justify-content: space-between;
+  margin-top: 32px;
+}
 .sortlist-container {
   column-gap: 26px;
 }

+ 16 - 6
src/components/layouts/HeaderEditor.vue

@@ -18,6 +18,13 @@ const options = ref([
 
 const value = ref("article"); // default article
 
+//跳转到个人中心
+const toinfo = ()=>{
+  Router.push({
+    path:'personal'
+  })
+}
+
 watch(
   () => value.value,
   (val) => {
@@ -58,14 +65,17 @@ watch(
       </el-select>
     </div>
     <div class="header__right flex-row flex-aic">
+      <div class="" @click="toinfo">
+        <img class="userinfo-avatar" :src="User.avatar" alt="" />
+      </div>
       <!-- NOTE: User Avatar container -->
-      <el-popover placement="bottom-start" :width="276" trigger="click">
+      <!-- <el-popover placement="bottom-start" :width="276" trigger="click">
         <template #reference>
           <div class="userinfo-avatar">
-            <img :src="User.avatar" :alt="User.name" />
+            <img class="userinfo-avatar" :src="User.avatar" alt="" />
           </div>
-        </template>
-        <div class="userinfo-container uc">
+        </template> -->
+      <!-- <div class="userinfo-container uc">
           <div class="uc__avatar">
             <img :src="User.avatar" :alt="User.name" />
           </div>
@@ -131,8 +141,8 @@ watch(
               <div class="label">兑换记录</div>
             </div>
           </div>
-        </div>
-      </el-popover>
+        </div> -->
+      <!-- </el-popover> -->
     </div>
   </div>
   <ActivateMembership />

+ 2 - 1
src/main.js

@@ -8,6 +8,7 @@ import Router from '~/router/index'
 import { createPinia } from 'pinia'
 import piniaPluginPersist from 'pinia-plugin-persist'
 import App from './App.vue'
+import VueQrcode from 'vue-qrcode'
 
 // NOTE: register svg-icons
 import 'virtual:svg-icons-register'
@@ -15,7 +16,7 @@ import 'virtual:svg-icons-register'
 const pinia = createPinia()
 pinia.use(piniaPluginPersist)
 const app = createApp(App)
-
+app.component('vue-qrcode', VueQrcode)
 app.use(Router)
 app.use(pinia)
 

+ 31 - 1
src/router/index.js

@@ -117,6 +117,20 @@ const routes = [
       }
     ]
   },
+  {
+    path: '/post',
+    meta: {
+      title: '论坛'
+    },
+    component: Layout,
+    children: [
+      {
+        path: '',
+        name: 'post',
+        component: () => import('~/views/postDetail.vue')
+      }
+    ]
+  },
   // forum 论坛
   {
     path: '/forum',
@@ -297,6 +311,11 @@ const routes = [
         path: '/urlManagement',//地址管理
         name: 'urlManagement',
         component: () => import('~/views/personal/address.vue')
+      },
+      {
+        path: '/draft',//草稿箱
+        name: 'draft',
+        component: () => import('~/views/personal/draft.vue')
       }
     ]
   },
@@ -338,7 +357,18 @@ const routes = [
         component: () => import('~/views/sundry/editor.vue')
       }
     ]
-  }
+  },
+  //富文本
+  {
+    path: '/text',
+    children: [
+      {
+        path: '',
+        name: 'text',
+        component: () => import('~/views/text.vue')
+      }
+    ]
+  },
 ]
 
 const router = createRouter({

+ 3 - 0
src/store/user.js

@@ -32,6 +32,9 @@ export const useUser = defineStore('user', {
     shoot_badge: '',
     backgroud_image: '',
     already_upgrade_rate: 0,
+    follow_count: 0, //关注数量
+    collect_count: 0, //收藏数量
+    view_count: 0, //浏览数
   }),
 
   getters: {},

+ 14 - 1
src/useHook/useErrorReport.js

@@ -1,5 +1,6 @@
 
 import { reactive, ref } from 'vue'
+import * as userApi from '~/api/user'
 
 export const useErrorReport = () => {
   const formRef = ref(null)
@@ -21,9 +22,21 @@ export const useErrorReport = () => {
       if (!valid) {
         return ElMessage.error('请查看填写情况')
       }
-      console.log('%c confirm error report >>>', 'background: blue; color: #fff', Form);
+      __feedback__()
     })
   }
+  const __feedback__ = async () => {
+    try {
+      const { data } = await userApi.feedback({
+        ...Form
+      });
+      ElMessage({
+        message: '反馈成功',
+        type: 'success',
+      })
+      Props.visibility = false
+    } catch (error) {}
+  };
   return {
     formRef,
     Form,

+ 3 - 3
src/useHook/useForum.js

@@ -37,13 +37,13 @@ export function useForumIndex() {
     if (FORUM_ITEM_TYPE.includes(type)) {
       forumType.value = type
       handleLoadForumData({
-        page:1,
+        page: 1,
         order: FORUM_ITEM_TYPE_ENUM[forumType.value]
       })
     }
   }
 
-  async function fetchTableData (formdata) {
+  async function fetchTableData(formdata) {
     try {
       const { data = [] } = await forumApi.list(formdata)
       const { total = 0, page = 1, limit = 10, last_page, list = [] } = data
@@ -55,7 +55,7 @@ export function useForumIndex() {
       params.total - total
 
     } catch (error) {
-      
+
     }
   }
 

+ 23 - 0
src/utils/constance.js

@@ -119,3 +119,26 @@ export const USER_INFO = [
     value: "xiaoxi"
   },
 ]
+
+export const DRAFT = [
+  {
+    label: "全部",
+    value: ""
+  },
+  {
+    label: "文章",
+    value: "article"
+  },
+  {
+    label: "资讯",
+    value: "info"
+  },
+  {
+    label: "视频",
+    value: "video"
+  },
+  {
+    label: "帖子",
+    value: "post"
+  },
+]

+ 1 - 1
src/utils/request.js

@@ -51,7 +51,7 @@ service.interceptors.response.use(
    */
   response => {
     const res = response.data
-
+    console.log(res);
     // if the custom code is not 20000, it is judged as an error.
     if (res.code !== 10000) {
       // place relogin 20001

+ 12 - 0
src/views/articles/index.vue

@@ -73,6 +73,7 @@ const todetails = (id) => {
     <div class="content-list content-list--c2 flex-row">
       <template v-for="(item, idx) in articleList" :key="idx">
         <IndexSection
+          @article="__articles__()"
           @update="todetails(item.id)"
           :type="!item.image ? 'article' : 'common'"
           :title="item.title"
@@ -84,8 +85,13 @@ const todetails = (id) => {
           :view_count="item.view_count"
           :comment_count="item.comment_count"
           :collect_count="item.collect_count"
+          :like_count="item.like_count"
           :share_count="item.share_count"
           :image="item.image"
+          :is_like="item.is_like"
+          :is_collect="item.is_collect"
+          :source_id="item.id"
+          source_type="article"
         />
       </template>
     </div>
@@ -94,6 +100,7 @@ const todetails = (id) => {
     <div class="article-main">
       <template v-for="(item, idx) in articleListj" :key="idx">
         <IndexSection
+          @article="__articles__()"
           @update="todetails(item.id)"
           :type="!item.image ? 'article' : 'common'"
           :title="item.title"
@@ -103,10 +110,15 @@ const todetails = (id) => {
           :author="item.user?.username"
           :author-avatar="item.user?.avatar"
           :view_count="item.view_count"
+          :like_count="item.like_count"
           :comment_count="item.comment_count"
           :collect_count="item.collect_count"
           :share_count="item.share_count"
           :image="item.image"
+          :is_like="item.is_like"
+          :is_collect="item.is_collect"
+          :source_id="item.id"
+          source_type="article"
         />
       </template>
     </div>

+ 29 - 5
src/views/forum/index.vue

@@ -19,6 +19,15 @@ const handleGetScrollEnd = () => {
   // TODO: 假设最后一页。 直接 return
   // TODO: 缺少滚动分页
 };
+//跳转到详情
+const todetail = (id) => {
+  router.push({
+    path: "/post",
+    query: {
+      id: id,
+    },
+  });
+};
 
 useScrollEvent({
   callback: handleGetScrollEnd,
@@ -38,7 +47,7 @@ const {
 console.log("%c forumty >>>", "background: blue; color: #fff", forumType.value);
 
 const handleRefreshListData = () => {
-  // TODO: 刷新列表数据
+  useForumIndex();
 };
 
 // 话题推荐
@@ -56,16 +65,31 @@ const __news__ = async () => {
 onMounted(__news__);
 
 //我的话题
+const show = ref(true);
 let aboutMeList = ref([]);
-
+const totala = ref(0);
 const __mylist__ = async () => {
   try {
     const { data } = await topic.aboutMe({
       is_page: 0,
     });
+    aboutMeList.value = data.slice(0, 6);
+    totala.value = data.length;
+  } catch (error) {}
+};
+onMounted(__mylist__);
+//查看更多
+const tomore = async () => {
+  try {
+    const { data } = await topic.aboutMe({
+      is_page: 0,
+    });
     aboutMeList.value = data;
+    totala.value = data.length;
+    show.value = false;
   } catch (error) {}
 };
+
 let type = ref("myself");
 //用户信息
 let userInfo = ref([{}]);
@@ -149,7 +173,7 @@ onMounted(() => {
             type="forum"
             :detail="item"
             @refresh="handleRefreshListData"
-            @click="todetail(item.id)"
+            @detail="todetail(item.id)"
           />
         </template>
       </div>
@@ -194,8 +218,8 @@ onMounted(() => {
         >
           {{ item.title }}
         </dd>
-        <dd class="more">
-          <span style="cursor: pointer" v-if="aboutMeList.length > 0"
+        <dd class="more" @click="tomore()">
+          <span style="cursor: pointer" v-if="totala.length > 5 && show == true"
             >查看更多话题</span
           >
         </dd>

+ 3 - 0
src/views/forum/topic.vue

@@ -48,6 +48,9 @@ onMounted(__news__);
 const jointopic = () => {
   router.push({
     path: "/forum/edit",
+    query:{
+      id:route.query.id
+    }
   });
 };
 

+ 22 - 5
src/views/index/components/SigninPrize.vue

@@ -1,29 +1,44 @@
 <script setup>
 import { ref, onMounted } from "vue";
 import * as qianApi from "~/api/qiandao";
-import more from "~/views/more.vue";
 
 const prize = ref([]);
 const total = ref(0);
+const show = ref(false);
 const __prizeList__ = async () => {
   try {
     const { data } = await qianApi.prize({
       is_page: 0,
     });
-    prize.value = data;
-    total.value = prize.value.length;
+    prize.value = data.slice(0, 5);
+    total.value = data.length;
+    if (total.value > 5) {
+      show.value = true;
+    }
   } catch (error) {}
 };
 
 onMounted(__prizeList__);
+const address_id = ref(0);
 
 //领取
 const get = async (id) => {
   try {
     const { data } = await qianApi.receive({
       id: id,
-      address_id: "",
+      address_id: address_id.value,
+    });
+    // __prizeList__()
+  } catch (error) {}
+};
+const more = async () => {
+  try {
+    const { data } = await qianApi.prize({
+      is_page: 0,
     });
+    prize.value = data;
+    total.value = data.length;
+    show.value = false;
   } catch (error) {}
 };
 </script>
@@ -32,7 +47,9 @@ const get = async (id) => {
   <div class="signin-prize-container">
     <div class="heade flex-row flex-aic flex-jc-sb">
       <div class="title">签到领福利</div>
-      <div class="more" @click="more" v-if="total > 3">更多</div>
+      <div class="more" style="cursor: pointer" @click="more" v-if="show">
+        更多
+      </div>
     </div>
     <div class="main">
       <div

+ 19 - 1
src/views/index/content.vue

@@ -213,6 +213,8 @@ const topicinfo = (id) => {
           :like-count="item.like_count || '0'"
           :comment-count="item.comment_count || '0'"
           :image="item.image"
+          :is_like="item.is_like"
+          :is_collect="item.is_collect"
         />
       </template>
     </div>
@@ -220,6 +222,7 @@ const topicinfo = (id) => {
     <div class="content-list content-list--c2 flex-row">
       <template v-for="(item, idx) in articleList" :key="idx">
         <IndexSection
+          @article="__articles__()"
           @update="todetail(item.id)"
           :type="!item.image ? 'article' : 'common'"
           :title="item.title"
@@ -232,7 +235,12 @@ const topicinfo = (id) => {
           :comment_count="item.comment_count || 0"
           :collect_count="item.collect_count || 0"
           :share_count="item.share_count || 0"
+          :like_count="item.like_count"
           :image="item.image"
+          :is_like="item.is_like"
+          :is_collect="item.is_collect"
+          :source_id="item.id"
+          source_type="article"
         />
       </template>
     </div>
@@ -240,6 +248,7 @@ const topicinfo = (id) => {
     <div class="content-list content-list--c2 flex-row">
       <template v-for="(item, idx) in videoList" :key="idx">
         <IndexSection
+          @video="__videos__()"
           @update="detail(item.id, 'common')"
           :type="!item.image ? 'article' : 'common'"
           :title="item?.title"
@@ -248,7 +257,16 @@ const topicinfo = (id) => {
           :topic-name="item.topic?.title"
           :author="item.user?.username"
           :author-avatar="item.user?.avatar"
+          :view_count="item.view_count || 0"
+          :comment_count="item.comment_count || 0"
+          :collect_count="item.collect_count || 0"
+          :share_count="item.share_count || 0"
           :image="item.image"
+          :is_like="item.is_like"
+          :is_collect="item.is_collect"
+          :source_id="item.id"
+          source_type="video"
+          :like_count="item.like_count"
         />
       </template>
     </div>
@@ -322,7 +340,7 @@ const topicinfo = (id) => {
 
     .content-list {
       margin-bottom: 30px;
-      column-gap: 20px;
+      column-gap: 18px;
       flex-wrap: wrap;
       height: 255px;
       overflow: hidden;

+ 1 - 1
src/views/more.vue

@@ -152,7 +152,7 @@ const todetails = (id, type) => {
 
   .content-list {
     margin-bottom: 30px;
-    column-gap: 20px;
+    column-gap: 18px;
     flex-wrap: wrap;
     height: 255px;
     overflow: hidden;

+ 0 - 1
src/views/personal/address.vue

@@ -1,5 +1,4 @@
 <template>
-  <!-- 视频管理-->
   <div class="personal-container" style="display: flex">
     <!-- main -->
     <div

+ 1 - 0
src/views/personal/components/ExperienceCard.vue

@@ -4,6 +4,7 @@ import Level from "~/components/Level/index.vue";
 import { ref, onMounted } from "vue";
 import * as taskApi from "~/api/task";
 import { useRouter } from "vue-router";
+import ActivateMembership from "~/components/ActivateMembership/index.vue";
 const router = useRouter();
 // import { useOpenMember, useRenewMember } from "~/useHook/useMember";
 const User = useUser();

+ 9 - 12
src/views/personal/components/count.vue

@@ -29,36 +29,33 @@
       <div class="box flex-row flex-jc-sb" style="align-items: center">
         <div class="flex-row">
           <div class="font" v-if="item.is_use == 0 && item.is_expire == 0">
-            <div v-if="item.coupon.amount">
+            <div v-if="item.coupon.type == 'shoot'">预约拍摄优惠券</div>
+            <div v-if="item.coupon.type == 'lease'">设备租赁优惠券</div>
+            <div v-else-if="item.coupon.amount">
               <span>¥</span>
               <span>{{ item.coupon.amount }}</span>
               <div style="margin-top: 16px">
                 满{{ item.coupon.threshold }}可用
               </div>
             </div>
-
-            <div v-else>
-              <div v-if="item.coupon.type == 'shoot'">预约拍摄优惠券</div>
-              <div v-if="item.coupon.type == 'lease'">设备租赁优惠券</div>
-            </div>
           </div>
           <div class="font1" v-else>
-            <div v-if="item.coupon.amount">
+            <div v-if="item.coupon.type == 'shoot'">预约拍摄优惠券</div>
+            <div v-else-if="item.coupon.type == 'lease'">设备租赁优惠券</div>
+            <div v-else-if="item.coupon.amount">
               <span>¥</span>
               <span>{{ item.coupon.amount }}</span>
               <div style="margin-top: 16px">
                 满{{ item.coupon.threshold }}可用
               </div>
             </div>
-            <div v-else>
-              <div v-if="item.coupon.type == 'shoot'">预约拍摄优惠券</div>
-              <div v-if="item.coupon.type == 'lease'">设备租赁优惠券</div>
-            </div>
           </div>
           <div style="margin-left: 16px">
             <div>
               <div class="title">{{ item.coupon.name }}</div>
-              <div class="use" style="width: 300px;">{{ item.coupon.description }}</div>
+              <div class="use" style="width: 300px">
+                {{ item.coupon.description }}
+              </div>
             </div>
             <div class="date">到期时间:{{ item.expired_at }}</div>
           </div>

+ 127 - 7
src/views/personal/components/sett.vue

@@ -71,6 +71,8 @@
             v-model="introduction"
             style="width: 422px; height: 160px"
             placeholder="请介绍一下自己吧"
+            type="textarea"
+            :rows="8"
           />
         </div>
       </div>
@@ -112,19 +114,69 @@
               我的邀请
             </div>
           </div>
-          <div class="myfriend">邀请好友</div>
+          <div class="myfriend" @click="invite" style="cursor: pointer">
+            邀请好友
+          </div>
         </div>
-        <div style="margin-top: 40px">
+        <!-- " style="margin-top: 40px"> -->
+        <!-- <div v-if="inviteList.length > 0"> -->
+        <div
+          v-for="(item, idx) in inviteList"
+          :key="idx"
+          style="margin-top: 40px"
+        >
           <img
-            src=""
+            :src="item.avatar"
             alt=""
             style="width: 36px; height: 36px; border-radius: 50%"
           />
           <span style="margin-left: 14px" class="bei">邀请人备份</span>
           <span style="margin-left: 40px" class="time">2023-02-12</span>
         </div>
+        <!-- </div>
+        <div v-else>
+          <div></div>
+        </div> -->
       </div>
-      <div></div>
+      <el-dialog width="380" style="border-radius: 8px" v-model="inviteshow">
+        <div
+          class="back"
+          style="width: 380px; height: 520px; position: relative"
+        >
+          <div class="invitetop">好友邀请函</div>
+          <div
+            style="
+              display: flex;
+              flex-direction: column;
+              align-items: center;
+              justify-content: center;
+              margin-top: 33px;
+            "
+          >
+            <div class="min">我的邀请码</div>
+            <div class="code">{{ User.invite_code }}</div>
+          </div>
+          <div
+            style="
+              position: absolute;
+              top: 190px;
+              left: 105px;
+              width: 170px;
+              height: 170px;
+              display: flex;
+              flex-direction: column;
+              align-items: center;
+              justify-content: center;
+            "
+          >
+            <vue-qrcode :value="qrCodeValue" :size="qrCodeSize"></vue-qrcode>
+          </div>
+          <div style="position: absolute; top: 374px; left: 107px">
+            <div class="saoma">扫码响应好友的邀请</div>
+            <div class="btnlink">复制邀请链接</div>
+          </div>
+        </div>
+      </el-dialog>
     </div>
     <!-- 设置 -->
     <div v-if="subNavCurrent == 'zhang'">
@@ -195,7 +247,7 @@
               v-model="who_can_like"
               label="follower"
               style="margin-left: 90px"
-              >我关注的</el-radio
+              >我关注的</el-radio
             >
           </div>
           <div>
@@ -219,7 +271,7 @@
               v-model="who_can_collect"
               label="follower"
               style="margin-left: 90px"
-              >我关注的</el-radio
+              >我关注的</el-radio
             >
           </div>
           <div>
@@ -243,7 +295,7 @@
               v-model="who_can_comment"
               label="follower"
               style="margin-left: 90px"
-              >我关注的</el-radio
+              >我关注的</el-radio
             >
           </div>
           <div>
@@ -370,6 +422,17 @@ import { useUser } from "~/store/user";
 import { useRoute } from "vue-router";
 import { checkPhone } from "~/utils/util";
 import { COUNT_DOWN_MAX } from "~/utils/constance";
+//邀请
+const qrCodeValue = ref();
+qrCodeValue.value = "https://example.com";
+const qrCodeSize = ref();
+qrCodeSize.value = 170;
+const inviteshow = ref(false);
+//邀请弹框
+const invite = () => {
+  inviteshow.value = true;
+};
+
 //获取验证码
 // 获取短信二维码
 let msgCodeTxt = ref("获取短信验证码");
@@ -580,6 +643,59 @@ const handleSwitchSubNav = debounce((type) => {
       
 <style lang="scss" scoped>
 @import "~/styles/variable.scss";
+::v-deep .el-dialog__header {
+  padding: 0 !important;
+}
+::v-deep .el-dialog__body {
+  padding: 0 !important;
+}
+.saoma {
+  font-family: PingFangSC, PingFang SC;
+  font-weight: 400;
+  font-size: 14px;
+  color: #999999;
+  line-height: 20px;
+  text-align: left;
+  font-style: normal;
+}
+.btnlink {
+  width: 166px;
+  height: 44px;
+  background: #00b0b0;
+  border-radius: 4px;
+  font-family: PingFangSC, PingFang SC;
+  font-weight: 400;
+  font-size: 16px;
+  color: #ffffff;
+  line-height: 44px;
+  text-align: center;
+  font-style: normal;
+  margin-top: 22px;
+}
+.code {
+  font-family: JDZhengHT, JDZhengHT;
+  font-weight: 400;
+  font-size: 26px;
+  color: #00b0b0;
+  line-height: 31px;
+  text-align: left;
+  font-style: normal;
+  margin-top: 12px;
+}
+.invitetop {
+  font-family: PingFangSC, PingFang SC;
+  font-weight: 500;
+  font-size: 20px;
+  color: #ffffff;
+  line-height: 28px;
+  text-align: center;
+  font-style: normal;
+  padding-top: 19px;
+}
+.back {
+  background: url(../../../assets/bj.png) no-repeat;
+  background-size: 380px 520px;
+}
 //消息推送
 .zhi {
   font-family: PingFangSC, PingFang SC;
@@ -926,5 +1042,9 @@ ul {
   background: #f5f5f5 !important;
   border-radius: 4px !important;
 }
+::v-deep .el-textarea__inner {
+  background: #f5f5f5 !important;
+  border-radius: 4px !important;
+}
 </style>
       

+ 28 - 53
src/views/personal/components/wallet.vue

@@ -61,62 +61,18 @@
             </div>
           </div>
         </div>
-        <div class="complete" v-if="item.status == 'finished'">已完成</div>
+        <div class="complete" v-if="item.status == 'received'">已完成</div>
+        <div
+          class="success"
+          v-else-if="item.status == 'finished'"
+          @click="toget(item.id)"
+        >
+          领取奖励
+        </div>
         <div class="success" v-else @click="tosucc(item.source_type)">
           去完成
         </div>
       </div>
-      <!-- <div class="box">
-        <div style="display: flex">
-          <img src="../../../assets/wallet/icon-02.png" alt="" />
-          <div class="left">
-            <div class="title1">发帖</div>
-            <div>
-              <img
-                src="../../../assets/wallet/header-02.png"
-                style="width: 14px; height: 14px"
-                alt=""
-              />
-              <span class="cal">积分+2</span>
-            </div>
-          </div>
-        </div>
-        <div class="success" @click="tosucc(1)">去完成</div>
-      </div>
-      <div class="box">
-        <div style="display: flex">
-          <img src="../../../assets/wallet/icon-03.png" alt="" />
-          <div class="left">
-            <div class="title1">开通会员</div>
-            <div>
-              <img
-                src="../../../assets/wallet/header-02.png"
-                style="width: 14px; height: 14px"
-                alt=""
-              />
-              <span class="cal">积分+2</span>
-            </div>
-          </div>
-        </div>
-        <div class="success" @click="tosucc(2)">去完成</div>
-      </div>
-      <div class="box">
-        <div style="display: flex">
-          <img src="../../../assets/wallet/icon-04.png" alt="" />
-          <div class="left">
-            <div class="title1">邀请好友</div>
-            <div>
-              <img
-                src="../../../assets/wallet/header-02.png"
-                style="width: 14px; height: 14px"
-                alt=""
-              />
-              <span class="cal">积分+2</span>
-            </div>
-          </div>
-        </div>
-        <div class="success" @click="tosucc(3)">去完成</div>
-      </div> -->
     </div>
   </div>
   <div class="discount" v-else>
@@ -143,6 +99,7 @@
   <el-dialog v-model="dialogVisible" title="积分说明" width="500">
     <div v-html="articleContent"></div>
   </el-dialog>
+  <ActivateMembership :visiblePay="pan" />
 </template>
     
 <script setup>
@@ -155,6 +112,7 @@ import { useUser } from "~/store/user";
 import * as taskApi from "~/api/task";
 import { useRouter } from "vue-router";
 import { getAgreementDetail } from "~/api/common";
+import ActivateMembership from "~/components/ActivateMembership/index.vue";
 const User = useUser();
 const router = useRouter();
 const dialogVisible = ref(false);
@@ -178,6 +136,7 @@ const __detail__ = async () => {
   } catch (error) {}
 };
 onMounted(__detail__);
+const pan = ref(false);
 //去完成
 const tosucc = (type) => {
   if (type == "like") {
@@ -213,6 +172,22 @@ const tosucc = (type) => {
       path: "/setting",
     });
   }
+  if (type == "vip") {
+    pan.value = true;
+  }
+};
+// 领取积分
+const toget = async (id) => {
+  try {
+    const { data } = await taskApi.task({
+      id: id,
+    });
+    ElMessage({
+      message: "领取成功",
+      type: "success",
+    });
+    __task__();
+  } catch (error) {}
 };
 //任务列表
 let taskList = ref([]);
@@ -234,7 +209,7 @@ const __topic__ = async () => {
     const { data } = await userApi.finance({
       is_page: 0,
     });
-    tableData.value = data.list;
+    tableData.value = data;
   } catch (error) {}
 };
 onMounted(__topic__);

+ 33 - 7
src/views/personal/foot.vue

@@ -1,5 +1,4 @@
 <template>
-  <!-- 视频管理-->
   <div class="personal-container" style="display: flex">
     <!-- main -->
     <div style="width: 840px" class="back">
@@ -18,12 +17,18 @@
           >
             <div>
               <img
-                :src="child.source.image"
-                style="width: 230px; height: 132px"
+                v-if="child.source.image || child.source.images[0]"
+                :src="child.source.image || child.source.images[0]"
+                style="width: 230px; height: 132px; object-fit: cover"
                 alt=""
               />
+              <div v-else style="width: 230px; height: 132px"></div>
               <div style="margin-top: 12px; width: 230px">
-                {{ child.source.name || child.source.title }}
+                {{
+                  child.source.name ||
+                  child.source.title ||
+                  child.source.content
+                }}
               </div>
             </div>
           </div>
@@ -79,7 +84,15 @@ const todetail = (id, type) => {
     });
   } else if (type == "post") {
     router.push({
-      path: "/topic",
+      name: "post",
+      query: {
+        id: id,
+        type: type,
+      },
+    });
+  } else if (type == "video") {
+    router.push({
+      name: "videos",
       query: {
         id: id,
         type: type,
@@ -89,16 +102,29 @@ const todetail = (id, type) => {
 };
 
 //我的足迹列表
+const total = ref();
 let commList = ref([]);
 const __detail__ = async () => {
   try {
     const { data } = await userApi.browse({
-      is_page: 0,
+      is_page: 1,
+      limit: total.value,
+    });
+    commList.value = data.list;
+  } catch (error) {}
+};
+const __details__ = async () => {
+  try {
+    const { data } = await userApi.browse({
+      is_page: 1,
+      limit: 10,
     });
+    total.value = data.total;
     commList.value = data.list;
+    __detail__();
   } catch (error) {}
 };
-onMounted(__detail__);
+onMounted(__details__);
 </script>
            
 <style lang="scss" scoped>

+ 8 - 5
src/views/personal/index.vue

@@ -6,7 +6,7 @@ import Routers from "./components/Routers.vue";
 import MomentLayout from "~/components/MomentLayout/index.vue";
 import Level from "~/components/Level/index.vue";
 import { useUser } from "~/store/user";
-import { onMounted, reactive, ref, watch, watchEffect, } from "vue";
+import { onMounted, reactive, ref, watch, watchEffect } from "vue";
 import {
   PERSONAL_SUB_NAV_LIST,
   PERSONAL_SECOND_SUB_NAV_LIST,
@@ -17,7 +17,7 @@ import debounce from "loadsh/debounce";
 import * as follow from "~/api/user";
 import { collect } from "~/api/gather";
 import { useRoute } from "vue-router";
-const route = useRoute()
+const route = useRoute();
 //弹出层
 const dialogVisible = ref(false);
 const User = useUser();
@@ -54,6 +54,10 @@ const atten = async (id) => {
     const { data } = await follow.userfollow({
       id: id,
     });
+    ElMessage({
+      message: "操作成功",
+      type: "success",
+    });
     if (inde.value == 0) {
       __articles__();
     } else {
@@ -305,9 +309,8 @@ const handleRefreshListData = () => {
           </template>
         </template>
         <!-- 收藏 -->
-        <!-- collectbox -->
+        <div v-else></div>
       </div>
-
       <div class="pm-side">
         <ExperienceCard />
         <div class="gap"></div>
@@ -449,7 +452,7 @@ const handleRefreshListData = () => {
   text-align: justify;
   font-style: normal;
   margin-top: 4px;
-  width: 558px;
+  width: 280px;
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;

+ 20 - 5
src/views/personal/make.vue

@@ -26,25 +26,28 @@
         </div>
         <div v-if="type == 1">
           <div
+            v-for="(item, idx) in box"
+            :key="idx"
             class="box"
             style="
               display: flex;
               justify-content: space-between;
               align-items: center;
+              margin-bottom:20px;
             "
           >
             <div>
               <div>
                 <span class="success">提交成功</span>
                 <span style="margin-left: 10px" class="date"
-                  >2023-10-30 10:00:00</span
+                  >{{ item.updated_at }}</span
                 >
               </div>
               <div style="margin-top: 21px" class="topbto">
                 恭喜!你已成功的提交了预约申请
               </div>
             </div>
-            <div class="add" @click="getConfiguser">添加客服</div>
+            <div class="add" style="cursor: pointer;" @click="getConfiguser">添加客服</div>
           </div>
         </div>
       </div>
@@ -221,11 +224,12 @@ if (route.query.type) {
   activeName.value = "second";
   type.value = 1;
 }
-const imageshow = ref(false)
+const imageshow = ref(false);
 
 //添加客服接口
 const customer_service_qrcode = ref();
 const getConfiguser = async () => {
+  visibilityDialog2.value = false
   try {
     const { data } = await commonApi.getConfiguser({
       module: "basic",
@@ -234,7 +238,16 @@ const getConfiguser = async () => {
   } catch (error) {}
   imageshow.value = true;
 };
-
+const box = ref([]);
+const getbox = async () => {
+  try {
+    const { data } = await shootApi.list({
+      is_page: 0,
+    });
+    box.value = data;
+  } catch (error) {}
+};
+onMounted(getbox);
 
 //预约切换
 const make = (idx) => {
@@ -248,6 +261,7 @@ const handleClick = (tab) => {
     type.value = 0;
   } else if (tab.index == 1) {
     type.value = 1;
+    getbox()
   }
 };
 
@@ -265,6 +279,7 @@ const change = (val) => {
 const visibilityDialog2 = ref(false);
 //预约拍摄
 const submit = async () => {
+  visibilityDialog.value = false
   try {
     const { data } = await shootApi.shoot({
       ...form,
@@ -425,7 +440,7 @@ onMounted(() => {});
 }
 .top {
   width: 842px;
-  height: 194px;
+  // height: 194px;
   background: #ffffff;
   padding: 26px 24px;
   box-sizing: border-box;

+ 130 - 12
src/views/postDetail.vue

@@ -16,6 +16,7 @@ import * as videos from "~/api/video";
 import * as detail from "~/api/jifen";
 import * as commentApi from "~/api/comment";
 import * as gatherApi from "~/api/gather";
+import * as forumApi from "~/api/forum";
 
 const Route = useRoute();
 let postType = ref(); // [articles, news, videos]
@@ -43,6 +44,7 @@ const shareLink = async () => {
   try {
     await navigator.clipboard.writeText(url.value);
     alert("链接已复制到剪贴板");
+    __share__();
   } catch (err) {
     alert("复制链接失败");
   }
@@ -65,6 +67,10 @@ const details = reactive({
   user: {
     avatar: "",
   },
+  is_like: "",
+  is_collect: "",
+  is_comment: "",
+  is_follow: "",
 });
 //资讯
 const __postDetail__ = async () => {
@@ -86,6 +92,10 @@ const __postDetail__ = async () => {
       collect_count: data.collect_count, //收藏数量
       share_count: data.share_count,
       user: data.user,
+      is_like: data.is_like,
+      is_collect: data.is_collect,
+      is_comment: data.is_comment,
+      is_follow: data.is_follow,
     });
   } catch (error) {}
 };
@@ -109,6 +119,10 @@ const __articlesDetail__ = async () => {
       collect_count: data.collect_count, //收藏数量
       share_count: data.share_count,
       user: data.user,
+      is_like: data.is_like,
+      is_collect: data.is_collect,
+      is_comment: data.is_comment,
+      is_follow: data.is_follow,
     });
   } catch (error) {}
 };
@@ -133,11 +147,44 @@ const __videoDetail__ = async () => {
       share_count: data.share_count,
       user: data.user,
       video_url: data.video_url,
+      is_like: data.is_like,
+      is_collect: data.is_collect,
+      is_comment: data.is_comment,
+      is_follow: data.is_follow,
+    });
+  } catch (error) {}
+};
+//论坛
+const __posDetail__ = async () => {
+  console.log(Route.name);
+  try {
+    const { data } = await forumApi.info({
+      id: Route.query.id,
+    });
+    Object.assign(details, {
+      title: data.title,
+      image: data.image, //封面图
+      description: data.description,
+      content: data.content, //内容
+      status: data.status, //状态: frozen.冻结, normal.正常
+      is_boutique: data.is_boutique, //是否精品: 0.否, 1.是
+      view_count: data.view_count, //浏览数
+      comment_count: data.comment_count, //评论数量
+      like_count: data.like_count, //点赞数量
+      collect_count: data.collect_count, //收藏数量
+      share_count: data.share_count,
+      user: data.user,
+      video_url: data.video_url,
+      is_like: data.is_like,
+      is_collect: data.is_collect,
+      is_comment: data.is_comment,
+      is_follow: data.is_follow,
     });
   } catch (error) {}
 };
 const detaildType = ref();
 let type = ref("");
+type.value = Route.query.type;
 if (Route.name == "news") {
   onMounted(__postDetail__);
   detaildType.value = "info";
@@ -147,31 +194,92 @@ if (Route.name == "news") {
 } else if (Route.name == "videos") {
   detaildType.value = "video";
   onMounted(__videoDetail__);
-  type.value = Route.query.type;
+} else if (Route.name == "post") {
+  detaildType.value = "post";
+  onMounted(__posDetail__);
 }
+
 //分享
 const source_type = ref();
-const share = () => {
+const share = (type) => {
   if (Route.name == "news") {
     source_type.value = "info";
   } else if (Route.name == "articles") {
     source_type.value = "article";
-  } else if (Route.name == "video") {
+  } else if (Route.name == "videos") {
     source_type.value = "video";
-  } else {
+  } else if (Route.name == "post") {
     source_type.value = "post";
   }
-  __share__();
+  if (type == 0) {
+    like();
+  } else if (type == 1) {
+    collect();
+  } else {
+    dialogVisible.value = true;
+  }
 };
 
 //分享接口
 const __share__ = async () => {
   try {
-    const { data } = await commentApi.list({
+    const { data } = await gatherApi.share({
       source_type: source_type.value,
       source_id: Route.query.id,
     });
-    dialogVisible.value = true;
+    if (Route.name == "news") {
+      __postDetail__();
+    } else if (Route.name == "articles") {
+      __articlesDetail__();
+    } else if (Route.name == "videos") {
+      __videoDetail__();
+    } else if (Route.name == "post") {
+      __posDetail__();
+    }
+  } catch (error) {}
+};
+//点赞
+const like = async () => {
+  try {
+    const { msg } = await gatherApi.like({
+      source_type: source_type.value,
+      source_id: Route.query.id,
+    });
+    if (Route.name == "news") {
+      __postDetail__();
+    } else if (Route.name == "articles") {
+      __articlesDetail__();
+    } else if (Route.name == "videos") {
+      __videoDetail__();
+    } else if (Route.name == "post") {
+      __posDetail__();
+    }
+    ElMessage({
+      message: msg,
+      type: "success",
+    });
+  } catch (error) {}
+};
+//收藏
+const collect = async () => {
+  try {
+    const { msg } = await gatherApi.collect({
+      source_type: source_type.value,
+      source_id: Route.query.id,
+    });
+    if (Route.name == "news") {
+      __postDetail__();
+    } else if (Route.name == "articles") {
+      __articlesDetail__();
+    } else if (Route.name == "videos") {
+      __videoDetail__();
+    } else if (Route.name == "post") {
+      __posDetail__();
+    }
+    ElMessage({
+      message: msg,
+      type: "success",
+    });
   } catch (error) {}
 };
 
@@ -239,17 +347,27 @@ console.log("%c route >>>", "background: blue; color: #fff", Route, Route.name);
     <div class="post-context" v-html="details.content"></div>
     <div class="post-footer flex-row flex-aic flex-jc-sb">
       <div class="left">
-        <span class="link" style="cursor: pointer">
-          <SvgIcon name="like" :size="22" :rgap="2" color="#00b0b0" />
+        <span @click="share(0)" :style="{color:details.is_like == 1 ? '#00b0b0' : '#999999'}" class="link" style="cursor: pointer">
+          <SvgIcon
+            name="like"
+            :size="22"
+            :rgap="2"
+            :color="details.is_like == 1 ? '#00b0b0' : '#999999'"
+          />
           {{ details.like_count || 0 }}
         </span>
-        <span class="collect" style="cursor: pointer">
-          <SvgIcon name="collect" :size="22" :rgap="2" color="#00b0b0" />
+        <span :style="{color:details.is_collect == 1 ? '#00b0b0' : '#999999'}" @click="share(1)" class="collect" style="cursor: pointer">
+          <SvgIcon
+            name="collect"
+            :size="22"
+            :rgap="2"
+            :color="details.is_collect == 1 ? '#00b0b0' : '#999999'"
+          />
           {{ details.collect_count || 0 }}
         </span>
       </div>
       <div class="right" style="cursor: pointer">
-        <span class="forword" @click="share">
+        <span class="forword" @click="share(2)">
           <SvgIcon name="forward" :size="22" :rgap="2" color="#999999" />
           {{ details.share_count || 0 }}
         </span>

+ 2 - 1
src/views/reservation/index.vue

@@ -19,6 +19,7 @@
             class="box"
             style="
               display: flex;
+              margin-bottom: 20px;
               justify-content: space-between;
               align-items: center;
             "
@@ -415,7 +416,7 @@ onMounted(() => {});
 }
 .top {
   width: 842px;
-  height: 194px;
+  // height: 194px;
   background: #ffffff;
   padding: 26px 24px;
   box-sizing: border-box;

+ 165 - 109
src/views/sundry/editor.vue

@@ -2,38 +2,47 @@
 /**
  * 文章/咨询/视频 发布模块
  */
-import '@wangeditor/editor/dist/css/style.css' // 引入 css
-import { onBeforeUnmount, ref, shallowRef, watch, onMounted, nextTick } from 'vue'
-import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
-import ChooseSubjectToTalk from '~/components/ChooseSubjectToTalk/index.vue'
-import { getSourcesSuffix } from '~/utils/util'
-import { Plus } from '@element-plus/icons-vue'
+import "@wangeditor/editor/dist/css/style.css"; // 引入 css
+import {
+  onBeforeUnmount,
+  ref,
+  shallowRef,
+  watch,
+  onMounted,
+  nextTick,
+} from "vue";
+import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
+import ChooseSubjectToTalk from "~/components/ChooseSubjectToTalk/index.vue";
+import { getSourcesSuffix } from "~/utils/util";
+import { Plus } from "@element-plus/icons-vue";
 import { useUploadImage } from "~/useHook/useUploadImage";
 import { useCommonStore } from "~/store/index";
 import { usePost } from "~/useHook/usePost";
-import { genFileId } from 'element-plus'
+import { genFileId } from "element-plus";
+import { useRouter } from "vue-router";
 
-const commonStore = useCommonStore()
+const commonStore = useCommonStore();
+const router = useRouter();
 
 // 编辑器实例,必须用 shallowRef
-const editorRef = shallowRef()
+const editorRef = shallowRef();
 // 内容 HTML
-const valueHtml = ref('<p></p>')
+const valueHtml = ref("<p></p>");
 
 const toolbarConfig = {
   toolbarKeys: [
-    'undo',
-    'redo',
-    '|',
-    'bold',
-    'italic',
-    '|',
-    'justifyLeft',
-    'justifyCenter',
-    '|',
-    'divider',
+    "undo",
+    "redo",
+    "|",
+    "bold",
+    "italic",
+    "|",
+    "justifyLeft",
+    "justifyCenter",
+    "|",
+    "divider",
     // 'insertImage',
-    'uploadImage'
+    "uploadImage",
   ],
   MENU_CONF: {
     uploadImage: {
@@ -43,113 +52,122 @@ const toolbarConfig = {
       // 最多可上传几个文件,默认为 100
       maxNumberOfFiles: 10,
       // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
-      allowedFileTypes: ['image/*'],
+      allowedFileTypes: ["image/*"],
       // 自定义增加 http  header
       headers: {
-        "Content-Type": "multipart/form-data"
+        "Content-Type": "multipart/form-data",
       },
       timeout: 5 * 1000, // 5 秒
 
       // 单个文件上传成功之后
-      onSuccess(file, res) {          // JS 语法
-        console.log(`${file.name} 上传成功`, res)
+      onSuccess(file, res) {
+        // JS 语法
+        console.log(`${file.name} 上传成功`, res);
       },
 
       // 自定义插入图片
-      customInsert(res, insertFn) {                  // JS 语法
+      customInsert(res, insertFn) {
+        // JS 语法
         // res 即服务端的返回结果
 
-        console.log('%c custom insert >>>', 'background: blue; color: #fff', res);
-
+        console.log(
+          "%c custom insert >>>",
+          "background: blue; color: #fff",
+          res
+        );
 
         // 从 res 中找到 url alt href ,然后插入图片
-        insertFn(url, alt, href)
+        insertFn(url, alt, href);
       },
-
-    }
-  }
-}
-const editorConfig = { placeholder: '请输入正文' }
+    },
+  },
+};
+const editorConfig = { placeholder: "请输入正文" };
 
 // 组件销毁时,也及时销毁编辑器
 onBeforeUnmount(() => {
-  const editor = editorRef.value
-  if (editor == null) return
-  editor.destroy()
-})
+  const editor = editorRef.value;
+  if (editor == null) return;
+  editor.destroy();
+});
 
 const handleCreated = (editor) => {
-  editorRef.value = editor // 记录 editor 实例,重要!
+  editorRef.value = editor; // 记录 editor 实例,重要!
 
-  console.log('%c ??? >>>', 'background: blue; color: #fff', editor.getConfig().MENU_CONF);
+  console.log(
+    "%c ??? >>>",
+    "background: blue; color: #fff",
+    editor.getConfig().MENU_CONF
+  );
 
   // const toolbar = DomEditor.getToolbar(editor)
   // console.log('%c ----- >>>', 'background: blue; color: #fff', toolbar);
-}
+};
 
-const mode = 'default'
+const mode = "default";
 
 watch(valueHtml, () => {
-  const valueText = editorRef.value.getText()
-  wordLen.value = valueText.length
-})
+  const valueText = editorRef.value.getText();
+  wordLen.value = valueText.length;
+});
 
-const type = ref('')
-const title = ref('')
+const type = ref("");
+const title = ref("");
 // valueHtml
-const imageCover = ref('')
-const wordLen = ref(0) // 写字数量
-
-
-const handlePictureCardPreview = () => { }
+const imageCover = ref("");
+const wordLen = ref(0); // 写字数量
 
-const handleRemove = () => { }
+const handlePictureCardPreview = () => {};
 
-const uploadRef = ref()
+const handleRemove = () => {};
 
+const uploadRef = ref();
 
 // NOTE: 图片超出限制替换
 const handleExceedImage = (files) => {
-  uploadRef.value.clearFiles()
-  uploadRef.value.handleStart(files[0])
-  uploadRef.value.submit()
-}
-
-const handleCustomUploadImage = async options => {
-  console.log('%c --- handle custom upload image >>>', 'background: blue; color: #fff', options);
+  uploadRef.value.clearFiles();
+  uploadRef.value.handleStart(files[0]);
+  uploadRef.value.submit();
+};
+
+const handleCustomUploadImage = async (options) => {
+  console.log(
+    "%c --- handle custom upload image >>>",
+    "background: blue; color: #fff",
+    options
+  );
   try {
+    const { file } = options;
 
-    const { file } = options
+    const formdata = new FormData();
 
-    const formdata = new FormData()
+    formdata.append("image", file);
 
-    formdata.append('image', file)
-
-    const { imageFile } = await useUploadImage(formdata)
-    if (imageFile.value) imageCover.value = imageFile.value
-    options.onSuccess()
+    const { imageFile } = await useUploadImage(formdata);
+    if (imageFile.value) imageCover.value = imageFile.value;
+    options.onSuccess();
   } catch (error) {
-    options.onError()
-    console.log('%c ??? >>>', 'background: blue; color: #fff', error);
-    ElMessage.error('上传封面图出错')
+    options.onError();
+    console.log("%c ??? >>>", "background: blue; color: #fff", error);
+    ElMessage.error("上传封面图出错");
   }
-}
+};
 
-const videoTitle = ref('')
-const videoUrl = ref('')
+const videoTitle = ref("");
+const videoUrl = ref("");
 // 发布
-const handleRecordMoment = status => {
+const handleRecordMoment = (status) => {
   // status: draft.草稿, normal.发布
 
-  let str = status === 'draft' ? '存草稿' : '发布'
+  let str = status === "draft" ? "存草稿" : "发布";
 
   ElMessageBox.confirm(`确认要${str}吗`).then(async () => {
     let formdata = {
       title: title.value,
       content: valueHtml.value,
-      topic_id: currentTopic.value ? currentTopic.value.id : '0', // default 0 or ''
+      topic_id: currentTopic.value ? currentTopic.value.id : "0", // default 0 or ''
       status: status,
-      image: imageCover.value
+      image: imageCover.value,
 
       // article mode
       // title
@@ -162,36 +180,48 @@ const handleRecordMoment = status => {
 
       // video_title
       // video_url
-    }
+    };
 
-    if (commonStore.editorType === 'video') {
-      formdata.video_title = videoTitle.value
-      formdata.video_url = videoUrl.value
+    if (commonStore.editorType === "video") {
+      formdata.video_title = videoTitle.value;
+      formdata.video_url = videoUrl.value;
     }
 
     try {
-      const result = await usePost(commonStore.editorType, formdata)
-      ElMessage.success(`${str}成功`)
+      const result = await usePost(commonStore.editorType, formdata);
+      ElMessage.success(`${str}成功`);
+      if (commonStore.editorType == "video") {
+        router.push({
+          path: "video",
+        });
+      } else if (commonStore.editorType == "article") {
+        router.push({
+          path: "articles",
+        });
+      }
     } catch (error) {
-      ElMessage.error(`${str}失败`)
+      ElMessage.error(`${str}失败`);
     }
-  })
-}
+  });
+};
 
 // 接收话题
-const currentTopic = ref(null)
-const handleReciveTopic = topic => {
-  console.log('%c current topic >>>', 'background: blue; color: #fff', topic);
-  currentTopic.value = topic
-}
-
+const currentTopic = ref(null);
+const handleReciveTopic = (topic) => {
+  console.log("%c current topic >>>", "background: blue; color: #fff", topic);
+  currentTopic.value = topic;
+};
 </script>
 
 <template>
   <div class="editor-container">
     <div class="editor-header p800">
       <div class="mainbox">
-        <Toolbar :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
+        <Toolbar
+          :editor="editorRef"
+          :defaultConfig="toolbarConfig"
+          :mode="mode"
+        />
       </div>
     </div>
 
@@ -202,29 +232,55 @@ const handleReciveTopic = topic => {
         <div class="editor-main__border editor-main__border--video"></div>
         <el-form label-position="left" class="video-custom">
           <el-form-item label="请添加关联视频标题">
-            <el-input v-model="videoTitle" size="large" placeholder="请输入标题"></el-input>
+            <el-input
+              v-model="videoTitle"
+              size="large"
+              placeholder="请输入标题"
+            ></el-input>
           </el-form-item>
           <el-form-item label="请添加关联视频链接">
-            <el-input size="large" v-model="videoUrl"
-              placeholder="视频链接,例:https://www.bilibili.com/video/BV188411V7Z7/?spm_id_from"></el-input>
+            <el-input
+              size="large"
+              v-model="videoUrl"
+              placeholder="视频链接,例:https://www.bilibili.com/video/BV188411V7Z7/?spm_id_from"
+            ></el-input>
           </el-form-item>
         </el-form>
       </div>
     </div>
     <div class="editor-main">
-      <el-input class="inputtitle" v-model="title" size="large" placeholder="请输入标题"></el-input>
+      <el-input
+        class="inputtitle"
+        v-model="title"
+        size="large"
+        placeholder="请输入标题"
+      ></el-input>
       <div class="editor-main__border"></div>
-      <Editor style="height: 500px; overflow-y: hidden;" v-model="valueHtml" :defaultConfig="editorConfig" :mode="mode"
-        @onCreated="handleCreated" />
+      <Editor
+        style="height: 500px; overflow-y: hidden"
+        v-model="valueHtml"
+        :defaultConfig="editorConfig"
+        :mode="mode"
+        @onCreated="handleCreated"
+      />
       <div class="editor-main__border"></div>
       <div class="footerbox">
         <div class="footerbox-title">发布设置</div>
         <el-form label-width="100" label-position="left">
           <el-form-item label="添加封面" class="flex-customs">
-            <el-upload ref="uploadRef" :show-file-list="false" :limit="1" :accept="getSourcesSuffix('image')"
-              :auto-upload="true" action="#" list-type="picture-card" :on-preview="handlePictureCardPreview"
-              :on-exceed="handleExceedImage" :http-request="handleCustomUploadImage" :on-remove="handleRemove">
-
+            <el-upload
+              ref="uploadRef"
+              :show-file-list="false"
+              :limit="1"
+              :accept="getSourcesSuffix('image')"
+              :auto-upload="true"
+              action="#"
+              list-type="picture-card"
+              :on-preview="handlePictureCardPreview"
+              :on-exceed="handleExceedImage"
+              :http-request="handleCustomUploadImage"
+              :on-remove="handleRemove"
+            >
               <img v-if="imageCover" :src="imageCover" class="image-cover" />
               <template v-else>
                 <el-icon :size="18" color="#999">
@@ -247,7 +303,9 @@ const handleReciveTopic = topic => {
         <div class="fixed__left">字数:{{ wordLen }}</div>
         <div class="fixed__right">
           <el-button @click="handleRecordMoment('draft')">存草稿</el-button>
-          <el-button type="primary" @click="handleRecordMoment('normal')">发布</el-button>
+          <el-button type="primary" @click="handleRecordMoment('normal')"
+            >发布</el-button
+          >
         </div>
       </div>
     </el-footer>
@@ -257,7 +315,7 @@ const handleReciveTopic = topic => {
 
 <style lang="scss">
 .el-container {
-  >div.placehbox {
+  > div.placehbox {
     width: 100%;
   }
 }
@@ -282,7 +340,6 @@ const handleReciveTopic = topic => {
         width: 100%;
       }
     }
-
   }
 
   &-main {
@@ -305,7 +362,7 @@ const handleReciveTopic = topic => {
 
     &__border {
       height: 1px;
-      background-color: #EEEEEE;
+      background-color: #eeeeee;
       margin-top: 18px;
       margin-bottom: 18px;
     }
@@ -336,7 +393,6 @@ const handleReciveTopic = topic => {
   &.videobox {
     margin-bottom: 20px;
   }
-
 }
 
 .footerbox {

+ 69 - 9
src/views/tongzhi/components/comment.vue

@@ -1,9 +1,14 @@
 <template>
-  <div class="box" v-for="(item, idx) in 1" :key="idx">
+  <div
+    class="box"
+    v-for="(item, idx) in newsList"
+    :key="idx"
+    style="margin-bottom: 20px"
+  >
     <div style="display: flex">
       <div>
         <img
-          src=""
+          :src="User.avatar"
           style="width: 48px; height: 48px; border-radius: 50%"
           alt=""
         />
@@ -12,27 +17,31 @@
         <div style="width: 775px">
           <div>
             <div style="display: flex">
-              <div class="title">火凤燎原</div>
+              <div class="title">{{ item.user.username }}</div>
               <div class="ping" style="margin-left: 8px">评论了我的文章</div>
             </div>
           </div>
-          <div class="date">2023-02-16 18:23</div>
+          <div class="date">{{ item.created_at }}</div>
         </div>
         <div>
-          <div class="content">过去没发过,这回是卡梅隆弄完了《深渊》《</div>
+          <div class="content">{{ item.content }}</div>
           <div></div>
         </div>
-        <div class="back" style="display: flex; margin-top: 19px">
+        <div
+          @click="todetail(item.source_id, item.source_type)"
+          class="back"
+          style="display: flex; margin-top: 19px"
+        >
           <div>
             <img
-              src=""
+              :src="item.source.image"
               style="width: 48px; height: 48px; border-radius: 50%"
               alt=""
             />
           </div>
           <div style="margin-left: 13px">
-            <div class="title">第二十七人</div>
-            <div class="contena">哈哈哈哈哈,怀念啊,我得骄傲的说一下,小</div>
+            <div class="title">{{ item.source.title }}</div>
+            <div class="contena" v-html="item.source.content"></div>
           </div>
         </div>
       </div>
@@ -44,6 +53,8 @@
 import { useRouter } from "vue-router";
 import { onMounted, ref } from "vue";
 import * as commentApi from "~/api/comment";
+import { useUser } from "~/store/user";
+const User = useUser();
 let newsList = ref([]);
 const __news__ = async () => {
   try {
@@ -53,6 +64,51 @@ const __news__ = async () => {
     newsList.value = data;
   } catch (error) {}
 };
+//跳转到详情
+const router = useRouter();
+const todetail = (id, type) => {
+  if (type == "article") {
+    router.push({
+      name: "articles",
+      query: {
+        id: id,
+        type: type,
+      },
+    });
+  } else if (type == "info") {
+    router.push({
+      name: "news",
+      query: {
+        id: id,
+        type: type,
+      },
+    });
+  } else if (type == "integral_goods") {
+    router.push({
+      path: "/store/pointshoping/:id",
+      query: {
+        id: id,
+        type: type,
+      },
+    });
+  } else if (type == "post") {
+    router.push({
+      name: "post",
+      query: {
+        id: id,
+        type: type,
+      },
+    });
+  } else if (type == "video") {
+    router.push({
+      name: "videos",
+      query: {
+        id: id,
+        type: type,
+      },
+    });
+  }
+};
 
 onMounted(__news__);
 </script>
@@ -70,6 +126,7 @@ onMounted(__news__);
 .back {
   background: #f7f7f7;
   border-radius: 6px;
+  cursor: pointer;
 }
 .ping {
   background: rgba(0, 176, 176, 0.1);
@@ -103,5 +160,8 @@ onMounted(__news__);
   line-height: 18px;
   text-align: left;
   font-style: normal;
+  height: 30px;
+  overflow: hidden;
+  width: 710px;
 }
 </style>

+ 13 - 1
src/views/video/index.vue

@@ -29,7 +29,7 @@ onMounted(__article__);
 //第几页
 const handleCurrentChange = (val) => {
   page.value = val;
-  __article__()
+  __article__();
 };
 
 // 精选视频
@@ -72,6 +72,7 @@ const pickmore = (val) => {
     <div class="content-list content-list--c2 flex-row">
       <template v-for="(item, idx) in videoList" :key="idx">
         <IndexSection
+          @video="__articles__()"
           @update="todetails(item.id)"
           :type="!item.image ? 'article' : 'common'"
           :title="item.title"
@@ -85,6 +86,11 @@ const pickmore = (val) => {
           :collect_count="item.collect_count"
           :share_count="item.share_count"
           :image="item.image"
+          :is_like="item.is_like"
+          :is_collect="item.is_collect"
+          :source_id="item.id"
+          :like_count="item.like_count"
+          source_type="video"
         />
       </template>
     </div>
@@ -93,6 +99,7 @@ const pickmore = (val) => {
     <div class="article-main">
       <template v-for="(item, idx) in newList" :key="idx">
         <IndexSection
+          @video="__article__()"
           @update="todetails(item.id)"
           :type="!item.image ? 'article' : 'common'"
           :title="item.title"
@@ -106,6 +113,11 @@ const pickmore = (val) => {
           :collect_count="item.collect_count"
           :share_count="item.share_count"
           :image="item.image"
+          :is_like="item.is_like"
+          :is_collect="item.is_collect"
+          :source_id="item.id"
+          :like_count="item.like_count"
+          source_type="video"
         />
       </template>
     </div>

+ 6 - 5
src/views/zixun.vue

@@ -9,7 +9,7 @@ import { useRouter } from "vue-router";
 const router = useRouter();
 
 const page = ref(1);
-const total = ref(0)
+const total = ref(0);
 //分页器
 const handleCurrentChange = (val) => {
   page.value = val;
@@ -26,7 +26,7 @@ const __news__ = async () => {
       is_boutique: 1,
     });
     newsList.value = data.list;
-    total.value = data.total
+    total.value = data.total;
   } catch (error) {}
 };
 onMounted(__news__);
@@ -44,7 +44,7 @@ const todetails = (id) => {
 <template>
   <div class="articles-container">
     <div class="title">精选资讯</div>
-    <div class="content-list flex-row flex-jc-sb">
+    <div class="content-list flex-row">
       <template v-for="(item, idx) in newsList" :key="idx">
         <IndexNews
           @update="todetails(item.id)"
@@ -53,6 +53,8 @@ const todetails = (id) => {
           :like-count="item.like_count"
           :comment-count="item.comment_count"
           :image="item.image"
+          :is_like="item.is_like"
+          :is_collect="item.is_collect"
         />
       </template>
     </div>
@@ -89,9 +91,8 @@ const todetails = (id) => {
 
   .content-list {
     margin-bottom: 30px;
-    column-gap: 20px;
+    column-gap: 18px;
     flex-wrap: wrap;
-    height: 255px;
     overflow: hidden;
   }
 

+ 6 - 2
src/views/zixun/index.vue

@@ -65,7 +65,7 @@ const zixunMore = (val) => {
   <div class="articles-container">
     <Banner type="info" />
     <IndexTitle title="精选资讯" @seeMore="zixunMore" />
-    <div class="content-list flex-row ">
+    <div class="content-list flex-row">
       <template v-for="(item, idx) in newsList" :key="idx">
         <IndexNews
           @update="todetails(item.id)"
@@ -74,6 +74,8 @@ const zixunMore = (val) => {
           :like-count="item.like_count"
           :comment-count="item.comment_count"
           :image="item.image"
+          :is_like="item.is_like"
+          :is_collect="item.is_collect"
         />
       </template>
     </div>
@@ -88,6 +90,8 @@ const zixunMore = (val) => {
           :like-count="item.like_count"
           :comment-count="item.comment_count"
           :image="item.image"
+          :is_like="item.is_like"
+          :is_collect="item.is_collect"
         />
       </template>
     </div>
@@ -116,7 +120,7 @@ const zixunMore = (val) => {
 
   .content-list {
     margin-bottom: 30px;
-    column-gap: 20px;
+    column-gap: 18px;
     flex-wrap: wrap;
     height: 255px;
     overflow: hidden;

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików