|
|
@@ -168,12 +168,25 @@
|
|
|
<span class="add-icon">+</span>
|
|
|
</div>
|
|
|
<div
|
|
|
- v-for="(cell, cellIndex) in row.cells"
|
|
|
+ v-for="cell in row.cells"
|
|
|
:key="cell.id"
|
|
|
class="shelf-cell"
|
|
|
- :class="{ occupied: cell.slotStatus === '占用' }"
|
|
|
+ :class="{
|
|
|
+ occupied: cell.slotStatus === '占用',
|
|
|
+ 'is-outbound-selected': isSlotOutboundSelected(cell.id)
|
|
|
+ }"
|
|
|
@click="handleOpenOccupancyDialog(cell)"
|
|
|
>
|
|
|
+ <button
|
|
|
+ v-if="isSlotSelectableForOutbound(cell)"
|
|
|
+ class="cell-check-btn"
|
|
|
+ type="button"
|
|
|
+ title="选择出库"
|
|
|
+ :aria-pressed="isSlotOutboundSelected(cell.id)"
|
|
|
+ @click="toggleSlotOutboundSelect(cell, $event)"
|
|
|
+ >
|
|
|
+ <span class="cell-check-btn__mark">✓</span>
|
|
|
+ </button>
|
|
|
<button
|
|
|
class="cell-delete-btn"
|
|
|
@click.stop="handleDeleteSlot(cell)"
|
|
|
@@ -1286,13 +1299,10 @@
|
|
|
return cell?.slotStatus === '占用' && !!(cell?.storedOccupancyId || '').toString().trim()
|
|
|
}
|
|
|
|
|
|
- // Task 3 shelf-cell checkbox UI will call these helpers
|
|
|
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
function isSlotOutboundSelected(slotId: string): boolean {
|
|
|
return selectedOutboundMap.value.has(slotId)
|
|
|
}
|
|
|
|
|
|
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
function toggleSlotOutboundSelect(cell: any, ev?: Event) {
|
|
|
ev?.stopPropagation?.()
|
|
|
if (!isSlotSelectableForOutbound(cell)) return
|
|
|
@@ -2660,6 +2670,59 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ .cell-check-btn {
|
|
|
+ position: absolute;
|
|
|
+ top: 3px;
|
|
|
+ left: 3px;
|
|
|
+ width: 18px;
|
|
|
+ height: 18px;
|
|
|
+ padding: 0;
|
|
|
+ border: 1.5px solid #cbd5e1;
|
|
|
+ border-radius: 4px;
|
|
|
+ background: #fff;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ cursor: pointer;
|
|
|
+ z-index: 2;
|
|
|
+
|
|
|
+ .cell-check-btn__mark {
|
|
|
+ font-size: 11px;
|
|
|
+ line-height: 1;
|
|
|
+ color: transparent;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ border-color: var(--primary, #10b981);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .shelf-cell.is-outbound-selected {
|
|
|
+ outline: 2px solid var(--primary, #10b981);
|
|
|
+ outline-offset: 1px;
|
|
|
+ background: #ecfdf5;
|
|
|
+ border-color: #a7f3d0;
|
|
|
+
|
|
|
+ &.occupied {
|
|
|
+ background: #ecfdf5;
|
|
|
+ border-color: #a7f3d0;
|
|
|
+
|
|
|
+ .cell-product-name,
|
|
|
+ .cell-product-type {
|
|
|
+ color: var(--primary-dark, #059669);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .cell-check-btn {
|
|
|
+ background: var(--primary, #10b981);
|
|
|
+ border-color: var(--primary, #10b981);
|
|
|
+
|
|
|
+ .cell-check-btn__mark {
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
.cell-delete-btn {
|
|
|
position: absolute;
|
|
|
top: 0;
|