zhangwencui
2026-04-30 927f9a4e4d26a2024c797ca0f29125556a514095
生产排产
已添加1个文件
已修改3个文件
287 ■■■■■ 文件已修改
src/api/productionManagement/workOrder.js 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages.json 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionScheduling/index.vue 241 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/works.vue 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/productionManagement/workOrder.js
@@ -2,7 +2,7 @@
export function productWorkOrderPage(query) {
  return request({
    url: "/productWorkOrder/page",
    url: "/productionOperationTask/page",
    method: "get",
    params: query,
  });
@@ -10,7 +10,7 @@
export function updateProductWorkOrder(data) {
  return request({
    url: "/productWorkOrder/updateProductWorkOrder",
    url: "/productionOperationTask/updateProductWorkOrder",
    method: "post",
    data: data,
  });
@@ -24,10 +24,18 @@
  });
}
export function assignProductWorkOrder(data) {
  return request({
    url: "/productionOperationTask/assign",
    method: "post",
    data: data,
  });
}
// ä¸‹è½½å·¥å•流转卡(返回文件流)
export function downProductWorkOrder(id) {
  return request({
    url: "/productWorkOrder/down",
    url: "/productionOperationTask/down",
    method: "post",
    data: { id },
    responseType: "blob",
src/pages.json
@@ -840,7 +840,14 @@
    {
      "path": "pages/productionManagement/mainProductionPlan/detail",
      "style": {
        "navigationBarTitleText": "计划详情",
        "navigationBarTitleText": "生产计划详情",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/productionManagement/productionScheduling/index",
      "style": {
        "navigationBarTitleText": "生产排产",
        "navigationStyle": "custom"
      }
    },
src/pages/productionManagement/productionScheduling/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,241 @@
<template>
  <view class="production-scheduling">
    <!-- é€šç”¨é¡µé¢å¤´éƒ¨ -->
    <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.workOrderNo"
                    @confirm="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="ledger-list"
                 v-if="tableData.length > 0"
                 @scrolltolower="loadMore">
      <view v-for="(item, index) in tableData"
            :key="item.id || index"
            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>
            </view>
            <text class="item-id">{{ item.workOrderNo }}</text>
          </view>
          <view class="item-right">
            <up-tag :text="item.workOrderType"
                    size="mini"
                    type="primary"
                    plain></up-tag>
          </view>
        </view>
        <up-divider></up-divider>
        <view class="item-details">
          <view class="detail-row">
            <text class="detail-label">生产订单号</text>
            <text class="detail-value">{{ item.npsNo || '-' }}</text>
          </view>
          <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="detail-row">
            <text class="detail-label">工序名称</text>
            <text class="detail-value">{{ item.operationName || '-' }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">需求数量</text>
            <text class="detail-value">{{ item.planQuantity || 0 }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">完成数量</text>
            <text class="detail-value">{{ item.completeQuantity || 0 }}</text>
          </view>
          <view class="progress-section">
            <text class="detail-label">完成进度</text>
            <view class="progress-bar">
              <up-line-progress :percentage="toProgressPercentage(item.completionStatus)"
                                :activeColor="progressColor(item.completionStatus)"
                                :showText="true"></up-line-progress>
            </view>
          </view>
          <view class="detail-row">
            <text class="detail-label">计划开始</text>
            <text class="detail-value">{{ item.planStartTime || '-' }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">计划结束</text>
            <text class="detail-value">{{ item.planEndTime || '-' }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">实际开始</text>
            <text class="detail-value">{{ item.actualStartTime || '-' }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">实际结束</text>
            <text class="detail-value">{{ item.actualEndTime || '-' }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">指定报工人</text>
            <view class="detail-value tags-box">
              <template v-if="item.userNames">
                <up-tag v-for="(name, idx) in item.userNames.split(',')"
                        :key="idx"
                        :text="name"
                        size="mini"
                        type="info"
                        plain
                        class="user-tag"></up-tag>
              </template>
              <text v-else>-</text>
            </view>
          </view>
        </view>
      </view>
      <up-loadmore :status="loadStatus" />
    </scroll-view>
    <view v-else-if="!loading"
          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 { productWorkOrderPage } from "@/api/productionManagement/workOrder.js";
  import PageHeader from "@/components/PageHeader.vue";
  const { proxy } = getCurrentInstance();
  const loading = ref(false);
  const tableData = ref([]);
  const loadStatus = ref("loadmore");
  const page = reactive({
    current: 1,
    size: 10,
    total: 0,
  });
  const data = reactive({
    searchForm: {
      workOrderNo: "",
    },
  });
  const { searchForm } = toRefs(data);
  const goBack = () => {
    uni.navigateBack();
  };
  const handleQuery = () => {
    page.current = 1;
    tableData.value = [];
    getList();
  };
  const getList = () => {
    if (loading.value) return;
    loading.value = true;
    const params = {
      ...searchForm.value,
      ...page,
    };
    productWorkOrderPage(params)
      .then(res => {
        loading.value = false;
        const records = res.data.records || [];
        tableData.value =
          page.current === 1 ? records : [...tableData.value, ...records];
        page.total = res.data.total;
        if (tableData.value.length >= page.total) {
          loadStatus.value = "nomore";
        } else {
          loadStatus.value = "loadmore";
        }
      })
      .catch(() => {
        loading.value = false;
        uni.showToast({ title: "加载失败", icon: "error" });
      });
  };
  const loadMore = () => {
    if (loadStatus.value === "nomore" || loading.value) return;
    page.current++;
    getList();
  };
  const toProgressPercentage = val => {
    const n = Number(val);
    if (!Number.isFinite(n)) return 0;
    if (n <= 0) return 0;
    if (n >= 100) return 100;
    return Math.round(n);
  };
  const progressColor = percentage => {
    const p = toProgressPercentage(percentage);
    if (p < 30) return "#f56c6c";
    if (p < 50) return "#e6a23c";
    if (p < 80) return "#409eff";
    return "#67c23a";
  };
  onShow(() => {
    handleQuery();
  });
</script>
<style scoped lang="scss">
  @import "@/styles/sales-common.scss";
  .production-scheduling {
    padding-bottom: 20rpx;
  }
  .progress-bar {
    margin-top: 20rpx;
    margin-bottom: 20rpx;
  }
  .tags-box {
    display: flex;
    flex-wrap: wrap;
    gap: 8rpx;
    justify-content: flex-end;
  }
  .user-tag {
    margin-bottom: 4rpx;
  }
</style>
src/pages/works.vue
@@ -570,17 +570,17 @@
  // ç”Ÿäº§ç®¡æŽ§åŠŸèƒ½æ•°æ®
  const productionItems = reactive([
    {
      icon: "/static/images/icon/shengchandingdan@2x.svg",
      icon: "/static/images/icon/shengchanbaogong.svg",
      label: "生产订单",
    },
    // {
    //   icon: "/static/images/icon/shengchanpaigong@2x.svg",
    //   label: "生产派工",
    // },
    // {
    //   icon: "/static/images/icon/shengchanpaichan@2x.svg",
    //   label: "工序排产",
    // },
    {
      icon: "/static/images/icon/shengchanpaichan@2x.svg",
      label: "生产排产",
    },
    {
      icon: "/static/images/icon/shengchanbaogong.svg",
      label: "主生产计划",
@@ -589,10 +589,10 @@
      icon: "/static/images/icon/shengchanbaogong.svg",
      label: "生产报工",
    },
    {
      icon: "/static/images/icon/shengchanbaogong.svg",
      label: "生产工单",
    },
    // {
    //   icon: "/static/images/icon/shengchanbaogong.svg",
    //   label: "生产工单",
    // },
    // {
    //   icon: "/static/images/icon/shengchanhesuan@2x.svg",
    //   label: "生产核算",
@@ -852,6 +852,11 @@
          url: "/pages/productionManagement/mainProductionPlan/index",
        });
        break;
      case "生产排产":
        uni.navigateTo({
          url: "/pages/productionManagement/productionScheduling/index",
        });
        break;
      case "生产报工":
        getcode();
        break;