From a9d97b150701e634bdb751eab277696abd136cca Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 16 六月 2026 14:39:47 +0800
Subject: [PATCH] 君歌app 1.依照web端功能修改
---
src/pages/productionDesign/bom/BomStructureItem.vue | 256 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 256 insertions(+), 0 deletions(-)
diff --git a/src/pages/productionDesign/bom/BomStructureItem.vue b/src/pages/productionDesign/bom/BomStructureItem.vue
new file mode 100644
index 0000000..689010c
--- /dev/null
+++ b/src/pages/productionDesign/bom/BomStructureItem.vue
@@ -0,0 +1,256 @@
+<template>
+ <view class="structure-item-wrapper"
+ :class="{ 'is-root': level === 0, 'is-last': isLast }">
+ <!-- 鏍戝舰杩炴帴绾� (闈炴牴鑺傜偣鏄剧ず) -->
+ <template v-if="level > 0">
+ <view class="line-v"></view>
+ <view class="line-h"></view>
+ </template>
+ <view class="structure-item-card"
+ :class="{ 'has-children': hasChildren }">
+ <view class="card-main">
+ <view class="item-header"
+ @click="toggleExpand">
+ <view class="header-left">
+ <view v-if="hasChildren"
+ class="expand-icon"
+ :class="{ 'is-expanded': isExpanded }">
+ <up-icon name="arrow-right"
+ size="14"
+ color="#999"></up-icon>
+ </view>
+ <view v-else
+ class="dot-icon"></view>
+ <text class="item-title">{{ item.productName || '鏈�夋嫨浜у搧' }}</text>
+ </view>
+ <up-tag v-if="hasChildren"
+ text="缁勫悎"
+ type="primary"
+ size="mini"
+ plain
+ shape="circle" />
+ </view>
+ <view class="item-body">
+ <view class="info-grid">
+ <view class="info-item">
+ <text class="label">瑙勬牸鍨嬪彿锛�</text>
+ <text class="value">{{ item.model || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="label">娑堣�楀伐搴忥細</text>
+ <text class="value">{{ getProcessName(item.processId) }}</text>
+ </view>
+ <view class="info-item">
+ <text class="label">鍗曚綅鏁伴噺锛�</text>
+ <text class="value highlight">{{ item.unitQuantity || 0 }}</text>
+ </view>
+ <view class="info-item">
+ <text class="label">闇�姹傛�婚噺锛�</text>
+ <text class="value highlight">{{ item.demandedQuantity || 0 }}</text>
+ </view>
+ <view class="info-item">
+ <text class="label">鍗曚綅锛�</text>
+ <text class="value">{{ item.unit || '-' }}</text>
+ </view>
+ <view class="info-item">
+ <text class="label">鐩樻暟锛�</text>
+ <text class="value">{{ item.diskQuantity || 0 }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ <!-- 閫掑綊灞曠ず瀛愯妭鐐� -->
+ <view v-if="hasChildren && isExpanded"
+ class="children-container">
+ <BomStructureItem v-for="(child, index) in item.children"
+ :key="index"
+ :item="child"
+ :level="level + 1"
+ :isLast="index === item.children.length - 1"
+ :processOptions="processOptions" />
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { ref, computed, defineProps } from "vue";
+
+ const props = defineProps({
+ item: {
+ type: Object,
+ required: true,
+ },
+ level: {
+ type: Number,
+ default: 0,
+ },
+ isLast: {
+ type: Boolean,
+ default: false,
+ },
+ processOptions: {
+ type: Array,
+ default: () => [],
+ },
+ });
+
+ const isExpanded = ref(true);
+ const hasChildren = computed(
+ () => props.item.children && props.item.children.length > 0
+ );
+
+ const toggleExpand = () => {
+ if (hasChildren.value) {
+ isExpanded.value = !isExpanded.value;
+ }
+ };
+
+ const getProcessName = id => {
+ const process = props.processOptions.find(p => p.id === id);
+ return process ? process.name : "-";
+ };
+</script>
+
+<script>
+ export default {
+ name: "BomStructureItem",
+ };
+</script>
+
+<style scoped lang="scss">
+ .structure-item-wrapper {
+ position: relative;
+ padding-left: 44rpx;
+
+ &.is-root {
+ padding-left: 0;
+ }
+ }
+
+ // 鍨傜洿杩炴帴绾挎
+ .line-v {
+ position: absolute;
+ left: 18rpx; // 灞呬腑浜� 44rpx 鐨勭缉杩涘唴
+ top: -20rpx; // 鍚戜笂寤朵几瑕嗙洊涓婁竴涓妭鐐圭殑 margin-bottom
+ bottom: 0;
+ width: 2rpx;
+ background-color: #ddd;
+ z-index: 1;
+ }
+
+ // 鏈�鍚庝竴涓妭鐐圭殑鍨傜洿绾垮彧寤朵几鍒版按骞崇嚎浣嶇疆
+ .is-last > .line-v {
+ bottom: auto;
+ height: 60rpx; // 20rpx (top offset) + 40rpx (to horizontal line)
+ }
+
+ // 姘村钩杩炴帴绾�
+ .line-h {
+ position: absolute;
+ left: 18rpx;
+ top: 40rpx; // 瀵归綈鍒板崱鐗囧唴閮ㄥ浘鏍囦腑蹇� (padding 24 + icon 32/2)
+ width: 26rpx;
+ height: 2rpx;
+ background-color: #ddd;
+ z-index: 1;
+ }
+
+ .structure-item-card {
+ position: relative;
+ background: #fff;
+ border-radius: 16rpx;
+ margin-bottom: 20rpx;
+ padding: 24rpx;
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
+ border: 1rpx solid #f0f0f0;
+ transition: all 0.3s;
+ z-index: 2;
+
+ &:active {
+ background-color: #f9f9f9;
+ }
+
+ &.has-children {
+ border-left: 6rpx solid #3c9cff;
+ }
+ }
+
+ .card-main {
+ .item-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20rpx;
+
+ .header-left {
+ display: flex;
+ align-items: center;
+ flex: 1;
+
+ .expand-icon {
+ margin-right: 12rpx;
+ transition: transform 0.3s;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 32rpx;
+ height: 32rpx;
+
+ &.is-expanded {
+ transform: rotate(90deg);
+ }
+ }
+
+ .dot-icon {
+ width: 12rpx;
+ height: 12rpx;
+ border-radius: 50%;
+ background-color: #ccc;
+ margin-right: 20rpx;
+ margin-left: 10rpx;
+ }
+
+ .item-title {
+ font-size: 30rpx;
+ font-weight: bold;
+ color: #333;
+ line-height: 1.4;
+ }
+ }
+ }
+
+ .item-body {
+ .info-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 12rpx 20rpx;
+
+ .info-item {
+ display: flex;
+ font-size: 24rpx;
+ line-height: 1.5;
+
+ .label {
+ color: #999;
+ white-space: nowrap;
+ }
+
+ .value {
+ color: #666;
+ word-break: break-all;
+
+ &.highlight {
+ color: #3c9cff;
+ font-weight: 500;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .children-container {
+ position: relative;
+ }
+</style>
--
Gitblit v1.9.3