spring
9 天以前 84ab677962e1e8fb3634b5991f4251cffb1f6168
fix: 搬迁军泰生产功能
已重命名1个文件
已修改7个文件
已删除6个文件
8757 ■■■■■ 文件已修改
src/api/productionManagement/productionOrder.js 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/productionManagement/productionReporting.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/index.vue 690 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/operationScheduling/components/formDia.vue 323 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/operationScheduling/index.vue 292 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionCosting/index.vue 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionDispatching/components/DispatchModal.vue 168 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionDispatching/components/autoDispatchDia.vue 381 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionDispatching/index.vue 995 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionOrder/index.vue 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionReport/index.vue 84 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionReporting/components/formDia.vue 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yarn.lock 5464 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/productionManagement/productionOrder.js
@@ -16,64 +16,4 @@
    method: "post",
    data: query,
  });
}
// è‡ªåŠ¨æ´¾å·¥
export function productionDispatchList(query) {
  return request({
    url: "/salesLedger/scheduling/productionDispatchList",
    method: "post",
    data: query,
  });
}
// èŽ·å–ç‚’æœºæ­£åœ¨å·¥ä½œé‡æ•°æ®
export function schedulingList(query) {
  return request({
    url: "/salesLedger/scheduling/list",
    method: "get",
    params: query,
  });
}
// ä¿å­˜ç‚’机设置
export function addSpeculatTrading(data) {
  return request({
    url: "/salesLedger/scheduling/addSpeculatTrading",
    method: "post",
    data: data,
  });
}
// ä¿®æ”¹ç‚’机设置
export function updateSpeculatTrading(data) {
  return request({
    url: "/salesLedger/scheduling/updateSpeculatTrading",
    method: "post",
    data: data,
  });
}
// æŸ¥è¯¢æŸè€—率
export function getLossRate() {
  return request({
    url: "/salesLedger/scheduling/loss",
    method: "get",
  });
}
// æ–°å¢žæŸè€—率
export function addLossRate(data) {
  return request({
    url: "/salesLedger/scheduling/addLoss",
    method: "post",
    data: data,
  });
}
// ä¿®æ”¹æŸè€—率
export function updateLossRate(data) {
  return request({
    url: "/salesLedger/scheduling/updateLoss",
    method: "post",
    data: data,
  });
}
src/api/productionManagement/productionReporting.js
@@ -17,6 +17,14 @@
    params: query,
  });
}
// æ ¹æ®ID获取工单详情
export function getProductWorkOrderById(query) {
  return request({
    url: "/productWorkOrder/getProductWorkOrderById",
    method: "get",
    params: query,
  });
}
// ç”Ÿäº§æŠ¥å·¥
export function productionReport(query) {
  return request({
@@ -33,7 +41,7 @@
    data: query,
  });
}
// æ–°å¢žæŠ¥å·¥
// æ–°å¢žäº§å“ä¸»è¡¨
export function addProductMain(data) {
  return request({
    url: "/productionProductMain/addProductMain",
src/pages.json
@@ -501,7 +501,7 @@
      }
    },
    {
      "path": "pages/productionManagement/productionReporting/index",
      "path": "pages/productionManagement/productionReport/index",
      "style": {
        "navigationBarTitleText": "生产报工",
        "navigationStyle": "custom"
@@ -758,4 +758,4 @@
    "navigationBarTitleText": "RuoYi",
    "navigationBarBackgroundColor": "#FFFFFF"
  }
}
}
src/pages/index.vue
@@ -18,7 +18,7 @@
    <view class="hero-section">
      <view class="bg-img">
        <view class="hero-content">
          <text class="hero-title">海川开心食品</text>
          <text class="hero-title">军泰伟业</text>
        </view>
        <view class="hero-wave"></view>
      </view>
@@ -38,103 +38,108 @@
    <!--            </view>-->
    <!--        </view>-->
    <!-- è¥é”€ç®¡ç†æ¨¡å— -->
    <view class="common-module marketing-module">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">营销管理</text>
        </view>
      </view>
      <view class="module-content">
        <up-grid :border="false"
                 col="4">
          <up-grid-item v-for="(item, index) in marketingItems"
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container"
                  :style="{ background: item.bgColor }">
              <up-icon :name="item.icon"
                       :size="58"
                       color="#ffffff"></up-icon>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
        </up-grid>
      </view>
    </view>
    <!-- é‡‡è´­ç®¡ç†æ¨¡å— -->
    <view class="common-module purchase-module">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">采购管理</text>
        </view>
      </view>
      <view class="module-content">
        <up-grid :border="false"
                 col="4">
          <up-grid-item v-for="(item, index) in purchaseItems"
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container"
                  :style="{ background: item.bgColor }">
              <up-icon :name="item.icon"
                       :size="58"
                       color="#ffffff"></up-icon>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
        </up-grid>
      </view>
    </view>
    <!-- ååŒåŠžå…¬æ¨¡å— -->
    <view class="common-module collaboration-module">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">协同办公</text>
        </view>
      </view>
      <view class="module-content">
        <up-grid :border="false"
                 col="4">
          <up-grid-item v-for="(item, index) in collaborationItems"
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container"
                  :style="{ background: item.bgColor }">
              <up-icon :name="item.icon"
                       :size="58"
                       color="#ffffff"></up-icon>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
        </up-grid>
      </view>
    </view>
    <!-- å…¥åº“管理 -->
    <view class="common-module collaboration-module">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">仓储物流</text>
        </view>
      </view>
      <view class="module-content">
        <up-grid :border="false"
                 col="4">
          <up-grid-item v-for="(item, index) in inventoryManagement"
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container"
                  :style="{ background: item.bgColor }">
              <up-icon :name="item.icon"
                       :size="58"
                       color="#ffffff"></up-icon>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
        </up-grid>
      </view>
    </view>
    <!--    <view class="common-module marketing-module">-->
    <!--      <view class="module-header">-->
    <!--        <view class="module-title-container">-->
    <!--          <text class="module-title">营销管理</text>-->
    <!--        </view>-->
    <!--      </view>-->
    <!--      <view class="module-content">-->
    <!--        <up-grid :border="false"-->
    <!--                 col="4">-->
    <!--          <up-grid-item v-for="(item, index) in marketingItems"-->
    <!--                        :key="index"-->
    <!--                        @click="handleCommonItemClick(item)">-->
    <!--            <view class="icon-container"-->
    <!--                  :style="{ background: item.bgColor }">-->
    <!--              <up-icon :name="item.icon"-->
    <!--                       :size="58"-->
    <!--                       color="#ffffff"></up-icon>-->
    <!--            </view>-->
    <!--            <text class="item-label">{{item.label}}</text>-->
    <!--          </up-grid-item>-->
    <!--        </up-grid>-->
    <!--      </view>-->
    <!--    </view>-->
    <!--    &lt;!&ndash; é‡‡è´­ç®¡ç†æ¨¡å— &ndash;&gt;-->
    <!--    <view class="common-module purchase-module">-->
    <!--      <view class="module-header">-->
    <!--        <view class="module-title-container">-->
    <!--          <text class="module-title">采购管理</text>-->
    <!--        </view>-->
    <!--      </view>-->
    <!--      <view class="module-content">-->
    <!--        <up-grid :border="false"-->
    <!--                 col="4">-->
    <!--          <up-grid-item v-for="(item, index) in purchaseItems"-->
    <!--                        :key="index"-->
    <!--                        @click="handleCommonItemClick(item)">-->
    <!--            <view class="icon-container"-->
    <!--                  :style="{ background: item.bgColor }">-->
    <!--              <up-icon :name="item.icon"-->
    <!--                       :size="58"-->
    <!--                       color="#ffffff"></up-icon>-->
    <!--            </view>-->
    <!--            <text class="item-label">{{item.label}}</text>-->
    <!--          </up-grid-item>-->
    <!--        </up-grid>-->
    <!--      </view>-->
    <!--    </view>-->
    <!--    &lt;!&ndash; ååŒåŠžå…¬æ¨¡å— &ndash;&gt;-->
    <!--    <view class="common-module collaboration-module">-->
    <!--      <view class="module-header">-->
    <!--        <view class="module-title-container">-->
    <!--          <text class="module-title">协同办公</text>-->
    <!--        </view>-->
    <!--      </view>-->
    <!--      <view class="module-content">-->
    <!--        <up-grid :border="false"-->
    <!--                 col="4">-->
    <!--          <up-grid-item v-for="(item, index) in collaborationItems"-->
    <!--                        :key="index"-->
    <!--                        @click="handleCommonItemClick(item)">-->
    <!--            <view class="icon-container"-->
    <!--                  :style="{ background: item.bgColor }">-->
    <!--              <up-icon :name="item.icon"-->
    <!--                       :size="58"-->
    <!--                       color="#ffffff"></up-icon>-->
    <!--            </view>-->
    <!--            <text class="item-label">{{item.label}}</text>-->
    <!--          </up-grid-item>-->
    <!--        </up-grid>-->
    <!--      </view>-->
    <!--    </view>-->
    <!-- ç”Ÿäº§ç®¡æŽ§æ¨¡å— -->
    <view class="common-module production-module">
    <!--        <view class="common-module production-module">-->
    <!--            <view class="module-header">-->
    <!--                <view class="module-title-container">-->
    <!--                    <text class="module-title">生产管控</text>-->
    <!--                </view>-->
    <!--            </view>-->
    <!--            <view class="module-content">-->
    <!--                <up-grid-->
    <!--                    :border="false"-->
    <!--                    col="4"-->
    <!--                >-->
    <!--                    <up-grid-item-->
    <!--                        v-for="(item, index) in productionItems"-->
    <!--                        :key="index"-->
    <!--                        @click="handleCommonItemClick(item)"-->
    <!--                    >-->
    <!--                        <view class="icon-container" :style="{ background: item.bgColor }">-->
    <!--                            <up-icon-->
    <!--                                :name="item.icon"-->
    <!--                                :size="58"-->
    <!--                                color="#ffffff"-->
    <!--                            ></up-icon>-->
    <!--                        </view>-->
    <!--                        <text class="item-label">{{item.label}}</text>-->
    <!--                    </up-grid-item>-->
    <!--                </up-grid>-->
    <!--            </view>-->
    <!--        </view>-->
    <!-- ç”Ÿäº§ç®¡æŽ§æ¨¡å— -->
    <view class="common-module equipment-module">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">生产管控</text>
