| src/api/productionManagement/processRoute.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/api/productionManagement/productionOrder.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages.json | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages/productionManagement/processRoute/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages/productionManagement/processRoute/items.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages/productionManagement/productionOrder/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages/works.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/api/productionManagement/processRoute.js
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,37 @@ // å·¥èºè·¯çº¿ç¸å ³æ¥å£ import request from "@/utils/request"; // å页æ¥è¯¢å·¥èºè·¯çº¿å表 export function listPage(query) { return request({ url: "/technologyRouting/page", method: "get", params: query, }); } // æ¥è¯¢å·¥èºè·¯çº¿é¡¹ç®å表 export function findProcessRouteItemList(query) { return request({ url: "/technologyRoutingOperation/list", method: "get", params: query, }); } // è·åå·¥åºåæ°å表 export function getProcessParamList(query) { return request({ url: "/technologyRoutingOperationParam/list", method: "get", params: query, }); } // æ¥è¯¢BOMç»æ (å·¥èºè·¯çº¿) export function queryBomList(bomId) { return request({ url: "/technologyBomStructure/listByBomId/" + bomId, method: "get", }); } src/api/productionManagement/productionOrder.js
@@ -42,3 +42,29 @@ method: "get", }); } // è·åç产订åå ³èçå·¥èºè·¯çº¿ä¸»ä¿¡æ¯ export function getOrderProcessRouteMain(orderId) { return request({ url: "/productionOrderRouting/listMain", method: "get", params: { orderId }, }); } // æ¥è¯¢BOMç»æ (ç产订å) export function queryOrderBomList(bomId) { return request({ url: "/productionBomStructure/listByBomId/" + bomId, method: "get", }); } // è·åå·¥åºåæ°å表 (ç产订å) export function findProcessParamListOrder(query) { return request({ url: "/productionOrderRoutingOperationParam/list", method: "get", params: query, }); } src/pages.json
@@ -789,6 +789,20 @@ } }, { "path": "pages/productionManagement/processRoute/index", "style": { "navigationBarTitleText": "å·¥èºè·¯çº¿", "navigationStyle": "custom" } }, { "path": "pages/productionManagement/processRoute/items", "style": { "navigationBarTitleText": "路线项ç®", "navigationStyle": "custom" } }, { "path": "pages/productionManagement/productionDispatching/index", "style": { "navigationBarTitleText": "ç产派工", src/pages/productionManagement/processRoute/index.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,287 @@ <template> <view class="process-route"> <!-- 使ç¨éç¨é¡µé¢å¤´é¨ç»ä»¶ --> <PageHeader title="å·¥èºè·¯çº¿" @back="goBack" /> <!-- æç´¢åºå --> <view class="search-section"> <view class="search-bar"> <view class="search-input"> <up-input class="search-text" placeholder="请è¾å ¥è§æ ¼åç§°æç´¢" v-model="searchForm.model" @change="handleQuery" clearable /> </view> <view class="filter-button" @click="handleQuery"> <up-icon name="search" size="24" color="#999"></up-icon> </view> </view> </view> <!-- å表åºå --> <scroll-view scroll-y class="list-container" v-if="tableData.length > 0" @scrolltolower="loadMore"> <view v-for="(item, index) in tableData" :key="item.id || index" @click="goDetail(item)"> <view class="ledger-item"> <view class="item-header"> <view class="item-left"> <view class="document-icon"> <up-icon name="share-square" size="16" color="#ffffff"></up-icon> </view> <text class="item-id">{{ item.processRouteCode }}</text> </view> </view> <up-divider></up-divider> <view class="item-details"> <view class="detail-row"> <text class="detail-label">产ååç§°</text> <text class="detail-value font-bold">{{ item.productName || '-' }}</text> </view> <view class="detail-row"> <text class="detail-label">è§æ ¼åç§°</text> <text class="detail-value">{{ item.model || '-' }}</text> </view> <view class="detail-row"> <text class="detail-label">BOMç¼å·</text> <text class="detail-value">{{ item.bomNo || '-' }}</text> </view> <view class="detail-row"> <text class="detail-label">æè¿°</text> <text class="detail-value">{{ item.description || '-' }}</text> </view> </view> <view class="item-footer"> <text class="more-detail">路线项ç®</text> <up-icon name="arrow-right" size="14" color="#999"></up-icon> </view> </view> </view> <up-loadmore :status="loadStatus" v-if="tableData.length >= page.size" /> </scroll-view> <view v-else class="no-data"> <up-empty mode="data" text="ææ å·¥èºè·¯çº¿æ°æ®"></up-empty> </view> </view> </template> <script setup> import { ref, reactive, toRefs, getCurrentInstance } from "vue"; import { onShow } from "@dcloudio/uni-app"; import { listPage } from "@/api/productionManagement/processRoute.js"; import PageHeader from "@/components/PageHeader.vue"; const { proxy } = getCurrentInstance(); // å è½½ç¶æ const loading = ref(false); const loadStatus = ref("loadmore"); // åè¡¨æ°æ® const tableData = ref([]); // å页é ç½® const page = reactive({ current: 1, size: 10, total: 0, }); // æç´¢è¡¨åæ°æ® const data = reactive({ searchForm: { model: "", }, }); const { searchForm } = toRefs(data); // è¿åä¸ä¸é¡µ const goBack = () => { uni.navigateBack(); }; // æ¥è¯¢å表 const handleQuery = () => { page.current = 1; tableData.value = []; getList(); }; // å è½½æ´å¤ const loadMore = () => { if (loadStatus.value === "nomore" || loading.value) return; page.current++; getList(); }; // è·ååè¡¨æ°æ® const getList = () => { loading.value = true; loadStatus.value = "loading"; const params = { current: page.current, size: page.size, model: searchForm.value.model, }; listPage(params) .then(res => { loading.value = false; const records = res.data.records || []; if (page.current === 1) { tableData.value = records; } else { tableData.value = [...tableData.value, ...records]; } if (records.length < page.size) { loadStatus.value = "nomore"; } else { loadStatus.value = "loadmore"; } page.total = res.data.total || 0; }) .catch(() => { loading.value = false; loadStatus.value = "loadmore"; uni.showToast({ title: "å 载失败", icon: "error", }); }); }; // è·³è½¬è·¯çº¿é¡¹ç® const goDetail = item => { uni.navigateTo({ url: `/pages/productionManagement/processRoute/items?id=${ item.id }&processRouteCode=${ item.processRouteCode }&productName=${encodeURIComponent( item.productName || "" )}&model=${encodeURIComponent(item.model || "")}&bomNo=${ item.bomNo || "" }&bomId=${item.bomId || ""}&description=${encodeURIComponent( item.description || "" )}`, }); }; // 页颿¾ç¤ºæ¶å è½½æ°æ® onShow(() => { handleQuery(); }); </script> <style scoped lang="scss"> @import "@/styles/sales-common.scss"; .process-route { min-height: 100vh; background: #f8f9fa; display: flex; flex-direction: column; } .list-container { flex: 1; height: 0; } .ledger-item { background: #fff; margin: 20rpx; padding: 24rpx; border-radius: 16rpx; box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06); .item-header { display: flex; justify-content: space-between; align-items: center; padding-bottom: 12rpx; .item-left { display: flex; align-items: center; .document-icon { width: 44rpx; height: 44rpx; background: #3c9cff; border-radius: 10rpx; display: flex; justify-content: center; align-items: center; margin-right: 20rpx; } .item-id { font-size: 30rpx; font-weight: bold; color: #333; } } } .item-details { padding: 16rpx 0; .detail-row { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 16rpx; .detail-label { font-size: 26rpx; color: #999; min-width: 140rpx; } .detail-value { font-size: 26rpx; color: #333; text-align: right; flex: 1; &.font-bold { font-weight: bold; } } } } .item-footer { display: flex; justify-content: flex-end; align-items: center; padding-top: 16rpx; border-top: 1rpx solid #f0f0f0; .more-detail { font-size: 24rpx; color: #3c9cff; margin-right: 8rpx; } } } .no-data { padding-top: 200rpx; } </style> src/pages/productionManagement/processRoute/items.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,544 @@ <template> <view class="process-route-items"> <PageHeader title="路线项ç®" @back="goBack" /> <!-- 路线åºç¡ä¿¡æ¯å¡ç --> <view class="route-info-card"> <view class="info-row"> <text class="label">å·¥èºè·¯çº¿ç¼å·</text> <text class="value">{{ routeInfo.processRouteCode || '-' }}</text> </view> <view class="info-row"> <text class="label">产ååç§°</text> <text class="value">{{ routeInfo.productName || '-' }}</text> </view> <view class="info-row"> <text class="label">è§æ ¼åç§°</text> <text class="value">{{ routeInfo.model || '-' }}</text> </view> <view class="info-row"> <text class="label">BOMç¼å·</text> <text class="value">{{ routeInfo.bomNo || '-' }}</text> </view> </view> <!-- é项å¡åæ¢ --> <view class="tabs-box"> <up-tabs :list="tabsList" @click="handleTabClick" :current="currentTab"></up-tabs> </view> <!-- å·¥åºé¡¹ç®å表 --> <scroll-view scroll-y class="content-scroll" v-if="currentTab === 0"> <view v-if="itemsList.length > 0"> <view v-for="(item, index) in itemsList" :key="index" class="process-card"> <view class="card-header"> <view class="index-badge">{{ index + 1 }}</view> <text class="process-name">{{ item.technologyOperationName || item.operationName || '-' }}</text> </view> <view class="card-content"> <view class="detail-row"> <text class="detail-label">å ³è产å</text> <text class="detail-value">{{ item.productName || '-' }}</text> </view> <view class="detail-row"> <text class="detail-label">è§æ ¼åå·</text> <text class="detail-value">{{ item.model || '-' }}</text> </view> <view class="detail-row"> <text class="detail-label">åä½</text> <text class="detail-value">{{ item.unit || '-' }}</text> </view> <view class="tag-row"> <up-tag v-if="item.isQuality" text="è´¨æ£" type="primary" size="mini" plain /> <up-tag v-if="item.isProduction" text="ç产" type="success" size="mini" plain /> </view> </view> <view class="card-footer" @click="showParams(item)"> <text class="action-text">æ¥çåæ°å表</text> <up-icon name="arrow-right" size="14" color="#3c9cff"></up-icon> </view> </view> </view> <view v-else class="no-data"> <up-empty mode="data" text="ææ è·¯çº¿é¡¹ç®"></up-empty> </view> </scroll-view> <!-- BOM ç»æå±ç¤º --> <scroll-view scroll-y class="content-scroll" v-if="currentTab === 1"> <view v-if="bomList.length > 0" class="bom-tree"> <view v-for="(node, nIndex) in flatBomList" :key="nIndex" class="bom-node" :style="{ paddingLeft: (node.level * 40) + 'rpx' }"> <view class="bom-node-inner"> <view class="bom-line" v-if="node.level > 0"></view> <view class="bom-content"> <view class="bom-header"> <text class="bom-product">{{ node.productName }}</text> <text class="bom-model" v-if="node.model">({{ node.model }})</text> </view> <view class="bom-details"> <text class="bom-info">å·¥åº: {{ node.operationName || '-' }}</text> <text class="bom-info">æé: {{ node.unitQuantity || 0 }} {{ node.unit || '' }}</text> </view> </view> </view> </view> </view> <view v-else class="no-data"> <up-empty mode="data" text="ææ BOM ç»æ"></up-empty> </view> </scroll-view> <!-- åæ°åè¡¨å¼¹çª --> <up-popup :show="showPopup" mode="bottom" @close="showPopup = false" round="10"> <view class="popup-content"> <view class="popup-header"> <text class="title">åæ°å表 - {{ currentItem.technologyOperationName || currentItem.operationName }}</text> <up-icon name="close" size="20" @click="showPopup = false"></up-icon> </view> <scroll-view scroll-y class="param-list"> <view v-if="paramList.length > 0"> <view v-for="(param, pIndex) in paramList" :key="pIndex" class="param-item"> <view class="param-row"> <text class="param-label">åæ°åç§°ï¼</text> <text class="param-value">{{ param.paramName || '-' }}</text> </view> <view class="param-row"> <text class="param-label">æ åå¼ï¼</text> <text class="param-value">{{ param.standardValue || '-' }}</text> </view> <view class="param-row"> <text class="param-label">åä½ï¼</text> <text class="param-value">{{ param.unit || '-' }}</text> </view> </view> </view> <view v-else class="no-record"> <text>ææ åæ°è®°å½</text> </view> </scroll-view> </view> </up-popup> </view> </template> <script setup> import { ref, reactive, computed } from "vue"; import { onLoad } from "@dcloudio/uni-app"; import { findProcessRouteItemList, getProcessParamList, queryBomList, } from "@/api/productionManagement/processRoute.js"; import { queryOrderBomList, findProcessParamListOrder, } from "@/api/productionManagement/productionOrder.js"; import PageHeader from "@/components/PageHeader.vue"; const routeInfo = ref({}); const itemsList = ref([]); const bomList = ref([]); const loading = ref(false); const pageType = ref("route"); // route | order // éé¡¹å¡ const tabsList = reactive([{ name: "路线项ç®" }, { name: "BOMç»æ" }]); const currentTab = ref(0); // å¼¹çªç¸å ³ const showPopup = ref(false); const currentItem = ref({}); const paramList = ref([]); const paramLoading = ref(false); const goBack = () => { uni.navigateBack(); }; const handleTabClick = item => { currentTab.value = item.index; if (item.index === 1 && bomList.value.length === 0) { fetchBom(); } }; // æå¹³å BOM æ ç¨äºå±ç¤º const flatBomList = computed(() => { const result = []; const flatten = (nodes, level = 0) => { nodes.forEach(node => { result.push({ ...node, level }); if (node.children && node.children.length > 0) { flatten(node.children, level + 1); } }); }; flatten(bomList.value); return result; }); onLoad(options => { if (options.id) { pageType.value = options.type || "route"; routeInfo.value = { id: options.id, processRouteCode: options.processRouteCode || "", productName: decodeURIComponent(options.productName || ""), model: decodeURIComponent(options.model || ""), bomNo: options.bomNo || "", bomId: options.bomId || "", description: decodeURIComponent(options.description || ""), orderId: options.orderId || "", }; fetchItems(options.id); } }); const fetchItems = id => { loading.value = true; findProcessRouteItemList({ routeId: id, orderId: routeInfo.value.orderId }) .then(res => { itemsList.value = res.data || []; loading.value = false; }) .catch(() => { loading.value = false; uni.showToast({ title: "è·å项ç®å¤±è´¥", icon: "error", }); }); }; const fetchBom = () => { console.log(routeInfo.value.bomId, "routeInfo.value.bomId"); if (!routeInfo.value.bomId) return; loading.value = true; const api = pageType.value === "order" ? queryOrderBomList : queryBomList; api(routeInfo.value.bomId) .then(res => { bomList.value = res.data || []; loading.value = false; }) .catch(() => { loading.value = false; uni.showToast({ title: "è·å BOM 失败", icon: "error", }); }); }; const showParams = item => { currentItem.value = item; showPopup.value = true; paramLoading.value = true; paramList.value = []; const api = pageType.value === "order" ? findProcessParamListOrder : getProcessParamList; const params = pageType.value === "order" ? { productionOrderRoutingOperationId: item.id, productionOrderId: routeInfo.value.orderId, } : { technologyRoutingOperationId: item.id }; api(params) .then(res => { paramList.value = res.data || []; paramLoading.value = false; }) .catch(() => { paramLoading.value = false; uni.showToast({ title: "è·ååæ°å¤±è´¥", icon: "error", }); }); }; </script> <style scoped lang="scss"> .process-route-items { min-height: 100vh; background: #f8f9fa; display: flex; flex-direction: column; } .route-info-card { background: #fff; margin: 20rpx; padding: 24rpx; border-radius: 16rpx; box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05); .info-row { display: flex; justify-content: space-between; margin-bottom: 12rpx; &:last-child { margin-bottom: 0; } .label { font-size: 26rpx; color: #999; } .value { font-size: 26rpx; color: #333; font-weight: bold; } } } .tabs-box { background: #fff; margin-bottom: 10rpx; } .content-scroll { flex: 1; height: 0; padding: 0 20rpx; } .process-card { background: #fff; margin-bottom: 24rpx; border-radius: 16rpx; overflow: hidden; box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05); .card-header { display: flex; align-items: center; padding: 20rpx 24rpx; background: #fcfcfc; border-bottom: 1rpx solid #f5f5f5; .index-badge { width: 40rpx; height: 40rpx; background: #3c9cff; color: #fff; border-radius: 20rpx; display: flex; justify-content: center; align-items: center; font-size: 24rpx; margin-right: 20rpx; } .process-name { font-size: 28rpx; font-weight: bold; color: #333; } } .card-content { padding: 24rpx; .detail-row { display: flex; justify-content: space-between; margin-bottom: 12rpx; .detail-label { font-size: 24rpx; color: #999; } .detail-value { font-size: 24rpx; color: #666; } } .tag-row { display: flex; gap: 16rpx; margin-top: 10rpx; } } .card-footer { padding: 16rpx 24rpx; border-top: 1rpx dashed #eee; display: flex; justify-content: space-between; align-items: center; .action-text { font-size: 24rpx; color: #3c9cff; } } } /* BOM æ æ ·å¼ */ .bom-tree { padding: 20rpx 0; } .bom-node { position: relative; margin-bottom: 20rpx; } .bom-node-inner { background: #fff; padding: 20rpx; border-radius: 12rpx; box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03); display: flex; align-items: center; } .bom-line { position: absolute; left: -20rpx; top: 50%; width: 20rpx; height: 2rpx; background: #ddd; } .bom-content { flex: 1; } .bom-header { display: flex; align-items: center; margin-bottom: 8rpx; .bom-product { font-size: 28rpx; font-weight: bold; color: #333; } .bom-model { font-size: 24rpx; color: #999; margin-left: 10rpx; } } .bom-details { display: flex; justify-content: space-between; .bom-info { font-size: 24rpx; color: #666; } } .no-data { padding-top: 100rpx; } /* å¼¹çªæ ·å¼ */ .popup-content { background: #fff; padding: 30rpx; max-height: 70vh; display: flex; flex-direction: column; } .popup-header { display: flex; justify-content: space-between; align-items: center; padding-bottom: 30rpx; border-bottom: 1rpx solid #eee; .title { font-size: 30rpx; font-weight: bold; color: #333; } } .param-list { flex: 1; height: 0; padding-top: 20rpx; } .param-item { padding: 20rpx; background: #f9f9f9; border-radius: 12rpx; margin-bottom: 16rpx; .param-row { display: flex; margin-bottom: 8rpx; &:last-child { margin-bottom: 0; } .param-label { font-size: 24rpx; color: #999; width: 140rpx; } .param-value { font-size: 24rpx; color: #333; flex: 1; } } } .no-record { padding: 100rpx 0; text-align: center; color: #999; font-size: 26rpx; } </style> src/pages/productionManagement/productionOrder/index.vue
@@ -1,43 +1,50 @@ <template> <view class="production-order"> <!-- 使ç¨éç¨é¡µé¢å¤´é¨ç»ä»¶ --> <PageHeader title="ç产订å" @back="goBack" /> <PageHeader title="ç产订å" @back="goBack" /> <!-- æç´¢åºå --> <view class="search-section"> <view class="search-bar"> <view class="search-input"> <up-input class="search-text" <up-input class="search-text" placeholder="请è¾å ¥è®¢åå·æäº§ååç§°" v-model="searchForm.keyword" @change="handleQuery" clearable /> clearable /> </view> <view class="filter-button" @click="handleQuery"> <up-icon name="search" size="24" color="#999"></up-icon> <view class="filter-button" @click="handleQuery"> <up-icon name="search" size="24" color="#999"></up-icon> </view> </view> </view> <!-- å表åºå --> <scroll-view scroll-y class="list-container" v-if="tableData.length > 0" @scrolltolower="loadMore"> <view v-for="(item, index) in tableData" :key="item.id || index"> <scroll-view scroll-y class="list-container" v-if="tableData.length > 0" @scrolltolower="loadMore"> <view v-for="(item, index) in tableData" :key="item.id || index"> <view class="ledger-item"> <view class="item-header"> <view class="item-left"> <view class="document-icon"> <up-icon name="file-text" size="16" color="#ffffff"></up-icon> <up-icon name="file-text" size="16" color="#ffffff"></up-icon> </view> <text class="item-id">{{ item.npsNo }}</text> </view> <view class="item-right"> <up-tag :text="getStatusText(item.status)" :type="getStatusType(item.status)" size="mini" /> <up-tag :text="getStatusText(item.status)" :type="getStatusType(item.status)" size="mini" /> </view> </view> <up-divider></up-divider> <view class="item-details"> <view class="detail-row"> <text class="detail-label">产ååç§°</text> @@ -65,36 +72,53 @@ <text class="detail-value">{{ formatDate(item.planCompleteTime) }}</text> </view> </view> <view class="item-footer"> <view class="action-btns"> <up-button type="primary" size="mini" plain text="æ¥æº" @click="goSource(item)"></up-button> <up-button type="success" size="mini" plain text="é¢æè¯¦æ " @click="goPickingDetail(item)"></up-button> <up-button type="info" size="mini" plain text="å·¥èºè·¯çº¿" @click="goProcessRoute(item)"></up-button> <up-button type="primary" size="mini" plain text="æ¥æº" @click="goSource(item)"></up-button> <up-button type="success" size="mini" plain text="é¢æè¯¦æ " @click="goPickingDetail(item)"></up-button> </view> </view> </view> </view> <up-loadmore :status="loadStatus" v-if="tableData.length >= page.size" /> <up-loadmore :status="loadStatus" v-if="tableData.length >= page.size" /> </scroll-view> <view v-else class="no-data"> <up-empty mode="data" text="ææ çäº§è®¢åæ°æ®"></up-empty> <view v-else class="no-data"> <up-empty mode="data" text="ææ çäº§è®¢åæ°æ®"></up-empty> </view> </view> </template> <script setup> import { ref, reactive, toRefs, getCurrentInstance } from "vue"; import { onShow } from '@dcloudio/uni-app'; import { onShow } from "@dcloudio/uni-app"; import dayjs from "dayjs"; import { productOrderListPage } from "@/api/productionManagement/productionOrder.js"; import { productOrderListPage, getOrderProcessRouteMain, } from "@/api/productionManagement/productionOrder.js"; import PageHeader from "@/components/PageHeader.vue"; const { proxy } = getCurrentInstance(); // å è½½ç¶æ const loading = ref(false); const loadStatus = ref('loadmore'); const loadStatus = ref("loadmore"); // åè¡¨æ°æ® const tableData = ref([]); @@ -119,12 +143,12 @@ }; // æ ¼å¼åæ¥æ const formatDate = (date) => { return date ? dayjs(date).format('YYYY-MM-DD') : '-'; const formatDate = date => { return date ? dayjs(date).format("YYYY-MM-DD") : "-"; }; // è·åç¶æææ¬ const getStatusText = (status) => { const getStatusText = status => { const statusMap = { 1: "å¾ å¼å§", 2: "è¿è¡ä¸", @@ -135,7 +159,7 @@ }; // è·åç¶æç±»å const getStatusType = (status) => { const getStatusType = status => { const typeMap = { 1: "primary", 2: "warning", @@ -146,7 +170,7 @@ }; // 宿è¿åº¦ç¾åæ¯ const toProgressPercentage = (val) => { const toProgressPercentage = val => { const n = Number(val); if (!Number.isFinite(n)) return 0; if (n <= 0) return 0; @@ -155,7 +179,7 @@ }; // è¿åº¦æ¡é¢è² const progressColor = (percentage) => { const progressColor = percentage => { const p = toProgressPercentage(percentage); if (p < 30) return "#f56c6c"; if (p < 50) return "#e6a23c"; @@ -172,7 +196,7 @@ // å è½½æ´å¤ const loadMore = () => { if (loadStatus.value === 'nomore' || loading.value) return; if (loadStatus.value === "nomore" || loading.value) return; page.current++; getList(); }; @@ -180,16 +204,17 @@ // è·ååè¡¨æ°æ® const getList = () => { loading.value = true; loadStatus.value = 'loading'; loadStatus.value = "loading"; const params = { current: page.current, size: page.size, npsNo: searchForm.value.keyword, productName: searchForm.value.keyword productName: searchForm.value.keyword, }; productOrderListPage(params).then((res) => { productOrderListPage(params) .then(res => { loading.value = false; const records = res.data.records || []; if (page.current === 1) { @@ -199,32 +224,63 @@ } if (records.length < page.size) { loadStatus.value = 'nomore'; loadStatus.value = "nomore"; } else { loadStatus.value = 'loadmore'; loadStatus.value = "loadmore"; } page.total = res.data.total || 0; }).catch(() => { }) .catch(() => { loading.value = false; loadStatus.value = 'loadmore'; loadStatus.value = "loadmore"; uni.showToast({ title: 'å 载失败', icon: 'error' title: "å 载失败", icon: "error", }); }); }; // 跳转工èºè·¯çº¿ (BOM) const goProcessRoute = item => { getOrderProcessRouteMain(item.id) .then(res => { const data = res.data || {}; if (!data.id) { uni.showToast({ title: "æªæ¾å°å·¥èºè·¯çº¿", icon: "none" }); return; } uni.navigateTo({ url: `/pages/productionManagement/processRoute/items?id=${ data.id }&bomId=${data.orderBomId}&processRouteCode=${ data.processRouteCode || "" }&productName=${encodeURIComponent( item.productName || "" )}&model=${encodeURIComponent(item.model || "")}&orderId=${ item.id }&type=order`, }); }) .catch(() => { uni.showToast({ title: "è·å路线失败", icon: "none" }); }); }; // è·³è½¬æ¥æº const goSource = (item) => { const goSource = item => { uni.navigateTo({ url: `/pages/productionManagement/productionOrder/source?id=${item.id}&productName=${encodeURIComponent(item.productName)}&model=${encodeURIComponent(item.model)}&quantity=${item.quantity}` url: `/pages/productionManagement/productionOrder/source?id=${ item.id }&productName=${encodeURIComponent( item.productName )}&model=${encodeURIComponent(item.model)}&quantity=${item.quantity}`, }); }; // è·³è½¬é¢æè¯¦æ const goPickingDetail = (item) => { const goPickingDetail = item => { uni.navigateTo({ url: `/pages/productionManagement/productionOrder/pickingDetail?id=${item.id}&npsNo=${item.npsNo}` url: `/pages/productionManagement/productionOrder/pickingDetail?id=${item.id}&npsNo=${item.npsNo}`, }); }; @@ -235,7 +291,7 @@ </script> <style scoped lang="scss"> @import '@/styles/sales-common.scss'; @import "@/styles/sales-common.scss"; .production-order { min-height: 100vh; src/pages/works.vue
@@ -837,9 +837,9 @@ url: "/pages/productionManagement/productionDispatching/index", }); break; case "å·¥åºæäº§": case "å·¥èºè·¯çº¿": uni.navigateTo({ url: "/pages/productionManagement/processScheduling/index", url: "/pages/productionManagement/processRoute/index", }); break; case "ç产工å":