Browse Source

修改网页和移动端,工作填报新增开始日期和结束日期

余思翰 1 month ago
parent
commit
42e5b70cee

+ 253
- 47
oa-ui-app/pages/form/declare/declare.vue View File

30
 
30
 
31
 			<!-- 选择项目 -->
31
 			<!-- 选择项目 -->
32
 			<uni-forms-item label="选择项目" required class="form-item" v-if="!isScattered" name="projectId">
32
 			<uni-forms-item label="选择项目" required class="form-item" v-if="!isScattered" name="projectId">
33
-				<!-- <ProjectPicker v-model="formData.projectId" placeholder="请选择项目" :labelKey="'projectName'"
34
-					:valueKey="'projectId'" @change="handleProjectChange"
35
-					:customStyle="{ borderColor: '#e5e5e5', borderRadius: '8px' }" v-if="taskName == '工作填报'" /> -->
36
-				<!-- <ProjectInfo :project="projectObj" v-else></ProjectInfo> -->
37
 				<u-button type="primary" @click="openProject = true" v-if="taskName == '工作填报'">选择项目</u-button>
33
 				<u-button type="primary" @click="openProject = true" v-if="taskName == '工作填报'">选择项目</u-button>
38
 				<ProjectPicker :visible.sync="openProject" :selected.sync="selectedProject" @confirm="handleConfirm" />
34
 				<ProjectPicker :visible.sync="openProject" :selected.sync="selectedProject" @confirm="handleConfirm" />
39
 				<ProjectInfo :project="projectObj"></ProjectInfo>
35
 				<ProjectInfo :project="projectObj"></ProjectInfo>
49
 			<uni-forms-item label="工作细项" required class="form-item" name="workItem">
45
 			<uni-forms-item label="工作细项" required class="form-item" name="workItem">
50
 				<picker @change="bindWorkItemChange" :value="formData.workItem" :range="workItemList"
46
 				<picker @change="bindWorkItemChange" :value="formData.workItem" :range="workItemList"
51
 					:disabled="taskName != '工作填报'">
47
 					:disabled="taskName != '工作填报'">
52
-					<view class="uni-input">
53
-						<uni-easyinput type="text" :disabled="taskName != '工作填报'" v-model="formData.workItem"
54
-							@click="showType = true" placeholder="请选择" :styles="inputStyle" />
48
+					<view class="picker-selector" :class="{ 'picker-disabled': taskName != '工作填报' }">
49
+						<text class="picker-text" :class="{ 'picker-placeholder': !formData.workItem }">
50
+							{{ formData.workItem || '请选择' }}
51
+						</text>
52
+						<uni-icons type="arrowdown" size="16" color="#c0c4cc"></uni-icons>
55
 					</view>
53
 					</view>
56
 				</picker>
54
 				</picker>
57
 			</uni-forms-item>
55
 			</uni-forms-item>
58
 
56
 
57
+			<!-- 工作日期 -->
58
+			<uni-forms-item label="工作日期" required class="form-item" name="beginDate">
59
+				<uni-datetime-picker v-if="taskName == '工作填报'" type="daterange" v-model="dateRange" start-placeholder="开始日期"
60
+					end-placeholder="结束日期" range-separator="至" return-type="string" @change="handleDateRangeChange" :border="true"
61
+					:clear-icon="true" />
62
+				<view v-else class="date-display">
63
+					<text class="date-text">{{ formatDateRange() }}</text>
64
+				</view>
65
+			</uni-forms-item>
66
+
59
 			<!-- 具体内容 -->
67
 			<!-- 具体内容 -->
60
 			<uni-forms-item label="具体内容" required class="form-item" name="workContent">
68
 			<uni-forms-item label="具体内容" required class="form-item" name="workContent">
61
 				<uni-easyinput :disabled="taskName != '工作填报'" type="textarea" v-model="formData.workContent"
69
 				<uni-easyinput :disabled="taskName != '工作填报'" type="textarea" v-model="formData.workContent"
64
 
72
 
65
 			<!-- 工天 -->
73
 			<!-- 工天 -->
66
 			<uni-forms-item label="工天" required class="form-item" name="workLoad">
74
 			<uni-forms-item label="工天" required class="form-item" name="workLoad">
67
-				<uni-easyinput :disabled="taskName != '工作填报'" type="number" v-model="formData.workLoad" placeholder="请输入所需工天"
75
+				<uni-easyinput :disabled="taskName != '工作填报'" type="number" v-model="formData.workLoad" placeholder="请输入工天"
68
 					:styles="inputStyle">
76
 					:styles="inputStyle">
69
 					<text slot="right" class="unit">天</text>
77
 					<text slot="right" class="unit">天</text>
