Browse Source

提取学校模糊搜索为组件、替换页面内的原有使用

clientSet-zq-1128
zq 3 weeks ago
parent
commit
f95e4b6347
  1. 226
      src/components/clientSet/searchInput.vue
  2. 79
      src/views/super/clientSet/coverInfoPage.vue
  3. 78
      src/views/super/paiban/tpl.vue

226
src/components/clientSet/searchInput.vue

@ -0,0 +1,226 @@
<template>
<el-autocomplete
class="school-auto-complete"
:value="value"
:fetch-suggestions="querySearchAsync"
:placeholder="placeholder"
:debounce="debounce"
:loading="loading"
@select="handleSelect"
@input="handleInput"
:clearable="clearable"
:size="size"
:disabled="disabled"
>
<!-- 自定义下拉选项 -->
<template #default="{ item }">
<div class="flex-between school-option">
<span>{{ item.name }}</span>
<img
v-if="showSelectedIcon && item.id === selectedSchoolId"
src="@/assets/site/dropdown_chose_ic.svg"
alt="selected"
/>
</div>
</template>
</el-autocomplete>
</template>
<script>
export default {
name: 'SchoolAutoComplete',
props: {
//
value: {
type: String,
default: ''
},
// ID
selectedSchoolId: {
type: [String, Number],
default: null
},
//
placeholder: {
type: String,
default: '请输入学校名称'
},
//
debounce: {
type: Number,
default: 300
},
//
clearable: {
type: Boolean,
default: true
},
//
size: {
type: String,
default: 'medium'
},
//
disabled: {
type: Boolean,
default: false
},
//
showSelectedIcon: {
type: Boolean,
default: true
}
},
data() {
return {
loading: false,
timeout: null,
lastSearchKeyword: '',
schoolList: []
}
},
beforeDestroy() {
clearTimeout(this.timeout)
},
methods: {
/**
* 异步搜索学校
* @param {string} queryString 搜索关键字
* @param {Function} callback 回调函数
*/
async querySearchAsync(queryString, callback) {
const keyword = queryString.trim()
//
if (!keyword || keyword === this.lastSearchKeyword) {
callback([])
return
}
this.lastSearchKeyword = keyword
this.loading = true
// 使
clearTimeout(this.timeout)
this.timeout = setTimeout(async () => {
try {
const schools = await this.searchSchools(keyword)
this.schoolList = schools
callback(schools)
} catch (error) {
console.error('搜索学校失败:', error)
callback([])
} finally {
this.loading = false
}
}, this.debounce)
},
/**
* 搜索学校API调用
* @param {string} keyword 搜索关键字
* @returns {Promise<Array>} 学校列表
*/
async searchSchools(keyword) {
try {
const response = await this.$http('POST', '/supernew/ajax_get_paiban_schools', {
keyword
})
if (response.status && response.data) {
return response.data
}
return []
} catch (error) {
this.$message.error('搜索学校列表失败')
throw error
}
},
/**
* 处理选择事件
* @param {Object} item 选中的学校对象
*/
handleSelect(item) {
//
this.$emit('select', item)
// ID
this.$emit('update:selectedSchoolId', item.id)
//
this.$emit('input', item.name)
this.$emit('change', item)
},
/**
* 处理输入事件
* @param {string} value 输入的值
*/
handleInput(value) {
this.$emit('input', value)
//
if (!value) {
this.$emit('clear')
this.$emit('update:selectedSchoolId', null)
this.lastSearchKeyword = ''
}
},
/**
* 手动设置选中的学校
* @param {Object} school 学校对象
*/
setSelectedSchool(school) {
if (school && school.id && school.name) {
this.$emit('input', school.name)
this.$emit('update:selectedSchoolId', school.id)
this.$emit('select', school)
}
},
/**
* 清空选择
*/
clear() {
this.$emit('input', '')
this.$emit('update:selectedSchoolId', null)
this.$emit('clear')
this.lastSearchKeyword = ''
},
/**
* 手动触发搜索
* @param {string} keyword 搜索关键字
* @returns {Promise<Array>} 学校列表
*/
async triggerSearch(keyword) {
return await this.searchSchools(keyword || this.value)
}
}
}
</script>
<style lang="scss" scoped>
.school-auto-complete {
width: 100%;
}
.school-option {
width: 100%;
span {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
img {
width: 16px;
height: 16px;
margin-left: 8px;
}
}
</style>

79
src/views/super/clientSet/coverInfoPage.vue

@ -6,25 +6,16 @@
<el-form :model="coverInfo" ref="baseInfoRef"> <el-form :model="coverInfo" ref="baseInfoRef">
<div class="flex-label mb24"> <div class="flex-label mb24">
<div class="label-text">所属学校</div> <div class="label-text">所属学校</div>
<div class="colon"></div> <div class="colon" style="margin-right: 12px;"></div>
<el-autocomplete <SchoolAutoComplete
class="autoInput"
slot="formDom" slot="formDom"
v-model="coverInfo.school_name" v-model="coverInfo.school_name"
:fetch-suggestions="querySearchAsync" :selected-school-id="coverInfo.school"
@select="handleSchoolSelect"
@clear="handleSchoolClear"
placeholder="请输入学校名称" placeholder="请输入学校名称"
@select="handleSelect" style="width: 356px;"
:debounce="300" />
:loading="loading"
>
<!-- 自定义下拉选项 -->
<template #default="{ item }">
<div class="flex-between school-option">
<span>{{ item.name }}</span>
<img src="@/assets/site/dropdown_chose_ic.svg" alt="" v-if="item.id == coverInfo.school">
</div>
</template>
</el-autocomplete>
</div> </div>
<!-- <GuipInput v-model="coverInfo.school" :client-form-flex="true" label="所属学校" width="356px" /> --> <!-- <GuipInput v-model="coverInfo.school" :client-form-flex="true" label="所属学校" width="356px" /> -->
<GuipRadio :options="collegeList" v-model="coverInfo.collegeId" :client-form-flex="true" label="学院" /> <GuipRadio :options="collegeList" v-model="coverInfo.collegeId" :client-form-flex="true" label="学院" />
@ -65,6 +56,7 @@ import GroupFormBtns from '@/components/GroupFormBtns.vue';
import GuipRadio from '@/components/GuipRadio.vue'; import GuipRadio from '@/components/GuipRadio.vue';
import GuipButton from '@/components/GuipButton.vue'; import GuipButton from '@/components/GuipButton.vue';
// import GuipSelect from '@/components/GuipSelect.vue'; // import GuipSelect from '@/components/GuipSelect.vue';
import SchoolAutoComplete from '@/components/clientSet/searchInput.vue'; //
export default { export default {
name: 'CoverInfoPage', name: 'CoverInfoPage',
@ -73,6 +65,7 @@ export default {
GuipInput, GuipInput,
GuipRadio, GuipRadio,
GuipButton, GuipButton,
SchoolAutoComplete
// GuipSelect // GuipSelect
}, },
data() { data() {
@ -127,55 +120,17 @@ export default {
}, },
methods: { methods: {
handleSelect(item) { handleSchoolSelect(item) {
console.log('选中:', item); console.log('选中学校:', item);
this.$emit('select', item);
this.coverInfo.school = item.id; this.coverInfo.school = item.id;
this.coverInfo.school_name = item.name; this.coverInfo.school_name = item.name;
console.log(this.coverInfo.school,this.coverInfo.school_name,'===');
}, },
querySearchAsync(queryString, callback) { handleSchoolClear() {
const keyword = queryString && queryString.trim(); console.log('学校选择已清空');
this.coverInfo.school = '';
// this.coverInfo.school_name = '';
if (!keyword || keyword === this.lastSearchKeyword) {
callback([]);
return;
}
this.lastSearchKeyword = keyword;
this.loading = true;
// 使
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.getSchoolSearchList(keyword, callback);
}, 300);
}, },
getSchoolSearchList(keyword, callback) {
try {
this.$http('POST', '/supernew/ajax_get_paiban_schools', {
keyword
}).then(response => {
if(response.status){
const data = response.data || [];
if (data.length === 0) {
// this.$Message.info('')
}
callback(data);
}else{
callback([]);
}
}).catch(error => {
this.$Message.info('搜索学校列表失败')
callback([]);
console.error(error, 'error')
})
} catch (error) {
console.error('数据加载失败:', error)
}
},
async getCoverInfo(){ async getCoverInfo(){
// this.$http('POST', '/supernew/ajax_get_paiban_template_list', {}, { // this.$http('POST', '/supernew/ajax_get_paiban_template_list', {}, {
// }).then(response => { // }).then(response => {
@ -342,8 +297,4 @@ export default {
align-items: flex-start; align-items: flex-start;
padding: 24px 32px; padding: 24px 32px;
} }
.autoInput{
width: 300px;
}
</style> </style>

78
src/views/super/paiban/tpl.vue

@ -7,7 +7,7 @@
<label for="">模板列表</label> <label for="">模板列表</label>
<GuipSelect width="180px" clearable label="学历" :options="degreesList" v-model="degree" @change="getList"/> <GuipSelect width="180px" clearable label="学历" :options="degreesList" v-model="degree" @change="getList"/>
<GuipFormItem label="学校"> <GuipFormItem label="学校">
<el-autocomplete <!-- <el-autocomplete
slot="formDom" slot="formDom"
class="autoInput" class="autoInput"
v-model="schoolName" v-model="schoolName"
@ -17,14 +17,23 @@
:debounce="300" :debounce="300"
:loading="loading" :loading="loading"
> >
<!-- 自定义下拉选项 -->
<template #default="{ item }"> <template #default="{ item }">
<div class="flex-between school-option"> <div class="flex-between school-option">
<span>{{ item.name }}</span> <span>{{ item.name }}</span>
<img src="@/assets/site/dropdown_chose_ic.svg" alt="" v-if="item.id == school"> <img src="@/assets/site/dropdown_chose_ic.svg" alt="" v-if="item.id == school">
</div> </div>
</template> </template>
</el-autocomplete> </el-autocomplete> -->
<SchoolAutoComplete
slot="formDom"
v-model="schoolName"
:selected-school-id="school"
@select="handleSchoolSelect"
@clear="handleSchoolClear"
placeholder="请输入学校名称"
style="width: 300px;"
/>
</GuipFormItem> </GuipFormItem>
<!-- <GuipInput ref="GuipInput" label="学校" placeholder="输入学校名称" @blur="getSchoolSearchList" width="280px" v-model="school" /> --> <!-- <GuipInput ref="GuipInput" label="学校" placeholder="输入学校名称" @blur="getSchoolSearchList" width="280px" v-model="school" /> -->
</div> </div>
@ -64,15 +73,15 @@ import GuipTable from "@/components/GuipTable.vue";
import GuipSelect from "@/components/GuipSelect.vue"; import GuipSelect from "@/components/GuipSelect.vue";
// import GuipInput from "@/components/GuipInput.vue"; // import GuipInput from "@/components/GuipInput.vue";
import GuipFormItem from '@/components/GuipFormItem.vue' import GuipFormItem from '@/components/GuipFormItem.vue'
import SchoolAutoComplete from '@/components/clientSet/searchInput.vue'; //
export default { export default {
components: { components: {
// GuipInput, // GuipInput,
GuipSelect, GuipSelect,
GuipTable, GuipTable,
GuipButton, GuipButton,
GuipFormItem GuipFormItem,
SchoolAutoComplete
}, },
options: { styleIsolation: "shared" }, options: { styleIsolation: "shared" },
data() { data() {
@ -120,55 +129,17 @@ export default {
this.getList() this.getList()
this.getStatusList() // this.getStatusList() //
}, },
handleSelect(item) { handleSchoolSelect(item) {
console.log('选中:', item); console.log('选中学校:', item);
this.$emit('select', item);
this.school = item.id; this.school = item.id;
this.schoolName = item.name; this.schoolName = item.name;
console.log(this.school,this.schoolName,'==='); this.getList();
this.getList()
}, },
querySearchAsync(queryString, callback) { handleSchoolClear() {
const keyword = queryString.trim(); console.log('学校选择已清空');
this.school = '';
// this.schoolName = '';
if (!keyword || keyword === this.lastSearchKeyword) { this.getList();
callback([]);
return;
}
this.lastSearchKeyword = keyword;
this.loading = true;
// 使
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.getSchoolSearchList(keyword, callback);
}, 300);
},
getSchoolSearchList(keyword, callback) {
try {
this.$http('POST', '/supernew/ajax_get_paiban_schools', {
keyword
}).then(response => {
if(response.status){
const data = response.data || [];
if (data.length === 0) {
// this.$Message.info('')
}
callback(data);
}else{
callback([]);
}
}).catch(error => {
this.$Message.info('搜索学校列表失败')
callback([]);
console.error(error, 'error')
})
} catch (error) {
console.error('数据加载失败:', error)
}
}, },
getStatusList() { getStatusList() {
@ -240,9 +211,6 @@ export default {
::v-deep .el-form-item{ ::v-deep .el-form-item{
margin: 0; margin: 0;
} }
.autoInput{
width: 300px;
}
.filter-area{ .filter-area{
gap: 32px; gap: 32px;

Loading…
Cancel
Save