@@ -158,39 +163,38 @@
      </view>
    </view>
    <!-- è®¾å¤‡ç®¡ç†æ¨¡å— -->
    <view class="common-module equipment-module">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">设备管理</text>
        </view>
      </view>
      <view class="module-content">
        <up-grid :border="false"
                 col="4">
          <up-grid-item v-for="(item, index) in equipmentItems"
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container"
                  :style="{ background: item.bgColor }">
              <up-icon :name="item.icon"
                       :size="58"
                       color="#ffffff"></up-icon>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
        </up-grid>
      </view>
    </view>
    <!--    <view class="common-module equipment-module">-->
    <!--      <view class="module-header">-->
    <!--        <view class="module-title-container">-->
    <!--          <text class="module-title">设备管理</text>-->
    <!--        </view>-->
    <!--      </view>-->
    <!--      <view class="module-content">-->
    <!--        <up-grid :border="false"-->
    <!--                 col="4">-->
    <!--          <up-grid-item v-for="(item, index) in equipmentItems"-->
    <!--                        :key="index"-->
    <!--                        @click="handleCommonItemClick(item)">-->
    <!--            <view class="icon-container"-->
    <!--                  :style="{ background: item.bgColor }">-->
    <!--              <up-icon :name="item.icon"-->
    <!--                       :size="58"-->
    <!--                       color="#ffffff"></up-icon>-->
    <!--            </view>-->
    <!--            <text class="item-label">{{item.label}}</text>-->
    <!--          </up-grid-item>-->
    <!--        </up-grid>-->
    <!--      </view>-->
    <!--    </view>-->
  </view>
</template>
<script setup>
  import { ref, onMounted, nextTick, reactive } from "vue";
  import dayjs from "dayjs";
  import { userLoginFacotryList, noticesList } from "@/api/login";
  import { userLoginFacotryList } from "@/api/login";
  import { getProductWorkOrderById } from "@/api/productionManagement/productionReporting";
  import modal from "@/plugins/modal";
  import useUserStore from "@/store/modules/user";
  import { onShow } from "@dcloudio/uni-app";
  const userStore = useUserStore();
  const factoryId = ref("");
@@ -275,46 +279,6 @@
  // ååŒåŠžå…¬åŠŸèƒ½æ•°æ®
  const collaborationItems = reactive([
    {
      icon: "/static/images/icon/gongchuguanli@2x.png",
      label: "公出管理",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "请假管理",
    },
    {
      icon: "/static/images/icon/chuchaiguanli@2x.png",
      label: "出差管理",
    },
    {
      icon: "/static/images/icon/chuchaiguanli@2x.png",
      label: "报销管理",
    },
    {
      icon: "/static/images/icon/chuchaiguanli@2x.png",
      label: "采购管理",
    },
    {
      icon: "/static/images/icon/chuchaiguanli@2x.png",
      label: "报价管理",
    },
    {
      icon: "/static/images/icon/chuchaiguanli@2x.png",
      label: "出库管理",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "会议设置",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "会议列表",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "会议申请",
    },
    {
      icon: "/static/images/icon/xietongshenpi@2x.png",
      label: "协同审批",
    },
@@ -322,58 +286,43 @@
      icon: "/static/images/icon/kehubaifang@2x.png",
      label: "客户拜访",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "通知公告",
    },
  ]);
  // ååŒåŠžå…¬åŠŸèƒ½æ•°æ®inventoryManagement/receiptManagement
  const inventoryManagement = reactive([
    {
      icon: "/static/images/icon/rukuguanli@2x.png",
      label: "自定义入库",
    },
    {
      icon: "/static/images/icon/zidingyichuku.png",
      label: "自定义出库",
    },
  ]);
  // ç”Ÿäº§ç®¡æŽ§åŠŸèƒ½æ•°æ®
  const productionItems = reactive([
    {
      icon: "/static/images/icon/shengchandingdan@2x.png",
      label: "生产订单",
      bgColor: "#FF9800",
    },
    {
      icon: "/static/images/icon/shengchanpaigong@2x.png",
      label: "生产派工",
      bgColor: "#FF6B35",
    },
    {
      icon: "/static/images/icon/shengchanpaichan@2x.png",
      label: "工序排产",
      bgColor: "#E91E63",
    },
    // {
    //   icon: "/static/images/icon/shengchandingdan@2x.png",
    //   label: "生产订单",
    //   bgColor: "#FF9800",
    // },
    // {
    //   icon: "/static/images/icon/shengchanpaigong@2x.png",
    //   label: "生产派工",
    //   bgColor: "#FF6B35",
    // },
    // {
    //   icon: "/static/images/icon/shengchanpaichan@2x.png",
    //   label: "工序排产",
    //   bgColor: "#E91E63",
    // },
    {
      icon: "/static/images/icon/shengchanbaogong@2x.png",
      label: "生产报工",
      bgColor: "#673AB7",
    },
    {
      icon: "/static/images/icon/shengchanhesuan@2x.png",
      label: "生产核算",
      bgColor: "#3F51B5",
    },
    // {
    //   icon: "/static/images/icon/shengchanhesuan@2x.png",
    //   label: "生产核算",
    //   bgColor: "#3F51B5",
    // },
  ]);
  // è®¾å¤‡ç®¡ç†åŠŸèƒ½æ•°æ®
  const equipmentItems = reactive([
    {
      icon: "/static/images/icon/shebeitaizhang@2x.png",
      label: "设备台账",
    },
    // {
    //     icon: '/static/images/icon/shebeitaizhang@2x.png',
    //     label: '设备台账',
    // },
    {
      icon: "/static/images/icon/shbeibaoxiu@2x.png",
      label: "设备报修",
@@ -386,26 +335,26 @@
      icon: "/static/images/icon/xunjianshangchuan@2x.png",
      label: "巡检上传",
    },
    // {
    //     icon: '/static/images/icon/guzhangfenxi@2x.png',
    //     label: '分析追溯',
    //     bgColor: '#ff9800'
    // },
    // {
    //     icon: '/static/images/icon/zhinengpaidan@2x.png',
    //     label: '智能派单',
    //     bgColor: '#ff6b35'
    // },
    // {
    //     icon: '/static/images/icon/zuoyezhidao@2x.png',
    //     label: '作业指导',
    //     bgColor: '#4caf50'
    // },
    // {
    //     icon: '/static/images/icon/jieguoyanzheng@2x.png',
    //     label: '结果验证',
    //     bgColor: '#9c27b0'
    // }
    {
      icon: "/static/images/icon/guzhangfenxi@2x.png",
      label: "分析追溯",
      bgColor: "#ff9800",
    },
    {
      icon: "/static/images/icon/zhinengpaidan@2x.png",
      label: "智能派单",
      bgColor: "#ff6b35",
    },
    {
      icon: "/static/images/icon/zuoyezhidao@2x.png",
      label: "作业指导",
      bgColor: "#4caf50",
    },
    {
      icon: "/static/images/icon/jieguoyanzheng@2x.png",
      label: "结果验证",
      bgColor: "#9c27b0",
    },
  ]);
  // å¤„理常用功能点击
@@ -472,56 +421,6 @@
          url: "/pages/procurementManagement/paymentLedger/index",
        });
        break;
      case "公出管理":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index1",
        });
        break;
      case "请假管理":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index2",
        });
        break;
      case "出差管理":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index3",
        });
        break;
      case "报销管理":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index4",
        });
        break;
      case "采购管理":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index5",
        });
        break;
      case "报价管理":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index6",
        });
        break;
      case "出库管理":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index7",
        });
        break;
      case "会议设置":
        uni.navigateTo({
          url: "/pages/managementMeetings/meetingSettings/index",
        });
        break;
      case "会议列表":
        uni.navigateTo({
          url: "/pages/managementMeetings/meetingList/index",
        });
        break;
      case "会议申请":
        uni.navigateTo({
          url: "/pages/managementMeetings/meetApplication/index",
        });
        break;
      case "协同审批":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index",
@@ -530,21 +429,6 @@
      case "客户拜访":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/clientVisit/index",
        });
        break;
      case "通知公告":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/noticeManagement/index",
        });
        break;
      case "自定义入库":
        uni.navigateTo({
          url: "/pages/inventoryManagement/receiptManagement/index",
        });
        break;
      case "自定义出库":
        uni.navigateTo({
          url: "/pages/inventoryManagement/issueManagement/index",
        });
        break;
      case "生产订单":
@@ -559,18 +443,15 @@
        break;
      case "工序排产":
        uni.navigateTo({
          url: "/pages/productionManagement/operationScheduling/index",
          url: "/pages/productionManagement/processScheduling/index",
        });
        break;
      case "生产报工":
        getcode();
        // uni.navigateTo({
        //     url: '/pages/productionManagement/productionReporting/index'
        // });
        break;
      case "生产核算":
        uni.navigateTo({
          url: "/pages/productionManagement/productionCosting/index",
          url: "/pages/productionManagement/productionAccounting/index",
        });
        break;
      case "设备台账":
