zhangwencui
2026-01-14 67ff1c675d2f97619349ed234a56fa0ea3ab33b8
src/pages/productionManagement/productionReporting/index.vue
@@ -1,214 +1,168 @@
<template>
  <view class="prod-reporting">
    <PageHeader title="生产报工" />
    <view class="search_form">
      <u-form>
        <view class="form-row">
          <u-form-item label="客户名称" label-width="80">
            <up-input v-model="searchForm.customerName" placeholder="请输入" clearable @change="handleQuery" />
          </u-form-item>
        </view>
        <view class="form-row">
          <u-form-item label="状态" label-width="80" style="flex:1">
           <uni-data-select v-model="searchForm.status" :localdata="statusList"></uni-data-select>
            <!-- <up-input v-model="statusDisplay" placeholder="请选择状态" readonly @click="showStatusPicker = true" /> -->
          </u-form-item>
        </view>
        <view class="form-actions">
          <u-button type="primary" size="small" @click="handleQuery">搜索</u-button>
        </view>
      </u-form>
    </view>
    <view class="list_container">
      <u-loading-icon v-if="tableLoading" text="加载中..." />
      <view v-else>
        <view v-if="!tableData || tableData.length === 0" class="empty">暂无数据</view>
        <view v-else class="card_list">
          <view v-for="item in tableData" :key="item.id" class="card_item">
            <view class="card_header">
              <u-tag :type="statusType(item.status)" size="mini">{{ statusText(item.status) }}</u-tag>
              <text class="card_title">{{ item.projectName }}</text>
            </view>
            <view class="card_body">
              <view class="row"><text class="label">排产日期</text><text class="value">{{ item.schedulingDate }}</text></view>
              <view class="row"><text class="label">排产人</text><text class="value">{{ item.schedulingUserName }}</text></view>
              <view class="row"><text class="label">合同号</text><text class="value">{{ item.salesContractNo }}</text></view>
              <!-- <view class="row"><text class="label">客户合同号</text><text class="value">{{ item.customerContractNo }}</text></view> -->
              <view class="row"><text class="label">客户名称</text><text class="value">{{ item.customerName }}</text></view>
              <view class="row"><text class="label">产品大类</text><text class="value">{{ item.productCategory }}</text></view>
              <view class="row"><text class="label">规格型号</text><text class="value">{{ item.specificationModel }}</text></view>
              <view class="row inline">
                <view class="col"><text class="label">单位</text><text class="value">{{ item.unit }}</text></view>
                <view class="col"><text class="label">排产数量</text><text class="value">{{ item.schedulingNum }}</text></view>
                <view class="col"><text class="label">生产数量</text><text class="value">{{ item.finishedNum }}</text></view>
                <view class="col"><text class="label">待报工数量</text><text class="value">{{ item.pendingFinishNum }}</text></view>
              </view>
            </view>
            <view class="card_actions">
              <u-button type="primary" size="small" @click="openForm('add', item)" :disabled="item.pendingFinishNum == 0">生产报工</u-button>
            </view>
          </view>
        </view>
  <view class="invoice-add">
    <!-- 使用通用页面头部组件 -->
    <PageHeader title="生产报工"
                @back="goBack" />
    <!-- 表单内容 -->
    <u-form @submit="submitForm"
            ref="formRef"
            label-width="110"
            input-align="right"
            error-message-align="right">
      <!-- 基本信息 -->
      <view class="form-section">
        <u-form-item label="待生产数量"
                     prop="planQuantity"
                     required>
          <u-input v-model="form.planQuantity"
                   placeholder="自动填充"
                   disabled />
        </u-form-item>
        <u-form-item label="本次生产数量"
                     prop="quantity"
                     required>
          <u-input v-model="form.quantity"
                   placeholder="请输入"
                   type="number" />
          <!-- <u-number-box v-model="form.quantity"
                        step="0.1"
                        bgColor="#fff"
                        decimal-length="1"
                        :min="0"></u-number-box> -->
        </u-form-item>
        <u-form-item label="班组信息"
                     prop="schedulingUserId"
                     required>
          <u-input v-model="form.userName"
                   placeholder="请选择生产人"
                   readonly />
        </u-form-item>
      </view>
    </view>
    <form-dia ref="formDia" @close="handleQuery"></form-dia>
    <!-- 状态选择器 -->
    <up-action-sheet :show="showStatusPicker" :actions="statusActions" title="选择状态" @select="onStatusSelect" @close="showStatusPicker = false" />
      <!-- 使用FooterButtons组件 -->
      <FooterButtons @cancel="goBack"
                     @confirm="submitForm"
                     :loading="submitting" />
      <!-- 为底部按钮留出空间 -->
      <view style="height: 80px;"></view>
    </u-form>
    <!-- 生产人选择器 -->
    <up-action-sheet :show="showProducerPicker"
                     :actions="producerList"
                     title="选择生产人"
                     @select="onProducerConfirm"
                     @close="showProducerPicker = false" />
  </view>