70
 				</uni-easyinput>
78
 				</uni-easyinput>
118
 		startUserName: String, // 流程发起人
126
 		startUserName: String, // 流程发起人
119
 	},
127
 	},
120
 	created() {
128
 	created() {
121
-    this.applierUserName = this.startUserName;
129
+		this.applierUserName = this.startUserName;
122
 		this.getProjectList();
130
 		this.getProjectList();
123
 		this.initForm();
131
 		this.initForm();
124
 		if (this.taskName != '工作填报') {
132
 		if (this.taskName != '工作填报') {
139
 				projectId: '',
147
 				projectId: '',
140
 				workType: '',
148
 				workType: '',
141
 				workItem: '',
149
 				workItem: '',
150
+				beginDate: '',
151
+				endDate: '',
142
 				workContent: '',
152
 				workContent: '',
143
 				workLoad: '',
153
 				workLoad: '',
144
 				price: 200,
154
 				price: 200,
165
 						errorMessage: '请选择工作细项',
175
 						errorMessage: '请选择工作细项',
166
 					},]
176
 					},]
167
 				},
177
 				},
178
+				beginDate: {
179
+					rules: [{
180
+						required: true,
181
+						errorMessage: '请选择开始日期',
182
+					},]
183
+				},
184
+				endDate: {
185
+					rules: [{
186
+						required: true,
187
+						errorMessage: '请选择结束日期',
188
+					},]
189
+				},
168
 				workContent: {
190
 				workContent: {
169
 					rules: [{
191
 					rules: [{
170
 						required: true,
192
 						required: true,
174
 				workLoad: {
196
 				workLoad: {
175
 					rules: [{
197
 					rules: [{
176
 						required: true,
198
 						required: true,
177
-						errorMessage: '请输入工作量',
199
+						errorMessage: '请输入工',
178
 					},]
200
 					},]
179
 				},
201
 				},
180
 				coefficient: {
202
 				coefficient: {
205
 				borderRadius: '8px',
227
 				borderRadius: '8px',
206
 				height: '100px'
228
 				height: '100px'
207
 			},
229
 			},
208
-			showType: false,
230
+
209
 			workTypeColumns: [{
231
 			workTypeColumns: [{
210
 				text: '外业',
232
 				text: '外业',
211
 				value: '外业',
233
 				value: '外业',
218
 			workItemList: [],
240
 			workItemList: [],
219
 			hasForm: false,
241
 			hasForm: false,
220
 			show: false,
242
 			show: false,
243
+			isSubmitting: false, // 提交状态
221
 		};
244
 		};
222
 	},
245
 	},
246
+	computed: {
247
+		dateRange: {
248
+			get() {
249
+				if (this.formData.beginDate && this.formData.endDate) {
250
+					return [this.formData.beginDate, this.formData.endDate];
251
+				}
252
+				return [];
253
+			},
254
+			set(value) {
255
+				if (value && value.length === 2) {
256
+					this.formData.beginDate = value[0];
257
+					this.formData.endDate = value[1];
258
+				} else {
259
+					this.formData.beginDate = '';
260
+					this.formData.endDate = '';
261
+				}
262
+			}
263
+		}
264
+	},
223
 	methods: {
265
 	methods: {
224
 		handleConfirm(project) {
266
 		handleConfirm(project) {
225
 			this.selectedProject = project;
267
 			this.selectedProject = project;
226
 			this.projectObj = project;
268
 			this.projectObj = project;
269
+			// 同时设置formData中的projectId,避免表单验证失败
270
+			this.formData.projectId = project.projectId;
227
 		},
271
 		},
228
 		initForm() {
272
 		initForm() {
229
 			if (this.taskName == '工作填报') {
273
 			if (this.taskName == '工作填报') {
246
 					this.projectObj = res.data.project;
290
 					this.projectObj = res.data.project;
247
 					this.selectedProject = res.data.project;
291
 					this.selectedProject = res.data.project;
248
 					this.bindWorkTypeChange(this.formData.workType);
292
 					this.bindWorkTypeChange(this.formData.workType);
293
+
294
+					// 处理日期范围和工天的关系
295
+					if (!this.formData.beginDate) {
296
+						this.formData.beginDate = '';
297
+					}
298
+					if (!this.formData.endDate) {
299
+						this.formData.endDate = '';
300
+					}
301
+					if (this.formData.beginDate && this.formData.endDate) {
302
+						// 如果有日期范围,计算建议工天数但不覆盖现有值
303
+						this.calculateWorkDays();
304
+					}
305
+
249
 					this.countMoney();
306
 					this.countMoney();
250
 				} else {
307
 				} else {
251
 					this.hasForm = false;
308
 					this.hasForm = false;
296
 			let result = Number(this.formData.price) * Number(this.formData.workLoad) * Number(this.formData.coefficient)
353
 			let result = Number(this.formData.price) * Number(this.formData.workLoad) * Number(this.formData.coefficient)
297
 			this.money = result.toFixed(2)
354
 			this.money = result.toFixed(2)
298
 		},
355
 		},
299
-		async save() {
300
-			if (!this.isScattered) {
301
-				this.formData.projectId = this.projectObj.projectId;
302
-			} else {
303
-				this.formData.projectId = ''
356
+		handleDateRangeChange(range) {
357
+			this.dateRange = range;
358
+			this.calculateWorkDays();
359
+		},
360
+		calculateWorkDays() {
361
+			if (!this.formData.beginDate || !this.formData.endDate) {
362
+				return;
304
 			}
363
 			}
305
-			if (this.hasForm) {
306
-				let updateRes = await updateDeclare(this.formData);
307
-			} else {
308
-				this.formData.formId = this.taskForm.formId;
309
-				let addRes = await addDeclare(this.formData);
310
-				if (addRes.code == 200) {
311
-					this.hasForm = true;
364
+
365
+			const startDate = new Date(this.formData.beginDate);
366
+			const endDate = new Date(this.formData.endDate);
367
+
368
+			if (startDate && endDate && startDate <= endDate) {
369
+				// 计算日期差(包含开始和结束日期)
370
+				const timeDiff = endDate.getTime() - startDate.getTime();
371
+				const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24)) + 1;
372
+
373
+				// 直接设置工天
374
+				this.formData.workLoad = daysDiff;
375
+			}
376
+		},
377
+
378
+		formatDateRange() {
379
+			if (this.formData.beginDate && this.formData.endDate) {
380
+				const beginDate = this.formData.beginDate.split(' ')[0]; // 只取日期部分,去掉时间
381
+				const endDate = this.formData.endDate.split(' ')[0];
382
+				return `${beginDate} 到 ${endDate}`;
383
+			}
384
+			return '未选择日期';
385
+		},
386
+		async save(showToast = true) {
387
+			try {
388
+				if (!this.isScattered) {
389
+					this.formData.projectId = this.projectObj.projectId;
312
 				} else {
390
 				} else {
313
-					this.hasForm = false;
391
+					this.formData.projectId = ''
314
 				}
392
 				}
393
+
394
+				let result;
395
+				if (this.hasForm) {
396
+					result = await updateDeclare(this.formData);
397
+				} else {
398
+					this.formData.formId = this.taskForm.formId;
399
+					result = await addDeclare(this.formData);
400
+					if (result.code == 200) {
401
+						this.hasForm = true;
402
+					} else {
403
+						this.hasForm = false;
404
+					}
405
+				}
406
+
407
+				if (result && result.code === 200) {
408
+					if (showToast) {
409
+						uni.showToast({
410
+							title: '保存成功',
411
+							icon: 'success'
412
+						});
413
+					}
414
+					return Promise.resolve(result);
415
+				} else {
416
+					throw new Error(result?.msg || '保存失败');
417
+				}
418
+			} catch (error) {
419
+				console.error('保存失败:', error);
420
+				if (showToast) {
421
+					uni.showToast({
422
+						title: error.message || '保存失败',
423
+						icon: 'error'
424
+					});
425
+				}
426
+				return Promise.reject(error);
315
 			}
427
 			}
316
-			uni.showToast({
317
-				title: '保存成功',
318
-				icon: 'success'
319
-			});
320
 		},
428
 		},
321
 		submitForm() {
429
 		submitForm() {
430
+			// 在表单验证前确保projectId被正确设置
431
+			if (!this.isScattered && this.projectObj && this.projectObj.projectId) {
432
+				this.formData.projectId = this.projectObj.projectId;
433
+			} else if (this.isScattered) {
434
+				this.formData.projectId = '';
435
+			}
436
+
322
 			this.$refs.form.validate().then(res => {
437
 			this.$refs.form.validate().then(res => {
323
 				this.taskForm.variables.skip = false;
438
 				this.taskForm.variables.skip = false;
324
 				if (!this.projectObj.projectLeader) {
439
 				if (!this.projectObj.projectLeader) {
332
 				console.log('表单错误信息:', err);
447
 				console.log('表单错误信息:', err);
333
 			})
448
 			})
334
 		},
449
 		},
335
-		confirmSubmit() {
336
-			if (this.taskName == '工作填报') {
337
-				this.declareSubmit();
338
-			} else if (this.taskName == '项目负责人审核' || this.taskName == '部门负责人审核') {
339
-				this.approveForm();
340
-			} else {
341
-				this.confirmForm();
450
+		async confirmSubmit() {
451
+			if (this.isSubmitting) return; // 防止重复提交
452
+
453
+			try {
454
+				this.isSubmitting = true;
455
+
456
+				// 显示保存中提示
457
+				uni.showLoading({
458
+					title: '正在保存...'
459
+				});
460
+
461
+				// 先保存表单,不显示保存成功提示
462
+				await this.save(false);
463
+
464
+				uni.hideLoading();
465
+
466
+				if (this.taskName != '填报人确认') {
467
+					// 显示提交中提示
468
+					uni.showLoading({
469
+						title: '正在提交...'
470
+					});
471
+				}
472
+
473
+				// 保存成功后执行相应的提交流程
474
+				if (this.taskName == '工作填报') {
475
+					await this.declareSubmit();
476
+				} else if (this.taskName == '项目负责人审核' || this.taskName == '部门负责人审核') {
477
+					await this.approveForm();
478
+				} else {
479
+					await this.confirmForm();
480
+				}
481
+			} catch (error) {
482
+				console.error('保存失败,无法提交:', error);
483
+				uni.hideLoading();
484
+				uni.showToast({
485
+					title: '保存失败,请重试',
486
+					icon: 'error'
487
+				});
488
+			} finally {
489
+				this.isSubmitting = false;
342
 			}
490
 			}
343
 		},
491
 		},
344
 		async declareSubmit() {
492
 		async declareSubmit() {
347
 				this.taskForm.variables.approval = approval
495
 				this.taskForm.variables.approval = approval
348
 			} else {
496
 			} else {
349
 				let resData = await getUsersDeptLeader({
497
 				let resData = await getUsersDeptLeader({
350
-					userId: this.form.userId
498
+					userId: this.formData.userId
351
 				});
499
 				});
352
 				if (resData.data) {
500
 				if (resData.data) {
353
 					this.taskForm.variables.approval = resData.data.userId
501
 					this.taskForm.variables.approval = resData.data.userId
354
 					this.taskForm.variables.skip = true;
502
 					this.taskForm.variables.skip = true;
355
 				}
503
 				}
356
 			}
504
 			}
357
-			if (this.hasForm) {
358
-				updateDeclare(this.formData);
359
-			} else {
360
-				this.formData.formId = this.taskForm.formId;
361
-				addDeclare(this.formData);
362
-			}
505
+			// 数据已在confirmSubmit中保存,直接进行流程提交
363
 			this.handleComplete(this.taskForm);
506
 			this.handleComplete(this.taskForm);
364
 		},
507
 		},
365
 		async approveForm() {
508
 		async approveForm() {
366
 			if (this.taskName == '项目负责人审核') {
509
 			if (this.taskName == '项目负责人审核') {
367
 				this.formData.checkStatus = '1';
510
 				this.formData.checkStatus = '1';
368
-				updateDeclare(this.formData);
511
+				// 更新状态后需要再次保存
512
+				await updateDeclare(this.formData);
369
 				let resData = await getUsersDeptLeader({
513
 				let resData = await getUsersDeptLeader({
370
 					userId: this.formData.userId
514
 					userId: this.formData.userId
371
 				});
515
 				});
376
 			} else if (this.taskName == '部门负责人审核') {
520
 			} else if (this.taskName == '部门负责人审核') {
377
 				this.formData.checkStatus = '1';
521
 				this.formData.checkStatus = '1';
378
 				this.formData.auditStatus = '1';
522
 				this.formData.auditStatus = '1';
379
-				updateDeclare(this.formData);
523
+				// 更新状态后需要再次保存
524
+				await updateDeclare(this.formData);
380
 				this.taskForm.variables.approval = this.formData.userId;
525
 				this.taskForm.variables.approval = this.formData.userId;
381
 				this.handleComplete(this.taskForm);
526
 				this.handleComplete(this.taskForm);
382
 			}
527
 			}
383
 		},
528
 		},
384
 		confirmForm() {
529
 		confirmForm() {
385
-			this.$modal.confirm('最后一个节点,提交将结束流程,是否提交?').then(() => {
530
+			return this.$modal.confirm('最后一个节点,提交将结束流程,是否提交?').then(async () => {
386
 				this.formData.confirmStatus = '1';
531
 				this.formData.confirmStatus = '1';
387
-				updateDeclare(this.formData);
532
+				// 更新确认状态后需要再次保存
533
+				await updateDeclare(this.formData);
388
 				this.handleComplete(this.taskForm);
534
 				this.handleComplete(this.taskForm);
389
 			})
535
 			})
390
 		},
536
 		},
394
 			};
540
 			};
395
 			getNextFlowNode(params).then(() => {
541
 			getNextFlowNode(params).then(() => {
396
 				complete(taskForm).then(response => {
542
 				complete(taskForm).then(response => {
543
+					uni.hideLoading(); // 隐藏loading
397
 					uni.showToast({
544
 					uni.showToast({
398
 						title: response.msg,
545
 						title: response.msg,
399
 						icon: 'success'
546
 						icon: 'success'
403
 							url: '/pages/message/index'
550
 							url: '/pages/message/index'
404
 						})
551
 						})
405
 					}, 500);
552
 					}, 500);
553
+				}).catch(error => {
554
+					uni.hideLoading(); // 隐藏loading
555
+					console.error('提交失败:', error);
556
+					uni.showToast({
557
+						title: '提交失败,请重试',
558
+						icon: 'error'
559
+					});
406
 				})
560
 				})
561
+			}).catch(error => {
562
+				uni.hideLoading(); // 隐藏loading
563
+				console.error('获取下一节点失败:', error);
564
+				uni.showToast({
565
+					title: '提交失败,请重试',
566
+					icon: 'error'
567
+				});
407
 			})
568
 			})
408
-
409
 		},
569
 		},
