diff --git a/src/components/ProductSelector.vue b/src/components/ProductSelector.vue index 2ed8bc0..a1f0942 100644 --- a/src/components/ProductSelector.vue +++ b/src/components/ProductSelector.vue @@ -7,7 +7,27 @@ arrow @click="open" > - + + (); const expandedProductKeyList = ref>([]); const selectedSpecValueMap = reactive>({}); -const selectedText = computed(() => { +const selectedProduct = computed(() => { if (!props.modelValue?.skuId) { - return ""; + return undefined; } - const product = props.selectedProduct || productList.value.find(item => item.skuList?.some(sku => sku.id === props.modelValue?.skuId)); - const sku = product?.skuList?.find(item => item.id === props.modelValue?.skuId); - const unit = sku?.unitList?.find(item => item.id === props.modelValue?.skuUnitId); - return `${getProductSkuText(product?.name, sku)}${unit?.name ? ` · ${unit.name}` : ""}`; + return props.selectedProduct || productList.value.find(item => item.skuList?.some(sku => sku.id === props.modelValue?.skuId)); }); +const selectedSku = computed(() => selectedProduct.value?.skuList?.find(item => item.id === props.modelValue?.skuId)); +const selectedUnit = computed(() => selectedSku.value?.unitList?.find(item => item.id === props.modelValue?.skuUnitId)); +const selectedProductName = computed(() => selectedProduct.value?.name || ""); +const selectedSkuSpecEntries = computed(() => getProductSkuSpecEntries(selectedSku.value || { specValueIdList: [] }, selectedProduct.value?.specList || [])); const filteredProductList = computed(() => { const text = keyword.value.toLocaleLowerCase(); return productList.value.filter(item => !text || `${item.name}${item.code}`.toLocaleLowerCase().includes(text)); @@ -231,6 +252,13 @@ function selectUnit(sku: ProductSku, skuUnitId: string): void { .picker-text { color: var(--td-text-color-primary); } + + .selected-tags { + gap: .375rem; + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + } } .popup { diff --git a/src/components/ProductSkuSnapshotTags.vue b/src/components/ProductSkuSnapshotTags.vue new file mode 100644 index 0000000..2355e70 --- /dev/null +++ b/src/components/ProductSkuSnapshotTags.vue @@ -0,0 +1,47 @@ + + + + + diff --git a/src/layout/MainLayout.vue b/src/layout/MainLayout.vue index 16ce98f..63ba2ce 100644 --- a/src/layout/MainLayout.vue +++ b/src/layout/MainLayout.vue @@ -35,7 +35,7 @@ import AppNavBar from "@/components/navbar/index.vue"; import PageTransition from "@/components/PageTransition.vue"; import { useTabBarStore } from "@/store/tabBarStore"; -import { gaoRoleCodes, permissionCodes } from "@/utils/permission"; +import { permissionCodes } from "@/utils/permission"; import { useUserStore } from "timi-web-api"; const route = useRoute(); @@ -71,7 +71,22 @@ const tabList: TabItem[] = [ text: "客户", permission: [permissionCodes.customer.create, permissionCodes.eventRecord.create] }, - { value: "/product", icon: "layers", text: "产品", role: gaoRoleCodes.storeManager }, + { + value: "/product", + icon: "layers", + text: "产品", + permission: [ + permissionCodes.productCategory.read, + permissionCodes.product.read, + permissionCodes.productStock.read, + permissionCodes.salesOrder.read, + permissionCodes.fundRecord.read, + permissionCodes.orderFulfillment.read, + permissionCodes.packageConfig.read, + permissionCodes.stat.read + ], + permissionMode: "or" + }, { value: "/store", icon: "shop-3", text: "门店", permission: permissionCodes.stat.read }, { value: "/management", icon: "setting-1", text: "管理" } ]; diff --git a/src/pages/fulfillment/OrderFulfillmentCreate.vue b/src/pages/fulfillment/OrderFulfillmentCreate.vue index 9ebd8b8..aaa9d9e 100644 --- a/src/pages/fulfillment/OrderFulfillmentCreate.vue +++ b/src/pages/fulfillment/OrderFulfillmentCreate.vue @@ -24,8 +24,27 @@
- - +
+ + +
+
+ + +
navBarStore.clearRight()); justify-content: space-between; .title { + gap: .375rem; + display: flex; + flex-direction: column; + .heading { + gap: .5rem; + display: flex; + min-width: 0; + align-items: baseline; + justify-content: space-between; + + strong { + min-width: 0; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + span { + color: var(--td-text-color-secondary); + font-size: .75rem; + white-space: nowrap; + } + } + + .sku-tags { + gap: .375rem; + display: flex; + flex-wrap: wrap; + align-items: center; + } } .input { diff --git a/src/pages/fulfillment/OrderFulfillmentDetail.vue b/src/pages/fulfillment/OrderFulfillmentDetail.vue index b8eeb96..e75c26d 100644 --- a/src/pages/fulfillment/OrderFulfillmentDetail.vue +++ b/src/pages/fulfillment/OrderFulfillmentDetail.vue @@ -30,10 +30,19 @@ class="item" v-for="item in fulfillment.itemList || []" :key="item.id" - :title="getItemTitle(item)" - :description="`${item.quantity} ${item.unitSnapshot}`" + :title="item.productNameSnapshot || '未命名产品'" :note="`待履约 ${item.reservedBefore || 0} → ${item.reservedAfter || 0}`" > +