lifanagju_citu hai 1 ano
pai
achega
992ab2210a

+ 1 - 0
components.d.ts

@@ -9,6 +9,7 @@ declare module 'vue' {
   export interface GlobalComponents {
     AreaSelect: typeof import('./src/components/AreaSelect/index.vue')['default']
     Autocomplete: typeof import('./src/components/FormUI/autocomplete/index.vue')['default']
+    Combobox: typeof import('./src/components/FormUI/combobox/index.vue')['default']
     copy: typeof import('./src/components/CtForm/index copy.vue')['default']
     CtBtn: typeof import('./src/components/CtVuetify/CtBtn/index.vue')['default']
     CtDialog: typeof import('./src/components/CtDialog/index.vue')['default']

+ 16 - 0
src/api/resume.js

@@ -102,4 +102,20 @@ export const saveResumePersonSkill = async (data) => {
     url: '/app-api/menduner/system/person/resume/save/person/skill',
     data
   })
+}
+
+// 根据学校名称模糊搜索
+export const schoolSearchByName = async (params) => {
+  return await request.get({
+    url: '/app-api/menduner/system/school/search/by/name',
+    params
+  })
+}
+
+// 根据专业名称模糊搜索
+export const schoolMajorByName = async (params) => {
+  return await request.get({
+    url: '/app-api/menduner/system/major/search/by/name',
+    params
+  })
 }

+ 8 - 0
src/components/CtForm/index.vue

@@ -22,6 +22,13 @@
                 :item="item"
                 @change="handleChange(item)"
               ></autocompleteUI>
+              <comboboxUI
+                v-if="item.type === 'combobox'"
+                v-model="item.value"
+                :item="item"
+                @search="val => item.search ? item.search(val) : null"
+                @change="handleChange(item)"
+              ></comboboxUI>
               <radioGroupUI
                 v-if="item.type === 'ifRadio'"
                 v-model="item.value"
@@ -55,6 +62,7 @@
 defineOptions({ name:'components-ct-form'})
 import textUI from './../FormUI/TextInput'
 import autocompleteUI from './../FormUI/autocomplete'
+import comboboxUI from './../FormUI/combobox'
 import radioGroupUI from './../FormUI/radioGroup'
 import textareaUI from './../FormUI/textArea'
 import datePicker from '../FormUI/datePicker'

+ 41 - 0
src/components/FormUI/combobox/index.vue

@@ -0,0 +1,41 @@
+<template>
+  <div :style="{ width: item.width ? item.width + 'px' : '100%' }">
+    <v-combobox
+      v-model="value"
+      :rules="item.rules"
+      :attach="!item.noAttach"
+      :label="item.label"
+      :placeholder="item.placeholder || item.label"
+      :item-title="item.itemText || 'label'"
+      :item-value="item.itemValue || 'value'"
+      :items="item.items"
+      variant="outlined"
+      :density="item.dense || 'compact'"
+      :clearable="item.clearable"
+      :disabled="item.disabled"
+      :return-object="item.returnObject || false"
+      @update:search="search"
+      @update:modelValue="modelValueUpDate"
+    ></v-combobox>
+  </div>
+</template>
+<script setup>
+import { ref, defineEmits } from 'vue';
+defineOptions({ name:'FormUI-v-combobox'})
+
+const props = defineProps({item: Object, modelValue: [String, Number]})
+const emit = defineEmits(['update:modelValue', 'change', 'search'])
+const item = props.item
+const value = ref(props.modelValue)
+const modelValueUpDate = (val) => {
+  value.value = val
+  emit('update:modelValue', value.value)
+  // let obj = null // if (item.getObject) obj = item.items.find(e => e[item.itemValue] === value.value) || null
+  emit('change', value.value)
+}
+const search = (val) => {
+  emit('search', val)
+}
+</script>
+<style lang="scss" scoped>
+</style>

+ 1 - 1
src/utils/getText.js