</template>
<script setup>
import { onMounted, ref, reactive, toRefs, nextTick, computed } from "vue";
import PageHeader from '@/components/PageHeader.vue'
import FormDia from './components/formDia.vue'
import { workListPage } from "@/api/productionManagement/productionReporting.js";
  import { ref, onMounted } from "vue";
  import { onLoad } from "@dcloudio/uni-app";
  import FooterButtons from "@/components/FooterButtons.vue";
  import modal from "@/plugins/modal";
const statusList = reactive([{
   text:'待报工',
   value: 1
},{
   text:'排产中',
   value: 2
},
// {
//    text:'生产中',
//    value: 3
// },
])
  const showToast = message => {
    uni.showToast({
      title: message,
      icon: "none",
    });
  };
  import { addProductMain } from "@/api/productionManagement/productionReporting";
  import { getInfo } from "@/api/login";
const data = reactive({
  searchForm: {
    customerName: "",
    projectName: "",
    status: undefined,
  },
});
const { searchForm } = toRefs(data);
const showStatusPicker = ref(false)
const statusOptions = ref([
  { label: '待报工', value: 1 },
  { label: '生产中', value: 2 },
  { label: '已报工', value: 3 },
])
const statusActions = computed(() => statusOptions.value.map(o => ({ name: o.label, value: o.value })))
const statusDisplay = ref('')
const tableData = ref([]);
const tableLoading = ref(false);
const page = reactive({
  current: -1,
  size: -1,
});
const formDia = ref()
  // 表单引用
  const formRef = ref();
// 查询列表
/** 搜索按钮操作 */
const handleQuery = () => {
  page.current = -1;
  page.size = -1;
  getList();
};
const getList = () => {
  tableLoading.value = true;
  const params = { ...searchForm.value, ...page };
  workListPage(params).then(res => {
    tableLoading.value = false;
    tableData.value = res.data.records.map(item => ({
      ...item,
      pendingFinishNum: (Number(item.schedulingNum) || 0) - (Number(item.finishedNum) || 0)
    }));
  }).catch(err => {
    tableLoading.value = false;
  })
};
// 状态选择
const onStatusSelect = (item) => {
  searchForm.value.status = item?.value
  statusDisplay.value = item?.name || ''
  showStatusPicker.value = false
  handleQuery()
}
// 打开弹框
const openForm = (type, row) => {
  if (!row) return
  if ((Number(row.pendingFinishNum) || 0) === 0) {
    uni.showToast({ title: '无需再报工', icon: 'none' })
    return
  }
  nextTick(() => { formDia.value?.openDialog(type, row) })
};
  // 表单数据
  let form = ref({
    planQuantity: 0,
    quantity: 0,
    userName: "",
    workOrderId: "",
    reportWork: "",
    productProcessRouteItemId: "",
    userId: "",
    productMainId: null,
  });
  let schedulingUserName = ref("");
