main.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. <!--
  2. - Copyright (C) 2018-2019
  3. - All rights reserved, Designed By www.joolun.com
  4. 芋道源码:
  5. ① 移除 avue 组件,使用 ElementUI 原生组件
  6. -->
  7. <template>
  8. <div class="pb-30px">
  9. <!-- 类型:image -->
  10. <div v-if="objData.type === 'image'">
  11. <div class="waterfall" v-loading="loading">
  12. <div class="waterfall-item" v-for="item in list" :key="item.mediaId">
  13. <img class="material-img" :src="item.url" />
  14. <p class="item-name">{{ item.name }}</p>
  15. <el-row class="ope-row">
  16. <el-button type="success" @click="selectMaterialFun(item)">
  17. 选择 <Icon icon="ep:circle-check" />
  18. </el-button>
  19. </el-row>
  20. </div>
  21. </div>
  22. <!-- 分页组件 -->
  23. <Pagination
  24. :total="total"
  25. v-model:page="queryParams.pageNo"
  26. v-model:limit="queryParams.pageSize"
  27. @pagination="getMaterialPageFun"
  28. />
  29. </div>
  30. <!-- 类型:voice -->
  31. <div v-else-if="objData.type === 'voice'">
  32. <!-- 列表 -->
  33. <el-table v-loading="loading" :data="list">
  34. <el-table-column label="编号" align="center" prop="mediaId" />
  35. <el-table-column label="文件名" align="center" prop="name" />
  36. <el-table-column label="语音" align="center">
  37. <template #default="scope">
  38. <WxVoicePlayer :url="scope.row.url" />
  39. </template>
  40. </el-table-column>
  41. <el-table-column
  42. label="上传时间"
  43. align="center"
  44. prop="createTime"
  45. width="180"
  46. :formatter="dateFormatter"
  47. />
  48. <el-table-column label="操作" align="center" fixed="right">
  49. <template #default="scope">
  50. <el-button type="text" @click="selectMaterialFun(scope.row)">
  51. 选择<Icon icon="ep:plus" />
  52. </el-button>
  53. </template>
  54. </el-table-column>
  55. </el-table>
  56. <!-- 分页组件 -->
  57. <Pagination
  58. :total="total"
  59. v-model:page="queryParams.pageNo"
  60. v-model:limit="queryParams.pageSize"
  61. @pagination="getPage"
  62. />
  63. </div>
  64. <!-- 类型:video -->
  65. <div v-else-if="objData.type === 'video'">
  66. <!-- 列表 -->
  67. <el-table v-loading="loading" :data="list">
  68. <el-table-column label="编号" align="center" prop="mediaId" />
  69. <el-table-column label="文件名" align="center" prop="name" />
  70. <el-table-column label="标题" align="center" prop="title" />
  71. <el-table-column label="介绍" align="center" prop="introduction" />
  72. <el-table-column label="视频" align="center">
  73. <template #default="scope">
  74. <WxVideoPlayer :url="scope.row.url" />
  75. </template>
  76. </el-table-column>
  77. <el-table-column
  78. label="上传时间"
  79. align="center"
  80. prop="createTime"
  81. width="180"
  82. :formatter="dateFormatter"
  83. />
  84. <el-table-column
  85. label="操作"
  86. align="center"
  87. fixed="right"
  88. class-name="small-padding fixed-width"
  89. >
  90. <template #default="scope">
  91. <el-button type="text" @click="selectMaterialFun(scope.row)">
  92. 选择<Icon icon="akar-icons:circle-plus" />
  93. </el-button>
  94. </template>
  95. </el-table-column>
  96. </el-table>
  97. <!-- 分页组件 -->
  98. <Pagination
  99. :total="total"
  100. v-model:page="queryParams.pageNo"
  101. v-model:limit="queryParams.pageSize"
  102. @pagination="getMaterialPageFun"
  103. />
  104. </div>
  105. <!-- 类型:news -->
  106. <div v-else-if="objData.type === 'news'">
  107. <div class="waterfall" v-loading="loading">
  108. <div class="waterfall-item" v-for="item in list" :key="item.mediaId">
  109. <div v-if="item.content && item.content.newsItem">
  110. <WxNews :articles="item.content.newsItem" />
  111. <el-row class="ope-row">
  112. <el-button type="success" @click="selectMaterialFun(item)">
  113. 选择<Icon icon="ep:circle-check" />
  114. </el-button>
  115. </el-row>
  116. </div>
  117. </div>
  118. </div>
  119. <!-- 分页组件 -->
  120. <Pagination
  121. :total="total"
  122. v-model:page="queryParams.pageNo"
  123. v-model:limit="queryParams.pageSize"
  124. @pagination="getMaterialPageFun"
  125. />
  126. </div>
  127. </div>
  128. </template>
  129. <script lang="ts" name="WxMaterialSelect">
  130. import WxNews from '@/views/mp/components/wx-news/main.vue'
  131. import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue'
  132. import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue'
  133. import { getMaterialPage } from '@/api/mp/material'
  134. import { getFreePublishPage } from '@/api/mp/freePublish'
  135. import { getDraftPage } from '@/api/mp/draft'
  136. import { dateFormatter } from '@/utils/formatTime'
  137. import { defineComponent, PropType } from 'vue'
  138. export default defineComponent({
  139. components: {
  140. WxNews,
  141. WxVoicePlayer,
  142. WxVideoPlayer
  143. },
  144. props: {
  145. objData: {
  146. type: Object, // type - 类型;accountId - 公众号账号编号
  147. required: true
  148. },
  149. newsType: {
  150. // 图文类型:1、已发布图文;2、草稿箱图文
  151. type: String as PropType<string>,
  152. default: '1'
  153. }
  154. },
  155. setup(props, ctx) {
  156. // 遮罩层
  157. const loading = ref(false)
  158. // 总条数
  159. const total = ref(0)
  160. // 数据列表
  161. const list = ref([])
  162. // 查询参数
  163. const queryParams = reactive({
  164. pageNo: 1,
  165. pageSize: 10,
  166. accountId: props.objData.accountId
  167. })
  168. const objDataRef = reactive(props.objData)
  169. const newsTypeRef = ref(props.newsType)
  170. const selectMaterialFun = (item) => {
  171. ctx.emit('select-material', item)
  172. }
  173. /** 搜索按钮操作 */
  174. const handleQuery = () => {
  175. queryParams.pageNo = 1
  176. getPage()
  177. }
  178. const getPage = () => {
  179. loading.value = true
  180. if (objDataRef.type === 'news' && newsTypeRef.value === '1') {
  181. // 【图文】+ 【已发布】
  182. getFreePublishPageFun()
  183. } else if (objDataRef.type === 'news' && newsTypeRef.value === '2') {
  184. // 【图文】+ 【草稿】
  185. getDraftPageFun()
  186. } else {
  187. // 【素材】
  188. getMaterialPageFun()
  189. }
  190. }
  191. const getMaterialPageFun = async () => {
  192. let data = await getMaterialPage({
  193. ...queryParams,
  194. type: objDataRef.type
  195. })
  196. list.value = data.list
  197. total.value = data.total
  198. loading.value = false
  199. }
  200. const getFreePublishPageFun = async () => {
  201. let data = await getFreePublishPage(queryParams)
  202. data.list.forEach((item) => {
  203. const newsItem = item.content.newsItem
  204. newsItem.forEach((article) => {
  205. article.picUrl = article.thumbUrl
  206. })
  207. })
  208. list.value = data.list
  209. total.value = data.total
  210. loading.value = false
  211. }
  212. const getDraftPageFun = async () => {
  213. let data = await getDraftPage(queryParams)
  214. data.list.forEach((item) => {
  215. const newsItem = item.content.newsItem
  216. newsItem.forEach((article) => {
  217. article.picUrl = article.thumbUrl
  218. })
  219. })
  220. list.value = data.list
  221. total.value = data.total
  222. loading.value = false
  223. }
  224. onMounted(async () => {
  225. getPage()
  226. })
  227. return {
  228. handleQuery,
  229. dateFormatter,
  230. selectMaterialFun,
  231. getMaterialPageFun,
  232. getPage,
  233. formatDate,
  234. queryParams,
  235. objDataRef,
  236. list,
  237. total,
  238. loading
  239. }
  240. }
  241. })
  242. </script>
  243. <style lang="scss" scoped>
  244. /*瀑布流样式*/
  245. .waterfall {
  246. width: 100%;
  247. column-gap: 10px;
  248. column-count: 5;
  249. margin: 0 auto;
  250. }
  251. .waterfall-item {
  252. padding: 10px;
  253. margin-bottom: 10px;
  254. break-inside: avoid;
  255. border: 1px solid #eaeaea;
  256. }
  257. .material-img {
  258. width: 100%;
  259. }
  260. p {
  261. line-height: 30px;
  262. }
  263. @media (min-width: 992px) and (max-width: 1300px) {
  264. .waterfall {
  265. column-count: 3;
  266. }
  267. p {
  268. color: red;
  269. }
  270. }
  271. @media (min-width: 768px) and (max-width: 991px) {
  272. .waterfall {
  273. column-count: 2;
  274. }
  275. p {
  276. color: orange;
  277. }
  278. }
  279. @media (max-width: 767px) {
  280. .waterfall {
  281. column-count: 1;
  282. }
  283. }
  284. /*瀑布流样式*/
  285. </style>