Commit 27a753722437d951242ce15ba1ec3754d2c61387

Authored by “wangming”
1 parent 25c153f3

Enhance attendance record detail view by adding related workflows display for le…

…ave and sick statuses. Refactor logic to determine related workflows and update UI components for better clarity. Introduce new methods for handling workflow data in the backend.
antis-ncc-admin/src/views/attendance-record/components/record-detail-dialog.vue
... ... @@ -8,7 +8,7 @@
8 8 <div class="detail-hero__title-row">
9 9 <div class="detail-hero__title">{{ detail.employeeName || '无' }}</div>
10 10 <el-tag class="detail-hero__status-tag" :type="statusTagType" effect="dark">{{ detail.statusText || '无'
11   - }}</el-tag>
  11 + }}</el-tag>
12 12 </div>
13 13 <div class="detail-hero__meta">
14 14 <span>{{ detail.attendanceDate || '无' }}</span>
... ... @@ -144,33 +144,27 @@
144 144 </div>
145 145 </el-card>
146 146  
147   - <el-card v-if="detail && detail.leaveApply" shadow="never" class="leave-apply-card">
  147 + <el-card v-if="hasRelatedWorkflows || isLeaveOrSickStatus" shadow="never" class="supplement-card workflow-card">
148 148 <div slot="header" class="supplement-card__header">
149   - <span>请假/病假流程</span>
  149 + <span>关联流程</span>
  150 + <el-button v-if="isLeaveOrSickStatus" type="danger" size="mini" :loading="cancelLoading"
  151 + :disabled="cancelLoading" style="float: right; margin-top: -4px;" @click="cancelLeave">确认销假</el-button>
150 152 </div>
151   - <div class="supplement-grid">
152   - <div class="field-item">
153   - <label>请假类型</label>
154   - <span>{{ detail.leaveApply.leaveType || '无' }}</span>
155   - </div>
156   - <div class="field-item">
157   - <label>流程单号</label>
158   - <span>{{ detail.leaveApply.billNo || '无' }}</span>
159   - </div>
160   - <div class="field-item field-item--full">
161   - <label>流程操作</label>
162   - <span class="action-link">
163   - <el-button type="text" size="mini" icon="el-icon-view" :disabled="!detail.leaveApply.id"
164   - @click="goToLeaveApply">查看申请信息</el-button>
165   - </span>
166   - </div>
167   - <div class="field-item field-item--full">
168   - <label>销假</label>
169   - <el-button type="danger" size="mini" :loading="cancelLoading"
170   - :disabled="cancelLoading || !(detail.status === 4 || detail.status === 5)"
171   - @click="cancelLeave">确认销假</el-button>
  153 + <div v-if="hasRelatedWorkflows" class="workflow-list">
  154 + <div v-for="(wf, idx) in detail.relatedWorkflows" :key="idx" class="workflow-item">
  155 + <el-tag size="mini" :type="workflowTagType(wf.type)" effect="plain" class="workflow-item__tag">
  156 + {{ wf.type }}
  157 + </el-tag>
  158 + <span v-if="wf.leaveType" class="workflow-item__leave-type">{{ wf.leaveType }}</span>
  159 + <span v-if="wf.billNo" class="workflow-item__bill">{{ wf.billNo }}</span>
  160 + <span v-if="wf.time" class="workflow-item__time">{{ wf.time }}</span>
  161 + <el-button v-if="wf.id && wf.type === '请假'" type="text" size="mini" icon="el-icon-view"
  162 + @click="goToLeaveApply(wf)">查看申请</el-button>
172 163 </div>
173 164 </div>
  165 + <div v-else class="workflow-empty">
  166 + <span>当前为{{ detail.statusText }}状态,暂无关联流程记录</span>
  167 + </div>
