From 6a415a072a98d64d2f95d16eef73b6d7270b8d56 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期六, 30 五月 2026 15:14:25 +0800
Subject: [PATCH] 新疆马铃薯 1.首页问题:挪新系统ui,需要确认一下页面数据完整。 2.协同办公:挪新系统 3.营销管理:客户往来取消回款金额字段,改为点击左侧客户时显示与该客户的所有订单信息,以及发货情况。销售可以选好对应的采购订单方便质量追溯。 4.采购管理:供应商往来同上逻辑,显示是否收货,也加上采购退货和采购报表功能。 5.采购加上设备备件选项,设备备件入库到备件库存。设备,仓储不足时做采购提醒。 6.仓储物流:得区分成品库和原料库(不存在半成品,成品只有一个产品,很好确认),原材料需要有批号,采集原料库需要做好仓库字段,让他们可以区分哪个仓库,然后把数采设备信息做一个实时的显示。总库存显示好当前存在的批次信息。 7.质量:只有不通过才需要填写对应的数据信息。在外侧做好选择通过不通过。过程,出厂检验无法对应到生产订单,那就对应到销售订单。 8.决策分析:基础数据分析和进销存分析,质量数据分析需要重新设计

---
 src/components/ProjectManagement/ProgressReportDialog.vue |  242 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 242 insertions(+), 0 deletions(-)