410
 	}
570
 	}
411
 };
571
 };
473
 	color: #999;
633
 	color: #999;
474
 	padding: 0 10px;
634
 	padding: 0 10px;
475
 }
635
 }
636
+
637
+
638
+
639
+.date-display {
640
+	padding: 10px;
641
+	border: 1px solid #e5e5e5;
642
+	border-radius: 8px;
643
+	background-color: #f7f6f6;
644
+	min-height: 44px;
645
+	display: flex;
646
+	align-items: center;
647
+}
648
+
649
+.date-text {
650
+	font-size: 14px;
651
+	color: #333333;
652
+	line-height: 1.4;
653
+}
654
+
655
+.picker-selector {
656
+	display: flex;
657
+	align-items: center;
658
+	justify-content: space-between;
659
+	padding: 10px;
660
+	border: 1px solid #e5e5e5;
661
+	border-radius: 8px;
662
+	background-color: #fff;
663
+	min-height: 44px;
664
+	box-sizing: border-box;
665
+}
666
+
667
+.picker-selector.picker-disabled {
668
+	background-color: #f7f6f6;
669
+	color: #333333;
670
+}
671
+
672
+.picker-text {
673
+	flex: 1;
674
+	font-size: 14px;
675
+	color: #333;
676
+	line-height: 1.4;
677
+}
678
+
679
+.picker-text.picker-placeholder {
680
+	color: #c0c4cc;
681
+}
476
 </style>
