audit-list.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. <script setup>
  2. import { reactive, ref, watch, onBeforeMount } from "vue"
  3. import {
  4. getTableDataApi,
  5. getQueryCollegesApi,
  6. getQueryPeriodsApi,
  7. getQueryMajorsApi,
  8. getQueryClassesApi,
  9. getQueryPassTypesApi,
  10. toExamineClubApi,
  11. queryClubProcessExcelApi
  12. } from "@/api/alumniOrganization/audit-list"
  13. import { ElMessageBox } from "element-plus"
  14. import { usePagination } from "@/hooks/usePagination"
  15. const loading = ref(false)
  16. const { paginationData, handleCurrentChange, handleSizeChange } = usePagination()
  17. //#region 查
  18. const tableData = ref([])
  19. const searchFormRef = ref(null)
  20. const searchData = reactive({
  21. userName: undefined,
  22. createTime: null,
  23. status: undefined,
  24. statusOptions: undefined,
  25. name: undefined,
  26. college: undefined,
  27. collegeOptions: undefined,
  28. period: undefined,
  29. periodOptions: undefined,
  30. major: undefined,
  31. majorOptions: undefined,
  32. class: undefined,
  33. classOptions: undefined
  34. })
  35. /**
  36. * 获取 审核状态列表
  37. */
  38. const getQueryPassTypes = () => {
  39. loading.value = true
  40. getQueryPassTypesApi()
  41. .then(({ data }) => {
  42. searchData.statusOptions = data
  43. })
  44. .catch(() => {
  45. searchData.statusOptions = []
  46. })
  47. .finally(() => {
  48. loading.value = false
  49. })
  50. }
  51. /**
  52. * 获取 学院列表
  53. */
  54. const getQueryColleges = () => {
  55. loading.value = true
  56. getQueryCollegesApi()
  57. .then(({ data }) => {
  58. searchData.collegeOptions = data
  59. })
  60. .catch(() => {
  61. searchData.collegeOptions = []
  62. })
  63. .finally(() => {
  64. loading.value = false
  65. })
  66. }
  67. /**
  68. * 获取 学段列表
  69. */
  70. const getQueryPeriods = () => {
  71. if (searchData.college === undefined) {
  72. return
  73. }
  74. searchData.periodOptions = []
  75. searchData.period = ""
  76. searchData.majorOptions = []
  77. searchData.major = ""
  78. searchData.classOptions = []
  79. searchData.class = ""
  80. loading.value = true
  81. getQueryPeriodsApi({
  82. collegeId: searchData.college
  83. })
  84. .then(({ data }) => {
  85. searchData.periodOptions = data
  86. })
  87. .catch(() => {
  88. searchData.periodOptions = []
  89. })
  90. .finally(() => {
  91. loading.value = false
  92. })
  93. }
  94. /**
  95. * 获取 专业列表
  96. */
  97. const getQueryMajors = () => {
  98. if (searchData.period === undefined) {
  99. return
  100. }
  101. searchData.majorOptions = []
  102. searchData.major = ""
  103. searchData.classOptions = []
  104. searchData.class = ""
  105. loading.value = true
  106. getQueryMajorsApi({
  107. periodId: searchData.period
  108. })
  109. .then(({ data }) => {
  110. searchData.majorOptions = data
  111. })
  112. .catch(() => {
  113. searchData.majorOptions = []
  114. })
  115. .finally(() => {
  116. loading.value = false
  117. })
  118. }
  119. /**
  120. * 获取 班级列表
  121. */
  122. const getQueryClasses = () => {
  123. if (searchData.major === undefined) {
  124. return
  125. }
  126. searchData.classOptions = []
  127. searchData.class = ""
  128. loading.value = true
  129. getQueryClassesApi({
  130. majorId: searchData.major
  131. })
  132. .then(({ data }) => {
  133. searchData.classOptions = data
  134. })
  135. .catch(() => {
  136. searchData.classOptions = []
  137. })
  138. .finally(() => {
  139. loading.value = false
  140. })
  141. }
  142. /**
  143. * 获取 表格数据
  144. */
  145. const getTableData = () => {
  146. loading.value = true
  147. getTableDataApi({
  148. currentPage: paginationData.currentPage,
  149. pageCount: paginationData.pageSize,
  150. name: searchData.name,
  151. userName: searchData.userName,
  152. isPass: searchData.status,
  153. collegeId: searchData.college,
  154. periodId: searchData.period,
  155. majorId: searchData.major,
  156. classId: searchData.class,
  157. startTime: searchData.createTime ? searchData.createTime[0] : undefined,
  158. endTime: searchData.createTime ? searchData.createTime[1] : undefined
  159. })
  160. .then(({ data }) => {
  161. paginationData.total = data.totalCount
  162. tableData.value = data.list
  163. })
  164. .catch(() => {
  165. tableData.value = []
  166. })
  167. .finally(() => {
  168. loading.value = false
  169. })
  170. }
  171. /**
  172. * 导出 表格数据
  173. */
  174. const handleDownload = async () => {
  175. loading.value = true
  176. const res = await queryClubProcessExcelApi({
  177. name: searchData.name,
  178. userName: searchData.userName,
  179. isPass: searchData.status,
  180. college: searchData.college,
  181. period: searchData.period,
  182. major: searchData.major,
  183. class: searchData.class,
  184. startTime: searchData.createTime ? searchData.createTime[0] : undefined,
  185. endTime: searchData.createTime ? searchData.createTime[1] : undefined
  186. })
  187. // console.log(res)
  188. // 请求成功返回后,获取到Excel文件的二进制数据
  189. const blob = new Blob([res], { type: "application/vnd.ms-excel" })
  190. // 创建下载链接
  191. const downloadUrl = URL.createObjectURL(blob)
  192. // 创建一个隐藏的a标签,设置下载链接和文件名,模拟点击下载
  193. const link = document.createElement("a")
  194. link.style.display = "none"
  195. link.href = downloadUrl
  196. link.download = `审核列表数据_下载时间_${getCurrentDateTime()}.xlsx`
  197. document.body.appendChild(link)
  198. link.click()
  199. document.body.removeChild(link)
  200. loading.value = false
  201. }
  202. /**
  203. * 获取日期时间
  204. */
  205. const getCurrentDateTime = () => {
  206. const now = new Date()
  207. const year = now.getFullYear()
  208. const month = String(now.getMonth() + 1).padStart(2, "0") // 月份从0开始,需要加1
  209. const day = String(now.getDate()).padStart(2, "0")
  210. const hours = String(now.getHours()).padStart(2, "0")
  211. const minutes = String(now.getMinutes()).padStart(2, "0")
  212. const seconds = String(now.getSeconds()).padStart(2, "0")
  213. return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  214. }
  215. const handleSearch = () => {
  216. paginationData.currentPage === 1 ? getTableData() : (paginationData.currentPage = 1)
  217. }
  218. const resetSearch = () => {
  219. searchFormRef.value?.resetFields()
  220. handleSearch()
  221. }
  222. //#endregion
  223. /** 监听分页参数的变化 */
  224. watch([() => paginationData.currentPage, () => paginationData.pageSize], getTableData, { immediate: true })
  225. /** 通过 */
  226. const handlePass = (row) => {
  227. ElMessageBox.confirm("确认通过?", "提示", {
  228. confirmButtonText: "确定",
  229. cancelButtonText: "取消",
  230. type: "warning",
  231. closeOnPressEscape: false,
  232. closeOnClickModal: false
  233. }).then(() => {
  234. // 调用通过接口
  235. toExamineClubApi({
  236. id: row.id,
  237. isPass: 2
  238. })
  239. .then(() => {
  240. ElMessage.success("已审核通过")
  241. getTableData()
  242. })
  243. .catch(() => {})
  244. })
  245. }
  246. /** 拒绝 */
  247. const handleReject = (row) => {
  248. ElMessageBox.prompt("确认拒绝?", "提示", {
  249. confirmButtonText: "确定",
  250. cancelButtonText: "取消",
  251. inputPattern: /[\u4e00-\u9fa5a-zA-Z0-9_-]{2,100}/,
  252. inputErrorMessage: "请输入拒绝理由",
  253. closeOnPressEscape: false,
  254. closeOnClickModal: false
  255. }).then((content) => {
  256. // 调用拒绝接口
  257. toExamineClubApi({
  258. id: row.id,
  259. isPass: 3,
  260. passValue: content.value
  261. })
  262. .then(() => {
  263. ElMessage.success("已拒绝")
  264. getTableData()
  265. })
  266. .catch(() => {})
  267. })
  268. }
  269. onBeforeMount(() => {
  270. getQueryPassTypes()
  271. getQueryColleges()
  272. })
  273. </script>
  274. <template>
  275. <div class="app-container">
  276. <el-card v-loading="loading" header="审核列表">
  277. <div class="toolbar-wrapper">
  278. <el-form ref="searchFormRef" :inline="true" :model="searchData">
  279. <el-form-item prop="name" label="组织名称">
  280. <el-input v-model="searchData.name" clearable placeholder="请输入" style="width: 150px" />
  281. </el-form-item>
  282. <el-form-item prop="userName" label="申请人">
  283. <el-input v-model="searchData.userName" clearable placeholder="请输入" style="width: 150px" />
  284. </el-form-item>
  285. <el-form-item prop="status" label="审核状态">
  286. <el-select v-model="searchData.status" placeholder="请选择" style="width: 150px">
  287. <el-option v-for="item in searchData.statusOptions" :key="item.id" :label="item.name" :value="item.id" />
  288. </el-select>
  289. </el-form-item>
  290. <el-form-item prop="college" label="学院">
  291. <el-select
  292. v-model="searchData.college"
  293. placeholder="请选择"
  294. @change="getQueryPeriods"
  295. clearable
  296. style="width: 178px"
  297. >
  298. <el-option v-for="item in searchData.collegeOptions" :key="item.id" :label="item.name" :value="item.id" />
  299. </el-select>
  300. </el-form-item>
  301. <el-form-item prop="period" label="学段">
  302. <el-select
  303. v-model="searchData.period"
  304. placeholder="请选择"
  305. @change="getQueryMajors"
  306. clearable
  307. style="width: 178px"
  308. :disabled="!searchData.college"
  309. >
  310. <el-option v-for="item in searchData.periodOptions" :key="item.id" :label="item.name" :value="item.id" />
  311. </el-select>
  312. </el-form-item>
  313. <el-form-item prop="major" label="专业">
  314. <el-select
  315. v-model="searchData.major"
  316. placeholder="请选择"
  317. @change="getQueryClasses"
  318. clearable
  319. style="width: 178px"
  320. :disabled="!searchData.period"
  321. >
  322. <el-option v-for="item in searchData.majorOptions" :key="item.id" :label="item.name" :value="item.id" />
  323. </el-select>
  324. </el-form-item>
  325. <el-form-item prop="class" label="班级">
  326. <el-select
  327. v-model="searchData.class"
  328. placeholder="请选择"
  329. clearable
  330. style="width: 178px"
  331. :disabled="!searchData.major"
  332. >
  333. <el-option v-for="item in searchData.classOptions" :key="item.id" :label="item.name" :value="item.id" />
  334. </el-select>
  335. </el-form-item>
  336. <el-form-item prop="createTime" label="创建时间">
  337. <el-date-picker
  338. v-model="searchData.createTime"
  339. type="datetimerange"
  340. start-placeholder="开始时间"
  341. end-placeholder="结束时间"
  342. value-format="YYYY-MM-DD HH:mm:ss"
  343. />
  344. </el-form-item>
  345. <el-form-item>
  346. <el-button type="primary" @click="handleSearch">查询</el-button>
  347. <el-button @click="resetSearch" plain>重置</el-button>
  348. <el-button plain @click="handleDownload">导出</el-button>
  349. </el-form-item>
  350. </el-form>
  351. </div>
  352. <div class="table-wrapper">
  353. <el-table :data="tableData" max-height="450" height="450">
  354. <el-table-column type="index" label="序号" width="80" align="center" />
  355. <el-table-column prop="applyName" label="申请人" align="center" />
  356. <el-table-column prop="collegeName" label="学院" align="center" />
  357. <el-table-column prop="periodName" label="学段" align="center" />
  358. <el-table-column prop="majorName" label="专业" align="center" />
  359. <el-table-column prop="className" label="班级" align="center" />
  360. <el-table-column prop="name" label="申请组织" align="center" />
  361. <el-table-column prop="applyUserName" label="审核人" align="center" />
  362. <el-table-column prop="passName" label="审核状态" align="center" />
  363. <el-table-column prop="passTime" label="审核时间" align="center" width="160" />
  364. <el-table-column prop="createTime" label="创建时间" align="center" width="160" />
  365. <el-table-column fixed="right" label="操作" width="200" align="center">
  366. <template #default="scope">
  367. <el-link type="danger" @click="handleReject(scope.row)">拒绝</el-link>
  368. <el-link type="primary" @click="handlePass(scope.row)">通过</el-link>
  369. </template>
  370. </el-table-column>
  371. </el-table>
  372. </div>
  373. <div class="pager-wrapper">
  374. <el-pagination
  375. background
  376. :layout="paginationData.layout"
  377. :page-sizes="paginationData.pageSizes"
  378. :total="paginationData.total"
  379. :page-size="paginationData.pageSize"
  380. :currentPage="paginationData.currentPage"
  381. @size-change="handleSizeChange"
  382. @current-change="handleCurrentChange"
  383. />
  384. </div>
  385. </el-card>
  386. </div>
  387. </template>
  388. <style lang="scss" scoped>
  389. .toolbar-wrapper {
  390. margin-bottom: 26px;
  391. }
  392. .table-wrapper {
  393. margin-bottom: 29px;
  394. .el-link {
  395. margin-right: 15px;
  396. }
  397. }
  398. .pager-wrapper {
  399. display: flex;
  400. justify-content: flex-end;
  401. }
  402. </style>