requirement.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <!-- -->
  2. <template>
  3. <view class="f-straight wrapper">
  4. <uni-forms ref="form" :modelValue="formData" :rules="rules" validateTrigger="bind" label-width="90px" label-align="right">
  5. <uni-forms-item label="招聘类型" name="type" required>
  6. <uni-data-picker popup-title="请选择招聘类型" v-model="formData.type" :localdata="jobType" :clear-icon="false" :map="{ text: 'key', value: 'value'}" @change="typeChange"></uni-data-picker>
  7. </uni-forms-item>
  8. <uni-forms-item label="学历要求" name="eduType" required>
  9. <uni-data-picker popup-title="请选择学历要求" v-model="formData.eduType" :localdata="dictObj?.edu_extend || []" :clear-icon="false" :map="{ text: 'label', value: 'value'}"></uni-data-picker>
  10. </uni-forms-item>
  11. <uni-forms-item label="工作经验" name="expType" required>
  12. <uni-data-picker popup-title="请选择工作经验" v-model="formData.expType" :localdata="dictObj?.exp_extend || []" :clear-icon="false" :map="{ text: 'label', value: 'value'}"></uni-data-picker>
  13. </uni-forms-item>
  14. <uni-forms-item label="最低薪资" name="payFrom" :required="salary?.length === 0" label-width="90px">
  15. <view class="d-flex">
  16. <uni-number-box v-model="formData.payFrom" :disabled="salary?.length > 0" :min="1" :max="999999999" :step="salaryStep" :width="100" @change="payChange"></uni-number-box>
  17. <uni-data-checkbox v-model="salary" multiple :localdata="[{ text: '薪资面议', value: 1 }]" selectedColor="#00B760" class="ss-m-l-20" @change="salaryCheckboxChange"></uni-data-checkbox>
  18. </view>
  19. </uni-forms-item>
  20. <uni-forms-item label="最高薪资" name="payTo" :required="salary?.length === 0" label-width="90px">
  21. <uni-number-box v-model="formData.payTo" :disabled="salary?.length > 0" :min="payToMin" :max="999999999" :step="salaryStep" :width="100"></uni-number-box>
  22. </uni-forms-item>
  23. <uni-forms-item v-if="!salary?.length" label="计薪时段" name="payUnit" required>
  24. <uni-data-picker popup-title="请选择计薪时段" v-model="formData.payUnit" placeholder="请选择" :localdata="dictObj?.payUnit || []" :clear-icon="false" :map="{ text: 'label', value: 'value'}"></uni-data-picker>
  25. </uni-forms-item>
  26. <uni-forms-item label="工作城市" name="areaId" required label-width="90px">
  27. <uni-data-picker popup-title="请选择工作城市" v-model="formData.areaId" :localdata="dictObj?.areaTreeData_extend || []" :clear-icon="false" :map="{ text: 'name', value: 'id'}"></uni-data-picker>
  28. </uni-forms-item>
  29. <uni-forms-item required label="详情地址" name="address">
  30. <uni-easyinput v-model="formData.address" placeholder="请填写详细地址"></uni-easyinput>
  31. </uni-forms-item>
  32. <uni-forms-item label="职位关键字" name="tagList">
  33. <view class="tagsBox" @tap="portraitOpen">
  34. <view class="tags" v-if="tagList?.length">
  35. <view
  36. v-for="tag in tagList"
  37. :key="tag"
  38. class="tag"
  39. >
  40. {{ tag }}
  41. </view>
  42. </view>
  43. <uni-icons
  44. type="icon-Edit"
  45. color="#00B760"
  46. class="ss-m-t-20"
  47. custom-prefix="iconfont"
  48. size="18"
  49. ></uni-icons>
  50. </view>
  51. </uni-forms-item>
  52. </uni-forms>
  53. <portrait ref="portraitRef" @submit="portraitSubmit"></portrait>
  54. </view>
  55. </template>
  56. <script setup>
  57. import { ref, unref } from 'vue'
  58. import { dictObj } from '@/utils/position.js'
  59. import { getEnterprisePubJobTypePermission } from '@/api/new/position'
  60. import portrait from './portrait.vue'
  61. const emit = defineEmits(['requireTypeChange'])
  62. const props = defineProps({
  63. data: {
  64. type: Object,
  65. default: () => {}
  66. }
  67. })
  68. const formData = ref({
  69. type: props.data?.type || '',
  70. eduType: props.data?.eduType ? props.data?.eduType : props.data?.eduType === null ? -1 : '',
  71. expType: props.data?.expType ? props.data?.expType : props.data?.expType === null ? -1 : '',
  72. payFrom: props.data?.payFrom || '',
  73. payTo: props.data?.payTo || '',
  74. payUnit: props.data?.payUnit || '',
  75. areaId: props.data?.areaId ? props.data?.areaId : props.data?.areaId === null ? -1 : '',
  76. address: props.data?.address || '',
  77. })
  78. const tagList = ref(props.data?.tagList?.length ? props.data.tagList : [])
  79. // const salaryDisabled = computed(() => {
  80. // return Boolean(salary?.value.length)
  81. // })
  82. const salaryCheckboxChange = (e) => {
  83. const bool = e.detail.value.length ? e.detail.value[0] : ''
  84. salary.value = bool ? [1] : []
  85. formData.value.payFrom = null
  86. formData.value.payTo = null
  87. formData.value.payUnit = null
  88. }
  89. const rules = {
  90. type:{
  91. rules: [{required: true, errorMessage: '请选择招聘类型' }]
  92. },
  93. eduType:{
  94. rules: [{required: true, errorMessage: '请选择学历要求' }]
  95. },
  96. expType:{
  97. rules: [{required: true, errorMessage: '请选择工作经验' }]
  98. },
  99. areaId:{
  100. rules: [{required: true, errorMessage: '请选择工作城市' }]
  101. },
  102. address:{
  103. rules: [{required: true, errorMessage: '请填写详细地址' }]
  104. },
  105. // 薪资
  106. payFrom: {
  107. rules: [
  108. // { required: true, errorMessage: '请填写最低薪资' },
  109. {
  110. validateFunction: function (rule, value, data, callback) {
  111. if (value < 1) {
  112. callback('数额不得小于1')
  113. }
  114. return true
  115. }
  116. },
  117. {
  118. validateFunction: function (rule, value, data, callback) {
  119. if (!formData.value?.payTo || (Number(value) < formData.value.payTo ? Number(formData.value.payTo) : 0)) {
  120. return true
  121. } else {
  122. callback('应低于最高薪资')
  123. }
  124. }
  125. }
  126. ]
  127. },
  128. payTo: {
  129. rules: [
  130. // { required: true, errorMessage: '请填写最高薪资' },
  131. {
  132. validateFunction: function (rule, value, data, callback) {
  133. if (value < 1) {
  134. callback('数额不得小于1')
  135. }
  136. return true
  137. }
  138. },
  139. {
  140. validateFunction: function (rule, value, data, callback) {
  141. if (!formData.value?.payFrom || (Number(value) > formData.value?.payFrom ? Number(formData.value?.payFrom) : 0)) {
  142. return true
  143. } else {
  144. callback('应高于最低薪资')
  145. }
  146. }
  147. }
  148. ]
  149. },
  150. payUnit: {
  151. rules: [{required: true, errorMessage: '请选择计薪时段' }]
  152. }
  153. }
  154. // const salaryRules = {}
  155. const jobType = ref([])
  156. const getJobTypeList = async () => {
  157. const res = await getEnterprisePubJobTypePermission()
  158. jobType.value = res?.data?.length ? res.data : []
  159. }
  160. getJobTypeList()
  161. // 薪资面议
  162. const salaryStep = 1000
  163. const payToMin = ref(0)
  164. const payChange = (val) => {
  165. payToMin.value = val
  166. if (val > formData.value.payTo) formData.value.payTo = val + salaryStep
  167. }
  168. const portraitRef = ref()
  169. const portraitOpen = () => {
  170. portraitRef.value?.handleOpen()
  171. }
  172. const portraitSubmit = (arr) => {
  173. tagList.value = arr?.length ? arr : []
  174. }
  175. const typeChange = (e) => {
  176. const bool = Boolean(e?.detail?.value?.length ? e.detail.value[0]?.text === '实习' : false)
  177. emit('requireTypeChange', bool)
  178. }
  179. const form = ref()
  180. // const salary = ref([])
  181. const salary = ref((props.data?.payFrom === null &&props.data?.payTo === null) ? [1] : [])
  182. const getQuery = async () => {
  183. const valid = await unref(form).validate()
  184. if (!valid) return
  185. const obj = {
  186. hirePrice: 0,
  187. hire: false,
  188. salary: Boolean(salary.value?.length),
  189. tagList: tagList.value,
  190. ...formData.value
  191. }
  192. obj && Object.keys(obj).length && Object.keys(obj).forEach(key => {
  193. if (['areaId', 'eduType', 'expType'].includes(key) && obj[key] === -1) obj[key] = null
  194. if (obj.salary && ['payFrom', 'payTo', 'payUnit'].includes(key)) obj[key] = null
  195. })
  196. return obj
  197. }
  198. defineExpose({
  199. getQuery
  200. })
  201. </script>
  202. <style lang="scss" scoped>
  203. $px: 30rpx;
  204. .positionTemplate {
  205. display: flex;
  206. .picker {
  207. flex: 1;
  208. margin-right: 5px;
  209. }
  210. .btn {
  211. width: 90px;
  212. line-height: 34px;
  213. }
  214. }
  215. .tagsBox {
  216. display: flex;
  217. flex-wrap: wrap;
  218. .tags {
  219. padding-top: 10px;
  220. display: flex;
  221. flex-wrap: wrap;
  222. .tag {
  223. margin: 0 10rpx 10rpx 0;
  224. border: 2rpx solid #00B760;
  225. color: #00B760;
  226. white-space: nowrap;
  227. padding: 4rpx 10rpx;
  228. border-radius: 10rpx;
  229. font-size: 24rpx;
  230. }
  231. }
  232. }
  233. </style>