682
 </style>

+ 8
- 9
oa-ui-app/pages/oa/device/instrumentsList.vue View File

2
  * @Author: ysh
2
  * @Author: ysh
3
  * @Date: 2025-07-08 14:00:47
3
  * @Date: 2025-07-08 14:00:47
4
  * @LastEditors: Please set LastEditors
4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-07-08 15:50:20
5
+ * @LastEditTime: 2025-07-16 15:22:13
6
 -->
6
 -->
7
 <template>
7
 <template>
8
   <view class="device-container">
8
   <view class="device-container">
427
 
427
 
428
     handleViewLogs() {
428
     handleViewLogs() {
429
       this.closeDetailPopup();
429
       this.closeDetailPopup();
430
-      uni.navigateTo({
431
-        url: `/pages/oa/device/deviceLog?deviceId=${this.currentDevice.deviceId}`
432
-      });
430
+      
433
     },
431
     },
434
 
432
 
435
     handleAdd() {
433
     handleAdd() {
683
   align-items: center;
681
   align-items: center;
684
   padding: 15px;
682
   padding: 15px;
685
   border-bottom: 1px solid #f0f0f0;
683
   border-bottom: 1px solid #f0f0f0;
684
+  background: linear-gradient(90deg, #e0e7ff 0%, #f8fafc 100%);
686
 }
685
 }
687
 
686
 
688
 .device-info {
687
 .device-info {
744
     align-items: center;
743
     align-items: center;
745
     justify-content: center;
744
     justify-content: center;
746
     gap: 4px;
745
     gap: 4px;
747
-    padding: 12px;
746
+    padding: 5px;
748
     background: none;
747
     background: none;
749
     border: none;
748
     border: none;
750
     font-size: 13px;
749
     font-size: 13px;
806
   bottom: 30px;
805
   bottom: 30px;
807
   width: 56px;
806
   width: 56px;
808
   height: 56px;
807
   height: 56px;
809
-  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
808
+  background: #6366f1;
810
   border-radius: 50%;
809
   border-radius: 50%;
811
   display: flex;
810
   display: flex;
812
   align-items: center;
811
   align-items: center;
916
 .popup-footer {
915
 .popup-footer {
917
   display: flex;
916
   display: flex;
918
   gap: 15px;
917
   gap: 15px;
919
-  padding: 20px;
918
+  padding: 10px;
920
   border-top: 1px solid #f0f0f0;
919
   border-top: 1px solid #f0f0f0;
921
 
920
 
922
   .popup-btn {
921
   .popup-btn {
923
     flex: 1;
922
     flex: 1;
924
-    padding: 12px;
923
+    padding: 1px;
925
     border-radius: 8px;
924
     border-radius: 8px;
926
     font-size: 16px;
925
     font-size: 16px;
927
     border: none;
926
     border: none;
932
     }
931
     }
933
 
932
 
934
     &.primary {
933
     &.primary {
935
-      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
934
+      background: #6366f1;
936
       color: #fff;
935
       color: #fff;
937
     }
936
     }
938
   }
937
   }

+ 9
- 4
oa-ui/src/assets/styles/element-reset.scss View File

23
 }
23
 }
24
 
24
 
25
 // 复选框
25
 // 复选框
26
-::v-deep .el-checkbox__input.is-disabled+span.el-checkbox__label{
26
+::v-deep .el-checkbox__input.is-disabled+span.el-checkbox__label {
27
   color: #686a6e;
27
   color: #686a6e;
28
 }
28
 }
29
 
29
 
30
-::v-deep .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{
30
+::v-deep .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner {
31
   background-color: #409EFF;
31
   background-color: #409EFF;
32
   border-color: #409EFF;
32
   border-color: #409EFF;
33
 }
33
 }
34
-::v-deep .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner::after{
34
+
35
+::v-deep .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner::after {
35
   border-color: #fff;
36
   border-color: #fff;
36
 }
37
 }
37
 
38
 
38
 // 描述框
39
 // 描述框
39
-::v-deep .el-descriptions-item__label.is-bordered-label{
40
+::v-deep .el-descriptions-item__label.is-bordered-label {
40
   color: #686a6e;
41
   color: #686a6e;
41
 }
42
 }
42
 
43
 
43
 // 多选框
44
 // 多选框
44
 ::v-deep .el-tag.el-tag--info {
45
 ::v-deep .el-tag.el-tag--info {
45
   color: #535559;
46
   color: #535559;
47
+}
48
+
49
+::v-deep .el-range-editor.is-disabled input {
50
+  color: #535559;
46
 }
51
 }

+ 56
- 3
oa-ui/src/views/flowable/form/work/declareForm.vue View File

1
 <!--
1
 <!--
2
  * @Author: ysh
2
  * @Author: ysh
3
  * @Date: 2024-08-16 09:16:36
3
  * @Date: 2024-08-16 09:16:36
4
- * @LastEditors: wrh
5
- * @LastEditTime: 2025-06-09 08:51:49
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2025-07-31 09:48:58
6
 -->
6
 -->
7
 <template>
7
 <template>
8
   <div>
8
   <div>
49
             <el-input type="textarea" v-model="form.workContent" :autosize="{ minRows: 4, maxRows: 10 }"
49
             <el-input type="textarea" v-model="form.workContent" :autosize="{ minRows: 4, maxRows: 10 }"
50
               :disabled="taskName != '工作填报'"></el-input>
50
               :disabled="taskName != '工作填报'"></el-input>
51
           </el-form-item>
51
           </el-form-item>
52
+          <el-form-item label="工作日期:" prop="dateRange">
53
+            <el-date-picker v-model="form.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期"
54
+              end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd"
55
+              :disabled="taskName != '工作填报'" @change="handleDateRangeChange">
56
+            </el-date-picker>
57
+          </el-form-item>
52
           <el-form-item label="工天:" prop="workLoad">
58
           <el-form-item label="工天:" prop="workLoad">
53
             <el-input-number v-model="form.workLoad" @change="countMoney()"
59
             <el-input-number v-model="form.workLoad" @change="countMoney()"
54
               :disabled="taskName != '工作填报'"></el-input-number>
60
               :disabled="taskName != '工作填报'"></el-input-number>
158
         price: 200,
164
         price: 200,
159
         userId: undefined,
165
         userId: undefined,
160
         submitTime: undefined,
166
         submitTime: undefined,
167
+        beginDate: undefined,
168
+        endDate: undefined,
169
+        dateRange: [],
161
       },
