index.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <template>
  2. <v-card class="pa-5" style="height: calc(100vh - 130px);font-size: 14px;">
  3. <div class="d-flex justify-space-between">
  4. <div class="d-flex mb-3">
  5. <Autocomplete class="mr-3" v-model="query.jobId" :item="jobItem"></Autocomplete>
  6. <Autocomplete v-model="query.status" :item="statusItem"></Autocomplete>
  7. <v-btn color="primary" class="half-button ml-3" @click="handleSearch">查 询</v-btn>
  8. <v-btn class="half-button ml-3" variant="outlined" color="primary" @click="handleReset">重 置</v-btn>
  9. </div>
  10. </div>
  11. <v-divider class="mb-3"></v-divider>
  12. <div class="d-flex" style="height: calc(100vh - 228px);">
  13. <div>
  14. <div class="d-flex justify-space-between px-5">
  15. <div v-if="selectDateValue">
  16. <span>{{ timesTampChange(selectDateValue, 'Y-M-D') }}</span>
  17. <span class="ml-2" style="cursor: pointer; color: var(--v-primary-base);" @click="handleClear">{{ $t('common.cleanUp') }}</span>
  18. </div>
  19. <div v-else class="color-999">{{ $t('interview.noDateSelected') }}</div>
  20. <v-btn color="primary" variant="text" size="small" @click="selectDateValue = new Date(); handleChangeDate()">{{ $t('interview.today') }}</v-btn>
  21. </div>
  22. <VueDatePicker
  23. class="mr-5"
  24. v-model="selectDateValue"
  25. inline auto-apply
  26. locale="zh-CN"
  27. :enable-time-picker="false"
  28. :day-names="['一', '二', '三', '四', '五', '六', '七']"
  29. :markers="markers"
  30. hide-offset-dates
  31. @update:model-value="handleChangeDate"
  32. >
  33. <template #marker>
  34. <span class="custom-marker"></span>
  35. </template>
  36. </VueDatePicker>
  37. </div>
  38. <v-divider style="height: auto;" class="mr-5" vertical></v-divider>
  39. <div style="flex: 1;">
  40. <div v-if="items.length">
  41. <div style="height: calc(100vh - 318px);overflow: auto;padding-right: 12px;">
  42. <itemPage :items="items" :statusList="statusList" :positionItems="positionItems" @refresh="handleRefresh"></itemPage>
  43. </div>
  44. <CtPagination
  45. v-if="total > 0"
  46. :total="total"
  47. :page="query.pageNo"
  48. :limit="query.pageSize"
  49. @handleChange="handleChangePage"
  50. ></CtPagination>
  51. </div>
  52. <Empty v-else :elevation="false"></Empty>
  53. </div>
  54. </div>
  55. </v-card>
  56. </template>
  57. <script setup>
  58. defineOptions({ name: 'enterprise-interview'})
  59. import { ref } from 'vue'
  60. import { getInterviewInvitePage, getEnterpriseInterviewCountByTime } from '@/api/recruit/enterprise/interview'
  61. import { getDict } from '@/hooks/web/useDictionaries'
  62. import { getJobAdvertised } from '@/api/enterprise'
  63. import { dealDictArrayData } from '@/utils/position'
  64. import { timesTampChange, getStartAndEndOfDay } from '@/utils/date'
  65. import itemPage from './components/item.vue'
  66. const items = ref([])
  67. const statusList = ref()
  68. const total = ref(0)
  69. const query = ref({
  70. pageSize: 20,
  71. pageNo: 1,
  72. status: null,
  73. jobId: null,
  74. time: []
  75. })
  76. const positionItems = ref([])
  77. const jobItem = ref({ width: 300, items: positionItems, clearable: true, hireDetails: true, label: '职位' })
  78. const statusItem = ref({ width: 300, items: statusList, clearable: true, hireDetails: true, label: '面试状态' })
  79. // 获取有面试的日期列表
  80. const markers = ref([])
  81. const getCountByTime = async () => {
  82. const data = await getEnterpriseInterviewCountByTime()
  83. if (!data || !data.length) return
  84. markers.value = data.map(e => {
  85. return { date: e.key, type: 'dot' }
  86. })
  87. }
  88. getCountByTime()
  89. // 状态字典
  90. const getStatusList = async () => {
  91. const { data } = await getDict('menduner_interview_invite_status')
  92. statusList.value = data
  93. }
  94. getStatusList()
  95. // 列表
  96. const getData = async () => {
  97. const { list, total: number } = await getInterviewInvitePage(query.value)
  98. items.value = list
  99. total.value = number
  100. }
  101. getData()
  102. const handleRefresh = () => {
  103. query.value.pageNo = 1
  104. getData()
  105. }
  106. // 分页
  107. const handleChangePage = (e) => {
  108. query.value.pageNo = e
  109. getData()
  110. }
  111. // 日期选择
  112. const selectDateValue = ref(null)
  113. const handleChangeDate = () => {
  114. const time = getStartAndEndOfDay(selectDateValue.value)
  115. if (!time || !time.length) return delete query.value.time
  116. query.value.time = time
  117. query.value.pageNo = 1
  118. getData()
  119. }
  120. // 清除
  121. const handleClear = () => {
  122. query.value.pageNo = 1
  123. selectDateValue.value = null
  124. delete query.value.time
  125. getData()
  126. }
  127. const handleSearch = () => {
  128. query.value.pageNo = 1
  129. getData()
  130. }
  131. const handleReset = () => {
  132. query.value = {
  133. pageSize: 10,
  134. pageNo: 1,
  135. status: null,
  136. jobId: null,
  137. time: []
  138. }
  139. selectDateValue.value = null
  140. getData()
  141. }
  142. // 职位
  143. const getPositionList = async () => {
  144. const data = await getJobAdvertised()
  145. if (!data.length) return
  146. const list = dealDictArrayData([], data)
  147. positionItems.value = list.map(e => {
  148. return { label: `${e.name}${e.areaName ? '_' + e.areaName : ''} ${e.payFrom ? e.payFrom + '-' : ''}${e.payTo}${e.payName ? '/' + e.payName : ''}`, value: e.id }
  149. })
  150. }
  151. getPositionList()
  152. </script>
  153. <style scoped lang="scss">
  154. :deep(.dp__menu) {
  155. border: none !important;
  156. }
  157. .custom-marker {
  158. position: absolute;
  159. bottom: 0;
  160. right: 50%;
  161. transform: translateX(50%);
  162. height: 8px;
  163. width: 8px;
  164. border-radius: 100%;
  165. background-color: var(--v-primary-base);
  166. }
  167. /* 滚动条样式 */
  168. ::-webkit-scrollbar {
  169. -webkit-appearance: none;
  170. width: 4px;
  171. height: 0px;
  172. }
  173. /* 滚动条内的轨道 */
  174. ::-webkit-scrollbar-track {
  175. background: rgba(0, 0, 0, 0.1);
  176. border-radius: 0;
  177. }
  178. /* 滚动条内的滑块 */
  179. ::-webkit-scrollbar-thumb {
  180. cursor: pointer;
  181. border-radius: 5px;
  182. background: rgba(0, 0, 0, 0.15);
  183. transition: color 0.2s ease;
  184. }
  185. </style>