|
@@ -32,8 +32,8 @@
|
|
|
<div class="action-cards">
|
|
<div class="action-cards">
|
|
|
<!-- 空料箱上架 -->
|
|
<!-- 空料箱上架 -->
|
|
|
<div class="action-card" @click="handlePlaceEmptyBin(false)">
|
|
<div class="action-card" @click="handlePlaceEmptyBin(false)">
|
|
|
- <div class="card-border" />
|
|
|
|
|
- <div class="card-glow" />
|
|
|
|
|
|
|
+ <!-- <div class="card-border" /> -->
|
|
|
|
|
+ <!-- <div class="card-glow" /> -->
|
|
|
<div class="card-content">
|
|
<div class="card-content">
|
|
|
<div class="card-icon green">
|
|
<div class="card-icon green">
|
|
|
<i class="fas fa-arrow-up-from-bracket" />
|
|
<i class="fas fa-arrow-up-from-bracket" />
|
|
@@ -48,33 +48,41 @@
|
|
|
|
|
|
|
|
<!-- 请求空料箱 -->
|
|
<!-- 请求空料箱 -->
|
|
|
<div class="action-card" @click="handleRequestEmptyBin(false)">
|
|
<div class="action-card" @click="handleRequestEmptyBin(false)">
|
|
|
- <div class="card-border" />
|
|
|
|
|
- <div class="card-glow" />
|
|
|
|
|
<div class="card-content">
|
|
<div class="card-content">
|
|
|
<div class="card-icon blue">
|
|
<div class="card-icon blue">
|
|
|
<i class="fas fa-box-open" />
|
|
<i class="fas fa-box-open" />
|
|
|
</div>
|
|
</div>
|
|
|
<div class="card-label">请求空料箱</div>
|
|
<div class="card-label">请求空料箱</div>
|
|
|
- <!-- <div class="card-decoration">
|
|
|
|
|
- <div class="deco-line" />
|
|
|
|
|
- <div class="deco-corner" />
|
|
|
|
|
- </div> -->
|
|
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<!-- 请求校验 -->
|
|
<!-- 请求校验 -->
|
|
|
<div class="action-card" @click="handleRequestVerification(false)">
|
|
<div class="action-card" @click="handleRequestVerification(false)">
|
|
|
- <div class="card-border" />
|
|
|
|
|
- <div class="card-glow" />
|
|
|
|
|
<div class="card-content">
|
|
<div class="card-content">
|
|
|
<div class="card-icon orange">
|
|
<div class="card-icon orange">
|
|
|
<i class="fas fa-magnifying-glass-chart" />
|
|
<i class="fas fa-magnifying-glass-chart" />
|
|
|
</div>
|
|
</div>
|
|
|
<div class="card-label">工装/设备上架</div>
|
|
<div class="card-label">工装/设备上架</div>
|
|
|
- <!-- <div class="card-decoration">
|
|
|
|
|
- <div class="deco-line" />
|
|
|
|
|
- <div class="deco-corner" />
|
|
|
|
|
- </div> -->
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 成品上架 -->
|
|
|
|
|
+ <div class="action-card" @click="handleProductShelf(false)">
|
|
|
|
|
+ <div class="card-content">
|
|
|
|
|
+ <div class="card-icon purple">
|
|
|
|
|
+ <i class="fas fa-boxes-packing" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card-label">成品上架</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 成品下架 -->
|
|
|
|
|
+ <div class="action-card" @click="handleProductOffShelf">
|
|
|
|
|
+ <div class="card-content">
|
|
|
|
|
+ <div class="card-icon red">
|
|
|
|
|
+ <i class="fas fa-dolly" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card-label">成品下架</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -150,14 +158,233 @@
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 底部按钮 -->
|
|
|
|
|
+ <div class="dialog-footer">
|
|
|
|
|
+ <button v-if="showVerificationStatus" class="modal-btn primary-btn" @click="handleReverify">
|
|
|
|
|
+ <i class="fas fa-sync-alt" />
|
|
|
|
|
+ 重新校验
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button class="modal-btn close-action-btn" @click="closeDialog">
|
|
|
|
|
+ 关闭
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 成品上架弹窗 -->
|
|
|
|
|
+ <div v-if="showProductShelfDialog" class="tech-modal-overlay" @click.self="closeProductShelfDialog">
|
|
|
|
|
+ <div class="tech-modal product-modal">
|
|
|
|
|
+ <div class="modal-header">
|
|
|
|
|
+ <h3>成品上架</h3>
|
|
|
|
|
+ <button class="close-btn" @click="closeProductShelfDialog">
|
|
|
|
|
+ <i class="fas fa-times" />
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="dialog-content">
|
|
|
|
|
+ <!-- 状态标签 -->
|
|
|
|
|
+ <div class="verification-status">
|
|
|
|
|
+ <span class="status-tag" :class="productShelfSuccess ? 'success' : 'danger'">
|
|
|
|
|
+ <i :class="productShelfSuccess ? 'fas fa-check-circle' : 'fas fa-times-circle'" />
|
|
|
|
|
+ {{ productShelfSuccess ? '校验通过' : '校验未通过' }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <span v-if="productShelfError" class="status-tag danger">
|
|
|
|
|
+ {{ productShelfError }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 可滚动内容区域:包含双栏 + 已选成品 -->
|
|
|
|
|
+ <div class="dialog-main">
|
|
|
|
|
+ <!-- 双栏布局 -->
|
|
|
|
|
+ <div class="dialog-body">
|
|
|
|
|
+ <!-- 左侧:料箱列表 -->
|
|
|
|
|
+ <div class="list-section">
|
|
|
|
|
+ <h3 class="section-title">
|
|
|
|
|
+ <i class="fas fa-boxes" />
|
|
|
|
|
+ 料箱信息
|
|
|
|
|
+ </h3>
|
|
|
|
|
+ <div class="item-list">
|
|
|
|
|
+ <div v-for="bin in productShelfBinList" :key="bin.feedBoxId" class="item-card">
|
|
|
|
|
+ <div class="item-header">
|
|
|
|
|
+ <div class="item-info">
|
|
|
|
|
+ <div class="item-id">{{ bin.feedBoxName }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <span class="item-tag">{{ bin.feedBoxNo }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="productShelfBinList.length === 0" class="empty-tip">
|
|
|
|
|
+ 暂无料箱信息
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 右侧:根据校验状态显示不同内容 -->
|
|
|
|
|
+ <div class="list-section">
|
|
|
|
|
+ <template v-if="!productShelfSuccess">
|
|
|
|
|
+ <!-- 校验未通过时显示工装设备信息 -->
|
|
|
|
|
+ <h3 class="section-title">
|
|
|
|
|
+ <i class="fas fa-tools" />
|
|
|
|
|
+ 工装 / 设备信息
|
|
|
|
|
+ </h3>
|
|
|
|
|
+ <div class="item-list">
|
|
|
|
|
+ <div v-for="tool in productShelfToolList" :key="tool.inventoryNo" class="item-card">
|
|
|
|
|
+ <div class="item-info">
|
|
|
|
|
+ <div class="item-name">{{ tool.inventoryName }}</div>
|
|
|
|
|
+ <div class="item-id">编号: {{ tool.inventoryNo }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="productShelfToolList.length === 0" class="empty-tip">
|
|
|
|
|
+ 暂无工装/设备信息
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-else>
|
|
|
|
|
+ <!-- 校验通过时显示成品列表,可选择 -->
|
|
|
|
|
+ <h3 class="section-title">
|
|
|
|
|
+ <i class="fas fa-box" />
|
|
|
|
|
+ 成品信息(点击选择/取消)
|
|
|
|
|
+ </h3>
|
|
|
|
|
+ <div class="item-list">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="product in productShelfProductList" :key="product.productId" class="item-card selectable"
|
|
|
|
|
+ :class="{ selected: isProductSelected(product.productId) }"
|
|
|
|
|
+ @click="toggleProductSelection(product)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="item-header">
|
|
|
|
|
+ <div class="item-info">
|
|
|
|
|
+ <div class="item-name">{{ product.productName }}</div>
|
|
|
|
|
+ <div class="item-id">编号: {{ product.productNo }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <span v-if="isProductSelected(product.productId)" class="selected-icon">
|
|
|
|
|
+ <i class="fas fa-check-circle" />
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="productShelfProductList.length === 0" class="empty-tip">
|
|
|
|
|
+ 暂无成品信息
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 已选成品区域 -->
|
|
|
|
|
+ <!-- <div v-if="productShelfSuccess && selectedProducts.length > 0" class="selected-section">
|
|
|
|
|
+ <h3 class="section-title">
|
|
|
|
|
+ <i class="fas fa-clipboard-check" />
|
|
|
|
|
+ 已选成品({{ selectedProducts.length }})
|
|
|
|
|
+ </h3>
|
|
|
|
|
+ <div class="selected-list">
|
|
|
|
|
+ <div v-for="product in selectedProducts" :key="product.productId" class="selected-item">
|
|
|
|
|
+ <span class="selected-name">{{ product.productName }}</span>
|
|
|
|
|
+ <span class="selected-no">{{ product.productNo }}</span>
|
|
|
|
|
+ <button class="remove-btn" @click="removeSelectedProduct(product.productId)">
|
|
|
|
|
+ <i class="fas fa-times" />
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div> -->
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 底部按钮 -->
|
|
|
|
|
+ <div class="dialog-footer">
|
|
|
|
|
+ <button class="modal-btn primary-btn" @click="handleProductShelfReverify">
|
|
|
|
|
+ <i class="fas fa-sync-alt" />
|
|
|
|
|
+ 重新校验
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button v-if="!isEmptySubmit" class="modal-btn submit-btn" @click="submitProductShelf">
|
|
|
|
|
+ <i class="fas fa-arrow-up-from-bracket" />
|
|
|
|
|
+ 成品上架
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button v-else class="modal-btn submit-btn" @click="submitProductShelfEmpty">
|
|
|
|
|
+ <i class="fas fa-arrow-up-from-ground-water" />
|
|
|
|
|
+ 空料箱上架
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 成品下架弹窗 -->
|
|
|
|
|
+ <div v-if="showProductOffShelfDialog" class="tech-modal-overlay" @click.self="closeProductOffShelfDialog">
|
|
|
|
|
+ <div class="tech-modal product-modal">
|
|
|
|
|
+ <div class="modal-header">
|
|
|
|
|
+ <h3>成品下架</h3>
|
|
|
|
|
+ <button class="close-btn" @click="closeProductOffShelfDialog">
|
|
|
|
|
+ <i class="fas fa-times" />
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="dialog-content">
|
|
|
|
|
+ <!-- 可滚动内容区域:包含双栏 -->
|
|
|
|
|
+ <div class="dialog-main">
|
|
|
|
|
+ <!-- 双栏布局 -->
|
|
|
|
|
+ <div class="dialog-body">
|
|
|
|
|
+ <!-- 左侧:成品列表 -->
|
|
|
|
|
+ <div class="list-section">
|
|
|
|
|
+ <h3 class="section-title">
|
|
|
|
|
+ <i class="fas fa-box" />
|
|
|
|
|
+ 成品列表(点击选择)
|
|
|
|
|
+ </h3>
|
|
|
|
|
+ <div class="item-list">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="product in offShelfProductList" :key="product.id" class="item-card selectable"
|
|
|
|
|
+ :class="{ selected: isOffShelfProductSelected(product.id) }"
|
|
|
|
|
+ @click="toggleOffShelfProductSelection(product)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="item-header">
|
|
|
|
|
+ <div class="item-info">
|
|
|
|
|
+ <div class="item-name">{{ product.name }}</div>
|
|
|
|
|
+ <div class="item-id">编号: {{ product.no }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <span class="item-tag">{{ product.feedBoxName }}</span>
|
|
|
|
|
+ <span v-if="isOffShelfProductSelected(product.id)" class="selected-icon">
|
|
|
|
|
+ <i class="fas fa-check-circle" />
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="offShelfProductList.length === 0" class="empty-tip">
|
|
|
|
|
+ 暂无成品信息
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 右侧:已选成品 -->
|
|
|
|
|
+ <div class="list-section">
|
|
|
|
|
+ <h3 class="section-title">
|
|
|
|
|
+ <i class="fas fa-clipboard-check" />
|
|
|
|
|
+ 已选成品({{ selectedOffShelfProducts.length }})
|
|
|
|
|
+ </h3>
|
|
|
|
|
+ <div class="item-list">
|
|
|
|
|
+ <div v-for="product in selectedOffShelfProducts" :key="product.id" class="item-card selected-card">
|
|
|
|
|
+ <div class="item-header">
|
|
|
|
|
+ <div class="item-info">
|
|
|
|
|
+ <div class="item-name">{{ product.name }}</div>
|
|
|
|
|
+ <div class="item-id">编号: {{ product.no }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <span class="item-tag">{{ product.feedBoxName }}</span>
|
|
|
|
|
+ <button class="remove-btn" @click="removeOffShelfProduct(product.id)">
|
|
|
|
|
+ <i class="fas fa-times" />
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="selectedOffShelfProducts.length === 0" class="empty-tip">
|
|
|
|
|
+ 请从左侧选择要下架的成品
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
<!-- 底部按钮 -->
|
|
<!-- 底部按钮 -->
|
|
|
<div class="dialog-footer">
|
|
<div class="dialog-footer">
|
|
|
- <button v-if="showVerificationStatus" class="modal-btn primary-btn" @click="handleReverify">
|
|
|
|
|
- <i class="fas fa-sync-alt" />
|
|
|
|
|
- 重新校验
|
|
|
|
|
|
|
+ <button class="modal-btn submit-btn" @click="submitProductOffShelf">
|
|
|
|
|
+ <i class="fas fa-dolly" />
|
|
|
|
|
+ 成品下架
|
|
|
</button>
|
|
</button>
|
|
|
- <button class="modal-btn close-action-btn" @click="closeDialog">
|
|
|
|
|
|
|
+ <button class="modal-btn close-action-btn" @click="closeProductOffShelfDialog">
|
|
|
关闭
|
|
关闭
|
|
|
</button>
|
|
</button>
|
|
|
</div>
|
|
</div>
|
|
@@ -183,8 +410,11 @@
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
import { ref, onMounted, onUnmounted } from 'vue';
|
|
import { ref, onMounted, onUnmounted } from 'vue';
|
|
|
-import { showNotify, showToast } from 'vant';
|
|
|
|
|
-import { checkBlankBox, requestBlankBox, checkBlankBoxAndInventory } from '../api/blankBox.js';
|
|
|
|
|
|
|
+import { showNotify } from 'vant';
|
|
|
|
|
+import {
|
|
|
|
|
+ checkBlankBox, requestBlankBox, checkBlankBoxAndInventory, checkFeedBoxAndProduct, productRack,
|
|
|
|
|
+ findProductCanRemoved, productRemoved,
|
|
|
|
|
+} from '../api/blankBox.js';
|
|
|
import { useRouter } from 'vue-router';
|
|
import { useRouter } from 'vue-router';
|
|
|
|
|
|
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
@@ -201,6 +431,21 @@ const binList = ref([]);
|
|
|
|
|
|
|
|
const toolList = ref([]);
|
|
const toolList = ref([]);
|
|
|
|
|
|
|
|
|
|
+// 成品上架相关状态
|
|
|
|
|
+const showProductShelfDialog = ref(false);
|
|
|
|
|
+const productShelfSuccess = ref(false);
|
|
|
|
|
+const productShelfError = ref('');
|
|
|
|
|
+const productShelfBinList = ref([]);
|
|
|
|
|
+const productShelfToolList = ref([]);
|
|
|
|
|
+const productShelfProductList = ref([]);
|
|
|
|
|
+const selectedProducts = ref([]);
|
|
|
|
|
+const isEmptySubmit = ref(false); // 是否为成品空料箱上架
|
|
|
|
|
+
|
|
|
|
|
+// 成品下架相关状态
|
|
|
|
|
+const showProductOffShelfDialog = ref(false);
|
|
|
|
|
+const offShelfProductList = ref([]);
|
|
|
|
|
+const selectedOffShelfProducts = ref([]);
|
|
|
|
|
+
|
|
|
const goBack = () => {
|
|
const goBack = () => {
|
|
|
router.back();
|
|
router.back();
|
|
|
};
|
|
};
|
|
@@ -290,7 +535,7 @@ const handleRequestVerification = async isReverify => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleReverify = () => {
|
|
const handleReverify = () => {
|
|
|
- showNotify({ type: 'primary', message: '正在重新校验....', zIndex: 9999999 });
|
|
|
|
|
|
|
+ showNotify({ type: 'primary', message: '正在重新校验....', duration: 1000, zIndex: 9999999 });
|
|
|
if (dialogTitle.value === '上架结果') {
|
|
if (dialogTitle.value === '上架结果') {
|
|
|
handlePlaceEmptyBin();
|
|
handlePlaceEmptyBin();
|
|
|
} else if (dialogTitle.value === '校验结果')
|
|
} else if (dialogTitle.value === '校验结果')
|
|
@@ -302,6 +547,242 @@ const closeDialog = () => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+// 处理成品上架接口数据
|
|
|
|
|
+const handleProductShelfDataProcessing = (res, isReverify = false) => {
|
|
|
|
|
+ if (res.data) {
|
|
|
|
|
+ isEmptySubmit.value = false;
|
|
|
|
|
+ productShelfBinList.value = [];
|
|
|
|
|
+ productShelfToolList.value = [];
|
|
|
|
|
+ productShelfProductList.value = [];
|
|
|
|
|
+ if (!isReverify) {
|
|
|
|
|
+ selectedProducts.value = [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const { success, rfidFeedBoxResponseList, rfidInventoryResponseList, productResponseList, feedBoxDetailIds, blankFeedBox } = res.data;
|
|
|
|
|
+
|
|
|
|
|
+ if (!isReverify) showProductShelfDialog.value = true;
|
|
|
|
|
+
|
|
|
|
|
+ productShelfSuccess.value = success;
|
|
|
|
|
+ isEmptySubmit.value = blankFeedBox;
|
|
|
|
|
+
|
|
|
|
|
+ if (rfidFeedBoxResponseList && rfidFeedBoxResponseList.length > 0) {
|
|
|
|
|
+ productShelfBinList.value = rfidFeedBoxResponseList;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (rfidInventoryResponseList && rfidInventoryResponseList.length > 0) {
|
|
|
|
|
+ productShelfToolList.value = rfidInventoryResponseList;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (productResponseList && productResponseList.length > 0) {
|
|
|
|
|
+ productShelfProductList.value = productResponseList;
|
|
|
|
|
+
|
|
|
|
|
+ // 根据 feedBoxDetailIds 预选中对应成品
|
|
|
|
|
+ if (Array.isArray(feedBoxDetailIds) && feedBoxDetailIds.length > 0) {
|
|
|
|
|
+ const selectedIdSet = new Set(feedBoxDetailIds);
|
|
|
|
|
+ const preSelected = productResponseList.filter(p => selectedIdSet.has(p.productId));
|
|
|
|
|
+ if (preSelected.length > 0) {
|
|
|
|
|
+ selectedProducts.value = preSelected.map(p => ({ ...p }));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (res.errorCode !== 0) {
|
|
|
|
|
+ productShelfSuccess.value = false;
|
|
|
|
|
+ productShelfError.value = res.errorMessage;
|
|
|
|
|
+ showNotify({ type: 'danger', message: res.errorMessage, duration: 6000, zIndex: 9999999 });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ productShelfError.value = '';
|
|
|
|
|
+ }
|
|
|
|
|
+ if (res.data.blankFeedBox) productShelfError.value += ',您可以进行空料想上架';
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 成品上架点击
|
|
|
|
|
+const handleProductShelf = async (isReverify = false) => {
|
|
|
|
|
+ loading.value = true;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await checkFeedBoxAndProduct();
|
|
|
|
|
+ handleProductShelfDataProcessing(res, isReverify);
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('成品上架校验失败:', error);
|
|
|
|
|
+ productShelfSuccess.value = false;
|
|
|
|
|
+ showNotify({ type: 'danger', message: '成品上架校验API调用失败' });
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 重新校验成品上架
|
|
|
|
|
+const handleProductShelfReverify = () => {
|
|
|
|
|
+ showNotify({ type: 'primary', message: '正在重新校验....', duration: 1000, zIndex: 9999999 });
|
|
|
|
|
+ handleProductShelf(true);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 关闭成品上架弹窗
|
|
|
|
|
+const closeProductShelfDialog = () => {
|
|
|
|
|
+ showProductShelfDialog.value = false;
|
|
|
|
|
+ selectedProducts.value = [];
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 检查成品是否已选中
|
|
|
|
|
+const isProductSelected = productId => {
|
|
|
|
|
+ return selectedProducts.value.some(p => p.productId === productId);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 切换成品选中状态
|
|
|
|
|
+const toggleProductSelection = product => {
|
|
|
|
|
+ const index = selectedProducts.value.findIndex(p => p.productId === product.productId);
|
|
|
|
|
+ if (index > -1) {
|
|
|
|
|
+ selectedProducts.value.splice(index, 1);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ selectedProducts.value.push({ ...product });
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 移除已选成品
|
|
|
|
|
+const removeSelectedProduct = productId => {
|
|
|
|
|
+ const index = selectedProducts.value.findIndex(p => p.productId === productId);
|
|
|
|
|
+ if (index > -1) {
|
|
|
|
|
+ selectedProducts.value.splice(index, 1);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 提交成品上架
|
|
|
|
|
+const submitProductShelf = async () => {
|
|
|
|
|
+ console.log(productShelfSuccess.value);
|
|
|
|
|
+ if (!productShelfSuccess.value) {
|
|
|
|
|
+ showNotify({ type: 'danger', message: '校验未通过,请重新校验', duration: 3000, zIndex: 9999999 });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 校验: 是否选择了成品
|
|
|
|
|
+ if (selectedProducts.value.length === 0) {
|
|
|
|
|
+ showNotify({ type: 'danger', message: '请先选择要上架的成品', duration: 3000, zIndex: 9999999 });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取料箱ID和所选成品ID集合
|
|
|
|
|
+ const feedBoxId = productShelfBinList.value[0].feedBoxId;
|
|
|
|
|
+ const productIds = selectedProducts.value.map(p => p.productId);
|
|
|
|
|
+ const params = { feedBoxId, productIds };
|
|
|
|
|
+
|
|
|
|
|
+ console.log('成品上架提交数据:', params);
|
|
|
|
|
+
|
|
|
|
|
+ loading.value = true;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await productRack(params);
|
|
|
|
|
+ if (res.errorCode === 0) {
|
|
|
|
|
+ showNotify({ type: 'success', message: '成品上架成功', duration: 3000, zIndex: 9999999 });
|
|
|
|
|
+ closeProductShelfDialog();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showNotify({ type: 'danger', message: res.errorMessage, duration: 3000, zIndex: 9999999 });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ productShelfSuccess.value = false;
|
|
|
|
|
+ console.error('成品上架校验失败:', error);
|
|
|
|
|
+ showNotify({ type: 'danger', message: '成品上架校验API调用失败' });
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 提交成名空料箱上架
|
|
|
|
|
+const submitProductShelfEmpty = () => {
|
|
|
|
|
+ closeProductShelfDialog();
|
|
|
|
|
+ handlePlaceEmptyBin(false);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 成品下架点击
|
|
|
|
|
+const handleProductOffShelf = async () => {
|
|
|
|
|
+ offShelfProductList.value = [];
|
|
|
|
|
+ selectedOffShelfProducts.value = [];
|
|
|
|
|
+ loading.value = true;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await findProductCanRemoved();
|
|
|
|
|
+ if (res.errorCode === 0) {
|
|
|
|
|
+ if (res.datas && res.datas.length > 0) {
|
|
|
|
|
+ offShelfProductList.value = res.datas;
|
|
|
|
|
+ selectedOffShelfProducts.value = [];
|
|
|
|
|
+ showProductOffShelfDialog.value = true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ offShelfProductList.value = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showNotify({ type: 'danger', message: res.errorMessage, duration: 3000, zIndex: 9999999 });
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取成品下架列表失败:', error);
|
|
|
|
|
+ showNotify({ type: 'danger', message: '获取成品下架列表失败' });
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 关闭成品下架弹窗
|
|
|
|
|
+const closeProductOffShelfDialog = () => {
|
|
|
|
|
+ showProductOffShelfDialog.value = false;
|
|
|
|
|
+ selectedOffShelfProducts.value = [];
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 检查成品下架是否已选中
|
|
|
|
|
+const isOffShelfProductSelected = productId => {
|
|
|
|
|
+ return selectedOffShelfProducts.value.some(p => p.id === productId);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 切换成品下架选中状态
|
|
|
|
|
+const toggleOffShelfProductSelection = product => {
|
|
|
|
|
+ const index = selectedOffShelfProducts.value.findIndex(p => p.id === product.id);
|
|
|
|
|
+ if (index > -1) {
|
|
|
|
|
+ selectedOffShelfProducts.value.splice(index, 1);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ selectedOffShelfProducts.value.push({ ...product });
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 移除已选成品下架
|
|
|
|
|
+const removeOffShelfProduct = productId => {
|
|
|
|
|
+ const index = selectedOffShelfProducts.value.findIndex(p => p.id === productId);
|
|
|
|
|
+ if (index > -1) {
|
|
|
|
|
+ selectedOffShelfProducts.value.splice(index, 1);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 提交成品下架
|
|
|
|
|
+const submitProductOffShelf = async () => {
|
|
|
|
|
+ // 校验是否选择了成品
|
|
|
|
|
+ if (selectedOffShelfProducts.value.length === 0) {
|
|
|
|
|
+ showNotify({ type: 'danger', message: '请先选择要下架的成品', duration: 3000, zIndex: 9999999 });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取所选成品ID集合
|
|
|
|
|
+ const params = selectedOffShelfProducts.value.map(p => {
|
|
|
|
|
+ return {
|
|
|
|
|
+ id: p.id,
|
|
|
|
|
+ feedBoxId: p.feedBoxId,
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ console.log('成品下架提交数据:', params);
|
|
|
|
|
+
|
|
|
|
|
+ loading.value = true;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await productRemoved(params);
|
|
|
|
|
+ if (res.errorCode === 0) {
|
|
|
|
|
+ showNotify({ type: 'success', message: '成品下架成功', duration: 3000, zIndex: 9999999 });
|
|
|
|
|
+ closeProductOffShelfDialog();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showNotify({ type: 'danger', message: res.errorMessage, duration: 6000, zIndex: 9999999 });
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('成品下架API调用失败:', error);
|
|
|
|
|
+ showNotify({ type: 'danger', message: '成品下架API调用失败' });
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
const updateDateTime = () => {
|
|
const updateDateTime = () => {
|
|
|
const now = new Date();
|
|
const now = new Date();
|
|
|
const year = now.getFullYear();
|
|
const year = now.getFullYear();
|
|
@@ -524,9 +1005,9 @@ onUnmounted(() => {
|
|
|
position: relative;
|
|
position: relative;
|
|
|
z-index: 5;
|
|
z-index: 5;
|
|
|
flex: 1;
|
|
flex: 1;
|
|
|
- padding: 60px 40px;
|
|
|
|
|
|
|
+ padding: 40px 40px;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
- align-items: center;
|
|
|
|
|
|
|
+ align-items: flex-start;
|
|
|
justify-content: center;
|
|
justify-content: center;
|
|
|
overflow-y: auto;
|
|
overflow-y: auto;
|
|
|
overflow-x: hidden;
|
|
overflow-x: hidden;
|
|
@@ -544,7 +1025,7 @@ onUnmounted(() => {
|
|
|
|
|
|
|
|
.action-card {
|
|
.action-card {
|
|
|
position: relative;
|
|
position: relative;
|
|
|
- height: 350px;
|
|
|
|
|
|
|
+ height: 300px;
|
|
|
max-height: calc((100vh - 200px) / 1.5);
|
|
max-height: calc((100vh - 200px) / 1.5);
|
|
|
cursor: pointer;
|
|
cursor: pointer;
|
|
|
transition: all 0.4s ease;
|
|
transition: all 0.4s ease;
|
|
@@ -620,15 +1101,15 @@ onUnmounted(() => {
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
justify-content: center;
|
|
|
- gap: 40px;
|
|
|
|
|
|
|
+ gap: 30px;
|
|
|
backdrop-filter: blur(15px);
|
|
backdrop-filter: blur(15px);
|
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
box-shadow: inset 0 0 50px rgba(0, 255, 255, 0.1), 0 15px 50px rgba(0, 0, 0, 0.6);
|
|
box-shadow: inset 0 0 50px rgba(0, 255, 255, 0.1), 0 15px 50px rgba(0, 0, 0, 0.6);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.card-icon {
|
|
.card-icon {
|
|
|
- width: 160px;
|
|
|
|
|
- height: 160px;
|
|
|
|
|
|
|
+ width: 130px;
|
|
|
|
|
+ height: 130px;
|
|
|
border-radius: 50%;
|
|
border-radius: 50%;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
@@ -658,6 +1139,18 @@ onUnmounted(() => {
|
|
|
box-shadow: 0 0 50px rgba(255, 153, 0, 1), inset 0 0 30px rgba(255, 153, 0, 0.3);
|
|
box-shadow: 0 0 50px rgba(255, 153, 0, 1), inset 0 0 30px rgba(255, 153, 0, 0.3);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.card-icon.purple {
|
|
|
|
|
+ background: linear-gradient(135deg, rgba(153, 51, 255, 0.3), rgba(102, 0, 204, 0.3));
|
|
|
|
|
+ border-color: rgba(153, 51, 255, 0.8);
|
|
|
|
|
+ box-shadow: 0 0 50px rgba(153, 51, 255, 1), inset 0 0 30px rgba(153, 51, 255, 0.3);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.card-icon.red {
|
|
|
|
|
+ background: linear-gradient(135deg, rgba(255, 71, 87, 0.3), rgba(220, 20, 60, 0.3));
|
|
|
|
|
+ border-color: rgba(255, 71, 87, 0.8);
|
|
|
|
|
+ box-shadow: 0 0 50px rgba(255, 71, 87, 1), inset 0 0 30px rgba(255, 71, 87, 0.3);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
@keyframes iconPulse {
|
|
@keyframes iconPulse {
|
|
|
|
|
|
|
|
0%,
|
|
0%,
|
|
@@ -825,7 +1318,7 @@ onUnmounted(() => {
|
|
|
background: rgba(20, 30, 50, 0.6);
|
|
background: rgba(20, 30, 50, 0.6);
|
|
|
border-radius: 10px;
|
|
border-radius: 10px;
|
|
|
padding: 15px;
|
|
padding: 15px;
|
|
|
- margin-bottom: 15px;
|
|
|
|
|
|
|
+ margin-bottom: 4px;
|
|
|
border: 1px solid rgba(0, 153, 255, 0.3);
|
|
border: 1px solid rgba(0, 153, 255, 0.3);
|
|
|
transition: all 0.3s ease;
|
|
transition: all 0.3s ease;
|
|
|
}
|
|
}
|
|
@@ -982,7 +1475,7 @@ onUnmounted(() => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.action-card {
|
|
.action-card {
|
|
|
- height: 300px;
|
|
|
|
|
|
|
+ height: 260px;
|
|
|
max-height: calc((100vh - 180px) / 1.5);
|
|
max-height: calc((100vh - 180px) / 1.5);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1179,18 +1672,19 @@ onUnmounted(() => {
|
|
|
border-radius: 16px;
|
|
border-radius: 16px;
|
|
|
width: 90%;
|
|
width: 90%;
|
|
|
max-width: 800px;
|
|
max-width: 800px;
|
|
|
- max-height: 80vh;
|
|
|
|
|
|
|
+ max-height: 88vh;
|
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
box-shadow: 0 0 40px rgba(4, 159, 216, 0.3);
|
|
box-shadow: 0 0 40px rgba(4, 159, 216, 0.3);
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
|
|
+ padding: 20px 28px !important;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.modal-header {
|
|
.modal-header {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
|
- padding: 20px 25px;
|
|
|
|
|
|
|
+ padding: 14px 24px;
|
|
|
border-bottom: 1px solid rgba(4, 159, 216, 0.3);
|
|
border-bottom: 1px solid rgba(4, 159, 216, 0.3);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1222,9 +1716,11 @@ onUnmounted(() => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.dialog-content {
|
|
.dialog-content {
|
|
|
- padding: 20px 25px;
|
|
|
|
|
- overflow-y: auto;
|
|
|
|
|
|
|
+ padding: 14px 24px 20px;
|
|
|
|
|
+ overflow: hidden;
|
|
|
flex: 1;
|
|
flex: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.verification-status {
|
|
.verification-status {
|
|
@@ -1257,6 +1753,7 @@ onUnmounted(() => {
|
|
|
.dialog-body {
|
|
.dialog-body {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
gap: 20px;
|
|
gap: 20px;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.list-section {
|
|
.list-section {
|
|
@@ -1333,6 +1830,16 @@ onUnmounted(() => {
|
|
|
border-radius: 12px;
|
|
border-radius: 12px;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/* 弹窗中部滚动容器:双栏 + 已选成品 */
|
|
|
|
|
+.dialog-main {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 16px;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ padding-right: 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.result-header {
|
|
.result-header {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
@@ -1362,9 +1869,10 @@ onUnmounted(() => {
|
|
|
.dialog-footer {
|
|
.dialog-footer {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
gap: 15px;
|
|
gap: 15px;
|
|
|
- margin-top: 20px;
|
|
|
|
|
- padding-top: 20px;
|
|
|
|
|
|
|
+ margin-top: 16px;
|
|
|
|
|
+ padding-top: 16px;
|
|
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.modal-btn {
|
|
.modal-btn {
|
|
@@ -1401,6 +1909,113 @@ onUnmounted(() => {
|
|
|
background: rgba(42, 127, 255, 0.2);
|
|
background: rgba(42, 127, 255, 0.2);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/* ========== 成品上架/下架相关样式 ========== */
|
|
|
|
|
+.product-modal {
|
|
|
|
|
+ max-width: 900px;
|
|
|
|
|
+ max-height: 88vh;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-card.selectable {
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-card.selectable:hover {
|
|
|
|
|
+ background: rgba(4, 159, 216, 0.3);
|
|
|
|
|
+ border-color: rgba(4, 159, 216, 0.6);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-card.selected {
|
|
|
|
|
+ background: rgba(16, 185, 129, 0.3);
|
|
|
|
|
+ border-color: rgba(16, 185, 129, 0.8);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-card.selected-card {
|
|
|
|
|
+ background: rgba(16, 185, 129, 0.2);
|
|
|
|
|
+ border-color: rgba(16, 185, 129, 0.5);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selected-icon {
|
|
|
|
|
+ color: #34d399;
|
|
|
|
|
+ font-size: 20px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.empty-tip {
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ color: rgba(255, 255, 255, 0.5);
|
|
|
|
|
+ padding: 30px 0;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 已选成品区域 */
|
|
|
|
|
+.selected-section {
|
|
|
|
|
+ background: rgba(0, 0, 0, 0.2);
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ padding: 15px;
|
|
|
|
|
+ margin-top: 20px;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selected-list {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+ max-height: 180px;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selected-item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+ background: rgba(16, 185, 129, 0.2);
|
|
|
|
|
+ border: 1px solid rgba(16, 185, 129, 0.5);
|
|
|
|
|
+ border-radius: 20px;
|
|
|
|
|
+ padding: 8px 12px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selected-name {
|
|
|
|
|
+ color: #34d399;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selected-no {
|
|
|
|
|
+ color: rgba(255, 255, 255, 0.6);
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.remove-btn {
|
|
|
|
|
+ width: 22px;
|
|
|
|
|
+ height: 22px;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ background: rgba(239, 68, 68, 0.3);
|
|
|
|
|
+ border: 1px solid rgba(239, 68, 68, 0.5);
|
|
|
|
|
+ color: #f87171;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ transition: all 0.3s;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.remove-btn:hover {
|
|
|
|
|
+ background: rgba(239, 68, 68, 0.5);
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 提交按钮样式 */
|
|
|
|
|
+.submit-btn {
|
|
|
|
|
+ background: linear-gradient(90deg, #10b981 0%, #34d399 100%);
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.submit-btn:hover {
|
|
|
|
|
+ box-shadow: 0 0 20px rgba(16, 185, 129, 0.5);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/* 响应式 */
|
|
/* 响应式 */
|
|
|
@media screen and (max-width: 768px) {
|
|
@media screen and (max-width: 768px) {
|
|
|
.dialog-body {
|
|
.dialog-body {
|
|
@@ -1411,5 +2026,13 @@ onUnmounted(() => {
|
|
|
max-width: 95%;
|
|
max-width: 95%;
|
|
|
max-height: 90vh;
|
|
max-height: 90vh;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ .product-modal {
|
|
|
|
|
+ max-width: 95%;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .selected-list {
|
|
|
|
|
+ max-height: 100px;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|