170
       },
162
       radio: '0',
171
       radio: '0',
163
       rules: {
172
       rules: {
172
         ],
181
         ],
173
         workContent: [
182
         workContent: [
174
           { required: true, trigger: "blur", message: "请填写具体内容" },
183
           { required: true, trigger: "blur", message: "请填写具体内容" },
184
+        ],
185
+        dateRange: [
186
+          { required: true, trigger: "change", message: "请选择工作日期范围" },
175
         ]
187
         ]
176
       },
188
       },
177
       prOpen: false,
189
       prOpen: false,
198
           this.form.price = 200;
210
           this.form.price = 200;
199
           this.hasForm = true;
211
           this.hasForm = true;
200
           this.countMoney();
212
           this.countMoney();
213
+
214
+          // 设置日期范围
215
+          if (res.data.beginDate && res.data.endDate) {
216
+            this.form.dateRange = [res.data.beginDate, res.data.endDate];
217
+          }
218
+
201
           if (!res.data.projectId) {
219
           if (!res.data.projectId) {
202
             this.radio = '1'
220
             this.radio = '1'
203
           } else {
221
           } else {
241
               let approval = this.chooseProject.projectLeader;
259
               let approval = this.chooseProject.projectLeader;
242
               this.$set(this.taskForm.variables, "approval", approval);
260
               this.$set(this.taskForm.variables, "approval", approval);
243
             } else {
261
             } else {
244
-              let resData = await getUsersDeptLeader({ userId: this.form.userId }); 
262
+              let resData = await getUsersDeptLeader({ userId: this.form.userId });
245
               if (resData.data) {
263
               if (resData.data) {
246
                 this.$set(this.taskForm.variables, "approval", resData.data.userId);
264
                 this.$set(this.taskForm.variables, "approval", resData.data.userId);
247
                 this.$set(this.taskForm.variables, "skip", true);
265
                 this.$set(this.taskForm.variables, "skip", true);
377
           ],
395
           ],
378
           workContent: [
396
           workContent: [
379
             { required: true, trigger: "blur", message: "请填写具体内容" },
397
             { required: true, trigger: "blur", message: "请填写具体内容" },
398
+          ],
399
+          dateRange: [
400
+            { required: true, trigger: "change", message: "请选择工作日期范围" },
380
           ]
401
           ]
381
         }
402
         }
