list.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <template>
  2. <hc-card class="hc-project-collect-admin-list" w-to="1660">
  3. <template #headerToSearch>
  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.searchValue" text="搜索" color="#151921" @search="searchClick">
  7. <!-- <template #prepend>
  8. <el-select v-model="searchForm.year" placeholder="年份" clearable style="width: 80px">
  9. <el-option label="2023" value="2023" />
  10. <el-option label="2024" value="2024" />
  11. </el-select>
  12. </template> -->
  13. </hc-search-input>
  14. </div>
  15. </template>
  16. <template #extraToHeader>
  17. <div class="w-[120px]">
  18. <el-select v-model="searchForm.projectStage" filterable clearable block placeholder="项目阶段" @change="searchClick">
  19. <el-option v-for="item in stateOptions" :key="item.value" :label="item.label" :value="item.value" />
  20. </el-select>
  21. </div>
  22. <div class="ml-2 w-[100px]">
  23. <el-select v-model="searchForm.projectType" filterable clearable block placeholder="项目类型" @change="searchClick">
  24. <el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value" />
  25. </el-select>
  26. </div>
  27. </template>
  28. <template #extra>
  29. <el-button type="success" class="ml-6" @click="reportsClick">生成报告</el-button>
  30. <el-button v-del-com:[delTableItem] type="danger" class="ml-2" :disabled="tableCheckKeys.length <= 0">批量删除</el-button>
  31. <el-button type="warning" class="ml-2" @click="importClick">导入</el-button>
  32. <el-button v-yes-com:[deriveTableItem] type="primary" class="ml-2" :disabled="tableCheckKeys.length <= 0">批量导出</el-button>
  33. </template>
  34. <HcTableList ref="tableRef" is-admin :datas="tableData" @tap="rowNameClick" @check="tableCheck" @change="searchClick" />
  35. <template #action>
  36. <div>建设规模:共计 xx 公里</div>
  37. <hc-pages :pages="searchForm" @change="pageChange" />
  38. </template>
  39. <!-- 生成报告 -->
  40. <hc-dialog v-model="isReportsShow" widths="24rem" title="生成报告" @close="reportsModalClose">
  41. <el-form ref="reportsFormRef" :model="reportsForm" :rules="reportsFormRules" label-position="top" label-width="auto">
  42. <el-row :gutter="20">
  43. <el-col :span="12">
  44. <el-form-item label="选择季度:" prop="key1">
  45. <el-select v-model="reportsForm.key1" placeholder="选择季度">
  46. <el-option label="一季度" value="1" />
  47. <el-option label="二季度" value="2" />
  48. <el-option label="三季度" value="3" />
  49. <el-option label="四季度" value="4" />
  50. </el-select>
  51. </el-form-item>
  52. </el-col>
  53. <el-col :span="12">
  54. <el-form-item label="选择月份:" prop="key2">
  55. <el-select v-model="reportsForm.key2" placeholder="选择月份">
  56. <template v-for="item in 12" :key="item">
  57. <el-option :label="`${item}月`" :value="item" />
  58. </template>
  59. </el-select>
  60. </el-form-item>
  61. </el-col>
  62. </el-row>
  63. </el-form>
  64. <template #footer>
  65. <div class="dialog-footer">
  66. <el-button size="large" @click="reportsModalClose">取消</el-button>
  67. <el-button :loading="reportsLoding" type="primary" @click="saveReportsClick">确定</el-button>
  68. </div>
  69. </template>
  70. </hc-dialog>
  71. <!-- 导入 -->
  72. <hc-dialog v-model="isImportShow" widths="24rem" title="项目数据导入" :footer="false" @close="modalImportClose">
  73. <hc-form-upload
  74. v-model="importFile" class="hc-form-drop-upload"
  75. :options="{ num: 0, type: 'list', drop: true }"
  76. :upload="{ options: uploadOptions }"
  77. />
  78. <div class="hc-flex mt-5">
  79. <span class="mr-2">模板下载:</span>
  80. <el-button color="#20C98B" size="small" class="text-white">点击下载</el-button>
  81. </div>
  82. </hc-dialog>
  83. </hc-card>
  84. </template>
  85. <script setup>
  86. import { onMounted, ref } from 'vue'
  87. import HcTableList from '../modules/project-list.vue'
  88. import { arrToId, getArrValue } from 'js-fast-way'
  89. import mainApi from '~api/project/project'
  90. import { getDictionaryData } from '~src/utils/tools'
  91. //事件
  92. const emit = defineEmits(['edit'])
  93. //渲染完成
  94. onMounted(async () => {
  95. await getProStation()
  96. await getProType()
  97. getTableData()
  98. })
  99. const tableRef = ref(null)
  100. //表格数据
  101. const tableData = ref([])
  102. const tableLoading = ref(false)
  103. const getTableData = async () => {
  104. tableData.value = []
  105. tableLoading.value = true
  106. const { error, code, data } = await mainApi.page(searchForm.value)
  107. //处理数据
  108. tableLoading.value = false
  109. if (!error && code === 200) {
  110. tableData.value = getArrValue(data['records'])
  111. searchForm.value.total = data.total || 0
  112. } else {
  113. tableData.value = []
  114. searchForm.value.total = 0
  115. }
  116. }
  117. //项目阶段
  118. const stateOptions = ref([])
  119. const getProStation = async () => {
  120. stateOptions.value = await getDictionaryData('projectStage', true)
  121. }
  122. //项目类型
  123. const typeOptions = ref([])
  124. const getProType = async () => {
  125. typeOptions.value = await getDictionaryData('projectType', true)
  126. }
  127. //搜索条件
  128. const searchForm = ref({
  129. startYear: '', endYear: '', searchValue: '', year: '', projectStage:'', projectType:'',
  130. current: 1, size: 20, total: 0,
  131. })
  132. const searchClick = () => {
  133. searchForm.value.current = 1
  134. getTableData()
  135. }
  136. //分页
  137. const pageChange = ({ current, size }) => {
  138. searchForm.value.current = current
  139. searchForm.value.size = size
  140. getTableData()
  141. }
  142. //表格被选择
  143. const tableCheckKeys = ref([])
  144. const tableCheck = (row) => {
  145. tableCheckKeys.value = row
  146. }
  147. //项目名称被点击
  148. const rowNameClick = (row) => {
  149. emit('edit', row)
  150. }
  151. //批量删除
  152. //批量删除
  153. const delTableItem = async (_, resolve) => {
  154. const ids = arrToId(tableCheckKeys.value)
  155. const { error, code, msg } = await mainApi.del(ids)
  156. if (!error && code === 200) {
  157. window.$message.success('删除成功')
  158. resolve()
  159. searchClick()
  160. } else {
  161. window.$message.error(msg ?? '删除失败')
  162. }
  163. }
  164. //批量导出
  165. const deriveTableItem = (_, resolve) => {
  166. tableRef.value?.batchExport()
  167. resolve()
  168. }
  169. //生成报告弹窗
  170. const isReportsShow = ref(false)
  171. const reportsClick = () => {
  172. isReportsShow.value = true
  173. }
  174. //生成报告表单
  175. const reportsFormRef = ref(null)
  176. const reportsForm = ref({})
  177. const reportsFormRules = {
  178. key1: {
  179. required: true,
  180. trigger: 'blur',
  181. message: '请选择季度',
  182. },
  183. key2: {
  184. required: true,
  185. trigger: 'blur',
  186. message: '请选择月份',
  187. },
  188. }
  189. //确认生成报告
  190. const reportsLoding = ref(false)
  191. const saveReportsClick = () => {
  192. isReportsShow.value = false
  193. }
  194. //关闭弹窗
  195. const reportsModalClose = () => {
  196. isReportsShow.value = false
  197. }
  198. //项目数据导入
  199. const isImportShow = ref(false)
  200. const importFile = ref([])
  201. const uploadOptions = {
  202. accept: '.xls,.xlsx',
  203. accept_tip: '请选择Excel文件',
  204. }
  205. const importClick = () => {
  206. isImportShow.value = true
  207. }
  208. //关闭项目数据导入弹窗
  209. const modalImportClose = () => {
  210. isImportShow.value = false
  211. }
  212. </script>
  213. <style lang="scss">
  214. .hc-project-collect-admin-list {
  215. .hc-card-action {
  216. display: flex;
  217. align-items: center;
  218. }
  219. }
  220. </style>