@@ -620,53 +501,12 @@
        });
    }
  };
  const getcode = () => {
    uni.scanCode({
      success: res => {
        // è§£æžäºŒç»´ç å†…容
        const scanResult = res.result;
        let orderRow = "";
        // å°è¯•从扫码结果中提取orderRow参数
        try {
          // å¤„理混合格式: http://...?orderRow={...}
          const orderRowStart = scanResult.indexOf("orderRow={");
          // æå–从orderRow={开始的JSON内容
          const jsonPart = scanResult.substring(orderRowStart + 9); // 9是"orderRow=".length
          // å°è¯•直接使用这个JSON部分
          orderRow = jsonPart;
        } catch (e) {
          orderRow = "";
        }
        try {
          JSON.parse(orderRow);
        } catch (error) {
          modal.msgError("订单解析失败");
          return;
        }
        // æ‰«ç æˆåŠŸåŽè·³è½¬åˆ°ç”Ÿäº§æŠ¥å·¥é¡µé¢ï¼Œå¹¶ä¼ é€’orderRow参数
        uni.navigateTo({
          url: `/pages/productionManagement/productionReporting/index?orderRow=${orderRow}`,
        });
      },
      fail: err => {
        uni.showToast({
          title: "扫码失败",
          icon: "none",
        });
        // uni.navigateTo({
        //   url: `/pages/productionManagement/productionReporting/index`,
        // });
      },
    });
  };
  // åˆ›å»ºå¯¹å­ç»„件的引用
  const uToastRef = ref(null);
  function getUserLoginFacotryList() {
    userLoginFacotryList({
      userName: userStore.nickName,
    })
    userLoginFacotryList({ userName: userStore.nickName })
      .then(res => {
        // æ£€æŸ¥res.data是否为数组
        factoryList.value[0] = [];
@@ -686,6 +526,89 @@
        factoryList.value = [];
      });
  }
  const getcode = () => {
    uni.scanCode({
      success: async res => {
        // è§£æžäºŒç»´ç å†…容
        const scanResult = res.result;
        let orderRow = "";
        // åˆ¤æ–­æ‰«æç»“果是否为纯数字(id)
        const isNumericId = /^\d+$/.test(scanResult.trim());
        if (isNumericId) {
          // å¦‚果是纯数字,根据 id èŽ·å–å·¥å•æ•°æ®
          const workOrderId = scanResult.trim();
          modal.loading("正在获取工单信息...");
          try {
            const workRes = await getProductWorkOrderById({ id: workOrderId });
            modal.closeLoading();
            console.log("工单查询结果:", workRes);
            if (workRes.code === 200 && workRes.data) {
              // æ–°æŽ¥å£è¿”回的是单个对象,不是数组
              const workData = workRes.data;
              console.log("工单数据:", workData);
              orderRow = JSON.stringify({
                id: workData.id || workOrderId,
                planQuantity: workData.planQuantity-workData.completeQuantity,
                productProcessRouteItemId: workData.productProcessRouteItemId || workData.产品工艺路线项ID || "",
              });
              console.log("构造的orderRow:", orderRow);
            } else {
              modal.msgError("未找到对应的工单信息");
              return;
            }
          } catch (error) {
            modal.closeLoading();
            console.error("获取工单信息失败:", error);
            modal.msgError("获取工单信息失败: " + (error.message || "未知错误"));
            return;
          }
        } else {
          // å¦‚果不是纯数字,尝试从扫码结果中提取orderRow参数
          try {
            // å¤„理混合格式: http://...?orderRow={...}
            const orderRowStart = scanResult.indexOf("orderRow={");
            if (orderRowStart !== -1) {
              // æå–从orderRow={开始的JSON内容
              const jsonPart = scanResult.substring(orderRowStart + 9); // 9是"orderRow=".length
              orderRow = jsonPart;
            } else {
              // å¦‚果直接是JSON字符串,尝试解析
              orderRow = scanResult;
            }
          } catch (e) {
            console.error(e, "解析失败====????=====");
            orderRow = "";
          }
          // éªŒè¯æ˜¯å¦ä¸ºæœ‰æ•ˆçš„JSON
          try {
            JSON.parse(orderRow);
          } catch (error) {
            modal.msgError("订单解析失败,请检查二维码格式");
            return;
          }
        }
        console.log(orderRow, "orderRow======@@@@@@@@");
        // æ‰«ç æˆåŠŸåŽè·³è½¬åˆ°ç”Ÿäº§æŠ¥å·¥é¡µé¢ï¼Œå¹¶ä¼ é€’orderRow参数
        uni.navigateTo({
          url: `/pages/productionManagement/productionReport/index?orderRow=${orderRow}`,
        });
      },
      fail: err => {
        uni.showToast({
          title: "扫码失败",
          icon: "none",
        });
      },
    });
  };
  const changeFactory = async arr => {
    show.value = false;
    const factoryId = factoryListTem.value[arr.indexs[0]].deptId;
@@ -707,7 +630,6 @@
        modal.closeLoading();
      });
  };
  function loginSuccess(result) {
    uni.reLaunch({
      url: "/pages/index",
@@ -720,68 +642,6 @@
      uToastRef.value.success(`点击了第${name + 1}个`); // æ³¨æ„ï¼šè¿™é‡ŒåŠ 1是因为通常我们是从第1个开始计数的
    }
  };
  const isShowNoticesList = ref(true);
  // èŽ·å–å…¬å‘Šæ•°é‡
  const getNoticesList = () => {
    if (!isShowNoticesList.value) {
      return;
    }
    const current_date = dayjs().format("YYYY-MM-DD");
    noticesList({
      current: -1,
      size: -1,
      status: 1,
      current_date,
    })
      .then(resp => {
        console.log("noticesList", resp);
        if (
          resp.code != 200 ||
          !resp.data ||
          !resp.data.records ||
          !resp.data.records.length
        ) {
          return;
        }
        const res = uni.getAppAuthorizeSetting();
        if (res.notificationAuthorized == "denied") {
          uni.showModal({
            title: "提示",
            content: "请在设置中开启通知权限",
            success: res => {
              if (res.confirm) {
                uni.openAppAuthorizeSetting({
                  success: res => {},
                });
              } else {
                isShowNoticesList.value = false;
              }
            },
          });
          return;
        }
        resp.data.records.map(item => {
          createPushMessage(item.title);
        });
      })
      .catch(error => {
        // modal.msgError("获取公告数量:", error);
      });
  };
  const createPushMessage = text => {
    uni.createPushMessage({
      title: "公告通知",
      content: text || "",
      success: resp => {
        console.log("success", resp);
        isShowNoticesList.value = false;
      },
      fail: resp => {
        console.log("fail", resp);
      },
    });
  };
  onMounted(() => {
    // è®¾ç½®ç”¨æˆ·ä¿¡æ¯
@@ -790,10 +650,8 @@
    // å¯åŠ¨é€šçŸ¥çŠ¶æ€å®šæ—¶å™¨
    startStatusTimer();
  });
  onShow(() => {
    getNoticesList();
  });
</script>
<style scoped lang="scss">
  .content {
@@ -943,12 +801,10 @@
    letter-spacing: 0.03125rem;
    text-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.5);
  }
  .hero-subtitle {
    font-size: 0.8125rem;
    margin-top: 0.375rem;
  }
  .hero-wave {
    height: 2.75rem;
  }
@@ -1029,7 +885,6 @@
    0% {
      transform: translateX(-100%) translateY(-100%) rotate(45deg);
    }
    100% {
      transform: translateX(100%) translateY(100%) rotate(45deg);
    }
@@ -1040,7 +895,6 @@
      opacity: 0;
      transform: translateY(-1.25rem);
    }
    to {
      opacity: 1;
      transform: translateY(0);
@@ -1052,7 +906,6 @@
      opacity: 0;
      transform: translateY(1.25rem);
    }
    to {
      opacity: 1;
      transform: translateY(0);
@@ -1064,7 +917,6 @@
      opacity: 0;
      transform: translateY(0.5rem) scale(0.96);
    }
    100% {
      opacity: 1;
      transform: translateY(0) scale(1);
@@ -1124,9 +976,10 @@
  }
  .notice-unit {
    color: #666666;
    font-size: 0.875rem;
    margin-left: 0.125rem;
    font-weight: 600;
    font-size: 1rem;
    color: #1976d2;
    margin-left: 0.25rem;
  }
  /* åŠŸèƒ½æ¨¡å—æ ·å¼ */
