<template>
  <div class="request-page">
    <el-card class="form-card" shadow="never">
      <div slot="header" class="card-header">
        <span>日常报销申请</span>
        <div class="actions">
          <el-button size="mini" icon="el-icon-arrow-left" @click="$router.back()">返回</el-button>
        </div>
      </div>

      <el-form ref="formRef" :model="form" :rules="rules" label-width="120px" size="small" class="metal-form">
        <div class="form-summary">
          <div class="summary-left">
            <div class="summary-title">发起日常报销</div>
            <div class="summary-sub">请完善信息后提交，系统将按流程节点流转</div>
          </div>
          <div class="summary-right">
            <div class="summary-item">
              <div class="k">申请人</div>
              <div class="v">{{ currentApplicantText }}</div>
            </div>
            <div class="summary-item">
              <div class="k">报销金额</div>
              <div class="v">{{ form.totalAmount != null ? '¥' + form.totalAmount : '-' }}</div>
            </div>
          </div>
        </div>

        <el-row :gutter="14">
          <el-col :span="12">
            <el-form-item label="报销类型" prop="reimburseType">
              <el-select v-model="form.reimburseType" filterable allow-create default-first-option clearable
                placeholder="选择或输入（如：差旅费/招待费/办公费）" style="width: 100%">
                <el-option v-for="t in reimburseTypeOptions" :key="t" :label="t" :value="t" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="报销总金额">
              <div class="amount-readonly">
                {{ form.totalAmount != null && form.totalAmount > 0 ? '¥' + form.totalAmount : '根据发票明细自动汇总' }}
              </div>
            </el-form-item>
          </el-col>
        </el-row>

        <div class="block-title">绑定项目</div>
        <el-row>
          <el-col>
            <el-form-item label="项目" prop="projectId">
              <project-select v-model="form.projectId" placeholder="请选择项目" style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 报销单据附件（OCR触发区） -->
        <el-form-item label="报销单据附件" prop="accessoryApplyIds">
          <file-upload v-model="form.accessoryApplyIds" :limit="200" :file-size="50"
            :file-type="['pdf', 'jpg', 'jpeg', 'png', 'doc', 'docx']" multiple
            @delete="onFileDelete" />
          <div class="hint-text">上传发票、收据、付款截图等（支持 PDF/图片，上传后自动识别明细）</div>
        </el-form-item>

        <!-- OCR 识别中提示 -->
        <div v-if="anyOcrLoading" class="ocr-thinking">
          <i class="el-icon-loading"></i>
          <span>模型思考中，正在识别发票内容…</span>
        </div>

        <!-- 发票明细条目表 -->
        <div class="block-title">
          发票明细
          <span class="block-title-hint">（上传发票后自动识别，删除条目将同步移除对应文件）</span>
        </div>
        <div class="invoice-table" v-if="invoiceItems.length">
          <div class="invoice-table-header">
            <span class="col-reason">事由说明</span>
            <span class="col-amount">金额（元）</span>
            <span class="col-action"></span>
          </div>
          <div v-for="(item, idx) in invoiceItems" :key="idx" class="invoice-table-row">
            <el-input
              v-model="item.reason"
              :placeholder="item.itemName || '请填写事由'"
              size="small"
              class="col-reason"
            />
            <el-input-number
              v-model="item.amount"
              :min="0"
              :precision="2"
              size="small"
              class="col-amount"
              @change="recalcTotal"
            />
            <div class="col-action">
              <el-button size="mini" type="danger" plain icon="el-icon-delete" circle @click="removeInvoiceItem(idx)" />
            </div>
          </div>
          <div class="invoice-table-footer">
            <span class="total-hint">
              合计：<b>¥{{ invoiceTotalFormatted }}</b>（已自动更新报销总金额）
            </span>
          </div>
        </div>

        <el-form-item label="补充说明" prop="reason">
          <el-input v-model="form.reason" type="textarea" :rows="2" placeholder="可选：填写整体说明或补充" show-word-limit
            maxlength="3000" />
        </el-form-item>

        <el-form-item label="回执附件(可选)" prop="accessoryReceiptIds">
          <file-upload v-model="form.accessoryReceiptIds" :limit="200" :file-size="50"
            :file-type="['pdf', 'jpg', 'jpeg', 'png', 'doc', 'docx']" multiple />
          <div class="hint-text">可选：上传回执、对账单等（归档用）</div>
        </el-form-item>

        <el-form-item label="备注">
          <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="可选：补充说明" show-word-limit
            maxlength="200" />
        </el-form-item>

        <div class="block-title">抄送</div>
        <el-form-item label="抄送目标" prop="ccUserIds">
          <el-button size="mini" type="primary" plain icon="el-icon-user" @click="openUserMultiSelect">选择抄送人</el-button>
          <div class="selected-users" v-if="ccForm.selectedUsers && ccForm.selectedUsers.length">
            <el-tag v-for="u in ccForm.selectedUsers" :key="u.userId" size="mini" closable @close="removeCcUser(u)">
              {{ u.nickName || u.userName || ('ID:' + u.userId) }}
            </el-tag>
          </div>
        </el-form-item>
        <el-form-item label="抄送备注" prop="ccRemark">
          <el-input v-model="ccForm.remark" type="textarea" :rows="2" placeholder="可以填写抄送的目的或原因等信息" show-word-limit
            maxlength="1000" />
        </el-form-item>
        <UserMultiSelect ref="userMultiSelect" :init="ccUserIds" @onSelected="onCcUsersSelected" />

        <!-- 审批方式 -->
        <div class="block-title">审批方式</div>
        <div class="approve-mode">
          <el-radio-group v-model="approverMode" size="small" @change="onApproverModeChange">
            <el-radio-button label="template">使用模板流程</el-radio-button>
            <el-radio-button label="manual">手动选择审批人（一次审批）</el-radio-button>
          </el-radio-group>

          <div class="approve-panel">
            <div v-if="approverMode === 'template'">
              <div class="approve-row">
                <div class="k">流程模板</div>
                <div class="v">
                  <el-select v-model="tplId" size="small" clearable filterable placeholder="请选择流程模板"
                    style="width: 360px" @change="onTplChange">
                    <el-option v-for="t in availableTpls" :key="t.tplId"
                      :label="`${t.tplName}${t.version ? ' (v' + t.version + ')' : ''}`" :value="t.tplId" />
                  </el-select>
                </div>
              </div>
              <div class="hint-text">提示：选择模板后，将按模板节点自动流转（含抄送节点）。</div>
            </div>

            <div v-else>
              <div class="approve-row">
                <div class="k">审批人</div>
                <div class="v" style="max-width: 520px">
                  <el-button size="mini" type="primary" plain @click="openUserSelect">选择审批人</el-button>
                  <span style="margin-left: 10px; font-weight: 600; color: #2b2f36">
                    {{ assigneeUserName || '未选择' }}
                  </span>
                </div>
              </div>
              <div class="hint-text">提示：手动选择审批人将创建一次性审批流程，审批通过后流程立即结束。</div>
            </div>
          </div>
        </div>

        <div class="flow-preview" v-loading="flowLoading">
          <div class="flow-title">流程预览</div>
          <div class="flow-sub">
            <template v-if="approverMode === 'template'">
              <span v-if="flowTpl">当前模板：{{ flowTpl.tplName }}（v{{ flowTpl.version || 1 }}）</span>
              <span v-else>请选择流程模板</span>
            </template>
            <template v-else>
              <span>一次性审批（手动指定审批人）</span>
            </template>
          </div>

          <div v-if="approverMode === 'template'">
            <div v-if="flowNodes && flowNodes.length" class="flow-steps">
              <div class="flow-step"><div class="dot"></div><div class="txt">填写申请</div></div>
              <div class="line"></div>
              <div class="flow-step"><div class="dot"></div><div class="txt">提交</div></div>
              <template v-for="(n, idx) in flowNodes">
                <div class="line"></div>
                <div class="flow-step">
                  <div class="dot" :class="{ success: idx === flowNodes.length - 1 }"></div>
                  <div class="txt">{{ nodePreviewText(n, idx) }}</div>
                </div>
              </template>
            </div>
            <div v-else class="flow-fallback">
              <div class="hint-text">提示：请选择一个模板后将展示对应节点预览。</div>
            </div>
          </div>

          <div v-else class="flow-steps">
            <div class="flow-step"><div class="dot"></div><div class="txt">填写申请</div></div>
            <div class="line"></div>
            <div class="flow-step"><div class="dot"></div><div class="txt">提交审批（{{ assigneeUserName || '请选择' }}）</div></div>
            <div class="line"></div>
            <div class="flow-step"><div class="dot success"></div><div class="txt">审批结束</div></div>
          </div>
        </div>

        <div class="form-actions">
          <el-button @click="$router.back()">取消</el-button>
          <el-button type="primary" :loading="submitting" @click="submit">提交申请</el-button>
        </div>

        <UserSelect ref="userSelect" @onSelected="onUserSelected" />
      </el-form>
    </el-card>
  </div>
