mblog.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. <template>
  2. <v-container class="grey lighten-5">
  3. <v-row justify="space-between">
  4. <v-col>
  5. <v-row dense>
  6. <v-col>
  7. <v-card
  8. color="#385F73"
  9. dark
  10. >
  11. <v-row dense>
  12. <v-textarea
  13. v-model="statusPost.content"
  14. solo
  15. falt
  16. filled
  17. auto-grow
  18. label="说点什么呢?"
  19. rows="3"
  20. />
  21. </v-row>
  22. <v-row>
  23. <v-col>
  24. <!-- 接收 filepond-image 中 this.$emit('resp', resp) 的数据 -->
  25. <!--<FilePondUploadImage @resp="uploadCallback" />-->
  26. <div>
  27. <file-pond
  28. ref="pond"
  29. name="file"
  30. label-idle="选择图片或拖动图片到此处"
  31. label-file-processing="图片正在上传,请稍后"
  32. label-file-processing-aborted="图片上传被取消"
  33. label-tap-to-retry="尝试重试"
  34. label-file-processing-complete="图片上传成功!"
  35. label-max-file-size="上传的图片大小不能超过 10MB"
  36. label-max-file-size-exceeded="上传的图片大小不能超过 10MB"
  37. allow-file-size-validation="true"
  38. max-file-size="10MB"
  39. accepted-file-types="image/png, image/jpeg, image/jpg, image/gif"
  40. :allow-multiple="true"
  41. :max-files="9"
  42. :server="server"
  43. :instant-upload="true"
  44. @init="handleFilePondInit"
  45. @processfile="success"
  46. @removefile="removeFile"
  47. />
  48. </div>
  49. </v-col>
  50. </v-row>
  51. <v-row dense>
  52. <v-col>
  53. <v-card-actions>
  54. <v-btn text @click="publish">
  55. 发布
  56. </v-btn>
  57. </v-card-actions>
  58. </v-col>
  59. </v-row>
  60. </v-card>
  61. </v-col>
  62. <v-col>
  63. <v-sheet
  64. class="mx-auto"
  65. max-width="720"
  66. />
  67. </v-col>
  68. <v-col>
  69. <div v-infinite-scroll="loadMore" infinite-scroll-disabled="true" infinite-scroll-distance="10">
  70. <v-col cols="12">
  71. <v-tabs>
  72. <v-tab @click="setType(0)">状态</v-tab>
  73. <v-tab @click="setType(1)">视频</v-tab>
  74. <v-tab @click="setType(2)">回答</v-tab>
  75. </v-tabs>
  76. <v-row
  77. v-for="item in cardList"
  78. :key="item.statusId"
  79. dense
  80. >
  81. <status-card v-if="cardType === 'status'" :item="item" />
  82. <item-card v-if="cardType === 'video'" :video="item" />
  83. <status-card v-if="cardType === 'answer'" :item="item" />
  84. </v-row>
  85. </v-col>
  86. </div>
  87. </v-col>
  88. </v-row>
  89. </v-col>
  90. <v-col md="4">
  91. <v-row dense>
  92. <v-col cols="12">
  93. <v-card
  94. class="mx-auto"
  95. color="#26c6da"
  96. dark
  97. >
  98. <v-card-title>
  99. <v-avatar size="32">
  100. <v-img
  101. :src="this.$store.state.user.userInfo.avatarUrl"
  102. :alt="this.$store.state.user.userInfo.username"
  103. :title="this.$store.state.user.userInfo.username"
  104. />
  105. </v-avatar>
  106. <span class="text-h6 font-weight-light">{{ this.$store.state.user.userInfo.username }}</span>
  107. </v-card-title>
  108. <v-card-text class="text-h5 font-weight-light">
  109. {{ this.$store.state.user.userInfo.intro }}
  110. </v-card-text>
  111. <v-card-text class="text-h5 font-weight-light">
  112. 关注 {{ this.$store.state.user.userInfo.followingCount }} | 被关注 {{ this.$store.state.user.userInfo.followerCount }}
  113. </v-card-text>
  114. </v-card>
  115. </v-col>
  116. <v-col cols="12">
  117. <v-card
  118. color="#385F73"
  119. light
  120. >
  121. <v-card-title class="text-h5">
  122. 热门问题
  123. </v-card-title>
  124. <v-card-text>
  125. <p class="text-body-1 text--primary">
  126. 1.第1条
  127. </p>
  128. <p class="text-body-1 text--primary">
  129. 2.第2条
  130. </p>
  131. </v-card-text>
  132. </v-card>
  133. </v-col>
  134. <v-col cols="12">
  135. <v-card
  136. color="#385F73"
  137. light
  138. >
  139. <v-card-title class="text-h5">
  140. 热门视频
  141. </v-card-title>
  142. <v-card-text>
  143. <p class="text-body-1 text--primary">
  144. 1.第1条
  145. </p>
  146. <p class="text-body-1 text--primary">
  147. 2.第2条
  148. </p>
  149. </v-card-text>
  150. </v-card>
  151. </v-col>
  152. </v-row>
  153. </v-col>
  154. </v-row>
  155. <v-snackbar
  156. v-model="showMessage"
  157. :top="true"
  158. :timeout="3000"
  159. >
  160. {{ message }}
  161. <template v-slot:action="{ attrs }">
  162. <v-btn
  163. color="pink"
  164. text
  165. v-bind="attrs"
  166. @click="showMessage = false"
  167. >
  168. 关闭
  169. </v-btn>
  170. </template>
  171. </v-snackbar>
  172. </v-container>
  173. </template>
  174. <script>
  175. import { mapActions, mapGetters } from 'vuex'
  176. import { pubStatus, statusRecommend } from '@/api/mblog/status'
  177. import { videoTimeline } from '@/api/media/video'
  178. import StatusCard from '@/components/card/status-card'
  179. import ItemCard from '@/components/card/item-card'
  180. import VueFilePond from 'vue-filepond'
  181. import FilePondPluginImagePreview from 'filepond-plugin-image-preview'
  182. import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type'
  183. import FilePondPluginFileValidateSize from 'filepond-plugin-file-validate-size'
  184. import 'filepond/dist/filepond.min.css'
  185. import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css'
  186. const FilePond = VueFilePond(
  187. FilePondPluginFileValidateType,
  188. FilePondPluginImagePreview,
  189. FilePondPluginFileValidateSize
  190. )
  191. var imgFileIds = []
  192. export default {
  193. name: 'Home',
  194. components: {
  195. FilePond,
  196. StatusCard,
  197. ItemCard
  198. },
  199. data() {
  200. return {
  201. server: {
  202. url: '//api.reghao.cn/api/file/upload/image',
  203. revert: null,
  204. process: {
  205. headers: {
  206. 'Authorization': this.$store.getters.token
  207. },
  208. ondata(formData) {
  209. return formData
  210. },
  211. onload(response) {
  212. const resp = JSON.parse(response)
  213. if (resp.code === 0) {
  214. imgFileIds.push(resp.data.imageFileId)
  215. } else {
  216. if (resp.msg != null) {
  217. this.message = '上传文件出现异常,请重新上传!' + resp.msg
  218. } else {
  219. this.message = '上传文件出现异常,请重新上传!'
  220. }
  221. this.showMessage = true
  222. }
  223. }
  224. }
  225. },
  226. statusPost: {
  227. imageFileIds: [],
  228. content: '',
  229. location: ''
  230. },
  231. cardType: null,
  232. cardList: [],
  233. busy: false,
  234. page: 1,
  235. followingUser: [
  236. { username: 'haha', avatar: '', userId: 10000 },
  237. { username: 'haha', avatar: '', userId: 10001 },
  238. { username: 'haha', avatar: '', userId: 10002 }
  239. ],
  240. showMessage: false,
  241. message: ''
  242. }
  243. },
  244. computed: {
  245. ...mapGetters({
  246. statuses: 'my_content',
  247. option: 'my_content_option',
  248. showImage: 'image_zoom_show'
  249. })
  250. },
  251. watch: {
  252. option: {
  253. handler: function(val, oldVal) {
  254. if (val && val.page === 1) {
  255. this.cardList = []
  256. }
  257. },
  258. deep: true
  259. },
  260. statuses: function(val, oldVal) {
  261. if (val) {
  262. if (this.option.page === 1) {
  263. this.cardList = val
  264. } else {
  265. this.cardList = [...this.cardList, ...val]
  266. }
  267. }
  268. }
  269. },
  270. created() {
  271. this.getFollowingStatus(this.page)
  272. },
  273. mounted() {
  274. },
  275. methods: {
  276. ...mapActions([
  277. 'getMyContent'
  278. ]),
  279. handleFilePondInit() {
  280. // FilePond instance methods are available on `this.$refs.pond`
  281. },
  282. success(error, metadata) {
  283. if (error === null) {
  284. return
  285. }
  286. },
  287. removeFile(error, metadata) {
  288. if (error === null) {
  289. const file = metadata.file
  290. const uploadId = this.imgMap[file.name]
  291. fetch('//file.reghao.cn/api/file/rm/' + uploadId, {
  292. headers: {
  293. 'Authorization': this.$store.getters.token
  294. },
  295. method: 'DELETE'
  296. }).then(response => response.json())
  297. .then(json => {
  298. console.log('删除 this.statusPost.imageFileIds 中相应的图片')
  299. })
  300. .catch(e => {
  301. return null
  302. })
  303. }
  304. },
  305. setType(type) {
  306. if (type === this.type) {
  307. return
  308. }
  309. this.type = type
  310. this.page = 1
  311. if (type === 0) {
  312. this.getFollowingStatus(this.page)
  313. this.$vuetify.goTo(type)
  314. } else if (type === 1) {
  315. this.getFollowingVideos(this.page)
  316. this.$vuetify.goTo(type)
  317. } else if (type === 2) {
  318. this.getFollowingAnswers(this.page)
  319. this.$vuetify.goTo(type)
  320. }
  321. },
  322. loadMore: function() {
  323. this.busy = true
  324. setTimeout(() => {
  325. if (this.cardType === 'status') {
  326. this.getFollowingStatus(this.page)
  327. } else if (this.cardType === 'video') {
  328. this.getFollowingVideos(this.page)
  329. } else if (this.cardType === 'answer') {
  330. this.getFollowingAnswers(this.page)
  331. }
  332. }, 1000)
  333. },
  334. getFollowingStatus(page) {
  335. statusRecommend(page)
  336. .then(res => {
  337. if (res.code === 0) {
  338. this.cardType = 'status'
  339. if (page === 1) {
  340. this.cardList = []
  341. }
  342. for (const item of res.data.list) {
  343. this.cardList.push(item)
  344. }
  345. this.page += 1
  346. this.busy = false
  347. } else {
  348. this.message = res.msg
  349. this.showMessage = true
  350. }
  351. })
  352. .catch(error => {
  353. this.message = error.message
  354. this.showMessage = true
  355. })
  356. },
  357. getFollowingVideos(page) {
  358. videoTimeline(page)
  359. .then(res => {
  360. if (res.code === 0) {
  361. this.cardType = 'video'
  362. if (page === 1) {
  363. this.cardList = []
  364. }
  365. for (const item of res.data.list) {
  366. this.cardList.push(item)
  367. }
  368. this.page += 1
  369. this.busy = false
  370. } else {
  371. this.message = res.msg
  372. this.showMessage = true
  373. }
  374. })
  375. .catch(error => {
  376. this.message = error.message
  377. this.showMessage = true
  378. })
  379. },
  380. getFollowingAnswers(page) {
  381. this.cardType = 'answer'
  382. console.log('获取关注的用户回答')
  383. },
  384. selectFollowingUser() {
  385. console.log('加载选中用户的状态...')
  386. },
  387. publish() {
  388. if (this.statusPost.content === '') {
  389. this.message = '内容不能为空'
  390. this.showMessage = true
  391. return
  392. }
  393. this.statusPost.imageFileIds = imgFileIds
  394. pubStatus(this.statusPost)
  395. .then(res => {
  396. if (res.code === 0) {
  397. this.message = '状态已发布'
  398. this.showMessage = true
  399. this.statusPost.content = ''
  400. this.statusPost.imageFileIds = []
  401. } else {
  402. this.message = res.msg
  403. this.showMessage = true
  404. }
  405. }).catch(error => {
  406. this.message = error.message
  407. this.showMessage = true
  408. })
  409. }
  410. }
  411. }
  412. </script>
  413. <style>
  414. </style>