|
|
@@ -0,0 +1,340 @@
|
|
|
+<template>
|
|
|
+ <block v-if="!isBom">
|
|
|
+ <view class="search-box">
|
|
|
+ <up-search placeholder="搜索关键词" v-model="keyword" height="35" @blur="onSearch" :clearabled="false"
|
|
|
+ :showAction="false" />
|
|
|
+ <view v-if="content.where.condition" class="clear" @click.stop="onSearch('')">
|
|
|
+ <up-icon name="close-circle-fill" size="20" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view style="height: 20rpx;" />
|
|
|
+ </block>
|
|
|
+
|
|
|
+ <My_listbox v-if="!isBom" ref="listBox" :empty="!list.length" :pullDown="!isBom" @getlist="getList">
|
|
|
+ <showList :result="resultIds" :list='list' @onClick="onSelect" />
|
|
|
+ <view style="height: 200rpx;" />
|
|
|
+ </My_listbox>
|
|
|
+
|
|
|
+ <view v-else-if="bomList.length" class="bom">
|
|
|
+ <view class="left">
|
|
|
+ <view class="class1" :class="active.class1 == index ? 'class1active' : ''" @click="changeClass1(index)"
|
|
|
+ v-for="(item, index) in bomList" :key="item.plm_bomid" hover-class="navigator-hover">
|
|
|
+ {{ item.bomname }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="right">
|
|
|
+ <My_listbox ref="listBox" :pullDown="false">
|
|
|
+ <up-collapse :value="collapse1" @change="changeCollapse1($event)">
|
|
|
+ <up-collapse-item :ref="el => {
|
|
|
+ if (el) {
|
|
|
+ collapseRefs['collapse' + item.plm_bomid] = el
|
|
|
+ }
|
|
|
+ }" :cellCustomStyle="{
|
|
|
+ backgroundColor: '#fff',
|
|
|
+ }" v-for="item in bomList[active.class1].subdep" :key="item.plm_bomid" :title="item.bomname"
|
|
|
+ :name="item.plm_bomid">
|
|
|
+ <up-collapse @change="changeCollapse($event, item.plm_bomid)" v-if="item.subdep.length"
|
|
|
+ :name="item.plm_bomid">
|
|
|
+ <up-collapse-item :cellCustomStyle="{
|
|
|
+ backgroundColor: '#fff',
|
|
|
+ }" :ref="el => {
|
|
|
+ if (el) {
|
|
|
+ collapseRefs['collapse' + item.plm_bomid] = el
|
|
|
+ }
|
|
|
+ }" v-for="item1 in item.subdep" :key="item1.plm_bomid" :title="item1.bomname"
|
|
|
+ :name="item1.plm_bomid">
|
|
|
+ <showList v-if="item1.items.length" size="small" :result="resultIds" :list='item1.items'
|
|
|
+ @onClick="onSelect" />
|
|
|
+ </up-collapse-item>
|
|
|
+ </up-collapse>
|
|
|
+
|
|
|
+ <showList v-if="item.items.length" size="small" :result="resultIds" :list='item.items'
|
|
|
+ @onClick="onSelect" />
|
|
|
+ </up-collapse-item>
|
|
|
+ </up-collapse>
|
|
|
+ <view style="height: 200rpx;" />
|
|
|
+ </My_listbox>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <My_listbox v-else ref="listBox" :empty="true" @getlist="getBomList" />
|
|
|
+ <view class="footer">
|
|
|
+ <My-button :text="`确定添加(${resultIds.length})`" @onClick="onAdd" />
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, reactive, getCurrentInstance, nextTick } from 'vue';
|
|
|
+import { onLoad } from '@dcloudio/uni-app';
|
|
|
+import showList from "./accessoriesList.vue"
|
|
|
+const { $Http } = getCurrentInstance().proxy;
|
|
|
+
|
|
|
+const listBox = ref(null);
|
|
|
+const isBom = ref(false);
|
|
|
+let result = reactive([]);
|
|
|
+const resultIds = ref([]);
|
|
|
+
|
|
|
+const content = reactive({
|
|
|
+ loading: false,
|
|
|
+ "pageNumber": 1,
|
|
|
+ "pageSize": 20,
|
|
|
+ "where": {
|
|
|
+ "condition": ""
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+function onAdd() {
|
|
|
+ $Http.selectAcc(result)
|
|
|
+}
|
|
|
+
|
|
|
+function onSelect(e) {
|
|
|
+ if (result.some(item => item.itemid == e.itemid)) {
|
|
|
+ result = result.filter(item => item.itemid != e.itemid);
|
|
|
+ } else {
|
|
|
+ result.push(e);
|
|
|
+ }
|
|
|
+ resultIds.value = result.map(item => item.itemid);
|
|
|
+}
|
|
|
+
|
|
|
+const list = ref([]);
|
|
|
+
|
|
|
+onLoad((options) => {
|
|
|
+ console.log("options", options)
|
|
|
+ console.log("$Http", $Http)
|
|
|
+
|
|
|
+ result = result.concat(JSON.parse(options.list || '[]'));
|
|
|
+ resultIds.value = result.map(item => item.itemid);
|
|
|
+ console.log("初始选中", result, resultIds.value)
|
|
|
+ let content1 = $Http.content1;
|
|
|
+ content.sys_enterpriseid = content1.sys_enterpriseid;
|
|
|
+ content.sa_workorderid = content1.sa_workorderid;
|
|
|
+
|
|
|
+ if (content1.sku) $Http.basic({
|
|
|
+ "id": 2025080610424703,
|
|
|
+ "content": content1
|
|
|
+ }).then(res => {
|
|
|
+ console.log("查询产品是否存在BOM", res)
|
|
|
+ if (res.data == 0) {
|
|
|
+ // 不存在BOM
|
|
|
+ getList(true);
|
|
|
+ } else {
|
|
|
+ // 存在BOM
|
|
|
+ isBom.value = true;
|
|
|
+ getBomList();
|
|
|
+ }
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+const bomList = ref([]);
|
|
|
+
|
|
|
+let active = reactive({
|
|
|
+ class1: 0
|
|
|
+});
|
|
|
+
|
|
|
+function changeClass1(index) {
|
|
|
+ active.class1 = index;
|
|
|
+}
|
|
|
+
|
|
|
+// 折叠面板
|
|
|
+const collapseRefs = ref({})
|
|
|
+const collapse1 = ref([])
|
|
|
+
|
|
|
+function changeCollapse1(e) {
|
|
|
+ collapse1.value = e.filter(v => v.status == 'open').map(v => v.name)
|
|
|
+}
|
|
|
+
|
|
|
+function changeCollapse(e, id) {
|
|
|
+ nextTick(() => {
|
|
|
+ collapseRefs.value['collapse' + id].init()
|
|
|
+ });
|
|
|
+ setTimeout(() => {
|
|
|
+ nextTick(() => {
|
|
|
+ collapseRefs.value['collapse' + id].init()
|
|
|
+ });
|
|
|
+ }, 330);
|
|
|
+}
|
|
|
+
|
|
|
+// 有bom
|
|
|
+function getBomList() {
|
|
|
+ $Http.basic({
|
|
|
+ "id": "2025080610425503",
|
|
|
+ content: {
|
|
|
+ "sa_aftersalesbomid": content.sa_workorderid,
|
|
|
+ "sys_enterpriseid": content.sys_enterpriseid,
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ console.log("获取bom配件列表", res)
|
|
|
+ listBox.value.refreshToComplete();
|
|
|
+ listBox.value.setHeight();
|
|
|
+ if (res.code == 1) {
|
|
|
+ bomList.value = processBomData(res.data)
|
|
|
+ console.log("bomList", bomList.value);
|
|
|
+ } else {
|
|
|
+ if (res.msg) uni.showToast({
|
|
|
+ title: res.msg,
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function processBomData(originalData) {
|
|
|
+ // 1. 提取所有一级分类节点
|
|
|
+ const topLevelNodes = [];
|
|
|
+
|
|
|
+ // 遍历原始数据
|
|
|
+ originalData.forEach(dataSet => {
|
|
|
+ dataSet.bom?.forEach(rootNode => {
|
|
|
+ // 提取根节点下的一级分类
|
|
|
+ if (rootNode.subdep && rootNode.subdep.length > 0) {
|
|
|
+ topLevelNodes.push(...rootNode.subdep);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ // 2. 递归处理节点
|
|
|
+ const processNode = (node) => {
|
|
|
+ node.items = node.items || [];
|
|
|
+ node.subdep = node.subdep || [];
|
|
|
+ // 如果当前节点没有items和subdep,直接返回null
|
|
|
+ if (node.items.length === 0 && node.subdep.length === 0) return null;
|
|
|
+
|
|
|
+ try {
|
|
|
+ if (node.items.length) node.items = node.items.map(item => {
|
|
|
+ item.imageUrl = item.attinfos.length ? $Http.getSpecifiedImage(item.attinfos[0]) : ''
|
|
|
+ return item;
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+
|
|
|
+ }
|
|
|
+ // 创建新节点副本
|
|
|
+ const newNode = { ...node };
|
|
|
+ // 处理子节点
|
|
|
+ if (node.subdep.length) newNode.subdep = node.subdep.map(subNode => processNode(subNode)).filter(subNode => subNode !== null);
|
|
|
+ return newNode;
|
|
|
+ };
|
|
|
+
|
|
|
+ // 3. 处理所有一级分类节点
|
|
|
+ return topLevelNodes.map(node => processNode(node)).filter(node => node && (node.subdep.length || node.items.length));
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// 无BOM
|
|
|
+
|
|
|
+const keyword = ref('');
|
|
|
+
|
|
|
+function onSearch(e) {
|
|
|
+ if (content.where.condition == e) return;
|
|
|
+ content.where.condition = e;
|
|
|
+ keyword.value = e;
|
|
|
+ getList(true);
|
|
|
+}
|
|
|
+
|
|
|
+function getList(init = false) {
|
|
|
+ if (isBom.value) return;
|
|
|
+ if (content.loading) return;
|
|
|
+ if (init) content.pageNumber = 1;
|
|
|
+ content.loading = true;
|
|
|
+ $Http.basic({
|
|
|
+ "id": "2025080610425103",
|
|
|
+ content
|
|
|
+ }).then(res => {
|
|
|
+ console.log("获取配件列表", res)
|
|
|
+ content.loading = false;
|
|
|
+ listBox.value.refreshToComplete();
|
|
|
+ listBox.value.setHeight();
|
|
|
+ res.data = res.data.map(item => {
|
|
|
+ item.imageUrl = item.attinfos.length ? $Http.getSpecifiedImage(item.attinfos[0]) : ''
|
|
|
+ return item;
|
|
|
+ });
|
|
|
+ if (res.code == 1) {
|
|
|
+ list.value = reactive(res.firstPage ? res.data : list.value.concat(res.data));
|
|
|
+ content.pageTotal = res.pageTotal;
|
|
|
+ content.pageNumber = res.pageNumber;
|
|
|
+ } else {
|
|
|
+ if (res.msg) uni.showToast({
|
|
|
+ title: res.msg,
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.bom {
|
|
|
+ width: 100vw;
|
|
|
+ display: flex;
|
|
|
+ min-height: 100vh;
|
|
|
+
|
|
|
+ .left {
|
|
|
+ width: 250rpx;
|
|
|
+ background: #fff;
|
|
|
+ flex-shrink: 0;
|
|
|
+
|
|
|
+ .class1 {
|
|
|
+ padding: 30rpx 30rpx;
|
|
|
+ width: 250rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 0rpx 8rpx 0rpx 0rpx;
|
|
|
+ font-family: PingFang SC, PingFang SC;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #999999;
|
|
|
+ }
|
|
|
+
|
|
|
+ .class1active {
|
|
|
+ position: relative;
|
|
|
+ background: #F7F7FF;
|
|
|
+ color: #3774F6;
|
|
|
+ }
|
|
|
+
|
|
|
+ .class1active::after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 8rpx;
|
|
|
+ height: 100%;
|
|
|
+ background: #3774F6;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .right {
|
|
|
+ flex: 1;
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.search-box {
|
|
|
+ position: relative;
|
|
|
+ padding: 20rpx;
|
|
|
+ background: #fff;
|
|
|
+
|
|
|
+ .clear {
|
|
|
+ position: absolute;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ right: 0;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ width: 80rpx;
|
|
|
+ padding-left: 10rpx;
|
|
|
+ height: 70rpx;
|
|
|
+ z-index: 2;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.footer {
|
|
|
+ position: fixed;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 120rpx;
|
|
|
+ padding: 10rpx 20rpx;
|
|
|
+ background: #fff;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+</style>
|