myResources.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. <template>
  2. <a-card>
  3. <!-- 标签页 -->
  4. <a-tabs v-model:activeKey="formState.verifyStatus" @change="tabChange">
  5. <a-tab-pane key="0" tab="未发布" v-if="!pageType"></a-tab-pane>
  6. <a-tab-pane key="1" tab="待审核"></a-tab-pane>
  7. <a-tab-pane key="2" tab="已发布" v-if="!pageType"></a-tab-pane>
  8. <!-- <a-tab-pane key="3" tab="已审核" v-if="pageType == 'economize'"></a-tab-pane> -->
  9. <a-tab-pane key="4" tab="回收站"></a-tab-pane>
  10. </a-tabs>
  11. <!-- 搜索和操作区域 -->
  12. <a-row :gutter="16" style="margin-bottom: 16px">
  13. <a-col :span="18">
  14. <a-input v-model:value="formState.fileName" placeholder="请输入资源名称" style="width: 200px" />
  15. <a-cascader
  16. style="width: 200px; margin-left: 8px"
  17. v-model:value="formState.majorIdName"
  18. :options="collegeMajorOptions"
  19. :fieldNames="{ label: 'name', value: 'parentId', children: 'children' }"
  20. placeholder="请选择院系"
  21. changeOnSelect
  22. @change="changeCollegeMajor"
  23. />
  24. <a-select
  25. v-model:value="formState.courseTypeName"
  26. style="width: 200px; margin-left: 8px"
  27. :options="courseTypeOptions"
  28. placeholder="请选择资源类型"
  29. />
  30. <a-select v-model:value="formState.suffix" placeholder="课件格式" style="width: 200px; margin-left: 8px">
  31. <a-select-option value="mp4">mp4</a-select-option>
  32. <a-select-option value="ppt">ppt</a-select-option>
  33. <a-select-option value="word">word</a-select-option>
  34. <a-select-option value="pdf">pdf</a-select-option>
  35. </a-select>
  36. <!-- <a-select
  37. v-model:value="formState.suffix"
  38. style="width: 200px; margin-left: 8px"
  39. :options="suffixTypeOptions"
  40. placeholder="请选择课件格式"
  41. /> -->
  42. <a-button type="primary" style="margin-left: 8px" @click="handleSearch">查询</a-button>
  43. <a-button style="margin-left: 8px" @click="handleReset">重置</a-button>
  44. </a-col>
  45. <a-col :span="6" style="text-align: right">
  46. <a-button
  47. type="primary"
  48. style="margin-right: 8px"
  49. v-if="formState.verifyStatus === '0'"
  50. @click="batchPublish"
  51. :disabled="selectedRowKeys.length === 0"
  52. >
  53. + 批量发布
  54. </a-button>
  55. <a-button type="primary" @click="showUploadModal">+ 上传资源</a-button>
  56. </a-col>
  57. </a-row>
  58. <!-- 表格 -->
  59. <a-table
  60. :columns="currentColumns"
  61. :data-source="dataSource"
  62. :pagination="false"
  63. :loading="loading"
  64. bordered
  65. :row-key="(record) => record.id"
  66. :row-selection="rowSelection"
  67. >
  68. <template #bodyCell="{ column, text, record }">
  69. <template
  70. v-if="
  71. ['fileName', 'collegeIdName', 'majorIdName', 'courseTypeName', 'suffix', 'uploadTime'].includes(
  72. column.dataIndex
  73. )
  74. "
  75. >
  76. <div class="multiLine-ellipsis" :title="text">{{ text || '-' }}</div>
  77. </template>
  78. <!-- 状态列 -->
  79. <template v-if="column.key === 'verifyStatus'">
  80. <span v-if="record.verifyStatus === '0'">
  81. <a-badge status="processing" text="处理中" />
  82. </span>
  83. <span v-else-if="record.verifyStatus === 'uploaded'">
  84. <a-badge status="success" text="已上传" />
  85. </span>
  86. <span v-else-if="record.verifyStatus === '1'">
  87. <a-badge status="default" text="待审核" />
  88. </span>
  89. <span v-else-if="record.verifyStatus === '2'">
  90. <a-badge status="success" text="已发布" />
  91. </span>
  92. <span v-else-if="record.verifyStatus === '4'">
  93. <a-badge status="error" text="已删除" />
  94. </span>
  95. </template>
  96. <!-- 操作列 -->
  97. <template v-else-if="column.key === 'action'">
  98. <div class="editable-cell">
  99. <a v-if="formState.verifyStatus === '0' && !pageType" @click="handlePublish(record)">发布</a>
  100. <a v-if="formState.verifyStatus === '1' && pageType == 'economize'" @click="handleAudit(record)">审核</a>
  101. <a v-if="formState.verifyStatus === '2' && pageType == 'economize'" @click="handlePermission(record)"
  102. >权限</a
  103. >
  104. <a v-if="formState.verifyStatus === '4'" @click="handleRestore(record)">恢复</a>
  105. <a-divider type="vertical" />
  106. <a-dropdown>
  107. <a class="ant-dropdown-link">
  108. 更多
  109. <DownOutlined />
  110. </a>
  111. <template #overlay>
  112. <a-menu>
  113. <a-menu-item>
  114. <a href="javascript:;" @click="handleView(record)">播放</a>
  115. </a-menu-item>
  116. <a-menu-item>
  117. <a href="javascript:;">下载</a>
  118. </a-menu-item>
  119. <a-menu-item v-if="formState.verifyStatus === '2'">
  120. <a href="javascript:;" @click="edit(record)">编辑</a>
  121. </a-menu-item>
  122. <a-menu-item>
  123. <a-popconfirm title="确认删除吗?" @confirm="resourcesDelete(record, 1)">
  124. <a href="javascript:;">删除</a>
  125. </a-popconfirm>
  126. </a-menu-item>
  127. </a-menu>
  128. </template>
  129. </a-dropdown>
  130. </div>
  131. </template>
  132. </template>
  133. </a-table>
  134. <div class="dis-flex-sb margin-top">
  135. <div>
  136. <a-button @click="selectAll">选择全部</a-button>
  137. <a-button @click="invertSelection" style="margin-left: 8px">反选选择</a-button>
  138. </div>
  139. <div>
  140. <CustomPagination
  141. :total="pagination.total"
  142. :current="pagination.pageNum"
  143. :pageSize="pagination.pageSize"
  144. :showQuickJumper="true"
  145. :showSizeChanger="true"
  146. :showTotal="(total) => `共 ${total} 条数据`"
  147. @change="handlePageChange"
  148. @showSizeChange="handlePageSizeChange"
  149. />
  150. </div>
  151. </div>
  152. <!-- 权限树模态框 -->
  153. <permissionTree v-if="permissionTreeVisible" @close="permissionTreeVisible = false"></permissionTree>
  154. <!-- 审核播放模态框 -->
  155. <auditModal
  156. v-if="auditModalVisible"
  157. :recordData="publishedData"
  158. :isAudit="auditState"
  159. @confirm="auditConfirm"
  160. @close="auditModalVisible = false"
  161. ></auditModal>
  162. <!-- 资源上传模态框 -->
  163. <resourceUpload
  164. v-if="uploadModalVisible"
  165. :isState="isState"
  166. :resourcesId="editResourcesId"
  167. @close="uploadModalVisible = false"
  168. @getList="getList"
  169. ></resourceUpload>
  170. <!-- 发布模态框 -->
  171. <releaseModal v-if="releaseVisible" @close="releaseVisible = false" @confirm="confirm"></releaseModal>
  172. </a-card>
  173. </template>
  174. <script setup>
  175. import { ref, onMounted } from 'vue'
  176. import { DownOutlined } from '@ant-design/icons-vue'
  177. import releaseModal from './releaseModal.vue'
  178. import resourceUpload from './resourceUpload.vue'
  179. import resourceAuditApi from '@/api/resourceAudit.js'
  180. import permissionTree from './permissionTree.vue'
  181. import auditModal from './auditModal.vue'
  182. import CustomPagination from '@/components/customPagination.vue'
  183. import tool from '@/utils/tool'
  184. // eslint-disable-next-line vue/no-setup-props-destructure
  185. const { pageType } = defineProps({
  186. pageType: {
  187. type: String,
  188. default: () => {}
  189. }
  190. })
  191. // 数据源
  192. const dataSource = ref([])
  193. //发布按钮状态
  194. const releaseVisible = ref(false)
  195. const permissionTreeVisible = ref(false) //权限树
  196. const auditModalVisible = ref(false) //播放审核
  197. const isPublishBulk = ref(false) //是否批量发布
  198. const loading = ref(false) // 列表loading
  199. const isState = ref(0) //是否是编辑 0:新增 1:编辑
  200. const editResourcesId = ref(null) //资源id
  201. // 搜索值
  202. const searchValue = ref('')
  203. //课程类型
  204. const courseTypeOptions = tool.dictList('COURSE_TYPE')
  205. const suffixTypeOptions = ref([])
  206. const pagination = reactive({
  207. pageSize: 10,
  208. pageNum: 1,
  209. total: 0
  210. })
  211. const formState = reactive({
  212. fileName: null,
  213. verifyStatus: '0',
  214. resourcesId: null,
  215. majorIdName: null,
  216. courseTypeName: null,
  217. suffix: null
  218. })
  219. // 添加选择状态
  220. const selectedRowKeys = ref([])
  221. const selectedRows = ref([])
  222. const publishedData = ref([]) //当前点击数据
  223. // 行选择配置
  224. const rowSelection = computed(() => {
  225. return {
  226. selectedRowKeys: selectedRowKeys.value,
  227. onChange: (keys, rows) => {
  228. selectedRowKeys.value = keys
  229. selectedRows.value = rows
  230. },
  231. onSelectAll: (selected, selectedRows, changeRows) => {
  232. if (selected) {
  233. // 全选当前页
  234. selectedRowKeys.value = dataSource.value.map((item) => item.id)
  235. selectedRows.value = dataSource.value
  236. } else {
  237. // 取消全选
  238. selectedRowKeys.value = []
  239. selectedRows.value = []
  240. }
  241. },
  242. onSelectInvert: () => {
  243. // 反选当前页
  244. const allKeys = dataSource.value.map((item) => item.id)
  245. const newSelectedKeys = allKeys.filter((key) => !selectedRowKeys.value.includes(key))
  246. selectedRowKeys.value = newSelectedKeys
  247. selectedRows.value = dataSource.value.filter((item) => newSelectedKeys.includes(item.id))
  248. }
  249. }
  250. })
  251. // 列定义
  252. const columnsUnpublished = [
  253. {
  254. title: '编号',
  255. align: 'center',
  256. dataIndex: 'fileId',
  257. key: 'fileId'
  258. },
  259. {
  260. title: '资源名称',
  261. align: 'center',
  262. dataIndex: 'fileName',
  263. key: 'fileName'
  264. },
  265. {
  266. title: '课件格式',
  267. align: 'center',
  268. dataIndex: 'suffix',
  269. key: 'suffix'
  270. },
  271. {
  272. title: '上传时间',
  273. dataIndex: 'uploadTime',
  274. align: 'center',
  275. key: 'uploadTime'
  276. },
  277. {
  278. title: '状态',
  279. align: 'center',
  280. key: 'verifyStatus'
  281. },
  282. {
  283. title: '操作',
  284. align: 'center',
  285. key: 'action'
  286. },
  287. {
  288. title: '资源缩略图',
  289. align: 'center',
  290. key: 'image'
  291. }
  292. ]
  293. const columnsPending = [
  294. {
  295. title: '编号',
  296. dataIndex: 'id',
  297. align: 'center',
  298. key: 'id'
  299. },
  300. {
  301. title: '资源名称',
  302. align: 'center',
  303. dataIndex: 'fileName',
  304. key: 'fileName'
  305. },
  306. {
  307. title: '所属院系',
  308. align: 'center',
  309. dataIndex: 'collegeAllIdName',
  310. key: 'collegeAllIdName'
  311. },
  312. // {
  313. // title: '所属课程',
  314. // align: 'center',
  315. // dataIndex: 'collegeIdName',
  316. // key: 'collegeIdName'
  317. // },
  318. // {
  319. // title: '所属专业',
  320. // align: 'center',
  321. // dataIndex: 'majorIdName',
  322. // key: 'majorIdName'
  323. // },
  324. {
  325. title: '资源类型',
  326. align: 'center',
  327. dataIndex: 'courseTypeName',
  328. key: 'courseTypeName'
  329. },
  330. {
  331. title: '资源格式',
  332. align: 'center',
  333. dataIndex: 'suffix',
  334. key: 'suffix'
  335. },
  336. {
  337. title: '上传时间',
  338. align: 'center',
  339. dataIndex: 'uploadTime',
  340. key: 'uploadTime'
  341. },
  342. {
  343. title: '状态',
  344. align: 'center',
  345. key: 'verifyStatus'
  346. },
  347. {
  348. title: '操作',
  349. align: 'center',
  350. key: 'action'
  351. },
  352. {
  353. title: '资源缩略图',
  354. align: 'center',
  355. key: 'image'
  356. }
  357. ]
  358. const columnsPublished = [...columnsPending]
  359. const columnsRecycle = [...columnsPending]
  360. const collegeMajorOptions = ref([])
  361. const currentColumns = computed(() => {
  362. switch (formState.verifyStatus) {
  363. case '0':
  364. return columnsUnpublished
  365. case '1':
  366. return columnsPending
  367. case '2':
  368. return columnsPublished
  369. case '3':
  370. return columnsPublished
  371. case '4':
  372. return columnsRecycle
  373. default:
  374. return []
  375. }
  376. })
  377. const getListData = () => {
  378. loading.value = true
  379. let params = {
  380. current: pagination.pageNum,
  381. size: pagination.pageSize,
  382. verifyStatus: formState.verifyStatus,
  383. fileName: formState.fileName,
  384. majorIdName: formState.majorIdName?.join(','),
  385. courseTypeName: formState.courseTypeName,
  386. suffix: formState.suffix
  387. }
  388. resourceAuditApi
  389. .page(params)
  390. .then((res) => {
  391. console.log(res, '资源审核列表')
  392. dataSource.value = res.data.records
  393. pagination.total = res.data.total
  394. loading.value = false
  395. })
  396. .catch((err) => {
  397. console.log(err)
  398. dataSource.value = []
  399. pagination.total = 0
  400. loading.value = false
  401. })
  402. }
  403. const getList = () => {
  404. getListData()
  405. }
  406. //院系组织查询
  407. const getOrgTreeSelector = () => {
  408. resourceAuditApi
  409. .orgTreeSelector()
  410. .then((res) => {
  411. console.log(res.data, '获取组织树选择器')
  412. collegeMajorOptions.value = res.data
  413. })
  414. .catch((err) => {
  415. console.log(err)
  416. })
  417. }
  418. // 方法
  419. const handleSearch = () => {
  420. console.log('Search:', searchValue.value)
  421. getListData()
  422. }
  423. const handleReset = () => {
  424. searchValue.value = null
  425. formState.majorIdName = null
  426. formState.fileName = null
  427. formState.courseTypeName = null
  428. formState.suffix = null
  429. getListData()
  430. }
  431. const tabChange = () => {
  432. dataSource.value = []
  433. getListData()
  434. }
  435. //发布
  436. const handlePublish = (record) => {
  437. publishedData.value = record
  438. releaseVisible.value = true
  439. isPublishBulk.value = false
  440. }
  441. // 批量发布方法
  442. const batchPublish = () => {
  443. if (selectedRows.value.length === 0) {
  444. message.warning('请至少选择一条记录')
  445. return
  446. }
  447. isState.value = 0
  448. isPublishBulk.value = true
  449. releaseVisible.value = true
  450. }
  451. // 全选当前页数据
  452. const selectAll = () => {
  453. selectedRowKeys.value = dataSource.value.map((item) => item.id)
  454. selectedRows.value = dataSource.value
  455. }
  456. // 反选当前页数据
  457. const invertSelection = () => {
  458. const allKeys = dataSource.value.map((item) => item.id)
  459. const newSelectedKeys = allKeys.filter((key) => !selectedRowKeys.value.includes(key))
  460. selectedRowKeys.value = newSelectedKeys
  461. selectedRows.value = dataSource.value.filter((item) => newSelectedKeys.includes(item.id))
  462. }
  463. //发布确定
  464. const confirm = (obj) => {
  465. console.log(obj, selectedRows.value, '传回来的数据')
  466. releaseVisible.value = false
  467. if (isPublishBulk.value) {
  468. // const batchParams = selectedRows.value.map((item) => ({
  469. // id: item.id,
  470. // coverImage: item.coverImage,
  471. // resourceDesc: item.resourceDesc,
  472. // verifyStatus: 1
  473. // }))
  474. const params = {
  475. ids: selectedRows.value.map((item) => item.id).join(','),
  476. coverImage: obj.coverImageId,
  477. resourceDesc: obj.resourceDesc,
  478. verifyStatus: 1
  479. }
  480. console.log(params, '批量发布参数')
  481. // handleRelease(params)
  482. } else {
  483. const params = {
  484. ids: publishedData.value.id,
  485. coverImage: obj.coverImageId,
  486. resourceDesc: obj.resourceDesc,
  487. verifyStatus: 1
  488. }
  489. console.log(params, '发布参数')
  490. handleRelease(params)
  491. }
  492. }
  493. // updateStatus接口调用
  494. const handleRelease = (Params) => {
  495. resourceAuditApi
  496. .updateStatus(Params)
  497. .then((res) => {
  498. getListData()
  499. selectedRowKeys.value = []
  500. })
  501. .catch((err) => {
  502. console.error(err)
  503. })
  504. }
  505. const auditState = ref(null)
  506. const handleAudit = (record) => {
  507. console.log('Audit:', record)
  508. publishedData.value = record
  509. auditState.value = true
  510. auditModalVisible.value = true
  511. }
  512. const handleView = (record) => {
  513. publishedData.value = record
  514. auditState.value = false
  515. auditModalVisible.value = true
  516. }
  517. const handlePermission = (record) => {
  518. console.log('Permission:', record)
  519. permissionTreeVisible.value = true
  520. }
  521. const auditConfirm = (obj) => {
  522. console.log('auditConfirm:', obj)
  523. const params = {
  524. ids: obj.id,
  525. verifyStatus: obj.auditResult
  526. }
  527. resourceAuditApi
  528. .updateStatus(params)
  529. .then((res) => {
  530. if (res.code == 200) {
  531. auditModalVisible.value = false
  532. }
  533. getListData()
  534. })
  535. .catch((err) => {
  536. console.error(err)
  537. })
  538. }
  539. const handleDelete = (record) => {
  540. console.log('Delete:', record)
  541. }
  542. const handleRestore = (record) => {
  543. const params = {
  544. ids: record.id,
  545. verifyStatus: 1
  546. }
  547. resourceAuditApi
  548. .updateStatus(params)
  549. .then((res) => {
  550. getListData()
  551. })
  552. .catch((err) => {
  553. console.error(err)
  554. })
  555. }
  556. //资源编辑
  557. const edit = (record) => {
  558. console.log('Restore:', record)
  559. uploadModalVisible.value = true
  560. isState.value = 1
  561. editResourcesId.value = record.id
  562. }
  563. //资源删除
  564. const resourcesDelete = (record) => {
  565. const params = {
  566. ids: record.id,
  567. verifyStatus: 4
  568. }
  569. if (formState.verifyStatus == 4) {
  570. resourceAuditApi
  571. .deletefile(params)
  572. .then((res) => {
  573. getListData()
  574. })
  575. .catch((err) => {
  576. console.error(err)
  577. })
  578. } else {
  579. resourceAuditApi
  580. .updateStatus(params)
  581. .then((res) => {
  582. getListData()
  583. })
  584. .catch((err) => {
  585. console.error(err)
  586. })
  587. }
  588. }
  589. // 上传资源模态框
  590. const uploadModalVisible = ref(false)
  591. // 显示上传模态框
  592. const showUploadModal = () => {
  593. isState.value = 0
  594. uploadModalVisible.value = true
  595. }
  596. // 翻页
  597. const handlePageChange = (page) => {
  598. pagination.pageNum = page
  599. getListData()
  600. }
  601. // 每页条数
  602. const handlePageSizeChange = (pageNum, size) => {
  603. pagination.pageNum = 1
  604. pagination.pageSize = size
  605. getListData()
  606. }
  607. onMounted(() => {
  608. if (pageType == 'economize') {
  609. formState.verifyStatus = '1'
  610. }
  611. getOrgTreeSelector()
  612. getListData()
  613. })
  614. </script>
  615. <style scoped>
  616. .editable-cell {
  617. position: relative;
  618. }
  619. .ant-dropdown-link {
  620. margin-left: 8px;
  621. }
  622. .upload-area {
  623. border: 2px dashed #3ca9f5;
  624. padding: 40px;
  625. text-align: center;
  626. }
  627. .upload-area p {
  628. margin: 10px 0;
  629. }
  630. .file-item {
  631. display: flex;
  632. align-items: center;
  633. margin: 10px 0;
  634. }
  635. .file-item .ant-progress {
  636. flex: 1;
  637. margin: 0 10px;
  638. }
  639. </style>