|
|
|
|
@ -48,11 +48,25 @@
|
|
|
|
|
<el-transfer
|
|
|
|
|
v-model="form.machineIds"
|
|
|
|
|
:data="availableMachines"
|
|
|
|
|
:titles="['可选机床', '已绑定']"
|
|
|
|
|
:titles="['全部机床', '已绑定']"
|
|
|
|
|
:props="{ key: 'id', label: 'label' }"
|
|
|
|
|
filterable
|
|
|
|
|
filter-placeholder="搜索机床"
|
|
|
|
|
/>
|
|
|
|
|
>
|
|
|
|
|
<template #default="{ option }">
|
|
|
|
|
<span :class="['machine-transfer-item', getStatusClass(option)]">
|
|
|
|
|
<span class="status-dot"></span>
|
|
|
|
|
{{ option.name }}
|
|
|
|
|
<template v-if="option.deviceCode"> ({{ option.deviceCode }})</template>
|
|
|
|
|
<template v-if="option.workshopName"> - {{ option.workshopName }}</template>
|
|
|
|
|
</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-transfer>
|
|
|
|
|
<div class="transfer-legend">
|
|
|
|
|
<span><span class="status-dot online"></span>在线</span>
|
|
|
|
|
<span><span class="status-dot offline"></span>离线</span>
|
|
|
|
|
<span><span class="status-dot disabled"></span>停用</span>
|
|
|
|
|
</div>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
<template #footer><el-button @click="dialogVisible=false">取消</el-button><el-button type="primary" :loading="submitting" @click="handleSubmit">保存</el-button></template>
|
|
|
|
|
@ -72,7 +86,8 @@ const loading=ref(false);const tableData=ref<Worker[]>([]);const selectedRows=re
|
|
|
|
|
// 分页信息
|
|
|
|
|
const pagination=ref<{ currentPage: number; pageSize: number; total: number }>({ currentPage: 1, pageSize: 20, total: 0 })
|
|
|
|
|
const dialogVisible=ref(false);const submitting=ref(false);const editingId=ref<number|null>(null)
|
|
|
|
|
const availableMachines=ref<{ id: number; label: string; name: string }[]>([])
|
|
|
|
|
interface MachineItem { id: number; name: string; label: string; deviceCode?: string; workshopName?: string; isOnline: number; isEnabled: number }
|
|
|
|
|
const availableMachines=ref<MachineItem[]>([])
|
|
|
|
|
const query=reactive({isEnabled:undefined as number | undefined,keyword:''})
|
|
|
|
|
const form=reactive({code:'',name:'',machineIds:[] as number[]})
|
|
|
|
|
const workerForm=ref<FormInstance | null>(null)
|
|
|
|
|
@ -100,8 +115,38 @@ function handleEdit(row: Worker){editingId.value=row.id;Object.assign(form,{code
|
|
|
|
|
async function handleSubmit(){submitting.value=true;try{const ok = await (workerForm.value?.validate ? new Promise<boolean>((resolve)=>workerForm.value!.validate((valid:boolean)=>resolve(valid))) : Promise.resolve(true)); if(!ok){return} await request[editingId.value?'put':'post'](editingId.value?`/admin/worker/${editingId.value}`:'/admin/worker',{...form});ElMessage.success('保存成功');dialogVisible.value=false;loadData()}finally{submitting.value=false}}
|
|
|
|
|
async function handleDelete(row:any){await ElMessageBox.confirm('确定删除【'+row.name+'】?此操作不可恢复。','提示',{type:'warning'});await request.delete(`/admin/worker/${row.id}`);ElMessage.success('已删除');loadData()}
|
|
|
|
|
async function batchStatus(isEnabled:number){await ElMessageBox.confirm('确定对选中的'+selectedRows.value.length+'项操作?','提示',{type:'warning'});for(const id of selectedRows.value.map((r:any)=>r.id)){await request.put(`/admin/worker/${id}/toggle`,{isEnabled})};ElMessage.success('操作成功');loadData()}
|
|
|
|
|
async function loadDrops(){try{const r: ApiResponse<{ items: Array<{ id: number; name: string; deviceCode?: string; workshopName?: string }> }> = await request.get('/admin/worker/available-machines'); availableMachines.value = (r.data?.items ?? []).map(m => ({ id: m.id, name: m.name, label: `${m.deviceCode || m.name} (${m.name})${m.workshopName ? ' - ' + m.workshopName : ''}` }))}catch{/* 接口不可用时保持为空,不影响其他功能 */}}
|
|
|
|
|
async function loadDrops(){try{const r: ApiResponse<{ items: MachineItem[] }> = await request.get('/admin/machine',{params:{pageSize:999}}); availableMachines.value = (r.data?.items ?? []).map(m => ({ id: m.id, name: m.name, label: m.name, deviceCode: m.deviceCode, workshopName: m.workshopName, isOnline: m.isOnline, isEnabled: m.isEnabled }))}catch{/* 接口不可用时保持为空,不影响其他功能 */}}
|
|
|
|
|
/** 根据机床在线/启用状态返回样式类 */
|
|
|
|
|
function getStatusClass(m: MachineItem): string {
|
|
|
|
|
if (!m.isEnabled) return 'status-disabled'
|
|
|
|
|
if (m.isOnline) return 'status-online'
|
|
|
|
|
return 'status-offline'
|
|
|
|
|
}
|
|
|
|
|
function handlePageChange(page:number){pagination.value.currentPage=page;loadData()}
|
|
|
|
|
function handleSizeChange(size:number){pagination.value.pageSize=size;pagination.value.currentPage=1;loadData()}
|
|
|
|
|
onMounted(()=>{loadData();loadDrops()})
|
|
|
|
|
</script>
|
|
|
|
|
<style scoped>
|
|
|
|
|
/* 穿梭框状态色点 */
|
|
|
|
|
.status-dot {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
width: 8px;
|
|
|
|
|
height: 8px;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
margin-right: 6px;
|
|
|
|
|
vertical-align: middle;
|
|
|
|
|
}
|
|
|
|
|
.status-online .status-dot { background-color: #67c23a; }
|
|
|
|
|
.status-offline .status-dot { background-color: #c0c4cc; }
|
|
|
|
|
.status-disabled .status-dot { background-color: #f56c6c; }
|
|
|
|
|
/* 图例 */
|
|
|
|
|
.transfer-legend {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 16px;
|
|
|
|
|
margin-top: 8px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #909399;
|
|
|
|
|
align-items: center;
|
|
|
|
|
}
|
|
|
|
|
.transfer-legend .status-dot { margin-right: 4px; }
|
|
|
|
|
</style>
|
|
|
|
|
|