<template>
  <div class="flow-detail-container">
    <template v-if="!flowInstance || !flowInstance.instanceId">
      <div class="flow-empty-detail-box">
        <a-empty />
      </div>
    </template>
    <template v-else>
      <div class="flow-status-stamp">
        <flow-status-stamp :status="flowInstance.instanceState" :size="120" />
      </div>
      <!-- 基本信息 -->
      <div class="flow-header-box">
        <div class="flow-no">编号：{{ flowInstance.instanceId }}</div>
        <div class="action-area">
          <!-- Placeholder for action items like print -->
        </div>
      </div>
      <!-- 流程详情 -->
      <div class="flow-detail-box">
        <div class="header-box">
          <div class="summary-info">
            <div class="title">{{ flowInstance.processName }}</div>
            <div class="status">
              <a-tag
                v-if="flowInstance.instanceState == STATUS_LIST[0].value"
                color="blue"
              >
                {{ STATUS_LIST[0].name }}
              </a-tag>
              <a-tag
                v-else-if="flowInstance.instanceState == STATUS_LIST[1].value"
                color="green"
              >
                {{ STATUS_LIST[1].name }}
              </a-tag>
              <a-tag
                v-else-if="flowInstance.instanceState == STATUS_LIST[2].value"
                color="red"
              >
                {{ STATUS_LIST[2].name }}
              </a-tag>
              <a-tag
                v-else-if="flowInstance.instanceState == STATUS_LIST[3].value"
                color="orange"
              >
                {{ STATUS_LIST[3].name }}
              </a-tag>
              <a-tag
                v-else-if="flowInstance.instanceState == STATUS_LIST[4].value"
                color="orange"
              >
                {{ STATUS_LIST[4].name }}
              </a-tag>
              <a-tag
                v-else-if="flowInstance.instanceState == STATUS_LIST[5].value"
                color="red"
              >
                {{ STATUS_LIST[5].name }}
              </a-tag>
            </div>
          </div>
          <div class="initiator-info">
            <flow-node-avatar
              :size="24"
              :user-id="flowInstance.startUser.id"
              :set-type="flowInstance.setType || 1"
            />
            <div class="start-time">{{ dayjs(flowInstance.startTime).format('YYYY-MM-DD HH:mm:ss') }} 提交</div>
          </div>
        </div>
        <a-divider />
        <!-- 表单数据 -->
        <flow-from-detail :form-data="instanceForm.formData" :form-items="instanceForm.formItems" />
        <a-divider />
        <!-- 审批流程时间线 -->
        <div class="flow-box">
          <a-timeline>
            <a-timeline-item v-for="action in flowActions" :key="action.id" class="custom-timeline-item">
              <template #dot>
                <div class="assignee-container">
                  <div v-if="action.underway">
                    <a-avatar v-if="action.type == 1" size="default" style="background-color: #1890ff">
                      <i class="x-iconfont x-icon-stamp" style="font-size: 20px"></i>
                    </a-avatar>
                    <a-avatar v-else size="default" style="background-color: #926bd5">
                      <i class="x-iconfont x-icon-edit" style="font-size: 20px"></i>
                    </a-avatar>
                    <div class="badge x-iconfont x-icon-underway" style="color: #2a5eff"></div>
                  </div>
                  <div v-else-if="[ACTION.COPY].includes(action.actionType)">
                    <a-avatar size="default" style="background-color: #1890ff">
                      <i class="x-iconfont x-icon-promotion" style="font-size: 20px"></i>
                    </a-avatar>
                    <div class="badge x-iconfont x-icon-success" style="color: #52c41a"></div>
                  </div>
                  <div v-else-if="[ACTION.APPROVED].includes(action.actionType)">
                    <flow-node-avatar
                      :size="36"
                      :user-id="action.auditorId"
                      :show-name="false"
                      :set-type="action.setType || 1"
                    />
                    <div class="badge x-iconfont x-icon-success" style="color: #52c41a"></div>
                  </div>
                  <div v-else-if="[ACTION.REJECTED].includes(action.actionType)">
                    <flow-node-avatar
                      :size="36"
                      :user-id="action.auditorId"
                      :show-name="false"
                      :set-type="action.setType || 1"
                    />
                    <div class="badge x-iconfont x-icon-error" style="color: #f56c6c"></div>
                  </div>
                  <div v-else-if="[ACTION.AUTO_APPROVED].includes(action.actionType)">
                    <a-avatar size="default" style="background-color: #1890ff">
                      <i class="x-iconfont x-icon-robot" style="font-size: 20px"></i>
                    </a-avatar>
                    <div class="badge x-iconfont x-icon-success" style="color: #52c41a"></div>
                  </div>
                  <div v-else-if="[ACTION.AUTO_REJECTED].includes(action.actionType)">
                    <a-avatar size="default" style="background-color: #1890ff">
                      <i class="x-iconfont x-icon-robot" style="font-size: 20px"></i>
                    </a-avatar>
                    <div class="badge x-iconfont x-icon-error" style="color: #f56c6c"></div>
                  </div>
                  <div v-else>
                    <flow-node-avatar
                      :size="36"
                      :user-id="action.auditorId"
                      :show-name="false"
                      :set-type="action.setType || 1"
                    />
                    <div class="badge x-iconfont x-icon-success" style="color: #52c41a"></div>
                  </div>
                </div>
              </template>
              <div class="audit-record">
                <div class="avatar sgement">
                  <div class="node-name">
                    <template v-if="action.actionType === ACTION.START">提交</template>
                    <template
                      v-else-if="
                        [ACTION.APPROVED, ACTION.REJECTED, ACTION.AUTO_APPROVED, ACTION.AUTO_REJECTED].includes(
                          action.actionType
                        )
                      "
                    >
                      审批
                    </template>
                    <template v-else-if="action.actionType === ACTION.CANCELED">撤销</template>
                    <template v-else-if="action.actionType === ACTION.ASSIGN">转交</template>
                    <template v-else-if="action.actionType === ACTION.BACK">回退</template>
                    <template v-else-if="action.actionType === ACTION.ADD_BEFORE_SIGN">前加签</template>
                    <template v-else-if="action.actionType === ACTION.ADD_AFTER_SIGN">后加签</template>
                    <template v-else-if="action.actionType === ACTION.ADD_SIGN">并加签</template>
                    <template v-else-if="action.actionType === ACTION.DEL_SIGN">减签</template>
                    <template v-else-if="action.actionType === ACTION.COPY">抄送</template>
                    <template v-else-if="action.actionType === ACTION.COMMENT">评论</template>
                    <template v-else-if="action.actionType === ACTION.TRANSACT">办理</template>
                    <template v-else-if="action.underway">
                      <div class="in-approval">
                        <template v-if="action.type === 1">审批中...</template>
                        <template v-else>办理中...</template>
                      </div>
                    </template>
                  </div>
                  <!-- 审批人姓名 -->
                  <div class="auditor-name">
                    <template v-if="action.underway">
                      <div class="node-sign-type">
                        <template v-if="action.examineMode === 3 || action.nodeAssigneeList.length === 1">
                          <span>只需一人审批同意</span>
                        </template>
                        <template v-else-if="action.examineMode === 2 || action.examineMode === 1">
                          <span>需所有人审批同意</span>
                        </template>
                        <template v-else-if="action.examineMode === 4">
                          <span>需总权重大于50%</span>
                        </template>
                      </div>
                      <div class="node-assignee">
                        <flow-node-avatar
                          v-for="userId in action.userIds"
                          :size="20"
                          :user-id="userId"
                          :set-type="action.setType || 1"
                          class="assignee-item"
                        />
                      </div>
                    </template>
                    <template v-else>
                      <template v-if="action.actionType === ACTION.COPY">
                        <div class="node-assignee">
                          <flow-node-avatar
                            v-for="userId in action.userIds"
                            :key="userId"
                            :size="20"
                            :user-id="userId"
                            :set-type="action.setType || 1"
                            class="assignee-item"
                          />
                        </div>
                      </template>
                      <template v-else>
                        <div class="assignee-name">
                          <flow-user-name :user-id="action.auditorId" />
                        </div>
                        <div class="node-sign-assignee">
                          <template v-if="[ACTION.ADD_BEFORE_SIGN, ACTION.ADD_AFTER_SIGN, ACTION.ADD_SIGN].includes(action.actionType)">
                            加签
                            <div class="node-sign-assignee-name">
                              <flow-user-name :user-id="action.assigneeId" />
                            </div>
                          </template>
                          <template v-else-if="[ACTION.DEL_SIGN].includes(action.actionType)">
                            减签
                            <div class="node-sign-assignee-name">
                              <flow-user-name :user-id="action.assigneeId" />
                            </div>
                          </template>
                          <template v-else-if="[ACTION.ASSIGN].includes(action.actionType)">
                            转交给
                            <div class="node-sign-assignee-name">
                              <flow-user-name :user-id="action.assigneeId" />
                            </div>
                          </template>
                        </div>
                      </template>
                    </template>
                  </div>
                  <div v-if="action.comment" class="comment">
                    <div class="comment-content">
                      {{ action.comment }}
                    </div>
                    <div class="comment-attachment">
                      <div
                        v-for="attachment in action.attachments"
                        :key="attachment.id"
                        class="comment-attachment-item"
                      >
                        <div class="name">
                          <i class="x-iconfont x-icon-file" style="font-size: 16px"></i>
                          {{ attachment ? attachment.fileName : '' }}
                        </div>
                        <div class="download-icon">
                          <a class="link" @click.prevent.stop="onAttachmentDownload(attachment, $event)">
                            <i class="x-iconfont x-icon-download" style="font-size: 16px"></i>
                          </a>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div style="font-size: 12px;margin-left: -5px">{{ action.createTime }}</div>
                </div>
              </div>
            </a-timeline-item>
          </a-timeline>
        </div>
      </div>
      <!-- 底部操作栏 -->
      <div class="flow-actions">
        <template v-if="commentable">
          <a-button size="small" @click="onComment">
            <i class="x-iconfont x-icon-message text-gray-600"></i>
            <span class="text-gray-600">评论</span>
          </a-button>
        </template>
        <template v-if="!finished && actionable">
          <template v-if="currentNodeInfo.type === 1">
            <a-button type="primary" size="small" @click="onApproved">
              <i class="x-iconfont x-icon-check"></i>
              同意
            </a-button>
            <a-button type="danger" size="small" @click="onRejected">
              <i class="x-iconfont x-icon-close"></i>
              拒绝
            </a-button>
          </template>
        </template>
        <template v-if="!finished && cancelable">
          <a-button size="small" @click="onCanceled">
            <i class="x-iconfont x-icon-undo text-gray-600"></i>
            <span class="text-gray-600">撤销</span>
          </a-button>
        </template>
        <template v-if="canResubmit">
          <a-button type="primary" size="small" @click="onResubmit">
            <i class="x-iconfont x-icon-refresh"></i>
            重新提交
          </a-button>
        </template>
        <a-dropdown v-if="moreOptions.length > 0 && !finished && actionable" :trigger="['click']">
          <a-button size="small" @click="toggleMoreOptions">
            <i
              class="x-iconfont text-gray-600"
              :class="showMoreOptions ? 'x-icon-arrow-up' : 'x-icon-arrow-down'"
            ></i>
            <span class="text-gray-600">更多</span>
          </a-button>
          <a-menu slot="overlay" @click="onMoreOptionsSelect">
            <a-menu-item v-for="option in moreOptions" :key="option.key">
              <i :class="moreIcon(option)" style="margin-right: 8px"></i>
              {{ option.label }}
            </a-menu-item>
          </a-menu>
        </a-dropdown>
      </div>
      <!-- 操作弹窗 -->
      <a-modal
        :visible="modalConfig.show"
        :title="modalConfig.title"
        :width="600"
        :body-style="{ padding: '10px 25px' }"
        @cancel="onHandleModelCancel"
      >
        <a-form-model
          ref="formRef"
          :model="modalConfig.formData"
          :rules="rules"
          :label-col="{ span: 4 }"
          :wrapper-col="{ span: 20 }"
        >
          <a-form-model-item
            :label="handleModelCommentLabel(modalConfig.type)"
            name="comment"
            :required="modalConfig.type === ACTION.COMMENT"
          >
            <a-textarea
              v-model="modalConfig.formData.comment"
              :max-length="64"
              show-count
              allow-clear
              :rows="2"
              :placeholder="`请输入${handleModelCommentLabel(modalConfig.type)}`"
            />
          </a-form-model-item>
          <a-form-model-item label="附件" name="attachments">
            <a-upload
              :action="fileUploadUrl"
              :headers="headers"
              :multiple="true"
              :max-count="3"
              :data="{}"
              @change="uploadFinishHandle"
            >
              <a-button>
                <i class="x-iconfont x-icon-attachment"></i>
                上传
              </a-button>
            </a-upload>
          </a-form-model-item>
        </a-form-model>
        <div slot="footer" class="flex justify-end space-x-3">
          <a-button size="small" @click="onHandleModelCancel">取消</a-button>
          <a-button type="primary" size="small" @click="onHandleModelOK">提交</a-button>
        </div>
      </a-modal>
      <!-- 重新提交弹窗 -->
      <a-modal
        :visible="showResubmitModal"
        title="重新提交"
        :width="600"
        :body-style="{ padding: '10px 25px' }"
        @cancel="() => (showResubmitModal = false)"
      >
        <flow-from-detail
          :form-data="resubmitFormData"
          :form-items="instanceForm.formItems"
          :editable="true"
          @update:formData="val => resubmitFormData = val"
        />
        <div slot="footer" class="flex justify-end space-x-3">
          <a-button size="small" @click="() => (showResubmitModal = false)">取消</a-button>
          <a-button type="primary" size="small" :loading="submitting" @click="onResubmitSubmit">提交</a-button>
        </div>
      </a-modal>
    </template>
  </div>
