baseInfo.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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, true) }}元</span>
  29. <span class="calculation">平台{{ calculation('hirePrice', 0, true) }}元</span>
  30. <span class="calculation">投递人{{ calculation('hirePrice', 2, true) }}元</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. <v-btn class="ml-3 half-button" color="primary" style="margin-top: 2px;" @click="useJobTemplate(item)">岗位模板</v-btn>
  53. </template>
  54. </CtForm>
  55. <CtDialog :visible="show" :widthType="1" titleClass="text-h6" title="众聘岗位规则说明" :footer="false" @close="show = false">
  56. <RulePage />
  57. </CtDialog>
  58. </div>
  59. </template>
  60. <script setup>
  61. defineOptions({ name: 'position-add-baseInfo'})
  62. import CtForm from '@/components/CtForm'
  63. import { reactive, ref, watch } from 'vue'
  64. import textUI from '@/components/FormUI/TextInput'
  65. import jobTypeCard from '@/components/jobTypeCard'
  66. import RulePage from './rule.vue'
  67. import { commissionCalculation } from '@/utils/position'
  68. import { getPublicRatio, getRecruitPositionDetails } from '@/api/recruit/enterprise/position'
  69. const props = defineProps({
  70. itemData: Object
  71. })
  72. const show = ref(false)
  73. const ratio = ref({})
  74. // 按分配比例计算金额积分
  75. const calculation = (key, type) => {
  76. const value = items.value.options.find(e => e.key === key).value
  77. return commissionCalculation(value, type)
  78. }
  79. const getValue = (key) => {
  80. return items.value.options.find(e => e.key === key)
  81. }
  82. // 是否众聘岗位
  83. const handleChangePublic = (val) => {
  84. items.value.options.forEach(e => {
  85. if (!val && Object.prototype.hasOwnProperty.call(e, 'hide')) {
  86. e.hide = true
  87. e.value = null
  88. return
  89. }
  90. if (val && Object.prototype.hasOwnProperty.call(e, 'show')) {
  91. e.hide = false
  92. return
  93. }
  94. // if (e.slotName === 'explain') e.hide = val ? false : true
  95. })
  96. }
  97. const formPageRef = ref()
  98. let query = reactive({})
  99. const items = ref({
  100. options: [
  101. {
  102. type: 'ifRadio',
  103. key: 'hire',
  104. value: false,
  105. label: '众聘岗位 *',
  106. width: 90,
  107. disabled: false,
  108. hideDetails: true,
  109. items: [
  110. { label: '是', value: true },
  111. { label: '否', value: false }
  112. ],
  113. change: val => handleChangePublic(val)
  114. },
  115. // {
  116. // slotName: 'explain',
  117. // noParam: true,
  118. // value: null,
  119. // disabled: false,
  120. // hide: true,
  121. // flexStyle: 'mb-3'
  122. // },
  123. {
  124. type: 'number',
  125. key: 'hirePrice',
  126. value: null,
  127. label: '请填写点数 (1赏金=10点数,点数填入不得少于10且为10的倍数)',
  128. suffix: '点',
  129. // integer: true,
  130. hide: true,
  131. show: true,
  132. disabled: false,
  133. hideDetails: true,
  134. change: val => hirePriceChange(val, 'hirePrice')
  135. // col: 6,
  136. // flexStyle: 'mr-3'
  137. },
  138. // {
  139. // type: 'number',
  140. // key: 'hirePoint',
  141. // value: null,
  142. // label: '众聘奖励积分数',
  143. // suffix: '点',
  144. // hide: true,
  145. // col: 6,
  146. // disabled: false,
  147. // hideDetails: true,
  148. // show: false
  149. // },
  150. {
  151. slotName: 'numericalValue',
  152. noParam: true,
  153. show: true,
  154. hide: true
  155. },
  156. {
  157. type: 'text',
  158. key: 'name',
  159. value: '',
  160. label: '职位名称 *',
  161. rules: [v => !!v || '请填写职位名称']
  162. },
  163. {
  164. slotName: 'positionId',
  165. key: 'positionId',
  166. value: '',
  167. labelKey: 'positionName',
  168. label: '职位类型 *',
  169. noParam: true,
  170. readonly: true,
  171. rules: [v => !!v || '请选择职位类型']
  172. },
  173. // {
  174. // type: 'datePicker',
  175. // key: 'expireTime',
  176. // dateType: 'date', // 时间类型 year month date time
  177. // value: null,
  178. // label: '到期时间 *',
  179. // outlined: true,
  180. // rules: [v => !!v || '请选择到期时间']
  181. // },
  182. {
  183. type: 'wangEditor',
  184. key: 'content',
  185. value: '',
  186. label: '岗位职责 *',
  187. },
  188. {
  189. type: 'wangEditor',
  190. key: 'requirement',
  191. value: '',
  192. label: '岗位要求 *',
  193. },
  194. // {
  195. // type: 'textarea',
  196. // key: 'content',
  197. // rows: 10,
  198. // value: '',
  199. // label: '岗位职责 *',
  200. // counter: 5000,
  201. // clearable: true,
  202. // rules: [
  203. // value => {
  204. // if (value) return true
  205. // return '请输入岗位职责'
  206. // },
  207. // value => {
  208. // if (value?.length <= 5000) return true
  209. // return '请输入2-5000个字符'
  210. // }
  211. // ]
  212. // },
  213. // {
  214. // type: 'textarea',
  215. // key: 'requirement',
  216. // rows: 10,
  217. // value: '',
  218. // label: '岗位要求 *',
  219. // counter: 5000,
  220. // clearable: true,
  221. // rules: [
  222. // value => {
  223. // if (value) return true
  224. // return '请输入岗位要求'
  225. // },
  226. // value => {
  227. // if (value?.length <= 5000) return true
  228. // return '请输入2-5000个字符'
  229. // }
  230. // ]
  231. // }
  232. ]
  233. })
  234. // items.value.options.forEach(e => e.rules = []) // 测试使用
  235. // 获取众聘分配比例
  236. const getRatio = async () => {
  237. const data = await getPublicRatio()
  238. ratio.value = data
  239. }
  240. getRatio()
  241. // 编辑回显
  242. watch(
  243. () => props.itemData,
  244. (val) => {
  245. if (!Object.keys(val).length) return
  246. items.value.options.forEach(e => {
  247. if (Object.prototype.hasOwnProperty.call(e, 'disabled')) e.disabled = val.hire
  248. if (e.labelKey) {
  249. query[e.key] = val[e.key]
  250. e.value = val[e.labelKey]
  251. return
  252. }
  253. if (e.noParam) return
  254. e.value = val[e.key]
  255. e.change && e.change(e.value)
  256. })
  257. },
  258. { immediate: true },
  259. { deep: true }
  260. )
  261. // 职位类型
  262. const handleJobClickItem = (list, name) => {
  263. const positionId = getValue('positionId')
  264. if (!list.length) {
  265. delete query.positionId
  266. positionId.value = ''
  267. return
  268. }
  269. query.positionId = list[0]
  270. positionId.value = name
  271. }
  272. // 岗位模板
  273. import Snackbar from '@/plugins/snackbar'
  274. const useJobTemplate = async () => {
  275. if (!query.positionId) return Snackbar.warning('请先选择职位类型')
  276. // 获取职位模板内容-赋值
  277. const res = await getRecruitPositionDetails(query.positionId)
  278. if (!res) return Snackbar.warning('此职位类型没有可使用的模板!')
  279. if (res.content || res.requirement) {
  280. items.value.options.forEach(e => {
  281. if (res.content && e.key === 'content') e.value = res.content
  282. if (res.requirement && e.key === 'requirement') e.value = res.requirement
  283. })
  284. Snackbar.success('模板填充完成!')
  285. }
  286. }
  287. // 众聘规则查看
  288. const handleViewRule = () => {
  289. show.value = true
  290. }
  291. // 众聘规则查看
  292. const hirePriceChange = (value, key) => {
  293. let calcCost = value-0
  294. if (calcCost < 10 ) calcCost = 10
  295. else {
  296. calcCost = parseInt(calcCost/10)*10
  297. }
  298. const obj = items.value.options.find(k => k.key === key)
  299. if (obj) {
  300. obj.value = calcCost
  301. }
  302. }
  303. const getQuery = async () => {
  304. const { valid } = await formPageRef.value.formRef.validate()
  305. if (!valid) return
  306. const obj = {}
  307. items.value.options.forEach(e => {
  308. if (e.noParam) return
  309. else obj[e.key] = e.value
  310. })
  311. // 不是众聘岗位的默认给0
  312. if (!obj.hire) {
  313. // obj.hirePoint = 0
  314. obj.hirePrice = 0
  315. }
  316. query = Object.assign(query, obj)
  317. return query
  318. }
  319. defineExpose({
  320. formPageRef,
  321. getQuery
  322. })
  323. </script>
  324. <style scoped lang="scss">
  325. .jobTypeCardBox {
  326. position: absolute;
  327. top: -22px;
  328. left: 0;
  329. }
  330. .calculation {
  331. display: block;
  332. width: 120px;
  333. }
  334. </style>