382
       } else {
403
       } else {
392
           ],
413
           ],
393
           workContent: [
414
           workContent: [
394
             { required: true, trigger: "blur", message: "请填写具体内容" },
415
             { required: true, trigger: "blur", message: "请填写具体内容" },
416
+          ],
417
+          dateRange: [
418
+            { required: true, trigger: "change", message: "请选择工作日期范围" },
395
           ]
419
           ]
396
         }
420
         }
397
       }
421
       }
422
+    },
423
+    handleDateRangeChange(val) {
424
+      if (val) {
425
+        this.form.beginDate = val[0];
426
+        this.form.endDate = val[1];
427
+        this.calculateWorkDays();
428
+      } else {
429
+        this.form.beginDate = undefined;
430
+        this.form.endDate = undefined;
431
+        this.form.workLoad = 1; // 如果取消选择,则重置工天为1
432
+        this.countMoney();
433
+      }
434
+    },
435
+    // 计算工天
436
+    calculateWorkDays() {
437
+      if (this.form.beginDate && this.form.endDate) {
438
+        const beginDate = new Date(this.form.beginDate);
439
+        const endDate = new Date(this.form.endDate);
440
+
441
+        if (endDate >= beginDate) {
442
+          // 计算天数差值,加1是因为要包含开始和结束日期
443
+          const timeDiff = endDate.getTime() - beginDate.getTime();
444
+          const dayDiff = Math.ceil(timeDiff / (1000 * 3600 * 24)) + 1;
445
+
446
+          this.form.workLoad = dayDiff;
447
+          // 重新计算金额
448
+          this.countMoney();
449
+        }
450
+      }
398
     }
