baseInfo.vue 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <template>
  2. <div>
  3. <CtForm ref="formPageRef" :items="items" style="width: 650px;">
  4. <template #explain>
  5. <div class="d-flex align-center font-size-13">
  6. <div style="color: var(--v-error-base); cursor: pointer;" @click="handleViewRule">
  7. <v-icon size="20" color="error">mdi-help-circle-outline</v-icon>
  8. 众聘岗位规则说明;
  9. </div>
  10. <div class=" ml-5" style="color: var(--v-error-base);">
  11. 众聘岗位分配比例:推荐人占比{{ ratio.recommendRate }}%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 平台占比{{ ratio.headhuntRate }}%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 投递人占比{{ ratio.cvRate }}%
  12. </div>
  13. </div>
  14. </template>
  15. <template #numericalValue>
  16. <div class="font-size-14 color-error my-1">
  17. <div class="d-flex">
  18. 按众聘岗位分配比例计算后的赏金:
  19. <span class="calculation ml-3">推荐人{{ calculation('hirePrice', 1) }}元</span>
  20. <span class="calculation">平台{{ calculation('hirePrice', 0) }}元</span>
  21. <span class="calculation">投递人{{ calculation('hirePrice', 2) }}元</span>
  22. </div>
  23. <div class="d-flex">
  24. 按众聘岗位分配比例计算后的积分:
  25. <span class="calculation ml-3">推荐人{{ calculation('hirePoint', 1) }}点</span>
  26. <span class="calculation">平台{{ calculation('hirePoint', 0) }}点</span>
  27. <span class="calculation">投递人{{ calculation('hirePoint', 2) }}点</span>
  28. </div>
  29. </div>
  30. </template>
  31. <template #positionId="{ item }">
  32. <v-menu :close-delay="1" :open-delay="0" v-bind="$attrs">
  33. <template v-slot:activator="{ props }">
  34. <textUI
  35. :modelValue="item.value"
  36. :item="item"
  37. v-bind="props"
  38. style="position: relative;"
  39. ></textUI>
  40. </template>
  41. <jobTypeCard class="jobTypeCardBox" :select="[query.positionId].filter(Boolean)" :isSingle="true" @handleJobClick="handleJobClickItem"></jobTypeCard>
  42. </v-menu>
  43. </template>
  44. </CtForm>
  45. <CtDialog :visible="show" :widthType="1" titleClass="text-h6" title="众聘岗位规则说明" :footer="false" @close="show = false">
  46. <RulePage />
  47. </CtDialog>
  48. </div>
  49. </template>
  50. <script setup>
  51. defineOptions({ name: 'position-add-baseInfo'})
  52. import CtForm from '@/components/CtForm'
  53. import { reactive, ref, defineExpose, watch } from 'vue'
  54. import textUI from '@/components/FormUI/TextInput'
  55. import jobTypeCard from '@/components/jobTypeCard'
  56. import RulePage from './rule.vue'
  57. import { commissionCalculation } from '@/utils/position'
  58. import { getPublicRatio } from '@/api/recruit/enterprise/position'
  59. const props = defineProps({
  60. itemData: Object
  61. })
  62. const show = ref(false)
  63. const ratio = ref({})
  64. // 按分配比例计算金额积分
  65. const calculation = (key, type) => {
  66. const value = items.value.options.find(e => e.key === key).value
  67. return commissionCalculation(value, type)
  68. }
  69. const getValue = (key) => {
  70. return items.value.options.find(e => e.key === key)
  71. }
  72. // 是否众聘岗位
  73. const handleChangePublic = (val) => {
  74. items.value.options.forEach(e => {
  75. if (!val && Object.prototype.hasOwnProperty.call(e, 'hide')) {
  76. e.hide = true
  77. e.value = null
  78. return
  79. }
  80. if (val && Object.prototype.hasOwnProperty.call(e, 'show')) {
  81. e.hide = false
  82. return
  83. }
  84. if (e.slotName === 'explain') e.hide = val ? false : true
  85. })
  86. }
  87. const formPageRef = ref()
  88. let query = reactive({})
  89. const items = ref({
  90. options: [
  91. {
  92. type: 'ifRadio',
  93. key: 'hire',
  94. value: false,
  95. label: '众聘岗位 *',
  96. width: 90,
  97. disabled: false,
  98. hideDetails: true,
  99. items: [
  100. { label: '是', value: true },
  101. { label: '否', value: false }
  102. ],
  103. change: val => handleChangePublic(val)
  104. },
  105. {
  106. slotName: 'explain',
  107. noParam: true,
  108. value: null,
  109. disabled: false,
  110. hide: true,
  111. flexStyle: 'mb-3'
  112. },
  113. {
  114. type: 'number',
  115. key: 'hirePrice',
  116. value: null,
  117. label: '众聘赏金',
  118. suffix: '元',
  119. hide: true,
  120. show: true,
  121. disabled: false,
  122. hideDetails: true,
  123. col: 6,
  124. flexStyle: 'mr-3'
  125. },
  126. {
  127. type: 'number',
  128. key: 'hirePoint',
  129. value: null,
  130. label: '众聘奖励积分数',
  131. suffix: '点',
  132. hide: true,
  133. col: 6,
  134. disabled: false,
  135. hideDetails: true,
  136. show: false
  137. },
  138. {
  139. slotName: 'numericalValue',
  140. noParam: true,
  141. show: true,
  142. hide: true
  143. },
  144. {
  145. type: 'text',
  146. key: 'name',
  147. value: '',
  148. label: '职位名称 *',
  149. rules: [v => !!v || '请填写职位名称']
  150. },
  151. {
  152. slotName: 'positionId',
  153. key: 'positionId',
  154. value: '',
  155. labelKey: 'positionName',
  156. label: '职位类型 *',
  157. noParam: true,
  158. rules: [v => !!v || '请选择职位类型']
  159. },
  160. {
  161. type: 'datePicker',
  162. key: 'expireTime',
  163. value: null,
  164. class: 'mb-3',
  165. options: {
  166. format: 'timestamp',
  167. placeholder: '到期时间 *',
  168. },
  169. rules: [v => !!v || '请选择到期时间']
  170. },
  171. {
  172. type: 'textarea',
  173. key: 'content',
  174. rows: 10,
  175. value: '',
  176. label: '岗位职责 *',
  177. counter: 5000,
  178. clearable: true,
  179. rules: [
  180. value => {
  181. if (value) return true
  182. return '请输入岗位职责'
  183. },
  184. value => {
  185. if (value?.length <= 5000) return true
  186. return '请输入2-5000个字符'
  187. }
  188. ]
  189. },
  190. {
  191. type: 'textarea',
  192. key: 'requirement',
  193. rows: 10,
  194. value: '',
  195. label: '岗位要求 *',
  196. counter: 5000,
  197. clearable: true,
  198. rules: [
  199. value => {
  200. if (value) return true
  201. return '请输入岗位要求'
  202. },
  203. value => {
  204. if (value?.length <= 5000) return true
  205. return '请输入2-5000个字符'
  206. }
  207. ]
  208. }
  209. ]
  210. })
  211. // 获取众聘分配比例
  212. const getRatio = async () => {
  213. const data = await getPublicRatio()
  214. ratio.value = data
  215. }
  216. getRatio()
  217. // 编辑回显
  218. watch(
  219. () => props.itemData,
  220. (val) => {
  221. if (!Object.keys(val).length) return
  222. items.value.options.forEach(e => {
  223. if (Object.prototype.hasOwnProperty.call(e, 'disabled')) e.disabled = val.hire
  224. if (e.labelKey) {
  225. query[e.key] = val[e.key]
  226. e.value = val[e.labelKey]
  227. return
  228. }
  229. if (e.noParam) return
  230. e.value = val[e.key]
  231. e.change && e.change(e.value)
  232. })
  233. },
  234. { immediate: true },
  235. { deep: true }
  236. )
  237. // 职位类型
  238. const handleJobClickItem = (list, name) => {
  239. const positionId = getValue('positionId')
  240. if (!list.length) {
  241. delete query.positionId
  242. positionId.value = ''
  243. return
  244. }
  245. query.positionId = list[0]
  246. positionId.value = name
  247. }
  248. // 众聘规则查看
  249. const handleViewRule = () => {
  250. show.value = true
  251. }
  252. const getQuery = async () => {
  253. const { valid } = await formPageRef.value.formRef.validate()
  254. if (!valid) return
  255. const obj = {}
  256. items.value.options.forEach(e => {
  257. if (e.noParam) return
  258. else obj[e.key] = e.value
  259. })
  260. // 不是众聘岗位的默认给0
  261. if (!obj.hire) {
  262. obj.hirePoint = 0
  263. obj.hirePrice = 0
  264. }
  265. query = Object.assign(query, obj)
  266. return query
  267. }
  268. defineExpose({
  269. formPageRef,
  270. getQuery
  271. })
  272. </script>
  273. <style scoped lang="scss">
  274. .jobTypeCardBox {
  275. position: absolute;
  276. top: -22px;
  277. left: 0;
  278. }
  279. .calculation {
  280. display: block;
  281. width: 120px;
  282. }
  283. </style>