bonus-ui/src/views/business/businessHandling/index.vue

1090 lines
33 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-form
:model="maForm"
ref="maForm"
size="small"
:rules="rules"
:inline="true"
label-width="120px"
:disabled="isDetail"
>
<el-form-item label="领用单位" prop="unitId">
<treeselect
v-model="maForm.unitId"
:disabled="isEdit || isDetail"
:options="uniteList"
:normalizer="normalizer"
:show-count="true"
style="width: 240px"
:disable-branch-nodes="true"
noChildrenText="没有数据了"
noOptionsText="没有数据"
noResultsText="没有搜索结果"
placeholder="请选择领用单位"
@select="uniteChange"
/>
</el-form-item>
<el-form-item label="领用工程" prop="projectId">
<treeselect
v-model="maForm.projectId"
:disabled="isEdit || isDetail"
:options="projectList"
:normalizer="normalizer"
:show-count="true"
style="width: 240px"
:disable-branch-nodes="true"
noChildrenText="没有数据了"
noOptionsText="没有数据"
noResultsText="没有搜索结果"
placeholder="请选择领用工程"
@select="projectChange"
/>
</el-form-item>
<el-form-item label="领料人" prop="leasePerson">
<el-input
v-model="maForm.leasePerson"
placeholder="请输入领料人"
clearable
maxlength="50"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-row :gutter="20">
<el-col :span="24" :offset="0">
<el-form-item label="联系电话" prop="phone">
<el-input
v-model="maForm.phone"
placeholder="请输入联系电话"
clearable
maxlength="11"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="采购申请编号" prop="applyCode">
<el-input
v-model="maForm.applyCode"
placeholder="请输入采购申请编号"
clearable
maxlength="150"
style="width: 240px"
rows="2"
/>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="标准配置" prop="standardConfig">
<treeselect
v-model="maForm.standardConfig"
:disabled="isDetail"
:options="standardConfigList"
:normalizer="normalizer"
:show-count="true"
style="width: 240px"
:disable-branch-nodes="true"
noChildrenText="没有数据了"
noOptionsText="没有数据"
noResultsText="没有搜索结果"
placeholder="请选择标准配置"
@select="standardConfigChange"
/>
</el-form-item>
<el-form-item label="类型规格" prop="deviceType">
<el-row :gutter="10">
<el-col :span="15">
<el-select
ref="typeSelect"
v-model="tempDeviceType"
multiple
filterable
placeholder="请输入类型规格"
style="width: 500px"
@change="handleTypeChange"
clearable
collapse-tags
:filter-method="handleSearchImpl"
:popper-class="'type-select-dropdown'"
:popper-append-to-body="false"
@visible-change="handleVisibleChange"
>
<el-option
v-for="item in filteredOptions"
:key="item.typeId"
:label="item.fullPath"
:value="item.typeId"
:data-key="item.typeId"
>
<span v-html="highlightText(item.fullPath, searchKeyword)"></span>
<span style="float: right; color: #8492a6; font-size: 13px">库存:{{ item.storageNum }}</span>
</el-option>
</el-select>
</el-col>
<el-col :span="6">
<el-input
ref="searchInput"
v-model="searchKeyword"
placeholder="输入类型规格高亮搜索"
prefix-icon="el-icon-search"
clearable
style="width: 300px"
@input="handleHighlightSearch"
@focus="handleSearchFocus"
@click.native="handleSearchClick"
>
<template slot="append">
<span v-if="matchedOptions.length" style="margin: 0 5px">
{{ currentMatchIndex + 1 }}/{{ matchedOptions.length }}
</span>
</template>
</el-input>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="委托书" prop="bmFileInfos" v-if="isFileFbs">
<el-upload
:action="uploadUrl"
:file-list="maForm.bmFileInfos"
:show-file-list="true"
:auto-upload="true"
:key="uploadKey"
:limit="5"
list-type="picture-card"
accept=".png, .jpg, .jpeg, .pdf"
:on-change="handleChangeBusinessList"
:class="{ disabledFbs: uploadDisabled }"
:on-preview="picturePreviewFbs"
:on-remove="handleRemoveElectricianImgList"
:disabled="isDetail"
>
<!-- 文件格式下载,图片格式预览 -->
<div slot="file" slot-scope="{ file }">
<img v-if="isImage(file)" class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
<div v-else class="picture-card-container">
<img class="picture-card" :src="urlTemp" alt="" />
<p class="file-name">{{ file.name }}</p>
</div>
<span class="el-upload-list__item-actions">
<span v-if="updataIf(file)" class="el-upload-list__item-delete" @click="handleDownload(file)">
<i class="el-icon-download" />
</span>
<span v-else class="el-upload-list__item-preview" @click="picturePreviewFbs(file)">
<i class="el-icon-zoom-in" />
</span>
<span v-if="!isDetail" class="el-upload-list__item-delete" @click="handleRemoveElectricianImgList(file)">
<i class="el-icon-delete" />
</span>
</span>
</div>
<i class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleSave" v-if="!isDetail">
{{ isEdit ? '保存' : '发起申请' }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-arrow-left" size="mini" @click="handleApplyRecord">
领料记录查看
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="equipmentList" @selection-change="handleSelectionChange">
<!-- <el-table-column type="selection" width="55" align="center" /> -->
<el-table-column align="center" label="序号" type="index" width="55" />
<el-table-column align="center" label="类型名称" prop="maTypeName" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="规格型号" prop="typeName" show-overflow-tooltip />
<el-table-column align="center" label="计量单位" prop="unitName" />
<el-table-column label="预领数量" prop="preNum" align="center">
<template v-slot="scope">
<el-input
v-model.number="scope.row.preNum"
controls-position="right"
type="number"
style="width: 100%"
:disabled="isDetail"
:min="0"
@input="
v =>
scope.row.unitValue == 1
? (scope.row.preNum = Number(v.replace(/[^\d.]/g, '')))
: (scope.row.preNum = Number(v.replace(/[^\d]/g, '')))
"
></el-input>
</template>
</el-table-column>
<!-- <el-table-column align="center" label="当前库存" prop="storageNum" /> -->
<!-- <el-table-column label="待出库数量" align="center" prop="alNum" show-overflow-tooltip /> -->
<el-table-column label="备注" prop="remark" align="center" label-width="500px">
<template v-slot="scope">
<el-input
v-model="scope.row.remark"
controls-position="right"
:disabled="isDetail"
style="width: 100%"
></el-input>
</template>
</el-table-column>
<el-table-column label="操作" align="center" v-if="!isDetail">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-delete" style="color: red" @click="handleDelete(scope.row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { equipmentTypeTree } from '@/api/purchase/goodsArrived'
import { getListProject, getListUnite, getAgreement } from '@/api/lease/apply'
import {
getStandardConfigList,
getListsByConfigId,
addLeaseTask,
editLeaseTask,
getLeaseTaskDetail
} from '@/api/business/index'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
export default {
dicts: ['purchase_task_status'],
components: { Treeselect },
data() {
return {
id: '',
isEdit: false, // 是否编辑
isDetail: false, // 是否查看
// 遮罩层
loading: false,
loadingTwo: false,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
selectTreeProps: {
children: 'children',
label: 'name',
// multiple: false,
value: 'id'
// multiple: true,
},
//租赁单位
uniteList: [],
//租赁工程
projectList: [],
standardConfigList: [], //标准配置
//机具类型
equipmentTypeList: [],
// 角色表格数据
equipmentList: [],
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
rowData: {},
unitId: null,
projectId: null,
maForm: {
unitId: undefined,
projectId: undefined,
arrivalTime: '',
applyCode: '', // 采购申请编号
bmFileInfos: [] // 附件
},
// 表单参数
form: {},
defaultProps: {
children: 'children',
label: 'label'
},
// 表单校验
rules: {
unitId: [
{
required: true,
message: '请选择租赁单位',
trigger: 'blur'
}
],
projectId: [
{
required: true,
message: '请选择租赁工程',
trigger: 'blur'
}
],
leasePerson: [
{
required: true,
message: '请输入领料人',
trigger: 'blur'
}
],
phone: [
{ required: true, message: '联系电话不能为空', trigger: 'blur' },
{
pattern: /^(?:(?:\+|00)86)?1[3-9]\d{9}$/,
message: '请输入正确的手机号码',
trigger: 'blur'
}
],
applyCode: [
{
required: true,
message: '请输入采购申请编号',
trigger: 'blur'
}
],
bmFileInfos: [
{
required: false, // 是否分包商(是:合同编号必填)
message: '请上传委托书',
trigger: 'change'
}
]
},
deviceTypeTreeProps: {
children: 'children',
label: 'typeName',
value: 'typeId',
multiple: true,
emitPath: true
},
deviceType: [],
propsKey: 1000,
unitTemp: undefined,
agreementId: undefined,
// taxRate:0,
// 类型规格
flattenOptions: [], // 扁平化后的选项数据
typePopoverVisible: false,
typeOptions: [], // 类型选项
allTypeList: [], // 所有类型数据
flattenTypeOptions: [], // 扁平化后的选项数据(缓存所有选项)
typeGroups: [], // 分组后的类型选项
typeGroupsBackup: [], // 备份原始分组数据,用于搜索
typeMap: new Map(), // 用于快速查找类型数据
tempDeviceType: [], // 临时选中值
filteredOptions: [], // 过滤后的选项(用于显示)
maxShowOptions: 100, // 最大显示选项数
searchTimer: null, // 用于自定义防抖
searchKeyword: '', // 高亮搜索关键字
currentMatchIndex: -1, // 当前匹配项索引
matchedOptions: [], // 匹配的选项
keepSelectOpen: false, // 控制下拉框是否保持打开
isSearching: false, // 添加搜索状态标记
//是否是分包商
isFileFbs: false,
urlTemp: '',
delBusinessFileIdList: [],
//图片查看弹窗
dialogImageUrl: '',
dialogVisible: false,
uploadKey: Date.now(),
uploadUrl: process.env.VUE_APP_BASE_API + '/file/upload' // 上传的图片服务器地址
}
},
computed: {
//图片上传1张后隐藏上传框
uploadDisabled() {
return this.maForm.bmFileInfos && this.maForm.bmFileInfos.length == 5
}
},
created() {
if (this.$route.query.type == 'edit') {
this.isEdit = true
this.isDetail = false
this.id = this.$route.query.id
const obj = Object.assign({}, this.$route, { title: '领用申请编辑' })
this.$tab.updatePage(obj)
} else if (this.$route.query.type == 'detail') {
this.isEdit = false
this.isDetail = true
this.id = this.$route.query.id
const obj = Object.assign({}, this.$route, { title: '领用申请详情' })
this.$tab.updatePage(obj)
} else {
this.isEdit = false
this.isDetail = false
this.id = ''
const obj = Object.assign({}, this.$route, { title: '领用申请' })
this.$tab.updatePage(obj)
}
this.projectInfoList() //单位工程下拉选
this.equipmentType() //机具类型下拉选
this.getStandardConfigList() // 标准配置下拉选
if (this.isEdit || this.isDetail) {
console.log('isEdit', this.isEdit)
this.getTaskInfo()
}
console.log(this.$store, 'this.$store.getters')
console.log(this.$route.query, 'this.$route.query')
},
methods: {
// 获取标准配置
async getStandardConfigList() {
try {
const res = await getStandardConfigList()
console.log('🚀 ~ getStandardConfigList ~ res:', res)
this.standardConfigList = res.data
} catch (error) {
console.log('🚀 ~ error:', error)
}
},
// 查看领料记录
handleApplyRecord() {
this.$router.push({ path: '/business/businessHandlingRecord/index' })
},
/** 转换菜单数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children
}
return {
id: node.id,
label: node.name,
children: node.children
}
},
uniteChange(val) {
if (val.typeKey == 'fbs') {
this.isFileFbs = true
this.rules['bmFileInfos'][0].required = true
} else {
this.isFileFbs = false
this.rules['bmFileInfos'][0].required = false
}
setTimeout(() => {
getListProject({ unitId: this.maForm.unitId }).then(response => {
this.projectList = response.data
this.maForm.projectId = null
})
}, 500)
},
projectChange(val) {
setTimeout(() => {
// projectId: this.maForm.projectId
getListUnite({}).then(response => {
this.uniteList = response.data
})
}, 500)
},
async standardConfigChange(val) {
console.log('🚀 ~ standardConfigChange ~ val:', val)
const loading = this.$loading()
try {
const params = {
configId: val.id
}
const res = await getListsByConfigId(params)
console.log('🚀 ~ standardConfigChange ~ res:', res)
// this.equipmentList.unshift(...res.data)
res.data.forEach(newItem => {
const existingItem = this.equipmentList.find(item => item.typeId === newItem.typeId)
if (existingItem) {
existingItem.preNum += newItem.preNum
} else {
this.equipmentList.unshift(newItem)
}
})
loading.close()
} catch (error) {
console.log('🚀 ~ error:', error)
loading.close()
}
},
/** 租赁单位和工程-下拉选 */
projectInfoList() {
if (!this.isEdit) {
getListUnite({ projectId: null }).then(response => {
this.uniteList = response.data
})
getListProject({ unitId: null }).then(response => {
this.projectList = response.data
})
} else {
getListUnite({ projectId: null }).then(response => {
this.uniteList = response.data
})
getListProject({ unitId: this.maForm.unitId }).then(response => {
this.projectList = response.data
})
}
},
/** 机具类型 */
equipmentType() {
equipmentTypeTree().then(response => {
this.equipmentTypeList = response.data
// 处理并扁平化所有类型数据
this.flattenTypeOptions = this.processTypeData(response.data)
// 初始显示所有选项
this.filteredOptions = [...this.flattenTypeOptions]
// 反显选中数据
if (this.equipmentList.length > 0) {
this.deviceType = this.equipmentList.map(item => item.typeId)
}
})
},
// 处理类型数据
processTypeData(data) {
const result = []
const traverse = (node, parents = []) => {
const path = [...parents, node.typeName]
if (!node.children || node.children.length === 0) {
result.push({
typeId: node.typeId,
typeName: node.typeName,
fullPath: path.join(' / '),
searchKey: path.join('').toLowerCase(),
storageNum: node.storageNum || 0,
maTypeName: parents[parents.length - 1] || '',
specificationType: node.typeName,
unitName: node.unitName,
unitValue: node.unitValue
})
}
if (node.children) {
node.children.forEach(child => traverse(child, path))
}
}
data.forEach(node => traverse(node))
return result
},
// 搜索处理函数
handleSearchImpl(query) {
if (!query) {
this.filteredOptions = [...this.flattenTypeOptions]
return
}
const lowercaseQuery = query.toLowerCase()
this.filteredOptions = this.flattenTypeOptions.filter(
item => item.searchKey.includes(lowercaseQuery) || item.fullPath.toLowerCase().includes(lowercaseQuery)
)
},
// 选择变化处理
handleTypeChange(val) {
if (!val || val.length === 0) return
// 获取新选中的项
const lastSelected = val[val.length - 1]
const typeData = this.flattenTypeOptions.find(item => item.typeId === lastSelected)
if (typeData) {
if (this.equipmentList.some(item => item.typeId === lastSelected)) {
this.$message({
message: `${typeData.typeName} 已添加到列表中`,
type: 'warning'
})
this.tempDeviceType = this.tempDeviceType.filter(id => id !== lastSelected)
} else if (typeData.storageNum <= 0) {
this.$message.error('所选物资规格类型暂时无库存,无法申请!')
this.tempDeviceType = this.tempDeviceType.filter(id => id !== lastSelected)
} else {
// 将新项添加到数组开头,实现倒序
this.equipmentList.unshift({
...typeData,
preNum: 0
})
this.deviceType.push(lastSelected)
this.$message({
message: `已添加 ${typeData.typeName}`,
type: 'success'
})
}
}
// 清空临时选中值
this.$nextTick(() => {
this.tempDeviceType = []
})
},
//获取任务详情--- 编辑回显数据
async getTaskInfo() {
const loading = this.$loading()
try {
const res = await getLeaseTaskDetail(this.id)
console.log('🚀 ~ getTaskInfo ~ res:', res)
this.maForm = res.data.leaseApplyInfo
this.maForm.unitId = res.data.leaseApplyInfo.leaseUnitId
this.maForm.projectId = res.data.leaseApplyInfo.leaseProjectId
this.equipmentList = res.data.leaseApplyDetailsList
// 如果 bmFileInfos有值
if (this.maForm.bmFileInfos && this.maForm.bmFileInfos.length > 0) {
this.isFileFbs = true
}
loading.close()
} catch (error) {
console.log('🚀 ~ error:', error)
loading.close()
}
},
//单位,工程树结构数据获取父
treeParentsById(list, id) {
for (let i in list) {
if (list[i].id == id) {
//查询到就返回该数组对象的value
return [list[i].id]
}
if (list[i].children) {
let node = this.treeParentsById(list[i].children, id)
if (node !== undefined) {
//查询到把父节把父节点加到数组前面
node.unshift(list[i].id)
return node
}
}
}
},
// 多选框选中数据
handleSelectionChange() {},
/** 保存按钮操作 */
handleSave() {
// console.log(this.equipmentList)
console.log('maForm', this.maForm)
if (this.equipmentList.length > 0) {
this.$refs['maForm'].validate(async valid => {
if (valid) {
for (let i = 0; i < this.equipmentList.length; i++) {
if (this.equipmentList[i].preNum <= 0) {
this.$message.error(`第 ${i + 1} 行的 ${'预领数量必须大于0'} `)
return
}
if (this.equipmentList[i].preNum > this.equipmentList[i].storageNum) {
this.$message.error(`第 ${i + 1} 行的 ${'预领数量不可大于库存量'} `)
return
}
}
await getAgreement({
unitId: this.maForm.unitId,
projectId: this.maForm.projectId
}).then(response => {
this.agreementId = response.data.agreementId
this.maForm.agreementId = this.agreementId
})
await this.$modal
.confirm('是否确认保存当前页面')
.then(async () => {
if (this.isEdit) {
try {
const res = await editLeaseTask({
leaseApplyDetailsList: this.equipmentList,
leaseApplyInfo: this.maForm
})
if (res.code === 200) {
this.$modal.msgSuccess('编辑成功')
// 关闭页面
this.$tab.closePage()
}
this.loading = false
} catch (error) {
console.log('🚀 ~ error:', error)
this.loading = false
}
} else if (!this.isEdit) {
console.log('新增')
console.log(this.equipmentList)
this.loading = true
try {
const res = await addLeaseTask({
leaseApplyDetailsList: this.equipmentList,
leaseApplyInfo: this.maForm
})
if (res.code === 200) {
this.$modal.msgSuccess('新增成功')
this.$refs['maForm'].resetFields()
this.equipmentList = []
}
this.loading = false
} catch (error) {
console.log('🚀 ~ error:', error)
this.loading = false
}
}
})
.catch(() => {})
}
})
} else {
this.$modal.msgError('请先添加类型规格')
}
},
/** 删除按钮操作 */
handleDelete(row) {
this.$modal
.confirm('是否确认删除所选择的数据项?')
.then(() => {
this.equipmentList = this.equipmentList.filter(item => item.typeId !== row.typeId)
// 更新实际存储的选中值
this.deviceType = this.equipmentList.map(item => item.typeId)
})
.catch(() => {})
},
//委托书文件
handleChangeBusinessList(file, fileList) {
const fileListTemp = fileList.filter(item => {
return item.uid != file.uid
})
const parts = file.name.split('.')
const extension = parts.pop().toLowerCase()
if (fileList.length > 5) {
this.$message.warning('最多上传5张附件')
fileList = fileList.filter(item => {
return item.uid != file.uid
})
} else if (!(extension === 'pdf' || extension === 'png' || extension === 'jpg' || extension === 'jpeg')) {
this.$message.warning('文件格式不正确')
fileList = fileList.filter(item => {
return item.uid != file.uid
})
} else if (file.size > 1024 * 1024 * 10) {
this.$message.warning('文件大小不能超过10Mb')
fileList = fileList.filter(item => {
return item.uid != file.uid
})
} else if (file.name.length > 40) {
this.$message.warning('文件名长度不能超过40个字符')
fileList = fileList.filter(item => {
return item.uid != file.uid
})
} else if (fileListTemp.some(item => item.name === file.name)) {
this.$message.warning('文件名重复')
fileList = fileList.filter(item => {
return item.uid != file.uid
})
}
fileList.forEach(file => {
if (extension === 'pdf') {
this.urlTemp = require('@/assets/file.png')
}
})
this.maForm.bmFileInfos = fileList
console.log('🚀 ~ handleChangeBusinessList ~ this.bmFileInfos:', this.bmFileInfos)
// 手动触发表单验证
this.$refs.maForm.validateField('bmFileInfos')
},
isImage(file) {
this.urlTemp = require('@/assets/file.png')
if (this.updataIf(file)) {
return false
} else {
return true
}
},
// 判断文件类型,图片预览,文件下载
updataIf(e) {
if (e.fileName) {
const parts = e.fileName.split('.')
const extension = parts.pop().toLowerCase()
if (extension === 'png' || extension === 'jpeg' || extension === 'jpg') {
return false
} else {
return true
}
} else {
const parts = e.name.split('.')
const extension = parts.pop().toLowerCase()
if (extension === 'png' || extension === 'jpeg' || extension === 'jpg') {
return false
} else {
return true
}
}
},
//上传组件-图片查看
picturePreviewFbs(file) {
this.dialogImageUrl = file.url.replaceAll('#', '%23')
const parts = file.name.split('.')
const extension = parts.pop()
if (extension === 'pdf') {
const windowName = file.name
window.open(file.url, windowName)
} else {
this.dialogVisible = true
}
},
//上传组件-图片删除
handleRemoveElectricianImgList(file, fileList) {
let sum = 0
this.maForm.bmFileInfos.forEach((item, index) => {
if (item.uid == file.uid) {
sum = index
}
})
this.maForm.bmFileInfos.splice(sum, 1)
if (file.status == 'success') {
this.delBusinessFileIdList.push(file.url)
}
console.log('delBusinessFileIdList', this.delBusinessFileIdList)
},
handleDownload(file) {
console.log(file)
if (file.status === 'ready') {
downloadFile({ fileName: file.name, fileData: file.raw, fileType: 'application/vnd.ms-excel;charset=utf-8' })
} else if (file.status === 'success') {
downloadFileData({ fileName: file.name, fileUrl: file.url })
// downloadFileData({ fileName: file.name,fileUrl:file.url })
}
},
// 高亮文本
highlightText(text, keyword) {
if (!keyword) return text
const reg = new RegExp(keyword, 'gi')
return text.replace(reg, match => `<span class="highlight-text">${match}</span>`)
},
// 处理下拉框可见性变化
handleVisibleChange(visible) {
if (!visible && this.keepSelectOpen && !this.isSearching) {
// 只有在非搜索状态下才重新打开下拉框
this.$nextTick(() => {
this.$refs.typeSelect.focus()
})
}
},
// 处理搜索框点击
handleSearchClick() {
this.isSearching = true
this.keepSelectOpen = true
// 确保下拉框打开
this.$refs.typeSelect.focus()
// 立即将焦点返回给搜索框
this.$nextTick(() => {
this.$refs.searchInput.focus()
})
},
// 处理搜索框获得焦点
handleSearchFocus() {
this.isSearching = true
if (!this.$refs.typeSelect.visible) {
this.$refs.typeSelect.focus()
this.$nextTick(() => {
this.$refs.searchInput.focus()
})
}
},
// 高亮搜索处理
handleHighlightSearch() {
this.isSearching = true
this.keepSelectOpen = true
if (!this.searchKeyword) {
this.currentMatchIndex = -1
this.matchedOptions = []
return
}
// 找到所有匹配项
this.matchedOptions = this.filteredOptions.filter(item =>
item.fullPath.toLowerCase().includes(this.searchKeyword.toLowerCase())
)
if (this.matchedOptions.length > 0) {
this.currentMatchIndex = 0
this.$nextTick(() => {
this.scrollToMatch()
})
}
},
// 滚动到匹配项
scrollToMatch() {
if (this.currentMatchIndex === -1 || !this.matchedOptions.length) return
const option = this.matchedOptions[this.currentMatchIndex]
const selectDom = this.$el.querySelector('.el-select-dropdown__wrap')
const optionDom = selectDom?.querySelector(`[data-key="${option.typeId}"]`)
if (optionDom) {
optionDom.scrollIntoView({ block: 'center', behavior: 'smooth' })
}
}
},
// 添加组件销毁时的清理
beforeDestroy() {
this.keepSelectOpen = false
this.isSearching = false
}
}
</script>
<style lang="scss" scoped>
//隐藏图片上传框的css
::v-deep.disabledFbs {
.el-upload--picture-card {
display: none;
}
}
::v-deep .el-upload-list__item {
margin-bottom: 20px;
overflow: unset !important;
}
::v-deep .el-upload-list__item-actions {
overflow: unset !important;
}
.popper-select {
.el-cascader-panel .el-scrollbar .el-checkbox {
display: none;
}
.el-cascader-panel .el-scrollbar:nth-child(4) .el-checkbox {
display: block !important;
}
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
.el-icon-arrow-down.is-reverse {
transform: rotateZ(180deg);
}
// .el-tree {
// max-height: 300px;
// overflow-y: auto;
// }
.highlight-text {
background-color: #ffd04b;
color: #000;
}
::v-deep .el-input-group__append {
padding: 0;
.el-button {
padding: 0 10px;
border: none;
height: 100%;
&:first-child {
border-right: 1px solid #dcdfe6;
}
&[disabled] {
color: #c0c4cc;
}
}
}
.type-select-dropdown {
.el-select-dropdown__wrap {
max-height: 400px !important;
}
.el-select-dropdown__item {
height: auto;
padding: 8px 20px;
white-space: normal;
word-break: break-all;
}
}
.highlight-text {
background-color: #ffd04b;
color: #000;
}
.el-input-group__append {
padding: 0;
.el-button {
padding: 0 10px;
border: none;
height: 100%;
&:first-child {
border-right: 1px solid #dcdfe6;
}
&[disabled] {
color: #c0c4cc;
}
}
}
.el-upload-list__item-thumbnail {
height: 145px !important;
}
.picture-card-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
}
.picture-card {
width: 100%;
height: 100%;
object-fit: cover;
justify-content: center;
// border: 1px solid #ddd;
// border-radius: 4px;
}
.file-name {
width: 90%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
position: absolute;
bottom: -35px;
margin-top: 8px;
text-align: center;
font-size: 12px;
color: #333;
z-index: 999999;
}
.file-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 20px;
}
</style>