</template>

<script>
import dayjs from 'dayjs';
import FlowStatusStamp from '@/views/workFlow/workspace/component/flowStatusStamp.vue';
import FlowNodeAvatar from '@/views/workFlow/workspace/component/flowNodeAvatar.vue';
import FlowFromDetail from '@/views/workFlow/workspace/component/flowFormDetail.vue';
import FlowUserName from '@/views/workFlow/workspace/component/flowUserName.vue';
import { ACTION, STATUS_LIST } from '@/views/workFlow/common/flowConstant';
import { getAction, postAction } from '@api/manage'

export default {
  name: 'FlowDetail',
  components: {
    FlowStatusStamp,
    FlowNodeAvatar,
    FlowFromDetail,
    FlowUserName
  },
  model: {
    prop: 'flowInstance',
    event: 'input'
  },
  props: {
    flowInstance: {
      type: Object,
      default: () => ({})
    },
    cancelable: {
      type: Boolean,
      default: false
    },
    commentable: {
      type: Boolean,
      default: true
    },
    actionable: {
      type: Boolean,
      default: false
    },
    editable: {
      type: Boolean,
      default: false
    }
  },
  data() {
    const userAuth = this.$store.state;
    let validatePass = (rule,value,callback) => {
      if (this.modalConfig.type == ACTION.COMMENT && !value) {
        callback(new Error(`请输入${this.handleModelCommentLabel(this.modalConfig.type)}`));
      } else {
        callback(); // 校验通过
      }
    };
    return {
      dayjs,
      ACTION,
      STATUS_LIST,
      fileUploadUrl: 'sys/upload/uploadMinioNew',
      headers: {
        token: userAuth.token,
        tanentId: userAuth.tenantid
      },
      flowActions: [],
      currentNodeInfo: {},
      showMoreOptions: false,
      moreOptions: [],
      modalConfig: {
        show: false,
        title: '',
        type: 0,
        formData: {
          instanceId: null,
          taskId: '',
          actionType: 0,
          assigneeId: null,
          comment: null,
          attachments: []
        }
      },
      instanceForm: {
        formData: {},
        formItems: []
      },
      rules: {
        comment: [
          {
            validator: validatePass,
            message: () => `请输入${this.handleModelCommentLabel(this.modalConfig.type)}`,
            trigger: 'blur'
          }
        ]
      },
      showResubmitModal: false,
      resubmitFormData: {},
      submitting: false
    };
  },
  computed: {
    finished() {
      return this.flowInstance.instanceState != 0;
    },
    canResubmit() {
      return (
        !this.finished &&
        this.currentNodeInfo.type == 0 &&
        this.$store.state.info.id == this.flowInstance.startUser.id
      );
    },
  },
  watch: {
    flowInstance: {
      handler() {
        console.log("******",this.flowInstance)
        if (this.flowInstance && this.flowInstance.instanceId && this.flowInstance.processId) {
          this.loadData();
        }
      },
      deep: true
    }
  },
  methods: {
    uploadFinishHandle({ file }) {
      if (file.status === 'done') {
        const resp = file.response;
        this.modalConfig.formData.attachments.push(resp.data.id);
      }
    },
    onAttachmentDownload(attachment, evt) {
      console.log("*****************attachment",attachment)
      evt.stopPropagation();
      window.open(`${this.baseURL}/api/oss/file/${attachment.id}?download=true`, '_blank');
    },
    moreIcon(option) {
      if (option.key === 'assignable') {
        return 'x-iconfont x-icon-swap';
      }
      if (option.key === 'jumped') {
        return 'x-iconfont x-icon-backward';
      }
      if (option.key === 'addSigned') {
        return 'x-iconfont x-icon-user-add';
      }
      if (option.key === 'delSigned') {
        return 'x-iconfont x-icon-user-delete';
      }
      return '';
    },
    handleModelCommentLabel(action) {
      switch (action) {
        case ACTION.APPROVED:
        case ACTION.REJECTED:
        case ACTION.ASSIGN:
        case ACTION.ADD_BEFORE_SIGN:
        case ACTION.ADD_AFTER_SIGN:
        case ACTION.ADD_SIGN:
        case ACTION.DEL_SIGN:
          return '审批意见';
        case ACTION.CANCELED:
          return '撤回理由';
        case ACTION.BACK:
          return '回退原因';
        case ACTION.COMMENT:
          return '评论';
        case ACTION.TRANSACT:
          return '办理意见';
      }
    },
    onHandleModelCancel() {
      this.modalConfig.show = false;
      this.modalConfig.title = '';
      this.modalConfig.formData = {
        instanceId: null,
        taskId: '',
        actionType: 0,
        assigneeId: null,
        comment: null,
        attachments: []
      };
    },
    onHandleModelOK() {
      this.$refs.formRef.validate((valid,errors) => {
        if (valid) {
          let req;
          const { actionType } = this.modalConfig.formData;
          switch (actionType) {
            case ACTION.CANCELED:
              req = postAction('/workflow/workspace/revoke',this.modalConfig.formData);
              break;
            case ACTION.APPROVED:
              req = postAction('/workflow/workspace/agree',this.modalConfig.formData);
              break;
            case ACTION.REJECTED:
              req = postAction('/workflow/workspace/refuse',this.modalConfig.formData);
              break;
            case ACTION.COMMENT:
              req = postAction('/workflow/workspace/comment',this.modalConfig.formData);
              break;
          }
          req.then(() => {
            if (this.modalConfig.formData.actionType === ACTION.CANCELED) {
              const data = { ...this.flowInstance };
              data.instanceState = 3;
              this.$emit('update:flowInstance', data);
            }
            this.loadData();
            this.onHandleModelCancel();
            if (
              [
                ACTION.ASSIGN,
                ACTION.BACK,
                ACTION.ADD_BEFORE_SIGN,
                ACTION.ADD_AFTER_SIGN,
                ACTION.APPROVED,
                ACTION.REJECTED,
                ACTION.TRANSACT
              ].includes(actionType)
            ) {
              this.$emit('update:flowInstance', {});
            }
            this.$emit('refresh');
          }).catch((error) => {
            console.error(error);
          });
        } else {
          console.log("this.modalConfig.formData",this.modalConfig.formData)
          console.log("rules",JSON.stringify(this.rules))
          console.error(errors);
        }
      });
    },
    initModalFormData(action) {
      this.modalConfig.type = action;
      this.modalConfig.formData.instanceId = this.flowInstance.instanceId;
      this.modalConfig.formData.taskId = this.flowInstance.taskId;
      this.modalConfig.formData.actionType = action;
      this.modalConfig.formData.assigneeId = null;
      this.modalConfig.formData.comment = null;
      this.modalConfig.formData.attachments = [];
    },
    loadData() {
      getAction('/workflow/workspace/process/instanceAction',{instanceId:this.flowInstance.instanceId}).then((res) => {
        this.flowActions = res.result;
      });
      getAction('/workflow/workspace/process/instanceForm',{instanceId:this.flowInstance.instanceId}).then((res) => {
        this.instanceForm.formData = res.result.formData;
        this.instanceForm.formItems = JSON.parse(res.result.formItems);
      });
      getAction('/workflow/workspace/process/getNodeInfo',{
        processId:this.flowInstance.processId,
        nodeId:this.flowInstance.currentNodeKey
      }).then((res) => {
        this.currentNodeInfo = res.result;
        this.moreOptions = [];
        if (res.result.allowTransfer) {
          this.moreOptions.push({
            label: '转交',
            key: 'assignable'
          });
        }
        if (res.result.allowRollback) {
          this.moreOptions.push({
            label: '回退',
            key: 'jumped'
          });
        }
        if (res.result.allowAppendNode) {
          this.moreOptions.push({
            label: '加签',
            key: 'addSigned'
          });
          this.moreOptions.push({
            label: '减签',
            key: 'delSigned'
          });
        }
      });
      // console.log("********finish",this.finished)
      // console.log("********actionable",this.actionable)
      // console.log("********cancelable",this.cancelable)
      // console.log("********flowActions",this.flowActions)
      // console.log("********instanceForm",this.instanceForm)
      // console.log("********currentNodeInfo",this.currentNodeInfo)
    },
    onComment() {
      this.initModalFormData(ACTION.COMMENT);
      this.modalConfig.title = '评论审批';
      this.modalConfig.show = true;
    },
    onApproved() {
      this.initModalFormData(ACTION.APPROVED);
      this.modalConfig.title = '同意审批';
      this.modalConfig.show = true;
    },
    onRejected() {
      this.initModalFormData(ACTION.REJECTED);
      this.modalConfig.title = '拒绝审批';
      this.modalConfig.show = true;
    },
    onCanceled() {
      this.initModalFormData(ACTION.CANCELED);
      this.modalConfig.title = '撤销审批';
      this.modalConfig.show = true;
    },
    toggleMoreOptions() {
      this.showMoreOptions = !this.showMoreOptions;
    },
    onMoreOptionsSelect({ key }) {
      this.showMoreOptions = false;
      console.log(key);
    },
    onResubmit() {
      this.resubmitFormData = JSON.parse(JSON.stringify(this.instanceForm.formData));
      this.showResubmitModal = true;
    },
    onResubmitSubmit() {
      this.submitting = true;
      postAction('/workflow/workspace/process/resubmit',{
        instanceId: this.flowInstance.instanceId,
        formData: this.resubmitFormData
      }).then(() => {
        this.showResubmitModal = false;
        this.loadData();
        this.$message.success('重新提交成功');
      }).finally(() => {
        this.submitting = false;
      });
    }
  }
};
</script>