451
     }
399
   },
452
   },
400
 }
453
 }

+ 2
- 14
oa-ui/src/views/oa/contract/index.vue View File

2
  * @Author: ysh
2
  * @Author: ysh
3
  * @Date: 2024-06-21 18:52:00
3
  * @Date: 2024-06-21 18:52:00
4
  * @LastEditors: Please set LastEditors
4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-07-24 11:09:01
5
+ * @LastEditTime: 2025-07-24 14:37:14
6
 -->
6
 -->
7
 <template>
7
 <template>
8
   <div class="app-container">
8
   <div class="app-container">
258
         listContract(this.queryParams).then(response => {
258
         listContract(this.queryParams).then(response => {
259
           this.contractList = response.rows;
259
           this.contractList = response.rows;
260
           this.total = response.total;
260
           this.total = response.total;
261
-          for (let contract of this.contractList) {
262
-            listContractPaid({ contractId: contract.contractId }).then(res => {
263
-              if (res.total > 0) {
264
-                let percentage = res.rows.reduce((sum, item) => sum + Number(item.paidPercentage), 0);
265
-                let paidAmount = res.rows.reduce((sum, item) => sum + Number(item.paidAmount), 0);
266
-                this.$set(contract, 'percentage', Number(percentage.toFixed(2)))
267
-                this.$set(contract, 'paidAmount', Number(paidAmount.toFixed(2)))
268
-              } else {
269
-                this.$set(contract, 'percentage', 0)
270
-              }
271
-              this.loading = false;
272
-            })
273
-          }
261
+          this.loading = false;
274
         });
262
         });
