<script lang="ts" setup>
|
import type { MesMdWorkstationApi } from '#/api/mes/md/workstation';
|
|
import { IconifyIcon } from '@vben/icons';
|
|
defineOptions({ name: 'WorkbenchWorkstationPanel' });
|
|
defineProps<{
|
workstation?: MesMdWorkstationApi.Workstation;
|
}>();
|
|
const emit = defineEmits<{
|
change: [];
|
}>();
|
</script>
|
|
<template>
|
<section
|
class="ws-panel"
|
:class="{ 'ws-panel--empty': !workstation }"
|
>
|
<div class="ws-panel__head">
|
<div class="ws-panel__title-row">
|
<IconifyIcon icon="lucide:map-pin" class="ws-panel__icon" />
|
<span class="ws-panel__title">工作站</span>
|
</div>
|
<button
|
v-if="workstation"
|
type="button"
|
class="ws-panel__switch"
|
@click="emit('change')"
|
>
|
切换
|
</button>
|
</div>
|
|
<!-- 已选工作站 -->
|
<div v-if="workstation" class="ws-panel__device">
|
<span class="ws-panel__code">{{ workstation.code }}</span>
|
<span class="ws-panel__name">{{ workstation.name }}</span>
|
<span v-if="workstation.processName" class="ws-panel__process">
|
{{ workstation.processName }}
|
</span>
|
</div>
|
|
<!-- 未选工作站 -->
|
<div v-else class="ws-panel__placeholder">
|
<IconifyIcon icon="lucide:monitor" class="ws-panel__placeholder-icon" />
|
<p>尚未选择工作站</p>
|
<button type="button" class="ws-panel__select-btn" @click="emit('change')">
|
选择工作站
|
</button>
|
</div>
|
|
<div v-if="workstation" class="ws-panel__meta">
|
<div class="ws-panel__meta-item">
|
<span class="ws-panel__meta-label">车间</span>
|
<span class="ws-panel__meta-value">{{ workstation.workshopName ?? '—' }}</span>
|
</div>
|
<div class="ws-panel__meta-item">
|
<span class="ws-panel__meta-label">地点</span>
|
<span class="ws-panel__meta-value">{{ workstation.address ?? '—' }}</span>
|
</div>
|
</div>
|
</section>
|
</template>
|
|
<style lang="scss" scoped>
|
$radius: 10px;
|
$shadow: 0 2px 12px rgb(0 0 0 / 8%);
|
|
.ws-panel {
|
flex-shrink: 0;
|
padding: 14px 16px;
|
border-radius: $radius;
|
color: #fff;
|
background: linear-gradient(
|
128deg,
|
#3b82f6 0%,
|
#2563eb 38%,
|
#1d4ed8 100%
|
);
|
box-shadow: $shadow;
|
border: 1px solid rgb(255 255 255 / 14%);
|
|
&--empty {
|
.ws-panel__meta {
|
opacity: 0.72;
|
}
|
}
|
}
|
|
.ws-panel__head {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
gap: 10px;
|
margin-bottom: 12px;
|
}
|
|
.ws-panel__title-row {
|
display: flex;
|
align-items: center;
|
gap: 8px;
|
}
|
|
.ws-panel__icon {
|
font-size: 20px;
|
opacity: 0.95;
|
}
|
|
.ws-panel__title {
|
font-size: 17px;
|
font-weight: 600;
|
letter-spacing: 0.02em;
|
}
|
|
.ws-panel__switch {
|
flex-shrink: 0;
|
padding: 6px 14px;
|
border: 1px solid rgb(255 255 255 / 36%);
|
border-radius: 8px;
|
background: rgb(255 255 255 / 14%);
|
color: #fff;
|
font-size: 14px;
|
font-weight: 600;
|
cursor: pointer;
|
transition: background 0.2s;
|
|
&:hover {
|
background: rgb(255 255 255 / 24%);
|
}
|
}
|
|
.ws-panel__device {
|
display: flex;
|
align-items: center;
|
gap: 10px;
|
margin-bottom: 12px;
|
padding: 12px 16px;
|
border-radius: 12px;
|
background: linear-gradient(
|
135deg,
|
rgb(255 255 255 / 24%) 0%,
|
rgb(255 255 255 / 10%) 100%
|
);
|
border: 2px solid rgb(255 255 255 / 28%);
|
box-shadow:
|
inset 0 1px 0 rgb(255 255 255 / 22%),
|
0 8px 20px rgb(0 0 0 / 12%);
|
}
|
|
.ws-panel__code {
|
flex-shrink: 0;
|
font-size: 28px;
|
font-weight: 800;
|
letter-spacing: 0.04em;
|
line-height: 1;
|
color: #fff176;
|
text-shadow:
|
0 1px 2px rgb(0 0 0 / 35%),
|
0 0 12px rgb(255 241 118 / 45%);
|
}
|
|
.ws-panel__name {
|
flex: 1;
|
min-width: 0;
|
font-size: 17px;
|
font-weight: 700;
|
line-height: 1.2;
|
color: #fff9c4;
|
text-shadow: 0 1px 3px rgb(0 0 0 / 22%);
|
white-space: nowrap;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
}
|
|
.ws-panel__process {
|
flex-shrink: 0;
|
padding: 4px 12px;
|
border-radius: 999px;
|
font-size: 14px;
|
font-weight: 700;
|
background: rgb(255 193 7 / 92%);
|
color: #5c3d00;
|
box-shadow: 0 2px 8px rgb(0 0 0 / 12%);
|
}
|
|
.ws-panel__placeholder {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
gap: 10px;
|
margin-bottom: 12px;
|
padding: 18px 12px;
|
border-radius: 12px;
|
background: rgb(0 0 0 / 12%);
|
border: 1px dashed rgb(255 255 255 / 28%);
|
text-align: center;
|
|
p {
|
margin: 0;
|
font-size: 15px;
|
opacity: 0.92;
|
}
|
}
|
|
.ws-panel__placeholder-icon {
|
font-size: 32px;
|
opacity: 0.85;
|
}
|
|
.ws-panel__select-btn {
|
padding: 10px 24px;
|
border: 1px solid rgb(255 255 255 / 40%);
|
border-radius: 8px;
|
background: rgb(255 255 255 / 18%);
|
color: #fff;
|
font-size: 15px;
|
font-weight: 700;
|
cursor: pointer;
|
transition: all 0.2s;
|
min-height: 44px;
|
|
&:hover {
|
background: rgb(255 255 255 / 28%);
|
border-color: rgb(255 255 255 / 55%);
|
}
|
}
|
|
.ws-panel__meta {
|
display: grid;
|
grid-template-columns: 1fr 1fr;
|
gap: 10px;
|
}
|
|
.ws-panel__meta-item {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
gap: 10px;
|
padding: 8px 12px;
|
border-radius: 10px;
|
background: rgb(255 255 255 / 16%);
|
border: 1px solid rgb(255 255 255 / 22%);
|
}
|
|
.ws-panel__meta-label {
|
flex-shrink: 0;
|
font-size: 13px;
|
font-weight: 600;
|
opacity: 0.88;
|
}
|
|
.ws-panel__meta-value {
|
min-width: 0;
|
font-size: 14px;
|
font-weight: 700;
|
font-variant-numeric: tabular-nums;
|
color: #fff9c4;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
}
|
</style>
|