yyb
10 小时以前 df5efb2ca2b0cf74d9160ffe2b6c215c4ddc9c99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<!-- 差旅/费用报销:审批列表内详情/审批弹窗内容(与报销页弹窗一致) -->
<template>
  <div v-loading="loading">
    <TravelDetailPanel v-if="isTravel" :row="reimburseRow" />
    <CostDetailPanel v-else :row="reimburseRow" />
 
    <el-divider content-position="left">流程进度</el-divider>
    <ApprovalFlowProgress
      :nodes="reimburseRow.approvalFlowNodes"
      :current-index="reimburseRow.currentNodeIndex ?? 0"
    />
 
    <template v-if="mode === 'detail'">
      <el-divider content-position="left">审批记录(全流程留痕)</el-divider>
      <el-timeline v-if="reimburseRow.approvalRecords?.length">
        <el-timeline-item
          v-for="(rec, i) in reimburseRow.approvalRecords"
          :key="i"
          :type="rec.result === 'approved' ? 'success' : rec.result === 'rejected' ? 'danger' : 'primary'"
          :timestamp="rec.time"
        >
          {{ rec.operatorName }} — {{ actionLabel(rec.result) }}:{{ rec.opinion || "无意见" }}
        </el-timeline-item>
      </el-timeline>
      <el-empty v-else description="暂无审批记录" :image-size="60" />
    </template>
 
    <el-form v-else label-width="100px" class="mt16">
      <el-form-item label="审批意见">
        <el-input
          :model-value="approveOpinion"
          type="textarea"
          :rows="3"
          maxlength="500"
          show-word-limit
          :placeholder="isTravel ? '通过可留空;驳回请填写原因' : '通过可留空;驳回请填写具体原因(如:发票模糊需重传)'"
          @update:model-value="$emit('update:approveOpinion', $event)"
        />
      </el-form-item>
    </el-form>
  </div>
</template>
 
<script setup>
import { computed } from "vue";
import { isTravelReimbursementType } from "../finReimbursementMappers.js";
import ApprovalFlowProgress from "../../travel-reimburse/components/ApprovalFlowProgress.vue";
import CostDetailPanel from "../../cost-reimburse/components/DetailPanel.vue";
import TravelDetailPanel from "../../travel-reimburse/components/DetailPanel.vue";
 
const props = defineProps({
  mode: { type: String, default: "detail" },
  moduleKey: { type: String, default: "" },
  reimburseRow: { type: Object, default: () => ({}) },
  loading: { type: Boolean, default: false },
  approveOpinion: { type: String, default: "" },
});
 
defineEmits(["update:approveOpinion"]);
 
const isTravel = computed(() =>
  isTravelReimbursementType(props.reimburseRow?.reimbursementType ?? props.moduleKey)
);
 
function actionLabel(v) {
  if (v === "approved") return "通过";
  if (v === "rejected") return "驳回";
  return "提交";
}
</script>