diff --git a/src/components/ProjectManagement/ProgressReportDialog.vue b/src/components/ProjectManagement/ProgressReportDialog.vue
new file mode 100644
index 0000000..dc6afe7
--- /dev/null
+++ b/src/components/ProjectManagement/ProgressReportDialog.vue
@@ -0,0 +1,242 @@
+<template>
+  <el-dialog v-model="visible" title="杩涘害姹囨姤" width="900px" top="8vh" append-to-body destroy-on-close @close="handleClose">
+    <el-form ref="formRef" :model="form" :rules="rules" label-position="top" label-width="120px">
+      <el-form-item label="椤圭洰闃舵" prop="planNodeId">
+        <el-select v-model="form.planNodeId" placeholder="璇烽�夋嫨" clearable style="width: 100%">
+          <el-option v-for="opt in stageOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
+        </el-select>
+      </el-form-item>
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="璁″垝寮�濮嬫椂闂�" prop="planStartTime">
+            <el-date-picker
+              v-model="form.planStartTime"
+              type="date"
+              value-format="YYYY-MM-DD"
+              format="YYYY-MM-DD"
+              placeholder="璇烽�夋嫨"
+              style="width: 100%"
+              clearable
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="璁″垝瀹屽伐鏃堕棿" prop="planEndTime">
+            <el-date-picker
+              v-model="form.planEndTime"
+              type="date"
+              value-format="YYYY-MM-DD"
+              format="YYYY-MM-DD"
+              placeholder="璇烽�夋嫨"
+              style="width: 100%"
+              clearable
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="瀹為檯寮�宸ユ棩鏈�" prop="actualStartTime">
+            <el-date-picker
+              v-model="form.actualStartTime"
+              type="date"
+              value-format="YYYY-MM-DD"
+              format="YYYY-MM-DD"
+              placeholder="璇烽�夋嫨"
+              style="width: 100%"
+              clearable
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="鏈杩涘害鏃ユ湡" prop="reportDate">
+            <el-date-picker
+              v-model="form.reportDate"
+              type="date"
+              value-format="YYYY-MM-DD"
+              format="YYYY-MM-DD"
+              placeholder="璇烽�夋嫨"
+              style="width: 100%"
+              clearable
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="涓婃杩涘害(%)" prop="lastProgress">
+            <el-input-number v-model="form.lastProgress" :min="0" :max="100" controls-position="right" style="width: 100%" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="瀹屾垚杩涘害(%)" prop="completionProgress">
+            <div style="display: flex; gap: 8px; width: 100%;">
+              <el-input-number v-model="form.completionProgress" :min="0" :max="100" controls-position="right" style="flex: 1" />
+              <el-button type="danger" @click="markDone">瀹屾垚</el-button>
+            </div>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="绱杩涘害(%)" prop="totalProgress">
+            <el-input-number v-model="form.totalProgress" :min="0" :max="100" controls-position="right" style="width: 100%" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="瀹為檯瀹屽伐鏃ユ湡" prop="actualEndTime">
+            <el-date-picker
+              v-model="form.actualEndTime"
+              type="date"
+              value-format="YYYY-MM-DD"
+              format="YYYY-MM-DD"
+              placeholder="璇烽�夋嫨"
+              style="width: 100%"
+              clearable
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="璐熻矗浜�" prop="managerName">
+            <el-input v-model="form.managerName" placeholder="璇疯緭鍏�" clearable />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="閮ㄩ棬" prop="departmentName">
+            <el-input v-model="form.departmentName" placeholder="璇疯緭鍏�" clearable />
+          </el-form-item>
+        </el-col>
+        <el-col :span="16">
+          <el-form-item label="澶囨敞" prop="remark">
+            <el-input v-model="form.remark" placeholder="璇疯緭鍏�" clearable />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-form-item label="闄勪欢" prop="attachmentIds">
+        <FileUpload v-model:file-list="form.storageBlobDTOs" />
+      </el-form-item>
+    </el-form>
+
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button type="primary" @click="submit">纭畾</el-button>
+        <el-button @click="visible = false">鍙栨秷</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup name="ProgressReportDialog">
+import { computed, reactive, ref, watch } from 'vue'
+import { ElMessage } from 'element-plus'
+import { getToken } from '@/utils/auth'
+import FileUpload from "@/components/AttachmentUpload/file/index.vue";
+
+const props = defineProps({
+  modelValue: { type: Boolean, default: false },
+  projectId: { type: [Number, String], default: undefined },
+  projectInfo: { type: Object, default: () => ({}) },
+  planNodes: { type: Array, default: () => [] },
+  defaultPlanNodeId: { type: [Number, String], default: undefined }
+})
+
+const emit = defineEmits(['update:modelValue', 'submitted'])
+
+const visible = computed({
+  get: () => props.modelValue,
+  set: v => emit('update:modelValue', v)
+})
+
+const formRef = ref()
+
+const form = ref({
+  planNodeId: undefined,
+  planStartTime: '',
+  planEndTime: '',
+  actualStartTime: '',
+  actualEndTime: '',
+  reportDate: '',
+  lastProgress: 0,
+  completionProgress: 0,
+  totalProgress: 0,
+  managerName: '',
+  departmentName: '',
+  remark: '',
+  storageBlobDTOs: []
+})
+
+const rules = {
+  planNodeId: [{ required: true, message: '璇烽�夋嫨', trigger: 'change' }],
+  planStartTime: [{ required: true, message: '璇烽�夋嫨璁″垝寮�濮嬫椂闂�', trigger: 'change' }],
+  planEndTime: [{ required: true, message: '璇烽�夋嫨璁″垝瀹屽伐鏃堕棿', trigger: 'change' }],
+  reportDate: [{ required: true, message: '璇烽�夋嫨', trigger: 'change' }],
+  completionProgress: [{ required: true, message: '璇疯緭鍏�', trigger: 'change' }]
+}
+
+const stageOptions = computed(() => {
+  const list = Array.isArray(props.planNodes) ? props.planNodes : []
+  const sorted = [...list].sort((a, b) => Number(a.sort ?? 0) - Number(b.sort ?? 0))
+  return sorted
+    .map(n => ({
+      label: n.name || n.workContent || n.title || String(n.id ?? ''),
+      value: n.id
+    }))
+    .filter(i => i.value !== undefined && i.value !== null && i.value !== '')
+})
+
+function resetFromProject() {
+  const info = props.projectInfo || {}
+  form.value = {
+    planNodeId: props.defaultPlanNodeId ?? stageOptions.value[0]?.value,
+    planStartTime: info.planStartTime || '',
+    planEndTime: info.planEndTime || '',
+    actualStartTime: info.actualStartTime || '',
+    actualEndTime: info.actualEndTime || '',
+    reportDate: '',
+    lastProgress: Number(info.lastProgress ?? 0) || 0,
+    completionProgress: 0,
+    totalProgress: Number(info.totalProgress ?? info.progress ?? 0) || 0,
+    managerName: info.managerName || '',
+    departmentName: info.departmentName || '',
+    remark: '',
+    storageBlobDTOs: []
+  }
+}
+
+watch(
+  () => props.modelValue,
+  v => {
+    if (v) resetFromProject()
+  }
+)
+
+function handleClose() {
+  formRef.value?.resetFields?.()
+}
+
+function markDone() {
+  form.value.completionProgress = 100
+  form.value.totalProgress = 100
+  if (!form.value.actualEndTime) form.value.actualEndTime = form.value.reportDate || ''
+}
+
+async function submit() {
+  await formRef.value?.validate?.()
+  emit('submitted', {
+    projectId: props.projectId,
+    ...form.value
+  })
+  visible.value = false
+}
+</script>
+
+<style scoped lang="scss">
+.dialog-footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: 10px;
+}
+</style>

--
Gitblit v1.9.3