index.vue 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960
  1. <template>
  2. <div>
  3. <div style="padding: 10px">
  4. <div style="border-bottom: 1px solid #e6e6e6;background-color: white; display: flex;justify-content: left;">
  5. <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="80px" style="padding-top: 10px">
  6. <el-form-item label="企微公司" prop="corpId">
  7. <el-select v-model="queryParams.corpId" placeholder="企微公司" size="small" @change="updateCorpId()">
  8. <el-option
  9. v-for="dict in myQwCompanyList"
  10. :key="dict.dictValue"
  11. :label="dict.dictLabel"
  12. :value="dict.dictValue"
  13. />
  14. </el-select>
  15. </el-form-item>
  16. <el-form-item label="标题" prop="title">
  17. <el-input
  18. v-model="queryParams.title"
  19. placeholder="请输入标题"
  20. clearable
  21. size="small"
  22. @keyup.enter.native="handleQuery"
  23. />
  24. </el-form-item>
  25. <el-form-item label="创建人" prop="createName">
  26. <el-input
  27. v-model="queryParams.createName"
  28. placeholder="请输入创建人"
  29. clearable
  30. size="small"
  31. @keyup.enter.native="handleQuery"
  32. />
  33. </el-form-item>
  34. <!-- <el-form-item label="发送次数" prop="sendCount">-->
  35. <!-- <el-input-->
  36. <!-- v-model="queryParams.sendCount"-->
  37. <!-- placeholder="请输入发送次数"-->
  38. <!-- clearable-->
  39. <!-- size="small"-->
  40. <!-- @keyup.enter.native="handleQuery"-->
  41. <!-- />-->
  42. <!-- </el-form-item>-->
  43. <el-form-item>
  44. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  45. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置/刷新页面/回到全部</el-button>
  46. <el-button type="primary" size="mini" @click="handleAdd()" v-hasPermi="['qw:material:add']">添加素材</el-button>
  47. </el-form-item>
  48. </el-form>
  49. </div>
  50. <div style="margin-top: 10px;height: 700px;width: auto;border: 1px solid #e6e6e6; display: flex;">
  51. <div style="background-color: white;height: 100%;width: 16%; overflow-y: auto; ">
  52. <div style="padding: 10px;">
  53. <MaterialGroup ref="MaterialGroup" @selectGroupScreen="selectGroupScreen" @refresh-index="refreshIndex"></MaterialGroup>
  54. </div>
  55. </div>
  56. <div style="height: 100%;width: 1%">
  57. </div>
  58. <div style="background-color: white;height: 100%;width: 83%;">
  59. <div style="padding: 20px; height: calc(100% - 40px); overflow-y: auto;">
  60. <el-tabs v-model="activeName" @tab-click="handleClick" style="height: 100%" >
  61. <el-tab-pane label="所有" name="1">
  62. <el-table v-loading="loading" :data="materialList" @selection-change="handleSelectionChange" border>
  63. <el-table-column label="素材内容" align="center" >
  64. <template slot-scope="scope">
  65. <div v-if="scope.row.materialType=='text'">
  66. <el-tooltip class="item" effect="dark" :content="scope.row.textContent" placement="top">
  67. <div style="display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; text-overflow: ellipsis;">
  68. <span>{{ scope.row.textContent }}</span>
  69. </div>
  70. </el-tooltip>
  71. </div>
  72. <el-image
  73. v-else-if="scope.row.materialType=='image'"
  74. style="width: 100px; height: 100px"
  75. :src="scope.row.materialUrl"
  76. fit="contain"
  77. @click="openImageViewer(scope.row.materialUrl)"/>
  78. <div v-else-if="scope.row.materialType=='imagetext'">
  79. <el-tooltip class="item" effect="dark" :content="scope.row.textContent" placement="top">
  80. <div style="display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; text-overflow: ellipsis;">
  81. <span>{{ scope.row.textContent }}</span>
  82. <el-link :href="scope.row.materialUrl" target="_blank">{{ scope.row.materialUrl }}</el-link>
  83. </div>
  84. </el-tooltip>
  85. <div v-if="scope.row.titleUrl">
  86. <el-image style="width: 100px; height: 100px" :src="scope.row.titleUrl"
  87. fit="contain" @click="openImageViewer(scope.row.titleUrl)" />
  88. </div>
  89. </div>
  90. <div v-else-if="scope.row.materialType == 'voice'" style="width: 200px">
  91. <audio controls :src="scope.row.materialUrl"/>
  92. </div>
  93. <video
  94. v-else-if="scope.row.materialType == 'video'"
  95. :src="scope.row.materialUrl"
  96. controls style="width: 200px;height: 100px">
  97. </video>
  98. <div v-else-if="scope.row.materialType == 'file'" class="file-link-container" style="width: 100%">
  99. <el-link type="primary" :href="downloadUrl(scope.row.materialUrl)" download>
  100. {{scope.row.materialUrl}}
  101. </el-link>
  102. </div>
  103. </template>
  104. </el-table-column>
  105. <el-table-column label="标题" align="center" prop="title"/>
  106. <el-table-column label="创建人" align="center" prop="createName"/>
  107. <!-- <el-table-column label="发送次数" align="center" prop="sendCount"/>-->
  108. <el-table-column label="隶属分组" align="center" prop="materialGroupName"></el-table-column>
  109. <el-table-column label="创建时间" align="center" prop="createTime"/>
  110. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  111. <template slot-scope="scope">
  112. <el-button
  113. size="mini"
  114. type="text"
  115. icon="el-icon-edit"
  116. @click="handleUpdate(scope.row)"
  117. v-hasPermi="['qw:material:edit']"
  118. >修改</el-button>
  119. <el-button
  120. size="mini"
  121. type="text"
  122. icon="el-icon-delete"
  123. @click="handleDelete(scope.row)"
  124. v-hasPermi="['qw:material:remove']"
  125. >删除</el-button>
  126. </template>
  127. </el-table-column>
  128. </el-table>
  129. </el-tab-pane>
  130. <el-tab-pane label="文本" name="2">
  131. <el-table v-loading="loading" :data="this.textMaterialsList" @selection-change="handleSelectionChange">
  132. <el-table-column label="素材内容" align="center" prop="textContent">
  133. <template slot-scope="scope">
  134. <el-tooltip class="item" effect="dark" :content="scope.row.textContent" placement="top">
  135. <div style="display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; text-overflow: ellipsis;">
  136. <span>文本消息:</span>{{ scope.row.textContent }}
  137. </div>
  138. </el-tooltip>
  139. </template>
  140. </el-table-column>
  141. <el-table-column label="标题" align="center" prop="title"/>
  142. <el-table-column label="创建人" align="center" prop="createName"/>
  143. <!-- <el-table-column label="发送次数" align="center" prop="sendCount"/>-->
  144. <el-table-column label="隶属分组" align="center" prop="materialGroupName"></el-table-column>
  145. <el-table-column label="创建时间" align="center" prop="createTime"/>
  146. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  147. <template slot-scope="scope">
  148. <el-button
  149. size="mini"
  150. type="text"
  151. icon="el-icon-edit"
  152. @click="handleUpdate(scope.row)"
  153. v-hasPermi="['qw:material:edit']"
  154. >修改</el-button>
  155. <el-button
  156. size="mini"
  157. type="text"
  158. icon="el-icon-delete"
  159. @click="handleDelete(scope.row)"
  160. v-hasPermi="['qw:material:remove']"
  161. >删除</el-button>
  162. </template>
  163. </el-table-column>
  164. </el-table>
  165. </el-tab-pane>
  166. <el-tab-pane label="图片" name="3">
  167. <div style="display: flex; flex-wrap: wrap; gap: 10px; ">
  168. <el-card
  169. v-for="(item, index) in imageMaterialsList"
  170. :key="index">
  171. <!-- style="width: 250px;height: 300px">-->
  172. <!-- <div class="card-header">-->
  173. <!-- <el-checkbox-->
  174. <!-- :label="item.id"-->
  175. <!-- @change="handleSelectionChange($event, item)"-->
  176. <!-- ></el-checkbox>-->
  177. <!-- </div>-->
  178. <el-image
  179. style="width: 200px; height: 180px"
  180. :src="item.materialUrl"
  181. fit="contain"
  182. @click="openImageViewer(item.materialUrl)"/>
  183. <div>
  184. <div style=" display: flex;flex-direction: column;">
  185. <span>标题:{{ item.title }}</span>
  186. <span>创建人:{{item.createName}}</span>
  187. <time class="time" style="white-space: nowrap">时间:{{ item.createTime }}</time>
  188. </div>
  189. <div class="bottom clearfix">
  190. <el-button
  191. class="button"
  192. size="mini"
  193. type="text"
  194. icon="el-icon-edit"
  195. @click="handleUpdate(item)"
  196. v-hasPermi="['qw:material:edit']"
  197. >修改</el-button>
  198. <el-button
  199. class="button"
  200. size="mini"
  201. type="text"
  202. icon="el-icon-delete"
  203. @click="handleDelete(item)"
  204. v-hasPermi="['qw:material:remove']"
  205. >删除</el-button>
  206. </div>
  207. </div>
  208. </el-card>
  209. </div>
  210. </el-tab-pane>
  211. <!-- <el-tab-pane label="图文" name="4">-->
  212. <!-- <div style="display: flex; flex-wrap: wrap; gap: 10px; ">-->
  213. <!-- <el-card-->
  214. <!-- v-for="(item, index) in imagetextMaterialsList"-->
  215. <!-- :key="index">-->
  216. <!-- <el-image-->
  217. <!-- v-if="item.titleUrl"-->
  218. <!-- style="width: 200px; height: 180px"-->
  219. <!-- :src="item.titleUrl"-->
  220. <!-- fit="contain"-->
  221. <!-- @click="openImageViewer(item.titleUrl)"-->
  222. <!-- />-->
  223. <!-- <div v-else style="width: 200px; height: 180px; display: flex; justify-content: center; align-items: center; border: 1px solid #dcdcdc;">-->
  224. <!-- 暂无标题图片-->
  225. <!-- </div>-->
  226. <!-- <div style="margin-top: 3%">-->
  227. <!-- <div style=" display: flex;flex-direction: column;width: 200px">-->
  228. <!-- <span>标题:{{ item.title }}</span>-->
  229. <!-- <div style="display: flex; flex-wrap: wrap; word-break: break-all;margin:3% 0">-->
  230. <!-- <span>链接:</span>-->
  231. <!-- <el-link :href="item.materialUrl" target="_blank">{{ item.materialUrl }}</el-link>-->
  232. <!-- </div>-->
  233. <!-- <span>创建人:{{item.createName}}</span>-->
  234. <!-- <time class="time" style="white-space: nowrap">时间:{{ item.createTime }}</time>-->
  235. <!-- </div>-->
  236. <!-- <div class="bottom clearfix">-->
  237. <!-- <el-button-->
  238. <!-- class="button"-->
  239. <!-- size="mini"-->
  240. <!-- type="text"-->
  241. <!-- icon="el-icon-edit"-->
  242. <!-- @click="handleUpdate(item)"-->
  243. <!-- v-hasPermi="['qw:material:edit']"-->
  244. <!-- >修改</el-button>-->
  245. <!-- <el-button-->
  246. <!-- class="button"-->
  247. <!-- size="mini"-->
  248. <!-- type="text"-->
  249. <!-- icon="el-icon-delete"-->
  250. <!-- @click="handleDelete(item)"-->
  251. <!-- v-hasPermi="['qw:material:remove']"-->
  252. <!-- >删除</el-button>-->
  253. <!-- </div>-->
  254. <!-- </div>-->
  255. <!-- </el-card>-->
  256. <!-- </div>-->
  257. <!-- </el-tab-pane>-->
  258. <!-- <el-tab-pane label="语音" name="5">-->
  259. <!-- <div style="display: flex; flex-wrap: wrap; gap: 10px; ">-->
  260. <!-- <el-card-->
  261. <!-- v-for="(item, index) in voiceMaterialsList"-->
  262. <!-- :key="index">-->
  263. <!-- &lt;!&ndash; style="width: 250px;height: 300px">&ndash;&gt;-->
  264. <!-- &lt;!&ndash; <div class="card-header">&ndash;&gt;-->
  265. <!-- &lt;!&ndash; <el-checkbox&ndash;&gt;-->
  266. <!-- &lt;!&ndash; :label="item.id"&ndash;&gt;-->
  267. <!-- &lt;!&ndash; @change="handleSelectionChange($event, item)"&ndash;&gt;-->
  268. <!-- &lt;!&ndash; ></el-checkbox>&ndash;&gt;-->
  269. <!-- &lt;!&ndash; </div>&ndash;&gt;-->
  270. <!-- <audio controls :src="item.materialUrl" style="width: 300px;height: 50px"/>-->
  271. <!-- <div>-->
  272. <!-- <div style=" display: flex;flex-direction: column;width: 200px">-->
  273. <!-- <span>标题:{{ item.title }}</span>-->
  274. <!-- <span>创建人:{{item.createName}}</span>-->
  275. <!-- <time class="time" style="white-space: nowrap">时间:{{ item.createTime }}</time>-->
  276. <!-- </div>-->
  277. <!-- <div class="bottom clearfix">-->
  278. <!-- <el-button-->
  279. <!-- class="button"-->
  280. <!-- size="mini"-->
  281. <!-- type="text"-->
  282. <!-- icon="el-icon-edit"-->
  283. <!-- @click="handleUpdate(item)"-->
  284. <!-- v-hasPermi="['qw:material:edit']"-->
  285. <!-- >修改</el-button>-->
  286. <!-- <el-button-->
  287. <!-- class="button"-->
  288. <!-- size="mini"-->
  289. <!-- type="text"-->
  290. <!-- icon="el-icon-delete"-->
  291. <!-- @click="handleDelete(item)"-->
  292. <!-- v-hasPermi="['qw:material:remove']"-->
  293. <!-- >删除</el-button>-->
  294. <!-- </div>-->
  295. <!-- </div>-->
  296. <!-- </el-card>-->
  297. <!-- </div>-->
  298. <!-- </el-tab-pane>-->
  299. <el-tab-pane label="视频" name="6">
  300. <div style="display: flex; flex-wrap: wrap; gap: 10px; ">
  301. <el-card
  302. v-for="(item, index) in videoMaterialsList"
  303. :key="index">
  304. <!-- style="width: 250px;height: 300px">-->
  305. <!-- <div class="card-header">-->
  306. <!-- <el-checkbox-->
  307. <!-- :label="item.id"-->
  308. <!-- @change="handleSelectionChange($event, item)"-->
  309. <!-- ></el-checkbox>-->
  310. <!-- </div>-->
  311. <video
  312. :src="item.materialUrl"
  313. controls style="width: 200px;height: 100px">
  314. </video>
  315. <div>
  316. <div style=" display: flex;flex-direction: column;width: 200px">
  317. <span>标题:{{ item.title }}</span>
  318. <span>创建人:{{item.createName}}</span>
  319. <time class="time" style="white-space: nowrap">时间:{{ item.createTime }}</time>
  320. </div>
  321. <div class="bottom clearfix">
  322. <el-button
  323. class="button"
  324. size="mini"
  325. type="text"
  326. icon="el-icon-edit"
  327. @click="handleUpdate(item)"
  328. v-hasPermi="['qw:material:edit']"
  329. >修改</el-button>
  330. <el-button
  331. class="button"
  332. size="mini"
  333. type="text"
  334. icon="el-icon-delete"
  335. @click="handleDelete(item)"
  336. v-hasPermi="['qw:material:remove']"
  337. >删除</el-button>
  338. </div>
  339. </div>
  340. </el-card>
  341. </div>
  342. </el-tab-pane>
  343. <el-tab-pane label="文件" name="7">
  344. <div style="display: flex; flex-wrap: wrap; gap: 10px; ">
  345. <el-card
  346. v-for="(item, index) in fileMaterialsList"
  347. :key="index">
  348. <!-- style="width: 250px;height: 300px">-->
  349. <!-- <div class="card-header">-->
  350. <!-- <el-checkbox-->
  351. <!-- :label="item.id"-->
  352. <!-- @change="handleSelectionChange($event, item)"-->
  353. <!-- ></el-checkbox>-->
  354. <!-- </div>-->
  355. <el-link type="primary" :href="downloadUrl(item.materialUrl)" download>
  356. {{item.materialUrl}}
  357. </el-link>
  358. <div>
  359. <div style=" display: flex;flex-direction: column;width: 200px">
  360. <span>标题:{{ item.title }}</span>
  361. <span>创建人:{{item.createName}}</span>
  362. <time class="time" style="white-space: nowrap">时间:{{ item.createTime }}</time>
  363. </div>
  364. <div class="bottom clearfix">
  365. <el-button
  366. class="button"
  367. size="mini"
  368. type="text"
  369. icon="el-icon-edit"
  370. @click="handleUpdate(item)"
  371. v-hasPermi="['qw:material:edit']"
  372. >修改</el-button>
  373. <el-button
  374. class="button"
  375. size="mini"
  376. type="text"
  377. icon="el-icon-delete"
  378. @click="handleDelete(item)"
  379. v-hasPermi="['qw:material:remove']"
  380. >删除</el-button>
  381. </div>
  382. </div>
  383. </el-card>
  384. </div>
  385. </el-tab-pane>
  386. </el-tabs>
  387. </div>
  388. </div>
  389. </div>
  390. <pagination
  391. v-show="total>0"
  392. :total="total"
  393. :page.sync="queryParams.pageNum"
  394. :limit.sync="queryParams.pageSize"
  395. @pagination="getList"
  396. />
  397. </div>
  398. <!-- 大图预览对话框 -->
  399. <el-dialog
  400. :visible.sync="dialogVisible"
  401. :modal="false"
  402. width="800"
  403. append-to-body>
  404. <img
  405. :src="this.dialogImageUrl"
  406. style="display: block; max-width: 100%; margin: 0 auto"
  407. />
  408. </el-dialog>
  409. <!-- 添加或修改素材对话框 -->
  410. <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
  411. <el-form ref="form" :model="form" :rules="rules" label-width="130px">
  412. <el-form-item label="分组名称" prop="materialGroupId">
  413. <el-select v-model="form.materialGroupId" filterable placeholder="请选择分组">
  414. <el-option
  415. v-for="item in meaterialGroupOptions"
  416. :key="item.materialGroupId"
  417. :label="item.materialGroupName"
  418. :value="item.materialGroupId"/>
  419. </el-select>
  420. </el-form-item>
  421. <el-form-item label="标题" prop="title">
  422. <el-input v-model="form.title" placeholder="请输入标题"/>
  423. </el-form-item>
  424. <div v-if="!form.materialId">
  425. <el-form-item label="素材类型" prop="materialType">
  426. <el-radio-group v-model="form.materialType">
  427. <el-radio :label="item.dictValue" v-for="item in materialTypeOptions" >{{item.dictLabel}}</el-radio>
  428. </el-radio-group>
  429. </el-form-item>
  430. </div>
  431. <div v-if="form.materialType=='text'">
  432. <el-form-item label="文本内容" prop="textContent" required>
  433. <el-input v-model="form.textContent" type="textarea" :rows="3" maxlength="1300" show-word-limit placeholder="请输入文本消息" required></el-input>
  434. </el-form-item>
  435. </div>
  436. <div v-else-if="form.materialType=='image'">
  437. <el-form-item label="上传图片" prop="materialUrl">
  438. <ImageUpload v-model="form.materialUrl" type="image" :num="1" :width="150" :height="150" />
  439. </el-form-item>
  440. </div>
  441. <div v-else-if="form.materialType=='imagetext'">
  442. <el-form-item label="上传标题图片" prop="textUrl">
  443. <ImageUpload v-model="form.titleUrl" type="image" :num="10" :width="150" :height="150" />
  444. </el-form-item>
  445. <el-form-item label="文本内容" prop="textContent">
  446. <el-input v-model="form.textContent" type="textarea" :rows="3" maxlength="1300" show-word-limit placeholder="请输入文本消息" ></el-input>
  447. </el-form-item>
  448. <el-form-item label="图文的URL地址" prop="materialUrl" required>
  449. <!-- <ImageUpload v-model="form.materialUrl" type="image" :num="10" :width="150" :height="150" />-->
  450. <el-input v-model="form.materialUrl" placeholder="请输入图文链接地址" />
  451. </el-form-item>
  452. </div>
  453. <div v-else-if="form.materialType=='voice'">
  454. <el-form-item label="上传音频" prop="materialUrl">
  455. <el-upload v-if="form.materialUrl==null || form.materialId"
  456. v-model="form.materialUrl"
  457. class="avatar-uploader"
  458. :action="uploadUrl"
  459. :show-file-list="false"
  460. :on-success="handleAvatarSuccess"
  461. :before-upload="beforeAvatarUploadVoice">
  462. <i class="el-icon-plus avatar-uploader-icon"></i>
  463. </el-upload>
  464. <audio v-if="form.materialUrl" controls :src="form.materialUrl" style="width: 300px;height: 50px"/>
  465. </el-form-item>
  466. </div>
  467. <div v-else-if="form.materialType=='video'">
  468. <el-form-item label="上传视频" prop="materialUrl">
  469. <el-upload v-if="form.materialUrl==null || form.materialId"
  470. v-model="form.materialUrl"
  471. class="avatar-uploader"
  472. :action="uploadUrl"
  473. :show-file-list="false"
  474. :on-success="handleAvatarSuccess"
  475. :before-upload="beforeAvatarUploadVideo">
  476. <i class="el-icon-plus avatar-uploader-icon"></i>
  477. </el-upload>
  478. <video v-if="form.materialUrl"
  479. :src="form.materialUrl"
  480. controls style="width: 300px;height: 200px">
  481. </video>
  482. </el-form-item>
  483. </div>
  484. <div v-else-if="form.materialType=='file'">
  485. <el-form-item label="上传文件" prop="materialUrl">
  486. <el-upload v-if="form.materialUrl==null || form.materialId"
  487. v-model="form.materialUrl"
  488. class="avatar-uploader"
  489. :action="uploadUrl"
  490. :show-file-list="false"
  491. :on-success="handleAvatarSuccess"
  492. :before-upload="beforeAvatarUploadFile">
  493. <i class="el-icon-plus avatar-uploader-icon"></i>
  494. </el-upload>
  495. <el-link v-if="form.materialUrl" type="primary" :href="downloadUrl(form.materialUrl)" download>
  496. {{ form.materialUrl }}
  497. </el-link>
  498. </el-form-item>
  499. </div>
  500. </el-form>
  501. <div slot="footer" class="dialog-footer">
  502. <el-button type="primary" @click="submitForm">确 定</el-button>
  503. <el-button @click="cancel">取 消</el-button>
  504. </div>
  505. </el-dialog>
  506. </div>
  507. </template>
  508. <script>
  509. import { listMaterial, getMaterial, delMaterial, addMaterial, updateMaterial, exportMaterial } from "@/api/qw/material";
  510. import MaterialGroup from '@/views/qw/materialGroup/materialGroup'
  511. import ImageUpload from "@/views/qw/material/ImageUpload";
  512. import { getMyQwUserList,getMyQwCompanyList } from "@/api/qw/user";
  513. export default {
  514. name: "Material",
  515. components: { MaterialGroup,ImageUpload},
  516. data() {
  517. return {
  518. //图片放大
  519. dialogVisible: false,
  520. dialogImageUrl:null,
  521. //上传地址
  522. uploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadOSS2",
  523. myQwCompanyList:[],
  524. // 遮罩层
  525. loading: true,
  526. // 导出遮罩层
  527. exportLoading: false,
  528. // 选中数组
  529. ids: [],
  530. // 非单个禁用
  531. single: true,
  532. // 非多个禁用
  533. multiple: true,
  534. // 显示搜索条件
  535. showSearch: true,
  536. // 总条数
  537. total: 0,
  538. // 素材库表格数据
  539. materialList: [],
  540. textMaterialsList:[],
  541. imageMaterialsList:[],
  542. imagetextMaterialsList:[],
  543. voiceMaterialsList:[],
  544. videoMaterialsList:[],
  545. fileMaterialsList:[],
  546. defaultMaterialList:[],
  547. //素材类型
  548. materialTypeOptions:[],
  549. //素材组
  550. meaterialGroupOptions:[],
  551. // 弹出层标题
  552. title: "",
  553. // 是否显示弹出层
  554. open: false,
  555. // 查询参数
  556. queryParams: {
  557. pageNum: 1,
  558. pageSize: 8,
  559. materialType: null,
  560. materialMediaId: null,
  561. createdAt: null,
  562. materialUrl: null,
  563. materialGroupId: null,
  564. companyId: null,
  565. corpId: null,
  566. textContent: null,
  567. title: null,
  568. createName: null,
  569. sendCount: null,
  570. groupType:"1",
  571. },
  572. //副框副列选择
  573. activeName:"1",
  574. //分组弹出
  575. group:{
  576. open:false,
  577. title:"",
  578. },
  579. // 表单参数
  580. form: {},
  581. // 表单校验
  582. rules: {
  583. title: [
  584. { required: true, message: "标题不能为空", trigger: "blur" }
  585. ],
  586. materialGroupId: [
  587. { required: true, message: "分组名称不能为空", trigger: "blur" }
  588. ],
  589. createName: [
  590. { required: true, message: "创建人不能为空", trigger: "blur" }
  591. ],
  592. materialUrl:[
  593. {required: true, message: "值不能为空", trigger: "blur"}
  594. ]
  595. }
  596. };
  597. },
  598. created() {
  599. getMyQwCompanyList().then(response => {
  600. this.myQwCompanyList = response.data;
  601. if(this.myQwCompanyList!=null){
  602. this.queryParams.corpId=this.myQwCompanyList[0].dictValue
  603. this.getList();
  604. }
  605. });
  606. //素材类型字典
  607. this.getDicts("sys_qw_material_type").then(response => {
  608. this.materialTypeOptions = response.data;
  609. });
  610. },
  611. methods: {
  612. updateCorpId(){
  613. this.getList();
  614. },
  615. /** 查询素材库列表 */
  616. getList() {
  617. this.loading = true;
  618. listMaterial(this.queryParams).then(response => {
  619. this.materialList = response.rows;
  620. this.total = response.total;
  621. this.loading = false;
  622. this.textMaterialsList= this.materialList.filter(item => item.materialType === 'text');
  623. this.imageMaterialsList= this.materialList.filter(item => item.materialType === 'image');
  624. this.imagetextMaterialsList= this.materialList.filter(item => item.materialType === 'imagetext');
  625. this.voiceMaterialsList= this.materialList.filter(item => item.materialType === 'voice');
  626. this.videoMaterialsList= this.materialList.filter(item => item.materialType === 'video');
  627. this.fileMaterialsList= this.materialList.filter(item => item.materialType === 'file');
  628. });
  629. },
  630. textMaterials() {
  631. this.queryParams.materialType = 'text';
  632. this.getList();
  633. },
  634. imageMaterials() {
  635. this.queryParams.materialType='image';
  636. this.getList();
  637. },
  638. imagetextMaterials() {
  639. this.queryParams.materialType='imagetext';
  640. this.getList();
  641. },
  642. voiceMaterials() {
  643. this.queryParams.materialType='voice';
  644. this.getList();
  645. },
  646. videoMaterials() {
  647. this.queryParams.materialType='video';
  648. this.getList();
  649. },
  650. fileMaterials() {
  651. this.queryParams.materialType='file';
  652. this.getList();
  653. },
  654. // 取消按钮
  655. cancel() {
  656. this.open = false;
  657. this.reset();
  658. },
  659. //下载文件
  660. downloadUrl(materialUrl) {
  661. // 直接返回文件 URL
  662. return materialUrl;
  663. },
  664. handleAvatarSuccess(res, file) {
  665. if(res.code==200){
  666. this.form.materialUrl=res.url;
  667. // this.self.$forceUpdate()
  668. }
  669. else{
  670. this.msgError(res.msg);
  671. }
  672. },
  673. beforeAvatarUploadVoice(file){
  674. const isLt1M = file.size / 1024 / 1024 < 2;
  675. if (!isLt1M) {
  676. this.$message.error('上传大小不能超过 2MB!');
  677. }
  678. return isLt1M;
  679. },
  680. beforeAvatarUploadVideo(file){
  681. const isLt1M = file.size / 1024 / 1024 < 10;
  682. if (!isLt1M) {
  683. this.$message.error('上传大小不能超过 10MB!');
  684. }
  685. return isLt1M;
  686. },
  687. beforeAvatarUploadFile(file){
  688. const isLt1M = file.size / 1024 / 1024 < 20;
  689. if (!isLt1M) {
  690. this.$message.error('上传大小不能超过 20MB!');
  691. }
  692. return isLt1M;
  693. },
  694. //选择小板块方法
  695. handleClick(row){
  696. switch (row.name) {
  697. case '1':
  698. this.resetParam();
  699. this.getList();
  700. break;
  701. case '2':
  702. this.textMaterials();
  703. break;
  704. case '3':
  705. this.imageMaterials();
  706. break;
  707. case '4':
  708. this.imagetextMaterials()
  709. break;
  710. case '5':
  711. this.voiceMaterials();
  712. break;
  713. case '6':
  714. this.videoMaterials()
  715. break;
  716. case '7':
  717. this.fileMaterials()
  718. break;
  719. default:
  720. this.resetParam();
  721. this.getList();
  722. break;
  723. }
  724. },
  725. //选择的分组
  726. selectGroupScreen(row){
  727. this.queryParams.materialGroupId=row
  728. this.getList();
  729. },
  730. //删除分组后刷新页面
  731. refreshIndex(){
  732. this.resetParam();
  733. this.reset();
  734. this.getList();
  735. },
  736. openImageViewer(url) {
  737. // 打开大图预览对话框
  738. this.dialogImageUrl=url
  739. this.dialogVisible = true;
  740. },
  741. // 表单重置 console.log(this.deptOptions)
  742. reset() {
  743. this.form = {
  744. materialId: null,
  745. materialType: null,
  746. materialMediaId: null,
  747. createdAt: null,
  748. materialUrl: null,
  749. materialGroupId: null,
  750. companyId: null,
  751. corpId: null,
  752. textContent: null,
  753. createTime: null,
  754. title: null,
  755. titleUrl: null,
  756. updateTime: null,
  757. createName: null,
  758. sendCount: null,
  759. groupType:"1",
  760. };
  761. this.resetForm("form");
  762. },
  763. /** 参数重置 */
  764. resetParam(){
  765. this.queryParams={
  766. pageNum: 1,
  767. pageSize: 8,
  768. materialType: null,
  769. materialMediaId: null,
  770. createdAt: null,
  771. materialUrl: null,
  772. materialGroupId: null,
  773. companyId: null,
  774. corpId: null,
  775. textContent: null,
  776. title: null,
  777. createName: null,
  778. groupType:"1",
  779. };
  780. },
  781. /** 素材组选择 */
  782. materialGroupRow(){},
  783. /** 搜索按钮操作 */
  784. handleQuery() {
  785. this.queryParams.pageNum = 1;
  786. this.getList();
  787. },
  788. /** 重置按钮操作 */
  789. resetQuery() {
  790. this.reset();
  791. this.resetParam();
  792. this.resetForm("queryForm");
  793. this.queryParams.corpId= this.myQwCompanyList[0].dictValue
  794. this.handleQuery();
  795. this.$refs.MaterialGroup.resetRow();
  796. },
  797. // 多选框选中数据
  798. handleSelectionChange(selection) {
  799. console.log("选中的数据",selection)
  800. this.ids = selection.map(item => item.materialId)
  801. this.single = selection.length!==1
  802. this.multiple = !selection.length
  803. },
  804. /** 新增按钮操作 */
  805. handleAdd() {
  806. this.reset();
  807. this.open = true;
  808. this.title = "添加素材库";
  809. this.form.materialType='text'
  810. this.meaterialGroupOptions=this.$refs.MaterialGroup.materialGroupList;
  811. },
  812. /** 新增分组操作 */
  813. handleAddGroup() {
  814. this.reset();
  815. this.group.open = true;
  816. this.group.title = "添加企业微信素材分组";
  817. },
  818. /** 修改按钮操作 */
  819. handleUpdate(row) {
  820. this.reset();
  821. const materialId = row.materialId || this.ids
  822. getMaterial(materialId).then(response => {
  823. this.form = response.data;
  824. this.open = true;
  825. this.title = "修改素材库";
  826. this.meaterialGroupOptions=this.$refs.MaterialGroup.materialGroupList;
  827. });
  828. },
  829. /** 提交按钮 */
  830. submitForm() {
  831. this.$refs["form"].validate(valid => {
  832. this.form.corpId=this.queryParams.corpId;
  833. if (valid) {
  834. if (this.form.materialId != null) {
  835. this.open = false;
  836. let loadingRock = this.$loading({
  837. lock: true,
  838. text: '正在执行中请稍后~!',
  839. spinner: 'el-icon-loading',
  840. background: 'rgba(0, 0, 0, 0.7)'
  841. });
  842. updateMaterial(this.form).then(response => {
  843. this.msgSuccess("修改成功");
  844. this.getList();
  845. }).finally(res=>{
  846. loadingRock.close();
  847. });
  848. } else {
  849. this.open = false;
  850. let loadingRock = this.$loading({
  851. lock: true,
  852. text: '正在执行中请稍后~~',
  853. spinner: 'el-icon-loading',
  854. background: 'rgba(0, 0, 0, 0.7)'
  855. });
  856. addMaterial(this.form).then(response => {
  857. this.msgSuccess("新增成功");
  858. this.getList();
  859. loadingRock.close();
  860. }).finally(res=>{
  861. loadingRock.close();
  862. });
  863. }
  864. }
  865. });
  866. },
  867. /** 删除按钮操作 */
  868. handleDelete(row) {
  869. const materialIds = row.materialId || this.ids;
  870. this.$confirm('是否确认删除素材库编号为"' + materialIds + '"的数据项?', "警告", {
  871. confirmButtonText: "确定",
  872. cancelButtonText: "取消",
  873. type: "warning"
  874. }).then(function() {
  875. return delMaterial(materialIds);
  876. }).then(() => {
  877. this.getList();
  878. this.msgSuccess("删除成功");
  879. }).catch(() => {});
  880. },
  881. /** 导出按钮操作 */
  882. handleExport() {
  883. const queryParams = this.queryParams;
  884. this.$confirm('是否确认导出所有素材库数据项?', "警告", {
  885. confirmButtonText: "确定",
  886. cancelButtonText: "取消",
  887. type: "warning"
  888. }).then(() => {
  889. this.exportLoading = true;
  890. return exportMaterial(queryParams);
  891. }).then(response => {
  892. this.download(response.msg);
  893. this.exportLoading = false;
  894. }).catch(() => {});
  895. }
  896. }
  897. };
  898. </script>
  899. <style scoped>
  900. .file-link-container {
  901. display: flex; /* 使用 Flexbox */
  902. justify-content: center; /* 水平居中 */
  903. align-items: center; /* 垂直居中 */
  904. height: 100px;
  905. width: 50px;
  906. }
  907. .text-container {
  908. max-height: 7.5em; /* 设置最大高度为6行,根据字体大小调整 */
  909. overflow-y: auto; /* 内容超出时显示滚动条 */
  910. line-height: 1.5em; /* 行高设置,确保每行高度一致 */
  911. }
  912. .custom-span-title {
  913. display: block; /* 确保元素是块级元素 */
  914. width: 500px;
  915. height: 45px; /* 设置固定高度 */
  916. overflow-y: auto; /* 超出高度时显示滚动条 */
  917. word-wrap: break-word; /* 自动换行 */
  918. word-break: break-all; /* 在必要时进行换行 */
  919. }
  920. </style>