@@ -1300,20 +1153,16 @@
    .content {
      background: linear-gradient(135deg, #121317 0%, #161a20 100%);
    }
    .content::before {
      background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="dots" width="20" height="20" patternUnits="userSpaceOnUse"><circle cx="10" cy="10" r="1" fill="rgba(255, 255, 255, 0.05)"/></pattern></defs><rect width="100" height="100" fill="url(%23dots)"/></svg>');
    }
    .common-module {
      background: linear-gradient(135deg, #1e1f24 0%, #23252b 100%);
      box-shadow: 0 0.375rem 1.5rem rgba(0, 0, 0, 0.35);
    }
    .module-title {
      color: #e9edf3;
    }
    .module-subtitle,
    .item-label,
    .notice-text,
@@ -1321,18 +1170,15 @@
    .notice-label {
      color: #c7cbd3;
    }
    .notice {
      background: linear-gradient(135deg, #1b2330 0%, #1a2432 100%);
      border-color: rgba(255, 255, 255, 0.06);
      box-shadow: 0 0.375rem 1.25rem rgba(0, 0, 0, 0.4);
    }
    .notice-status,
    .notice-number {
      color: #8ab4ff;
    }
    .bg-img {
      background: linear-gradient(135deg, #1f4fb9 0%, #0e3a8a 100%);
    }
@@ -1342,7 +1188,6 @@
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(360deg);
    }
@@ -1353,7 +1198,6 @@
      opacity: 0;
      transform: translateY(-1.25rem);
    }
    to {
      opacity: 1;
      transform: translateY(0);
@@ -1365,7 +1209,6 @@
      opacity: 0;
      transform: translateY(1.25rem);
    }
    to {
      opacity: 1;
      transform: translateY(0);
@@ -1377,7 +1220,6 @@
      opacity: 0;
      transform: translateY(0.5rem) scale(0.96);
    }
    100% {
      opacity: 1;
      transform: translateY(0) scale(1);
@@ -1387,31 +1229,25 @@
  .notice-left {
    margin-right: 1rem;
  }
  .notice-status {
    font-size: 1rem;
  }
  .notice-separator {
    width: 0.0625rem;
    height: 1.5rem;
    margin-right: 1rem;
  }
  .notice-label {
    font-size: 0.875rem;
    margin-right: 0.75rem;
  }
  .notice-text {
    font-size: 0.875rem;
  }
  .notice-number {
    font-size: 1rem;
    margin-left: 0.25rem;
  }
  .notice-unit {
    font-size: 0.875rem;
    margin-left: 0.125rem;
@@ -1527,7 +1363,6 @@
    margin-top: 0.25rem;
    margin-bottom: 0.625rem;
  }
  .grid-text {
    font-size: 0.875rem;
  }
@@ -1536,7 +1371,6 @@
    .common-module {
      box-shadow: 0 0.375rem 1.5rem rgba(0, 0, 0, 0.35);
    }
    .notice {
      box-shadow: 0 0.375rem 1.25rem rgba(0, 0, 0, 0.4);
    }
src/pages/productionManagement/operationScheduling/components/formDia.vue
ÎļþÒÑɾ³ý
src/pages/productionManagement/operationScheduling/index.vue
ÎļþÒÑɾ³ý
src/pages/productionManagement/productionCosting/index.vue
ÎļþÒÑɾ³ý
src/pages/productionManagement/productionDispatching/components/DispatchModal.vue
@@ -1,7 +1,7 @@
<template>
    <uni-popup
        ref="popupRef"
        type="bottom"
    <up-popup
        v-model:show="show"
        mode="bottom"
        :round="20"
        :safeAreaInsetBottom="true"
        @close="handleClose"
@@ -26,33 +26,19 @@
                >
                    <!-- é¡¹ç›®åŸºæœ¬ä¿¡æ¯ -->
                    <view class="form-section">
                        <text class="section-title">产品信息</text>
                    <!--     <up-form-item label="项目名称" prop="projectName">
                        <text class="section-title">项目信息</text>
                        <up-form-item label="项目名称" prop="projectName">
                            <up-input 
                                v-model="form.projectName" 
                                disabled 
                                placeholder="项目名称"
                            />
                        </up-form-item> -->
                        </up-form-item>
                        <up-form-item label="产品大类" prop="productCategory">
                            <up-input 
                                v-model="form.productCategory" 
                                disabled 
                                placeholder="产品大类"
                            />
                        </up-form-item>
                        <up-form-item label="规格型号" prop="specificationModel">
                            <up-input
                                v-model="form.specificationModel"
                                disabled
                                placeholder="规格型号"
                            />
                        </up-form-item>
                        <up-form-item label="绑定机器" prop="speculativeTradingName">
                            <up-input
                                v-model="form.speculativeTradingName"
                                disabled
                                placeholder="绑定机器"
                            />
                        </up-form-item>
                    </view>
@@ -90,14 +76,22 @@
                    <view class="form-section">
                        <text class="section-title">派工信息</text>
                        <up-form-item label="派工人" prop="schedulingUserId" required>
                            <uni-data-select v-model="form.schedulingUserId" :localdata="userColumns" :clear="false"></uni-data-select>
                            <up-input
                                v-model="selectedUserName"
                                placeholder="请选择派工人"
                                readonly
                                @click="showUserPicker = true"
                                suffixIcon="arrow-down"
                            />
                        </up-form-item>
                        <up-form-item label="派工日期" prop="schedulingDate" required>
                            <uni-datetime-picker type="date" :clear-icon="false" v-model="form.schedulingDate">
                                <view class="datetime-picker-value">
                                    {{form.schedulingDate}}
                                </view>
                            </uni-datetime-picker>
                            <up-input
                                v-model="form.schedulingDate"
                                placeholder="请选择派工日期"
                                readonly
                                @click="showDatePicker = true"
                                suffixIcon="calendar"
                            />
                        </up-form-item>
                    </view>
                </up-form>
@@ -121,7 +115,23 @@
                />
            </view>
        </view>
    </uni-popup>
        <!-- äººå‘˜é€‰æ‹©å™¨ -->
        <up-picker
            v-model="showUserPicker"
            :columns="userColumns"
            @confirm="handleUserSelect"
            @cancel="showUserPicker = false"
        />
        <!-- æ—¥æœŸé€‰æ‹©å™¨ -->
        <up-datetime-picker
            v-model="showDatePicker"
            mode="date"
            @confirm="handleDateSelect"
            @cancel="showDatePicker = false"
        />
    </up-popup>
</template>
<script setup>
@@ -136,16 +146,26 @@
const emit = defineEmits(['confirm']);
// å¼¹çª—显示状态
const popupRef = ref();
const show = ref(false);
const submitting = ref(false);
// é€‰æ‹©å™¨æ˜¾ç¤ºçŠ¶æ€
const showUserPicker = ref(false);
const showDatePicker = ref(false);
// ç”¨æˆ·åˆ—表
const userList = ref([]);
const userColumns = computed(() => {
    return userList.value.map(user => ({
        text: user.nickName,
const userColumns = computed(() => [
    userList.value.map(user => ({
        label: user.nickName,
        value: user.userId
    }))
]);
// é€‰ä¸­çš„用户名称(用于显示)
const selectedUserName = computed(() => {
    const user = userList.value.find(u => u.userId === form.schedulingUserId);
    return user ? user.nickName : '';
});
// è¡¨å•数据
@@ -162,15 +182,15 @@
// è¡¨å•验证规则
const rules = reactive({
    // schedulingNum: [
    //     { required: true, message: "请输入排产数量", trigger: "blur" }
    // ],
    // schedulingUserId: [
    //     { required: true, message: "请选择派工人", trigger: "change" }
    // ],
    // schedulingDate: [
    //     { required: true, message: "请选择派工日期", trigger: "change" }
    // ]
    schedulingNum: [
        { required: true, message: "请输入排产数量", trigger: "blur" }
    ],
    schedulingUserId: [
        { required: true, message: "请选择派工人", trigger: "change" }
    ],
    schedulingDate: [
        { required: true, message: "请选择派工日期", trigger: "change" }
    ]
});
// è¡¨å•引用
@@ -190,9 +210,9 @@
            schedulingUserId: userStore.id,
            schedulingDate: dayjs().format("YYYY-MM-DD")
        });
        popupRef.value.open()
        show.value = true;
    } catch (error) {
        console.log(error)
        uni.showToast({
            title: '加载用户列表失败',
            icon: 'error'
@@ -211,30 +231,29 @@
    }
};
// å¤„理用户选择
const handleUserSelect = (params) => {
    if (params.value && params.value.length > 0) {
        form.schedulingUserId = params.value[0];
    }
    showUserPicker.value = false;
};
// å¤„理日期选择
const handleDateSelect = (params) => {
    if (params.value) {
        form.schedulingDate = dayjs(params.value).format("YYYY-MM-DD");
    }
    showDatePicker.value = false;
};
// ç¡®è®¤æ´¾å·¥
const handleConfirm = async () => {
    if(!form.schedulingNum){
        uni.showToast({
            title: '请输入排产数量',
            icon:'none'
        })
        return
    }
    if(!form.schedulingUserId){
        uni.showToast({
            title: '请选择派工人',
            icon:'none'
        })
        return
    }
    if(!form.schedulingDate){
        uni.showToast({
            title: '请选择派工日期',
            icon:'none'
        })
        return
    }
    try {
        // è¡¨å•验证
        const valid = await formRef.value?.validate();
        if (!valid) return;
        if (form.schedulingNum <= 0) {
            uni.showToast({
                title: '排产数量必须大于0',
@@ -273,7 +292,10 @@
// å…³é—­å¼¹çª—
const handleClose = () => {
    popupRef.value.close()
    show.value = false;
    showUserPicker.value = false;
    showDatePicker.value = false;
    // é‡ç½®è¡¨å•
    Object.assign(form, {
        projectName: "",
@@ -331,24 +353,6 @@
    flex: 1;
    padding: 0 20px;
    overflow-y: auto;
    .datetime-picker-value{
        font-size: 14px;
        border: 1px solid #e5e5e5;
        box-sizing: border-box;
        border-radius: 4px;
        padding: 0 5px;
        padding-left: 10px;
        position: relative;
        display: flex;
        -webkit-user-select: none;
        -moz-user-select: none;
        user-select: none;
        flex-direction: row;
        align-items: center;
        width: 100%;
        flex: 1;
        height: 35px;
    }
}
.form-section {
src/pages/productionManagement/productionDispatching/components/autoDispatchDia.vue
ÎļþÒÑɾ³ý
src/pages/productionManagement/productionDispatching/index.vue
@@ -2,232 +2,109 @@
    <view class="production-dispatching">
        <!-- ä½¿ç”¨é€šç”¨é¡µé¢å¤´éƒ¨ç»„ä»¶ -->
        <PageHeader title="生产派工" @back="goBack" />
        <!-- ç‚’机状态展示 -->
        <view class="machines-section">
            <view class="section-title">炒机状态</view>
            <view class="machines-grid">
                <view v-for="machine in machines" :key="machine.id" class="machine-card">
                    <view class="machine-title">炒机{{ machine.id }}</view>
                    <view class="machine-metrics">
                        <view class="metric-item">
                            <text class="metric-label">总量(kg)</text>
                            <up-input
                                v-model="machineTotal[machine.key]"
                                type="number"
                                placeholder="请输入总量"
                                border="surround"
                                size="mini"
                                class="metric-input"
                                @change="updateMachineVacant(machine.key)"
                            />
                        </view>
                        <view class="metric-item">
                            <text class="metric-label">正在生产(kg)</text>
                            <text class="metric-value">{{ machineInProduction[machine.key] }}</text>
                        </view>
                        <view class="metric-item">
                            <text class="metric-label">空余量(kg)</text>
                            <text class="metric-value">{{ machineVacant[machine.key] }}</text>
                        </view>
                    </view>
                </view>
            </view>
            <!-- æŸè€—率设置 -->
        <view class="loss-rate-section">
            <view class="section-title">损耗率设置</view>
            <view class="loss-rate-content">
                <view class="loss-rate-item">
                    <up-button
                        class="loss-rate-btn"
                        type="primary"
                        plain
                        size="small"
                        @click="showLossRateSheet = true"
                    >{{ lossRate ? `损耗率: ${lossRate}%` : '请选择损耗率' }}</up-button>
                    <up-action-sheet
                    :show="showLossRateSheet"
                    :actions="lossRateOptions"
                    @select="onLossRateSelect"
                    title="选择损耗率"
                    @close="showLossRateSheet = false"
                />
                </view>
            </view>
        </view>
            <view class="save-section">
                <up-button type="primary" @click="saveMachineTotals" size="normal" class="save-btn">保存炒机设置</up-button>
            </view>
        </view>
        
        <!-- æœç´¢åŒºåŸŸ -->
        <view class="search-section">
            <view class="search-form">
                <view class="search-item">
                    <text class="search-label">客户名称</text>
            <view class="search-bar">
                <view class="search-input">
                    <up-input
                        class="search-text"
                        placeholder="请输入客户名称搜索"
                        v-model="searchForm.customerName"
                        placeholder="请输入客户名称"
                        @change="handleQuery"
                        clearable
                        border="surround"
                        class="search-input"
                    />
                </view>
                <view class="search-item">
                    <text class="search-label">项目名称</text>
                    <up-input
                        v-model="searchForm.projectName"
                        placeholder="请输入项目名称"
                        @change="handleQuery"
                        clearable
                        border="surround"
                        class="search-input"
                    />
                </view>
                <view class="search-buttons">
                    <up-button type="primary" @click="handleQuery" size="small" class="search-btn">搜索</up-button>
                    <up-button @click="handleReset" size="small" class="reset-btn">重置</up-button>
                <view class="filter-button" @click="handleQuery">
                    <up-icon name="search" size="24" color="#999"></up-icon>
                </view>
            </view>
        </view>
        
        <!-- æ‰¹é‡æ“ä½œåŒºåŸŸ -->
        <view class="batch-actions-section" v-if="showBatchActions">
            <view class="batch-info">
                <text class="batch-text">已选择 {{ selectedItems.length }} ä¸ªé¡¹ç›®</text>
            </view>
            <view class="batch-buttons">
                <up-button type="primary" size="small" @click="handleAutoDispatch" class="batch-btn">自动派单</up-button>
                <up-button type="default" size="small" @click="clearSelection" class="batch-btn">取消选择</up-button>
            </view>
        </view>
        <!-- å…¨é€‰æ“ä½œåŒºåŸŸ -->
        <view class="select-all-section" v-if="tableData.length > 0">
            <view class="select-all-content">
                <up-checkbox
                v-model="isAllSelected"
                @change="toggleAllSelection"
                label="全选"
                class="select-all-checkbox"
                :disabled="tableData.length === 0 || tableData.filter(item => item.pendingQuantity > 0 && item.speculativeTradingName).length === 0"
            />
            </view>
        </view>
        <!-- ç”Ÿäº§æ´¾å·¥åˆ—表 -->
        <view class="ledger-list" v-if="tableData.length > 0">
            <view v-for="(item, index) in tableData" :key="item.id || index" class="list-item">
            <view v-for="(item, index) in tableData" :key="item.id || index">
                <view class="ledger-item">
                    <!-- é€‰æ‹©å¤é€‰æ¡† -->
                    <view class="item-checkbox">
                        <up-checkbox
                    :model-value="selectedItems.some(selected => selected.id === item.id)"
                    @change="(checked) => toggleItemSelection(item, checked)"
                    :disabled="item.pendingQuantity <= 0 || !item.speculativeTradingName"
                    shape="circle"
                />
                    <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.salesContractNo }}</text>
                        </view>
                    </view>
                    <up-divider></up-divider>
                    <view class="item-details">
                        <view class="detail-row">
                            <text class="detail-label">录入日期</text>
                            <text class="detail-value">{{ item.entryDate }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">客户合同号</text>
                            <text class="detail-value">{{ item.customerContractNo }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">客户名称</text>
                            <text class="detail-value">{{ item.customerName }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">项目名称</text>
                            <text class="detail-value">{{ item.projectName }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">产品大类</text>
                            <text class="detail-value">{{ item.productCategory }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">规格型号</text>
                            <text class="detail-value">{{ item.specificationModel }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">总数量</text>
                            <text class="detail-value">{{ item.quantity }} {{ item.unit }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">排产数量</text>
                            <text class="detail-value highlight">{{ item.schedulingNum }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">待排数量</text>
                            <text class="detail-value" :class="{ 'danger': item.pendingQuantity <= 0 }">{{ item.pendingQuantity }}</text>
                        </view>
                    </view>
                    
                    <view class="item-content">
                        <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.salesContractNo }}</text>
                            </view>
                            <text class="entry-date">{{ item.entryDate }}</text>
                        </view>
                        <view class="item-details">
                            <!-- <view class="detail-row">
                                <text class="detail-label">客户合同号</text>
                                <text class="detail-value">{{ item.customerContractNo }}</text>
                            </view> -->
                            <view class="detail-row">
                                <text class="detail-label">客户名称</text>
                                <text class="detail-value">{{ item.customerName }}</text>
                            </view>
                            <!-- <view class="detail-row">
                                <text class="detail-label">项目名称</text>
                                <text class="detail-value">{{ item.projectName }}</text>
                            </view> -->
                            <view class="detail-row">
                                <text class="detail-label">产品大类</text>
                                <text class="detail-value">{{ item.productCategory }}</text>
                            </view>
                            <view class="detail-row">
                                <text class="detail-label">规格型号</text>
                                <text class="detail-value">{{ item.specificationModel }}</text>
                            </view>
                            <view class="detail-row">
                                <text class="detail-label">绑定机器</text>
                                <text class="detail-value">{{ item.speculativeTradingName }}</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.entryDate }}</text>
                            </view>
                            <view class="detail-row">
                                <text class="detail-label">数量</text>
                                <text class="detail-value">{{ item.quantity }}</text>
                            </view>
                            <view class="detail-row">
                                <text class="detail-label">排产数量</text>
                                <text class="detail-value highlight">{{ item.schedulingNum }}</text>
                            </view>
                            <view class="detail-row">
                                <text class="detail-label">待排数量</text>
                                <text class="detail-value" :class="{ 'danger': item.pendingQuantity <= 0 }">{{ item.pendingQuantity }}</text>
                            </view>
                            <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
                            <view class="action-buttons">
                                <up-button
                        type="primary"
                        size="small"
                        @click="handleDispatch(item)"
                        class="action-btn"
                        :disabled="item.pendingQuantity <= 0 || !item.speculativeTradingName"
                    >
                        {{ item.pendingQuantity <= 0 ? '无需派工' : !item.speculativeTradingName ? '未绑定机器' : '生产派工' }}
                    </up-button>
                            </view>
                        </view>
                    <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
                    <view class="action-buttons">
                        <up-button
                            type="primary"
                            size="small"
                            @click="handleDispatch(item)"
                            class="action-btn"
                            :disabled="item.pendingQuantity <= 0"
                        >
                            ç”Ÿäº§æ´¾å·¥
                        </up-button>
                    </view>
                </view>
            </view>
        </view>
        <view v-else class="no-data">
            <up-empty mode="data" icon="http://cdn.uviewui.com/uview/empty/data.png">
                <text class="no-data-text">暂无生产派工数据</text>
            </up-empty>
            <text>暂无生产派工数据</text>
        </view>
        
        <!-- æ´¾å·¥å¼¹çª— -->
        <DispatchModal ref="dispatchModalRef" @confirm="handleDispatchConfirm" />
        <!-- è‡ªåŠ¨æ´¾å•å¼¹çª— -->
        <AutoDispatchDia ref="autoDispatchDia" />
    </view>
</template>
<script setup>
import { ref, reactive, toRefs, getCurrentInstance, nextTick } from "vue";
import { ref, reactive, toRefs, getCurrentInstance } from "vue";
import { onShow } from '@dcloudio/uni-app';
import dayjs from "dayjs";
import {schedulingListPage, schedulingList, addSpeculatTrading, updateSpeculatTrading, getLossRate, addLossRate, updateLossRate} from "@/api/productionManagement/productionOrder.js";
import {schedulingListPage} from "@/api/productionManagement/productionOrder.js";
import PageHeader from "@/components/PageHeader.vue";
import DispatchModal from "./components/DispatchModal.vue";
import AutoDispatchDia from "./components/autoDispatchDia.vue";
const { proxy } = getCurrentInstance();
// åŠ è½½çŠ¶æ€
@@ -236,77 +113,23 @@
// åˆ—表数据
const tableData = ref([]);
// é€‰æ‹©ç›¸å…³æ•°æ®
const selectedItems = ref([]);
const isAllSelected = ref(false);
const showBatchActions = ref(false);
// æœç´¢è¡¨å•数据
const data = reactive({
    searchForm: {
        customerName: "",
        projectName: "",
    },
});
const { searchForm } = toRefs(data);
// åˆ†é¡µé…ç½®
const page = reactive({
    current: 1,
    size: 100,
    total: 0,
    current: -1,
    size: -1,
});
// ç‚’机状态数据
const machineTotal = reactive({
    m1: 0,
    m2: 0,
    m3: 0,
    m4: 0,
})
const machineInProduction = reactive({
    m1: 0,
    m2: 0,
    m3: 0,
    m4: 0,
})
const machineVacant = reactive({
    m1: 0,
    m2: 0,
    m3: 0,
    m4: 0,
})
// ç‚’机配置数组
const machines = [
    { id: 1, key: 'm1' },
    { id: 2, key: 'm2' },
    { id: 3, key: 'm3' },
    { id: 4, key: 'm4' }
]
// æ˜¯å¦æœ‰æŸ¥è¯¢æ•°æ®ï¼ˆç”¨äºŽåˆ¤æ–­æ˜¯æ–°å¢žè¿˜æ˜¯ä¿®æ”¹ï¼‰
const hasQueryData = ref(false);
// æŸè€—率相关数据
const lossRate = ref(""); // å½“前选择的损耗率
const showLossRateSheet = ref(false); // æŽ§åˆ¶æŸè€—率选择面板显示
const lossRateOptions = ref([
    { name: "6%", value: "6" },
    { name: "7%", value: "7" },
    { name: "8%", value: "8" },
    { name: "9%", value: "9" },
    { name: "10%", value: "10" }
]);
const lossRateData = ref(null); // æŸè€—率查询返回的数据
// æ´¾å·¥å¼¹çª—引用
const dispatchModalRef = ref();
// è‡ªåŠ¨æ´¾å•å¼¹çª—å¼•ç”¨
const autoDispatchDia = ref();
// é€šç”¨æç¤ºå‡½æ•°
const showLoadingToast = (message) => {
@@ -325,73 +148,9 @@
    uni.navigateBack();
};
// é‡ç½®æœç´¢
const handleReset = () => {
    searchForm.value.customerName = "";
    searchForm.value.projectName = "";
    handleQuery();
};
// æŸ¥è¯¢åˆ—表
const handleQuery = () => {
    page.current = 1;
    getList();
};
// èŽ·å–ç‚’æœºç”Ÿäº§æ•°æ®
const getMachineProductionData = () => {
    schedulingList().then((res) => {
        if (res.data && Array.isArray(res.data)) {
            // é‡ç½®æ•°æ®
            machineInProduction.m1 = 0;
            machineInProduction.m2 = 0;
            machineInProduction.m3 = 0;
            machineInProduction.m4 = 0;
            // å¤„理炒机数据
            res.data.forEach(item => {
                const machineId = Number(item.id);
                if (machineId >= 1 && machineId <= 4) {
                    const machineKey = `m${machineId}`;
                    if (item.workLoad !== null && item.workLoad !== undefined) {
                        machineTotal[machineKey] = Number(item.workLoad) || 0;
                    }
                    if (item.currentWorkLoad !== null && item.currentWorkLoad !== undefined) {
                        machineInProduction[machineKey] = Number(item.currentWorkLoad) || 0;
                    }
                    // è®¡ç®—空余量
                    machineVacant[machineKey] = machineTotal[machineKey] - machineInProduction[machineKey];
                }
            });
        }
    }).catch(err => {
        console.error('获取炒机数据失败:', err);
    });
};
// æŸè€—率选择事件
const onLossRateSelect = (action) => {
    lossRate.value = action.value;
    showLossRateSheet.value = false;
    console.log('选择了损耗率:', action.name, '值:', action.value);
};
// èŽ·å–æŸè€—çŽ‡æ•°æ®
const getLossRateData = () => {
    getLossRate().then((res) => {
        if (res.data) {
            lossRateData.value = res.data;
            // è®¾ç½®å½“前选择的损耗率
            if (res.data.rate !== null && res.data.rate !== undefined) {
                lossRate.value = res.data.rate.toString();
            }
        }
    }).catch(err => {
        console.error('获取损耗率失败:', err);
    });
};
// èŽ·å–åˆ—è¡¨æ•°æ®
@@ -399,25 +158,18 @@
    loading.value = true;
    showLoadingToast('加载中...');
    
    // æž„造请求参数
    const params = { ...searchForm.value, ...page };
    
    schedulingListPage(params).then((res) => {
        loading.value = false;
        closeToast();
        
        // å¤„理每条数据,增加pendingQuantity字段
        tableData.value = (res.data.records || []).map(item => ({
                ...item,
                pendingQuantity: (Number(item.quantity) || 0) - (Number(item.schedulingNum) || 0)
            })).filter(item => item.pendingQuantity > 0);
        page.total = res.data.total || 0;
        // èŽ·å–ç‚’æœºæ•°æ®
        getMachineProductionData();
        // èŽ·å–æŸè€—çŽ‡æ•°æ®
        getLossRateData();
            ...item,
            pendingQuantity: (Number(item.quantity) || 0) - (Number(item.schedulingNum) || 0)
        }));
    }).catch(() => {
        loading.value = false;
        closeToast();
@@ -438,14 +190,6 @@
        return;
    }
    
    if (!item.speculativeTradingName) {
        uni.showToast({
            title: '该项目未绑定机器,无法派工',
            icon: 'none'
        });
        return;
    }
    dispatchModalRef.value?.open(item);
};
@@ -454,595 +198,38 @@
    getList(); // åˆ·æ–°åˆ—表
};
// æ›´æ–°ç‚’机空余量
const updateMachineVacant = (machineKey) => {
    machineVacant[machineKey] = (Number(machineTotal[machineKey]) || 0) - (Number(machineInProduction[machineKey]) || 0);
};
// èŽ·å–ç‚’æœºæŸ¥è¯¢æ•°æ®
const getMachineQueryData = (machineId) => {
    // è¿™é‡Œéœ€è¦æ ¹æ®å®žé™…情况从查询数据中获取对应的炒机数据
    // æš‚时返回一个模拟数据
    return {
        id: machineId,
        name: `炒机${machineId}`,
        workLoad: machineTotal[`m${machineId}`] || 0,
        currentWorkLoad: machineInProduction[`m${machineId}`] || 0
    };
};
// ä¿å­˜æŸè€—率设置
const saveLossRate = () => {
    if (!lossRate.value) {
        console.log('未选择损耗率,跳过保存');
        return Promise.resolve();
    }
    const lossRateDataToSave = {
        rate: parseFloat(lossRate.value) || 0
    };
    // å¦‚果有查询到的损耗率数据,说明是修改操作,需要传递id
    if (lossRateData.value && lossRateData.value.id) {
        lossRateDataToSave.id = lossRateData.value.id;
    }
    console.log('保存损耗率数据:', lossRateDataToSave);
    // æ ¹æ®æ˜¯å¦æœ‰æŸè€—率数据决定调用新增接口还是修改接口
    const saveLossApi = lossRateData.value && lossRateData.value.id ? updateLossRate : addLossRate;
    const successMessage = lossRateData.value && lossRateData.value.id ? '损耗率修改成功' : '损耗率新增成功';
    return saveLossApi(lossRateDataToSave).then(res => {
        console.log('损耗率保存成功:', res);
        uni.showToast({
            title: successMessage,
            icon: 'success'
        });
        // æ›´æ–°æŸè€—率数据
        if (res.data) {
            lossRateData.value = res.data;
        }
        return res;
    }).catch(err => {
        console.error('损耗率保存失败:', err);
        uni.showToast({
            title: '损耗率保存失败',
            icon: 'none'
        });
        throw err;
    });
};
// ä¿å­˜ç‚’机总量设置
const saveMachineTotals = () => {
    // æž„造保存数据数组,使用machines数组循环构建
    const saveData = machines.map(machine => {
        const machineData = {
            name: `炒机${machine.id}`, // ç‚’机名称
            workLoad: machineTotal[machine.key] || 0,  // æ€»é‡
            vacant: machineVacant[machine.key] || 0   // ç©ºä½™é‡
        };
        // å¦‚果是修改操作,需要传递id字段
        if (hasQueryData.value) {
            // è¿™é‡Œéœ€è¦ä»ŽæŸ¥è¯¢æ•°æ®ä¸­èŽ·å–å¯¹åº”çš„id
            // å‡è®¾æŸ¥è¯¢æ•°æ®ä¸­æ¯ä¸ªç‚’机数据都有id字段
            const queryData = getMachineQueryData(machine.id);
            if (queryData && queryData.id) {
                machineData.id = queryData.id;
            }
        }
        return machineData;
    });
    console.log('保存炒机设置数据:', saveData);
    // æ ¹æ®æ˜¯å¦æœ‰æŸ¥è¯¢æ•°æ®å†³å®šè°ƒç”¨æ–°å¢žæŽ¥å£è¿˜æ˜¯ä¿®æ”¹æŽ¥å£
    const saveApi = hasQueryData.value ? updateSpeculatTrading : addSpeculatTrading;
    const successMessage = hasQueryData.value ? '炒机设置修改成功' : '炒机设置新增成功';
    console.log(`调用接口: ${hasQueryData.value ? '修改' : '新增'}`);
    // å…ˆä¿å­˜æŸè€—率,再保存炒机设置
    saveLossRate().then(() => {
        // è°ƒç”¨åŽç«¯API保存炒机设置
        return saveApi(saveData);
    }).then(res => {
        uni.showToast({
            title: successMessage,
            icon: 'success'
        });
        console.log('保存成功:', res);
        // ä¿å­˜æˆåŠŸåŽï¼Œè®¾ç½®hasQueryData为true,下次保存将调用修改接口
        if (!hasQueryData.value) {
            hasQueryData.value = true;
        }
    }).catch(err => {
        uni.showToast({
            title: '保存失败',
            icon: 'none'
        });
        console.error('保存失败:', err);
    });
};
// åˆ‡æ¢å•个项目选择状态
const toggleItemSelection = (item, checked) => {
    // ä»…允许选择已绑定机器且待派数量>0的项目
    if (!item.speculativeTradingName || item.pendingQuantity <= 0) return;
    console.log('切换选择状态:', item.id, checked);
    // ä½¿ç”¨æ›´ä¸¥æ ¼çš„æ¯”较逻辑,确保ID唯一性
    const index = selectedItems.value.findIndex(selected => {
        // æ·±åº¦æ¯”较对象,确保是同一个项目
        return JSON.stringify(selected) === JSON.stringify(item);
    });
    if (checked) {
        // å¦‚果选中且不在选中列表中,则添加
        if (index === -1) {
            selectedItems.value.push({...item}); // åˆ›å»ºæ–°å¯¹è±¡ï¼Œé¿å…å¼•用问题
            console.log('添加项目后选中数量:', selectedItems.value.length);
        }
    } else {
        // å¦‚果取消选中且在选中列表中,则移除
        if (index > -1) {
            selectedItems.value.splice(index, 1);
            console.log('移除项目后选中数量:', selectedItems.value.length);
        }
    }
    console.log('当前选中项目列表:', selectedItems.value.map(s => s.id));
    updateAllSelectedStatus();
    updateBatchActionsVisibility();
};
// åˆ‡æ¢å…¨é€‰çŠ¶æ€
const toggleAllSelection = () => {
    if (isAllSelected.value) {
        selectedItems.value = [];
    } else {
        selectedItems.value = tableData.value.filter(item => item.pendingQuantity > 0 && item.speculativeTradingName).map(item => ({ ...item }));
    }
    isAllSelected.value = !isAllSelected.value;
    updateBatchActionsVisibility();
};
// æ›´æ–°å…¨é€‰çŠ¶æ€
const updateAllSelectedStatus = () => {
    const selectableItems = tableData.value.filter(item => item.pendingQuantity > 0 && item.speculativeTradingName);
    if (selectableItems.length > 0 && selectedItems.value.length === selectableItems.length &&
        selectableItems.every(item => selectedItems.value.some(selected => selected.id === item.id))) {
        isAllSelected.value = true;
    } else {
        isAllSelected.value = false;
    }
};
// æ›´æ–°æ‰¹é‡æ“ä½œæ˜¾ç¤ºçŠ¶æ€
const updateBatchActionsVisibility = () => {
    showBatchActions.value = selectedItems.value.length > 0;
};
// æ¸…空选择
const clearSelection = () => {
    selectedItems.value = [];
    isAllSelected.value = false;
    showBatchActions.value = false;
};
// èŽ·å–é€‰ä¸­çš„é¡¹ç›®
const getSelectedItems = () => {
    return selectedItems.value;
};
// å¤„理自动派单
const handleAutoDispatch = () => {
    if (selectedItems.value.length === 0) {
        uni.showToast({
            title: '请选择要派工的项目',
            icon: 'none'
        });
        return;
    }
    // æ£€æŸ¥æ˜¯å¦æ‰€æœ‰é€‰ä¸­é¡¹ç›®éƒ½æœ‰ç»‘定机器
    const unboundItems = selectedItems.value.filter(item => !item.speculativeTradingName);
    if (unboundItems.length > 0) {
        uni.showToast({
            title: '所选项目中有未绑定机器的项目,无法自动派单',
            icon: 'none'
        });
        return;
    }
    // ç¡®ä¿ä¼ é€’的是完整的选中项目数组
    autoDispatchDia.value?.openDialog([...selectedItems.value]);
};
// é¡µé¢æ˜¾ç¤ºæ—¶åŠ è½½æ•°æ®
onShow(() => {
    // åŠ è½½åˆ—è¡¨æ•°æ®
    getList();
    clearSelection();
});
</script>
<style scoped lang="scss">
@import '@/styles/sales-common.scss';
// ç”Ÿäº§æ´¾å·¥é¡µé¢æ ·å¼
.production-dispatching {
    min-height: 100vh;
    background: #f8f9fa;
    padding: 20rpx;
    position: relative;
}
// æŸè€—率设置区域
.loss-rate-section {
    background: #ffffff;
    border: 1rpx solid #e4e7ed;
    border-radius: 12rpx;
    padding: 32rpx;
    margin-top: 24rpx;
    margin-bottom: 32rpx;
    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
}
.loss-rate-section .section-title {
    font-size: 32rpx;
    font-weight: 600;
    color: #303133;
    margin-bottom: 20rpx;
}
.loss-rate-section .loss-rate-content {
    display: flex;
    flex-direction: column;
    gap: 24rpx;
}
.loss-rate-section .loss-rate-content .loss-rate-item {
    display: flex;
    align-items: center;
    gap: 24rpx;
}
.loss-rate-section .loss-rate-content .loss-rate-label {
    font-size: 30rpx;
    font-weight: 500;
    color: #303133;
    min-width: 140rpx;
    white-space: nowrap;
}
.loss-rate-section .loss-rate-content .loss-rate-btn {
    min-width: 260rpx;
    font-size: 28rpx;
    height: 64rpx;
    line-height: 64rpx;
    border-radius: 8rpx;
    font-weight: 500;
}
// ç‚’机状态区域
.machines-section {
    margin-bottom: 30rpx;
}
.machines-section .section-title {
    font-size: 32rpx;
    font-weight: 600;
    color: #303133;
    margin-bottom: 20rpx;
}
.machines-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20rpx;
}
.machine-card {
    background: #ffffff;
    border-radius: 16rpx;
    padding: 24rpx;
    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
    border: 1rpx solid #e9ecef;
}
.machine-title {
    font-size: 28rpx;
    font-weight: 600;
    color: #2c3e50;
    text-align: center;
    margin-bottom: 20rpx;
    padding-bottom: 16rpx;
    border-bottom: 2rpx solid #3498db;
}
.machine-metrics {
    display: flex;
    flex-direction: column;
    gap: 16rpx;
}
.metric-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8rpx 0;
}
.metric-label {
    font-size: 24rpx;
    color: #6c757d;
}
.metric-value {
    font-size: 26rpx;
    font-weight: 600;
    color: #2c3e50;
}
// è¾“入框样式
.metric-input {
    width: 120rpx;
    text-align: right;
}
// ä¿å­˜åŒºåŸŸ
.save-section {
    display: flex;
    justify-content: center;
    margin-top: 30rpx;
    padding-top: 20rpx;
    border-top: 1rpx solid #e9ecef;
}
.save-btn {
    min-width: 200rpx;
}
// æœç´¢åŒºåŸŸ
.search-section {
    background: #ffffff;
    border-radius: 16rpx;
    padding: 24rpx;
    margin-bottom: 30rpx;
    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
}
.search-form {
    display: flex;
    flex-direction: column;
    gap: 20rpx;
}
.search-item {
    display: flex;
    align-items: center;
    gap: 20rpx;
}
.search-label {
    font-size: 26rpx;
    color: #606266;
    min-width: 140rpx;
}
.search-input {
    flex: 1;
}
.search-buttons {
    display: flex;
    gap: 20rpx;
    justify-content: flex-end;
    margin-top: 10rpx;
}
.search-btn, .reset-btn {
    min-width: 120rpx;
}
// åˆ—表样式
.ledger-list {
    display: flex;
    flex-direction: column;
    gap: 24rpx;
}
.list-item {
    background: #ffffff;
    border-radius: 16rpx;
    overflow: hidden;
    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
}
// åˆ—表项样式
.ledger-item {
    padding: 0;
}
.item-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 24rpx 24rpx 0 24rpx;
}
.item-left {
    display: flex;
    align-items: center;
    gap: 16rpx;
}
.document-icon {
    width: 48rpx;
    height: 48rpx;
    background: #409eff;
    border-radius: 8rpx;
    display: flex;
    align-items: center;
    justify-content: center;
}
.item-id {
    font-size: 28rpx;
    font-weight: 600;
    color: #303133;
}
.entry-date {
    font-size: 24rpx;
    color: #909399;
}
.item-details {
    padding: 24rpx;
}
.detail-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12rpx 0;
    border-bottom: 1rpx solid #f5f5f5;
}
.detail-row:last-child {
    border-bottom: none;
}
.detail-label {
    font-size: 26rpx;
    color: #606266;
}
.detail-value {
    font-size: 26rpx;
    color: #303133;
    font-weight: 500;
}
.detail-value.highlight {
    color: #ff6b35;
    font-weight: 600;
}
.detail-value.danger {
    color: #ee0a24;
    font-weight: 600;
}
.action-buttons {
    padding: 0 24rpx 24rpx 24rpx;
    display: flex;
    justify-content: flex-end;
}
.action-btn {
    min-width: 180rpx;
}
// æ‰¹é‡æ“ä½œåŒºåŸŸæ ·å¼
.batch-actions-section {
    background: #e8f4ff;
    border: 1rpx solid #409eff;
    border-radius: 12rpx;
    padding: 20rpx 24rpx;
    margin-bottom: 24rpx;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.batch-actions-section .batch-text {
    font-size: 28rpx;
    font-weight: 600;
    color: #409eff;
}
.batch-actions-section .batch-buttons {
    display: flex;
    gap: 16rpx;
}
.batch-actions-section .batch-btn {
    min-width: 140rpx;
}
// å…¨é€‰æ“ä½œåŒºåŸŸæ ·å¼
.select-all-section {
    background: #ffffff;
    border-radius: 12rpx;
    padding: 20rpx 24rpx;
    margin-bottom: 16rpx;
    border: 1rpx solid #e4e7ed;
}
.select-all-section .select-all-content {
    display: flex;
    align-items: center;
}
.select-all-section .select-all-checkbox {
    font-size: 28rpx;
    font-weight: 500;
}
// åˆ—表项选择框样式
.ledger-item {
    display: flex;
    align-items: flex-start;
    padding: 0;
}
.item-checkbox {
    padding: 24rpx 16rpx 0 24rpx;
    display: flex;
    align-items: center;
}
.item-content {
    flex: 1;
}
// ç©ºçŠ¶æ€
.no-data {
    padding: 100rpx 0;
    text-align: center;
}
.no-data-text {
    font-size: 28rpx;
    color: #909399;
    margin-top: 20rpx;
}
// ç‚¹å‡»ç¼–辑区域样式
.metric-value-container {
    cursor: pointer;
    min-width: 120rpx;
    text-align: right;
    padding: 4rpx 8rpx;
    border-radius: 4rpx;
    transition: all 0.2s ease;
}
.metric-value-container:hover {
    background-color: #f0f8ff;
    border: 1rpx solid #409eff;
    .detail-value.highlight {
        color: #ff6b35;
        font-weight: 600;
    }
    .detail-value.danger {
        color: #ee0a24;
        font-weight: 600;
    }
}
// é€‚配 uView ç»„件样式
:deep(.up-input) {
    background: transparent;
}
:deep(.up-input__content) {
    background: #f8f9fa;
}
</style>
</style>
src/pages/productionManagement/productionOrder/index.vue
@@ -40,29 +40,17 @@
                            <text class="detail-label">录入日期</text>
                            <text class="detail-value">{{ item.entryDate }}</text>
                        </view>
                    <!--     <view class="detail-row">
                        <view class="detail-row">
                            <text class="detail-label">客户合同号</text>
                            <text class="detail-value">{{ item.customerContractNo }}</text>
                        </view> -->
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">客户名称</text>
                            <text class="detail-value">{{ item.customerName }}</text>
                        </view>
                    <!--     <view class="detail-row">
                        <view class="detail-row">
                            <text class="detail-label">项目名称</text>
                            <text class="detail-value">{{ item.projectName }}</text>
                        </view> -->
                        <view class="detail-row">
                            <text class="detail-label">付款状态</text>
                            <view v-if="item.status=='已完成'" class="detail-value">
                                <uni-tag :inverted="true" text="已完成" type="success" size="mini" />
                            </view>
                            <view v-else-if="item.status=='未完成'" class="detail-value">
                                <uni-tag :inverted="true" text="未完成" type="error" size="mini" />
                            </view>
                            <view v-else class="detail-value">
                                <uni-tag :inverted="true" :text="item.status" type="primary" size="mini" />
                            </view>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">产品大类</text>
@@ -157,6 +145,7 @@
    schedulingListPage(params).then((res) => {
        loading.value = false;
        closeToast();
        tableData.value = res.data.records || [];
    }).catch(() => {
        loading.value = false;
src/pages/productionManagement/productionReport/index.vue
ÎļþÃû´Ó src/pages/productionManagement/productionReporting/index.vue ÐÞ¸Ä
@@ -35,7 +35,9 @@
                     required>
          <u-input v-model="form.userName"
                   placeholder="请选择生产人"
                   readonly />
                   readonly
                   @click="openProducerPicker"
                   suffix-icon="arrow-down" />
        </u-form-item>
      </view>
      <!-- ä½¿ç”¨FooterButtons组件 -->
@@ -55,10 +57,9 @@
</template>
<script setup>
  import { ref, onMounted } from "vue";
  import { ref, nextTick } from "vue";
  import { onLoad } from "@dcloudio/uni-app";
  import FooterButtons from "@/components/FooterButtons.vue";
  import modal from "@/plugins/modal";
  const showToast = message => {
    uni.showToast({
@@ -68,35 +69,52 @@
  };
  import { addProductMain } from "@/api/productionManagement/productionReporting";
  import { getInfo } from "@/api/login";
  import { userListNoPageByTenantId } from "@/api/system/user";
  // è¡¨å•引用
  const formRef = ref();
  // è¡¨å•数据
  let form = ref({
    planQuantity: 0,
    quantity: 0,
    planQuantity: "",
    quantity: "",
    userName: "",
    workOrderId: "",
    reportWork: "",
    productProcessRouteItemId: "",
    userId: "",
    productMainId: null,
    schedulingUserId: "",
  });
  let schedulingUserName = ref("");
  // æ—¥æœŸé€‰æ‹©å™¨çŠ¶æ€
  const showEnterDatePicker = ref(false);
  const enterDateValue = ref(Date.now());
  // ç”Ÿäº§äººé€‰æ‹©å™¨çŠ¶æ€
  const showProducerPicker = ref(false);
  const producerList = ref([]);
  // æ‰“开生产人选择器
  const openProducerPicker = async () => {
    if (producerList.value.length === 0) {
      // å¦‚果列表为空,先加载用户列表
      try {
        const res = await userListNoPageByTenantId();
        const users = res.data || [];
        // è½¬æ¢ä¸º action-sheet éœ€è¦çš„æ ¼å¼
        producerList.value = users.map(user => ({
          name: user.nickName || user.userName,
          value: user.userId,
        }));
      } catch (error) {
        console.error("加载用户列表失败:", error);
        showToast("加载用户列表失败");
        return;
      }
    }
    showProducerPicker.value = true;
  };
  // ç”Ÿäº§äººé€‰æ‹©ç¡®è®¤
  const onProducerConfirm = e => {
    form.value.schedulingUserId = e.value;
    schedulingUserName.value = e.name;
    form.value.userName = e.name;
    form.value.userId = e.value; // åŒæ—¶æ›´æ–° userId
    showProducerPicker.value = false;
  };
@@ -116,14 +134,28 @@
      showToast("请输入本次生产数量");
      return;
    }
    if (form.value.quantity > form.value.planQuantity) {
    if (!form.value.schedulingUserId) {
      submitting.value = false;
      showToast("请选择生产人");
      return;
    }
    // è½¬æ¢ä¸ºæ•°å­—进行比较
    const quantity = Number(form.value.quantity);
    const planQuantity = Number(form.value.planQuantity);
    if (quantity > planQuantity) {
      submitting.value = false;
      showToast("本次生产数量不能大于待生产数量");
      return;
    }
    console.log(form.value, "form.value");
    // å‡†å¤‡æäº¤æ•°æ®ï¼Œç¡®ä¿æ•°é‡å­—段为数字类型
    const submitData = {
      ...form.value,
      quantity: Number(form.value.quantity),
      planQuantity: Number(form.value.planQuantity) || 0,
    };
    console.log(submitData, "submitData");
    addProductMain(form.value).then(res => {
    addProductMain(submitData).then(res => {
      if (res.code === 200) {
        showToast("报工成功");
        submitting.value = false;
@@ -142,19 +174,25 @@
    console.log(options, "options");
    try {
      const orderRow = JSON.parse(options.orderRow);
      console.log("构造的orderRow:", orderRow);
      console.log(orderRow, "orderRow======########");
      form.value.planQuantity = orderRow.planQuantity;
      form.value.quantity = orderRow.quantity;
      form.value.productProcessRouteItemId = orderRow.productProcessRouteItemId;
      form.value.workOrderId = orderRow.id;
      form.value.reportWork = orderRow.reportWork;
      form.value.productMainId = orderRow.productMainId;
      // ç¡®ä¿ planQuantity è½¬æ¢ä¸ºå­—符串,以便在 u-input ä¸­æ­£ç¡®æ˜¾ç¤º
      form.value.planQuantity = orderRow.planQuantity != null ? String(orderRow.planQuantity) : "";
      form.value.productProcessRouteItemId = orderRow.productProcessRouteItemId || "";
      form.value.workOrderId = orderRow.id || "";
      getInfo().then(res => {
        // é»˜è®¤ä½¿ç”¨å½“前登录用户,但允许用户修改
        form.value.userId = res.user.userId;
        form.value.userName = res.user.userName;
        form.value.schedulingUserId = res.user.userId;
      });
      // ä½¿ç”¨ nextTick ç¡®ä¿ DOM æ›´æ–°
      nextTick(() => {
        console.log("form.value after assignment:", form.value);
      });
    } catch (error) {
      modal.msgError("订单解析失败");
      console.error("订单解析失败:", error);
      showToast("订单解析失败");
      goBack();
      return;
    }
src/pages/productionManagement/productionReporting/components/formDia.vue
ÎļþÒÑɾ³ý
yarn.lock
ÎļþÒÑɾ³ý