275
       }
263
       }
276
       else {
264
       else {

+ 2
- 14
oa-ui/src/views/oa/contract/subContract.vue View File

2
  * @Author: ysh
2
  * @Author: ysh
3
  * @Date: 2024-06-21 18:52:00
3
  * @Date: 2024-06-21 18:52:00
4
  * @LastEditors: Please set LastEditors
4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-07-24 10:39:15
5
+ * @LastEditTime: 2025-07-24 14:38:46
6
 -->
6
 -->
7
 <template>
7
 <template>
8
   <div class="app-container">
8
   <div class="app-container">
257
       listSubContract(this.queryParams).then(response => {
257
       listSubContract(this.queryParams).then(response => {
258
         this.subContractList = response.rows;
258
         this.subContractList = response.rows;
259
         this.total = response.total;
259
         this.total = response.total;
260
-        for (let subContract of this.subContractList) {
261
-          listContractPaid({ contractId: subContract.subContractId }).then(res => {
262
-            if (res.total > 0) {
263
-              let percentage = res.rows.reduce((sum, item) => sum + Number(item.paidPercentage), 0);
264
-              let paidAmount = res.rows.reduce((sum, item) => sum + Number(item.paidAmount), 0);
265
-              this.$set(subContract, 'percentage', Number(percentage.toFixed(2)));
266
-              this.$set(subContract, 'paidAmount', Number(paidAmount.toFixed(2)));
267
-            } else {
268
-              this.$set(subContract, 'percentage', 0)
269
-            }
270
-            this.loading = false;
271
-          })
272
-        }
260
+        this.loading = false;
273
       });
261
       });
274
     },
262
     },
275
     remoteMethod(val) {
263
     remoteMethod(val) {

+ 4
- 2
oa-ui/src/views/oa/declare/index.vue View File

2
  * @Author: wrh
2
  * @Author: wrh
3
  * @Date: 2024-08-14 14:24:11
3
  * @Date: 2024-08-14 14:24:11
4
  * @LastEditors: Please set LastEditors
4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-01-15 10:33:56
5
+ * @LastEditTime: 2025-07-31 10:00:14
6
 -->
6
 -->
7
 <template>
7
 <template>
8
   <div class="app-container">
8
   <div class="app-container">
54
       <el-table-column label="工作类别" align="center" prop="workType" />
54
       <el-table-column label="工作类别" align="center" prop="workType" />
55
       <el-table-column label="工作项目" align="center" prop="workItem" />
55
       <el-table-column label="工作项目" align="center" prop="workItem" />
56
       <el-table-column label="工作内容" align="center" prop="workContent" width="250px" />
56
       <el-table-column label="工作内容" align="center" prop="workContent" width="250px" />
57
+      <el-table-column label="开始日期" align="center" prop="beginDate" width="92px"/>
58
+      <el-table-column label="结束日期" align="center" prop="endDate" width="92px"/>
57
       <el-table-column label="工天" align="center" prop="workLoad" />
59
       <el-table-column label="工天" align="center" prop="workLoad" />
58
       <el-table-column label="工天单价" align="center" prop="price" />
60
       <el-table-column label="工天单价" align="center" prop="price" />
59
       <el-table-column label="系数" align="center" prop="coefficient" />
61
       <el-table-column label="系数" align="center" prop="coefficient" />
81
           </div>
83
           </div>
82
         </template>
84
         </template>
83
       </el-table-column>
85
       </el-table-column>
84
-      <el-table-column label="填报时间" align="center" prop="submitTime">
86
+      <el-table-column label="填报时间" align="center" prop="submitTime" width="92px">
85
         <template slot-scope="scope">
87
         <template slot-scope="scope">
86
           <span>{{ parseTime(scope.row.submitTime, '{y}-{m}-{d}') }}</span>
88
           <span>{{ parseTime(scope.row.submitTime, '{y}-{m}-{d}') }}</span>
87
         </template>
89
         </template>

Loading…
Cancel
Save