yanghao hace 2 semanas
padre
commit
7114393bb3

+ 0 - 14
src/views/researchProject/list/index.vue

@@ -473,20 +473,6 @@ const removeProject = async (id: number) => {
   color: var(--el-text-color-secondary);
   color: var(--el-text-color-secondary);
   font-size: 13px;
   font-size: 13px;
 }
 }
-.budget-total {
-  display: flex;
-  align-items: baseline;
-  justify-content: flex-end;
-  gap: 8px;
-  padding: 12px 8px;
-  color: var(--el-text-color-secondary);
-  border-top: 1px solid var(--el-border-color-lighter);
-}
-.budget-total strong {
-  color: var(--el-color-danger);
-  font-size: 20px;
-  font-variant-numeric: tabular-nums;
-}
 @media (max-width: 900px) {
 @media (max-width: 900px) {
   .budget-grid :deep(.el-col) {
   .budget-grid :deep(.el-col) {
     width: 50%;
     width: 50%;

+ 95 - 26
src/views/researchProject/progress/index.vue

@@ -200,23 +200,59 @@
         </div>
         </div>
       </el-form-item>
       </el-form-item>
       <el-divider content-position="left">费用预算(元)</el-divider>
       <el-divider content-position="left">费用预算(元)</el-divider>
-      <el-row :gutter="18" class="budget-grid"
-        ><el-col v-for="item in budgetItems" :key="item.key" :span="6"
-          ><el-form-item :label="item.label"
-            ><el-input-number
-              v-model="formData.budget[item.key]"
+      <el-table
+        :data="budgetItems"
+        border
+        class="budget-table"
+        :header-cell-style="{ background: '#f3f6fd', color: '#555' }"
+      >
+        <el-table-column
+          prop="label"
+          label="费用预算"
+          min-width="420"
+          align="center"
+          header-align="center"
+        />
+        <el-table-column label="预算" min-width="220" align="center" header-align="center">
+          <template #default="{ row }">
+            <el-input-number
+              disabled
+              v-model="formData.budget[row.key]"
               :min="0"
               :min="0"
               :precision="2"
               :precision="2"
               controls-position="right"
               controls-position="right"
-              class="w-full" /></el-form-item></el-col
-      ></el-row>
-      <div class="budget-total"
-        ><span>预算合计</span><strong>{{ budgetTotal.toFixed(2) }}</strong
-        ><span>元</span></div
-      >
+              class="budget-input"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="实际支出"
+          min-width="220"
+          align="center"
+          header-align="center"
+          class-name="actual-spend-column"
+        >
+          <template #default="{ row }">
+            <el-input-number
+              v-model="formData.actualSpend[row.key]"
+              :min="0"
+              :precision="2"
+              controls-position="right"
+              class="budget-input"
+            />
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="budget-total budget-total-row">
+        <strong>总计</strong>
+        <strong>{{ budgetTotal.toFixed(2) }}</strong>
+        <strong>{{ actualSpendTotal.toFixed(2) }}</strong>
+        <span>元</span>
+      </div>
       <el-divider content-position="left">附件上传</el-divider>
       <el-divider content-position="left">附件上传</el-divider>
       <el-form-item label="立项申请表" required
       <el-form-item label="立项申请表" required
         ><UploadFile
         ><UploadFile
+          :disabled="true"
           v-model="formData.attachments.application"
           v-model="formData.attachments.application"
           :return-object="true"
           :return-object="true"
           :auto-upload="false"
           :auto-upload="false"
@@ -224,6 +260,16 @@
           :file-type="['doc', 'docx', 'pdf']"
           :file-type="['doc', 'docx', 'pdf']"
       /></el-form-item>
       /></el-form-item>
       <el-form-item label="开题报告" required
       <el-form-item label="开题报告" required
+        ><UploadFile
+          :disabled="true"
+          v-model="formData.attachments.report"
+          :return-object="true"
+          :auto-upload="false"
+          :limit="1"
+          :file-type="['doc', 'docx', 'pdf']"
+      /></el-form-item>
+
+      <el-form-item label="进度报告" required
         ><UploadFile
         ><UploadFile
           v-model="formData.attachments.report"
           v-model="formData.attachments.report"
           :return-object="true"
           :return-object="true"
@@ -280,6 +326,7 @@ type Project = {
   innovation: string
   innovation: string
   schedule: ScheduleItem[]
   schedule: ScheduleItem[]
   budget: Record<string, number>
   budget: Record<string, number>
+  actualSpend: Record<string, number>
   attachments: { application: any[]; report: any[]; others: any[] }
   attachments: { application: any[]; report: any[]; others: any[] }
   status: string
   status: string
 }
 }
@@ -292,7 +339,7 @@ const projectTypes = [
   '情报调研类'
   '情报调研类'
 ]
 ]
 const budgetItems = [
 const budgetItems = [
-  { key: 'labor', label: '人工' },
+  { key: 'labor', label: '人工(包含工资、福利、社保、奖金等)' },
   { key: 'materials', label: '直接材料投入' },
   { key: 'materials', label: '直接材料投入' },
   { key: 'supplies', label: '劳保用品' },
   { key: 'supplies', label: '劳保用品' },
   { key: 'fuel', label: '燃料' },
   { key: 'fuel', label: '燃料' },
@@ -322,6 +369,7 @@ const createForm = () => ({
   innovation: '',
   innovation: '',
   schedule: [createSchedule(), createSchedule(), createSchedule()],
   schedule: [createSchedule(), createSchedule(), createSchedule()],
   budget: createBudget(),
   budget: createBudget(),
+  actualSpend: createBudget(),
   attachments: { application: [], report: [], others: [] }
   attachments: { application: [], report: [], others: [] }
 })
 })
 const list = ref<Project[]>([
 const list = ref<Project[]>([
@@ -341,6 +389,7 @@ const list = ref<Project[]>([
       { workPlan: '完成样机试制', deadline: '2026-10-31' }
       { workPlan: '完成样机试制', deadline: '2026-10-31' }
     ],
     ],
     budget: createBudget(),
     budget: createBudget(),
+    actualSpend: createBudget(),
     attachments: { application: [], report: [], others: [] },
     attachments: { application: [], report: [], others: [] },
     status: '进行中'
     status: '进行中'
   }
   }
@@ -375,6 +424,9 @@ const formRules = reactive<FormRules>({
 const budgetTotal = computed(() =>
 const budgetTotal = computed(() =>
   Object.values(formData.value.budget).reduce((sum, value) => sum + Number(value || 0), 0)
   Object.values(formData.value.budget).reduce((sum, value) => sum + Number(value || 0), 0)
 )
 )
+const actualSpendTotal = computed(() =>
+  Object.values(formData.value.actualSpend).reduce((sum, value) => sum + Number(value || 0), 0)
+)
 const handleQuery = () => {
 const handleQuery = () => {
   queryParams.pageNo = 1
   queryParams.pageNo = 1
 }
 }
@@ -406,6 +458,7 @@ const cloneProjectForm = (project: Project) => ({
   innovation: project.innovation,
   innovation: project.innovation,
   schedule: project.schedule.map((item) => ({ ...item })),
   schedule: project.schedule.map((item) => ({ ...item })),
   budget: { ...project.budget },
   budget: { ...project.budget },
+  actualSpend: { ...project.actualSpend },
   attachments: cloneAttachments(project.attachments)
   attachments: cloneAttachments(project.attachments)
 })
 })
 const openForm = (project?: Project) => {
 const openForm = (project?: Project) => {
@@ -484,24 +537,40 @@ const removeProject = async (id: number) => {
   color: var(--el-text-color-secondary);
   color: var(--el-text-color-secondary);
   font-size: 13px;
   font-size: 13px;
 }
 }
-.budget-total {
-  display: flex;
-  align-items: baseline;
-  justify-content: flex-end;
-  gap: 8px;
-  padding: 12px 8px;
-  color: var(--el-text-color-secondary);
-  border-top: 1px solid var(--el-border-color-lighter);
+.budget-table {
+  width: 100%;
+}
+.budget-table :deep(.el-input-number) {
+  width: 100%;
+}
+.budget-table :deep(.actual-spend-column) {
+  background-color: #fff900;
 }
 }
-.budget-total strong {
-  color: var(--el-color-danger);
-  font-size: 20px;
+.budget-total-row {
+  display: grid;
+  grid-template-columns: minmax(420px, 1fr) minmax(220px, 1fr) minmax(220px, 1fr) auto;
+  align-items: center;
+  gap: 0;
+  min-height: 48px;
+  border: 1px solid var(--el-border-color);
+  border-top: 0;
+  color: var(--el-text-color-primary);
+  text-align: center;
+}
+.budget-total-row strong,
+.budget-total-row span {
+  padding: 12px;
   font-variant-numeric: tabular-nums;
   font-variant-numeric: tabular-nums;
 }
 }
+.budget-total-row strong:first-child {
+  text-align: left;
+}
+.budget-total-row strong:not(:first-child) {
+  border-left: 1px solid var(--el-border-color);
+}
 @media (max-width: 900px) {
 @media (max-width: 900px) {
-  .budget-grid :deep(.el-col) {
-    width: 50%;
-    flex: 0 0 50%;
+  .budget-total-row {
+    grid-template-columns: minmax(220px, 1fr) minmax(150px, 1fr) minmax(150px, 1fr) auto;
   }
   }
 }
 }
 </style>
 </style>