<template>
  <div class="app-container fadan-quick-record" :class="{ 'fadan-quick-record--mobile': isMobile }">
    <el-card class="box-card">
      <el-form :model="form" label-position="top" class="fadan-form">
        <el-form-item label="分销标记">
          <div class="mark-row">
            <span class="mark-prefix" aria-hidden="true">F-</span>
            <el-input
              v-model="form.markSuffix"
              class="mark-suffix-input"
              placeholder="后缀，如 李旭、闲鱼；留空则仅为 F"
              clearable
            />
          </div>
        </el-form-item>
        <el-form-item label="型号" required>
          <div class="model-row">
            <el-autocomplete
              v-model="form.model"
              class="model-input-base"
              :fetch-suggestions="queryModels"
              placeholder="型号本体；点选历史型号会拆分店铺并带出付款/后返"
              clearable
              :trigger-on-focus="true"
              @select="onModelSuggestionSelect"
              @blur="onModelBlur"
            >
              <template slot-scope="{ item }">
                <span class="model-suggest-label">{{ item.label }}</span>
              </template>
            </el-autocomplete>
            <el-select
              v-model="form.shopPrefix"
              class="model-shop-select"
              :placeholder="shopOptions.length ? '店铺（必选）' : '店铺'"
              clearable
              filterable
            >
              <el-option
                v-for="opt in shopOptions"
                :key="opt.prefix"
                :label="opt.label"
                :value="opt.prefix"
              />
            </el-select>
            <el-button
              v-if="!isMobile"
              type="text"
              class="model-shop-config-btn"
              icon="el-icon-setting"
              title="配置型号店铺选项"
              @click="showShopConfig = true"
            />
          </div>
          <p class="model-shop-hint">
            <template v-if="shopOptions.length">
              落库型号 = 上方输入 + 所选店铺前缀（如 W5000PLUS2.0白 + 海尔厨房 → W5000PLUS2.0白海尔厨房）
            </template>
            <template v-else>
              尚未配置店铺选项，录单时不强制选择店铺。
            </template>
            <el-button type="text" size="mini" @click="showShopConfig = true">配置店铺选项</el-button>
          </p>
        </el-form-item>
        <el-form-item label="下单地址" required>
          <el-input
            v-model="form.address"
            type="textarea"
            :rows="2"
            placeholder="必填；可粘贴多行，失焦或点击录单时会压成一行（去逗号、多空格合并）"
            clearable
            @blur="normalizeAddressField"
          />
        </el-form-item>
        <el-form-item label="转链链接（可空）">
          <el-input v-model="form.link" type="textarea" :rows="2" placeholder="可空；留空则后台按型号尝试自动填充京粉链接" clearable />
        </el-form-item>
        <el-form-item label="第三方单号（选填）">
          <el-input
            v-model="form.thirdPartyOrderNoText"
            placeholder="选填；写入录单文案「第三方单号：」行，可覆盖「生」自动带出内容"
            clearable
          />
        </el-form-item>

        <el-divider content-position="left">落库必填（与中控录单一致）</el-divider>
        <el-form-item label="下单人">
          <el-input v-model="form.buyer" placeholder="落库必填" clearable />
        </el-form-item>
        <el-form-item label="下单付款（元）">
          <el-input v-model="form.paymentText" placeholder="落库必填，如 2999.00" clearable />
        </el-form-item>
        <el-form-item label="后返金额（元）">
          <el-input v-model="form.rebateText" placeholder="不写则按 0.00 落库" clearable />
        </el-form-item>
        <el-form-item label="订单号（京东）">
          <el-input v-model="form.orderIdText" placeholder="落库必填，与表单「订单号（需填）」一致" clearable />
        </el-form-item>
        <el-form-item label="物流链接">
          <el-input v-model="form.logisticsLink" type="textarea" :rows="2" placeholder="落库必填" clearable />
        </el-form-item>

        <div class="btn-row">
          <el-button type="primary" size="medium" :loading="loading" @click="generate">录单</el-button>
          <el-button size="medium" @click="resetForm">重置表单</el-button>
          <el-button v-if="resultText" size="medium" @click="copyResult">
            {{ resultPieces.length > 1 ? '复制全部（连在一起）' : '复制结果' }}
          </el-button>
        </div>
      </el-form>

      <template v-if="resultText">
        <el-divider content-position="left">录单结果</el-divider>
        <p v-if="resultPieces.length > 1" class="result-pieces-hint">按条复制，每条对应一条聊天消息。</p>
        <div class="result-pieces">
          <div v-for="(p, i) in resultPieces" :key="i" class="result-piece">
            <div class="result-piece-head">
              <span class="result-piece-title">{{ p.title }}</span>
              <el-button type="primary" plain size="mini" @click="copyPieceText(p.text)">复制本条</el-button>
            </div>
            <el-input
              :value="p.text"
              type="textarea"
              :autosize="{ minRows: resultPieceMinRows(p.text), maxRows: isMobile ? 22 : 28 }"
              readonly
              class="result-area"
            />
          </div>
        </div>
      </template>
    </el-card>

    <el-dialog
      title="地址/单号重复验证"
      :visible.sync="verifyDialogVisible"
      :width="dialogWidth"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      append-to-body
    >
      <div class="verify-body">
        <el-alert :title="verifyMessage" type="warning" :closable="false" />
        <div class="verify-code">{{ verifyCode }}</div>
        <el-input v-model="verifyInput" placeholder="请输入上方四位验证码" maxlength="4" @keyup.enter.native="handleVerify" />
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="verifyDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="verifyLoading" @click="handleVerify">确认录单</el-button>
      </div>
    </el-dialog>

    <quick-record-model-shop-config v-model="showShopConfig" @saved="loadShopOptions" />
  </div>
