main.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. <!--
  2. - Copyright (C) 2018-2019
  3. - All rights reserved, Designed By www.joolun.com
  4. -->
  5. <template>
  6. <el-tabs type="border-card" v-model="objData.repType" @tab-click="handleClick">
  7. <el-tab-pane name="text">
  8. <span slot="label"><i class="el-icon-document"></i> 文本</span>
  9. <el-input
  10. type="textarea"
  11. :rows="5"
  12. placeholder="请输入内容"
  13. v-model="objData.repContent">
  14. </el-input>
  15. </el-tab-pane>
  16. <el-tab-pane name="image">
  17. <span slot="label"><i class="el-icon-picture"></i> 图片</span>
  18. <el-row>
  19. <div class="select-item" v-if="objData.repUrl">
  20. <img class="material-img" :src="objData.repUrl">
  21. <p class="item-name" v-if="objData.repName">{{objData.repName}}</p>
  22. <el-row class="ope-row">
  23. <el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button>
  24. </el-row>
  25. </div>
  26. <div v-if="!objData.repUrl">
  27. <el-row style="text-align: center">
  28. <el-col :span="12" class="col-select">
  29. <el-button type="success" @click="openMaterial">素材库选择<i class="el-icon-circle-check el-icon--right"></i></el-button>
  30. </el-col>
  31. <el-col :span="12" class="col-add">
  32. <el-upload
  33. :action="actionUrl"
  34. :headers="headers"
  35. multiple
  36. :limit="1"
  37. :on-success="handleUploadSuccess"
  38. :file-list="fileList"
  39. :before-upload="beforeImageUpload"
  40. :data="uploadData">
  41. <el-button type="primary">上传图片</el-button>
  42. <div slot="tip" class="el-upload__tip">
  43. 支持bmp/png/jpeg/jpg/gif格式,大小不超过2M
  44. </div>
  45. </el-upload>
  46. </el-col>
  47. </el-row>
  48. </div>
  49. <el-dialog title="选择图片" :visible.sync="dialogImageVisible" width="90%" append-to-body>
  50. <WxMaterialSelect :objData="objData" @selectMaterial="selectMaterial"></WxMaterialSelect>
  51. </el-dialog>
  52. </el-row>
  53. </el-tab-pane>
  54. <el-tab-pane name="voice">
  55. <span slot="label"><i class="el-icon-phone"></i> 语音</span>
  56. <el-row>
  57. <div class="select-item2" v-if="objData.repName">
  58. <p class="item-name">{{objData.repName}}</p>
  59. <div class="item-infos">
  60. <WxVoicePlayer :objData="Object.assign(tempPlayerObj,{repMediaId: objData.media_id, repName: objData.repName})"></WxVoicePlayer>
  61. </div>
  62. <el-row class="ope-row">
  63. <el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button>
  64. </el-row>
  65. </div>
  66. <div v-if="!objData.repName">
  67. <el-row style="text-align: center">
  68. <el-col :span="12" class="col-select">
  69. <el-button type="success" @click="openMaterial">素材库选择<i class="el-icon-circle-check el-icon--right"></i></el-button>
  70. </el-col>
  71. <el-col :span="12" class="col-add">
  72. <el-upload
  73. :action="actionUrl"
  74. :headers="headers"
  75. multiple
  76. :limit="1"
  77. :on-success="handleUploadSuccess"
  78. :file-list="fileList"
  79. :before-upload="beforeVoiceUpload"
  80. :data="uploadData">
  81. <el-button type="primary">点击上传</el-button>
  82. <div slot="tip" class="el-upload__tip">
  83. 格式支持mp3/wma/wav/amr,文件大小不超过2M,播放长度不超过60s
  84. </div>
  85. </el-upload>
  86. </el-col>
  87. </el-row>
  88. </div>
  89. <el-dialog title="选择语音" :visible.sync="dialogVoiceVisible" width="90%" append-to-body>
  90. <WxMaterialSelect :objData="objData" @selectMaterial="selectMaterial"></WxMaterialSelect>
  91. </el-dialog>
  92. </el-row>
  93. </el-tab-pane>
  94. <el-tab-pane name="video">
  95. <span slot="label"><i class="el-icon-share"></i> 视频</span>
  96. <el-row>
  97. <el-input v-model="objData.repName" placeholder="请输入标题"></el-input>
  98. <div style="margin: 20px 0;"></div>
  99. <el-input v-model="objData.repDesc" placeholder="请输入描述"></el-input>
  100. <div style="margin: 20px 0;"></div>
  101. <div style="text-align: center;">
  102. <a target="_blank" v-if="objData.repUrl" :href="objData.repUrl"><i class="icon-shipinbofang">&nbsp;播放视频</i></a>
  103. </div>
  104. <div style="margin: 20px 0;"></div>
  105. <div style="text-align: center">
  106. <el-button type="success" @click="openMaterial">素材库选择<i class="el-icon-circle-check el-icon--right"></i></el-button>
  107. <!-- <el-button type="primary" v-if="permissions.wxmp_wxmaterial_add">新建视频<i class="el-icon-upload el-icon&#45;&#45;right"></i></el-button>-->
  108. </div>
  109. <el-dialog title="选择视频" :visible.sync="dialogVideoVisible" width="90%" append-to-body>
  110. <WxMaterialSelect :objData="objData" @selectMaterial="selectMaterial"></WxMaterialSelect>
  111. </el-dialog>
  112. </el-row>
  113. </el-tab-pane>
  114. <el-tab-pane name="news">
  115. <span slot="label"><i class="el-icon-news"></i> 图文</span>
  116. <el-row>
  117. <div class="select-item" v-if="objData.content">
  118. <WxNews :objData="objData.content.articles"></WxNews>
  119. <el-row class="ope-row">
  120. <el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button>
  121. </el-row>
  122. </div>
  123. <div v-if="!objData.content">
  124. <el-row style="text-align: center">
  125. <el-col :span="24" class="col-select2">
  126. <el-button type="success" @click="openMaterial">{{newsType == '1' ? '选择已发布图文' : '选择草稿箱图文'}}<i class="el-icon-circle-check el-icon--right"></i></el-button>
  127. </el-col>
  128. </el-row>
  129. </div>
  130. <el-dialog title="选择图文" :visible.sync="dialogNewsVisible" width="90%" append-to-body>
  131. <WxMaterialSelect :objData="objData" @selectMaterial="selectMaterial" :newsType="newsType"></WxMaterialSelect>
  132. </el-dialog>
  133. </el-row>
  134. </el-tab-pane>
  135. <el-tab-pane name="music">
  136. <span slot="label"><i class="el-icon-service"></i> 音乐</span>
  137. <el-row>
  138. <el-col :span="6">
  139. <div class="thumb-div">
  140. <img style="width: 100px" v-if="objData.repThumbUrl" :src="objData.repThumbUrl">
  141. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  142. <div class="thumb-but">
  143. <el-upload
  144. :action="actionUrl"
  145. :headers="headers"
  146. multiple
  147. :limit="1"
  148. :on-success="handleUploadSuccess"
  149. :file-list="fileList"
  150. :before-upload="beforeThumbImageUpload"
  151. :data="uploadData">
  152. <el-button slot="trigger" size="mini" type="text">本地上传</el-button>
  153. <el-button size="mini" type="text" @click="openMaterial" style="margin-left: 5px">素材库选择</el-button>
  154. </el-upload>
  155. </div>
  156. </div>
  157. <el-dialog title="选择图片" :visible.sync="dialogThumbVisible" width="80%" append-to-body>
  158. <WxMaterialSelect :objData="{repType:'image'}" @selectMaterial="selectMaterial"></WxMaterialSelect>
  159. </el-dialog>
  160. </el-col>
  161. <el-col :span="18">
  162. <el-input v-model="objData.repName" placeholder="请输入标题"></el-input>
  163. <div style="margin: 20px 0;"></div>
  164. <el-input v-model="objData.repDesc" placeholder="请输入描述"></el-input>
  165. </el-col>
  166. </el-row>
  167. <div style="margin: 20px 0;"></div>
  168. <el-input v-model="objData.repUrl" placeholder="请输入音乐链接"></el-input>
  169. <div style="margin: 20px 0;"></div>
  170. <el-input v-model="objData.repHqUrl" placeholder="请输入高质量音乐链接"></el-input>
  171. </el-tab-pane>
  172. </el-tabs>
  173. </template>
  174. <script>
  175. // import { getPage, getMaterialVideo } from '@/api/wxmp/wxmaterial'
  176. import WxNews from '@/views/mp/components/wx-news/main.vue'
  177. // import WxMaterialSelect from '@/components/wx-material-select/main.vue'
  178. import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue';
  179. import { getToken } from '@/utils/auth'
  180. export default {
  181. name: "wxReplySelect",
  182. components: {
  183. WxNews,
  184. // WxMaterialSelect,
  185. WxVoicePlayer
  186. },
  187. props: {
  188. objData:{
  189. type:Object
  190. },
  191. //图文类型:1、已发布图文;2、草稿箱图文
  192. newsType:{
  193. type: String,
  194. default: "1"
  195. },
  196. },
  197. data() {
  198. return {
  199. tempPlayerObj: {
  200. type: '2'
  201. },
  202. tableData: [],
  203. page: {
  204. total: 0, // 总页数
  205. currentPage: 1, // 当前页数
  206. pageSize: 20, // 每页显示多少条
  207. ascs:[],//升序字段
  208. descs:[]//降序字段
  209. },
  210. tableLoading: false,
  211. dialogNewsVisible:false,
  212. dialogImageVisible:false,
  213. dialogVoiceVisible:false,
  214. dialogVideoVisible:false,
  215. dialogThumbVisible:false,
  216. tempObj: new Map().set(this.objData.repType,Object.assign({},this.objData)),
  217. fileList:[],
  218. uploadData:{
  219. "mediaType":this.objData.repType,
  220. "title":'',
  221. "introduction":''
  222. },
  223. actionUrl: process.env.VUE_APP_BASE_API +'/wxmaterial/materialFileUpload',
  224. headers: {
  225. Authorization: 'Bearer ' + getToken()
  226. }
  227. }
  228. },
  229. computed: {
  230. },
  231. methods:{
  232. beforeThumbImageUpload(file){
  233. const isType = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/bmp' || file.type === 'image/jpg';
  234. const isLt = file.size / 1024 / 1024 < 2;
  235. if (!isType) {
  236. this.$message.error('上传图片格式不对!');
  237. }
  238. if (!isLt) {
  239. this.$message.error('上传图片大小不能超过2M!');
  240. }
  241. return isType && isLt;
  242. },
  243. deleteObj(){
  244. this.$delete(this.objData,'repName')
  245. this.$delete(this.objData,'repUrl')
  246. this.$delete(this.objData,'content')
  247. },
  248. beforeVoiceUpload(file){
  249. this.tableLoading = true
  250. const isType = file.type === 'audio/mp3' || file.type === 'audio/wma' || file.type === 'audio/wav' || file.type === 'audio/amr';
  251. const isLt = file.size / 1024 / 1024 < 2;
  252. if (!isType) {
  253. this.$message.error('上传语音格式不对!');
  254. }
  255. if (!isLt) {
  256. this.$message.error('上传语音大小不能超过2M!');
  257. }
  258. return isType && isLt;
  259. },
  260. beforeImageUpload(file){
  261. const isType = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/bmp' || file.type === 'image/jpg';
  262. const isLt = file.size / 1024 / 1024 < 2;
  263. if (!isType) {
  264. this.$message.error('上传图片格式不对!');
  265. }
  266. if (!isLt) {
  267. this.$message.error('上传图片大小不能超过2M!');
  268. }
  269. return isType && isLt;
  270. },
  271. handleUploadSuccess(response, file, fileList){
  272. if(response.code == 200){
  273. this.fileList = []
  274. this.uploadData.title = ''
  275. this.uploadData.introduction = ''
  276. let item = response.data
  277. this.selectMaterial(item)
  278. }else{
  279. this.$message.error('上传出错:' + response.msg)
  280. }
  281. },
  282. handleClick(tab, event){
  283. this.uploadData.mediaType = this.objData.repType
  284. let tempObjItem = this.tempObj.get(this.objData.repType)
  285. if(tempObjItem){
  286. this.objData.repName = tempObjItem.repName ? tempObjItem.repName : null
  287. this.objData.repMediaId = tempObjItem.repMediaId ? tempObjItem.repMediaId : null
  288. this.objData.media_id = tempObjItem.media_id ? tempObjItem.media_id : null
  289. this.objData.repUrl = tempObjItem.repUrl ? tempObjItem.repUrl : null
  290. this.objData.content = tempObjItem.content ? tempObjItem.content : null
  291. this.objData.repDesc = tempObjItem.repDesc ? tempObjItem.repDesc : null
  292. }else{
  293. this.$delete(this.objData,'repName')
  294. this.$delete(this.objData,'repMediaId')
  295. this.$delete(this.objData,'media_id')
  296. this.$delete(this.objData,'repUrl')
  297. this.$delete(this.objData,'content')
  298. this.$delete(this.objData,'repDesc')
  299. }
  300. },
  301. selectMaterial(item){
  302. let tempObjItem = {}
  303. tempObjItem.repType = this.objData.repType
  304. tempObjItem.repMediaId = item.mediaId
  305. tempObjItem.media_id = item.mediaId
  306. tempObjItem.content = item.content
  307. this.dialogNewsVisible = false
  308. this.dialogImageVisible = false
  309. this.dialogVoiceVisible = false
  310. this.dialogVideoVisible = false
  311. this.objData.repMediaId = item.mediaId
  312. this.objData.media_id = item.mediaId
  313. this.objData.content = item.content
  314. if(this.objData.repType == 'music'){
  315. tempObjItem.repThumbMediaId = item.mediaId
  316. tempObjItem.repThumbUrl = item.url
  317. this.objData.repThumbMediaId = item.mediaId
  318. this.objData.repThumbUrl = item.url
  319. this.dialogThumbVisible = false
  320. }else{
  321. tempObjItem.repName = item.name
  322. tempObjItem.repUrl = item.url
  323. this.objData.repName = item.name
  324. this.objData.repUrl = item.url
  325. }
  326. if(this.objData.repType == 'video'){
  327. // getMaterialVideo({
  328. // mediaId:item.mediaId
  329. // }).then(response => {
  330. // if(response.code == 200){
  331. // let data = response.data
  332. // this.$set(this.objData,'repName',data.title)
  333. // this.$set(this.objData,'repDesc',data.description)
  334. // this.$set(this.objData,'repUrl',data.downUrl)
  335. // tempObjItem.repDesc = data.description
  336. // tempObjItem.repUrl = data.downUrl
  337. // }
  338. // })
  339. }
  340. this.tempObj.set(this.objData.repType,tempObjItem)
  341. },
  342. openMaterial(){
  343. if(this.objData.repType == 'news'){
  344. this.dialogNewsVisible = true
  345. }else if(this.objData.repType == 'image'){
  346. this.dialogImageVisible = true
  347. }else if(this.objData.repType == 'voice'){
  348. this.dialogVoiceVisible = true
  349. }else if(this.objData.repType == 'video'){
  350. this.dialogVideoVisible = true
  351. }else if(this.objData.repType == 'music'){
  352. this.dialogThumbVisible = true
  353. }
  354. },
  355. getPage(page, params) {
  356. this.tableLoading = true
  357. // getPage(Object.assign({
  358. // current: page.currentPage,
  359. // size: page.pageSize,
  360. // type:this.objData.repType
  361. // }, params)).then(response => {
  362. // this.tableData = response.data.items
  363. // this.page.total = response.data.totalCount
  364. // this.page.currentPage = page.currentPage
  365. // this.page.pageSize = page.pageSize
  366. // this.tableLoading = false
  367. // })
  368. },
  369. sizeChange(val) {
  370. this.page.currentPage = 1
  371. this.page.pageSize = val
  372. this.getPage(this.page)
  373. }
  374. }
  375. };
  376. </script>
  377. <style lang="scss" scoped>
  378. .public-account-management{
  379. .el-input{
  380. width: 70%;
  381. margin-right: 2%;
  382. }
  383. }
  384. .pagination{
  385. text-align: right;
  386. margin-right: 25px;
  387. }
  388. .select-item{
  389. width: 280px;
  390. padding: 10px;
  391. margin: 0 auto 10px auto;
  392. border: 1px solid #eaeaea;
  393. }
  394. .select-item2{
  395. padding: 10px;
  396. margin: 0 auto 10px auto;
  397. border: 1px solid #eaeaea;
  398. }
  399. .ope-row{
  400. padding-top: 10px;
  401. text-align: center;
  402. }
  403. .item-name{
  404. font-size: 12px;
  405. overflow: hidden;
  406. text-overflow:ellipsis;
  407. white-space: nowrap;
  408. text-align: center;
  409. }
  410. .el-form-item__content{
  411. line-height:unset!important;
  412. }
  413. .col-select{
  414. border: 1px solid rgb(234, 234, 234);
  415. padding: 50px 0px;
  416. height: 160px;
  417. width: 49.5%;
  418. }
  419. .col-select2{
  420. border: 1px solid rgb(234, 234, 234);
  421. padding: 50px 0px;
  422. height: 160px;
  423. }
  424. .col-add{
  425. border: 1px solid rgb(234, 234, 234);
  426. padding: 50px 0px;
  427. height: 160px;
  428. width: 49.5%;
  429. float: right
  430. }
  431. .avatar-uploader-icon {
  432. border: 1px solid #d9d9d9;
  433. font-size: 28px;
  434. color: #8c939d;
  435. width: 100px!important;
  436. height: 100px!important;
  437. line-height: 100px!important;
  438. text-align: center;
  439. }
  440. .material-img {
  441. width: 100%;
  442. }
  443. .thumb-div{
  444. display: inline-block;
  445. text-align: center;
  446. }
  447. .item-infos{
  448. width: 30%;
  449. margin: auto
  450. }
  451. </style>