|
@@ -2,144 +2,163 @@
|
|
|
<template>
|
|
<template>
|
|
|
<div class="page-container">
|
|
<div class="page-container">
|
|
|
<!-- 顶部信息栏 -->
|
|
<!-- 顶部信息栏 -->
|
|
|
- <PageHeader />
|
|
|
|
|
|
|
+ <PageHeader title="拣货管理" />
|
|
|
|
|
|
|
|
<!-- 主内容区域 -->
|
|
<!-- 主内容区域 -->
|
|
|
<main class="main-content">
|
|
<main class="main-content">
|
|
|
<!-- 页面标题 -->
|
|
<!-- 页面标题 -->
|
|
|
- <div class="page-title">
|
|
|
|
|
|
|
+ <!-- <div class="page-title">
|
|
|
<h2>拣货管理</h2>
|
|
<h2>拣货管理</h2>
|
|
|
- </div>
|
|
|
|
|
|
|
+ </div> -->
|
|
|
|
|
|
|
|
<!-- 筛选区域 -->
|
|
<!-- 筛选区域 -->
|
|
|
- <FilterPanel :default-collapsed="false" :active-count="getActiveFilterCount()">
|
|
|
|
|
- <a-form layout="inline" class="filter-form">
|
|
|
|
|
- <a-form-item label="名称">
|
|
|
|
|
- <a-input
|
|
|
|
|
- v-model:value="filterForm.inventoryName" placeholder="输入名称" style="width: 150px"
|
|
|
|
|
|
|
+ <FilterPanel :default-collapsed="false" :enable-collapse="false" :active-count="getActiveFilterCount()">
|
|
|
|
|
+ <div class="filter-form">
|
|
|
|
|
+ <div class="filter-item">
|
|
|
|
|
+ <label class="filter-label">名称:</label>
|
|
|
|
|
+ <van-field
|
|
|
|
|
+ v-model="filterForm.inventoryName" placeholder="输入名称" class="filter-input"
|
|
|
@keyup.enter="getList"
|
|
@keyup.enter="getList"
|
|
|
/>
|
|
/>
|
|
|
- </a-form-item>
|
|
|
|
|
- <a-form-item label="编号">
|
|
|
|
|
- <a-input
|
|
|
|
|
- v-model:value="filterForm.inventoryNo" placeholder="输入编号" style="width: 150px"
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="filter-item">
|
|
|
|
|
+ <label class="filter-label">编号:</label>
|
|
|
|
|
+ <van-field
|
|
|
|
|
+ v-model="filterForm.inventoryNo" placeholder="输入编号" class="filter-input"
|
|
|
@keyup.enter="getList"
|
|
@keyup.enter="getList"
|
|
|
/>
|
|
/>
|
|
|
- </a-form-item>
|
|
|
|
|
- <a-form-item label="类型">
|
|
|
|
|
- <a-select
|
|
|
|
|
- v-model:value="filterForm.inventoryType" placeholder="选择类型" option-filter-prop="label" show-search
|
|
|
|
|
- allow-clear style="width: 150px" :options="inventoryTypeList" @change="getList"
|
|
|
|
|
- />
|
|
|
|
|
- </a-form-item>
|
|
|
|
|
- <a-form-item label="仓库">
|
|
|
|
|
- <a-select
|
|
|
|
|
- v-model:value="filterForm.warehouseId" :options="warehouseList" placeholder="选择仓库"
|
|
|
|
|
- option-filter-prop="name" show-search allow-clear :field-names="{ label: 'name', value: 'id' }"
|
|
|
|
|
- style="width: 150px" @change="getList"
|
|
|
|
|
- />
|
|
|
|
|
- </a-form-item>
|
|
|
|
|
- <a-form-item label="货位">
|
|
|
|
|
- <a-input
|
|
|
|
|
- v-model:value="filterForm.positionName" placeholder="输入货位名称" style="width: 150px"
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="filter-item">
|
|
|
|
|
+ <label class="filter-label">类型:</label>
|
|
|
|
|
+ <v-select
|
|
|
|
|
+ v-model="filterForm.inventoryType" :options="inventoryTypeList" :reduce="item => item.value"
|
|
|
|
|
+ label="label" placeholder="选择类型" :clearable="true" :filterable="true" class="filter-select"
|
|
|
|
|
+ @update:model-value="getList"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #no-options>
|
|
|
|
|
+ <span>无该选项数据</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </v-select>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="filter-item">
|
|
|
|
|
+ <label class="filter-label">仓库:</label>
|
|
|
|
|
+ <v-select
|
|
|
|
|
+ v-model="filterForm.warehouseId" :options="warehouseList" :reduce="item => item.id" label="name"
|
|
|
|
|
+ placeholder="选择仓库" :clearable="true" :filterable="true" class="filter-select"
|
|
|
|
|
+ @update:model-value="getList"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #no-options>
|
|
|
|
|
+ <span>无该选项数据</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </v-select>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="filter-item">
|
|
|
|
|
+ <label class="filter-label">货位:</label>
|
|
|
|
|
+ <van-field
|
|
|
|
|
+ v-model="filterForm.positionName" placeholder="输入货位名称" class="filter-input"
|
|
|
@keyup.enter="getList"
|
|
@keyup.enter="getList"
|
|
|
/>
|
|
/>
|
|
|
- </a-form-item>
|
|
|
|
|
- <a-form-item>
|
|
|
|
|
- <a-button type="primary" @click="getList">
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="filter-item filter-buttons">
|
|
|
|
|
+ <van-button type="primary" @click="getList">
|
|
|
<i class="fas fa-search mr-1" /> 搜索
|
|
<i class="fas fa-search mr-1" /> 搜索
|
|
|
- </a-button>
|
|
|
|
|
- <a-button class="ml-2" @click="handleReset">
|
|
|
|
|
|
|
+ </van-button>
|
|
|
|
|
+ <van-button class="ml-2" @click="handleReset">
|
|
|
<i class="fas fa-redo mr-1" /> 重置
|
|
<i class="fas fa-redo mr-1" /> 重置
|
|
|
- </a-button>
|
|
|
|
|
- </a-form-item>
|
|
|
|
|
- </a-form>
|
|
|
|
|
|
|
+ </van-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
</FilterPanel>
|
|
</FilterPanel>
|
|
|
|
|
|
|
|
<!-- 卡片容器 -->
|
|
<!-- 卡片容器 -->
|
|
|
<div class="card-container">
|
|
<div class="card-container">
|
|
|
- <!-- 卡片列表区域(可滚动) -->
|
|
|
|
|
|
|
+ <!-- 全选控制栏 -->
|
|
|
|
|
+ <div v-if="materialList.length > 0" class="select-all-bar">
|
|
|
|
|
+ <van-checkbox :model-value="isAllSelected" @update:model-value="toggleSelectAll">
|
|
|
|
|
+ <span class="select-all-text">全选当前页(已选 {{ selectedIds.length }} 项)</span>
|
|
|
|
|
+ </van-checkbox>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 卡片列表区域 -->
|
|
|
<div class="card-list-wrapper">
|
|
<div class="card-list-wrapper">
|
|
|
- <a-empty v-if="materialList.length === 0" description="暂无数据" :image="Empty.PRESENTED_IMAGE_SIMPLE" />
|
|
|
|
|
|
|
+ <!-- 空状态 -->
|
|
|
|
|
+ <van-empty v-if="materialList.length === 0" description="暂无数据" />
|
|
|
|
|
|
|
|
<!-- 卡片列表 -->
|
|
<!-- 卡片列表 -->
|
|
|
<div v-else class="card-list">
|
|
<div v-else class="card-list">
|
|
|
- <a-card
|
|
|
|
|
- v-for="(item, index) in materialList" :key="item.id || index" :hoverable="true"
|
|
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="(item, index) in materialList" :key="item.id || index"
|
|
|
:class="{ 'selected-card': selectedIds.includes(item.id) }" class="inventory-card"
|
|
:class="{ 'selected-card': selectedIds.includes(item.id) }" class="inventory-card"
|
|
|
@click="toggleSelect(item.id)"
|
|
@click="toggleSelect(item.id)"
|
|
|
>
|
|
>
|
|
|
- <template #title>
|
|
|
|
|
- <div class="card-header">
|
|
|
|
|
- <div class="card-header-left">
|
|
|
|
|
- <a-checkbox
|
|
|
|
|
- :checked="selectedIds.includes(item.id)" @click.stop
|
|
|
|
|
- @change="e => handleCheckboxChange(e, item.id)"
|
|
|
|
|
- />
|
|
|
|
|
- <a-avatar :size="42" :style="{ backgroundColor: '#3b82f6' }" class="ml-3">
|
|
|
|
|
- <template #icon>
|
|
|
|
|
- <i :class="getInventoryIcon(item.inventoryType)" style="font-size: 20px;" />
|
|
|
|
|
- </template>
|
|
|
|
|
- </a-avatar>
|
|
|
|
|
- <div class="ml-4 card-title-info">
|
|
|
|
|
- <div class="card-name">{{ item.inventoryName }}</div>
|
|
|
|
|
- <div class="card-subtitle">编号: {{ item.inventoryNo }}</div>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <div class="card-header">
|
|
|
|
|
+ <div class="card-header-left">
|
|
|
|
|
+ <van-checkbox
|
|
|
|
|
+ :model-value="selectedIds.includes(item.id)" @click.stop
|
|
|
|
|
+ @update:model-value="checked => handleCheckboxChange(checked, item.id)"
|
|
|
|
|
+ />
|
|
|
|
|
+ <div class="custom-avatar ml-3">
|
|
|
|
|
+ <i :class="getInventoryIcon(item.inventoryType)" />
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="card-header-right">
|
|
|
|
|
- <div class="card-location">
|
|
|
|
|
- <i class="fas fa-map-marker-alt mr-2" />
|
|
|
|
|
- <span>{{ item.positionName || '-' }}</span>
|
|
|
|
|
- <span class="mx-2">/</span>
|
|
|
|
|
- <span>{{ item.warehouseName || '-' }}</span>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <div class="ml-4 card-title-info">
|
|
|
|
|
+ <div class="card-name">{{ item.inventoryName }}</div>
|
|
|
|
|
+ <div class="card-subtitle">编号: {{ item.inventoryNo }}</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- </template>
|
|
|
|
|
|
|
+ <div class="card-header-right">
|
|
|
|
|
+ <div class="card-location">
|
|
|
|
|
+ <i class="fas fa-map-marker-alt mr-2" />
|
|
|
|
|
+ <span>{{ item.positionName || '-' }}</span>
|
|
|
|
|
+ <span class="mx-2">/</span>
|
|
|
|
|
+ <span>{{ item.warehouseName || '-' }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
<!-- 卡片展开内容:配送方式选择(只有选中时显示) -->
|
|
<!-- 卡片展开内容:配送方式选择(只有选中时显示) -->
|
|
|
- <template v-if="selectedIds.includes(item.id)">
|
|
|
|
|
- <div class="card-delivery-section" @click.stop>
|
|
|
|
|
- <!-- <div class="delivery-section-title">
|
|
|
|
|
- <i class="fas fa-truck mr-2" />
|
|
|
|
|
- 配送方式设置
|
|
|
|
|
- </div> -->
|
|
|
|
|
-
|
|
|
|
|
- <div class="delivery-options">
|
|
|
|
|
- <!-- 配送方式选择 -->
|
|
|
|
|
- <div class="delivery-option-item">
|
|
|
|
|
- <label class="option-label">配送方式:</label>
|
|
|
|
|
- <a-radio-group
|
|
|
|
|
- v-model:value="item.deliveryMethod" button-style="solid"
|
|
|
|
|
- @change="handleDeliveryMethodChange(item)"
|
|
|
|
|
|
|
+ <div v-if="selectedIds.includes(item.id)" class="card-delivery-section" @click.stop>
|
|
|
|
|
+ <div class="delivery-options">
|
|
|
|
|
+ <!-- 配送方式选择 -->
|
|
|
|
|
+ <div class="delivery-option-item">
|
|
|
|
|
+ <label class="option-label">配送方式:</label>
|
|
|
|
|
+ <div class="delivery-method-buttons">
|
|
|
|
|
+ <button
|
|
|
|
|
+ :class="['delivery-btn', 'agv-btn', { 'active': item.deliveryMethod === 'AGV_Delivery', 'disabled': item.deliveryType === '人工配送' }]"
|
|
|
|
|
+ :disabled="item.deliveryType === '人工配送'" @click="changeDeliveryMethod(item, 'AGV_Delivery')"
|
|
|
>
|
|
>
|
|
|
- <a-radio-button value="AGV_Delivery" :disabled="item.deliveryType === '人工配送'">
|
|
|
|
|
- <i class="fas fa-robot mr-1" /> AGV 配送
|
|
|
|
|
- </a-radio-button>
|
|
|
|
|
- <a-radio-button value="Manual_Delivery" :disabled="item.deliveryType === '强制AGV配送'">
|
|
|
|
|
- <i class="fas fa-user mr-1" /> 人工配送
|
|
|
|
|
- </a-radio-button>
|
|
|
|
|
- </a-radio-group>
|
|
|
|
|
- <span
|
|
|
|
|
- v-if="item.deliveryType" class="delivery-type-badge"
|
|
|
|
|
- :class="getDeliveryTypeBadgeClass(item.deliveryType)"
|
|
|
|
|
|
|
+ <i class="fas fa-robot" /> AGV 配送
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button
|
|
|
|
|
+ :class="['delivery-btn', 'manual-btn', { 'active': item.deliveryMethod === 'Manual_Delivery', 'disabled': item.deliveryType === '强制AGV配送' }]"
|
|
|
|
|
+ :disabled="item.deliveryType === '强制AGV配送'"
|
|
|
|
|
+ @click="changeDeliveryMethod(item, 'Manual_Delivery')"
|
|
|
>
|
|
>
|
|
|
- {{ item.deliveryType }}
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+ <i class="fas fa-user" /> 人工配送
|
|
|
|
|
+ </button>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <span
|
|
|
|
|
+ v-if="item.deliveryType" class="delivery-type-badge"
|
|
|
|
|
+ :class="getDeliveryTypeBadgeClass(item.deliveryType)"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ item.deliveryType }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
- <!-- 配送位置选择(仅 AGV 配送时显示) -->
|
|
|
|
|
- <div v-if="item.deliveryMethod === 'AGV_Delivery'" class="delivery-location-item">
|
|
|
|
|
- <label class="option-label">配送位置:</label>
|
|
|
|
|
- <a-select
|
|
|
|
|
- v-model:value="item.selectedLocation" placeholder="请选择" style="width: 200px"
|
|
|
|
|
- :options="locator"
|
|
|
|
|
- />
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <!-- 配送位置选择(仅 AGV 配送时显示) -->
|
|
|
|
|
+ <div v-if="item.deliveryMethod === 'AGV_Delivery'" class="delivery-location-item">
|
|
|
|
|
+ <label class="option-label">配送位置:</label>
|
|
|
|
|
+ <v-select
|
|
|
|
|
+ v-model="item.selectedLocation" :options="locator" placeholder="请选择" :clearable="false"
|
|
|
|
|
+ class="location-select"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #no-options>
|
|
|
|
|
+ <span>无该选项数据</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </v-select>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- </template>
|
|
|
|
|
- </a-card>
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -148,28 +167,38 @@
|
|
|
<span class="text-gray-600">共 {{ materialList.length }} 条数据</span>
|
|
<span class="text-gray-600">共 {{ materialList.length }} 条数据</span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
-
|
|
|
|
|
- <!-- 底部完成按钮 -->
|
|
|
|
|
- <div class="bottom-actions">
|
|
|
|
|
- <a-button
|
|
|
|
|
- type="primary" size="large" :disabled="selectedIds.length === 0" class="shadow-sm"
|
|
|
|
|
- @click="handleComplete"
|
|
|
|
|
- >
|
|
|
|
|
- <template #icon>
|
|
|
|
|
- <i class="fas fa-check-circle mr-2" />
|
|
|
|
|
- </template>
|
|
|
|
|
- 拣货 ({{ selectedIds.length }})
|
|
|
|
|
- </a-button>
|
|
|
|
|
- </div>
|
|
|
|
|
</main>
|
|
</main>
|
|
|
|
|
+ <!-- 底部完成按钮 -->
|
|
|
|
|
+ <div class="bottom-actions">
|
|
|
|
|
+ <van-button
|
|
|
|
|
+ type="primary" size="large" :disabled="selectedIds.length === 0" class="complete-btn"
|
|
|
|
|
+ @click="handleComplete"
|
|
|
|
|
+ >
|
|
|
|
|
+ <i class="fas fa-check-circle mr-2" />
|
|
|
|
|
+ 拣货 ({{ selectedIds.length }})
|
|
|
|
|
+ </van-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 拣货完成确认弹窗 -->
|
|
|
|
|
+ <van-dialog
|
|
|
|
|
+ v-model:show="completeModalVisible" title="拣货完成" show-cancel-button class-name="large-dialog"
|
|
|
|
|
+ confirm-button-text="确认" cancel-button-text="取消" @confirm="handleCompleteConfirm" @cancel="handleCompleteCancel"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="large-dialog-content">
|
|
|
|
|
+ <p>领料申请已完成,配送任务已创建!请确认是否返回主页?</p>
|
|
|
|
|
+ <!-- <p class="dialog-subtitle">如果是请点击【确认】按钮</p> -->
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </van-dialog>
|
|
|
</div>
|
|
</div>
|
|
|
<Loading v-if="loading" />
|
|
<Loading v-if="loading" />
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
import { useRouter } from 'vue-router';
|
|
import { useRouter } from 'vue-router';
|
|
|
-import { ref, reactive, onMounted } from 'vue';
|
|
|
|
|
-import { message, Empty } from 'ant-design-vue';
|
|
|
|
|
|
|
+import { ref, reactive, computed, onMounted } from 'vue';
|
|
|
|
|
+import { showNotify } from 'vant';
|
|
|
|
|
+import vSelect from 'vue-select';
|
|
|
|
|
+import 'vue-select/dist/vue-select.css';
|
|
|
import PageHeader from '../common/PageHeader.vue';
|
|
import PageHeader from '../common/PageHeader.vue';
|
|
|
import FilterPanel from '../common/FilterPanel.vue';
|
|
import FilterPanel from '../common/FilterPanel.vue';
|
|
|
import { list, createStockOut } from '../api/stockOut.js';
|
|
import { list, createStockOut } from '../api/stockOut.js';
|
|
@@ -195,6 +224,9 @@ const inventoryTypeList = ref([
|
|
|
// 表格加载状态
|
|
// 表格加载状态
|
|
|
const loading = ref(false);
|
|
const loading = ref(false);
|
|
|
|
|
|
|
|
|
|
+// 完成弹窗控制
|
|
|
|
|
+const completeModalVisible = ref(false);
|
|
|
|
|
+
|
|
|
// 物料列表数据
|
|
// 物料列表数据
|
|
|
const materialList = ref([]);
|
|
const materialList = ref([]);
|
|
|
|
|
|
|
@@ -209,6 +241,12 @@ const pagination = reactive({
|
|
|
const selectedIds = ref([]);
|
|
const selectedIds = ref([]);
|
|
|
const selectedRows = ref([]);
|
|
const selectedRows = ref([]);
|
|
|
|
|
|
|
|
|
|
+// 计算是否全选
|
|
|
|
|
+const isAllSelected = computed(() => {
|
|
|
|
|
+ if (materialList.value.length === 0) return false;
|
|
|
|
|
+ return materialList.value.every(item => selectedIds.value.includes(item.id));
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
// 可配送位置
|
|
// 可配送位置
|
|
|
const locator = ref([]);
|
|
const locator = ref([]);
|
|
|
|
|
|
|
@@ -262,8 +300,8 @@ const toggleSelect = id => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// 处理复选框变化
|
|
// 处理复选框变化
|
|
|
-const handleCheckboxChange = (e, id) => {
|
|
|
|
|
- if (e.target.checked) {
|
|
|
|
|
|
|
+const handleCheckboxChange = (checked, id) => {
|
|
|
|
|
+ if (checked) {
|
|
|
if (!selectedIds.value.includes(id)) {
|
|
if (!selectedIds.value.includes(id)) {
|
|
|
selectedIds.value.push(id);
|
|
selectedIds.value.push(id);
|
|
|
const item = materialList.value.find(item => item.id === id);
|
|
const item = materialList.value.find(item => item.id === id);
|
|
@@ -282,6 +320,25 @@ const handleCheckboxChange = (e, id) => {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+// 全选/取消全选
|
|
|
|
|
+const toggleSelectAll = checked => {
|
|
|
|
|
+ if (checked) {
|
|
|
|
|
+ // 全选当前页所有项(累加模式)
|
|
|
|
|
+ materialList.value.forEach(item => {
|
|
|
|
|
+ if (!selectedIds.value.includes(item.id)) {
|
|
|
|
|
+ selectedIds.value.push(item.id);
|
|
|
|
|
+ initDeliveryMethod(item);
|
|
|
|
|
+ selectedRows.value.push(item);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 取消全选当前页
|
|
|
|
|
+ const currentPageIds = materialList.value.map(item => item.id);
|
|
|
|
|
+ selectedIds.value = selectedIds.value.filter(id => !currentPageIds.includes(id));
|
|
|
|
|
+ selectedRows.value = selectedRows.value.filter(row => !currentPageIds.includes(row.id));
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
// 获取设备类型图标
|
|
// 获取设备类型图标
|
|
|
const getInventoryIcon = type => {
|
|
const getInventoryIcon = type => {
|
|
|
const iconMap = {
|
|
const iconMap = {
|
|
@@ -325,7 +382,7 @@ const addToRequisition = record => {
|
|
|
// 领料申请,直接验证并提交
|
|
// 领料申请,直接验证并提交
|
|
|
const handleComplete = async () => {
|
|
const handleComplete = async () => {
|
|
|
if (selectedIds.value.length === 0) {
|
|
if (selectedIds.value.length === 0) {
|
|
|
- message.warning('请选择物料加入领料申请!');
|
|
|
|
|
|
|
+ showNotify({ type: 'warning', message: '请至少选择一个物料' });
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -334,7 +391,7 @@ const handleComplete = async () => {
|
|
|
const hasEmptyLocation = agvItems.some(item => !item.selectedLocation);
|
|
const hasEmptyLocation = agvItems.some(item => !item.selectedLocation);
|
|
|
|
|
|
|
|
if (hasEmptyLocation) {
|
|
if (hasEmptyLocation) {
|
|
|
- message.warning('请为所有 AGV 配送的物料选择配送位置');
|
|
|
|
|
|
|
+ showNotify({ type: 'warning', message: '请为所有 AGV 配送的物料选择配送位置' });
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -343,7 +400,7 @@ const handleComplete = async () => {
|
|
|
params.push({
|
|
params.push({
|
|
|
stockOutPrepareLineId: item.id,
|
|
stockOutPrepareLineId: item.id,
|
|
|
deliveryMethod: item.deliveryMethod,
|
|
deliveryMethod: item.deliveryMethod,
|
|
|
- positionEndNo: item.selectedLocation,
|
|
|
|
|
|
|
+ positionEndNo: item.selectedLocation.value,
|
|
|
});
|
|
});
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -353,12 +410,13 @@ const handleComplete = async () => {
|
|
|
|
|
|
|
|
|
|
|
|
|
// 配送方式变更处理
|
|
// 配送方式变更处理
|
|
|
-const handleDeliveryMethodChange = record => {
|
|
|
|
|
|
|
+const changeDeliveryMethod = (item, method) => {
|
|
|
|
|
+ item.deliveryMethod = method;
|
|
|
// 当选择人工配送时,清空配送位置
|
|
// 当选择人工配送时,清空配送位置
|
|
|
- if (record.deliveryMethod === 'Manual_Delivery') {
|
|
|
|
|
- record.selectedLocation = '';
|
|
|
|
|
|
|
+ if (method === 'Manual_Delivery') {
|
|
|
|
|
+ item.selectedLocation = '';
|
|
|
}
|
|
}
|
|
|
- console.log('配送方式变更:', record.inventoryName, record.deliveryMethod);
|
|
|
|
|
|
|
+ console.log('配送方式变更:', item.inventoryName, item.deliveryMethod);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
@@ -421,11 +479,12 @@ const getList = async () => {
|
|
|
materialList.value = [];
|
|
materialList.value = [];
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- message.error(res.errorMessage);
|
|
|
|
|
|
|
+ showNotify({ type: 'danger', message: res.errorMessage });
|
|
|
}
|
|
}
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
loading.value = false;
|
|
loading.value = false;
|
|
|
console.error('获取物料列表API调用失败:', error);
|
|
console.error('获取物料列表API调用失败:', error);
|
|
|
|
|
+ showNotify({ type: 'danger', message: '获取物料列表API调用失败' });
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
@@ -436,23 +495,37 @@ const generateCFStockOut = async params => {
|
|
|
const res = await createStockOut(params);
|
|
const res = await createStockOut(params);
|
|
|
|
|
|
|
|
if (res.errorCode === 0) {
|
|
if (res.errorCode === 0) {
|
|
|
- message.success('领料申请已完成,配送任务已创建!');
|
|
|
|
|
|
|
+ showNotify({ type: 'success', message: '领料完成' });
|
|
|
selectedIds.value = [];
|
|
selectedIds.value = [];
|
|
|
selectedRows.value = [];
|
|
selectedRows.value = [];
|
|
|
- // getList();
|
|
|
|
|
- router.push('/home');
|
|
|
|
|
|
|
+ // 显示完成确认弹窗
|
|
|
|
|
+ completeModalVisible.value = true;
|
|
|
} else {
|
|
} else {
|
|
|
- message.error(res.errorMessage);
|
|
|
|
|
|
|
+ showNotify({ type: 'danger', message: res.errorMessage });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('生成CF出库单API调用失败:', error);
|
|
console.error('生成CF出库单API调用失败:', error);
|
|
|
- message.error('生成CF出库单API调用失败');
|
|
|
|
|
|
|
+ showNotify({ type: 'danger', message: '生成CF出库单API调用失败' });
|
|
|
} finally {
|
|
} finally {
|
|
|
loading.value = false;
|
|
loading.value = false;
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+// 处理完成确认
|
|
|
|
|
+const handleCompleteConfirm = () => {
|
|
|
|
|
+ completeModalVisible.value = false;
|
|
|
|
|
+ router.push('/home');
|
|
|
|
|
+ // showToast('领料申请已完成,配送任务已创建!');
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 处理完成取消
|
|
|
|
|
+const handleCompleteCancel = () => {
|
|
|
|
|
+ completeModalVisible.value = false;
|
|
|
|
|
+ // 留在当前页面,刷新列表
|
|
|
|
|
+ getList();
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
// 获取仓库列表
|
|
// 获取仓库列表
|
|
|
const getWarehouse = async () => {
|
|
const getWarehouse = async () => {
|
|
|
try {
|
|
try {
|
|
@@ -465,11 +538,11 @@ const getWarehouse = async () => {
|
|
|
warehouseList.value = [];
|
|
warehouseList.value = [];
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- message.error(res.errorMessage);
|
|
|
|
|
|
|
+ showNotify({ type: 'danger', message: res.errorMessage });
|
|
|
}
|
|
}
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('获取仓库列表API调用失败:', error);
|
|
console.error('获取仓库列表API调用失败:', error);
|
|
|
- message.error('获取仓库列表API调用失败');
|
|
|
|
|
|
|
+ showNotify({ type: 'danger', message: '获取仓库列表API调用失败' });
|
|
|
} finally {
|
|
} finally {
|
|
|
loading.value = false;
|
|
loading.value = false;
|
|
|
}
|
|
}
|
|
@@ -491,11 +564,11 @@ const getIdleLocator = async () => {
|
|
|
locator.value = [];
|
|
locator.value = [];
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- message.error(res.errorMessage);
|
|
|
|
|
|
|
+ showNotify({ type: 'warning', message: res.errorMessage });
|
|
|
}
|
|
}
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('获取空闲货位API调用失败:', error);
|
|
console.error('获取空闲货位API调用失败:', error);
|
|
|
- message.error('获取空闲货位API调用失败');
|
|
|
|
|
|
|
+ showNotify({ type: 'danger', message: '获取空闲货位API调用失败' });
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -504,19 +577,6 @@ onMounted(() => {
|
|
|
getList();
|
|
getList();
|
|
|
getIdleLocator();
|
|
getIdleLocator();
|
|
|
});
|
|
});
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-// 获取分页参数
|
|
|
|
|
-// const getPageParams = (current, pageSize) => {
|
|
|
|
|
-// pagination.start = current;
|
|
|
|
|
-// pagination.lang = pageSize;
|
|
|
|
|
-// getList();
|
|
|
|
|
-// };
|
|
|
|
|
-
|
|
|
|
|
-// 查询回到第一页
|
|
|
|
|
-// const getDatas = () => {
|
|
|
|
|
-// commonTableRef.value.backFirstPage();
|
|
|
|
|
-// };
|
|
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
@@ -533,7 +593,7 @@ onMounted(() => {
|
|
|
.main-content {
|
|
.main-content {
|
|
|
flex: 1;
|
|
flex: 1;
|
|
|
overflow-y: auto;
|
|
overflow-y: auto;
|
|
|
- padding: 1.5rem;
|
|
|
|
|
|
|
+ padding: 1rem;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
}
|
|
}
|
|
@@ -574,14 +634,21 @@ onMounted(() => {
|
|
|
.card-list {
|
|
.card-list {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
- gap: 1rem;
|
|
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.card-list > * {
|
|
|
|
|
+ margin-bottom: 1rem;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.card-list > *:last-child {
|
|
|
|
|
+ margin-bottom: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* 分页包装器(固定底部) */
|
|
/* 分页包装器(固定底部) */
|
|
|
.pagination-wrapper {
|
|
.pagination-wrapper {
|
|
|
padding: 0.5rem 1.5rem;
|
|
padding: 0.5rem 1.5rem;
|
|
|
border-top: 1px solid #e5e7eb;
|
|
border-top: 1px solid #e5e7eb;
|
|
|
- border-bottom: 1px solid #e5e7eb;
|
|
|
|
|
background-color: #fafafa;
|
|
background-color: #fafafa;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
justify-content: flex-end;
|
|
justify-content: flex-end;
|
|
@@ -592,7 +659,7 @@ onMounted(() => {
|
|
|
.bottom-actions {
|
|
.bottom-actions {
|
|
|
position: sticky;
|
|
position: sticky;
|
|
|
bottom: 0;
|
|
bottom: 0;
|
|
|
- padding: 1rem 1rem 0 1rem;
|
|
|
|
|
|
|
+ padding: 0 1rem 1rem 1rem;
|
|
|
background-color: #f9fafb;
|
|
background-color: #f9fafb;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
justify-content: flex-end;
|
|
justify-content: flex-end;
|
|
@@ -603,16 +670,108 @@ onMounted(() => {
|
|
|
.filter-form {
|
|
.filter-form {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
flex-wrap: wrap;
|
|
|
- gap: 0.5rem;
|
|
|
|
|
|
|
+ align-items: center;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-:deep(.ant-form-item) {
|
|
|
|
|
- margin-bottom: 0 !important;
|
|
|
|
|
|
|
+.filter-form > * {
|
|
|
|
|
+ margin-right: 1rem;
|
|
|
|
|
+ margin-bottom: 0.4rem;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-:deep(.ant-form-item-label > label) {
|
|
|
|
|
- font-size: 14px !important;
|
|
|
|
|
- font-weight: 600 !important;
|
|
|
|
|
|
|
+.filter-item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.filter-item > * {
|
|
|
|
|
+ margin-right: 0.5rem;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.filter-item > *:last-child {
|
|
|
|
|
+ margin-right: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.filter-label {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ color: #374151;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.filter-select {
|
|
|
|
|
+ width: 200px;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ z-index: 100;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.filter-input {
|
|
|
|
|
+ width: 200px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.filter-input .van-cell) {
|
|
|
|
|
+ padding: 8px 12px !important;
|
|
|
|
|
+ border: 1px solid #ccc !important;
|
|
|
|
|
+ border-radius: 4px !important;
|
|
|
|
|
+ background-color: white !important;
|
|
|
|
|
+ min-height: 32px !important;
|
|
|
|
|
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.filter-input .van-cell::after) {
|
|
|
|
|
+ display: none !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.filter-input .van-field__body) {
|
|
|
|
|
+ border: none !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.filter-input .van-field__control) {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* Vue Select 样式 */
|
|
|
|
|
+:deep(.v-select) {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.v-select .vs__dropdown-toggle) {
|
|
|
|
|
+ border: 1px solid #d1d5db;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ padding: 4px 8px;
|
|
|
|
|
+ min-height: 32px;
|
|
|
|
|
+ background: white;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.v-select .vs__dropdown-menu) {
|
|
|
|
|
+ z-index: 9999 !important;
|
|
|
|
|
+ border: 1px solid #d1d5db;
|
|
|
|
|
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.v-select .vs__selected) {
|
|
|
|
|
+ margin: 2px;
|
|
|
|
|
+ padding: 0 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.v-select .vs__search) {
|
|
|
|
|
+ padding: 0;
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.v-select .vs__actions) {
|
|
|
|
|
+ padding: 0 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.filter-buttons {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.filter-buttons > * {
|
|
|
|
|
+ margin-right: 0.5rem;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.filter-buttons > *:last-child {
|
|
|
|
|
+ margin-right: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* 库存卡片样式 */
|
|
/* 库存卡片样式 */
|
|
@@ -641,7 +800,15 @@ onMounted(() => {
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
- gap: 1.5rem;
|
|
|
|
|
|
|
+ padding: 1rem 1.5rem;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.card-header > * {
|
|
|
|
|
+ margin-right: 1.5rem;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.card-header > *:last-child {
|
|
|
|
|
+ margin-right: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.card-header-left {
|
|
.card-header-left {
|
|
@@ -654,19 +821,33 @@ onMounted(() => {
|
|
|
.card-header-right {
|
|
.card-header-right {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
- gap: 1rem;
|
|
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.card-header-right > * {
|
|
|
|
|
+ margin-left: 1rem;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.card-header-right > *:first-child {
|
|
|
|
|
+ margin-left: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* 卡片标题信息 */
|
|
/* 卡片标题信息 */
|
|
|
.card-title-info {
|
|
.card-title-info {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
- gap: 0.25rem;
|
|
|
|
|
min-width: 0;
|
|
min-width: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.card-title-info > * {
|
|
|
|
|
+ margin-bottom: 0.25rem;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.card-title-info > *:last-child {
|
|
|
|
|
+ margin-bottom: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.card-name {
|
|
.card-name {
|
|
|
- font-size: 1.125rem;
|
|
|
|
|
|
|
+ font-size: 1.2rem;
|
|
|
font-weight: 600;
|
|
font-weight: 600;
|
|
|
color: #111827;
|
|
color: #111827;
|
|
|
line-height: 1.5;
|
|
line-height: 1.5;
|
|
@@ -697,21 +878,18 @@ onMounted(() => {
|
|
|
color: #3b82f6;
|
|
color: #3b82f6;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 卡片标题样式 */
|
|
|
|
|
-:deep(.ant-card-head) {
|
|
|
|
|
- border-bottom: none;
|
|
|
|
|
- padding: 1rem 1.5rem;
|
|
|
|
|
- min-height: auto;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-:deep(.ant-card-head-title) {
|
|
|
|
|
- padding: 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/* 卡片内容区域 - 选中时显示 */
|
|
|
|
|
-:deep(.ant-card-body) {
|
|
|
|
|
- padding: 0;
|
|
|
|
|
- display: block;
|
|
|
|
|
|
|
+/* 自定义头像 */
|
|
|
|
|
+.custom-avatar {
|
|
|
|
|
+ width: 42px;
|
|
|
|
|
+ height: 42px;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ background-color: #3b82f6;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ font-size: 20px;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* 卡片配送方式选择区域 */
|
|
/* 卡片配送方式选择区域 */
|
|
@@ -719,41 +897,44 @@ onMounted(() => {
|
|
|
padding: 1rem 1.5rem;
|
|
padding: 1rem 1.5rem;
|
|
|
background-color: #f8fafc;
|
|
background-color: #f8fafc;
|
|
|
border-top: 1px solid #e5e7eb;
|
|
border-top: 1px solid #e5e7eb;
|
|
|
- margin-top: 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.delivery-section-title {
|
|
|
|
|
- font-size: 0.9375rem;
|
|
|
|
|
- font-weight: 600;
|
|
|
|
|
- color: #1f2937;
|
|
|
|
|
- margin-bottom: 1rem;
|
|
|
|
|
- display: flex;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.delivery-section-title i {
|
|
|
|
|
- color: #3b82f6;
|
|
|
|
|
- font-size: 1rem;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.delivery-options {
|
|
.delivery-options {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: row;
|
|
flex-direction: row;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
- gap: 2rem;
|
|
|
|
|
flex-wrap: wrap;
|
|
flex-wrap: wrap;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.delivery-options > * {
|
|
|
|
|
+ margin-right: 2rem;
|
|
|
|
|
+ margin-bottom: 1rem;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.delivery-option-item {
|
|
.delivery-option-item {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
- gap: 0.75rem;
|
|
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.delivery-option-item > * {
|
|
|
|
|
+ margin-right: 0.75rem;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.delivery-option-item > *:last-child {
|
|
|
|
|
+ margin-right: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.delivery-location-item {
|
|
.delivery-location-item {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
- gap: 0.75rem;
|
|
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.delivery-location-item > * {
|
|
|
|
|
+ margin-right: 0.75rem;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.delivery-location-item > *:last-child {
|
|
|
|
|
+ margin-right: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.option-label {
|
|
.option-label {
|
|
@@ -764,6 +945,82 @@ onMounted(() => {
|
|
|
margin: 0;
|
|
margin: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/* 配送方式按钮容器 */
|
|
|
|
|
+.delivery-method-buttons {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 配送方式按钮样式 */
|
|
|
|
|
+.delivery-btn {
|
|
|
|
|
+ display: inline-flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ padding: 6px 16px;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ border: 1px solid #d1d5db;
|
|
|
|
|
+ background-color: white;
|
|
|
|
|
+ color: #374151;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ transition: all 0.2s;
|
|
|
|
|
+ height: 32px;
|
|
|
|
|
+ min-width: 110px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.delivery-btn > * {
|
|
|
|
|
+ margin-right: 6px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.delivery-btn > *:last-child {
|
|
|
|
|
+ margin-right: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.delivery-btn:first-child {
|
|
|
|
|
+ border-radius: 4px 0 0 4px;
|
|
|
|
|
+ border-right: none;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.delivery-btn:last-child {
|
|
|
|
|
+ border-radius: 0 4px 4px 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.delivery-btn i {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* AGV配送按钮 - 蓝色 */
|
|
|
|
|
+.delivery-btn.agv-btn.active {
|
|
|
|
|
+ background-color: #3b82f6;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ border-color: #3b82f6;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.delivery-btn.agv-btn:hover:not(.disabled):not(.active) {
|
|
|
|
|
+ background-color: #eff6ff;
|
|
|
|
|
+ border-color: #3b82f6;
|
|
|
|
|
+ color: #3b82f6;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 人工配送按钮 - 蓝色 */
|
|
|
|
|
+.delivery-btn.manual-btn.active {
|
|
|
|
|
+ background-color: #3b82f6;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ border-color: #3b82f6;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.delivery-btn.manual-btn:hover:not(.disabled):not(.active) {
|
|
|
|
|
+ background-color: #f3f4f6;
|
|
|
|
|
+ border-color: #9ca3af;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 禁用状态 */
|
|
|
|
|
+.delivery-btn.disabled {
|
|
|
|
|
+ opacity: 0.5;
|
|
|
|
|
+ cursor: not-allowed;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.delivery-type-badge {
|
|
.delivery-type-badge {
|
|
|
margin-left: 0.75rem;
|
|
margin-left: 0.75rem;
|
|
|
padding: 0.25rem 0.625rem;
|
|
padding: 0.25rem 0.625rem;
|
|
@@ -791,37 +1048,147 @@ onMounted(() => {
|
|
|
color: #065f46;
|
|
color: #065f46;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* Radio Group 样式优化 */
|
|
|
|
|
-:deep(.ant-radio-button-wrapper) {
|
|
|
|
|
- display: inline-flex;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- height: 32px;
|
|
|
|
|
- padding: 0 15px;
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-:deep(.ant-radio-button-wrapper i) {
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/* Select 样式优化 */
|
|
|
|
|
-:deep(.ant-select) {
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
|
|
+/* 配送位置选择器样式 */
|
|
|
|
|
+.location-select {
|
|
|
|
|
+ width: 200px;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* 按钮样式 */
|
|
/* 按钮样式 */
|
|
|
-:deep(.ant-btn-primary) {
|
|
|
|
|
|
|
+:deep(.van-button--primary) {
|
|
|
background-color: #3b82f6;
|
|
background-color: #3b82f6;
|
|
|
border-color: #3b82f6;
|
|
border-color: #3b82f6;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-:deep(.ant-btn-primary:hover) {
|
|
|
|
|
|
|
+:deep(.van-button--primary:active) {
|
|
|
background-color: #2563eb;
|
|
background-color: #2563eb;
|
|
|
border-color: #2563eb;
|
|
border-color: #2563eb;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-:deep(.ant-btn[disabled]) {
|
|
|
|
|
|
|
+.complete-btn {
|
|
|
|
|
+ background-color: #10b981 !important;
|
|
|
|
|
+ border-color: #10b981 !important;
|
|
|
|
|
+ width: auto;
|
|
|
|
|
+ padding: 0 24px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.complete-btn.van-button--primary) {
|
|
|
|
|
+ background-color: #10b981 !important;
|
|
|
|
|
+ border-color: #10b981 !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.complete-btn.van-button--primary:active) {
|
|
|
|
|
+ background-color: #059669 !important;
|
|
|
|
|
+ border-color: #059669 !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.van-button--disabled) {
|
|
|
opacity: 0.5;
|
|
opacity: 0.5;
|
|
|
cursor: not-allowed;
|
|
cursor: not-allowed;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.van-cell) {
|
|
|
|
|
+ border: 1px solid #ddd;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ padding: 6px 8px !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.v-select .vs__dropdown-toggle) {
|
|
|
|
|
+ padding: 6px 8px !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 全选控制栏 */
|
|
|
|
|
+.select-all-bar {
|
|
|
|
|
+ background-color: white;
|
|
|
|
|
+ padding: 1rem 1.5rem;
|
|
|
|
|
+ border-bottom: 1px solid #e5e7eb;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.select-all-text {
|
|
|
|
|
+ font-size: 0.95rem;
|
|
|
|
|
+ color: #374151;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 大弹窗样式,适合触摸屏 */
|
|
|
|
|
+:deep(.large-dialog) {
|
|
|
|
|
+ width: 85vw !important;
|
|
|
|
|
+ max-width: 600px !important;
|
|
|
|
|
+ border-radius: 16px !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.large-dialog .van-dialog__header) {
|
|
|
|
|
+ padding: 2rem 1.5rem 1rem !important;
|
|
|
|
|
+ font-size: 1.5rem !important;
|
|
|
|
|
+ font-weight: 700 !important;
|
|
|
|
|
+ color: #111827 !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.large-dialog-content {
|
|
|
|
|
+ padding: 1.5rem 2rem 2.5rem !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.large-dialog-content p {
|
|
|
|
|
+ margin: 0 0 1rem 0;
|
|
|
|
|
+ font-size: 1.25rem !important;
|
|
|
|
|
+ line-height: 1.8 !important;
|
|
|
|
|
+ color: #374151 !important;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.large-dialog-content p:last-child {
|
|
|
|
|
+ margin-bottom: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.large-dialog-content .dialog-subtitle {
|
|
|
|
|
+ font-size: 1.125rem !important;
|
|
|
|
|
+ color: #6b7280 !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.large-dialog .van-dialog__footer) {
|
|
|
|
|
+ padding: 1rem 1.5rem 1.5rem !important;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.large-dialog .van-dialog__footer > *) {
|
|
|
|
|
+ margin-right: 1rem;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.large-dialog .van-dialog__footer > *:last-child) {
|
|
|
|
|
+ margin-right: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.large-dialog .van-dialog__cancel),
|
|
|
|
|
+:deep(.large-dialog .van-dialog__confirm) {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ height: 56px !important;
|
|
|
|
|
+ font-size: 1.125rem !important;
|
|
|
|
|
+ font-weight: 600 !important;
|
|
|
|
|
+ border-radius: 8px !important;
|
|
|
|
|
+ border: none !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.large-dialog .van-dialog__cancel) {
|
|
|
|
|
+ background-color: #f3f4f6 !important;
|
|
|
|
|
+ color: #374151 !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.large-dialog .van-dialog__cancel:active) {
|
|
|
|
|
+ background-color: #e5e7eb !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.large-dialog .van-dialog__confirm) {
|
|
|
|
|
+ background-color: #10b981 !important;
|
|
|
|
|
+ color: white !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.large-dialog .van-dialog__confirm:active) {
|
|
|
|
|
+ background-color: #059669 !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 大弹窗蒙层 */
|
|
|
|
|
+:deep(.van-overlay) {
|
|
|
|
|
+ background-color: rgba(0, 0, 0, 0.6) !important;
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|