index.html 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. {include file="/shopro/common/script" /}
  2. <style>
  3. .voice-content .item {
  4. background: var(--sa-background-assist);
  5. }
  6. .item {
  7. padding: 12px;
  8. line-height: 1;
  9. margin-bottom: 24px;
  10. box-shadow: 0 1px 6px rgb(89 89 89 / 12%);
  11. border-radius: 8px;
  12. border: 1px solid var(--sa-space);
  13. }
  14. .item:hover {
  15. box-shadow: 0 3px 12px rgb(89 89 89 / 20%);
  16. transform: translateY(-4px);
  17. }
  18. .news-content .item {
  19. min-height: 144px;
  20. }
  21. .news-content .item .frist-news>div {
  22. position: relative;
  23. }
  24. .news-content .item .frist-news .sa-image {
  25. width: 100%;
  26. height: 144px;
  27. }
  28. .news-content .item .frist-news .title {
  29. position: absolute;
  30. bottom: 0;
  31. left: 0;
  32. width: 100%;
  33. height: 32px;
  34. line-height: 32px;
  35. padding: 0 12px;
  36. background: rgba(38, 38, 38, 0.5);
  37. backdrop-filter: blur(1px);
  38. font-size: 12px;
  39. color: #fff;
  40. z-index: 1;
  41. }
  42. .news-content .item .other-news {
  43. height: 40px;
  44. padding: 0 12px !important;
  45. display: flex;
  46. align-items: center;
  47. }
  48. .news-content .item .other-news>div {
  49. width: 100%;
  50. }
  51. .news-content .item .other-news .title {
  52. flex: 1;
  53. font-size: 12px;
  54. color: var(--sa-subtitle);
  55. }
  56. .news-content .item .other-news .sa-image {
  57. width: 24px;
  58. height: 24px;
  59. flex-shrink: 0;
  60. }
  61. .image-content .sa-image {
  62. width: 100%;
  63. height: 144px;
  64. border-radius: 0;
  65. border: 1px solid var(--sa-space);
  66. }
  67. .image-content .name {
  68. padding: 10px 12px;
  69. font-size: 12px;
  70. color: var(--sa-title);
  71. }
  72. .video-content .cover-url {
  73. position: relative;
  74. }
  75. .video-content .cover-url .sa-image {
  76. width: 64px;
  77. height: 48px;
  78. border-radius: 0;
  79. }
  80. .video-content .cover-url .mask {
  81. position: absolute;
  82. top: 0;
  83. bottom: 0;
  84. left: 0;
  85. right: 0;
  86. background: rgba(38, 38, 38, 0.5);
  87. color: var(--sa-background-assist);
  88. backdrop-filter: blur(1px);
  89. border-radius: 2px;
  90. }
  91. .video-content .name {
  92. height: 16px;
  93. line-height: 16px;
  94. font-size: 14px;
  95. color: var(--sa-title);
  96. }
  97. .video-content .description {
  98. height: 16px;
  99. line-height: 16px;
  100. font-size: 14px;
  101. color: var(--sa-font);
  102. }
  103. .voice-content .item .voice-svg {
  104. flex-shrink: 0;
  105. width: 64px;
  106. height: 48px;
  107. background: var(--el-color-primary-light-9);
  108. backdrop-filter: blur(2px);
  109. border-radius: 2px;
  110. color: var(--el-color-primary);
  111. font-size: 20px;
  112. }
  113. .voice-content .name {
  114. height: 16px;
  115. line-height: 16px;
  116. font-size: 14px;
  117. color: var(--sa-title);
  118. }
  119. .voice-content .description {
  120. height: 16px;
  121. line-height: 16px;
  122. font-size: 12px;
  123. color: var(--sa-font);
  124. }
  125. .text-content .item-content {
  126. font-size: 12px;
  127. color: var(--sa-title);
  128. line-height: 20px;
  129. height: 40px;
  130. word-break: break-all;
  131. }
  132. .link-content .title {
  133. height: 16px;
  134. line-height: 16px;
  135. font-size: 14px;
  136. color: var(--sa-title);
  137. }
  138. .link-content .description {
  139. height: 16px;
  140. line-height: 16px;
  141. font-size: 12px;
  142. color: var(--sa-font);
  143. }
  144. .material-index .name {
  145. word-break: break-all;
  146. }
  147. </style>
  148. <div id="index" class="material-index panel panel-default panel-intro" v-cloak>
  149. <el-container class="panel-block">
  150. <el-header class="sa-header">
  151. <el-alert class="mt-4 mb-4" type="warning">
  152. <template #title>
  153. 素材管理中图文消息、图片、视频、音频,需要您在公众号平台进行上传。
  154. <a href="https://mp.weixin.qq.com" target="_blank">微信公众号管理</a>
  155. </template>
  156. </el-alert>
  157. <el-tabs class="sa-tabs" v-model="state.type" @tab-change="onChangeTab">
  158. <el-tab-pane label="图文消息" name="news"> </el-tab-pane>
  159. <el-tab-pane label="图片" name="image"> </el-tab-pane>
  160. <el-tab-pane label="视频" name="video"> </el-tab-pane>
  161. <el-tab-pane label="语音" name="voice"> </el-tab-pane>
  162. <el-tab-pane label="文本" name="text"> </el-tab-pane>
  163. <el-tab-pane label="链接" name="link"> </el-tab-pane>
  164. </el-tabs>
  165. <div v-if="state.type == 'text' || state.type == 'link'" class="sa-title sa-flex sa-row-between">
  166. <div class="sa-title-left">
  167. <div class="left-name"></div>
  168. </div>
  169. <div class="sa-title-right">
  170. <el-button class="sa-button-refresh" icon="RefreshRight" @click="getData"></el-button>
  171. {if $auth->check('shopro/wechat/material/add')}
  172. <el-button icon="Plus" type="primary" @click="onAdd">添加</el-button>
  173. {/if}
  174. </div>
  175. </div>
  176. </el-header>
  177. <el-main>
  178. <el-scrollbar height="100%">
  179. <el-row :gutter="20">
  180. <el-col v-for="item in state.data" :key="item" :xs="12" :sm="8" :md="6" :lg="4" :xl="4">
  181. <div :class="`${state.type}-content`">
  182. <template v-if="state.type == 'news'">
  183. <div class="item">
  184. <a v-for="(it, index) in item.content.news_item" :key="it"
  185. :class="index == 0 ? 'frist-news' : 'other-news'" :href="it.url"
  186. target="_blank">
  187. <div class="sa-flex sa-row-between sa-line-1">
  188. <div class="title sa-line-1">{{ it.title }}</div>
  189. <sa-image :url="it.thumb_url" fit="cover"></sa-image>
  190. </div>
  191. </a>
  192. </div>
  193. </template>
  194. <template v-if="state.type == 'image'">
  195. <div class="item">
  196. <sa-image :url="item.url" fit="cover"></sa-image>
  197. <div class="name sa-line-1">{{ item.name }}</div>
  198. </div>
  199. </template>
  200. <template v-if="state.type == 'video'">
  201. <div class="item sa-flex">
  202. <div class="cover-url">
  203. <sa-image :url="item.cover_url"></sa-image>
  204. <div class="mask sa-flex sa-row-center">
  205. <sa-svg name="sa-play" size="20"></sa-svg>
  206. </div>
  207. </div>
  208. <div class="ml-2">
  209. <div class="name mb-1 sa-table-line-1">{{ item.name }}</div>
  210. <div class="description sa-table-line-1">{{ item.description }}</div>
  211. </div>
  212. </div>
  213. </template>
  214. <template v-if="state.type == 'voice'">
  215. <div class="item sa-flex">
  216. <div class="voice-svg sa-flex sa-row-center">
  217. <sa-svg name="sa-play" size="20"></sa-svg>
  218. </div>
  219. <div class="ml-2">
  220. <div class="name mb-1 sa-table-line-1">{{ item.name }}</div>
  221. <div class="description sa-table-line-1">{{ item.description }}</div>
  222. </div>
  223. </div>
  224. </template>
  225. <template v-if="state.type == 'text'">
  226. <div class="item">
  227. <div class="item-content sa-line-2 mb-2" v-html="item.content"></div>
  228. <div class="sa-flex sa-row-right">
  229. {if $auth->check('shopro/wechat/material/edit')}
  230. <el-button type="primary" link @click="onEdit(item.id)">编辑</el-button>
  231. {/if}
  232. <el-popconfirm width="fit-content" confirm-button-text="确认"
  233. cancel-button-text="取消" title="确认删除这条记录?" @confirm="onDelete(item.id)">
  234. <template #reference>
  235. {if $auth->check('shopro/wechat/material/delete')}
  236. <el-button type="danger" link>删除</el-button>
  237. {/if}
  238. </template>
  239. </el-popconfirm>
  240. </div>
  241. </div>
  242. </template>
  243. <template v-if="state.type == 'link'">
  244. <div class="item">
  245. <div v-if="item.content" class="sa-flex mb-2">
  246. <sa-image :url="item.content.image" size="40"></sa-image>
  247. <div class="ml-2">
  248. <div class="title mb-1 sa-table-line-1">{{ item.content.title }}</div>
  249. <div class="description sa-table-line-1">
  250. {{ item.content.description }}
  251. </div>
  252. </div>
  253. </div>
  254. <div class="sa-flex sa-row-right">
  255. {if $auth->check('shopro/wechat/material/edit')}
  256. <el-button type="primary" link @click="onEdit(item.id)">编辑</el-button>
  257. {/if}
  258. <el-popconfirm width="fit-content" confirm-button-text="确认"
  259. cancel-button-text="取消" title="确认删除这条记录?" @confirm="onDelete(item.id)">
  260. <template #reference>
  261. {if $auth->check('shopro/wechat/material/delete')}
  262. <el-button type="danger" link>删除</el-button>
  263. {/if}
  264. </template>
  265. </el-popconfirm>
  266. </div>
  267. </div>
  268. </template>
  269. </div>
  270. </el-col>
  271. </el-row>
  272. </el-scrollbar>
  273. </el-main>
  274. <el-footer class="sa-footer sa-flex sa-row-right">
  275. <sa-pagination v-model="pagination" @pagination-change="getData"></sa-pagination>
  276. </el-footer>
  277. </el-container>
  278. </div>