</template>

<script>
import { addReimburseReq, listFlowNode, listFlowTemplate, ocrReimburseInvoice } from '@/api/hrm';
import { getEmployeeByUserId } from '@/api/hrm/employee';
import { ccFlowTask } from '@/api/hrm/flow';
import FileUpload from '@/components/FileUpload';
import UserMultiSelect from '@/components/UserSelect/multi.vue';
import UserSelect from '@/components/UserSelect/single.vue';

export default {
  name: 'HrmReimburseRequest',
  components: { FileUpload, UserSelect, UserMultiSelect },
  data () {
    return {
      currentEmp: null,
      submitting: false,
      flowLoading: false,
      flowTpl: null,
      flowNodes: [],
      approverMode: 'template',
      availableTpls: [],
      tplId: null,
      assigneeUserId: null,
      assigneeUserName: '',
      reimburseTypeOptions: ['差旅费', '招待费', '办公费', '交通费', '通讯费', '其他'],
      // 发票明细条目
      invoiceItems: [],
      // OCR加载状态 { ossId: true/false }
      ocrLoadingMap: {},
      // 已触发过OCR的ossId集合
      ocrDoneSet: new Set(),
      form: {
        empId: '',
        reimburseType: '',
        totalAmount: 0,
        reason: '',
        accessoryApplyIds: '',
        accessoryReceiptIds: '',
        remark: ''
      },
      ccForm: {
        selectedUsers: [{
          userId: '1859249502579310593',
          nickName: '胡雪娇',
          userName: 'huangxuejiao'
        }, {
          userId: '1859252208375152641',
          nickName: '高伟',
          userName: 'gaowei'
        }],
        remark: ''
      },
      rules: {
        reimburseType: [{ required: true, message: '请选择/输入报销类型', trigger: 'change' }],
        totalAmount: [],
        accessoryApplyIds: [{ required: true, message: '请上传报销单据附件', trigger: 'change' }]
      }
    }
  },
  created () {
    this.loadCurrentEmployee()
    this.loadTemplates()
  },
  computed: {
    currentApplicantText () {
      if (this.currentEmp) {
        const emp = this.currentEmp
        const name = emp.empName || emp.nickName || emp.userName || ''
        const no = emp.empNo ? ` · ${emp.empNo}` : ''
        const dept = emp.deptName ? ` · ${emp.deptName}` : ''
        return `${name || '员工'}${no}${dept}`.trim()
      }
      const user = this.$store?.state?.user || {}
      return user.nickName || user.userName || '加载中...'
    },
    ccUserIds () {
      return this.ccForm.selectedUsers?.map(u => u.userId) || []
    },
    anyOcrLoading () {
      return Object.values(this.ocrLoadingMap).some(v => v)
    },
    invoiceTotalFormatted () {
      const total = this.invoiceItems.reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0)
      return total.toFixed(2)
    }
  },
  watch: {
    'form.accessoryApplyIds' (newVal, oldVal) {
      const newIds = newVal ? newVal.split(',').filter(Boolean) : []
      const oldIds = oldVal ? oldVal.split(',').filter(Boolean) : []
      const added = newIds.filter(id => !oldIds.includes(id))
      added.forEach(id => this.triggerOcr(id))
    }
  },
  methods: {
    openUserMultiSelect () { this.$refs.userMultiSelect.open() },
    onCcUsersSelected (users) { this.ccForm.selectedUsers = users || [] },
    removeCcUser (user) { this.ccForm.selectedUsers = this.ccForm.selectedUsers.filter(u => u.userId !== user.userId) },

    async triggerOcr (ossId) {
      if (this.ocrDoneSet.has(ossId)) return
      this.$set(this.ocrLoadingMap, ossId, true)
      try {
        const res = await ocrReimburseInvoice(ossId)
        if (res.code === 200 && res.data) {
          const { items, totalAmount, sellerName, invoiceDate, invoiceType } = res.data
          // 拼接发票头部信息作为事由前缀：发票类型 · 销售方 · 开票日期
          const prefix = [invoiceType, sellerName, invoiceDate].filter(Boolean).join(' · ')
          if (items && items.length) {
            const startIdx = this.invoiceItems.length
            items.forEach((item, i) => {
              const reason = [prefix, item.itemName].filter(Boolean).join(' / ')
              this.invoiceItems.push({
                ossId: ossId,
                itemName: item.itemName || '',
                reason,
                amount: item.amount || 0,
                sortNo: startIdx + i
              })
            })
          } else if (totalAmount) {
            // 没有明细时用总金额创建一条，事由取发票头部信息
            this.invoiceItems.push({
              ossId: ossId,
              itemName: sellerName || '',
              reason: prefix || '',
              amount: totalAmount,
              sortNo: this.invoiceItems.length
            })
          }
          this.recalcTotal()
        }
        this.ocrDoneSet.add(ossId)
      } catch (e) {
        console.error('[OCR] 识别失败', e)
        this.$message.warning('发票识别失败，请手动填写事由和金额')
      } finally {
        this.$set(this.ocrLoadingMap, ossId, false)
      }
    },

    removeInvoiceItem (idx) {
      const item = this.invoiceItems[idx]
      if (item.ossId) {
        // 删除该文件下所有条目
        const ossId = String(item.ossId)
        this.invoiceItems = this.invoiceItems.filter(it => String(it.ossId) !== ossId)
        // 从附件 CSV 中移除该文件
        const ids = (this.form.accessoryApplyIds || '').split(',').filter(id => id && id !== ossId)
        this.form.accessoryApplyIds = ids.join(',')
      } else {
        this.invoiceItems.splice(idx, 1)
      }
      this.recalcTotal()
    },

    onFileDelete (deletedFile) {
      const ossId = String(deletedFile.ossId)
      this.invoiceItems = this.invoiceItems.filter(item => String(item.ossId) !== ossId)
      this.recalcTotal()
    },

    recalcTotal () {
      const total = this.invoiceItems.reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0)
      this.form.totalAmount = parseFloat(total.toFixed(2))
    },

    async loadTemplates () {
      try {
        const res = await listFlowTemplate({ pageNum: 1, pageSize: 200, bizType: 'reimburse', enabled: 1 })
        this.availableTpls = res.rows || res.data || []
        if (!this.tplId && this.availableTpls.length) {
          this.tplId = this.availableTpls[0].tplId
        }
        await this.refreshFlowPreview()
      } catch (err) {
        this.availableTpls = []
      }
    },
    async refreshFlowPreview () {
      this.flowLoading = true
      try {
        if (this.approverMode === 'manual') { this.flowTpl = null; this.flowNodes = []; return }
        if (!this.tplId) { this.flowTpl = null; this.flowNodes = []; return }
        this.flowTpl = this.availableTpls.find(t => t.tplId === this.tplId) || null
        const nodeRes = await listFlowNode({ pageNum: 1, pageSize: 500, tplId: this.tplId })
        this.flowNodes = (nodeRes.rows || nodeRes.data || []).filter(n => n.nodeType !== 'end').sort((a, b) => (a.orderNo || 0) - (b.orderNo || 0))
      } finally {
        this.flowLoading = false
      }
    },
    nodePreviewText (n, idx) {
      const typeMap = { approve: '审批', cc: '抄送' }
      const ruleMap = { fixed_user: '指定人员', role: '指定角色', position: '指定岗位', leader: '直属上级' }
      const nodeType = typeMap[n.nodeType] || '节点'
      const rule = ruleMap[n.approverRule] || '规则'
      let detail = ''
      try {
        const arr = Array.isArray(n.approverValue) ? n.approverValue : JSON.parse(n.approverValue || '[]')
        if (arr.length) detail = `：${arr.join('、')}`
      } catch (e) { detail = n.approverValue ? `：${n.approverValue}` : '' }
      const text = `${nodeType}（${rule}${detail}）`
      return idx === this.flowNodes.length - 1 ? `${text} → 结束` : text
    },
    normalizeOssIds (val) {
      if (!val) return ''
      if (typeof val === 'string') return val
      if (Array.isArray(val)) {
        const ids = val.map(x => (x && typeof x === 'object') ? (x.ossId ?? x.id ?? x.value) : x).filter(Boolean)
        return ids.join(',')
      }
      return String(val)
    },
    async loadCurrentEmployee () {
      const userId = this.$store?.state?.user?.id
      if (!userId) { this.$message.error('无法获取当前用户信息，请重新登录'); return }
      try {
        const res = await getEmployeeByUserId(userId)
        if (res.code === 200 && res.data) {
          this.currentEmp = res.data
          this.form.empId = res.data.empId
        } else {
          this.$message.error('未找到当前用户对应的员工信息，请在员工管理中关联系统用户')
        }
      } catch (e) {
        this.$message.error('加载员工信息失败')
      }
    },
    async onTplChange (val) { this.tplId = val; await this.refreshFlowPreview() },
    onApproverModeChange (val) {
      this.approverMode = val
      if (val === 'manual') this.tplId = null
      this.refreshFlowPreview()
    },
    openUserSelect () { this.$refs.userSelect.open() },
    onUserSelected (row) {
      if (row) {
        this.assigneeUserId = row.userId
        this.assigneeUserName = row.nickName || row.userName || row.userId
        this.refreshFlowPreview()
      }
    },
    async submit () {
      try {
        await this.$refs.formRef.validate()
        if (this.approverMode === 'template' && !this.tplId) {
          return this.$message.warning('请选择一个流程模板')
        }
        if (this.approverMode === 'manual' && !this.assigneeUserId) {
          return this.$message.warning('请选择审批人')
        }

        this.submitting = true
        const payload = {
          empId: this.form.empId,
          reimburseType: this.form.reimburseType,
          totalAmount: this.form.totalAmount,
          reason: this.form.reason,
          accessoryApplyIds: this.normalizeOssIds(this.form.accessoryApplyIds),
          accessoryReceiptIds: this.normalizeOssIds(this.form.accessoryReceiptIds),
          remark: this.form.remark,
          status: 'pending',
          projectId: this.form.projectId,
          manualAssigneeUserId: this.assigneeUserId,
          invoiceItems: this.invoiceItems.map((item, i) => ({
            ossId: item.ossId || null,
            sortNo: i,
            itemName: item.itemName || '',
            reason: item.reason || item.itemName || '',
            amount: item.amount || 0
          }))
        }
        if (this.approverMode === 'template') {
          payload.tplId = this.tplId
        }
        const { data: instance } = await addReimburseReq(payload)
        if (this.ccForm.selectedUsers.length && instance?.instId) {
          const ccUserIds = this.ccForm.selectedUsers.map(u => u.userId)
          const fromUserId = this.$store?.state?.user?.id
          await ccFlowTask({
            instId: instance.instId,
            bizId: instance.bizId,
            bizType: 'reimburse',
            ccUserIds,
            remark: this.ccForm.remark,
            fromUserId,
            nodeId: 0,
            readFlag: 0,
            nodeName: '节点#0'
          })
        }
        this.$message.success('提交成功')
        this.$router.push('/hrm/apply')
      } catch (err) {
        // no-op
      } finally {
        this.submitting = false
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.request-page {
  padding: 16px 20px 32px;
  background: #f8f9fb;
}

.form-card {
  max-width: 980px;
  margin: 0 auto;
  border: 1px solid #d7d9df;
  border-radius: 12px;
  background: #ffffff;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 700;
  color: #2b2f36;
}

.actions { display: flex; gap: 8px; }

.metal-form { padding-right: 8px; }

.hint-text {
  margin-top: 6px;
  font-size: 12px;
  color: #8a8f99;
  line-height: 1.4;
}

.form-summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 12px 12px;
  margin-bottom: 12px;
  border: 1px solid #e6e8ed;
  border-radius: 10px;
  background: linear-gradient(180deg, #ffffff 0%, #fbfcfe 100%);
}

.summary-title { font-size: 16px; font-weight: 800; color: #2b2f36; }
.summary-sub { margin-top: 4px; font-size: 12px; color: #8a8f99; }
.summary-right { display: flex; gap: 16px; }
.summary-item .k { font-size: 12px; color: #8a8f99; }
.summary-item .v { margin-top: 2px; font-weight: 700; color: #2b2f36; }

/* OCR 思考中提示 */
.ocr-thinking {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  margin: 8px 0 12px;
  border-radius: 8px;
  background: #f0f7ff;
  border: 1px solid #b3d8ff;
  color: #409eff;
  font-size: 13px;
  font-weight: 600;

  i { font-size: 16px; animation: spin 1s linear infinite; }
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* 发票明细表 */
.invoice-table {
  margin-bottom: 16px;
  border: 1px solid #e6e8ed;
  border-radius: 8px;
  overflow: hidden;
}

.invoice-table-header {
  display: flex;
  align-items: center;
  padding: 8px 12px;
  background: #f5f7fa;
  border-bottom: 1px solid #e6e8ed;
  font-size: 12px;
  color: #606266;
  font-weight: 600;
}

.invoice-table-row {
  display: flex;
  align-items: center;
  padding: 8px 12px;
  gap: 10px;
  border-bottom: 1px solid #f2f3f5;

  &:last-child { border-bottom: none; }
}

.col-reason {
  flex: 1;
}

.col-amount {
  width: 140px;
  flex-shrink: 0;
}

.col-action {
  width: 32px;
  flex-shrink: 0;
  display: flex;
  justify-content: center;
}

.invoice-table-header .col-reason { flex: 1; }
.invoice-table-header .col-amount { width: 140px; }
.invoice-table-header .col-action { width: 32px; }

.invoice-table-footer {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 12px;
  background: #fafafa;
  border-top: 1px solid #f0f1f3;
}

.total-hint {
  font-size: 13px;
  color: #606266;

  b { color: #e6a23c; font-size: 14px; }
}

.amount-readonly {
  height: 32px;
  line-height: 32px;
  padding: 0 12px;
  font-size: 14px;
  font-weight: 600;
  color: #e6a23c;
  background: #fffbf2;
  border: 1px solid #faecd8;
  border-radius: 4px;
}

.flow-preview {
  margin-top: 10px;
  padding: 12px;
  border: 1px solid #e6e8ed;
  border-radius: 10px;
  background: #fcfdff;
}

.flow-title { font-weight: 800; color: #2b2f36; }
.flow-sub { margin-top: 4px; font-size: 12px; color: #8a8f99; }

.flow-steps {
  margin-top: 10px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.flow-step {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-radius: 999px;
  border: 1px solid #e6e8ed;
  background: #fff;
}

.flow-step .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #9aa3b2;
}

.flow-step .dot.success { background: #67c23a; }
.flow-step .txt { font-size: 12px; color: #2b2f36; font-weight: 600; }
.flow-steps .line { width: 26px; height: 1px; background: #e6e8ed; }

.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 14px;
}

@media (max-width: 1200px) {
  .summary-right { display: none; }
}

.block-title {
  margin: 20px 0 12px;
  padding-left: 10px;
  font-weight: 700;
  color: #2f3440;
  border-left: 3px solid #9aa3b2;
}

.block-title-hint {
  font-size: 12px;
  font-weight: 400;
  color: #8a8f99;
  margin-left: 6px;
}

.approve-mode {
  padding: 12px;
  border: 1px solid #e6e8ed;
  border-radius: 10px;
  background: #fcfdff;
}

.approve-panel { margin-top: 12px; }
.approve-row { display: flex; align-items: center; gap: 12px; }
.approve-row .k { font-size: 14px; color: #606266; }

.selected-users { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
</style>
