| | |
| | | <el-form-item label="班组信息" |
| | | prop="teamList"> |
| | | <el-select v-model="reportForm.teamList" |
| | | ref="teamSelectRef" |
| | | multiple |
| | | filterable |
| | | allow-create |
| | |
| | | value-key="userName" |
| | | placeholder="请选择或输入班组成员" |
| | | @change="handleTeamListChange"> |
| | | <el-option v-for="user in reportForm.userIdsList" |
| | | :key="user.userId" |
| | | <el-option v-for="user in teamSelectOptions" |
| | | :key="user.userId || `custom-${user.nickName}`" |
| | | :label="user.nickName" |
| | | :value="{ userId: user.userId, userName: user.nickName }" /> |
| | | </el-select> |
| | |
| | | const currentUserId = ref(""); |
| | | const deviceOptions = ref([]); |
| | | const currentUserName = ref(""); |
| | | const teamSelectRef = ref(null); |
| | | |
| | | const ensureCurrentUser = async () => { |
| | | if (currentUserId.value) return; |
| | |
| | | teamList: [], |
| | | deviceId: null, |
| | | }); |
| | | const teamSelectOptions = computed(() => { |
| | | const base = |
| | | Array.isArray(reportForm.userIdsList) && reportForm.userIdsList.length > 0 |
| | | ? reportForm.userIdsList.map(u => ({ |
| | | userId: String(u.userId ?? ""), |
| | | nickName: String(u.nickName ?? "").trim(), |
| | | })) |
| | | : []; |
| | | const baseNameSet = new Set(base.map(u => u.nickName)); |
| | | const selected = Array.isArray(reportForm.teamList) |
| | | ? reportForm.teamList |
| | | : []; |
| | | const extraNames = selected |
| | | .map(item => { |
| | | if (typeof item === "string") return String(item).trim(); |
| | | const name = item?.userName ?? item?.nickName ?? ""; |
| | | return String(name).trim(); |
| | | }) |
| | | .filter(Boolean) |
| | | .filter(name => !baseNameSet.has(name)); |
| | | const extras = extraNames.map(name => ({ userId: "", nickName: name })); |
| | | return [...base, ...extras]; |
| | | }); |
| | | function removeLastFour(str) { |
| | | if (!str) return ""; // 空值保护 |
| | | return str.toString().slice(0, -4); // 核心:截取 0 到 倒数第4位 |
| | |
| | | |
| | | const handleTeamListChange = val => { |
| | | if (!Array.isArray(val)) return; |
| | | if (!val.some(item => typeof item === "string")) return; |
| | | reportForm.teamList = val.map(item => { |
| | | let hasString = false; |
| | | const newList = val.map(item => { |
| | | if (typeof item === "string") { |
| | | hasString = true; |
| | | return { userName: item }; |
| | | } |
| | | return item; |
| | | }); |
| | | |
| | | if (hasString) { |
| | | reportForm.teamList = newList; |
| | | } |
| | | |
| | | // 解决 allow-create 在 multiple 模式下输入框内容不自动清空的问题 |
| | | setTimeout(() => { |
| | | if (teamSelectRef.value) { |
| | | // 1. 清除内部 query 状态 |
| | | teamSelectRef.value.query = ""; |
| | | if (teamSelectRef.value.states) { |
| | | teamSelectRef.value.states.query = ""; |
| | | teamSelectRef.value.states.inputValue = ""; |
| | | } |
| | | // 2. 强制清除 DOM 输入框的值 |
| | | const input = teamSelectRef.value.$el?.querySelector("input"); |
| | | if (input) { |
| | | input.value = ""; |
| | | } |
| | | // 3. 针对某些版本,重置选中标签的内部偏移(防止输入框被挤占) |
| | | if (typeof teamSelectRef.value.resetInputState === "function") { |
| | | teamSelectRef.value.resetInputState(); |
| | | } |
| | | } |
| | | }, 50); |
| | | }; |
| | | // 审核人 |
| | | const handleReviewerIdChange = userId => { |