item.vue 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <template>
  2. <div>
  3. <div v-if="props.items.length" class="d-flex align-center mb-1">
  4. <v-checkbox v-model="selectAll" :label="!selectAll ? '全选' : `已选中${selectList.length}条`" hide-details color="primary" @update:model-value="handleChangeSelectAll"></v-checkbox>
  5. <div v-if="tab === 1" class="ml-8">
  6. <v-btn :disabled="!selectAll" color="primary" variant="tonal" size="small" @click="handleAction(2, 'batch', {})">刷新</v-btn>
  7. <v-btn class="mx-3" :disabled="!selectAll" color="primary" variant="tonal" size="small" @click="handleAction(3, 'top', {})">置顶</v-btn>
  8. <v-btn :disabled="!selectAll" color="primary" variant="tonal" size="small" @click="handleAction(0, 'close', {})">关闭</v-btn>
  9. </div>
  10. <v-btn v-if="tab === 2" class="ml-8" :disabled="!selectAll" color="primary" variant="tonal" size="small" @click="handleAction(1, 'activation', {})">激活</v-btn>
  11. </div>
  12. <div v-for="val in items" :key="val.id" class="itemBox mb-3">
  13. <div class="d-flex justify-space-between pa-5">
  14. <div class="position">
  15. <div class="item-select">
  16. <v-checkbox v-model="val.select" hide-details color="primary" @update:model-value="handleChangeSelect"></v-checkbox>
  17. </div>
  18. <div class="ml-10">
  19. <span v-if="val.name.indexOf('style')" v-html="val.name" class="position-name" @click="handleDetails(val)"></span>
  20. <span v-else class="position-name" @click="handleDetails(val)">{{ val.name }}</span>
  21. </div>
  22. <div class="mt-3 other-info ellipsis ml-10">
  23. <span>{{ val.areaName }}</span>
  24. <span class="lines"></span>
  25. <span>{{ val.eduName }}</span>
  26. <span class="lines"></span>
  27. <span>{{ val.expName }}</span>
  28. <span class="lines"></span>
  29. <span>{{ val.payFrom }}-{{ val.payTo }}/{{ val.payName }}</span>
  30. <span class="lines"></span>
  31. <span>{{ val.positionName }}</span>
  32. </div>
  33. </div>
  34. <div class="d-flex align-center">
  35. <div v-if="tab === 1">
  36. <v-btn color="primary" variant="tonal">人才搜索</v-btn>
  37. <v-btn class="ml-3" color="primary" @click="handleAction(2, '', val)">刷新职位</v-btn>
  38. </div>
  39. <div v-if="tab === 2">
  40. <v-btn color="primary" @click="handleAction(1, '', val)">激活职位</v-btn>
  41. </div>
  42. </div>
  43. </div>
  44. <div class="bottom pa-5 d-flex justify-space-between align-center">
  45. <div>刷新时间:{{ timesTampChange(val.updateTime).slice(0, 10) }} {{ val.expireDay && Number(val.expireDay) >= 1 ? `(${ val.expireDay }天后到期)` : '' }}</div>
  46. <div class="d-flex">
  47. <div class="ml-10 d-flex">
  48. <div v-if="tab === 1">
  49. <span class="cursor-pointer" @click="handleAction(3, '', val)">置顶</span>
  50. <span class="lines"></span>
  51. <span class="cursor-pointer" @click="handleAction(0, '', val)">{{ $t('common.close') }}</span>
  52. <span class="lines"></span>
  53. </div>
  54. <span class="cursor-pointer" @click="handleToStatistics">{{ $t('position.recruitmentStatistics') }}</span>
  55. <div v-if="tab !== 3">
  56. <span class="lines"></span>
  57. <span class="cursor-pointer" @click="handleEdit(val)">{{ $t('common.edit') }}</span>
  58. </div>
  59. <div v-if="tab === 4">
  60. <span class="lines"></span>
  61. <span class="cursor-pointer">{{ $t('common.close') }}</span>
  62. </div>
  63. </div>
  64. </div>
  65. </div>
  66. </div>
  67. </div>
  68. </template>
  69. <script setup>
  70. defineOptions({ name: 'enterprise-position-item'})
  71. import { defineEmits, ref, watch } from 'vue'
  72. import { useRouter } from 'vue-router'
  73. import { timesTampChange } from '@/utils/date'
  74. import { closeJobAdvertised, enableJobAdvertised, refreshJobAdvertised, topJobAdvertised } from '@/api/position'
  75. import Snackbar from '@/plugins/snackbar'
  76. const emit = defineEmits(['refresh'])
  77. const props = defineProps({
  78. tab: {
  79. type: Number,
  80. default: 1
  81. },
  82. items: Array
  83. })
  84. const selectAll = ref(false) // 全选
  85. const selectList = ref([]) // 选中列表
  86. const dealSelect = () => {
  87. selectList.value = props.items.filter(e => e.select).map(k => k.id)
  88. }
  89. // 全选
  90. const handleChangeSelectAll = () => {
  91. props.items.map(k => {
  92. k.select = selectAll.value
  93. return k
  94. })
  95. dealSelect()
  96. }
  97. // 单选
  98. const handleChangeSelect = () => {
  99. const length = props.items.filter(k => k.select).length
  100. selectAll.value = length > 0 ? true : false
  101. dealSelect()
  102. }
  103. // tab改变时清空选中的项
  104. watch(
  105. () => props.tab,
  106. () => {
  107. props.items.map(e => e.select = false)
  108. selectList.value = []
  109. selectAll.value = false
  110. },
  111. { immediate: true }
  112. )
  113. // 分页选中回显
  114. watch(
  115. () => props.items,
  116. (newVal) => {
  117. selectList.value.forEach(e => {
  118. const obj = newVal.find(k => k.id === e)
  119. if (obj) obj.select = true
  120. })
  121. },
  122. { immediate: true },
  123. { deep: true }
  124. )
  125. const apiList = [
  126. { api: closeJobAdvertised, desc: '关闭成功' },
  127. { api: enableJobAdvertised, desc: '激活成功' },
  128. { api: refreshJobAdvertised, desc: '刷新成功' },
  129. { api: topJobAdvertised, desc: '置顶成功' }
  130. ]
  131. // 职位关闭、激活、刷新、置顶
  132. const handleAction = async (index, type, { id }) => {
  133. const ids = type ? props.items.filter(e => e.select).map(k => k.id) : [id]
  134. if (!ids.length && !index) return
  135. await apiList[index].api(ids)
  136. Snackbar.success(apiList[index].desc)
  137. // 清空选项
  138. selectList.value = []
  139. selectAll.value = false
  140. emit('refresh')
  141. }
  142. const router = useRouter()
  143. // 职位编辑
  144. const handleEdit = (val) => {
  145. router.push(`/enterprise/position/edit?id=${val.id}`)
  146. }
  147. // 职位详情
  148. const handleDetails = (val) => {
  149. window.open(`/enterprise/position/details/${val.id}`)
  150. }
  151. // 跳转招聘统计
  152. const handleToStatistics = () => {
  153. router.push('/enterprise/statistics/overallAnalysis')
  154. }
  155. </script>
  156. <style scoped lang="scss">
  157. .itemBox {
  158. border: 1px solid #e5e6eb;
  159. height: 145px;
  160. }
  161. .position-name {
  162. color: #333;
  163. font-size: 19px;
  164. cursor: pointer;
  165. &:hover {
  166. color: var(--v-primary-base);
  167. }
  168. }
  169. .position {
  170. max-width: 46%;
  171. position: relative;
  172. .item-select {
  173. position: absolute;
  174. left: -8px;
  175. top: -13px;
  176. }
  177. }
  178. .lines {
  179. display: inline-block;
  180. width: 1px;
  181. height: 17px;
  182. vertical-align: middle;
  183. background-color: #e0e0e0;
  184. margin: 0 10px;
  185. }
  186. .other-info {
  187. font-size: 15px;
  188. color: #666;
  189. }
  190. .bottom {
  191. height: 40px;
  192. background-color: #f7f8fa;
  193. font-size: 14px;
  194. color: #888;
  195. }
  196. .resume {
  197. display: flex;
  198. font-size: 13px;
  199. flex-direction: column;
  200. align-items: center;
  201. color: #888;
  202. margin-right: 100px;
  203. cursor: pointer;
  204. }
  205. .resume-number {
  206. font-size: 20px;
  207. font-weight: 700;
  208. color: #999;
  209. }
  210. </style>