</template>

<script>
import { executeInstruction, executeInstructionWithForce } from '@/api/system/instruction'
import { listQuickRecordModelOptions, listQuickRecordShopOptions } from '@/api/system/jdorder'
import QuickRecordModelShopConfig from './components/QuickRecordModelShopConfig.vue'

export default {
  name: 'FadanQuickRecord',
  components: { QuickRecordModelShopConfig },
  props: {
    isMobile: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      form: {
        markSuffix: '',
        model: '',
        shopPrefix: '',
        address: '',
        link: '',
        thirdPartyOrderNoText: '',
        buyer: '',
        paymentText: '',
        rebateText: '',
        orderIdText: '',
        logisticsLink: ''
      },
      loading: false,
      resultText: '',
      resultListFromLast: [],
      verifyDialogVisible: false,
      verifyCode: '',
      verifyInput: '',
      verifyMessage: '',
      verifyLoading: false,
      pendingCommand: '',
      modelOptions: [],
      shopOptions: [],
      showShopConfig: false
    }
  },
  mounted() {
    this.loadModelOptions()
    this.loadShopOptions()
  },
  computed: {
    dialogWidth() {
      return this.isMobile ? '92%' : '480px'
    },
    resultPieces() {
      return this.splitResultTextIntoMessages(this.resultText)
    }
  },
  methods: {
    /**
     * 按「落库回执 / 发货摘要」拆成多条，便于逐条复制发送
     */
    splitResultTextIntoMessages(full) {
      const raw = String(full || '').replace(/\r\n/g, '\n').trim()
      if (!raw) return []
      const sepReceipt = /\n-{3,}\s*落库回执\s*-{3,}\s*\n/
      const m = sepReceipt.exec(raw)
      if (!m) {
        return [{ title: '录单结果', text: raw }]
      }
      const formBody = raw.slice(0, m.index).trim()
      const receiptRest = raw.slice(m.index + m[0].length).trim()
      const shipNeedle = '\n「发货摘要」'
      const idxShip = receiptRest.indexOf(shipNeedle)
      const out = []
      out.push({ title: '第 1 条 · 录单表单', text: formBody })
      if (idxShip >= 0) {
        const beforeShip = receiptRest.slice(0, idxShip).trim()
        const fromShip = receiptRest.slice(idxShip + 1).trim()
        out.push({
          title: '第 2 条 · 落库回执',
          text: `--- 落库回执 ---\n${beforeShip}`.trim()
        })
        out.push({ title: '第 3 条 · 发货摘要', text: fromShip })
      } else {
        out.push({
          title: '第 2 条 · 落库回执',
          text: `--- 落库回执 ---\n${receiptRest}`.trim()
        })
      }
      return out
    },
    resultPieceMinRows(text) {
      const n = String(text || '').split('\n').length
      const cap = this.isMobile ? 8 : 6
      return Math.min(Math.max(n + 1, cap), this.isMobile ? 18 : 14)
    },
    copyPieceText(text) {
      const t = (text || '').trim()
      if (!t) return
      if (navigator.clipboard) {
        navigator.clipboard.writeText(t).then(() => {
          this.$modal.msgSuccess('已复制本条')
        }).catch(() => this.fallbackCopy(t, '已复制本条'))
      } else {
        this.fallbackCopy(t, '已复制本条')
      }
    },
    buildDistributionMark() {
      let s = (this.form.markSuffix || '').trim()
      if (s.startsWith('-')) {
        s = s.slice(1).trim()
      }
      if (!s) {
        return 'F'
      }
      return 'F-' + s
    },
    /** 地址压成一行：换行/多空格合并为单空格，去掉中英文逗号 */
    compressAddressOneLine(raw) {
      if (raw == null) return ''
      return String(raw)
        .replace(/[，,]/g, '')
        .replace(/\s+/g, ' ')
        .trim()
    },
    normalizeAddressField() {
      this.form.address = this.compressAddressOneLine(this.form.address)
    },
    formatMoneyText(v) {
      if (v == null || v === '') return ''
      const n = Number(v)
      if (!Number.isFinite(n)) return ''
      return n.toFixed(2)
    },
    modelOptionLabel(row) {
      if (!row || !row.modelNumber) return ''
      const p = this.formatMoneyText(row.lastPaymentAmount)
      const r = this.formatMoneyText(row.lastRebateAmount)
      if (!p && !r) return row.modelNumber
      return `${row.modelNumber}（付款 ${p || '—'} / 后返 ${r || '—'}）`
    },
    async loadModelOptions() {
      try {
        const res = await listQuickRecordModelOptions()
        if (!(res && (res.code === 200 || res.msg === '操作成功'))) {
          return
        }
        this.modelOptions = Array.isArray(res.data) ? res.data : []
      } catch (e) {
        // 静默失败，不影响手输型号
      }
    },
    async loadShopOptions() {
      try {
        const res = await listQuickRecordShopOptions()
        if (!(res && (res.code === 200 || res.msg === '操作成功'))) {
          return
        }
        const rows = Array.isArray(res.data) ? res.data : []
        this.shopOptions = rows
          .filter(o => o && String(o.prefix || '').trim())
          .map(o => ({
            prefix: String(o.prefix).trim(),
            fullName: o.fullName || '',
            label: o.label || o.prefix
          }))
          .sort((a, b) => b.prefix.length - a.prefix.length)
      } catch (e) {
        this.shopOptions = []
      }
    },
    /** 从完整型号末尾匹配店铺前缀（长前缀优先），用于回显 */
    parseModelWithShop(fullModel) {
      const full = String(fullModel || '').trim()
      if (!full || !this.shopOptions.length) {
        return { base: full, prefix: '' }
      }
      for (const opt of this.shopOptions) {
        const p = opt.prefix
        if (p && full.endsWith(p) && full.length > p.length) {
          return { base: full.slice(0, -p.length), prefix: p }
        }
      }
      return { base: full, prefix: '' }
    },
    applyModelWithShop(fullModel) {
      const parsed = this.parseModelWithShop(fullModel)
      this.form.model = parsed.base
      this.form.shopPrefix = parsed.prefix
      return parsed
    },
    onModelBlur() {
      if (!this.form.model || !this.shopOptions.length) return
      const parsed = this.parseModelWithShop(this.form.model)
      if (parsed.prefix) {
        this.form.model = parsed.base
        this.form.shopPrefix = parsed.prefix
      }
    },
    buildFullModelNumber() {
      const base = (this.form.model || '').trim()
      const prefix = (this.form.shopPrefix || '').trim()
      if (!base) return ''
      return prefix ? base + prefix : base
    },
    fullModelFromOption(o) {
      if (!o) return ''
      const base = String(o.modelNumber || '').trim()
      const shop = String(o.modelShop || '').trim()
      if (!base) return shop
      if (!shop) return base
      if (base.endsWith(shop)) return base
      return base + shop
    },
    queryModels(queryString, cb) {
      const q = (queryString || '').trim().toLowerCase()
      const rows = this.modelOptions
        .filter(o => {
          const full = this.fullModelFromOption(o)
          if (!full) return false
          if (!q) return true
          const parsed = this.parseModelWithShop(full)
          return full.toLowerCase().includes(q) || parsed.base.toLowerCase().includes(q)
        })
        .slice(0, 100)
      cb(
        rows.map(o => {
          const full = this.fullModelFromOption(o)
          const parsed = this.parseModelWithShop(full)
          return {
            value: full,
            label: this.modelOptionLabel({ ...o, modelNumber: parsed.base || full })
          }
        })
      )
    },
    /** 仅从联想列表点选时回填金额；型号拆分为本体 + 店铺前缀 */
    onModelSuggestionSelect(item) {
      if (!item || !item.value) return
      const key = String(item.value).trim()
      const hit = this.modelOptions.find(o => this.fullModelFromOption(o) === key)
      if (hit && hit.modelShop) {
        this.form.model = String(hit.modelNumber || '').trim()
        this.form.shopPrefix = String(hit.modelShop || '').trim()
      } else {
        this.applyModelWithShop(key)
      }
      if (!hit) return
      const payRaw = hit.lastPaymentAmount
      const rebateRaw = hit.lastRebateAmount
      this.form.paymentText = payRaw != null && payRaw !== '' ? this.formatMoneyText(payRaw) : ''
      this.form.rebateText = rebateRaw != null && rebateRaw !== '' ? this.formatMoneyText(rebateRaw) : ''
    },
    buildCommand() {
      const mark = this.buildDistributionMark()
      this.onModelBlur()
      const model = this.buildFullModelNumber()
      this.normalizeAddressField()
      const address = (this.form.address || '').trim()
      if (!(this.form.model || '').trim()) {
        this.$modal.msgError('请填写型号')
        return null
      }
      if (this.shopOptions.length && !this.form.shopPrefix) {
        this.$modal.msgError('请选择型号对应店铺')
        return null
      }
      if (!model) {
        this.$modal.msgError('请填写型号')
        return null
      }
      if (!address) {
        this.$modal.msgError('请填写地址')
        return null
      }
      const link = (this.form.link || '').trim()
      const lines = ['生', mark, model, link, '1', address]
      return lines.join('\n')
    },
    injectOptional(raw) {
      if (!raw) return raw
      let t = String(raw).replace(/\r\n/g, '\n')
      const buyer = (this.form.buyer || '').trim()
      const pay = (this.form.paymentText || '').trim()
      const rebate = (this.form.rebateText || '').trim()
      const orderId = (this.form.orderIdText || '').trim()
      const logistics = (this.form.logisticsLink || '').trim()
      const thirdPartyOrderNo = (this.form.thirdPartyOrderNoText || '').trim()
      if (thirdPartyOrderNo) {
        // 与 InstructionServiceImpl.WENAN_D 一致：「第三方单号：值」同行，下一行才是分隔线
        const reInline = /第三方单号：[^\n]*\n(—————————)/g
        t = t.replace(reInline, `第三方单号：${thirdPartyOrderNo}\n$1`)
        // 兼容「标签独占一行 + 值独占一行」的旧文案
        const reMultiline = /(第三方单号：)\n([^\n]*)\n(—————————)/g
        t = t.replace(reMultiline, (_, a, _line, sep) => `${a}\n${thirdPartyOrderNo}\n${sep}`)
      }
      if (buyer) {
        t = t.replace(/(下单人（需填）：)\n\n/, `$1\n${buyer}\n\n`)
      }
      if (pay) {
        t = t.replace(/(下单付款（注意核对）：)\n\n/, `$1\n${pay}\n\n`)
      }
      if (rebate) {
        t = t.replace(/(后返金额（注意核对）：)\n\n/, `$1\n${rebate}\n\n`)
      } else {
        t = t.replace(/(后返金额（注意核对）：)\n\n/, `$1\n0.00\n\n`)
      }
      if (orderId) {
        t = t.replace(/(订单号（需填）：)\n\n/, `$1\n${orderId}\n\n`)
      }
      if (logistics) {
        t = t.replace(/(物流链接（需填）：)\n\n/, `$1\n${logistics}\n\n`)
      }
      return t
    },
    formBodyLooksPersistable(text) {
      const t = (text || '').trim()
      return t.startsWith('单')
    },
    canPersistOrderFields() {
      const buyer = (this.form.buyer || '').trim()
      const pay = (this.form.paymentText || '').trim()
      const orderId = (this.form.orderIdText || '').trim()
      const logistics = (this.form.logisticsLink || '').trim()
      return !!(buyer && pay && orderId && logistics)
    },
    formatInstructionData(data) {
      if (Array.isArray(data)) {
        return data.length ? data.join('\n\n') : ''
      }
      if (typeof data === 'string') {
        return data
      }
      return ''
    },
    isPersistFailureText(text) {
      const s = String(text || '')
      return s.includes('[炸弹]') || s.includes('录单警告')
    },
    applyPersistResult(mergedBody, persistMsg) {
      const msg = persistMsg || ''
      this.resultText = (mergedBody || '') + '\n\n--- 落库回执 ---\n' + msg
      if (this.isPersistFailureText(msg)) {
        this.$modal.msgError('落库未成功，请查看回执')
      } else {
        this.$modal.msgSuccess('已生成表单并落库')
      }
    },
    extractFirstResponse(data) {
      if (Array.isArray(data)) {
        return data.length ? String(data[0]) : ''
      }
      if (typeof data === 'string') {
        return data
      }
      return ''
    },
    checkDuplicateError(resultList) {
      if (!resultList || !resultList.length) return false
      for (let i = 0; i < resultList.length; i++) {
        const s = resultList[i]
        if (typeof s === 'string' && (
          s.includes('ERROR_CODE:ADDRESS_DUPLICATE') ||
          s.includes('ERROR_CODE:ORDER_NUMBER_DUPLICATE')
        )) {
          return true
        }
      }
      return false
    },
    showVerifyDialog(cmd) {
      this.pendingCommand = cmd
      this.verifyCode = String(Math.floor(1000 + Math.random() * 9000))
      this.verifyInput = ''
      let hasOrder = false
      let hasAddr = false
      const list = this.resultListFromLast || []
      list.forEach(s => {
        if (typeof s !== 'string') return
        if (s.includes('ERROR_CODE:ORDER_NUMBER_DUPLICATE')) hasOrder = true
        if (s.includes('ERROR_CODE:ADDRESS_DUPLICATE')) hasAddr = true
      })
      if (hasOrder && hasAddr) {
        this.verifyMessage = '检测到订单编号与地址可能重复，输入验证码后可强制录单'
      } else if (hasOrder) {
        this.verifyMessage = '检测到订单编号可能重复，输入验证码后可强制录单'
      } else {
        this.verifyMessage = '检测到地址可能重复，输入验证码后可强制录单'
      }
      this.verifyDialogVisible = true
    },
    async generate() {
      const cmd = this.buildCommand()
      if (!cmd) return
      this.loading = true
      this.resultText = ''
      try {
        const res = await executeInstruction({ command: cmd })
        if (!(res && (res.code === 200 || res.msg === '操作成功'))) {
          this.$modal.msgError((res && res.msg) || '生成表单失败')
          return
        }
        const list = Array.isArray(res.data) ? res.data : (res.data ? [String(res.data)] : [])
        if (this.checkDuplicateError(list)) {
          this.resultListFromLast = list
          this.showVerifyDialog(cmd)
          return
        }
        const rawForm = this.extractFirstResponse(res.data)
        const merged = this.injectOptional(rawForm)
        if (!this.formBodyLooksPersistable(merged)) {
          this.resultText = merged
          this.$modal.msgError('生成结果不是可落库表单，请重试或联系管理员')
          return
        }
        if (!this.canPersistOrderFields()) {
          this.resultText = merged
          this.$modal.msgWarning('已生成录单文案。落库需填写：下单人、下单付款、订单号、物流链接（后返可不填，将按 0.00）')
          return
        }
        const res2 = await executeInstruction({ command: merged })
        if (!(res2 && (res2.code === 200 || res2.msg === '操作成功'))) {
          this.$modal.msgError((res2 && res2.msg) || '落库失败')
          return
        }
        this.applyPersistResult(merged, this.formatInstructionData(res2.data))
      } catch (e) {
        this.$modal.msgError('请求失败')
      } finally {
        this.loading = false
      }
    },
    async handleVerify() {
      if (!this.verifyInput || this.verifyInput.length !== 4) {
        this.$modal.msgError('请输入四位验证码')
        return
      }
      if (this.verifyInput !== this.verifyCode) {
        this.$modal.msgError('验证码不正确')
        this.verifyInput = ''
        return
      }
      this.verifyLoading = true
      try {
        const res = await executeInstructionWithForce({ command: this.pendingCommand })
        if (!(res && (res.code === 200 || res.msg === '操作成功'))) {
          this.$modal.msgError((res && res.msg) || '执行失败')
          return
        }
        const merged = this.injectOptional(this.extractFirstResponse(res.data))
        if (!this.formBodyLooksPersistable(merged)) {
          this.resultText = merged
          this.verifyDialogVisible = false
          this.$modal.msgError('生成结果不是可落库表单')
          return
        }
        if (!this.canPersistOrderFields()) {
          this.resultText = merged
          this.verifyDialogVisible = false
          this.$modal.msgWarning('已强制生成表单。落库仍需填写：下单人、下单付款、订单号、物流链接')
          return
        }
        const res2 = await executeInstruction({ command: merged })
        this.verifyDialogVisible = false
        if (!(res2 && (res2.code === 200 || res2.msg === '操作成功'))) {
          this.$modal.msgError((res2 && res2.msg) || '落库失败')
          return
        }
        this.applyPersistResult(merged, this.formatInstructionData(res2.data))
      } catch (e) {
        this.$modal.msgError('请求失败')
      } finally {
        this.verifyLoading = false
      }
    },
    resetForm() {
      this.form = {
        markSuffix: '',
        model: '',
        shopPrefix: '',
        address: '',
        link: '',
        thirdPartyOrderNoText: '',
        buyer: '',
        paymentText: '',
        rebateText: '',
        orderIdText: '',
        logisticsLink: ''
      }
      this.resultText = ''
    },
    copyResult() {
      const t = this.resultText || ''
      if (!t) return
      if (navigator.clipboard) {
        navigator.clipboard.writeText(t).then(() => {
          this.$modal.msgSuccess('已复制全部')
        }).catch(() => this.fallbackCopy(t, '已复制全部'))
      } else {
        this.fallbackCopy(t, '已复制全部')
      }
    },
    fallbackCopy(text, successMsg) {
      const ta = document.createElement('textarea')
      ta.value = text
      document.body.appendChild(ta)
      ta.focus()
      ta.select()
      try {
        document.execCommand('copy')
        this.$modal.msgSuccess(successMsg || '已复制')
      } catch (e) {
        this.$modal.msgError('复制失败')
      }
      document.body.removeChild(ta)
    }
  }
}
</script>