174 168 </el-card>
175 169 </template>
176 170  
... ... @@ -219,6 +213,12 @@ export default {
219 213 default:
220 214 return 'danger'
221 215 }
  216 + },
  217 + hasRelatedWorkflows() {
  218 + return this.detail && Array.isArray(this.detail.relatedWorkflows) && this.detail.relatedWorkflows.length > 0
  219 + },
  220 + isLeaveOrSickStatus() {
  221 + return this.detail && (this.detail.status === 4 || this.detail.status === 5)
222 222 }
223 223 },
224 224 methods: {
... ... @@ -265,33 +265,33 @@ export default {
265 265 await this.loadDetail()
266 266 this.$emit('refresh')
267 267 },
268   - goToLeaveApply() {
269   - if (!this.detail || !this.detail.leaveApply || !this.detail.leaveApply.id) return
270   - const leaveType = this.detail.leaveApply.leaveType || ''
271   - const isPersonal = leaveType === '事假' || leaveType === '病假'
  268 + workflowTagType(type) {
  269 + if (type === '请假') return 'danger'
  270 + if (type === '补卡') return 'warning'
  271 + return 'info'
  272 + },
  273 + goToLeaveApply(wf) {
  274 + if (!wf || !wf.id) return
  275 + const lt = wf.leaveType || ''
  276 + const isPersonal = lt === '事假' || lt === '病假'
272 277 const path = isPersonal ? '/workFlow/personal-leave-apply' : '/workFlow/paid-leave-apply'
273   - this.$router.push({
274   - path,
275   - query: { id: this.detail.leaveApply.id }
276   - })
  278 + this.$router.push({ path, query: { id: wf.id } })
277 279 },
278 280 async cancelLeave() {
279 281 if (!this.detail || !this.detail.id) return
280   - if (!(this.detail.status === 4 || this.detail.status === 5)) {
  282 + if (!this.isLeaveOrSickStatus) {
281 283 this.$message.warning('当前考勤记录不是请假/病假状态,无法销假')
282 284 return
283 285 }
284 286 this.cancelLoading = true
285 287 try {
286   - await this.$confirm('确定要对该考勤记录销假吗?', '提示', { type: 'warning' })
287   - await cancelAttendanceLeave({
288   - id: this.detail.id
289   - })
  288 + await this.$confirm('确定要对该考勤记录销假吗?销假后将根据打卡记录重新判定考勤状态。', '确认销假', { type: 'warning' })
  289 + await cancelAttendanceLeave({ id: this.detail.id })
290 290 this.$message.success('销假成功')
291 291 await this.loadDetail()
292 292 this.$emit('refresh')
293 293 } catch (e) {
294   - // eslint-disable-next-line no-empty
  294 + // user cancelled or api error
295 295 } finally {
296 296 this.cancelLoading = false
297 297 }
... ... @@ -496,6 +496,53 @@ export default {
496 496 grid-column: 1 / -1;
497 497 }
498 498  
  499 +.workflow-card {
  500 + margin-top: 16px;
  501 +}
  502 +
  503 +.workflow-list {
  504 + display: flex;
  505 + flex-direction: column;
  506 + gap: 10px;
  507 +}
  508 +
  509 +.workflow-item {
  510 + display: flex;
  511 + align-items: center;
  512 + gap: 10px;
  513 + padding: 8px 12px;
  514 + border-radius: 8px;
  515 + background: #f8f9fb;
  516 + font-size: 13px;
  517 +}
  518 +
  519 +.workflow-item__tag {
  520 + flex-shrink: 0;
  521 +}
  522 +
  523 +.workflow-item__leave-type {
  524 + color: #606266;
  525 + font-weight: 500;
  526 +}
  527 +
  528 +.workflow-item__bill {
  529 + color: #409eff;
  530 + font-family: monospace;
  531 +}
  532 +
  533 +.workflow-item__time {
  534 + color: #909399;
  535 + font-size: 12px;
  536 + margin-left: auto;
  537 +}
  538 +
  539 +.workflow-empty {
  540 + color: #909399;
  541 + font-size: 13px;
  542 + text-align: center;
  543 + padding: 12px 0;
  544 +}
  545 +
499 546 @media (max-width: 960px) {
500 547  
501 548 .overview-grid,
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqAttendanceRecord/RelatedWorkflowItem.cs 0 → 100644
  1 +namespace NCC.Extend.Entitys.Dto.LqAttendanceRecord
  2 +{
  3 + /// <summary>
  4 + /// 考勤记录关联流程项(存储在 F_RelatedWorkflowsJson 字段中的数组元素)
  5 + /// </summary>
  6 + public class RelatedWorkflowItem
  7 + {
  8 + /// <summary>
  9 + /// 流程类型:请假 | 补卡
  10 + /// </summary>
  11 + public string type { get; set; }
  12 +
  13 + /// <summary>
  14 + /// 流程/表单主键(WFORM_LEAVEAPPLY.F_Id 等)
  15 + /// </summary>
  16 + public string id { get; set; }
  17 +
  18 + /// <summary>
  19 + /// 单号(如 YGQJ-202604020008)
  20 + /// </summary>
  21 + public string billNo { get; set; }
  22 +
  23 + /// <summary>
  24 + /// 假种(仅请假类型有值,如"年假"/"事假"/"病假")
  25 + /// </summary>
  26 + public string leaveType { get; set; }
  27 +
  28 + /// <summary>
  29 + /// 备注
  30 + /// </summary>
  31 + public string remark { get; set; }
  32 +
  33 + /// <summary>
  34 + /// 写入时间
  35 + /// </summary>
  36 + public string time { get; set; }
  37 + }
  38 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_attendance_record/LqAttendanceRecordEntity.cs
... ... @@ -240,6 +240,12 @@ namespace NCC.Extend.Entitys.lq_attendance_record
240 240 public DateTime? UpdateTime { get; set; }
241 241  
242 242 /// <summary>
  243 + /// 关联流程JSON(所有与该考勤记录关联的流程信息,含请假/补卡等)
  244 + /// </summary>
  245 + [SugarColumn(ColumnName = "F_RelatedWorkflowsJson", ColumnDataType = "longtext")]
  246 + public string RelatedWorkflowsJson { get; set; }
  247 +
  248 + /// <summary>
243 249 /// 是否有效(1-有效,0-无效)
244 250 /// </summary>
245 251 [SugarColumn(ColumnName = "F_IsEffective")]
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqAttendanceRecordService.cs
... ... @@ -25,6 +25,7 @@ using NCC.Extend.Entitys.lq_attendance_missing_card_rule;
25 25 using NCC.Extend.Entitys.lq_attendance_record;
26 26 using NCC.Extend.Entitys.lq_attendance_setting;
27 27 using NCC.Extend.Entitys.lq_mdxx;
  28 +using NCC.Extend.Entitys.wform_leaveapply;
28 29 using NCC.Extend.Interfaces.LqAttendanceRecord;
29 30 using NCC.FriendlyException;
30 31 using Newtonsoft.Json;
... ... @@ -361,24 +362,41 @@ namespace NCC.Extend
361 362 record = recalculated.FirstOrDefault() ?? record;
362 363 var group = await GetAttendanceGroupAsync(record.AttendanceGroupId, false);
363 364  
364   - // 如果当前状态来自“请假/病假同步写入”,则尝试从 Remark 中解析单号并反查请假单信息,便于在考勤详情中跳转流程/操作销假
365   - string leaveApplyId = null;
366   - string leaveApplyBillNo = null;
367   - string leaveApplyType = null;
  365 + var relatedWorkflows = ParseRelatedWorkflows(record.RelatedWorkflowsJson);
368 366  
369   - if (TryParseLeaveApplyFromSyncRemark(record.Remark, out var parsedLeaveType, out var parsedBillNo)
  367 + var isLeaveStatus = record.Status == (int)AttendanceRecordStatusEnum.请假
  368 + || record.Status == (int)AttendanceRecordStatusEnum.病假;
  369 + if (!relatedWorkflows.Any(x => x.type == "请假") && isLeaveStatus
  370 + && TryParseLeaveApplyFromSyncRemark(record.Remark, out var parsedLeaveType, out var parsedBillNo)
370 371 && !string.IsNullOrWhiteSpace(parsedBillNo))
371 372 {
372   - leaveApplyBillNo = parsedBillNo;
373   - leaveApplyType = parsedLeaveType;
374   - var leaveApply = await _db.Queryable<NCC.Extend.Entitys.wform_leaveapply.WformLeaveApplyEntityLite>()
  373 + var leaveApply = await _db.Queryable<WformLeaveApplyEntityLite>()
375 374 .Where(x => x.BillNo == parsedBillNo)
376 375 .WhereIF(!string.IsNullOrWhiteSpace(parsedLeaveType), x => x.LeaveType == parsedLeaveType)
377 376 .FirstAsync();
378   - leaveApplyId = leaveApply?.Id;
  377 +
  378 + relatedWorkflows.Add(new RelatedWorkflowItem
  379 + {
  380 + type = "请假",
  381 + id = leaveApply?.Id,
  382 + billNo = parsedBillNo,
  383 + leaveType = parsedLeaveType,
  384 + remark = record.Remark
  385 + });
  386 + }
  387 +
  388 + if (!string.IsNullOrWhiteSpace(record.SupplementWorkflowId) && !relatedWorkflows.Any(x => x.type == "补卡"))
  389 + {
  390 + relatedWorkflows.Add(new RelatedWorkflowItem
  391 + {
  392 + type = "补卡",
  393 + id = record.SupplementWorkflowId,
  394 + remark = record.SupplementRemark,
  395 + time = record.SupplementTime?.ToString("yyyy-MM-dd HH:mm:ss")
  396 + });
379 397 }
380 398  
381   - return BuildDetailResult(record, group, leaveApplyId, leaveApplyBillNo, leaveApplyType);
  399 + return BuildDetailResult(record, group, relatedWorkflows);
382 400 }
383 401  
384 402 /// <summary>
... ... @@ -411,13 +429,8 @@ namespace NCC.Extend
411 429 throw NCCException.Oh("当前考勤记录不是请假/病假状态,无法销假");
412 430 }
413 431  
414   - // 通过 Remark 解析请假单信息(用于展示与记录销假备注)
415   - if (!TryParseLeaveApplyFromSyncRemark(record.Remark, out var leaveType, out var billNo))
416   - {
417   - throw NCCException.Oh("请假备注格式不正确,无法解析销假所需信息");
418   - }
  432 + TryParseLeaveApplyFromSyncRemark(record.Remark, out var leaveType, out var billNo);
419 433  
420   - // 撤销对该日期的请假影响:根据假期/免考勤/打卡情况,把该日期恢复为“休息/正常/缺卡”等对应考勤状态
421 434 var attendanceDate = record.AttendanceDate.Date;
422 435 var isHoliday = await IsHolidayAsync(attendanceDate);
423 436 var isExempt = await IsExemptAsync(record.UserId, attendanceDate);
... ... @@ -445,13 +458,12 @@ namespace NCC.Extend
445 458 record.LateMinutes = 0;
446 459 record.EarlyLeaveMinutes = 0;
447 460 record.IsManual = 1;
448   - var cancelText = string.IsNullOrWhiteSpace(input.OperatorOpinion)
449   - ? "已销假"
450   - : input.OperatorOpinion.Trim();
451   - // 保留原 Remark 前缀,便于在考勤详情中仍能反查到对应请假单信息
452   - record.Remark = $"请假审批通过:{leaveType}(单号 {billNo});销假:{cancelText}";
453   -
454   - // 置空快照,确保 RecalculateRecordStatusesAsync 会重新生成规则快照
  461 + var cancelText = string.IsNullOrWhiteSpace(input.OperatorOpinion) ? "已销假" : input.OperatorOpinion.Trim();
  462 + var hasLeaveInfo = !string.IsNullOrWhiteSpace(leaveType) && !string.IsNullOrWhiteSpace(billNo);
  463 + record.Remark = hasLeaveInfo
  464 + ? $"请假审批通过:{leaveType}(单号 {billNo});销假:{cancelText}"
  465 + : $"销假:{cancelText}";
  466 + record.RuleSnapshotJson = null;
455 467 record.RuleSnapshotJson = null;
456 468 record.AllRuleSnapshotJson = null;
457 469  
... ... @@ -616,6 +628,17 @@ namespace NCC.Extend
616 628 record.UpdateUserId = operatorUserId;
617 629 record.UpdateTime = record.SupplementTime;
618 630  
  631 + if (!string.IsNullOrWhiteSpace(input.WorkflowId))
  632 + {
  633 + record.RelatedWorkflowsJson = AppendRelatedWorkflow(record.RelatedWorkflowsJson, new RelatedWorkflowItem
  634 + {
  635 + type = "补卡",
  636 + id = input.WorkflowId.Trim(),
  637 + remark = input.Remark?.Trim(),
  638 + time = record.SupplementTime?.ToString("yyyy-MM-dd HH:mm:ss")
  639 + });
  640 + }
  641 +
619 642 await _db.Updateable(record).ExecuteCommandAsync();
620 643  
621 644 return new
... ... @@ -1418,10 +1441,9 @@ namespace NCC.Extend
1418 1441 private static dynamic BuildDetailResult(
1419 1442 LqAttendanceRecordEntity record,
1420 1443 LqAttendanceGroupEntity group,
1421   - string leaveApplyId = null,
1422   - string leaveApplyBillNo = null,
1423   - string leaveApplyType = null)
  1444 + List<RelatedWorkflowItem> relatedWorkflows = null)
1424 1445 {
  1446 + var workflows = relatedWorkflows ?? new List<RelatedWorkflowItem>();
1425 1447 return new
1426 1448 {
1427 1449 id = record.Id,
... ... @@ -1472,14 +1494,15 @@ namespace NCC.Extend
1472 1494 operateTime = record.SupplementTime?.ToString("yyyy-MM-dd HH:mm:ss"),
1473 1495 workflowId = record.SupplementWorkflowId
1474 1496 },
1475   - leaveApply = string.IsNullOrWhiteSpace(leaveApplyId)
1476   - ? null
1477   - : new
1478   - {
1479   - id = leaveApplyId,
1480   - billNo = leaveApplyBillNo,
1481   - leaveType = leaveApplyType
1482   - },
  1497 + relatedWorkflows = workflows.Select(w => new
  1498 + {
  1499 + w.type,
  1500 + w.id,
  1501 + w.billNo,
  1502 + w.leaveType,
  1503 + w.remark,
  1504 + w.time
  1505 + }).ToList(),
1483 1506 ruleSnapshotJson = record.RuleSnapshotJson,
1484 1507 allRuleSnapshotJson = record.AllRuleSnapshotJson
1485 1508 };
... ... @@ -2263,6 +2286,35 @@ namespace NCC.Extend
2263 2286 return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
2264 2287 }
2265 2288  
  2289 + private static List<RelatedWorkflowItem> ParseRelatedWorkflows(string json)
  2290 + {
  2291 + if (string.IsNullOrWhiteSpace(json))
  2292 + {
  2293 + return new List<RelatedWorkflowItem>();
  2294 + }
  2295 +
  2296 + try
  2297 + {
  2298 + return JsonConvert.DeserializeObject<List<RelatedWorkflowItem>>(json) ?? new List<RelatedWorkflowItem>();
  2299 + }
  2300 + catch
  2301 + {
  2302 + return new List<RelatedWorkflowItem>();
  2303 + }
  2304 + }
  2305 +
  2306 + private static string AppendRelatedWorkflow(string existingJson, RelatedWorkflowItem item)
  2307 + {
  2308 + var list = ParseRelatedWorkflows(existingJson);
  2309 + if (!string.IsNullOrWhiteSpace(item.id))
  2310 + {
  2311 + list.RemoveAll(x => x.id == item.id && x.type == item.type);
  2312 + }
  2313 +
  2314 + list.Add(item);
  2315 + return JsonConvert.SerializeObject(list);
  2316 + }
  2317 +
2266 2318 private sealed class AttendanceStatusContext
2267 2319 {
2268 2320 public int Status { get; set; }
... ...
netcore/src/Modularity/WorkFlow/NCC.WorkFlow/WorkFlowForm/LeaveApplyService.cs
... ... @@ -16,6 +16,7 @@ using NCC.Extend.Entitys.lq_mdxx;
16 16 using NCC.FriendlyException;
17 17 using NCC.JsonSerialization;
18 18 using NCC.System.Entitys.Permission;
  19 +using Newtonsoft.Json;
19 20 using NCC.System.Interfaces.System;
20 21 using NCC.WorkFlow.Entitys;
21 22 using NCC.WorkFlow.Entitys.Dto.WorkFlowForm.LeaveApply;
... ... @@ -883,6 +884,36 @@ LIMIT 1&quot;;
883 884 }
884 885 return count;
885 886 }
  887 +
  888 + /// <summary>
  889 + /// 将新的请假流程项追加到已有的 RelatedWorkflowsJson(去重后返回新 JSON)
  890 + /// </summary>
  891 + private static string AppendLeaveWorkflow(string existingJson, string newItemArrayJson)
  892 + {
  893 + List<object> list;
  894 + try
  895 + {
  896 + list = string.IsNullOrWhiteSpace(existingJson)
  897 + ? new List<object>()
  898 + : JsonConvert.DeserializeObject<List<object>>(existingJson) ?? new List<object>();
  899 + }
  900 + catch
  901 + {
  902 + list = new List<object>();
  903 + }
  904 +
  905 + try
  906 + {
  907 + var newItems = JsonConvert.DeserializeObject<List<object>>(newItemArrayJson) ?? new List<object>();
  908 + list.AddRange(newItems);
  909 + }
  910 + catch
  911 + {
  912 + // ignore
  913 + }
  914 +
  915 + return JsonConvert.SerializeObject(list);
  916 + }
886 917 #endregion
887 918  
888 919 #region PublicMethod
... ... @@ -987,6 +1018,11 @@ LIMIT 1&quot;;
987 1018 .ToListAsync();
988 1019 var existing = existingList.FirstOrDefault();
989 1020  
  1021 + var workflowItemJson = JsonConvert.SerializeObject(new[]
  1022 + {
  1023 + new { type = "请假", id = leave.Id, billNo = leave.BillNo ?? "", leaveType, remark, time = now.ToString("yyyy-MM-dd HH:mm:ss") }
  1024 + });
  1025 +
990 1026 if (existing != null)
991 1027 {
992 1028 existing.Status = status;
... ... @@ -1001,6 +1037,7 @@ LIMIT 1&quot;;
1001 1037 existing.AttendanceGroupName = group?.GroupName;
1002 1038 existing.RuleSnapshotJson = "{}";
1003 1039 existing.AllRuleSnapshotJson = "{}";
  1040 + existing.RelatedWorkflowsJson = AppendLeaveWorkflow(existing.RelatedWorkflowsJson, workflowItemJson);
1004 1041 existing.UpdateUserId = operatorId;
1005 1042 existing.UpdateTime = now;
1006 1043 await _sqlSugarRepository.Context.Updateable(existing).ExecuteCommandAsync();
... ... @@ -1024,6 +1061,7 @@ LIMIT 1&quot;;
1024 1061 Remark = remark,
1025 1062 RuleSnapshotJson = "{}",
1026 1063 AllRuleSnapshotJson = "{}",
  1064 + RelatedWorkflowsJson = workflowItemJson,
1027 1065 CreateUserId = operatorId,
1028 1066 CreateTime = now,
1029 1067 UpdateUserId = operatorId,
... ...
项目文档相关/docs/数据库说明.md
... ... @@ -168,6 +168,7 @@
168 168 - `F_SupplementRemark`: 补卡备注
169 169 - `F_SupplementOperatorId` / `F_SupplementOperatorName` / `F_SupplementTime`: 补卡操作信息
170 170 - `F_SupplementWorkflowId`: 关联补卡流程ID(可空)
  171 + - `F_RelatedWorkflowsJson`: 关联流程 JSON(数组,记录与该日考勤相关的请假/补卡等流程,含类型、表单主键、单号、假种等,便于详情展示与追溯)
171 172 - **索引说明**:
172 173 - `uk_attendance_record_user_date`: 保证同一员工同一天只有一条有效记录
173 174 - `idx_attendance_record_month_group`: 支持按月份、分组快速查询月度矩阵
... ...
项目文档相关/sql/2026-3-23/创建考勤设置相关表.sql
... ... @@ -225,6 +225,7 @@ CREATE TABLE IF NOT EXISTS `lq_attendance_record` (
225 225 `F_SupplementOperatorName` varchar(100) DEFAULT NULL COMMENT '补卡操作人姓名',
226 226 `F_SupplementTime` datetime DEFAULT NULL COMMENT '补卡操作时间',
227 227 `F_SupplementWorkflowId` varchar(50) DEFAULT NULL COMMENT '关联补卡流程ID',
  228 + `F_RelatedWorkflowsJson` longtext COMMENT '关联流程JSON(所有与该考勤记录关联的流程信息,含请假/补卡等)',
228 229 `F_CreateUserId` varchar(50) DEFAULT NULL COMMENT '创建人ID',
229 230 `F_CreateTime` datetime DEFAULT NULL COMMENT '创建时间',
230 231 `F_UpdateUserId` varchar(50) DEFAULT NULL COMMENT '更新人ID',
... ...
项目文档相关/sql/2026-3-25/考勤相关表全量重建.sql
... ... @@ -325,6 +325,7 @@ CREATE TABLE `lq_attendance_record` (
325 325 `F_SupplementOperatorName` varchar(100) DEFAULT NULL COMMENT '补卡操作人姓名',
326 326 `F_SupplementTime` datetime DEFAULT NULL COMMENT '补卡操作时间',
327 327 `F_SupplementWorkflowId` varchar(50) DEFAULT NULL COMMENT '关联补卡流程ID',
  328 + `F_RelatedWorkflowsJson` longtext COMMENT '关联流程JSON(所有与该考勤记录关联的流程信息,含请假/补卡等)',
328 329 `F_CreateUserId` varchar(50) DEFAULT NULL COMMENT '创建人ID',
329 330 `F_CreateTime` datetime DEFAULT NULL COMMENT '创建时间',
330 331 `F_UpdateUserId` varchar(50) DEFAULT NULL COMMENT '更新人ID',
... ...
项目文档相关/sql/2026-4-2/考勤记录_新增关联流程JSON字段.sql 0 → 100644
  1 +-- 考勤记录新增关联流程JSON字段:存储所有与该考勤记录关联的流程信息(请假/补卡等)
  2 +-- 执行时间:2026-04-02
  3 +-- 影响表:lq_attendance_record
  4 +
  5 +ALTER TABLE lq_attendance_record
  6 +ADD COLUMN F_RelatedWorkflowsJson LONGTEXT NULL COMMENT '关联流程JSON(所有与该考勤记录关联的流程信息,含请假/补卡等)';
... ...