@@ -26,6 +26,8 @@
< el-col :span = "1.5" > < el-button size = "small" type = "warning" plain icon = "Download" @click ="handleExport" > 导出 < / el -button > < / el-col >
< el-col :span = "1.5" > < el-button size = "small" type = "info" plain icon = "Upload" @click ="openImport" > 导入 < / el -button > < / el-col >
< el-col :span = "1.8" > < el-button size = "small" plain icon = "Download" @click ="downloadTemplate" > 下载模板 < / el -button > < / el-col >
< el-col :span = "2.2" > < el-button size = "small" type = "primary" plain icon = "User" @click ="openUserSelectDialog" > 选择用户导入 < / el -button > < / el-col >
< right-toolbar v -model :showSearch = "showSearch" @queryTable ="getList" / >
< / el-row >
@@ -122,6 +124,21 @@
< el-button @click ="importOpen = false" > 取 消 < / el -button >
< / div >
< / template >
< / el-dialog >
<!-- 选择系统用户导入弹窗 -- >
< el-dialog title = "选择需要导入的用户" v-model = "userSelectOpen" width="700px" append -to -body >
< el-input v-model = "userSearchKey" placeholder="搜索账号/昵称/手机号" clearable style="width: 300px; margin-bottom: 10px" />
< el -table ref = "userSelectTableRef" v -model :selection = "selectedUserIds" :data = "filterUserList" border height = "350" @ selection -change = " handleUserSelectionChange "
>
< el-table-column type = "selection" width = "55" align = "center" / >
< el-table-column label = "账号" prop = "userName" align = "center" / >
< el-table-column label = "昵称" prop = "nickName" align = "center" / >
< el-table-column label = "手机号" prop = "phonenumber" align = "center" / >
< / el-table >
< template # footer >
< el-button @click ="userSelectOpen = false" > 取消 < / el -button >
< el-button type = "primary" @click ="confirmImportSelectedUser" > 确认导入 < / el -button >
< / template >
< / el-dialog >
< / div >
< / template >
@@ -129,6 +146,7 @@
< script setup name = "Worker" >
import { listWorker , getWorker , addWorker , updateWorker , delWorker , importWorkerData } from '@/api/oa/worker'
import { listWageRateConfig } from '@/api/oa/wageRateConfig'
import { listUser } from '@/api/system/user'
const { proxy } = getCurrentInstance ( )
@@ -148,8 +166,37 @@ const importLoading = ref(false)
const updateSupport = ref ( false )
const importFile = ref ( null )
// 选择用户导入相关
const userSelectOpen = ref ( false )
const allUserList = ref ( [ ] )
const selectedUserIds = ref ( [ ] )
// 已存在工号缓存
const existWorkerNos = ref ( [ ] )
// 用户检索关键词
const userSearchKey = ref ( '' )
// 过滤后的用户列表(账号/昵称/手机号模糊检索)
const filterUserList = computed ( ( ) => {
const key = userSearchKey . value . trim ( )
if ( ! key ) return allUserList . value
return allUserList . value . filter ( item =>
item . userName ? . includes ( key ) ||
item . nickName ? . includes ( key ) ||
item . phonenumber ? . includes ( key )
)
} )
// 表格ref
const userSelectTableRef = ref ( null )
// 同步选中的用户ID
function handleUserSelectionChange ( selection ) {
selectedUserIds . value = selection . map ( item => item . userId )
}
const rateOptions = ref ( [ ] )
const data = reactive ( {
form : { } ,
queryParams : {
@@ -358,5 +405,86 @@ function submitImport() {
} )
}
// 打开用户选择弹窗【修复空值初始化】
async function openUserSelectDialog ( ) {
// 每次打开都严格初始化所有变量,避免 undefined
allUserList . value = [ ]
selectedUserIds . value = [ ]
userSearchKey . value = ''
try {
loading . value = true
// 加载系统用户列表
const userRes = await listUser ( { pageNum : 1 , pageSize : 9999 , status : '0' } )
// 确保赋值为数组,避免 undefined
allUserList . value = userRes ? . rows || [ ]
} catch ( err ) {
console . error ( "加载用户失败" , err )
proxy . $modal . msgError ( '加载用户列表失败' )
} finally {
loading . value = false
userSelectOpen . value = true
}
}
// 确认导入选中用户【前端终极兜底 · 零报错】
async function confirmImportSelectedUser ( ) {
if ( ! selectedUserIds . value ? . length ) {
proxy . $modal . msgWarning ( '请至少选择一条用户' )
return
}
if ( ! filterUserList . value ? . length ) {
proxy . $modal . msgWarning ( '用户列表为空,无法导入' )
return
}
loading . value = true
let success = 0 , update = 0
try {
// 1. 一次性查询所有已存在工号, 构建Map
const { rows : existWorkers } = await listWorker ( { pageNum : 1 , pageSize : 9999 } )
const existMap = new Map ( existWorkers . map ( w => [ w . workerNo , w ] ) )
// 2. 过滤有效用户
const users = filterUserList . value . filter ( u =>
u ? . userId && selectedUserIds . value . includes ( u . userId )
)
// 3. 分批次处理,避免并发冲突
for ( const user of users ) {
const workerNo = user . userName
const data = {
workerNo ,
workerName : user . nickName || user . userName ,
phone : user . phonenumber ,
status : '0' ,
defaultBillingType : '1' ,
defaultWorkTypeName : '普通工人' ,
remark : '从系统用户导入'
}
// 4. 严格判断: Map中存在 → 更新,不存在 → 新增
if ( existMap . has ( workerNo ) ) {
data . workerId = existMap . get ( workerNo ) . workerId
await updateWorker ( data )
update ++
} else {
await addWorker ( data )
success ++
// 同步更新Map, 避免后续重复判断
existMap . set ( workerNo , { workerNo } )
}
}
proxy . $modal . msgSuccess ( ` 导入完成:新增 ${ success } 条,更新 ${ update } 条 ` )
userSelectOpen . value = false
getList ( )
} catch ( err ) {
console . error ( '导入失败:' , err )
proxy . $modal . msgError ( '导入失败,请查看控制台日志' )
} finally {
loading . value = false
}
}
getList ( )
< / script >