<style lang="less" scoped>
@import '../variables.module.less';

@bottomActionHeight: 52px;
@DetailHeaderHeight: 40px;
@FormLabelWidth: 84px;

.flow-detail-container {
  height: 100%;
  overflow: hidden;
  position: relative;
}

.flow-empty-detail-box {
  margin-top: 20%;
}

.flow-status-stamp {
  position: absolute;
  right: 30px;
  top: 30px;
}

.area-divider {
  border-bottom: 1px solid var(--color-neutral-3);
  margin: 20px 0;
  position: relative;
}

.action-form-edit-btn {
  user-select: none;
  position: absolute;
  right: 0;
  top: 0;
  border: 1px solid var(--color-neutral-3);
  border-top: 0;
  border-radius: 0 0 4px 4px;
  cursor: pointer;
  padding: 4px;
  font-size: 12px;
  color: #86909c;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;

  &:hover {
    background-color: #f2f3f5;
  }
}

.flow-header-box {
  font-weight: 400;
  font-size: 13px;
  border-bottom: 1px solid #e5e6ec;
  padding: 0 @GapLarge;
  height: calc(@DetailHeaderHeight - 1px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #86909c;

  .action-area {
    display: flex;
    gap: 4px;

    .action-item {
      cursor: pointer;
      padding: 4px;
      border-radius: @BorderRadius;
      width: fit-content;
      height: fit-content;

      &:hover {
        background-color: #f2f3f5;
      }
    }
  }
}

.flow-detail-box {
  height: calc(100% - @bottomActionHeight - @DetailHeaderHeight);
  overflow: hidden;
  overflow-y: auto;
  padding: 0 calc(@GapLarge + 10px);

  .header-box {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-top: 20px;

    .summary-info {
      display: flex;
      align-items: center;

      .title {
        font-size: 24px;
        font-family:
          PingFangSC-Semibold,
          PingFang SC;
        color: #1d2129;
      }

      .status {
        margin-left: 20px;
      }
    }

    .initiator-info {
      display: flex;
      align-items: center;
      margin-top: 16px;

      .start-time {
        margin-left: 20px;
        font-weight: 350;
        color: #86909c;
        font-size: 13px;
        user-select: none;
      }
    }
  }

  .flow-box {
    user-select: none;

    .assignee-container {
      position: relative;

      .badge {
        @BadgeSize: 14px;
        @BadgeOffset: -2px;
        position: absolute;
        width: @BadgeSize;
        height: @BadgeSize;
        display: flex;
        align-items: center;
        justify-content: center;
        bottom: @BadgeOffset;
        right: @BadgeOffset;
        z-index: 999;
        border: 2px solid #fff;
        background-color: #fff;
        border-radius: 50%;
        overflow: hidden;
      }
    }

    .audit-record {
      display: flex;
      flex-direction: row;
      justify-content: space-between;

      .sgement {
        margin-left: 8px;
        flex: 1;
      }

      .node-name {
        font-weight: 400;
        color: #86909c;

        .in-approval {
          color: #2a5eff;
        }
      }

      .auditor-name {
        font-size: 14px;

        .node-sign-type,
        .node-sign-assignee {
          font-weight: 400;
          color: #86909c;
          font-size: 12px;

          .node-sign-assignee-name {
            color: #2a5eff;
            display: inline-block;
          }
        }

        .node-assignee {
          margin-top: 4px;
          display: flex;
          flex-flow: row wrap;
          gap: 6px;
        }

        .assignee-name {
          color: #1d2129;
        }
      }

      .comment {
        user-select: none;
        margin: 4px 0 16px;
        padding: 8px 16px;
        border-radius: 4px;
        background-color: #f8f8fa;

        .comment-content {
          font-weight: 500;
          color: #1d2129;
        }

        .comment-attachment {
          gap: 10px;
          margin: 4px 0;
          display: flex;
          flex-wrap: wrap;

          .comment-attachment-item {
            border-radius: 4px;
            border: 1px solid #e1e1e1;
            padding: 4px 8px;
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 10px;

            .name {
              display: flex;
              align-items: center;
              gap: 4px;
            }

            .download-icon {
              display: flex;
              align-items: center;
              cursor: pointer;
              color: #165cfd;

              &:hover {
                opacity: 0.7;
              }
            }
          }
        }
      }

      .tag {
        text-align: right;
      }
    }
  }
}

.flow-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  height: @bottomActionHeight;
  border-top: 1px solid rgb(229, 230, 235);
  padding: 0 @GapLarge;

  button {
    + button {
      margin-left: 10px;
    }
  }
}

.custom-timeline-item {
  position: relative;
  min-height:60px;

  &::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;   // 关键！撑满整个条目的高度
    left: 4px;  // 对齐头像中心（根据实际头像大小调整）
    width: 2px;
    background-color: #e8e8e8;
  }

  // 最后一个去掉
  &:last-child::before {
    bottom: 80%; // 只画到中间，避免多出来
  }
}
</style>