lifanagju_citu 10 kuukautta sitten
vanhempi
commit
3d3f0e7280

+ 1 - 0
components.d.ts

@@ -10,6 +10,7 @@ declare module 'vue' {
     AreaSelect: typeof import('./src/components/AreaSelect/index.vue')['default']
     Autocomplete: typeof import('./src/components/FormUI/autocomplete/index.vue')['default']
     Checkbox: typeof import('./src/components/FormUI/checkbox/index.vue')['default']
+    CitySelect: typeof import('./src/components/FormUI/citySelect/index.vue')['default']
     Combobox: typeof import('./src/components/FormUI/combobox/index.vue')['default']
     ComboboxZhAndEn: typeof import('./src/components/FormUI/comboboxZhAndEn/index.vue')['default']
     copy: typeof import('./src/components/CtForm/index copy.vue')['default']

+ 3 - 3
src/components/CtForm/index.vue

@@ -31,13 +31,13 @@
                 @change="handleChange(item)"
               ></comboboxUI>
               <!-- comboboxZhAndEnUI暂不可用 -->
-              <comboboxZhAndEnUI 
+              <!-- <comboboxZhAndEnUI
                 v-if="item.type === 'comboboxZhAndEn'"
                 v-model="item.value"
                 :item="item"
                 @search="v => item.search ? item.search(v) : null"
                 @change="handleChange(item)"
-              ></comboboxZhAndEnUI>
+              ></comboboxZhAndEnUI> -->
               <radioGroupUI
                 v-if="item.type === 'ifRadio'"
                 v-model="item.value"
@@ -108,7 +108,7 @@ defineOptions({ name:'components-ct-form'})
 import textUI from './../FormUI/TextInput'
 import autocompleteUI from './../FormUI/autocomplete'
 import comboboxUI from './../FormUI/combobox'
-import comboboxZhAndEnUI from './../FormUI/comboboxZhAndEn'
+// import comboboxZhAndEnUI from './../FormUI/comboboxZhAndEn'
 import radioGroupUI from './../FormUI/radioGroup'
 import checkboxUI from './../FormUI/checkbox'
 import textareaUI from './../FormUI/textArea'

+ 74 - 17
src/components/FormUI/nestedListGroup/components/listGroup.vue

@@ -1,22 +1,36 @@
 <template>
-  <v-list class="side-box" color="primary">
-    <template v-for="(val, index) in list" :key="option?.itemValue? val[option.itemValue] : index">
-      <template v-if="!val.children?.length">
-        <v-list-item
-          active-class="active"
-          color="primary"
-          :title="val[option.itemText || 'label']"
-        >
-        </v-list-item>
-      </template>
-      <v-list-group
-        v-else
-        color="primary"
-      >
+  <v-list class="ml-1" color="primary">
+    <template v-for="(val, index) in list" :key="val[option.itemValue] ? val[option.itemValue] : 'listGroup'+index">
+      <v-list-group color="primary">
         <template v-slot:activator="{ props }">
-          <v-list-item v-bind="props" :title="val[option.itemText || 'label']"></v-list-item>
+          <v-list-item
+            v-bind="props"
+            color="primary"
+            active-class="active"
+            :active="activeCalc(val)"
+            :title="val[option.itemText || 'label']"
+            @click="handleClick(val)"
+          >
+            <!-- 没有children时去掉折叠icon -->
+            <template  v-if="!val?.children?.length" v-slot:append="{ appendProps }">
+              <template v-bind="appendProps"></template>
+            </template>
+            <!-- <template v-slot:prepend="{ isActive }">
+              <v-list-item-action start>
+                <v-checkbox-btn :model-value="isActive"></v-checkbox-btn>
+              </v-list-item-action>
+            </template> -->
+          </v-list-item>
         </template>
-        <listGroup :list="val.children" :option="option"></listGroup>
+        <listGroup
+          v-if="val?.children?.length"
+          :list="val.children"
+          :option="option"
+          :selectValue="propsData.selectValue"
+          :levelUI="propsData.levelUI + 1"
+          @labelUpdate="labelTxt => emit('labelUpdate', labelTxt)"
+          @clickUpdate="child => clickUpdate(val, child)"
+        ></listGroup>
       </v-list-group>
     </template>
   </v-list>
@@ -24,10 +38,53 @@
 
 <script setup>
 // import listGroup from './listGroup'
+// import { ref } from 'vue'
 defineOptions({ name:'nestedListGroup-listGroup'})
-const propsData = defineProps({list: Array, option: Object})
+const emit = defineEmits(['clickUpdate', 'parentActUpdate', 'labelUpdate'])
+const propsData = defineProps({
+  list: Array,
+  levelUI: {
+    type: Number,
+    default: 1
+  },
+  selectValue: {
+    type: [Array, String],
+    default: ''
+  },
+  option: {
+    type: Object,
+    default: () => {}
+  }
+})
+// const isActive = ref(false)
 const list = propsData.list
 const option = propsData.option
+
+const handleClick = (val) => {
+  val.levelUI = propsData.levelUI
+  if (val.levelUI >= option.selectLevel) {
+    emit('clickUpdate', val)
+  }
+}
+
+const activeCalc = (val) => {
+  if (!propsData.selectValue || !val[option.itemValue]) return false
+  else {
+    const bool = (val[option.itemValue] - 0) === (propsData.selectValue -0)
+    if (bool) {
+      emit('labelUpdate', val[option.itemText]) // 回显
+    }
+    return bool
+  }
+}
+
+const clickUpdate = (val, child) => {
+  emit('clickUpdate', child)
+}
 </script>
 <style lang="scss" scoped>
+.active {
+  color: var(--v-primary-base) !important;
+  background-color: var(--default-bgc) !important;
+}
 </style>

+ 88 - 32
src/components/FormUI/nestedListGroup/index.vue

@@ -1,37 +1,56 @@
 <!-- 嵌套列表 -->
 <template>
+  <div style="height: 100vh; width: 100vw; position: fixed; top: 0; left: 0;" @click="show = false"></div>
   <div :style="{ width: item.width ? item.width + 'px' : '100%' }">
-    <v-menu :close-on-content-click="closeOnContentClick">
+    <div style="position: relative;">
+      <v-text-field
+        v-model="model_selectLabel"
+        v-bind="props"
+        variant="outlined" hide-spin-buttons
+        :density="item.dense || 'compact'"
+        :type="item.type"
+        :rules="item.rules"
+        :disabled="item.disabled"
+        :style="{width: item.width}"
+        :color="item.color || 'primary'"
+        :label="item.label"
+        :placeholder="item.placeholder || item.label"
+        :autofocus="item.autofocus"
+        :required="item.required"
+        :class="item.class"
+        :suffix="item.suffix"
+        :append-icon="item.appendIcon"
+        :append-inner-icon="item.appendInnerIcon"
+        :clearable="item.clearable"
+        :readonly="item.readonly"
+        :counter="item.counter"
+        :prepend-inner-icon="item.prependInnerIcon"
+        :hide-details="item.hideDetails || false"
+        @update:modelValue="modelValueUpDate"
+        @click="show = !show"
+      ></v-text-field>
+      <div v-show="show" style="position: absolute; top: 40; left: 0">
+        <v-card class="mt-n5 py-1" elevation="5">
+          <listGroup
+            :list="item.items"
+            :option="option"
+            :selectValue="value"
+            class="px-1"
+            style="max-height: 350px; border-radius: 5px;"
+            @labelUpdate="labelTxt => labelUpdateDeal(labelTxt)"
+            @clickUpdate="val => clickUpdate(val)"
+          ></listGroup>
+        </v-card>
+      </div>
+    </div>
+    <!-- <v-menu :close-on-content-click="closeOnContentClick">
       <template v-slot:activator="{ props }">
         <v-text-field
-          v-model="value"
-          v-bind="props"
-          variant="outlined"
-          :density="item.dense || 'compact'"
-          :type="item.type"
-          :rules="item.rules"
-          :disabled="item.disabled"
-          :style="{width: item.width}"
-          :color="item.color || 'primary'"
-          :label="item.label"
-          :placeholder="item.placeholder || item.label"
-          :autofocus="item.autofocus"
-          :required="item.required"
-          :class="item.class"
-          :suffix="item.suffix"
-          :append-icon="item.appendIcon"
-          :append-inner-icon="item.appendInnerIcon"
-          :clearable="item.clearable"
-          :readonly="item.readonly"
-          :counter="item.counter"
-          :prepend-inner-icon="item.prependInnerIcon"
-          hide-spin-buttons
-          :hide-details="item.hideDetails || false"
-          @update:modelValue="modelValueUpDate"
         ></v-text-field>
       </template>
-      <listGroup :list="item.items" :option="option"></listGroup>
-    </v-menu>
+      <listGroup
+      ></listGroup>
+    </v-menu> -->
   </div>
 </template>
 
@@ -41,16 +60,53 @@ import { defineEmits, ref } from 'vue';
 defineOptions({ name:'FormUI-nestedListGroup'})
 const propsData = defineProps({item: Object, modelValue: [String, Number]})
 const item = propsData.item
-const option = { ...item, items: [] }
-const value = ref(propsData.modelValue)
+const option = {
+  ...item,
+  itemValue: item.itemValue || 'value',
+  itemText: item.itemText || 'label',
+  multiply: item.multiply || false, // 多选(待开发
+  selectLevel: item.selectLevel || -1, // 可选层级,-1代表只能选最后一级
+  relate: item.relate || false,
+  items: []
+}
 const emit = defineEmits(['update:modelValue', 'change'])
-const modelValueUpDate = (val) => {
-  value.value = val
+const modelValueUpDate = (newText) => {
+  if (option.rules) {
+    model_selectLabel.value = static_selectLabel
+  } else {
+    model_selectLabel.value = ''
+    console.log(newText)
+  }
+}
+let static_selectLabel = ''; const model_selectLabel = ref('')
+const value = ref(propsData.modelValue) // selectValue // modelValue
+const clickUpdate = (val) => {
+  static_selectLabel = model_selectLabel.value = val[option.itemText]
+  value.value = val[option.itemValue]
   emit('update:modelValue', value.value)
   emit('change', value.value)
 }
-const closeOnContentClick = ref(false) // multiple
+// const closeOnContentClick = ref(false) // multiple
+
+const labelUpdateDeal = (txt) => {
+  static_selectLabel = model_selectLabel.value = txt
+}
+
+const show = ref(false)
 </script>
 <style lang="scss" scoped>
+::-webkit-scrollbar {
+  width: 4px;
+  height: 10px;
+  // display: none;
+}
+::-webkit-scrollbar-thumb, .temporaryAdd ::-webkit-scrollbar-thumb, .details_edit ::-webkit-scrollbar-thumb {
+  // 滚动条-颜色
+  background: #c3c3c379;
+}
+::-webkit-scrollbar-track, .temporaryAdd ::-webkit-scrollbar-track, .details_edit ::-webkit-scrollbar-track {
+  // 滚动条-底色
+  background: #e5e5e58f;
+}
 </style>
  

+ 44 - 14
src/views/recruit/personal/remuse/components/jobIntention.vue

@@ -61,7 +61,7 @@
             <industryTypeCard :select="query.industryIdList" :currentData="currentSelect" showSelect @handleClickIndustry="handleIndustry"></industryTypeCard>
           </v-menu>
         </template>
-        <template #workAreaId="{ item }">
+        <!-- <template #workAreaId_old="{ item }">
           <v-menu :close-delay="1" :open-delay="0" v-bind="$attrs">
             <template v-slot:activator="{  props }">
               <textUI
@@ -71,9 +71,9 @@
                 style="position: relative;"
               ></textUI>
             </template>
-            <areaType :select="[query.workAreaId].filter(Boolean)" @handleAreaClick="handleArea" class="jobTypeCardBox" isSingle></areaType>
+            <areaType :select="[query.workAreaId_old].filter(Boolean)" @handleAreaClick="handleArea" class="jobTypeCardBox" isSingle></areaType>
           </v-menu>
-        </template>
+        </template> -->
       </CtForm>
       <div class="text-end">
         <v-btn class="half-button mr-3" variant="tonal" @click="isAdd = false; resetForm()">{{ $t('common.cancel') }}</v-btn>
@@ -89,11 +89,12 @@ import CtForm from '@/components/CtForm'
 import textUI from '@/components/FormUI/TextInput'
 import jobTypeCard from '@/components/jobTypeCard'
 import industryTypeCard from '@/components/industryTypeCard'
-import areaType from '@/components/AreaSelect'
+// import areaType from '@/components/AreaSelect'
 import Snackbar from '@/plugins/snackbar'
 import Confirm from '@/plugins/confirm'
 import { saveResumeJobInterested, getResumeJobInterested, deleteResumeJobInterested } from '@/api/recruit/personal/resume'
 import { dealJobData } from './dict'
+import { getDict } from '@/hooks/web/useDictionaries'
 
 const isAdd = ref(false)
 const formPageRef = ref()
@@ -141,15 +142,31 @@ const items = ref({
       outlined: true,
       rules: [v => !!v || '请输入薪资最高要求']
     },
+    // {
+    //   slotName: 'workAreaId_old',
+    //   key: 'workAreaId_old',
+    //   value: null,
+    //   label: '工作城市 *',
+    //   valueKey: 'workArea',
+    //   col: 6,
+    //   flexStyle: 'mr-3',
+    //   rules: [v => !!v || '请选择工作城市']
+    // },
     {
-      slotName: 'workAreaId',
+      // slotName: 'workAreaId',
+      // type: 'citySelect',
+      type: 'nestedListGroup',
       key: 'workAreaId',
       value: null,
       label: '工作城市 *',
-      valueKey: 'workArea',
+      itemText: 'name',
+      itemValue: 'id',
       col: 6,
       flexStyle: 'mr-3',
-      rules: [v => !!v || '请选择工作城市']
+      selectLevel: 2,
+      items: [],
+      rules: [v => !!v || '请选择工作城市'],
+      // valueKey: 'workArea',
     },
     {
       type: 'autocomplete',
@@ -171,6 +188,19 @@ const items = ref({
   ]
 })
 
+getDict('areaTreeData', null, 'areaTreeData').then(({ data }) => {
+  data = data?.length && data || []
+  if (!data?.length) return console.error('areaTreeData获取失败!')
+  //
+  const china = data.find(e => e.id === '1')
+  const chinaTreeData = china?.children?.length ? china.children : []
+  //
+  if (!chinaTreeData?.length) return console.error('chinaTreeData获取失败!')
+  const item = items.value.options.find(e => e.key === 'workAreaId')
+  if (item?.items) item.items = chinaTreeData
+})
+getDict()
+
 // 获取求职意向
 const interestList = ref([])
 const getJobInterested = async () => {
@@ -202,12 +232,12 @@ const handleIndustry = (list, arr) => {
   setValue('industryIdList', str)
 }
 
-// 工作城市
-const handleArea = (list, name) => {
-  if (!list.length) return
-  query.workAreaId = list[0]
-  setValue('workAreaId', name)
-}
+// // 工作城市
+// const handleArea = (list, name) => {
+//   if (!list.length) return
+//   query.workAreaId_old = list[0]
+//   setValue('workAreaId_old', name)
+// }
 
 const resetForm = () => {
   items.value.options.forEach(e => {
@@ -219,7 +249,7 @@ const resetForm = () => {
   currentSelect = []
 }
 
-const arr = ['payFrom', 'payTo', 'jobType']
+const arr = ['payFrom', 'payTo', 'jobType', 'workAreaId']
 const handleSave = async () => {
   const { valid } = await formPageRef.value.formRef.validate()
   if (!valid) return