@@ -1,5 +1,5 @@
 export const getText = (value, arr, itemText = 'label', itemValue = 'value') => { // 一维数组
-  console.log('getText', value, arr)
+  // console.log('getText', value, arr)
   if (!arr?.length || !(value && value !==0)) return
   const item = arr.find(e => e[itemValue] === value)
   if (!item) return

+ 68 - 33
src/views/resume/components/educationExp.vue

@@ -24,9 +24,9 @@
           <div>
             <span style="font-size: 18px; font-weight: bold;">{{ item.schoolName }}</span>
             <span class="color6 font15 ml-5">
-              <span>{{ item.eduStartText }}</span>
+              <span>{{ timesTampChange(item.startTime).slice(0, 10) }}</span>
               <span class="mx-1">至</span>
-              <span>{{ item.eduEndText }}</span>
+              <span>{{ timesTampChange(item.endTime).slice(0, 10) }}</span>
             </span>
           </div>
           <div v-if="item.active">
@@ -36,8 +36,9 @@
         </div>
         <div class="level2 my-2">
           <span class="color6 font15">{{ item.major }}</span>
-          <span class="vline"  v-if="item.educationTypeText"></span>
-          <span class="color6 font15">{{ item.educationTypeText }}</span>
+          <span class="vline"  v-if="item.educationSystemType"></span>
+          <!-- <span class="color6 font15">{{ getText(item.educationSystemType, dictItemsObj.educationType) }}</span> -->
+          <span class="color6 font15">{{ getText(item.educationSystemType, dictItemsObj.educationSystemType) }}</span>
         </div>
         <div class="level3">
           <span class="color6 font15">在校经历:</span>
@@ -53,36 +54,72 @@ import CtForm from '@/components/CtForm'
 import Snackbar from '@/plugins/snackbar'
 import { getDict } from '@/hooks/web/useDictionaries'
 import { getTimeStamp, timesTampChange } from '@/utils/date'
-import { saveResumeEduExp, getResumeEduExp, deleteResumeEduExp } from '@/api/resume'
+import { saveResumeEduExp, getResumeEduExp, deleteResumeEduExp, schoolSearchByName, schoolMajorByName } from '@/api/resume'
 import Confirm from '@/plugins/confirm'
-import { nextTick, ref } from 'vue'
-import { shallowRef } from 'vue'
+import { getText } from '@/utils/getText'
+import { debounce } from 'lodash'
+import { nextTick, shallowRef, reactive, ref } from 'vue'
 const CtFormRef = ref()
+const dictItemsObj = reactive({})
+dictItemsObj.educationSystemType = [{ label: '全日制', value: '0' }, { label: '非全日制', value: '1' }]
+
+// 学校下拉列表
+const schoolName = ref('')
+const getSchoolListData = async (name) => {
+  schoolName.value = name
+  const item = formItems.value.options.find(e => e.key === 'schoolId')
+  if (!item) return
+  const data = await schoolSearchByName({ name })
+  item.items = data
+}
+const debouncedCallbackSchool = debounce(newValue => {
+  getSchoolListData(newValue)
+}, 500)
+
+// 专业下拉列表
+const major = ref('')
+const getMajorListData = async (name) => {
+  major.value = name
+  const item = formItems.value.options.find(e => e.key === 'majorId')
+  if (!item) return
+  const data = await schoolMajorByName({ name })
+  item.items = data
+}
+const debouncedCallbackMajor = debounce(newValue => {
+  getMajorListData(newValue)
+}, 500)
 
 const formItems = ref({
   options: [
     {
-      type: 'autocomplete',
-      key: 'schoolName',
+      type: 'combobox',
+      key: 'schoolId',
       value: null,
       default: null,
       label: '学校名称 *',
       col: 6,
       outlined: true,
-      itemText: 'label',
-      itemValue: 'value',
+      clearable: true,
+      itemText: 'value',
+      itemValue: 'key',
       rules: [v => !!v || '请选择学校名称'],
-      items: [{ label: '广州大学', value: '广州大学'}, { label: '同济大学', value: '同济大学'}]
+      search: debouncedCallbackSchool,
+      items: []
     },
     {
-      type: 'text',
-      key: 'major',
+      type: 'combobox',
+      key: 'majorId',
       value: null,
       default: null,
       label: '所学专业 *',
       col: 6,
       outlined: true,
-      rules: [v => !!v || '请输入所学专业']
+      clearable: true,
+      itemText: 'nameCn',
+      itemValue: 'id',
+      rules: [v => !!v || '请选择所学专业'],
+      search: debouncedCallbackMajor,
+      items: []
     },
     {
       type: 'autocomplete',
@@ -108,7 +145,7 @@ const formItems = ref({
       itemText: 'label',
       itemValue: 'value',
       rules: [v => !!v || '请选择学制类型'],
-      items: [{ label: '全日制', value: '0' }, { label: '非全日制', value: '1' }],
+      items: dictItemsObj.educationSystemType,
     },
     {
       type: 'datepicker',
@@ -131,24 +168,15 @@ const formItems = ref({
       key: 'content',
       value: null,
       default: null,
-      counter: 200,
+      counter: 1600,
       label: '在校经历 *',
-      col: 12,
       outlined: true,
       rules: [v => !!v || '请输入在校经历']
     },
   ]
 })
 
-const dictList = [
-  { type: 'menduner_education_type', key: 'educationType' }
-]
-
-// 左侧加mr
-formItems.value.options.forEach((_e, index) => {
-  if ((index + 2) % 2 === 0 && !(!_e.col || _e.col >= 12)) _e.flexStyle = 'mr-3'
-})
-
+console.log('dictItemsObj', dictItemsObj)
 // 获取数据
 const projectExp = ref([])
 const getData = async () => {
@@ -174,13 +202,13 @@ const handle = (item) => {
   })
 }
 
-const transformItems = ['educationType', 'educationSystemType']
+// const transformItems = ['educationType', 'educationSystemType']
 formItems.value.options.forEach((e, index) => {
-  if ((index + 2) % 2 === 0) e.flexStyle = 'mr-3'
+  if (((index + 2) % 2 === 0) && Boolean(e.col) && e.col !== 12) e.flexStyle = 'mr-3' // 左侧加mr
   // 回显
   if (rowObj.value[e.key]) e.value = rowObj.value[e.key]
-  // 数字转为字符串
-  if (transformItems.includes(e.key) && e.value && e.value !== 0) e.value = e.value.toString()
+  // // 数字转为字符串
+  // if (transformItems.includes(e.key) && e.value && e.value !== 0) e.value = e.value.toString()
   // 日期相关
   if (e.type === 'datepicker') e.value = timesTampChange(e.value).slice(0, 10)
 })
@@ -194,9 +222,11 @@ const handleSave = async () => {
   formItems.value.options.forEach(e => {
     if (e.noReturn) return
     else if (e.type === 'datepicker') obj[e.key] = getTimeStamp(e.value)
-    else if (transformItems.includes(e.key) && e.value && e.value !== 0) obj[e.key] = e.value - 0
     else obj[e.key] = e.value
   })
+  obj.schoolName = schoolName.value
+  obj.major = major.value
+  if (rowObj.value?.id) obj.id = rowObj.value.id
   await saveResumeEduExp(obj)
   Snackbar.success('保存成功!')
   isEdit.value = false
@@ -214,17 +244,22 @@ const handleDelete = ({ id }) => {
 }
 
 // 获取字典内容
+const dictList = [
+  { type: 'menduner_education_type', key: 'educationType' }
+]
 const getDictData = async (obj) => {
   const item = formItems.value.options.find(e => e.key === obj.key)
   if (item) { //  && !item.items?.length
     const { data } = await getDict(obj.type)
-    item.items = data
+    item.items = data || []
+    dictItemsObj[obj.key] = data || []
   }
 }
 const getOptions = () => {
   dictList.forEach(obj =>  getDictData(obj))
 }
 getOptions()
+
 </script>
 
 <style scoped lang="scss">

+ 0 - 2
src/views/resume/components/vocationalSkills.vue

@@ -83,7 +83,6 @@ const dataList = ref([])
 const getData = async () => {
   const data = await getResumePersonSkill()
   dataList.value = data
-  console.log('data', data)
 }
 getData()
 
@@ -127,7 +126,6 @@ const skillLevelArr = ref([])
 getDict('menduner_skill_level').then(({ data }) => { // 字典
   data = data?.length && data || []
   skillLevelArr.value = data
-  console.log('skillLevelArr', data)
   const obj = formItems.value.options.find(e => e.key === 'level')
   if (obj) obj.items = data
 })

+ 0 - 1
src/views/resume/index.vue

@@ -71,7 +71,6 @@ const items = [
   { text: '职业技能', icon: 'mdi-star-check-outline', id: 'vocationalSkills' }
 ]
 
-
 onMounted(() => {
   const selector = document.getElementById('leftCadId')
   if (!selector) return