From b3f2fb5aef5945a5b7790d41cdb9504d1650c1e5 Mon Sep 17 00:00:00 2001
From: zss <zss@example.com>
Date: 星期三, 18 三月 2026 17:04:40 +0800
Subject: [PATCH] 能耗成本核算---按日月汇总统计页面对接
---
src/views/productionManagement/processRoute/processRouteItem/index.vue | 1563 +++++++++++++++++++++++++++++++--------------------------
1 files changed, 845 insertions(+), 718 deletions(-)
diff --git a/src/views/productionManagement/processRoute/processRouteItem/index.vue b/src/views/productionManagement/processRoute/processRouteItem/index.vue
index 0eb639d..ce3ee0b 100644
--- a/src/views/productionManagement/processRoute/processRouteItem/index.vue
+++ b/src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -1,9 +1,10 @@
<template>
<div class="app-container">
<PageHeader content="宸ヨ壓璺嚎椤圭洰" />
-
<!-- 宸ヨ壓璺嚎淇℃伅灞曠ず -->
- <el-card v-if="routeInfo.processRouteCode" class="route-info-card" shadow="hover">
+ <el-card v-if="routeInfo.processRouteCode"
+ class="route-info-card"
+ shadow="hover">
<div class="route-info">
<div class="info-item">
<div class="info-label-wrapper">
@@ -37,7 +38,8 @@
<span class="info-value">{{ routeInfo.bomNo || '-' }}</span>
</div>
</div>
- <div class="info-item full-width" v-if="routeInfo.description">
+ <div class="info-item full-width"
+ v-if="routeInfo.description">
<div class="info-label-wrapper">
<span class="info-label">鎻忚堪</span>
</div>
@@ -47,436 +49,292 @@
</div>
</div>
</el-card>
-
+ <!-- bom灞曠ず -->
<!-- 琛ㄦ牸瑙嗗浘 -->
- <div v-if="viewMode === 'table'" class="section-header">
+ <div v-if="viewMode === 'table'"
+ class="section-header">
<div class="section-title">宸ヨ壓璺嚎椤圭洰鍒楄〃</div>
<div class="section-actions">
- <el-button
- icon="Grid"
- @click="toggleView"
- style="margin-right: 10px;"
- >
+ <el-button icon="Grid"
+ @click="toggleView"
+ style="margin-right: 10px;">
鍗$墖瑙嗗浘
</el-button>
- <el-button type="primary" @click="handleAdd">鏂板</el-button>
+ <el-button type="primary"
+ @click="handleAdd">鏂板</el-button>
</div>
</div>
- <el-table
- v-if="viewMode === 'table'"
- ref="tableRef"
- v-loading="tableLoading"
- border
- :data="tableData"
- :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
- row-key="id"
- tooltip-effect="dark"
- class="lims-table"
- >
- <el-table-column align="center" label="搴忓彿" width="60" type="index" />
- <el-table-column label="宸ュ簭鍚嶇О" prop="processId" width="200">
+ <el-table v-if="viewMode === 'table'"
+ ref="tableRef"
+ v-loading="tableLoading"
+ border
+ :data="tableData"
+ :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
+ row-key="id"
+ tooltip-effect="dark"
+ class="lims-table">
+ <el-table-column align="center"
+ label="搴忓彿"
+ width="60"
+ type="index" />
+ <el-table-column label="宸ュ簭鍚嶇О"
+ prop="processId"
+ width="200">
<template #default="scope">
{{ getProcessName(scope.row.processId) || '-' }}
</template>
</el-table-column>
- <el-table-column label="浜у搧鍚嶇О" prop="productName" min-width="160" />
- <el-table-column label="瑙勬牸鍚嶇О" prop="model" min-width="140" />
- <el-table-column label="鍗曚綅" prop="unit" width="100" />
- <el-table-column label="鏄惁璐ㄦ" prop="isQuality" width="100">
+ <el-table-column label="浜у搧鍚嶇О"
+ prop="productName"
+ min-width="160" />
+ <el-table-column label="瑙勬牸鍚嶇О"
+ prop="model"
+ min-width="140" />
+ <el-table-column label="鍙傛暟鍒楄〃"
+ min-width="160">
+ <template #default="scope">
+ <el-button type="primary"
+ link
+ size="small"
+ @click="handleViewParams(scope.row)">鍙傛暟鍒楄〃</el-button>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍗曚綅"
+ prop="unit"
+ width="100" />
+ <el-table-column label="鏄惁璐ㄦ"
+ prop="isQuality"
+ width="100">
<template #default="scope">
{{scope.row.isQuality ? "鏄�" : "鍚�"}}
</template>
</el-table-column>
- <el-table-column label="鎿嶄綔" align="center" fixed="right" width="150">
+ <el-table-column label="鎿嶄綔"
+ align="center"
+ fixed="right"
+ width="150">
<template #default="scope">
- <el-button type="primary" link size="small" @click="handleEdit(scope.row)" :disabled="scope.row.isComplete">缂栬緫</el-button>
- <el-button type="danger" link size="small" @click="handleDelete(scope.row)" :disabled="scope.row.isComplete">鍒犻櫎</el-button>
+ <el-button type="primary"
+ link
+ size="small"
+ @click="handleEdit(scope.row)"
+ :disabled="scope.row.isComplete">缂栬緫</el-button>
+ <!-- <el-button type="info"
+ link
+ size="small"
+ @click="handleViewParams(scope.row)">鍙傛暟鍒楄〃</el-button> -->
+ <el-button type="danger"
+ link
+ size="small"
+ @click="handleDelete(scope.row)"
+ :disabled="scope.row.isComplete">鍒犻櫎</el-button>
</template>
</el-table-column>
</el-table>
-
<!-- 鍗$墖瑙嗗浘 -->
<template v-else>
<div class="section-header">
<div class="section-title">宸ヨ壓璺嚎椤圭洰鍒楄〃</div>
<div class="section-actions">
- <el-button
- icon="Menu"
- @click="toggleView"
- style="margin-right: 10px;"
- >
+ <el-button icon="Menu"
+ @click="toggleView"
+ style="margin-right: 10px;">
琛ㄦ牸瑙嗗浘
</el-button>
- <el-button type="primary" @click="handleAdd">鏂板</el-button>
+ <el-button type="primary"
+ @click="handleAdd">鏂板</el-button>
</div>
</div>
- <div v-loading="tableLoading" class="card-container">
- <div
- ref="cardsContainer"
- class="cards-wrapper"
- >
- <div
- v-for="(item, index) in tableData"
- :key="item.id || index"
- class="process-card"
- :data-index="index"
- >
- <!-- 搴忓彿鍦嗗湀 -->
- <div class="card-header">
- <div class="card-number">{{ index + 1 }}</div>
- <div class="card-process-name">{{ getProcessName(item.processId) || '-' }}</div>
- </div>
-
- <!-- 浜у搧淇℃伅 -->
- <div class="card-content">
- <div v-if="item.productName" class="product-info">
- <div class="product-name">{{ item.productName }}</div>
- <div v-if="item.model" class="product-model">
- {{ item.model }}
- <!-- <span v-if="item.unit" class="product-unit">{{ item.unit }}</span> -->
- </div>
- <el-tag type="primary" class="product-tag" v-if="item.isQuality">璐ㄦ</el-tag>
+ <div v-loading="tableLoading"
+ class="card-container">
+ <div ref="cardsContainer"
+ class="cards-wrapper">
+ <div v-for="(item, index) in tableData"
+ :key="item.id || index"
+ class="process-card"
+ :data-index="index">
+ <!-- 搴忓彿鍦嗗湀 -->
+ <div class="card-header">
+ <div class="card-number">{{ index + 1 }}</div>
+ <div class="card-process-name">{{ getProcessName(item.processId) || '-' }}</div>
</div>
- <div v-else class="product-info empty">鏆傛棤浜у搧淇℃伅</div>
- </div>
-
- <!-- 鎿嶄綔鎸夐挳 -->
- <div class="card-footer">
- <el-button type="primary" link size="small" @click="handleEdit(item)" :disabled="item.isComplete">缂栬緫</el-button>
- <el-button type="danger" link size="small" @click="handleDelete(item)" :disabled="item.isComplete">鍒犻櫎</el-button>
+ <!-- 浜у搧淇℃伅 -->
+ <div class="card-content">
+ <div v-if="item.productName"
+ class="product-info">
+ <div class="product-name">{{ item.productName }}</div>
+ <div v-if="item.model"
+ class="product-model">
+ {{ item.model }}
+ <!-- <span v-if="item.unit" class="product-unit">{{ item.unit }}</span> -->
+ </div>
+ <el-tag type="primary"
+ class="product-tag"
+ v-if="item.isQuality">璐ㄦ</el-tag>
+ </div>
+ <div v-else
+ class="product-info empty">鏆傛棤浜у搧淇℃伅</div>
+ </div>
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <div class="card-footer">
+ <el-button type="primary"
+ link
+ size="small"
+ @click="handleEdit(item)"
+ :disabled="item.isComplete">缂栬緫</el-button>
+ <el-button type="info"
+ link
+ size="small"
+ @click="handleViewParams(item)">鍙傛暟鍒楄〃</el-button>
+ <el-button type="danger"
+ link
+ size="small"
+ @click="handleDelete(item)"
+ :disabled="item.isComplete">鍒犻櫎</el-button>
+ </div>
</div>
</div>
- </div>
</div>
</template>
-
<!-- 鏂板/缂栬緫寮圭獥 -->
- <el-dialog
- v-model="dialogVisible"
- :title="operationType === 'add' ? '鏂板宸ヨ壓璺嚎椤圭洰' : '缂栬緫宸ヨ壓璺嚎椤圭洰'"
- width="500px"
- @close="closeDialog"
- >
- <el-form
- ref="formRef"
- :model="form"
- :rules="rules"
- label-width="120px"
- >
- <el-form-item label="宸ュ簭" prop="processId">
- <el-select
- v-model="form.processId"
- placeholder="璇烽�夋嫨宸ュ簭"
- clearable
- style="width: 100%"
- >
- <el-option
- v-for="process in processOptions"
- :key="process.id"
- :label="process.name"
- :value="process.id"
- />
+ <el-dialog v-model="dialogVisible"
+ :title="operationType === 'add' ? '鏂板宸ヨ壓璺嚎椤圭洰' : '缂栬緫宸ヨ壓璺嚎椤圭洰'"
+ width="500px"
+ @close="closeDialog">
+ <el-form ref="formRef"
+ :model="form"
+ :rules="rules"
+ label-width="120px">
+ <el-form-item label="宸ュ簭"
+ prop="processId">
+ <el-select v-model="form.processId"
+ placeholder="璇烽�夋嫨宸ュ簭"
+ clearable
+ style="width: 100%">
+ <el-option v-for="process in processOptions"
+ :key="process.id"
+ :label="process.name"
+ :value="process.id" />
</el-select>
</el-form-item>
-
- <el-form-item label="浜у搧鍚嶇О" prop="productModelId">
- <el-button type="primary" @click="showProductSelectDialog = true">
+ <el-form-item label="浜у搧鍚嶇О"
+ prop="productModelId">
+ <el-button type="primary"
+ @click="showProductSelectDialog = true">
{{ form.productName && form.model
? `${form.productName} - ${form.model}`
: '閫夋嫨浜у搧' }}
</el-button>
</el-form-item>
-
- <el-form-item label="鍗曚綅" prop="unit">
- <el-input
- v-model="form.unit"
- :placeholder="form.productModelId ? '鏍规嵁閫夋嫨鐨勪骇鍝佽嚜鍔ㄥ甫鍑�' : '璇峰厛閫夋嫨浜у搧'"
- clearable
- :disabled="true"
- />
+ <el-form-item label="鍗曚綅"
+ prop="unit">
+ <el-input v-model="form.unit"
+ :placeholder="form.productModelId ? '鏍规嵁閫夋嫨鐨勪骇鍝佽嚜鍔ㄥ甫鍑�' : '璇峰厛閫夋嫨浜у搧'"
+ clearable
+ :disabled="true" />
</el-form-item>
-
- <el-form-item label="鏄惁璐ㄦ" prop="isQuality">
- <el-switch v-model="form.isQuality" :active-value="true" inactive-value="false"/>
+ <el-form-item label="鏄惁璐ㄦ"
+ prop="isQuality">
+ <el-switch v-model="form.isQuality"
+ :active-value="true"
+ inactive-value="false" />
</el-form-item>
</el-form>
-
<template #footer>
<el-button @click="closeDialog">鍙栨秷</el-button>
- <el-button type="primary" @click="handleSubmit" :loading="submitLoading">纭畾</el-button>
+ <el-button type="primary"
+ @click="handleSubmit"
+ :loading="submitLoading">纭畾</el-button>
</template>
</el-dialog>
-
<!-- 浜у搧閫夋嫨瀵硅瘽妗� -->
- <ProductSelectDialog
- v-model="showProductSelectDialog"
- @confirm="handleProductSelect"
- single
- />
+ <ProductSelectDialog v-model="showProductSelectDialog"
+ @confirm="handleProductSelect"
+ single />
+ <!-- 鍙傛暟鍒楄〃瀵硅瘽妗� -->
+ <ProcessParamListDialog v-model="showParamListDialog"
+ :title="`${currentProcess ? getProcessName(currentProcess.processId) : ''} - 鍙傛暟鍒楄〃`"
+ :route-id="routeId"
+ :editable="false"
+ :process="currentProcess"
+ :param-list="paramList"
+ @refresh="refreshParamList" />
</div>
</template>
<script setup>
-import { ref, computed, getCurrentInstance, onMounted, onUnmounted, nextTick } from "vue";
-import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
-import { findProcessRouteItemList, addOrUpdateProcessRouteItem, sortProcessRouteItem, batchDeleteProcessRouteItem } from "@/api/productionManagement/processRouteItem.js";
-import { findProductProcessRouteItemList, deleteRouteItem, addRouteItem, addOrUpdateProductProcessRouteItem, sortRouteItem } from "@/api/productionManagement/productProcessRoute.js";
-import { processList } from "@/api/productionManagement/productionProcess.js";
-import { useRoute } from 'vue-router'
-import { ElMessageBox } from 'element-plus'
-import Sortable from 'sortablejs'
+ import {
+ ref,
+ computed,
+ getCurrentInstance,
+ onMounted,
+ onUnmounted,
+ nextTick,
+ } from "vue";
+ import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
+ import ProcessParamListDialog from "@/components/ProcessParamListDialog.vue";
+ import {
+ findProcessRouteItemList,
+ addOrUpdateProcessRouteItem,
+ sortProcessRouteItem,
+ batchDeleteProcessRouteItem,
+ getProcessParamList,
+ } from "@/api/productionManagement/processRouteItem.js";
+ import {
+ findProductProcessRouteItemList,
+ deleteRouteItem,
+ addRouteItem,
+ addOrUpdateProductProcessRouteItem,
+ sortRouteItem,
+ } from "@/api/productionManagement/productProcessRoute.js";
+ import { processList } from "@/api/productionManagement/productionProcess.js";
+ import { useRoute } from "vue-router";
+ import { ElMessageBox, ElMessage } from "element-plus";
+ import Sortable from "sortablejs";
-const route = useRoute()
-const { proxy } = getCurrentInstance() || {};
+ const route = useRoute();
+ const { proxy } = getCurrentInstance() || {};
-const routeId = computed(() => route.query.id);
-const orderId = computed(() => route.query.orderId);
-const pageType = computed(() => route.query.type);
+ const routeId = computed(() => route.query.id);
+ const orderId = computed(() => route.query.orderId);
+ const pageType = computed(() => route.query.type);
-const tableLoading = ref(false);
-const tableData = ref([]);
-const dialogVisible = ref(false);
-const operationType = ref('add'); // add | edit
-const formRef = ref(null);
-const submitLoading = ref(false);
-const cardsContainer = ref(null);
-const tableRef = ref(null);
-const viewMode = ref('table'); // table | card
-const routeInfo = ref({
- processRouteCode: '',
- productName: '',
- model: '',
- bomNo: '',
- description: ''
-});
-
-const processOptions = ref([]);
-const showProductSelectDialog = ref(false);
-let tableSortable = null;
-let cardSortable = null;
-
-// 鍒囨崲瑙嗗浘
-const toggleView = () => {
- viewMode.value = viewMode.value === 'table' ? 'card' : 'table';
- // 鍒囨崲瑙嗗浘鍚庨噸鏂板垵濮嬪寲鎷栨嫿鎺掑簭
- nextTick(() => {
- initSortable();
+ const tableLoading = ref(false);
+ const tableData = ref([]);
+ const dialogVisible = ref(false);
+ const operationType = ref("add"); // add | edit
+ const formRef = ref(null);
+ const submitLoading = ref(false);
+ const cardsContainer = ref(null);
+ const tableRef = ref(null);
+ const viewMode = ref("table"); // table | card
+ const routeInfo = ref({
+ processRouteCode: "",
+ productName: "",
+ model: "",
+ bomNo: "",
+ bomId: null,
+ description: "",
});
-};
-const form = ref({
- id: undefined,
- routeId: routeId.value,
- processId: undefined,
- productModelId: undefined,
- productName: "",
- model: "",
- unit: "",
- isQuality: false,
-});
+ const processOptions = ref([]);
+ const showProductSelectDialog = ref(false);
+ const showParamListDialog = ref(false);
+ const currentProcess = ref(null);
+ const paramList = ref([]);
+ let tableSortable = null;
+ let cardSortable = null;
-const rules = {
- processId: [{ required: true, message: '璇烽�夋嫨宸ュ簭', trigger: 'change' }],
- productModelId: [{ required: true, message: '璇烽�夋嫨浜у搧', trigger: 'change' }],
-};
-
-// 鏍规嵁宸ュ簭ID鑾峰彇宸ュ簭鍚嶇О
-const getProcessName = (processId) => {
- if (!processId) return '';
- const process = processOptions.value.find(p => p.id === processId);
- return process ? process.name : '';
-};
-
-// 鑾峰彇鍒楄〃
-const getList = () => {
- tableLoading.value = true;
- const listPromise =
- pageType.value === "order"
- ? findProductProcessRouteItemList({ orderId: orderId.value })
- : findProcessRouteItemList({ routeId: routeId.value });
-
- listPromise
- .then(res => {
- tableData.value = res.data || [];
- tableLoading.value = false;
- // 鍒楄〃鍔犺浇瀹屾垚鍚庡垵濮嬪寲鎷栨嫿鎺掑簭
- nextTick(() => {
- initSortable();
- });
- })
- .catch(err => {
- tableLoading.value = false;
- console.error("鑾峰彇鍒楄〃澶辫触锛�", err);
- proxy?.$modal?.msgError("鑾峰彇鍒楄〃澶辫触");
+ // 鍒囨崲瑙嗗浘
+ const toggleView = () => {
+ viewMode.value = viewMode.value === "table" ? "card" : "table";
+ // 鍒囨崲瑙嗗浘鍚庨噸鏂板垵濮嬪寲鎷栨嫿鎺掑簭
+ nextTick(() => {
+ initSortable();
});
-};
-
-// 鑾峰彇宸ュ簭鍒楄〃
-const getProcessList = () => {
- processList({})
- .then(res => {
- processOptions.value = res.data || [];
- })
- .catch(err => {
- console.error("鑾峰彇宸ュ簭澶辫触锛�", err);
- });
-};
-
-// 鑾峰彇宸ヨ壓璺嚎璇︽儏锛堜粠璺敱鍙傛暟鑾峰彇锛�
-const getRouteInfo = () => {
- routeInfo.value = {
- processRouteCode: route.query.processRouteCode || '',
- productName: route.query.productName || '',
- model: route.query.model || '',
- bomNo: route.query.bomNo || '',
- description: route.query.description || ''
};
-};
-// 鏂板
-const handleAdd = () => {
- operationType.value = 'add';
- resetForm();
- dialogVisible.value = true;
-};
-
-// 缂栬緫
-const handleEdit = (row) => {
- console.log(1111, row.isQuality);
- operationType.value = 'edit';
- form.value = {
- id: row.id,
- routeId: routeId.value,
- processId: row.processId,
- productModelId: row.productModelId,
- productName: row.productName || "",
- model: row.model || "",
- unit: row.unit || "",
- isQuality: row.isQuality,
- };
- dialogVisible.value = true;
-};
-
-// 鍒犻櫎
-const handleDelete = (row) => {
- ElMessageBox.confirm('纭鍒犻櫎璇ュ伐鑹鸿矾绾块」鐩紵', '鎻愮ず', {
- confirmButtonText: '纭',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- })
- .then(() => {
- // 鐢熶骇璁㈠崟涓嬩娇鐢� productProcessRoute 鐨勫垹闄ゆ帴鍙o紙璺敱鍚庢嫾鎺� id锛夛紝鍏跺畠鎯呭喌浣跨敤宸ヨ壓璺嚎椤圭洰鎵归噺鍒犻櫎鎺ュ彛
- const deletePromise =
- pageType.value === 'order'
- ? deleteRouteItem(row.id)
- : batchDeleteProcessRouteItem([row.id]);
-
- deletePromise
- .then(() => {
- proxy?.$modal?.msgSuccess('鍒犻櫎鎴愬姛');
- getList();
- })
- .catch(() => {
- proxy?.$modal?.msgError('鍒犻櫎澶辫触');
- });
- })
- .catch(() => {});
-};
-
-// 浜у搧閫夋嫨
-const handleProductSelect = (products) => {
- if (products && products.length > 0) {
- const product = products[0];
- form.value.productModelId = product.id;
- form.value.productName = product.productName;
- form.value.model = product.model;
- form.value.unit = product.unit || "";
- showProductSelectDialog.value = false;
- // 瑙﹀彂琛ㄥ崟楠岃瘉
- formRef.value?.validateField('productModelId');
- }
-};
-
-// 鎻愪氦
-const handleSubmit = () => {
- formRef.value.validate((valid) => {
- if (valid) {
- submitLoading.value = true;
-
- if (operationType.value === 'add') {
- // 鏂板锛氫紶鍗曚釜瀵硅薄锛屽寘鍚玠ragSort瀛楁
- // dragSort = 褰撳墠鍒楄〃闀垮害 + 1锛岃〃绀烘柊澧炶褰曟帓鍦ㄦ渶鍚�
- const dragSort = tableData.value.length + 1;
- const isOrderPage = pageType.value === 'order';
-
- const addPromise = isOrderPage
- ? addRouteItem({
- productOrderId: orderId.value,
- productRouteId: routeId.value,
- processId: form.value.processId,
- productModelId: form.value.productModelId,
- isQuality: form.value.isQuality,
- dragSort,
- })
- : addOrUpdateProcessRouteItem({
- routeId: routeId.value,
- processId: form.value.processId,
- productModelId: form.value.productModelId,
- isQuality: form.value.isQuality,
- dragSort,
- });
-
- addPromise
- .then(() => {
- proxy?.$modal?.msgSuccess('鏂板鎴愬姛');
- closeDialog();
- getList();
- })
- .catch(() => {
- proxy?.$modal?.msgError('鏂板澶辫触');
- })
- .finally(() => {
- submitLoading.value = false;
- });
- } else {
- // 缂栬緫锛氱敓浜ц鍗曚笅浣跨敤 productProcessRoute/updateRouteItem锛屽叾瀹冩儏鍐典娇鐢ㄥ伐鑹鸿矾绾块」鐩洿鏂版帴鍙�
- const isOrderPage = pageType.value === 'order';
-
- const updatePromise = isOrderPage
- ? addOrUpdateProductProcessRouteItem({
- id: form.value.id,
- processId: form.value.processId,
- productModelId: form.value.productModelId,
- isQuality: form.value.isQuality,
- })
- : addOrUpdateProcessRouteItem({
- routeId: routeId.value,
- processId: form.value.processId,
- productModelId: form.value.productModelId,
- id: form.value.id,
- isQuality: form.value.isQuality,
- });
-
- updatePromise
- .then(() => {
- proxy?.$modal?.msgSuccess('淇敼鎴愬姛');
- closeDialog();
- getList();
- })
- .catch(() => {
- proxy?.$modal?.msgError('淇敼澶辫触');
- })
- .finally(() => {
- submitLoading.value = false;
- });
- }
- }
- });
-};
-
-// 閲嶇疆琛ㄥ崟
-const resetForm = () => {
- form.value = {
+ const form = ref({
id: undefined,
routeId: routeId.value,
processId: undefined,
@@ -484,414 +342,683 @@
productName: "",
model: "",
unit: "",
+ isQuality: false,
+ });
+
+ const rules = {
+ processId: [{ required: true, message: "璇烽�夋嫨宸ュ簭", trigger: "change" }],
+ productModelId: [
+ { required: true, message: "璇烽�夋嫨浜у搧", trigger: "change" },
+ ],
};
- formRef.value?.resetFields();
-};
-// 鍏抽棴寮圭獥
-const closeDialog = () => {
- dialogVisible.value = false;
- resetForm();
-};
+ // 鏍规嵁宸ュ簭ID鑾峰彇宸ュ簭鍚嶇О
+ const getProcessName = processId => {
+ if (!processId) return "";
+ const process = processOptions.value.find(p => p.id === processId);
+ return process ? process.name : "";
+ };
-// 鍒濆鍖栨嫋鎷芥帓搴�
-const initSortable = () => {
- destroySortable();
-
- if (viewMode.value === 'table') {
- // 琛ㄦ牸瑙嗗浘鐨勬嫋鎷芥帓搴�
- if (!tableRef.value) return;
-
- const tbody = tableRef.value.$el.querySelector('.el-table__body tbody') ||
- tableRef.value.$el.querySelector('.el-table__body-wrapper > table > tbody');
-
- if (!tbody) return;
+ // 鑾峰彇鍒楄〃
+ const getList = () => {
+ tableLoading.value = true;
+ const listPromise =
+ pageType.value === "order"
+ ? findProductProcessRouteItemList({ orderId: orderId.value })
+ : findProcessRouteItemList({ routeId: routeId.value });
- tableSortable = new Sortable(tbody, {
- animation: 150,
- ghostClass: 'sortable-ghost',
- handle: '.el-table__row',
- filter: '.el-button, .el-select',
- onEnd: (evt) => {
- if (evt.oldIndex === evt.newIndex || !tableData.value[evt.oldIndex]) return;
+ listPromise
+ .then(res => {
+ tableData.value = res.data || [];
+ tableLoading.value = false;
+ // 鍒楄〃鍔犺浇瀹屾垚鍚庡垵濮嬪寲鎷栨嫿鎺掑簭
+ nextTick(() => {
+ initSortable();
+ });
+ })
+ .catch(err => {
+ tableLoading.value = false;
+ console.error("鑾峰彇鍒楄〃澶辫触锛�", err);
+ proxy?.$modal?.msgError("鑾峰彇鍒楄〃澶辫触");
+ });
+ };
- // 閲嶆柊鎺掑簭鏁扮粍
- const moveItem = tableData.value.splice(evt.oldIndex, 1)[0];
- tableData.value.splice(evt.newIndex, 0, moveItem);
-
- // 璁$畻鏂扮殑搴忓彿锛坉ragSort浠�1寮�濮嬶級
- const newIndex = evt.newIndex;
- const dragSort = newIndex + 1;
-
- // 璋冪敤鎺掑簭鎺ュ彛
- if (moveItem.id) {
- const isOrderPage = pageType.value === 'order';
- const sortPromise = isOrderPage
- ? sortRouteItem({
- id: moveItem.id,
- dragSort: dragSort
+ // 鑾峰彇宸ュ簭鍒楄〃
+ const getProcessList = () => {
+ processList({})
+ .then(res => {
+ processOptions.value = res.data || [];
+ })
+ .catch(err => {
+ console.error("鑾峰彇宸ュ簭澶辫触锛�", err);
+ });
+ };
+
+ // 鑾峰彇宸ヨ壓璺嚎璇︽儏锛堜粠璺敱鍙傛暟鑾峰彇锛�
+ const getRouteInfo = () => {
+ routeInfo.value = {
+ processRouteCode: route.query.processRouteCode || "",
+ productName: route.query.productName || "",
+ model: route.query.model || "",
+ bomNo: route.query.bomNo || "",
+ bomId: route.query.bomId || null,
+ description: route.query.description || "",
+ };
+ };
+
+ // 鏂板
+ const handleAdd = () => {
+ operationType.value = "add";
+ resetForm();
+ dialogVisible.value = true;
+ };
+
+ // 缂栬緫
+ const handleEdit = row => {
+ operationType.value = "edit";
+ form.value = {
+ id: row.id,
+ routeId: routeId.value,
+ processId: row.processId,
+ productModelId: row.productModelId,
+ productName: row.productName || "",
+ model: row.model || "",
+ unit: row.unit || "",
+ isQuality: row.isQuality,
+ };
+ dialogVisible.value = true;
+ };
+
+ // 鍒犻櫎
+ const handleDelete = row => {
+ ElMessageBox.confirm("纭鍒犻櫎璇ュ伐鑹鸿矾绾块」鐩紵", "鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ // 鐢熶骇璁㈠崟涓嬩娇鐢� productProcessRoute 鐨勫垹闄ゆ帴鍙o紙璺敱鍚庢嫾鎺� id锛夛紝鍏跺畠鎯呭喌浣跨敤宸ヨ壓璺嚎椤圭洰鎵归噺鍒犻櫎鎺ュ彛
+ const deletePromise =
+ pageType.value === "order"
+ ? deleteRouteItem(row.id)
+ : batchDeleteProcessRouteItem([row.id]);
+
+ deletePromise
+ .then(() => {
+ proxy?.$modal?.msgSuccess("鍒犻櫎鎴愬姛");
+ getList();
+ })
+ .catch(() => {
+ proxy?.$modal?.msgError("鍒犻櫎澶辫触");
+ });
+ })
+ .catch(() => {});
+ };
+
+ // 浜у搧閫夋嫨
+ const handleProductSelect = products => {
+ if (products && products.length > 0) {
+ const product = products[0];
+ form.value.productModelId = product.id;
+ form.value.productName = product.productName;
+ form.value.model = product.model;
+ form.value.unit = product.unit || "";
+ showProductSelectDialog.value = false;
+ // 瑙﹀彂琛ㄥ崟楠岃瘉
+ formRef.value?.validateField("productModelId");
+ }
+ };
+
+ // 鎻愪氦
+ const handleSubmit = () => {
+ formRef.value.validate(valid => {
+ if (valid) {
+ submitLoading.value = true;
+
+ if (operationType.value === "add") {
+ // 鏂板锛氫紶鍗曚釜瀵硅薄锛屽寘鍚玠ragSort瀛楁
+ // dragSort = 褰撳墠鍒楄〃闀垮害 + 1锛岃〃绀烘柊澧炶褰曟帓鍦ㄦ渶鍚�
+ const dragSort = tableData.value.length + 1;
+ const isOrderPage = pageType.value === "order";
+
+ const addPromise = isOrderPage
+ ? addRouteItem({
+ productOrderId: orderId.value,
+ productRouteId: routeId.value,
+ processId: form.value.processId,
+ productModelId: form.value.productModelId,
+ isQuality: form.value.isQuality,
+ dragSort,
})
- : sortProcessRouteItem({
- id: moveItem.id,
- dragSort: dragSort
+ : addOrUpdateProcessRouteItem({
+ routeId: routeId.value,
+ processId: form.value.processId,
+ productModelId: form.value.productModelId,
+ isQuality: form.value.isQuality,
+ dragSort,
});
- sortPromise
+ addPromise
.then(() => {
- // 鏇存柊鎵�鏈夎鐨刣ragSort
- tableData.value.forEach((item, index) => {
- if (item.id) {
- item.dragSort = index + 1;
- }
- });
- proxy?.$modal?.msgSuccess('鎺掑簭鎴愬姛');
+ proxy?.$modal?.msgSuccess("鏂板鎴愬姛");
+ closeDialog();
+ getList();
})
- .catch((err) => {
- // 鎺掑簭澶辫触锛屾仮澶嶅師鏁扮粍
- tableData.value.splice(newIndex, 1);
- tableData.value.splice(evt.oldIndex, 0, moveItem);
- proxy?.$modal?.msgError('鎺掑簭澶辫触');
- console.error("鎺掑簭澶辫触锛�", err);
+ .catch(() => {
+ proxy?.$modal?.msgError("鏂板澶辫触");
+ })
+ .finally(() => {
+ submitLoading.value = false;
+ });
+ } else {
+ // 缂栬緫锛氱敓浜ц鍗曚笅浣跨敤 productProcessRoute/updateRouteItem锛屽叾瀹冩儏鍐典娇鐢ㄥ伐鑹鸿矾绾块」鐩洿鏂版帴鍙�
+ const isOrderPage = pageType.value === "order";
+
+ const updatePromise = isOrderPage
+ ? addOrUpdateProductProcessRouteItem({
+ id: form.value.id,
+ processId: form.value.processId,
+ productModelId: form.value.productModelId,
+ isQuality: form.value.isQuality,
+ })
+ : addOrUpdateProcessRouteItem({
+ routeId: routeId.value,
+ processId: form.value.processId,
+ productModelId: form.value.productModelId,
+ id: form.value.id,
+ isQuality: form.value.isQuality,
+ });
+
+ updatePromise
+ .then(() => {
+ proxy?.$modal?.msgSuccess("淇敼鎴愬姛");
+ closeDialog();
+ getList();
+ })
+ .catch(() => {
+ proxy?.$modal?.msgError("淇敼澶辫触");
+ })
+ .finally(() => {
+ submitLoading.value = false;
});
}
}
});
- } else {
- // 鍗$墖瑙嗗浘鐨勬嫋鎷芥帓搴�
- if (!cardsContainer.value) return;
+ };
- cardSortable = new Sortable(cardsContainer.value, {
- animation: 150,
- ghostClass: 'sortable-ghost',
- handle: '.process-card',
- filter: '.el-button',
- onEnd: (evt) => {
- if (evt.oldIndex === evt.newIndex || !tableData.value[evt.oldIndex]) return;
+ // 閲嶇疆琛ㄥ崟
+ const resetForm = () => {
+ form.value = {
+ id: undefined,
+ routeId: routeId.value,
+ processId: undefined,
+ productModelId: undefined,
+ productName: "",
+ model: "",
+ unit: "",
+ };
+ formRef.value?.resetFields();
+ };
- // 閲嶆柊鎺掑簭鏁扮粍
- const moveItem = tableData.value.splice(evt.oldIndex, 1)[0];
- tableData.value.splice(evt.newIndex, 0, moveItem);
-
- // 璁$畻鏂扮殑搴忓彿锛坉ragSort浠�1寮�濮嬶級
- const newIndex = evt.newIndex;
- const dragSort = newIndex + 1;
-
- // 璋冪敤鎺掑簭鎺ュ彛
- if (moveItem.id) {
- const isOrderPage = pageType.value === 'order';
- const sortPromise = isOrderPage
- ? sortRouteItem({
- id: moveItem.id,
- dragSort: dragSort
+ // 鍏抽棴寮圭獥
+ const closeDialog = () => {
+ dialogVisible.value = false;
+ resetForm();
+ };
+
+ // 鍒濆鍖栨嫋鎷芥帓搴�
+ const initSortable = () => {
+ destroySortable();
+
+ if (viewMode.value === "table") {
+ // 琛ㄦ牸瑙嗗浘鐨勬嫋鎷芥帓搴�
+ if (!tableRef.value) return;
+
+ const tbody =
+ tableRef.value.$el.querySelector(".el-table__body tbody") ||
+ tableRef.value.$el.querySelector(
+ ".el-table__body-wrapper > table > tbody"
+ );
+
+ if (!tbody) return;
+
+ tableSortable = new Sortable(tbody, {
+ animation: 150,
+ ghostClass: "sortable-ghost",
+ handle: ".el-table__row",
+ filter: ".el-button, .el-select",
+ onEnd: evt => {
+ if (evt.oldIndex === evt.newIndex || !tableData.value[evt.oldIndex])
+ return;
+
+ // 閲嶆柊鎺掑簭鏁扮粍
+ const moveItem = tableData.value.splice(evt.oldIndex, 1)[0];
+ tableData.value.splice(evt.newIndex, 0, moveItem);
+
+ // 璁$畻鏂扮殑搴忓彿锛坉ragSort浠�1寮�濮嬶級
+ const newIndex = evt.newIndex;
+ const dragSort = newIndex + 1;
+
+ // 璋冪敤鎺掑簭鎺ュ彛
+ if (moveItem.id) {
+ const isOrderPage = pageType.value === "order";
+ const sortPromise = isOrderPage
+ ? sortRouteItem({
+ id: moveItem.id,
+ dragSort: dragSort,
+ })
+ : sortProcessRouteItem({
+ id: moveItem.id,
+ dragSort: dragSort,
+ });
+
+ sortPromise
+ .then(() => {
+ // 鏇存柊鎵�鏈夎鐨刣ragSort
+ tableData.value.forEach((item, index) => {
+ if (item.id) {
+ item.dragSort = index + 1;
+ }
+ });
+ proxy?.$modal?.msgSuccess("鎺掑簭鎴愬姛");
})
- : sortProcessRouteItem({
- id: moveItem.id,
- dragSort: dragSort
+ .catch(err => {
+ // 鎺掑簭澶辫触锛屾仮澶嶅師鏁扮粍
+ tableData.value.splice(newIndex, 1);
+ tableData.value.splice(evt.oldIndex, 0, moveItem);
+ proxy?.$modal?.msgError("鎺掑簭澶辫触");
+ console.error("鎺掑簭澶辫触锛�", err);
});
+ }
+ },
+ });
+ } else {
+ // 鍗$墖瑙嗗浘鐨勬嫋鎷芥帓搴�
+ if (!cardsContainer.value) return;
- sortPromise
- .then(() => {
- // 鏇存柊鎵�鏈夎鐨刣ragSort
- tableData.value.forEach((item, index) => {
- if (item.id) {
- item.dragSort = index + 1;
- }
+ cardSortable = new Sortable(cardsContainer.value, {
+ animation: 150,
+ ghostClass: "sortable-ghost",
+ handle: ".process-card",
+ filter: ".el-button",
+ onEnd: evt => {
+ if (evt.oldIndex === evt.newIndex || !tableData.value[evt.oldIndex])
+ return;
+
+ // 閲嶆柊鎺掑簭鏁扮粍
+ const moveItem = tableData.value.splice(evt.oldIndex, 1)[0];
+ tableData.value.splice(evt.newIndex, 0, moveItem);
+
+ // 璁$畻鏂扮殑搴忓彿锛坉ragSort浠�1寮�濮嬶級
+ const newIndex = evt.newIndex;
+ const dragSort = newIndex + 1;
+
+ // 璋冪敤鎺掑簭鎺ュ彛
+ if (moveItem.id) {
+ const isOrderPage = pageType.value === "order";
+ const sortPromise = isOrderPage
+ ? sortRouteItem({
+ id: moveItem.id,
+ dragSort: dragSort,
+ })
+ : sortProcessRouteItem({
+ id: moveItem.id,
+ dragSort: dragSort,
+ });
+
+ sortPromise
+ .then(() => {
+ // 鏇存柊鎵�鏈夎鐨刣ragSort
+ tableData.value.forEach((item, index) => {
+ if (item.id) {
+ item.dragSort = index + 1;
+ }
+ });
+ proxy?.$modal?.msgSuccess("鎺掑簭鎴愬姛");
+ })
+ .catch(err => {
+ // 鎺掑簭澶辫触锛屾仮澶嶅師鏁扮粍
+ tableData.value.splice(newIndex, 1);
+ tableData.value.splice(evt.oldIndex, 0, moveItem);
+ proxy?.$modal?.msgError("鎺掑簭澶辫触");
+ console.error("鎺掑簭澶辫触锛�", err);
});
- proxy?.$modal?.msgSuccess('鎺掑簭鎴愬姛');
- })
- .catch((err) => {
- // 鎺掑簭澶辫触锛屾仮澶嶅師鏁扮粍
- tableData.value.splice(newIndex, 1);
- tableData.value.splice(evt.oldIndex, 0, moveItem);
- proxy?.$modal?.msgError('鎺掑簭澶辫触');
- console.error("鎺掑簭澶辫触锛�", err);
- });
+ }
+ },
+ });
+ }
+ };
+
+ // 閿�姣佹嫋鎷芥帓搴�
+ const destroySortable = () => {
+ if (tableSortable) {
+ tableSortable.destroy();
+ tableSortable = null;
+ }
+ if (cardSortable) {
+ cardSortable.destroy();
+ cardSortable = null;
+ }
+ };
+
+ onMounted(() => {
+ getRouteInfo();
+ getList();
+ getProcessList();
+ });
+
+ // 鏌ョ湅鍙傛暟鍒楄〃
+ const handleViewParams = process => {
+ currentProcess.value = process;
+ // 璋冪敤API鑾峰彇鍙傛暟鍒楄〃
+ getProcessParamList({
+ routeItemId: process.id,
+ pageNum: 1,
+ pageSize: 1000,
+ })
+ .then(res => {
+ if (res.code === 200) {
+ paramList.value = res.data?.records || [];
+ } else {
+ ElMessage.error(res.msg || "鑾峰彇鍙傛暟鍒楄〃澶辫触");
+ paramList.value = [];
}
- }
- });
- }
-};
+ showParamListDialog.value = true;
+ })
+ .catch(err => {
+ console.error("鑾峰彇鍙傛暟鍒楄〃澶辫触锛�", err);
+ ElMessage.error("鑾峰彇鍙傛暟鍒楄〃澶辫触");
+ paramList.value = [];
+ showParamListDialog.value = true;
+ });
+ };
-// 閿�姣佹嫋鎷芥帓搴�
-const destroySortable = () => {
- if (tableSortable) {
- tableSortable.destroy();
- tableSortable = null;
- }
- if (cardSortable) {
- cardSortable.destroy();
- cardSortable = null;
- }
-};
+ // 鍒锋柊鍙傛暟鍒楄〃
+ const refreshParamList = () => {
+ if (!currentProcess.value) return;
+ // 閲嶆柊璋冪敤API鑾峰彇鍙傛暟鍒楄〃
+ getProcessParamList({
+ routeItemId: currentProcess.value.id,
+ pageNum: 1,
+ pageSize: 1000,
+ })
+ .then(res => {
+ if (res.code === 200) {
+ paramList.value = res.data?.records || [];
+ } else {
+ ElMessage.error(res.msg || "鑾峰彇鍙傛暟鍒楄〃澶辫触");
+ paramList.value = [];
+ }
+ })
+ .catch(err => {
+ console.error("鑾峰彇鍙傛暟鍒楄〃澶辫触锛�", err);
+ ElMessage.error("鑾峰彇鍙傛暟鍒楄〃澶辫触");
+ paramList.value = [];
+ });
+ };
-onMounted(() => {
- getRouteInfo();
- getList();
- getProcessList();
-});
-
-onUnmounted(() => {
- destroySortable();
-});
+ onUnmounted(() => {
+ destroySortable();
+ });
</script>
<style scoped>
-.card-container {
- padding: 20px 0;
-}
+ .card-container {
+ padding: 20px 0;
+ }
-.cards-wrapper {
- display: flex;
- gap: 16px;
- overflow-x: auto;
- padding: 10px 0;
- min-height: 200px;
-}
+ .cards-wrapper {
+ display: flex;
+ gap: 16px;
+ overflow-x: auto;
+ padding: 10px 0;
+ min-height: 200px;
+ }
-.cards-wrapper::-webkit-scrollbar {
- height: 8px;
-}
+ .cards-wrapper::-webkit-scrollbar {
+ height: 8px;
+ }
-.cards-wrapper::-webkit-scrollbar-track {
- background: #f1f1f1;
- border-radius: 4px;
-}
+ .cards-wrapper::-webkit-scrollbar-track {
+ background: #f1f1f1;
+ border-radius: 4px;
+ }
-.cards-wrapper::-webkit-scrollbar-thumb {
- background: #c1c1c1;
- border-radius: 4px;
-}
+ .cards-wrapper::-webkit-scrollbar-thumb {
+ background: #c1c1c1;
+ border-radius: 4px;
+ }
-.cards-wrapper::-webkit-scrollbar-thumb:hover {
- background: #a8a8a8;
-}
+ .cards-wrapper::-webkit-scrollbar-thumb:hover {
+ background: #a8a8a8;
+ }
-.process-card {
- flex-shrink: 0;
- width: 220px;
- background: #fff;
- border-radius: 8px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- padding: 16px;
- display: flex;
- flex-direction: column;
- cursor: move;
- transition: all 0.3s;
-}
+ .process-card {
+ flex-shrink: 0;
+ width: 220px;
+ background: #fff;
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ padding: 16px;
+ display: flex;
+ flex-direction: column;
+ cursor: move;
+ transition: all 0.3s;
+ }
-.process-card:hover {
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
- transform: translateY(-2px);
-}
+ .process-card:hover {
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ transform: translateY(-2px);
+ }
-.card-header {
- text-align: center;
- margin-bottom: 12px;
-}
+ .card-header {
+ text-align: center;
+ margin-bottom: 12px;
+ }
-.card-number {
- width: 36px;
- height: 36px;
- line-height: 36px;
- border-radius: 50%;
- background: #409eff;
- color: #fff;
- font-weight: bold;
- font-size: 16px;
- margin: 0 auto 8px;
-}
+ .card-number {
+ width: 36px;
+ height: 36px;
+ line-height: 36px;
+ border-radius: 50%;
+ background: #409eff;
+ color: #fff;
+ font-weight: bold;
+ font-size: 16px;
+ margin: 0 auto 8px;
+ }
-.card-process-name {
- font-size: 14px;
- color: #333;
- font-weight: 500;
- word-break: break-all;
-}
+ .card-process-name {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+ word-break: break-all;
+ }
-.card-content {
- flex: 1;
- margin-bottom: 12px;
- min-height: 60px;
- display: flex;
- align-items: center;
- justify-content: center;
-}
+ .card-content {
+ flex: 1;
+ margin-bottom: 12px;
+ min-height: 60px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
-.product-info {
- font-size: 13px;
- color: #666;
- text-align: center;
- width: 100%;
-}
+ .product-info {
+ font-size: 13px;
+ color: #666;
+ text-align: center;
+ width: 100%;
+ }
-.product-info.empty {
- color: #999;
- text-align: center;
- padding: 20px 0;
-}
+ .product-info.empty {
+ color: #999;
+ text-align: center;
+ padding: 20px 0;
+ }
-.product-name {
- margin-bottom: 6px;
- word-break: break-all;
- line-height: 1.5;
- text-align: center;
-}
+ .product-name {
+ margin-bottom: 6px;
+ word-break: break-all;
+ line-height: 1.5;
+ text-align: center;
+ }
-.product-model {
- color: #909399;
- font-size: 12px;
- word-break: break-all;
- line-height: 1.5;
- text-align: center;
-}
+ .product-model {
+ color: #909399;
+ font-size: 12px;
+ word-break: break-all;
+ line-height: 1.5;
+ text-align: center;
+ }
-.product-unit {
- margin-left: 4px;
- color: #409eff;
-}
+ .product-unit {
+ margin-left: 4px;
+ color: #409eff;
+ }
-.product-tag {
- margin: 10px 0;
-}
+ .product-tag {
+ margin: 10px 0;
+ }
-.card-footer {
- display: flex;
- justify-content: space-around;
- padding-top: 12px;
- border-top: 1px solid #f0f0f0;
-}
+ .card-footer {
+ display: flex;
+ justify-content: space-around;
+ padding-top: 12px;
+ border-top: 1px solid #f0f0f0;
+ }
-.card-footer .el-button {
- padding: 0;
- font-size: 12px;
-}
+ .card-footer .el-button {
+ padding: 0;
+ font-size: 12px;
+ }
-:deep(.sortable-ghost) {
- opacity: 0.5;
- background-color: #f5f7fa !important;
-}
+ :deep(.sortable-ghost) {
+ opacity: 0.5;
+ background-color: #f5f7fa !important;
+ }
-:deep(.sortable-drag) {
- opacity: 0.8;
-}
+ :deep(.sortable-drag) {
+ opacity: 0.8;
+ }
-/* 琛ㄦ牸瑙嗗浘鏍峰紡 */
-:deep(.el-table__row) {
- transition: background-color 0.2s;
- cursor: move;
-}
+ /* 琛ㄦ牸瑙嗗浘鏍峰紡 */
+ :deep(.el-table__row) {
+ transition: background-color 0.2s;
+ cursor: move;
+ }
-:deep(.el-table__row:hover) {
- background-color: #f9fafc !important;
-}
+ :deep(.el-table__row:hover) {
+ background-color: #f9fafc !important;
+ }
-/* 鍖哄煙鏍囬鏍峰紡 */
-.section-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 12px;
-}
+ /* 鍖哄煙鏍囬鏍峰紡 */
+ .section-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 12px;
+ }
-.section-title {
- font-size: 16px;
- font-weight: 600;
- color: #303133;
- padding-left: 12px;
- position: relative;
- margin-bottom: 0;
-}
+ .section-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #303133;
+ padding-left: 12px;
+ position: relative;
+ margin-bottom: 0;
+ }
-.section-title::before {
- content: '';
- position: absolute;
- left: 0;
- top: 50%;
- transform: translateY(-50%);
- width: 3px;
- height: 16px;
- background: #409eff;
- border-radius: 2px;
-}
+ .section-title::before {
+ content: "";
+ position: absolute;
+ left: 0;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 3px;
+ height: 16px;
+ background: #409eff;
+ border-radius: 2px;
+ }
-.section-actions {
- display: flex;
- align-items: center;
-}
+ .section-actions {
+ display: flex;
+ align-items: center;
+ }
-/* 宸ヨ壓璺嚎淇℃伅鍗$墖鏍峰紡 */
-.route-info-card {
- margin-bottom: 20px;
- border: 1px solid #e4e7ed;
- background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
- border-radius: 8px;
- overflow: hidden;
-}
+ /* 宸ヨ壓璺嚎淇℃伅鍗$墖鏍峰紡 */
+ .route-info-card {
+ margin-bottom: 20px;
+ border: 1px solid #e4e7ed;
+ background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
+ border-radius: 8px;
+ overflow: hidden;
+ }
-.route-info {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
- gap: 16px;
- padding: 4px;
-}
+ .route-info {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+ gap: 16px;
+ padding: 4px;
+ }
-.info-item {
- display: flex;
- flex-direction: column;
- background: #ffffff;
- border-radius: 6px;
- padding: 14px 16px;
- border: 1px solid #f0f2f5;
- transition: all 0.3s ease;
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
-}
+ .info-item {
+ display: flex;
+ flex-direction: column;
+ background: #ffffff;
+ border-radius: 6px;
+ padding: 14px 16px;
+ border: 1px solid #f0f2f5;
+ transition: all 0.3s ease;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
+ }
-.info-item:hover {
- border-color: #409eff;
- box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
- transform: translateY(-1px);
-}
+ .info-item:hover {
+ border-color: #409eff;
+ box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
+ transform: translateY(-1px);
+ }
-.info-item.full-width {
- grid-column: 1 / -1;
-}
+ .info-item.full-width {
+ grid-column: 1 / -1;
+ }
-.info-label-wrapper {
- margin-bottom: 8px;
-}
+ .info-label-wrapper {
+ margin-bottom: 8px;
+ }
-.info-label {
- display: inline-block;
- color: #909399;
- font-size: 12px;
- font-weight: 500;
- text-transform: uppercase;
- letter-spacing: 0.5px;
- padding: 2px 0;
- position: relative;
-}
+ .info-label {
+ display: inline-block;
+ color: #909399;
+ font-size: 12px;
+ font-weight: 500;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ padding: 2px 0;
+ position: relative;
+ }
-.info-label::after {
- content: '';
- position: absolute;
- left: 0;
- bottom: 0;
- width: 20px;
- height: 2px;
- background: linear-gradient(90deg, #409eff, transparent);
- border-radius: 1px;
-}
+ .info-label::after {
+ content: "";
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ width: 20px;
+ height: 2px;
+ background: linear-gradient(90deg, #409eff, transparent);
+ border-radius: 1px;
+ }
-.info-value-wrapper {
- flex: 1;
-}
+ .info-value-wrapper {
+ flex: 1;
+ }
-.info-value {
- display: block;
- color: #303133;
- font-size: 15px;
- font-weight: 500;
- line-height: 1.5;
- word-break: break-all;
-}
+ .info-value {
+ display: block;
+ color: #303133;
+ font-size: 15px;
+ font-weight: 500;
+ line-height: 1.5;
+ word-break: break-all;
+ }
</style>
--
Gitblit v1.9.3