ProductionResourceManage.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. <template>
  2. <div class="production-resource">
  3. <MenuPage cur-key="/personal_workbench/project" />
  4. <div class="production-resource-main">
  5. <div class="textbook-container">
  6. <MenuTree :id="select_node" :node-list="node_list" @selectNode="selectNode" />
  7. </div>
  8. <div class="textbook-chapter">
  9. <div class="textbook-chapter__header">
  10. <div class="courseware">
  11. <div class="operator flex">
  12. <span class="link" @click="handleAdd">上传</span>
  13. <span class="link" @click="handleDelete">删除</span>
  14. <span class="link" @click="handleSetInfo">设置信息</span>
  15. <span class="link" @click="handleChangeFile">更换文件</span>
  16. <span class="link" @click="handleMoveFile">移动文件</span>
  17. <span class="link" @click="handlePersonal">设置项目成员资源使用权限</span>
  18. <span class="link" @click="$router.push({ path: `/personal_workbench/project` })">返回项目列表</span>
  19. </div>
  20. </div>
  21. </div>
  22. <div class="search-box">
  23. <div class="search-left">
  24. <label
  25. v-for="(item, index) in type_list"
  26. :key="index"
  27. class="label-btn"
  28. :class="[type_index === index ? 'active' : '']"
  29. @click="changeType(index)"
  30. >
  31. {{ item.label }}
  32. </label>
  33. <el-input v-model="search_content" />
  34. <el-button type="primary" @click="queryList('')">查询</el-button>
  35. </div>
  36. <div class="search-right">
  37. <label>排序:</label>
  38. <el-select v-model="sort_value" placeholder="请选择">
  39. <el-option v-for="item in sort_list" :key="item.value" :label="item.label" :value="item.value" />
  40. </el-select>
  41. <SvgIcon
  42. :icon-class="isDesc ? 'sort-down' : 'sort-up'"
  43. size="16"
  44. style="cursor: pointer"
  45. @click="changeSort"
  46. />
  47. </div>
  48. </div>
  49. <div v-if="height > 0" v-loading="boxLoading" class="sources-box" :style="{ height: height + 'px' }">
  50. <div
  51. v-for="(item, index) in list"
  52. :key="index"
  53. class="sources-item"
  54. :class="[select_sources_id === item.id ? 'active' : '']"
  55. @click="selectSourceNode(item)"
  56. >
  57. <template v-if="type_index === 0"> <el-image :src="item.file_url" fit="contain" /></template>
  58. <template v-else-if="type_index === 1">
  59. <!-- <AudioLine
  60. ref="audioLine"
  61. :audio-id="'resource-audio-' + index"
  62. :mp3="item.file_url"
  63. :get-cur-time="getCurTime"
  64. :width="200"
  65. /> -->
  66. <!-- {{ item.media_duration }} -->
  67. </template>
  68. <template v-else-if="type_index === 2">
  69. <video
  70. class="sources-item-border"
  71. :src="item.file_url"
  72. width="100%"
  73. height="140px"
  74. :poster="item.video_preview_image_file_url"
  75. preload="none"
  76. ></video>
  77. </template>
  78. <template v-else-if="type_index === 3">
  79. <!-- <iframe
  80. class="sources-item-border"
  81. :src="item.new_path"
  82. width="100%"
  83. height="300px"
  84. frameborder="0"
  85. ></iframe> -->
  86. </template>
  87. <template v-else-if="type_index === 4"> </template>
  88. <template v-else-if="type_index === 5">
  89. <!-- <iframe
  90. class="sources-item-border"
  91. :src="item.new_path"
  92. width="100%"
  93. height="300px"
  94. frameborder="0"
  95. ></iframe> -->
  96. </template>
  97. <el-popover placement="bottom" width="300" trigger="hover">
  98. <div class="sources-info">
  99. <p class="name">名称:{{ item.name }}</p>
  100. <p class="label">标签:{{ item.label }}</p>
  101. <p class="name">简介:{{ item.intro }}</p>
  102. <p class="label">修改时间:{{ item.last_modify_time }}</p>
  103. <p class="label">文件大小:{{ item.file_size_desc }}</p>
  104. </div>
  105. <template #reference>
  106. <div class="sources-info">
  107. <p class="name">
  108. {{ item.name }}
  109. <SvgIcon
  110. v-show="
  111. item.file_id && (type_index === 5 || type_index === 3 || type_index === 2 || type_index === 1)
  112. "
  113. icon-class="uploadPreview"
  114. size="16"
  115. @click="viewDialog(item)"
  116. />
  117. </p>
  118. <b class="label">{{ item.label }}</b>
  119. </div>
  120. </template>
  121. </el-popover>
  122. </div>
  123. </div>
  124. <PaginationPage ref="pagination" :page-size="20" :total="total" @getList="queryList" />
  125. </div>
  126. </div>
  127. <!-- 上传 -->
  128. <el-dialog
  129. :visible.sync="sourceAddFlag"
  130. width="500px"
  131. append-to-body
  132. :show-close="true"
  133. title="上传资源"
  134. :close-on-click-modal="false"
  135. class="module-content"
  136. >
  137. <UploadFile
  138. v-if="sourceAddFlag"
  139. key="upload_resources"
  140. :type="'upload_resources_manager'"
  141. :total-size="20000"
  142. :file-list="file_list"
  143. :file-id-list="file_id_list"
  144. :label-text="labelText"
  145. :accept-file-type="acceptFileType"
  146. :icon-class="iconClass"
  147. :limit="limit"
  148. :single-size="200"
  149. :upload-tip="uploadTip"
  150. @updateFileList="updateFileList"
  151. />
  152. <footer style="text-align: right">
  153. <el-button @click="handleCancle">取 消</el-button>
  154. <el-button :loading="loading" type="primary" @click="submitAdd">确 定</el-button>
  155. </footer>
  156. </el-dialog>
  157. <!-- 更新信息 -->
  158. <el-dialog
  159. :visible.sync="sourceInfoFlag"
  160. width="500px"
  161. append-to-body
  162. :show-close="true"
  163. title="设置资源"
  164. :close-on-click-modal="false"
  165. >
  166. <el-form ref="form" label-width="80px" :model="sourceInfo">
  167. <el-form-item prop="name" label="名称">
  168. <el-input v-model="sourceInfo.name" />
  169. </el-form-item>
  170. <el-form-item prop="label" label="标签">
  171. <el-input v-model="sourceInfo.label" />
  172. </el-form-item>
  173. <el-form-item prop="intro" label="简介">
  174. <el-input v-model="sourceInfo.intro" type="textarea" />
  175. </el-form-item>
  176. <el-form-item style="text-align: right">
  177. <el-button @click="sourceInfoFlag = false">取 消</el-button>
  178. <el-button :loading="loading" type="primary" @click="submitSourceInfo">确 定</el-button>
  179. </el-form-item>
  180. </el-form>
  181. </el-dialog>
  182. <!-- 移动 -->
  183. <el-dialog
  184. :visible.sync="sourceMoveFlag"
  185. width="500px"
  186. append-to-body
  187. :show-close="true"
  188. title="移动文件"
  189. :close-on-click-modal="false"
  190. >
  191. <el-form ref="form" label-width="80px">
  192. <el-form-item prop="name" label="移动到">
  193. <el-cascader v-model="sourceMoveId" :props="{ checkStrictly: true }" :options="node_list" />
  194. </el-form-item>
  195. <el-form-item style="text-align: right">
  196. <el-button @click="sourceMoveFlag = false">取 消</el-button>
  197. <el-button :loading="loading" type="primary" @click="submitMoveSource">确 定</el-button></el-form-item
  198. >
  199. </el-form>
  200. </el-dialog>
  201. <el-dialog
  202. v-if="visible"
  203. :visible.sync="visible"
  204. :show-close="true"
  205. :close-on-click-modal="true"
  206. :modal-append-to-body="true"
  207. :append-to-body="true"
  208. :lock-scroll="true"
  209. width="80%"
  210. top="0"
  211. >
  212. <iframe v-if="visible" :src="newpath" width="100%" :height="iframeHeight" frameborder="0"></iframe>
  213. </el-dialog>
  214. </div>
  215. </template>
  216. <script>
  217. import MenuPage from '../common/menu.vue';
  218. import MenuTree from './components/MenuTree.vue';
  219. import {
  220. ChapterGetBookChapterStruct,
  221. MangerAddResource,
  222. MangerDeleteResource,
  223. MangerUpdateResourceFile,
  224. MangerUpdateResourceInfo,
  225. MangerMoveResource,
  226. } from '@/api/book';
  227. import { GetProjectBaseInfo } from '@/api/project';
  228. import PaginationPage from '@/components/PaginationPage.vue';
  229. import { PageQueryProjectResourceList } from '@/api/list';
  230. import UploadFile from './components/UploadFile.vue';
  231. import AudioLine from './components/AudioLine.vue';
  232. const Base64 = require('js-base64').Base64;
  233. import { getConfig } from '@/utils/auth';
  234. import { H5StartupFile, GetFileURLMap } from '@/api/app';
  235. export default {
  236. name: 'ProjectResourceManager',
  237. components: { MenuPage, MenuTree, PaginationPage, UploadFile, AudioLine },
  238. data() {
  239. return {
  240. book_id: this.$route.params.id,
  241. node_list: [],
  242. select_node: '',
  243. project_info: {}, // 项目基本信息
  244. type_list: [
  245. {
  246. value: 0,
  247. label: '图片',
  248. },
  249. {
  250. value: 1,
  251. label: '音频',
  252. },
  253. {
  254. value: 2,
  255. label: '视频',
  256. },
  257. {
  258. value: 3,
  259. label: 'H5 游戏',
  260. },
  261. {
  262. value: 4,
  263. label: '3D 模型',
  264. },
  265. {
  266. value: 5,
  267. label: '文本',
  268. },
  269. ], // 类型分类
  270. type_index: 0, // 类型索引
  271. sort_list: [
  272. {
  273. value: 'name',
  274. label: '名称',
  275. },
  276. {
  277. value: 'label',
  278. label: '标签',
  279. },
  280. {
  281. value: 'last_modify_time',
  282. label: '修改时间',
  283. },
  284. {
  285. value: 'file_size',
  286. label: '文件大小',
  287. },
  288. ], // 排序分类
  289. sort_value: '', // 排序值
  290. isDesc: false, // 排序是否为倒序
  291. select_sources_id: '', // 选中的资源id
  292. list: [],
  293. total: 0,
  294. search_content: '', // 查询内容
  295. height: 0,
  296. page_capacity: 20,
  297. cur_page: 1,
  298. sourceAddFlag: false, // 新增flag
  299. labelText: '资源',
  300. acceptFileType: '.jpg,.png,.jpeg',
  301. iconClass: '',
  302. file_id_list: [],
  303. file_list: [],
  304. loading: false,
  305. acceptFileTypeList: ['.jpg,.png,.jpeg', '.mp3', '.mp4', '.zip', '.fbx,.obj,.gltf,.glb', '.txt'],
  306. limit: 10,
  307. uploadTip: '',
  308. boxLoading: false,
  309. sourceInfoFlag: false, // 设置信息
  310. sourceInfo: {
  311. name: '',
  312. label: '',
  313. intro: '',
  314. },
  315. sourceMoveFlag: false,
  316. sourceMoveId: '',
  317. file_preview_url: getConfig() ? getConfig().doc_preview_service_address : '',
  318. visible: false,
  319. newpath: '',
  320. iframeHeight: `${window.innerHeight - 100}px`,
  321. };
  322. },
  323. created() {
  324. this.getProjectBaseInfo();
  325. },
  326. mounted() {
  327. this.height =
  328. document.getElementsByClassName('app-container')[0].clientHeight -
  329. document.getElementsByClassName('menu')[0].clientHeight -
  330. document.getElementsByClassName('textbook-chapter__header')[0].clientHeight -
  331. document.getElementsByClassName('search-box')[0].clientHeight -
  332. document.getElementsByClassName('el-pagination')[0].clientHeight -
  333. 30;
  334. },
  335. methods: {
  336. selectNode(nodeId) {
  337. this.select_node = nodeId;
  338. this.queryList('');
  339. },
  340. /**
  341. * 获取项目基本信息
  342. * @param {string} id - 项目ID
  343. */
  344. getProjectBaseInfo() {
  345. GetProjectBaseInfo({ id: this.book_id }).then(({ project_info }) => {
  346. this.project_info = project_info;
  347. this.getBookChapterStructExpandList(project_info.name);
  348. });
  349. },
  350. /**
  351. * 得到教材章节结构展开列表
  352. */
  353. getBookChapterStructExpandList(name) {
  354. ChapterGetBookChapterStruct({
  355. book_id: this.book_id,
  356. node_deep_mode: 0,
  357. is_contain_producer: 'false',
  358. is_contain_auditor: 'false',
  359. }).then(({ nodes }) => {
  360. this.node_list = [
  361. {
  362. auditor_desc: '',
  363. deep: 1,
  364. id: '',
  365. is_courseware: 'false',
  366. is_leaf: 'false',
  367. is_leaf_chapter: 'false',
  368. level_index: '0',
  369. label: name,
  370. nodes,
  371. children: nodes,
  372. value: '',
  373. },
  374. ];
  375. this.handleData(this.node_list[0], 1);
  376. });
  377. },
  378. // 递归
  379. handleData(data, nodeIndex) {
  380. if (data.nodes) {
  381. data.nodes.forEach((item) => {
  382. item.label = item.name;
  383. item.pid = data.id;
  384. item.nodexIndex = nodeIndex;
  385. item.isLeaf = item.is_leaf === 'true';
  386. item.value = item.id;
  387. if (item.nodes) {
  388. item.children = item.nodes;
  389. item.lists = item.nodes;
  390. this.handleData(item, nodeIndex + 1);
  391. }
  392. });
  393. }
  394. },
  395. // 上传
  396. handleAdd() {
  397. this.limit = 10;
  398. this.uploadTip = '最多上传 10 个文件,多文件分批上传';
  399. this.sourceAddFlag = true;
  400. },
  401. // 删除
  402. handleDelete() {
  403. if (this.select_sources_id) {
  404. this.$confirm('确定要删除此条资源吗?', '提示', {
  405. confirmButtonText: '确定',
  406. cancelButtonText: '取消',
  407. type: 'warning',
  408. })
  409. .then(() => {
  410. MangerDeleteResource({ id: this.select_sources_id }).then(() => {
  411. this.$message.success('删除成功!');
  412. this.select_sources_id = '';
  413. this.queryList('');
  414. });
  415. })
  416. .catch(() => {});
  417. } else {
  418. this.$message.warning('请先选择文件');
  419. }
  420. },
  421. // 设置信息
  422. handleSetInfo() {
  423. if (this.select_sources_id) {
  424. this.sourceInfoFlag = true;
  425. } else {
  426. this.$message.warning('请先选择文件');
  427. }
  428. },
  429. // 更换文件
  430. handleChangeFile() {
  431. if (this.select_sources_id) {
  432. this.limit = 1;
  433. this.uploadTip = '只能上传 1 个文件';
  434. this.sourceAddFlag = true;
  435. } else {
  436. this.$message.warning('请先选择文件');
  437. }
  438. },
  439. // 设置项目成员资源使用权限
  440. handlePersonal() {},
  441. // 移动文件
  442. handleMoveFile() {
  443. if (this.select_sources_id) {
  444. this.sourceMoveFlag = true;
  445. } else {
  446. this.$message.warning('请先选择文件');
  447. }
  448. },
  449. // 切换类型
  450. changeType(index) {
  451. this.type_index = index;
  452. this.select_sources_id = '';
  453. this.file_list = [];
  454. this.file_id_list = [];
  455. this.acceptFileType = this.acceptFileTypeList[index];
  456. this.queryList('');
  457. },
  458. // 查询列表
  459. queryList(data) {
  460. this.boxLoading = true;
  461. this.list = [];
  462. if (data) {
  463. this.page_capacity = data.page_capacity;
  464. this.cur_page = data.cur_page;
  465. } else {
  466. this.page_capacity = 20;
  467. this.cur_page = 1;
  468. }
  469. let order_column_list = [];
  470. if (this.sort_value) {
  471. order_column_list = [this.isDesc ? `${this.sort_value}:desc` : this.sort_value];
  472. }
  473. let datas = {
  474. page_capacity: this.page_capacity,
  475. cur_page: this.cur_page,
  476. project_id: this.book_id,
  477. book_chapter_node_id: this.select_node,
  478. type: this.type_list[this.type_index].value,
  479. name_or_label: this.search_content,
  480. order_column_list,
  481. };
  482. PageQueryProjectResourceList(datas)
  483. .then(({ total_count, resource_list }) => {
  484. this.total = total_count;
  485. // if (this.type_index === 5) {
  486. // resource_list.forEach((item) => {
  487. // item.new_path = `${this.file_preview_url}onlinePreview?url=${Base64.encode(item.file_url)}`;
  488. // });
  489. // this.boxLoading = false;
  490. // }
  491. // else if (this.type_index === 3) {
  492. // resource_list.forEach((item) => {
  493. // H5StartupFile({ file_id: item.file_id, index_file_name: 'index.html' }).then((res) => {
  494. // item.new_path = res.file_url;
  495. // this.boxLoading = false;
  496. // });
  497. // });
  498. // }
  499. // else {
  500. this.boxLoading = false;
  501. // }
  502. this.list = resource_list;
  503. })
  504. .catch(() => {
  505. this.boxLoading = false;
  506. });
  507. },
  508. // 切换排序升序降序
  509. changeSort() {
  510. this.isDesc = !this.isDesc;
  511. },
  512. updateFileList({ file_list, file_id_list }) {
  513. this.file_list = file_list;
  514. this.file_id_list = file_id_list;
  515. },
  516. handleCancle() {
  517. this.sourceAddFlag = false;
  518. this.file_list = [];
  519. this.file_id_list = [];
  520. },
  521. // 确定新增资源
  522. submitAdd() {
  523. this.loading = true;
  524. if (this.limit === 1) {
  525. // 更换文件
  526. let data = {
  527. id: this.select_sources_id,
  528. file_id: this.file_id_list[0],
  529. };
  530. MangerUpdateResourceFile(data)
  531. .then((res) => {
  532. this.loading = false;
  533. this.sourceAddFlag = false;
  534. if (res.status === 1) {
  535. this.$message.success('更换成功');
  536. this.queryList('');
  537. }
  538. })
  539. .catch(() => {
  540. this.loading = false;
  541. });
  542. } else {
  543. // 上传文件
  544. let data = {
  545. project_id: this.book_id,
  546. book_chapter_node_id: this.select_node,
  547. type: this.type_list[this.type_index].value,
  548. file_id_list: this.file_id_list,
  549. };
  550. MangerAddResource(data)
  551. .then((res) => {
  552. this.loading = false;
  553. this.sourceAddFlag = false;
  554. if (res.status === 1) {
  555. this.file_list = [];
  556. this.file_id_list = [];
  557. this.queryList('');
  558. }
  559. })
  560. .catch(() => {
  561. this.loading = false;
  562. });
  563. }
  564. },
  565. // 点击资源
  566. selectSourceNode(item) {
  567. this.select_sources_id = item.id;
  568. this.sourceInfo = {
  569. name: item.name,
  570. label: item.label,
  571. intro: item.intro,
  572. };
  573. },
  574. getCurTime() {},
  575. // 更新信息确定按钮
  576. submitSourceInfo() {
  577. this.loading = true;
  578. MangerUpdateResourceInfo({
  579. id: this.select_sources_id,
  580. resource_info: this.sourceInfo,
  581. })
  582. .then((res) => {
  583. this.loading = false;
  584. this.sourceInfoFlag = false;
  585. if (res.status === 1) {
  586. this.$message.success('设置成功');
  587. this.queryList('');
  588. }
  589. })
  590. .catch(() => {
  591. this.loading = false;
  592. });
  593. },
  594. // 确定移动
  595. submitMoveSource() {
  596. this.loading = true;
  597. MangerMoveResource({
  598. id: this.select_sources_id,
  599. project_id: this.book_id,
  600. book_chapter_node_id: this.sourceMoveId[this.sourceMoveId.length - 1],
  601. })
  602. .then((res) => {
  603. this.loading = false;
  604. this.sourceMoveFlag = false;
  605. if (res.status === 1) {
  606. this.$message.success('移动成功');
  607. this.queryList('');
  608. }
  609. })
  610. .catch(() => {
  611. this.loading = false;
  612. });
  613. },
  614. // 预览
  615. viewDialog(file) {
  616. this.newpath = '';
  617. if (this.type_index === 3) {
  618. H5StartupFile({ file_id: file.file_id, index_file_name: 'index.html' }).then((res) => {
  619. this.newpath = res.file_url;
  620. this.visible = true;
  621. });
  622. } else {
  623. GetFileURLMap({ file_id_list: [file.file_id] }).then(({ url_map }) => {
  624. this.newpath = `${this.file_preview_url}onlinePreview?url=${Base64.encode(url_map[file.file_id])}`;
  625. this.visible = true;
  626. });
  627. }
  628. },
  629. },
  630. };
  631. </script>
  632. <style lang="scss" scoped>
  633. @use '@/styles/mixin.scss' as *;
  634. .production-resource {
  635. @include page-content(true);
  636. .production-resource-main {
  637. display: flex;
  638. flex: 1;
  639. width: 100%;
  640. height: 100%;
  641. background: #fff;
  642. border-top: $border;
  643. .textbook-container {
  644. display: flex;
  645. flex-direction: column;
  646. width: 320px;
  647. height: calc(100vh - 120px);
  648. overflow: auto;
  649. border-right: $border;
  650. }
  651. .textbook-chapter {
  652. display: flex;
  653. flex: 1;
  654. flex-direction: column;
  655. &__header {
  656. display: flex;
  657. align-items: center;
  658. justify-content: flex-end;
  659. height: 40px;
  660. padding: 6px 4px;
  661. margin-bottom: 5px;
  662. background-color: #fff;
  663. border-bottom: 1px solid #e5e6eb;
  664. .operator {
  665. display: flex;
  666. flex: 1;
  667. justify-content: flex-end;
  668. .link {
  669. + .link {
  670. &::before {
  671. margin-right: 8px;
  672. color: #999;
  673. content: '|';
  674. }
  675. }
  676. }
  677. }
  678. }
  679. .search-box {
  680. display: flex;
  681. justify-content: space-between;
  682. padding: 5px;
  683. .search-left {
  684. display: flex;
  685. flex-flow: wrap;
  686. gap: 5px;
  687. align-items: center;
  688. }
  689. .label-btn {
  690. padding: 5px 10px;
  691. cursor: pointer;
  692. background: #ebebeb;
  693. border-radius: 4px;
  694. &.active {
  695. color: #f90;
  696. background: #ffefd6;
  697. }
  698. }
  699. .el-input,
  700. .el-select {
  701. width: 120px;
  702. }
  703. }
  704. }
  705. .sources-box {
  706. display: flex;
  707. flex-flow: wrap;
  708. gap: 10px;
  709. place-content: start start;
  710. padding: 5px;
  711. overflow: auto;
  712. .sources-item {
  713. width: 200px;
  714. cursor: pointer;
  715. &-txt {
  716. width: 400px;
  717. }
  718. &-zip {
  719. width: 500px;
  720. }
  721. &-border {
  722. border: 1px solid #ccc;
  723. }
  724. .el-image {
  725. width: 100%;
  726. height: 140px;
  727. border: 1px solid #ccc;
  728. }
  729. .name,
  730. .label {
  731. margin: 5px 0;
  732. font-size: 14px;
  733. font-weight: normal;
  734. line-height: 1.3;
  735. }
  736. :deep .audioLine {
  737. background: #f2f3f5;
  738. }
  739. &.active {
  740. .el-image {
  741. border-color: #f90;
  742. }
  743. .name,
  744. .label {
  745. color: #f90;
  746. }
  747. }
  748. }
  749. }
  750. }
  751. }
  752. </style>