<style scoped>
.fadan-quick-record {
  padding-bottom: 16px;
}

.fadan-quick-record--mobile .box-card {
  margin: 0 12px 20px;
}

.fadan-quick-record:not(.fadan-quick-record--mobile) .box-card {
  max-width: 960px;
}

.fadan-form ::v-deep .el-form-item {
  margin-bottom: 14px;
}

.mark-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
}

.mark-prefix {
  flex-shrink: 0;
  color: #606266;
  font-weight: 500;
  user-select: none;
}

.mark-suffix-input {
  flex: 1;
  min-width: 0;
}

.model-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  width: 100%;
}

.model-input-base {
  flex: 1;
  min-width: 0;
}

.model-shop-select {
  width: 220px;
  flex-shrink: 0;
}

.model-shop-config-btn {
  flex-shrink: 0;
  padding: 8px 4px;
}

.model-shop-hint {
  margin: 6px 0 0;
  font-size: 12px;
  color: #909399;
  line-height: 1.4;
}

.fadan-quick-record--mobile .model-row {
  flex-wrap: wrap;
}

.fadan-quick-record--mobile .model-shop-select {
  width: 100%;
}

.model-input-full {
  width: 100%;
}

.model-suggest-label {
  display: block;
  line-height: 1.45;
  white-space: normal;
  word-break: break-all;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 8px;
}

.result-area ::v-deep .el-textarea__inner {
  font-family: Consolas, 'Courier New', monospace;
  font-size: 13px;
}

.result-pieces-hint {
  margin: 0 0 10px;
  font-size: 13px;
  color: #909399;
}

.result-pieces {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.result-piece-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}

.result-piece-title {
  font-weight: 600;
  color: #303133;
  font-size: 14px;
}

.verify-body .verify-code {
  text-align: center;
  font-size: 26px;
  font-weight: 700;
  color: #409eff;
  margin: 16px 0;
}

@media (max-width: 768px) {
  .fadan-quick-record--mobile .box-card {
    margin: 0 8px 16px;
  }
}
</style>
