index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. <template>
  2. <div class="app-page">
  3. <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="100px">
  4. <el-form-item label="省份筛选" prop="provinceId">
  5. <el-cascader class="w-[180px]!" :options="areaList" :props="cascaderProps" v-model="selectedArea" clearable />
  6. </el-form-item>
  7. <el-form-item label="分配学校" prop="assignSchoolId">
  8. <ie-select v-model="selectedSchool" :options="schoolList" label-key="name" value-key="id" filterable
  9. class="w-[180px]!" />
  10. </el-form-item>
  11. <el-form-item label="注册学校" prop="schoolId">
  12. <ie-select v-model="queryParams.schoolId" :options="schoolList" label-key="name" value-key="id" filterable
  13. class="w-[180px]!" />
  14. </el-form-item>
  15. <el-form-item label="注册班级" prop="classId">
  16. <ie-select v-model="selectedClass" :options="classList" label-key="name" value-key="classId" filterable
  17. class="w-[180px]!" />
  18. </el-form-item>
  19. <el-form-item label="培训学校" prop="campusId">
  20. <ie-select v-model="selectedCampus" :options="campusList" label-key="name" value-key="id" filterable
  21. class="w-[180px]!" @change="handleCampusChange" />
  22. </el-form-item>
  23. <el-form-item label="培训班级" prop="campusClassId">
  24. <ie-select v-model="selectedCampusClass" :options="campusClassList" label-key="name" value-key="classId"
  25. filterable class="w-[180px]!" />
  26. </el-form-item>
  27. <el-form-item label="代理商" prop="agentId">
  28. <ie-agent-select v-model="queryParams.agentId" class="w-[180px]!" filterable />
  29. </el-form-item>
  30. <el-form-item label="姓名" prop="nickName">
  31. <el-input v-model="queryParams.nickName" type="text" class="w-[180px]!" placeholder="请输入姓名" clearable />
  32. </el-form-item>
  33. <el-form-item label="手机" prop="mobile">
  34. <el-input v-model="queryParams.mobile" type="text" maxlength="11" class="w-[180px]!" placeholder="请输入手机号"
  35. clearable />
  36. </el-form-item>
  37. <el-form-item label="卡号段" prop="begin">
  38. <div class="flex items-center gap-x-3">
  39. <el-input v-model="queryParams.begin" type="text" maxlength="11" class="w-[180px]!" placeholder="请输入开始卡号" />
  40. <span class="text-gray-500">-</span>
  41. <el-input v-model="queryParams.end" type="text" maxlength="11" class="w-[180px]!" placeholder="请输入结束卡号" />
  42. </div>
  43. </el-form-item>
  44. <el-form-item label="卡分配日期" prop="days">
  45. <el-date-picker v-model="queryParams.days" type="daterange" range-separator="至" start-placeholder="开始日期"
  46. end-placeholder="结束日期" class="w-[282px]!" />
  47. </el-form-item>
  48. <el-form-item label="平台机构" prop="deptId">
  49. <ie-institution-select v-model="queryParams.deptId" class="w-[180px]!" clearable />
  50. </el-form-item>
  51. <el-form-item label="考生类型" prop="examType">
  52. <ie-select v-model="queryParams.examType" :options="exam_type" class="w-[180px]!" clearable />
  53. </el-form-item>
  54. <el-form-item label="卡类型" prop="cardType">
  55. <ie-select v-model="queryParams.cardType" :options="card_type" class="w-[180px]!" clearable />
  56. </el-form-item>
  57. <el-form-item label="分配状态" prop="distributeStatus">
  58. <ie-select v-model="queryParams.distributeStatus" :options="card_distribute_status" class="w-[180px]!"
  59. clearable />
  60. </el-form-item>
  61. <el-form-item label="使用状态" prop="cardStatus">
  62. <ie-select v-model="queryParams.cardStatus" :options="CARD_STATUS" class="w-[180px]!" clearable />
  63. </el-form-item>
  64. <el-form-item label="过期状态" prop="timeStatus">
  65. <ie-select v-model="queryParams.timeStatus" :options="card_time_status" class="w-[180px]!" clearable />
  66. </el-form-item>
  67. <el-form-item label="结算状态" prop="payStatus">
  68. <ie-select v-model="queryParams.payStatus" :options="card_pay_status" class="w-[180px]!" clearable />
  69. </el-form-item>
  70. <el-form-item>
  71. <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
  72. <el-button icon="Refresh" @click="resetQuery">重置</el-button>
  73. </el-form-item>
  74. </el-form>
  75. <el-row class="mt-2">
  76. <CustomButton icon="plus" v-hasPermi="['dz:cards:add']" @click="handleAddCard">制卡</CustomButton>
  77. <CustomButton color="#67c23a" v-hasPermi="['dz:cards:assign']" @click="handleAssign">
  78. <svg-icon icon-class="peoples" class="mr-1" style="font-size: 12px" />
  79. 分配卡
  80. </CustomButton>
  81. <CustomButton color="#E6A23C" v-hasPermi="['dz:cards:pay']" :disabled="batchDisabled" @click="handlePay">
  82. <svg-icon icon-class="money" class="mr-1" style="font-size: 12px" />
  83. 缴费
  84. </CustomButton>
  85. <CustomButton color="#F56C6C" v-hasPermi="['dz:cards:close']" :disabled="batchDisabled" @click="handleClose">
  86. <svg-icon icon-class="lock" class="mr-1" style="font-size: 12px" />
  87. 关卡
  88. </CustomButton>
  89. <CustomButton color="#67C23A" v-hasPermi="['dz:cards:reopen']" :disabled="batchDisabled" @click="handleReopen">
  90. <svg-icon icon-class="enter" class="mr-1" style="font-size: 12px" />
  91. 重开
  92. </CustomButton>
  93. <CustomButton color="#E6A23C" v-hasPermi="['dz:cards:refund']" :disabled="batchDisabled" @click="handleRefund">
  94. <svg-icon icon-class="money" class="mr-1" style="font-size: 12px" />
  95. 退费
  96. </CustomButton>
  97. <CustomButton color="#9C27B0" v-hasPermi="['dz:cards:associateCampus']">
  98. <svg-icon icon-class="link" class="mr-1" style="font-size: 12px" />
  99. 关联校区
  100. </CustomButton>
  101. <CustomButton color="#00BCD4" v-hasPermi="['dz:cards:openFinished']" @click="handleOpenCard">
  102. <svg-icon icon-class="enter" class="mr-1" style="font-size: 12px" />
  103. 直接开卡
  104. </CustomButton>
  105. <CustomButton icon="delete" color="#F56C6C" v-hasPermi="['dz:cards:remove']" :disabled="batchDisabled"
  106. @click="handleDeleteBatch">
  107. 删除
  108. </CustomButton>
  109. <CustomButton color="#FFC107" :disabled="batchDisabled" @click="handleSettle">
  110. <svg-icon icon-class="chart" class="mr-1" style="font-size: 12px" />
  111. 结算
  112. </CustomButton>
  113. <CustomButton color="#009688" :disabled="batchDisabled" @click="handleRenew">
  114. <svg-icon icon-class="time" class="mr-1" style="font-size: 14px" />
  115. 续期
  116. </CustomButton>
  117. <CustomButton color="#673AB7" :disabled="editDisabled" @click="handleEdit">
  118. <svg-icon icon-class="edit" class="mr-1" style="font-size: 12px" />
  119. 修改
  120. </CustomButton>
  121. <CustomButton color="#606266" v-hasPermi="['dz:cards:export']" @click="handleExport">
  122. <svg-icon icon-class="download" class="mr-1" style="font-size: 14px" />
  123. 导出
  124. </CustomButton>
  125. <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
  126. </el-row>
  127. <card-table :data="cardList" :loading="loading" @selectionChange="handleSelectionChange" @delete="handleDelete" />
  128. <div class="flex justify-end">
  129. <Pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
  130. @pagination="getList" />
  131. </div>
  132. <MakeDialog ref="makeDialogRef" @refresh="getList" />
  133. <OpenDialog ref="openDialogRef" @refresh="getList" />
  134. <AssignDialog ref="assignDialogRef" @refresh="getList" />
  135. <EditDialog ref="editDialogRef" @refresh="getList" />
  136. </div>
  137. </template>
  138. <script setup>
  139. import useSchool from '@/hooks/useSchool';
  140. import IeSelect from '@/components/IeSelect/index.vue';
  141. import IeAgentSelect from '@/components/IeAgentSelect/index.vue';
  142. import IeInstitutionSelect from '@/components/IeInstitutionSelect/index.vue';
  143. import CardTable from './components/CardTable.vue';
  144. import Pagination from '@/components/Pagination/index.vue';
  145. import CustomButton from './components/CustomButton.vue';
  146. import MakeDialog from './components/MakeDialog.vue';
  147. import OpenDialog from './components/OpenDialog.vue';
  148. import AssignDialog from './components/AssignDialog.vue';
  149. import EditDialog from './components/EditDialog.vue';
  150. import { listCards, delCards, payCard, closeCard, reopenCard, refundCard, settleCard, renewCard } from '@/api/dz/cards';
  151. import { CARD_STATUS } from '@/common/enum';
  152. import { getCurrentInstance, nextTick } from 'vue';
  153. const { proxy } = getCurrentInstance();
  154. const {
  155. reset,
  156. areaList,
  157. selectedArea,
  158. schoolList,
  159. selectedSchool,
  160. classList,
  161. selectedClass,
  162. campusList,
  163. selectedCampus,
  164. campusClassList,
  165. selectedCampusClass,
  166. } = useSchool({ loadCampus: true, loadClass: true });
  167. const {
  168. exam_type,
  169. card_status,
  170. card_distribute_status,
  171. card_time_status,
  172. bool_values,
  173. card_pay_status,
  174. card_type,
  175. } = proxy.useDict("exam_type", "card_status", "card_distribute_status", "card_time_status", "bool_values", "card_pay_status", "card_type");
  176. const cascaderProps = {
  177. label: "areaName",
  178. value: "areaId",
  179. checkStrictly: true,
  180. }
  181. const queryParams = ref({
  182. pageSize: 20
  183. })
  184. const showSearch = ref(true)
  185. const cardList = ref([])
  186. const total = ref(0)
  187. const selectedRows = ref([])
  188. const loading = ref(false)
  189. const ids = computed(() => {
  190. return selectedRows.value.map(item => item.cardId);
  191. })
  192. const batchDisabled = computed(() => {
  193. return selectedRows.value.length === 0;
  194. })
  195. const editDisabled = computed(() => {
  196. return selectedRows.value.length !== 1;
  197. })
  198. const handleQuery = () => {
  199. queryParams.page = 1;
  200. getList();
  201. }
  202. const resetQuery = () => {
  203. queryParams.value = {
  204. pageSize: 20
  205. };
  206. reset();
  207. handleQuery();
  208. }
  209. const getList = () => {
  210. loading.value = true;
  211. listCards({
  212. ...queryParams.value,
  213. areaIds: selectedArea.value,
  214. assignSchoolId: selectedSchool.value,
  215. classId: selectedClass.value,
  216. campusId: selectedCampus.value
  217. }).then(res => {
  218. cardList.value = res.rows;
  219. total.value = res.total;
  220. }).finally(() => {
  221. loading.value = false;
  222. })
  223. }
  224. const handleSelectionChange = (selection) => {
  225. selectedRows.value = selection;
  226. }
  227. const makeDialogRef = ref(null);
  228. const handleAddCard = () => {
  229. makeDialogRef.value.open()
  230. }
  231. const handleDelete = (row) => {
  232. proxy.$modal.confirm(`是否确认删除学习卡号为"${row.cardNo}"的数据项?`).then(() => {
  233. delCards(row.cardId).then(() => {
  234. proxy.$modal.msgSuccess('删除成功')
  235. getList()
  236. })
  237. });
  238. }
  239. const handleDeleteBatch = () => {
  240. proxy.$modal.confirm(`是否确认删除所选数据 (${ids.value.length}项) ?`).then(() => {
  241. delCards(ids.value).then(() => {
  242. proxy.$modal.msgSuccess('删除成功')
  243. getList()
  244. })
  245. });
  246. }
  247. const openDialogRef = ref(null);
  248. const handleOpenCard = () => {
  249. openDialogRef.value.open()
  250. }
  251. const handlePay = () => {
  252. proxy.$modal.confirm(`是否确认缴费所选数据 (${ids.value.length}项) ?`).then(() => {
  253. payCard(ids.value).then(() => {
  254. proxy.$modal.msgSuccess('缴费成功')
  255. getList()
  256. })
  257. })
  258. }
  259. const handleClose = () => {
  260. proxy.$modal.confirm(`是否确认关卡所选数据 (${ids.value.length}项) ?`).then(() => {
  261. closeCard(ids.value).then(() => {
  262. proxy.$modal.msgSuccess('关卡成功')
  263. getList()
  264. })
  265. })
  266. }
  267. const handleReopen = () => {
  268. proxy.$modal.confirm(`是否确认重开所选数据 (${ids.value.length}项) ?`).then(() => {
  269. reopenCard(ids.value).then(() => {
  270. proxy.$modal.msgSuccess('重开成功')
  271. getList()
  272. })
  273. })
  274. }
  275. const handleRefund = () => {
  276. proxy.$modal.confirm(`是否确认退费所选数据 (${ids.value.length}项) ?`).then(() => {
  277. refundCard(ids.value).then(() => {
  278. proxy.$modal.msgSuccess('退费成功')
  279. getList()
  280. })
  281. })
  282. }
  283. const handleSettle = () => {
  284. proxy.$modal.confirm(`是否确认结算所选数据 (${ids.value.length}项) ?`).then(() => {
  285. settleCard(ids.value).then(() => {
  286. proxy.$modal.msgSuccess('结算成功')
  287. getList()
  288. })
  289. })
  290. }
  291. const handleRenew = () => {
  292. proxy.$modal.confirm(`是否确认续费所选数据 (${ids.value.length}项) ?`).then(() => {
  293. renewCard(ids.value).then(() => {
  294. proxy.$modal.msgSuccess('续费成功')
  295. getList()
  296. })
  297. })
  298. }
  299. const editDialogRef = ref(null);
  300. const handleEdit = () => {
  301. const row = selectedRows.value[0];
  302. if (row.status !== 30) {
  303. proxy.$modal.msgError('该卡未绑定用户');
  304. return;
  305. }
  306. editDialogRef.value.open({ ...row });
  307. }
  308. const assignDialogRef = ref(null);
  309. const handleAssign = () => {
  310. assignDialogRef.value.open()
  311. }
  312. const handleExport = () => {
  313. proxy.download('dz/cards/export', {
  314. ...queryParams.value
  315. }, `cards_${new Date().getTime()}.xlsx`)
  316. }
  317. onMounted(() => {
  318. handleQuery();
  319. })
  320. </script>
  321. <style lang="scss" scoped></style>