// 状态文本/类型
const statusText = (s) => {
  if (s == 3) return '已报工'
  if (s == 1) return '待报工'
  return '生产中'
}
const statusType = (s) => {
  if (s == 3) return 'success'
  if (s == 1) return 'primary'
  return 'warning'
}
  // 日期选择器状态
  const showEnterDatePicker = ref(false);
  const enterDateValue = ref(Date.now());
// 无分页
  // 生产人选择器状态
  const showProducerPicker = ref(false);
  const producerList = ref([]);
// 明细人员/日期选择
const openChildUserPicker = (index) => {
  if (!expandData.value[index]?.editType) return
  childUserPicker.value.index = index
  childUserPicker.value.show = true
}
const onChildUserSelect = (item) => {
  if (item && childUserPicker.value.index > -1) {
    const row = expandData.value[childUserPicker.value.index]
    row.schedulingUserId = item.value
    row.schedulingUserName = item.name
  }
  childUserPicker.value.show = false
}
const openChildDatePicker = (index) => {
  if (!expandData.value[index]?.editType) return
  childDatePicker.value.index = index
  childDatePicker.value.value = Date.now()
  childDatePicker.value.show = true
}
const onChildDateConfirm = (e) => {
  const d = new Date(e.value)
  const y = d.getFullYear(); const m = String(d.getMonth()+1).padStart(2, '0'); const day = String(d.getDate()).padStart(2, '0')
  const str = `${y}-${m}-${day}`
  if (childDatePicker.value.index > -1) {
    expandData.value[childDatePicker.value.index].schedulingDate = str
  }
  childDatePicker.value.show = false
}
  // 生产人选择确认
  const onProducerConfirm = e => {
    form.value.schedulingUserId = e.value;
    schedulingUserName.value = e.name;
    showProducerPicker.value = false;
  };
onMounted(() => {
  getList();
});
  // 提交状态
  const submitting = ref(false);
  // 返回上一页
  const goBack = () => {
    uni.navigateBack();
  };
  // 提交表单
  const submitForm = async () => {
    submitting.value = true;
    // 校验表单
    if (!form.value.quantity) {
      submitting.value = false;
      showToast("请输入本次生产数量");
      return;
    }
    if (form.value.quantity > form.value.planQuantity) {
      submitting.value = false;
      showToast("本次生产数量不能大于待生产数量");
      return;
    }
    console.log(form.value, "form.value");
    addProductMain(form.value).then(res => {
      if (res.code === 200) {
        showToast("报工成功");
        submitting.value = false;
        setTimeout(() => {
          goBack();
        }, 1000);
      } else {
        showToast(res.msg || "报工失败");
        submitting.value = false;
      }
    });
  };
  // 页面加载时初始化数据
  onLoad(options => {
    console.log(options, "options");
    try {
      const orderRow = JSON.parse(options.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;
      getInfo().then(res => {
        form.value.userId = res.user.userId;
        form.value.userName = res.user.userName;
      });
    } catch (error) {
      modal.msgError("订单解析失败");
      goBack();
      return;
    }
  });
</script>
<style scoped lang="scss">
.prod-reporting { padding-bottom: 12px; }
.search_form { margin: 12px; background: #fff; border-radius: 8px; padding: 10px; }
.form-row { display: flex; gap: 12px; }
.form-actions { display: flex; justify-content: flex-end; }
.list_container { padding: 0 12px; }
.empty { text-align: center; color: #888; padding: 20px 0; }
.card_list { display: flex; flex-direction: column; gap: 10px; }
.card_item { background: #fff; border-radius: 10px; padding: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.05); }
.card_header { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.card_title { font-weight: 500; color: #333; margin-left: auto; }
.card_body .row { display: flex; justify-content: space-between; padding: 4px 0; }
.card_body .row.inline { display: flex; gap: 10px; flex-wrap: wrap; }
.card_body .row.inline .col { min-width: 45%; display: flex; justify-content: space-between; }
.label { color: #666; font-size: 12px; }
.value { color: #333; font-size: 12px; }
.card_actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 8px; }
.ml8 { margin-left: 8px; }
  @import "@/static/scss/form-common.scss";
</style>