list.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <template>
  2. <hc-card class="hc-project-collect-gist-list">
  3. <template #header>
  4. <hc-date-year v-model="searchForm.startYear" v-model:end="searchForm.endYear" />
  5. <div class="relative ml-3 w-[300px]">
  6. <hc-search-input v-model="searchForm.targetPlan" text="搜索" color="#151921" @search="searchClick" />
  7. </div>
  8. </template>
  9. <template #extra>
  10. <div class="w-[120px]">
  11. <el-select v-model="searchForm.workFocusStage" filterable clearable block placeholder="项目阶段" @change="searchClick">
  12. <el-option v-for="item in projectStage" :key="item.value" :label="item.label" :value="item.value" />
  13. </el-select>
  14. </div>
  15. <el-button v-del-com:[delTableItem] type="danger" class="ml-2" :disabled="tableCheckKeys.length <= 0">批量删除</el-button>
  16. <el-button type="warning" class="ml-2" @click="importClick">导入</el-button>
  17. <el-button v-yes-com:[deriveTableItem] type="primary" class="ml-2" :disabled="tableCheckKeys.length <= 0">批量导出</el-button>
  18. </template>
  19. <HcTableList :datas="tableData" :loading="tableLoading" is-admin @tap="rowNameClick" @check="tableCheck" @change="searchClick" />
  20. <template #action>
  21. <hc-pages :pages="searchForm" @change="pageChange" />
  22. </template>
  23. <!-- 导入 -->
  24. <hc-dialog v-model="isImportShow" widths="24rem" title="项目数据导入" :footer="false" @close="modalImportClose">
  25. <hc-form-upload
  26. v-model="importFile" class="hc-form-drop-upload"
  27. :options="{ num: 1, type: 'list', drop: true }"
  28. :upload="{ options: uploadOptions }" @success="uploadSuccess"
  29. />
  30. <div class="hc-flex mt-5">
  31. <span class="mr-2">模板下载:</span>
  32. <el-button color="#20C98B" size="small" class="text-white" :loading="downloadTemplateLoading" @click="downloadTemplate">点击下载</el-button>
  33. </div>
  34. </hc-dialog>
  35. </hc-card>
  36. </template>
  37. <script setup>
  38. import { onMounted, ref } from 'vue'
  39. import { useClick } from 'hc-vue3-ui'
  40. import HcTableList from '../modules/gist-list.vue'
  41. import { getDictionaryData } from '~src/utils/tools'
  42. import { arrToId, getArrValue, newDownBlob } from 'js-fast-way'
  43. import mainApi from '~api/project/gist'
  44. //事件
  45. const emit = defineEmits(['edit'])
  46. onMounted(() => {
  47. getDataApi()
  48. })
  49. //获取接口数据
  50. const getDataApi = async () => {
  51. projectStage.value = await getDictionaryData('workFocusStage', true)
  52. searchClick()
  53. }
  54. //项目阶段
  55. const projectStage = ref([])
  56. //搜索条件
  57. const searchForm = ref({
  58. targetPlan: '', workFocusStage: null,
  59. current: 1, size: 20, total: 0,
  60. })
  61. const searchClick = () => {
  62. searchForm.value.current = 1
  63. getTableData()
  64. }
  65. //分页
  66. const pageChange = ({ current, size }) => {
  67. searchForm.value.current = current
  68. searchForm.value.size = size
  69. getTableData()
  70. }
  71. //表格数据
  72. const tableData = ref([])
  73. const tableLoading = ref(false)
  74. const getTableData = async () => {
  75. tableData.value = []
  76. tableLoading.value = true
  77. const { error, code, data } = await mainApi.page(searchForm.value)
  78. //处理数据
  79. tableLoading.value = false
  80. if (!error && code === 200) {
  81. tableData.value = getArrValue(data['records'])
  82. searchForm.value.total = data.total || 0
  83. } else {
  84. tableData.value = []
  85. searchForm.value.total = 0
  86. }
  87. }
  88. //表格被选择
  89. const tableCheckKeys = ref([])
  90. const tableCheck = (row) => {
  91. tableCheckKeys.value = row
  92. }
  93. //项目名称被点击
  94. const rowNameClick = (row) => {
  95. emit('edit', row)
  96. }
  97. //批量删除
  98. const delTableItem = async (_, resolve) => {
  99. const ids = arrToId(tableCheckKeys.value)
  100. const { error, code, msg } = await mainApi.del(ids)
  101. if (!error && code === 200) {
  102. window.$message.success('删除成功')
  103. resolve()
  104. searchClick()
  105. } else {
  106. window.$message.error(msg ?? '删除失败')
  107. }
  108. }
  109. //批量导出
  110. const deriveTableItem = async (_, resolve) => {
  111. const ids = arrToId(tableCheckKeys.value)
  112. const { error, val } = await mainApi.exportWorkfocus(ids)
  113. if (error) {
  114. window.$message?.error('数据异常')
  115. resolve()
  116. return
  117. }
  118. await newDownBlob(val)
  119. resolve()
  120. }
  121. //项目数据导入
  122. const isImportShow = ref(false)
  123. const importFile = ref('')
  124. const uploadOptions = {
  125. url: '/api/blade-attach/workfocus/import-workfocus',
  126. size: 120,
  127. accept: '.xls,.xlsx',
  128. accept_tip: '请选择Excel文件',
  129. }
  130. const importClick = () => {
  131. isImportShow.value = true
  132. }
  133. //下载模板
  134. const downloadTemplateLoading = ref(false)
  135. const downloadTemplate = async () => {
  136. await useClick() //这里要使用 await 来等待
  137. downloadTemplateLoading.value = true
  138. const { error, val } = await mainApi.exportTemplate()
  139. downloadTemplateLoading.value = false
  140. if (error) {
  141. window.$message?.error('数据异常')
  142. return
  143. }
  144. await newDownBlob(val)
  145. }
  146. //关闭项目数据导入弹窗
  147. const modalImportClose = () => {
  148. isImportShow.value = false
  149. }
  150. //上传完成
  151. const uploadSuccess = () => {
  152. setTimeout(() => {
  153. getTableData()
  154. modalImportClose()
  155. }, 1000)
  156. }
  157. </script>