com-attachment.php 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351
  1. <?php
  2. // 判断是门店模块
  3. if (
  4. strpos(Yii::$app->requestedRoute, "store/client/") !== false &&
  5. !empty(Yii::$app->store_user) &&
  6. class_exists(Yii::$app->store_user->identityClass) &&
  7. !empty(Yii::$app->store_user->identity)
  8. ) {
  9. $storeId = Yii::$app->store_user->identity['store_id'] ?? 0;
  10. }else {
  11. $storeId = 0;
  12. }
  13. if (
  14. strpos(Yii::$app->requestedRoute, "mch/client/") !== false &&
  15. !empty(Yii::$app->mch_user) &&
  16. class_exists(Yii::$app->mch_user->identityClass) &&
  17. !empty(Yii::$app->mch_user->identity)
  18. ) {
  19. $mchId = Yii::$app->mch_user->identity['mch_id'] ?? 0;
  20. }else {
  21. $mchId = 0;
  22. }
  23. $storeId = !is_numeric($storeId) ? 0 : $storeId;
  24. $mchId = !is_numeric($mchId) ? 0 : $mchId;
  25. ?>
  26. <style scoped>
  27. .com-attachment-list {
  28. padding: 5px;
  29. width: 100%;
  30. }
  31. .com-attachment-list * {
  32. box-sizing: border-box;
  33. }
  34. .com-attachment-list:after {
  35. clear: both;
  36. display: block;
  37. content: " ";
  38. }
  39. .com-attachment-item {
  40. display: inline-block;
  41. /*box-shadow: 0 0 0 1px rgba(0, 0, 0, .15);*/
  42. cursor: pointer;
  43. position: relative;
  44. float: left;
  45. width: 120px;
  46. height: 140px;
  47. margin: 7.5px;
  48. text-align: center;
  49. padding: 5px 5px 0;
  50. }
  51. .com-attachment-active-icon {
  52. position: absolute;
  53. right: 5px;
  54. top: 5px;
  55. font-size: 28px;
  56. color: #409EFF;
  57. text-shadow: 0 0 1px rgba(255, 255, 255, 0.75);
  58. opacity: 0;
  59. }
  60. .com-attachment-item:hover {
  61. /*del-box-shadow: 0 0 0 1px rgba(84, 200, 255, 0.41);*/
  62. }
  63. .com-attachment-item.checked,
  64. .com-attachment-item.selected {
  65. box-shadow: 0 0 0 1px #1ed0ff;
  66. background: #daf5ff;
  67. border-radius: 5px;
  68. }
  69. .com-attachment-item.checked .com-attachment-active-icon,
  70. .com-attachment-item.selected .com-attachment-active-icon {
  71. opacity: 1;
  72. }
  73. .com-attachment-item .com-attachment-img {
  74. display: block;
  75. }
  76. .com-attachment-item .file-type-icon {
  77. width: 30px;
  78. height: 30px;
  79. border-radius: 30px;
  80. background: #666;
  81. color: #fff;
  82. text-align: center;
  83. line-height: 30px;
  84. font-size: 24px;
  85. }
  86. .com-attachment-upload {
  87. box-shadow: none;
  88. border: 1px dashed #b2b6bd;
  89. height: 100px;
  90. width: 100px;
  91. margin: 12px;
  92. padding: 0;
  93. }
  94. .com-attachment-upload i {
  95. font-size: 30px;
  96. color: #909399;
  97. }
  98. .com-attachment-upload:hover {
  99. box-shadow: none;
  100. border: 1px dashed #409EFF;
  101. }
  102. .com-attachment-upload:hover i {
  103. color: #409EFF;
  104. }
  105. .com-attachment-upload:active {
  106. border: 1px dashed #20669c;
  107. }
  108. .com-attachment-upload:active i {
  109. color: #20669c;
  110. }
  111. .com-attachment-dialog .group-menu {
  112. border-right: none;
  113. width: 230px;
  114. }
  115. .com-attachment-dialog .group-menu .el-menu-item {
  116. padding-left: 10px !important;
  117. padding-right: 10px;
  118. }
  119. .com-attachment-dialog .group-menu .el-menu-item .el-button {
  120. padding: 3px 0;
  121. }
  122. .del-com-attachment-dialog .group-menu .el-menu-item .el-button:hover {
  123. background: #e2e2e2;
  124. }
  125. .com-attachment-dialog .group-menu .el-menu-item .el-button i {
  126. margin-right: 0;
  127. }
  128. .com-attachment-simple-upload {
  129. width: 100% !important;
  130. height: 120px;
  131. border: 1px dashed #e3e3e3;
  132. cursor: pointer;
  133. }
  134. .com-attachment-simple-upload:hover {
  135. background: rgba(0, 0, 0, .05);
  136. }
  137. .com-attachment-simple-upload i {
  138. font-size: 32px;
  139. }
  140. .com-attachment-video-cover {
  141. background-size: cover;
  142. background-position: center;
  143. width: 100%;
  144. height: 100%;
  145. }
  146. .com-attachment-video-info {
  147. background: rgba(0, 0, 0, .35);
  148. color: #fff;
  149. position: absolute;
  150. left: 0;
  151. bottom: 0;
  152. padding: 1px 3px;
  153. font-size: 14px;
  154. }
  155. .com-attachment-video-name {
  156. position: absolute;
  157. top: 100%;
  158. left: 0;
  159. width: 100%;
  160. font-size: 12px;
  161. white-space: nowrap;
  162. overflow: hidden;
  163. text-overflow: ellipsis;
  164. }
  165. .com-attachment-dialog .com-attachment-name {
  166. color: #666666;
  167. margin-top: 5px;
  168. font-size: 13px;
  169. word-break: break-all;
  170. text-overflow: ellipsis;
  171. display: -webkit-box;
  172. -webkit-box-orient: vertical;
  173. -webkit-line-clamp: 1;
  174. overflow: hidden;
  175. }
  176. .com-attachment-left {
  177. text-align: left;
  178. }
  179. .comattachment-copy {
  180. text-align: right;
  181. }
  182. .com-attachment-dialog .search {
  183. margin-top: 10px;
  184. margin-left: 20px;
  185. width: 250px;
  186. }
  187. .com-attachment-dialog .search .el-input__inner {
  188. border-right: 0;
  189. }
  190. .com-attachment-dialog .search .el-input__inner:hover {
  191. border: 1px solid #dcdfe6;
  192. border-right: 0;
  193. outline: 0;
  194. }
  195. .com-attachment-dialog .search .el-input__inner:focus {
  196. border: 1px solid #dcdfe6;
  197. border-right: 0;
  198. outline: 0;
  199. }
  200. .com-attachment-dialog .search .el-input-group__append {
  201. background-color: #fff;
  202. border-left: 0;
  203. width: 10%;
  204. padding: 0;
  205. }
  206. .com-attachment-dialog .search .el-input-group__append {
  207. background-color: #fff;
  208. border-left: 0;
  209. width: 10%;
  210. padding: 0;
  211. }
  212. .com-attachment-dialog .search .el-input-group__append .el-button {
  213. padding: 0;
  214. }
  215. .com-attachment-dialog .search .el-input-group__append .el-button {
  216. margin: 0;
  217. }
  218. .com-attachment-dialog .scrollbar {
  219. height: 100%;
  220. }
  221. .com-attachment-dialog .scrollbar .el-scrollbar__wrap {
  222. overflow-y: hidden;
  223. }
  224. .features_tree{
  225. display: flex;
  226. justify-content: center;
  227. }
  228. .features_tree button{
  229. flex: 1;
  230. }
  231. .el-tree-node{
  232. margin-top: 10px;
  233. }
  234. </style>
  235. <template id="com-attachment">
  236. <div class="com-attachment">
  237. <el-dialog class="com-attachment-dialog"
  238. :title="title ? title : '选择文件'"
  239. :visible.sync="dialogVisible"
  240. @opened="dialogOpened"
  241. :close-on-click-modal="false"
  242. :width="simple?'30%':'70%'"
  243. top="10vh"
  244. append-to-body>
  245. <el-tabs type="card" v-model="videoType" v-if="type == 'videos' && !simple && isComGoods" @tab-click="changeTab">
  246. <el-tab-pane label="普通视频" name="videos"></el-tab-pane>
  247. <el-tab-pane label="大视频" name="bigVideos" v-if="videoConfigInfo.is_show_long_vide === 1"></el-tab-pane>
  248. </el-tabs>
  249. <template v-if="simple">
  250. <com-upload-oss v-if="videoType == 'bigVideos'" class="com-attachment-simple-upload" :config="videoConfigInfo" v-loading="uploading" :disabled="uploading"
  251. @start="handleStart" @success="handleSuccessBig" :multiple="true" :max="1" :params="uploadParams" :fields="uploadFields" :accept="accept"
  252. flex="main:center cross:center">
  253. <div v-if="uploading">{{uploadCompleteFilesNum}}/{{uploadFilesNum}}</div>
  254. <i v-else class="el-icon-upload"></i>
  255. </com-upload-oss>
  256. <com-upload
  257. v-else
  258. class="com-attachment-simple-upload"
  259. v-loading="uploading"
  260. :disabled="uploading"
  261. @start="handleStart"
  262. @success="handleSuccess"
  263. @complete="handleComplete"
  264. :multiple="true"
  265. :max="10"
  266. :params="uploadParams"
  267. :fields="uploadFields"
  268. :accept="accept"
  269. flex="main:center cross:center">
  270. <div v-if="uploading">{{uploadCompleteFilesNum}}/{{uploadFilesNum}}</div>
  271. <i v-else class="el-icon-upload"></i>
  272. </com-upload>
  273. </template>
  274. <template v-else>
  275. <div style="height: 0;overflow: hidden;">
  276. <canvas id="com-attachment-canvas" style="border: 1px solid #ccc;visibility: hidden;"></canvas>
  277. </div>
  278. <div flex="cross:center box:last" style="margin-bottom: 12px;">
  279. <div></div>
  280. <div flex="cross:center">
  281. <el-button v-if="!showEditBlock <?= $storeId == 0 ? '' : ' && currentAttachmentStoreId == ' . $storeId ?> <?= $mchId == 0 ? '' : ' && currentAttachmentMchId == ' . $mchId ?>" @click="showEditBlock=true">开启编辑</el-button>
  282. <template v-if="showEditBlock <?= $storeId == 0 ? '' : ' && currentAttachmentStoreId == ' . $storeId ?> <?= $mchId == 0 ? '' : ' && currentAttachmentMchId == ' . $mchId ?>">
  283. <el-button @click="showEditBlock=false" style="margin-right: 12px">退出编辑模式</el-button>
  284. <el-checkbox border v-model="selectAll"
  285. @change="selectAllChange"
  286. label="全选"
  287. style="margin-right: 12px;margin-bottom: 0"></el-checkbox>
  288. <el-button :loading="deleteLoading" @click="deleteItems" type="danger" plain style="margin-right: 12px">删除</el-button>
  289. <el-dropdown v-loading="moveLoading"
  290. trigger="click"
  291. :split-button="true"
  292. @command="moveItems">
  293. <span>移动至</span>
  294. <el-dropdown-menu slot="dropdown" style="max-height: 500px;overflow-y: auto">
  295. <el-dropdown-item
  296. v-for="(item, index) in groupList"
  297. <?= $storeId == 0 || $mchId == 0 ? '' : 'v-if="item.store_id == ' . $storeId . ' || item.mch_id == ' . $mchId . '"' ?>
  298. :command="index"
  299. :key="index"
  300. >
  301. {{item.name}}
  302. </el-dropdown-item>
  303. </el-dropdown-menu>
  304. </el-dropdown>
  305. </template>
  306. </div>
  307. </div>
  308. <div flex="box:first" style="border: 1px solid #e3e3e3;margin-bottom: 10px;min-height: 300px">
  309. <div style="border-right: 1px solid #e3e3e3">
  310. <el-menu class="group-menu"
  311. mode="vertical"
  312. v-loading="groupListLoading">
  313. <el-scrollbar style="height:450px;width:100%">
  314. <el-menu-item index="all" @click="switchGroup(-1)">
  315. <i class="el-icon-tickets"></i>
  316. <span>全部</span>
  317. </el-menu-item>
  318. <div class="features_tree">
  319. <!-- @click="addNode" -->
  320. <el-button type="text" v-if="!is_recycle" @click="addNode"><i class="el-icon-circle-plus"></i>添加</el-button>
  321. <el-button type="text" v-if="!is_recycle <?= $storeId == 0 || $mchId == 0 ? '' : ' && currentAttachmentStoreId == ' . $storeId . ' || currentAttachmentMchId == ' . $mchId ?>" @click="editNode"><i class="el-icon-edit"></i>编辑</el-button>
  322. <el-button type="text" v-if="is_recycle" @click="deleteGroups(is_recycle,2)"><i class="el-icon-refresh"></i>还原</el-button>
  323. <el-button <?= $storeId == 0 || $mchId == 0 ? '' : 'v-if="currentAttachmentStoreId == ' . $storeId . ' || currentAttachmentMchId == ' . $mchId . '"' ?> type="text" @click="deleteGroups(is_recycle,is_recycle?3:1)"><i class="el-icon-delete"></i>删除</el-button>
  324. </div>
  325. <el-alert
  326. v-if="<?= $storeId == 0 || $mchId == 0 ? 'false' : 'true' ?>"
  327. title="注:需在自己门店或多商户目录才能上传图片,可点击【添加】按钮创建目录"
  328. type="info"
  329. :closable="false">
  330. </el-alert>
  331. <el-tree
  332. :data="data2"
  333. highlight-current
  334. @node-click="handleNodeClick"
  335. :props="defaultProps"
  336. >
  337. <span slot-scope="{ node, data }">
  338. <i class="el-icon-tickets"></i>
  339. <span>{{ node.label }}</span>
  340. </span>
  341. </el-tree>
  342. </el-scrollbar>
  343. </el-menu>
  344. </div>
  345. <div v-loading="loading" flex="dir:top">
  346. <el-scrollbar class="scrollbar">
  347. <div class="search" style="margin-right: 12px">
  348. <el-input placeholder="请输入名称搜索" v-model="p_keyword"
  349. @keyup.enter.native="picSearch"
  350. class="input-with-select">
  351. <el-button @click="picSearch" slot="append" icon="el-icon-search"></el-button>
  352. </el-input>
  353. </div>
  354. <div class="com-attachment-list">
  355. <div class="com-attachment-item com-attachment-upload" :style="{'width': (type == 'videos' || type === 'bigVideos') ? '165px' : ''}" <?= $storeId == 0 || $mchId == 0 ? '' : 'v-if="currentAttachmentStoreId == ' . $storeId . ' && currentAttachmentMchId == ' . $mchId . '"' ?>>
  356. <com-upload-oss v-if="videoType == 'bigVideos'" :config="videoConfigInfo" v-loading="uploading" :disabled="uploading" @start="handleStart" @success="handleSuccessBig" :multiple="true" :max="1" :params="uploadParams" :fields="uploadFields" :accept="accept" flex="main:center cross:center" style="width: 100%;height: 100px">
  357. <div v-if="uploading">{{uploadCompleteFilesNum}}/{{uploadFilesNum}}</div>
  358. <i v-else class="el-icon-upload"></i>
  359. </com-upload-oss>
  360. <com-upload
  361. v-else
  362. v-loading="uploading"
  363. :disabled="uploading"
  364. @start="handleStart"
  365. @success="handleSuccess"
  366. @complete="handleComplete"
  367. :multiple="true"
  368. :max="10"
  369. :params="uploadParams"
  370. :fields="uploadFields"
  371. :accept="accept"
  372. flex="main:center cross:center"
  373. style="width: 100%;height: 100px">
  374. <div v-if="uploading">{{uploadCompleteFilesNum}}/{{uploadFilesNum}}</div>
  375. <i v-else class="el-icon-upload"></i>
  376. </com-upload>
  377. </div>
  378. <template v-for="(item, index) in attachments">
  379. <el-tooltip class="item" effect="dark" :content="String(item.old_name)" placement="top"
  380. :open-delay="1">
  381. <div
  382. :key="index"
  383. :class="'com-attachment-item'+((item.checked&&!showEditBlock)?' checked':'')+(item.selected&&showEditBlock?' selected':'')"
  384. :style="{'width': (item.upload_type == 'videos' || item.upload_type == 'bigVideos') ? '180px' : ''}"
  385. @click="handleClick(item)">
  386. <!-- 图片 -->
  387. <img v-if="item.upload_type == 'images'" class="com-attachment-img"
  388. :src="item.url"
  389. style="width: 100px;height: 100px;">
  390. <!-- 视频 -->
  391. <div v-if="item.upload_type == 'videos' || item.upload_type == 'bigVideos'" class="com-attachment-img"
  392. style="width: 170px;height: 76px;position: relative" @click="playVideo(item)">
  393. <div v-if="item.cover_pic_src"
  394. class="com-attachment-video-cover"
  395. :style="'background-image: url('+item.cover_pic_src+');'"></div>
  396. <video style="width: 100%; height: 100%; object-fit: cover;" error="预览图加载失败"
  397. :id="'app_attachment_'+ _uid + '_' + index"
  398. :src="item.url">
  399. </video>
  400. <!--
  401. <div class="com-attachment-video-info" style="margin-left: 24px;">
  402. <i class="el-icon-video-play"></i>
  403. <span>{{item.duration?item.duration:'--:--'}}</span>
  404. </div>
  405. -->
  406. </div>
  407. <!-- 音频 -->
  408. <div v-if="item.upload_type == 'voices'" class="com-attachment-img"
  409. style="width: 100px;height: 100px;position: relative">
  410. <!-- <div v-if="item.cover_pic_src"
  411. class="com-attachment-video-cover"
  412. :style="'background-image: url('+item.cover_pic_src+');'">
  413. </div> -->
  414. <span>{{item.old_name}}</span>
  415. </div>
  416. <!-- 文件 -->
  417. <div v-if="item.upload_type == 'files'" class="com-attachment-img"
  418. style="width: 100px;height: 100px;line-height: 100px;text-align: center">
  419. <i class="file-type-icon el-icon-document"></i>
  420. </div>
  421. <!-- pdf -->
  422. <div v-if="item.upload_type == 'pdf'" class="com-attachment-img"
  423. style="width: 100px;height: 100px;line-height: 100px;text-align: center">
  424. <img
  425. src="resources/img/common/pdf-cover.png"
  426. style="width: 100%;height: 100%;">
  427. </div>
  428. <div v-if="item.upload_type != 'voices'" class="com-attachment-name" :class="[item.upload_type == 'images' ? '' : 'com-attachment-left']">{{item.old_name}}</div>
  429. <i v-if="false" class="com-attachment-active-icon el-icon-circle-check"></i>
  430. <div v-if="item.upload_type == 'videos' || item.upload_type == 'bigVideos'">
  431. <div style="fontSize: 12px; color: #666666; display: flex; justify-content: space-between;">
  432. <span>{{ item.created_at|dateTimeFormat('Y-m-d H:i:s') }}</span>
  433. <span>{{ (item.size/(1024*1024)).toFixed(2) }}M</span>
  434. </div>
  435. <div class="comattachment-copy" v-if="isComGoods">
  436. <el-link class="copy_btn" style="fontSize: 12px;" type="primary" type="primary" :underline="false" @click="copyLink(item.url)">复制链接</el-link>
  437. </div>
  438. </div>
  439. </div>
  440. </el-tooltip>
  441. </template>
  442. </div>
  443. </el-scrollbar>
  444. <div style="padding: 5px;text-align: right;margin-top:auto">
  445. <el-pagination
  446. v-if="pagination"
  447. background
  448. @size-change="handleLoadMore"
  449. @current-change="handleLoadMore"
  450. :current-page.sync="page"
  451. :page-size="pagination.pageSize"
  452. layout="prev, pager, next, jumper"
  453. :total="pagination.total_count">
  454. </el-pagination>
  455. </div>
  456. </div>
  457. </div>
  458. <div style="text-align: right">
  459. <span v-if="showEditBlock" style="color: #909399">请先退出编辑模式</span>
  460. <el-button @click="confirm" type="primary" :disabled="showEditBlock">选定</el-button>
  461. </div>
  462. </template>
  463. </el-dialog>
  464. <el-dialog append-to-body title="分组管理" :visible.sync="addGroupVisible" :close-on-click-modal="false"
  465. width="25%">
  466. <el-form @submit.native.prevent label-width="80px" ref="groupForm" :model="groupForm"
  467. :rules="groupFormRule">
  468. <el-form-item label="分组名称" prop="name" style="margin-bottom: 22px;">
  469. <el-input v-model="groupForm.name" maxlength="8" show-word-limit></el-input>
  470. </el-form-item>
  471. <el-form-item style="text-align: right">
  472. <el-button type="primary" @click="groupFormSubmit('groupForm')" :loading="groupFormLoading">保存
  473. </el-button>
  474. </el-form-item>
  475. </el-form>
  476. </el-dialog>
  477. <el-dialog append-to-body title="添加目录" :visible.sync="dialogFormVisible" :close-on-click-modal="false">
  478. <el-form :model="form_dir" :rules="form_dir_rule">
  479. <el-form-item label="父级目录" :label-width="formLabelWidth">
  480. <el-cascader
  481. expand-trigger="hover"
  482. :options="<?= $storeId == 0 || $mchId == 0 ? 'data2' : 'dirTree' ?>"
  483. v-model="selectedOptions2"
  484. :props="{ checkStrictly: true, value: 'id' }"
  485. clearable
  486. @change="handleChange">
  487. </el-cascader>
  488. </el-form-item>
  489. <el-form-item label="目录名称" :label-width="formLabelWidth">
  490. <el-input v-model="form_dir.name" auto-complete="off"></el-input>
  491. </el-form-item>
  492. </el-form>
  493. <div slot="footer" class="dialog-footer">
  494. <el-button @click="dialogFormVisible = false">取 消</el-button>
  495. <el-button type="primary" @click="postNode('add')">确 定</el-button>
  496. </div>
  497. </el-dialog>
  498. <el-dialog append-to-body title="编辑目录" :visible.sync="dialogFormVisibleEdit" :close-on-click-modal="false">
  499. <el-form :model="form_dir_s" :rules="form_dir_rules">
  500. <el-form-item label="父级目录" :label-width="formLabelWidth">
  501. <el-cascader
  502. expand-trigger="hover"
  503. :options="getOptions()"
  504. v-model="selectedOptions3"
  505. :props="{ checkStrictly: true, value: 'id' }"
  506. clearable
  507. @change="handleChange2">
  508. </el-cascader>
  509. </el-form-item>
  510. <el-form-item label="目录名称" :label-width="formLabelWidth">
  511. <el-input v-model="form_dir_s.name" auto-complete="off"></el-input>
  512. </el-form-item>
  513. </el-form>
  514. <div slot="footer" class="dialog-footer">
  515. <el-button @click="dialogFormVisibleEdit = false">取 消</el-button>
  516. <el-button type="primary" @click="postNode('edit')">确 定</el-button>
  517. </div>
  518. </el-dialog>
  519. <el-dialog append-to-body :visible.sync="videoPlayVisible" title="" @close="videoPlayVisible = false" width="42%">
  520. <video width="100%" height="460" :src="videoPlayUrl" autoplay controls></video>
  521. </el-dialog>
  522. <div style="line-height: normal;" @click="dialogVisible = !dialogVisible"
  523. :style="'display:'+(display?display:'inline-block')">
  524. <slot></slot>
  525. </div>
  526. </div>
  527. </template>
  528. <script>
  529. Vue.component('com-attachment', {
  530. template: '#com-attachment',
  531. props: {
  532. display: String,
  533. title: String,
  534. multiple: Boolean,
  535. max: Number,
  536. params: Object,
  537. simple: {
  538. type: Boolean,
  539. value: false,
  540. },
  541. type: {
  542. type: String,
  543. default: 'images',
  544. },
  545. value: {
  546. type: String,
  547. default: '',
  548. },
  549. openDialog: {
  550. type: Boolean,
  551. default: false,
  552. },
  553. },
  554. computed: {
  555. accept: {
  556. get() {
  557. if (this.type === 'images') {
  558. return 'image/*';
  559. }
  560. if (this.type === 'videos') {
  561. return 'video/*';
  562. }
  563. if (this.type === 'pdf') {
  564. return '.pdf';
  565. }
  566. return '*/*';
  567. },
  568. },
  569. },
  570. watch: {
  571. type(newVal, oldVal) {
  572. this.type = newVal;
  573. this.uploadFields.upload_type = this.type;
  574. },
  575. openDialog(newVal, oldVal) {
  576. this.dialogVisible = newVal;
  577. },
  578. dialogVisible(newVal, oldVal) {
  579. if (!newVal) {
  580. this.$emit("closed");
  581. }
  582. },
  583. keyword(newVal, oldVal) {
  584. const groupList = this.groupList;
  585. let arr = [];
  586. groupList.map(v => {
  587. if (v.label.indexOf(newVal) !== -1) {
  588. arr.push(v);
  589. }
  590. });
  591. this.groupItem = arr;
  592. }
  593. },
  594. data() {
  595. return {
  596. isComGoods: true,
  597. videoType: 'videos',
  598. canvas: null,
  599. uploading: false,
  600. dialogVisible: false,
  601. videoPlayVisible: false,
  602. videoPlayUrl: '',
  603. loading: true,
  604. loadingMore: false,
  605. noMore: false,
  606. attachments: [],
  607. checkedAttachments: [],
  608. uploadParams: {},
  609. uploadFields: {
  610. upload_type: this.type
  611. },
  612. uploadCompleteFilesNum: 0,
  613. uploadFilesNum: 0,
  614. page: 0,
  615. addGroupVisible: false,
  616. noMall: true,
  617. groupList: [],
  618. groupItem: [],
  619. groupListLoading: false,
  620. groupForm: {
  621. id: null,
  622. name: '',
  623. },
  624. groupFormRule: {
  625. name: [
  626. {required: true, message: '请填写分组名称。',}
  627. ],
  628. },
  629. groupFormLoading: false,
  630. showEditBlock: false,
  631. selectAll: false,
  632. deleteLoading: false,
  633. moveLoading: false,
  634. currentAttachmentGroupId: null,
  635. currentAttachmentStoreId: null,
  636. currentAttachmentMchId: null,
  637. video: null,
  638. keyword: '',
  639. pagination: null,
  640. p_keyword: '',
  641. data2: [],
  642. dirTree: [],
  643. defaultProps: {
  644. children: 'children',
  645. label: 'label'
  646. },
  647. dialogFormVisible: false,
  648. dialogFormVisibleEdit: false,
  649. form_dir: {
  650. name: '',
  651. parent_id:'',
  652. },
  653. form_dir_rule: {
  654. name: [
  655. {required: true, message: '请填写名称',}
  656. ],
  657. },
  658. form_dir_s: {
  659. id:'',
  660. parent_id: '',
  661. name: '',
  662. },
  663. form_dir_rules: {
  664. name: [
  665. {required: true, message: '请填写名称',}
  666. ],
  667. },
  668. formLabelWidth: '120px',
  669. selectedOptions: [],
  670. selectedOptions2: [],
  671. select_name:'全部',
  672. is_recycle:0,
  673. pppid: [],
  674. selectedOptions3: [],
  675. videoConfigInfo: {},
  676. };
  677. },
  678. created() {
  679. console.log('Starting', this.type, this.accept)
  680. this.uploadConfig()
  681. },
  682. methods: {
  683. getOptions() {
  684. let data = JSON.parse(JSON.stringify(this.data2))
  685. let id = this.form_dir_s.id
  686. let pid = this.form_dir_s.parent_id
  687. let self = this
  688. var dismap = function (v, i) {
  689. if (v.children && v.children.length > 0) {
  690. v.children.map(dismap)
  691. }
  692. if (v.id == id) {
  693. v.disabled = true
  694. }
  695. if (v.id == pid) {
  696. v.disabled = true
  697. }
  698. if (self.isChildrenId(v.id)) {
  699. v.disabled = true
  700. }
  701. return v
  702. }
  703. return data.map(dismap)
  704. },
  705. /**
  706. * 作用是不能把当前元素选择到当前元素的子元素下面
  707. */
  708. isChildrenId(cid) {
  709. let id = this.form_dir_s.id
  710. let child = []
  711. let cids = []
  712. var getChildren = function(arr) {
  713. arr.forEach(item => {
  714. if (item.id == id) {
  715. child = item.children
  716. }
  717. if (item.children && item.children.length > 0) {
  718. getChildren(item.children)
  719. }
  720. })
  721. }
  722. var getChildrenId = function(arr) {
  723. arr.forEach(item => {
  724. if (item.id) {
  725. cids.push(item.id)
  726. }
  727. if (item.children && item.children.length > 0) {
  728. getChildrenId(item.children)
  729. }
  730. })
  731. }
  732. getChildren(this.data2)
  733. getChildrenId(child)
  734. return cids.find(function(ccc) {
  735. return ccc == cid
  736. })
  737. },
  738. picSearch() {
  739. this.page = 1;
  740. this.loading = true;
  741. this.loadGroups();
  742. this.loadList({});
  743. },
  744. dialogOpened() {
  745. if (this.simple) {
  746. return;
  747. }
  748. this.page = 1;
  749. this.loading = true;
  750. this.loadGroups();
  751. this.loadList({});
  752. },
  753. deleteItems() {
  754. const itemIds = [];
  755. for (let i in this.attachments) {
  756. if (this.attachments[i].selected) {
  757. itemIds.push(this.attachments[i].id);
  758. }
  759. }
  760. if (!itemIds.length) {
  761. this.$message.warning('请先选择需要删除的图片。');
  762. return;
  763. }
  764. this.$confirm('确认删除所选的' + itemIds.length + '张图片?', '提示', {
  765. type: 'warning'
  766. }).then(() => {
  767. this.deleteLoading = true;
  768. this.$request({
  769. params: {
  770. r: 'common/file/delete'
  771. },
  772. method: 'post',
  773. data: {
  774. ids: itemIds,
  775. },
  776. }).then(e => {
  777. this.deleteLoading = false;
  778. if (e.data.code === 0) {
  779. this.$message.success(e.data.msg);
  780. for (let i in itemIds) {
  781. for (let j in this.attachments) {
  782. if (this.attachments[j].id == itemIds[i]) {
  783. this.attachments.splice(j, 1);
  784. break;
  785. }
  786. }
  787. }
  788. } else {
  789. this.$message.error(e.data.msg);
  790. }
  791. }).catch(e => {
  792. this.deleteLoading = false;
  793. });
  794. }).catch(() => {
  795. });
  796. },
  797. selectAllChange(value) {
  798. for (let i in this.attachments) {
  799. this.attachments[i].selected = value;
  800. }
  801. },
  802. selectItem(item) {
  803. item.selected = item.selected ? false : true;
  804. },
  805. moveItems(index) {
  806. const itemIds = [];
  807. for (let i in this.attachments) {
  808. if (this.attachments[i].selected) {
  809. itemIds.push(this.attachments[i].id);
  810. }
  811. }
  812. if (!itemIds.length) {
  813. this.$message.warning('请先选择需要移动的图片。');
  814. return;
  815. }
  816. this.$confirm('确认移动所选的' + itemIds.length + '张图片?', '提示', {
  817. type: 'warning'
  818. }).then(() => {
  819. this.moveLoading = true;
  820. this.$request({
  821. params: {
  822. r: 'common/file/move'
  823. },
  824. method: 'post',
  825. data: {
  826. ids: itemIds,
  827. attachment_group_id: this.groupItem[index].id,
  828. },
  829. }).then(e => {
  830. this.moveLoading = false;
  831. if (e.data.code === 0) {
  832. this.$message.success(e.data.msg);
  833. this.switchGroup(index);
  834. } else {
  835. this.$message.error(e.data.msg);
  836. }
  837. }).catch(e => {
  838. this.moveLoading = false;
  839. });
  840. }).catch(() => {
  841. });
  842. },
  843. loadGroups() {
  844. this.groupListLoading = true;
  845. this.$request({
  846. params: {
  847. r: 'common/file/group-list',
  848. is_recycle: 0,
  849. type: this.type == 'videos' ? this.videoType : this.type,
  850. },
  851. }).then(e => {
  852. this.groupListLoading = false;
  853. if (e.data.code === 0) {
  854. this.noMall = e.data.data.no_mall ? e.data.data.no_mall : false;
  855. this.groupItem = e.data.data.list;
  856. this.groupList = e.data.data.list;
  857. this.data2 = e.data.data.arr;
  858. } else {
  859. this.$message.error(e.data.msg);
  860. }
  861. }).catch(e => {
  862. this.groupListLoading = false;
  863. });
  864. },
  865. groupFormSubmit(formName) {
  866. this.$refs[formName].validate(valid => {
  867. if (valid) {
  868. this.groupFormLoading = true;
  869. this.$request({
  870. params: {
  871. r: 'common/attachment/group-update',
  872. },
  873. method: 'post',
  874. data: Object.assign({}, this.groupForm, {'type': this.type}),
  875. }).then(e => {
  876. this.groupFormLoading = false;
  877. if (e.data.code === 0) {
  878. this.$message.success(e.data.msg);
  879. this.addGroupVisible = false;
  880. if (this.groupForm.edit_index > -1) {
  881. this.groupItem[this.groupForm.edit_index] = e.data.data;
  882. } else {
  883. this.groupItem.push(e.data.data);
  884. }
  885. } else {
  886. this.$message.error(e.data.msg);
  887. }
  888. }).catch(e => {
  889. this.groupFormLoading = false;
  890. });
  891. }
  892. })
  893. },
  894. switchGroup(index) {
  895. this.attachments = [];
  896. this.page = 0;
  897. this.noMore = false;
  898. this.loading = true;
  899. this.uploadParams = {
  900. attachment_group_id: index > -1 ? this.groupItem[index].id : null,
  901. };
  902. this.currentAttachmentGroupId = index > -1 ? this.groupItem[index].id : null;
  903. this.loadList({});
  904. },
  905. changeTab() {
  906. this.loadGroups();
  907. this.loadList({});
  908. },
  909. loadList(params) {
  910. this.noMore = false;
  911. this.selectAll = false;
  912. params['r'] = 'common/file/selector';
  913. params['page'] = this.page;
  914. params['attachment_group_id'] = this.currentAttachmentGroupId;
  915. params['upload_type'] = this.type == 'videos' ? this.videoType : this.type;
  916. params['is_recycle'] = 0;
  917. params['keyword'] = this.p_keyword;
  918. this.$request({
  919. params: params,
  920. }).then(e => {
  921. if (e.data.code === 0) {
  922. if (!e.data.data.list.length) {
  923. this.noMore = true;
  924. }
  925. for (let i in e.data.data.list) {
  926. e.data.data.list[i].checked = false;
  927. e.data.data.list[i].selected = false;
  928. e.data.data.list[i].duration = null;
  929. }
  930. //this.attachments = this.attachments.concat(e.data.data.list);
  931. this.attachments = e.data.data.list;
  932. this.pagination = e.data.data.pagination;
  933. this.pagination.pageSize = e.data.data.page_size;
  934. this.pagination.total_count = e.data.data.count;
  935. this.checkedAttachments = [];
  936. this.loading = false;
  937. this.loadingMore = false;
  938. this.updateVideo();
  939. } else {
  940. this.$message.error(e.data.msg);
  941. this.dialogVisible = false;
  942. }
  943. }).catch(e => {
  944. });
  945. },
  946. handleClick(item) {
  947. if (this.showEditBlock) {
  948. this.selectItem(item);
  949. return;
  950. }
  951. if (item.checked) {
  952. item.checked = false;
  953. for (let i in this.checkedAttachments) {
  954. if (item.id === this.checkedAttachments[i].id) this.checkedAttachments.splice(i, 1);
  955. }
  956. return;
  957. }
  958. if (this.multiple) {
  959. let checkedCount = 0;
  960. for (let i in this.attachments) if (this.attachments[i].checked) checkedCount++;
  961. if (this.max && !item.checked && checkedCount >= this.max) return;
  962. item.checked = true;
  963. this.checkedAttachments.push(item);
  964. } else {
  965. for (let i in this.attachments) this.attachments[i].checked = false;
  966. item.checked = true;
  967. this.checkedAttachments = [item];
  968. }
  969. },
  970. confirm() {
  971. this.$emit('selected', this.checkedAttachments, this.params);
  972. this.dialogVisible = false;
  973. const urls = [];
  974. for (let i in this.checkedAttachments) {
  975. urls.push(this.checkedAttachments[i].url);
  976. }
  977. for (let i in this.attachments) {
  978. this.attachments[i].checked = false;
  979. }
  980. this.checkedAttachments = [];
  981. if (!urls.length) {
  982. return;
  983. }
  984. if (this.multiple) {
  985. this.$emit('input', urls);
  986. } else {
  987. this.$emit('input', urls[0]);
  988. }
  989. },
  990. // 上传开始
  991. handleStart(files) {
  992. this.uploading = true;
  993. this.uploadFilesNum = files.length;
  994. this.uploadCompleteFilesNum = 0;
  995. },
  996. // 成功上传
  997. handleSuccess(file) {
  998. console.log(file, 'file')
  999. if (file.response && file.response.data && file.response.data.code === 0) {
  1000. const newItem = {
  1001. checked: false,
  1002. selected: false,
  1003. created_at: file.response.data.data.created_at,
  1004. deleted_at: file.response.data.data.deleted_at,
  1005. id: `${file.response.data.data.id}`,
  1006. is_delete: file.response.data.data.is_delete,
  1007. mall_id: file.response.data.data.mall_id,
  1008. name: file.response.data.data.name,
  1009. old_name: file.response.data.data.old_name,
  1010. size: file.response.data.data.size,
  1011. storage_id: file.response.data.data.storage_id,
  1012. thumb_url: file.response.data.data.thumb_url,
  1013. type: file.response.data.data.type,
  1014. updated_at: file.response.data.data.updated_at,
  1015. url: file.response.data.data.url,
  1016. user_id: file.response.data.data.user_id,
  1017. duration: null,
  1018. cover_pic_src: null,
  1019. upload_type: file.response.data.data.upload_type
  1020. };
  1021. this.attachments.unshift(newItem);
  1022. this.uploadCompleteFilesNum++;
  1023. this.updateVideo();
  1024. }
  1025. },
  1026. handleSuccessBig() {
  1027. this.loadList({})
  1028. this.uploading = false;
  1029. },
  1030. // 上传完毕
  1031. handleComplete(files) {
  1032. this.uploading = false;
  1033. if (this.simple) {
  1034. let urls = [];
  1035. let attachments = [];
  1036. for (let i in files) {
  1037. if (files[i].response.data && files[i].response.data.code === 0) {
  1038. urls.push(files[i].response.data.data.url);
  1039. attachments.push(files[i].response.data.data);
  1040. }
  1041. }
  1042. if (!urls.length) {
  1043. return;
  1044. }
  1045. this.dialogVisible = false;
  1046. this.$emit('selected', attachments, this.params);
  1047. if (this.multiple) {
  1048. this.$emit('input', urls);
  1049. } else {
  1050. this.$emit('input', urls[0]);
  1051. }
  1052. }
  1053. },
  1054. handleLoadMore(currentPage) {
  1055. if (this.noMore) {
  1056. return;
  1057. }
  1058. this.page = currentPage;
  1059. this.loading = true;
  1060. this.loadingMore = true;
  1061. this.loadList({});
  1062. },
  1063. updateVideo() {
  1064. if (!this.canvas) {
  1065. this.canvas = document.getElementById('com-attachment-canvas');
  1066. }
  1067. for (let i in this.attachments) {
  1068. if (this.attachments[i].type == 2) {
  1069. if (this.attachments[i].duration) {
  1070. continue;
  1071. }
  1072. let times = 0;
  1073. let video = null;
  1074. const maxRetry = 10;
  1075. const id = 'app_attachment_' + this._uid + '_' + i;
  1076. const timer = setInterval(() => {
  1077. times++;
  1078. if (times >= maxRetry) {
  1079. clearInterval(timer);
  1080. }
  1081. if (!video) {
  1082. video = document.getElementById(id);
  1083. }
  1084. if (!video) {
  1085. return;
  1086. }
  1087. try {
  1088. const zoom = 0.15;
  1089. this.canvas.width = video.videoWidth * zoom;
  1090. this.canvas.height = video.videoHeight * zoom;
  1091. this.canvas.getContext('2d').drawImage(video, 0, 0, this.canvas.width, this.canvas.height);
  1092. this.attachments[i].cover_pic_src = this.canvas.toDataURL('image/jpg');
  1093. } catch (e) {
  1094. console.warn('获取视频封面异常: ', e);
  1095. }
  1096. if (video.duration && !isNaN(video.duration)) {
  1097. let m = Math.trunc(video.duration / 60);
  1098. let s = Math.trunc(video.duration) % 60;
  1099. m = m < 10 ? `0${m}` : `${m}`;
  1100. s = s < 10 ? `0${s}` : `${s}`;
  1101. this.attachments[i].duration = `${m}:${s}`;
  1102. clearInterval(timer);
  1103. }
  1104. }, 500);
  1105. }
  1106. }
  1107. },
  1108. editNode() {
  1109. if(this.form_dir_s.id == '') {
  1110. this.$message.error('请选择目录');
  1111. return false;
  1112. }
  1113. // 编辑时候自动选中当前的父级
  1114. let data = JSON.parse(JSON.stringify(this.data2))
  1115. let pid = 0
  1116. let id = this.form_dir_s.id
  1117. let pids = []
  1118. let getPid = function(arr, id) {
  1119. arr.forEach(item => {
  1120. if (item.id == id) {
  1121. pid = item.parent_id
  1122. if (pid > 0) {
  1123. pids.push(pid)
  1124. getPid(data, pid)
  1125. }
  1126. }
  1127. if (item.children && item.children.length > 0) {
  1128. getPid(item.children, id)
  1129. }
  1130. })
  1131. }
  1132. getPid(data, id)
  1133. pids.reverse()
  1134. this.selectedOptions3 = pids
  1135. this.dialogFormVisibleEdit = true;
  1136. },
  1137. handleChange(val) {
  1138. this.form_dir.parent_id = val;
  1139. },
  1140. handleChange2(val) {
  1141. this.form_dir_s.parent_id = val
  1142. },
  1143. postNode(type) {
  1144. let parent_id = this.form_dir.parent_id[this.form_dir.parent_id.length - 1]
  1145. let formData = {
  1146. name: type == 'add' ? this.form_dir.name : this.form_dir_s.name
  1147. }
  1148. if (type == 'add') {
  1149. formData.parent_id = parent_id
  1150. } else {
  1151. formData.id = this.form_dir_s.id
  1152. formData.parent_id = this.form_dir_s.parent_id[this.form_dir_s.parent_id.length - 1]
  1153. }
  1154. Object.assign(formData, {type: 0})
  1155. if (this.type == 'videos') {
  1156. formData.type = 1
  1157. }
  1158. this.$request({
  1159. params: {
  1160. r: 'common/file/save-group',
  1161. },
  1162. method: 'post',
  1163. data: formData,
  1164. }).then(e => {
  1165. this.groupListLoading = false;
  1166. if (e.data.code === 0) {
  1167. this.dialogFormVisible = false;
  1168. this.dialogFormVisibleEdit = false;
  1169. this.groupListLoading = true;
  1170. } else {
  1171. this.$message.error(e.data.msg);
  1172. }
  1173. this.dialogOpened();
  1174. }).catch(e => {
  1175. this.groupListLoading = false;
  1176. });
  1177. },
  1178. handleNodeClick(data) {
  1179. console.log(data);
  1180. this.uploadParams = {
  1181. attachment_group_id: data.id,
  1182. }
  1183. this.currentAttachmentGroupId = data.id;
  1184. this.form_dir_s.id = data.id;
  1185. this.form_dir_s.name = data.label;
  1186. this.select_name = data.label;
  1187. this.loading = true;
  1188. this.loadList({});
  1189. },
  1190. deleteGroups(is_recycle,type){ // 删除分组
  1191. let title;
  1192. let msg;
  1193. switch (type) {
  1194. case 1:
  1195. title = '是否确认将选中素材放入回收站中?删除的素材可通过回收站还原';
  1196. msg ='请选择要删除的目录';
  1197. break;
  1198. case 2:
  1199. title = '确认还原选择素材?';
  1200. msg ='请选择要还原的目录';
  1201. break;
  1202. case 3:
  1203. title = '素材删除后将无法恢复,您确认要彻底删除所选素材吗?';
  1204. msg ='请选择要删除的目录';
  1205. break;
  1206. default:
  1207. title = '';
  1208. msg = '';
  1209. break;
  1210. }
  1211. if(this.form_dir_s.id==''){
  1212. this.$message.error(msg);
  1213. return false;
  1214. }
  1215. this.$confirm(title, '提示', {
  1216. confirmButtonText: '确定',
  1217. cancelButtonText: '取消',
  1218. type: 'warning'
  1219. }).then(() => {
  1220. this.deleteLoading = true;
  1221. this.$request({
  1222. params: {r: 'common/file/del-group'},
  1223. method: 'POST',
  1224. data: {
  1225. id: this.form_dir_s,
  1226. //type 1回收 2还原 3删除
  1227. // type:type,
  1228. }
  1229. }).then(e => {
  1230. this.deleteLoading = false;
  1231. if (e.data.code === 0) {
  1232. this.$message.success(e.data.msg);
  1233. this.dialogOpened();
  1234. } else {
  1235. this.$message.error(e.data.msg);
  1236. }
  1237. }).catch(e => {
  1238. this.deleteLoading = false;
  1239. });
  1240. }).catch(() => {
  1241. });
  1242. },
  1243. /* 获取上传大视频配置 */
  1244. uploadConfig() {
  1245. const params = {};
  1246. params['r'] = 'mall/attachment/get-oss-config';
  1247. this.$request({
  1248. headers: {'Content-Type': 'multipart/form-data'},
  1249. params: params,
  1250. method: 'get',
  1251. }).then(e => {
  1252. if (e.data.code === 1) {
  1253. this.$message.error(e.data.msg);
  1254. }
  1255. this.videoConfigInfo = e.data.data
  1256. }).catch(e => {
  1257. console.log(e)
  1258. });
  1259. },
  1260. addNode() {
  1261. this.form_dir_s = {
  1262. id:'',
  1263. parent_id: '',
  1264. name: '',
  1265. }
  1266. this.dialogFormVisible = true
  1267. },
  1268. playVideo(item){
  1269. this.videoPlayUrl = item.url
  1270. this.videoPlayVisible = true
  1271. },
  1272. copyLink(url) { //复制链接
  1273. console.log(1111)
  1274. var clipboard = new ClipboardJS('.copy_btn', {
  1275. text: function() {
  1276. return url;
  1277. }
  1278. });
  1279. clipboard.on('success', (e) => {
  1280. this.$message.success('复制成功!');
  1281. clipboard.destroy()
  1282. });
  1283. clipboard.on('error', (e) => {
  1284. his.$message.error('复制失败!');
  1285. clipboard.destroy()
  1286. });
  1287. }
  1288. },
  1289. });
  1290. </script>