baseInfo.vue 8.4 KB

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