SettlementSheetDetailPanel.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. <!-- 结算单详情:凭证缩略图/视频可播放 + 订单树形表(含商品行) -->
  2. <template>
  3. <div class="sheet-detail-panel">
  4. <div class="view-hero">
  5. <div class="view-hero-icon">
  6. <el-icon><Document /></el-icon>
  7. </div>
  8. <div class="view-hero-main">
  9. <h2>{{ detail.settlementNo || '-' }}</h2>
  10. <div class="view-hero-tags">
  11. <el-tag type="primary" size="small">{{ counterpartyLabel }}:{{ counterpartyName || '-' }}</el-tag>
  12. <el-tag type="success" size="small">订单数 {{ detail.orderCount || 0 }}</el-tag>
  13. </div>
  14. <p class="view-hero-meta">
  15. 结算金额:<span class="amount-text">¥{{ formatAmount(detail.totalAmount) }}</span>
  16. <span class="dot">·</span>
  17. 结算时间:{{ detail.settlementAt || '-' }}
  18. <span class="dot">·</span>
  19. 操作人:{{ detail.createName || '-' }}
  20. </p>
  21. </div>
  22. </div>
  23. <div class="view-section">
  24. <h3>基础信息</h3>
  25. <el-descriptions :column="2" border>
  26. <el-descriptions-item label="结算单号" :span="2">{{ detail.settlementNo }}</el-descriptions-item>
  27. <el-descriptions-item :label="counterpartyLabel">{{
  28. counterpartyName || '-'
  29. }}</el-descriptions-item>
  30. <el-descriptions-item label="订单数">{{ detail.orderCount }}</el-descriptions-item>
  31. <el-descriptions-item label="结算金额(元)">
  32. <span class="amount-text">¥{{ formatAmount(detail.totalAmount) }}</span>
  33. </el-descriptions-item>
  34. <el-descriptions-item label="结算时间">{{ detail.settlementAt || '-' }}</el-descriptions-item>
  35. <el-descriptions-item label="操作人">{{ detail.createName || '-' }}</el-descriptions-item>
  36. <el-descriptions-item label="备注" :span="2">{{ detail.remark || '-' }}</el-descriptions-item>
  37. </el-descriptions>
  38. </div>
  39. <div class="view-section">
  40. <div class="detail-block-title">结算凭证</div>
  41. <div v-if="voucherUrls.length" class="voucher-preview-grid">
  42. <div
  43. v-for="(url, i) in voucherUrls"
  44. :key="i"
  45. class="voucher-tile"
  46. @click="openVoucher(url)"
  47. >
  48. <template v-if="isVideoUrl(url)">
  49. <video :src="url" class="voucher-thumb" muted preload="metadata" />
  50. <div class="voucher-tile-play">
  51. <el-icon :size="28"><VideoPlay /></el-icon>
  52. </div>
  53. </template>
  54. <el-image v-else :src="url" fit="cover" class="voucher-thumb" />
  55. </div>
  56. </div>
  57. <el-empty v-else description="无凭证" :image-size="56" />
  58. </div>
  59. <div class="view-section">
  60. <div class="detail-block-title">包含订单</div>
  61. <div class="detail-orders-list list-body list-wrap">
  62. <el-table
  63. ref="ordersTableRef"
  64. :data="orders"
  65. row-key="id"
  66. size="small"
  67. stripe
  68. max-height="480"
  69. class="orders-table"
  70. >
  71. <el-table-column type="expand" width="48">
  72. <template #default="{ row: ord }">
  73. <div class="order-row-expand-wrap">
  74. <div
  75. v-if="Array.isArray(ord.children) && ord.children.length"
  76. class="settlement-row-expand-table-wrap sqxp-subtable-wrap"
  77. >
  78. <el-table :data="ord.children" stripe size="small" class="order-row-expand-table sqxp-subtable">
  79. <el-table-column label="商品" min-width="180">
  80. <template #default="{ row: line }">
  81. <div class="expand-product-cell">
  82. <div class="expand-product-thumb-wrap">
  83. <el-image
  84. v-if="line.imageUrl"
  85. :src="line.imageUrl"
  86. fit="cover"
  87. class="expand-product-thumb"
  88. :preview-src-list="[line.imageUrl]"
  89. preview-teleported
  90. />
  91. <span v-else class="expand-product-thumb placeholder">无图</span>
  92. </div>
  93. <div class="expand-product-text">
  94. <span class="expand-product-name">{{ line.productName || '—' }}</span>
  95. <span v-if="line.note" class="expand-product-note">备注:{{ line.note }}</span>
  96. </div>
  97. </div>
  98. </template>
  99. </el-table-column>
  100. <el-table-column label="计量" width="88" align="center">
  101. <template #default="{ row: line }">{{ formatMeasureValue(line.measureValue) }}</template>
  102. </el-table-column>
  103. <el-table-column prop="unitName" label="单位" width="70" align="center" />
  104. <el-table-column label="数量" width="88" align="right">
  105. <template #default="{ row: line }">{{ formatQty(line.quantity) }}</template>
  106. </el-table-column>
  107. <el-table-column label="供货单价(元)" width="110" align="right">
  108. <template #default="{ row: line }">{{ formatAmount(line.supplierUnitPrice) }}</template>
  109. </el-table-column>
  110. <el-table-column label="供货金额(元)" width="110" align="right">
  111. <template #default="{ row: line }">
  112. <span class="amount-text">{{ formatAmount(line.supplierAmount) }}</span>
  113. </template>
  114. </el-table-column>
  115. <el-table-column label="售价单价(元)" width="110" align="right">
  116. <template #default="{ row: line }">{{ formatAmount(line.sellingUnitPrice) }}</template>
  117. </el-table-column>
  118. <el-table-column label="售出金额(元)" width="110" align="right">
  119. <template #default="{ row: line }">
  120. <span class="amount-text">{{ formatAmount(line.sellingAmount) }}</span>
  121. </template>
  122. </el-table-column>
  123. </el-table>
  124. <div class="order-row-expand-summary sqxp-subtable-summary">
  125. <span
  126. >供货总金额(元):<span class="sqxp-subtable-summary__amount"
  127. >¥{{ formatAmount(orderSupplierTotal(ord)) }}</span
  128. ></span
  129. >
  130. <span
  131. >售出总金额(元):<span class="sqxp-subtable-summary__amount"
  132. >¥{{ formatAmount(orderSellingTotal(ord)) }}</span
  133. ></span
  134. >
  135. </div>
  136. </div>
  137. <el-empty v-else description="暂无商品明细" :image-size="72" />
  138. </div>
  139. </template>
  140. </el-table-column>
  141. <el-table-column label="订单编号" min-width="180">
  142. <template #default="{ row: ord }">
  143. <el-button link type="primary" @click="toggleOrderExpand(ord)">{{ ord.orderNo }}</el-button>
  144. </template>
  145. </el-table-column>
  146. <el-table-column prop="clientName" label="客户名称" min-width="150" show-overflow-tooltip />
  147. <el-table-column label="区域" min-width="110" show-overflow-tooltip>
  148. <template #default="{ row: ord }">{{ ord.regionName || '—' }}</template>
  149. </el-table-column>
  150. <el-table-column label="订单金额(元)" min-width="130" align="right">
  151. <template #default="{ row: ord }">
  152. <span class="amount-text">¥{{ formatAmount(orderTotalAmount(ord)) }}</span>
  153. </template>
  154. </el-table-column>
  155. <el-table-column label="供货总金额(元)" min-width="140" align="right">
  156. <template #default="{ row: ord }">
  157. <span class="amount-text">¥{{ formatAmount(orderSupplierTotal(ord)) }}</span>
  158. </template>
  159. </el-table-column>
  160. <el-table-column label="订单状态" min-width="120">
  161. <template #default="{ row: ord }">
  162. <el-tag :type="orderStatusTagType(resolveOrderStatus(ord))" size="small">
  163. {{ orderStatusLabel(resolveOrderStatus(ord)) }}
  164. </el-tag>
  165. </template>
  166. </el-table-column>
  167. <el-table-column label="配送状态" min-width="120">
  168. <template #default="{ row: ord }">
  169. <el-tag :type="deliveryStatusTagType(resolveDeliveryStatus(ord))" size="small">
  170. {{ deliveryStatusLabel(resolveDeliveryStatus(ord)) }}
  171. </el-tag>
  172. </template>
  173. </el-table-column>
  174. <el-table-column label="支付状态" min-width="120">
  175. <template #default="{ row: ord }">
  176. <el-tag :type="payStatusTagType(resolvePayStatus(ord))" size="small">
  177. {{ payStatusLabel(resolvePayStatus(ord)) }}
  178. </el-tag>
  179. </template>
  180. </el-table-column>
  181. <el-table-column label="支付方式" min-width="110" align="center">
  182. <template #default="{ row: ord }">
  183. <el-tag :type="resolvePaymentMethod(ord) === 'offline' ? 'warning' : 'primary'" size="small">
  184. {{ paymentMethodLabel(resolvePaymentMethod(ord)) }}
  185. </el-tag>
  186. </template>
  187. </el-table-column>
  188. <el-table-column label="下单时间" min-width="170">
  189. <template #default="{ row: ord }">{{ ord.orderCreateAt || '—' }}</template>
  190. </el-table-column>
  191. </el-table>
  192. </div>
  193. </div>
  194. <el-dialog v-model="imagePreviewVisible" title="图片预览" width="820px" destroy-on-close>
  195. <el-image
  196. v-if="previewImageUrl"
  197. :src="previewImageUrl"
  198. fit="contain"
  199. style="width: 100%; height: 520px"
  200. />
  201. </el-dialog>
  202. <el-dialog v-model="videoPreviewVisible" title="视频播放" width="820px" destroy-on-close>
  203. <video
  204. v-if="previewVideoUrl"
  205. :src="previewVideoUrl"
  206. controls
  207. autoplay
  208. style="width: 100%; max-height: 520px"
  209. />
  210. </el-dialog>
  211. </div>
  212. </template>
  213. <script setup lang="ts">
  214. import { computed, ref } from 'vue'
  215. import { Document, VideoPlay } from '@element-plus/icons-vue'
  216. const ordersTableRef = ref()
  217. const props = withDefaults(
  218. defineProps<{
  219. detail: Record<string, any>
  220. counterpartyLabel?: string
  221. counterpartyName?: string
  222. }>(),
  223. {
  224. counterpartyLabel: '客户',
  225. counterpartyName: ''
  226. }
  227. )
  228. const VIDEO_URL_RE = /\.(mp4|webm|mov|m4v|avi|mkv)(\?|#|$)/i
  229. const voucherUrls = computed(() => {
  230. const v = props.detail?.voucherUrls
  231. return Array.isArray(v) ? v.filter(Boolean) : []
  232. })
  233. const treeItems = computed(() => {
  234. const items = props.detail?.items
  235. return Array.isArray(items) ? items : []
  236. })
  237. const orders = computed(() => treeItems.value.filter((x: any) => x && x.rowType === 'order'))
  238. const formatAmount = (val: number) => (Number(val || 0) || 0).toFixed(2)
  239. const formatQty = (val: number) => {
  240. const n = Number(val || 0)
  241. if (!Number.isFinite(n)) return '0'
  242. return Number.isInteger(n) ? String(n) : n.toFixed(4).replace(/\.?0+$/, '')
  243. }
  244. const formatMeasure = (row: any) => {
  245. const u = row.unitName || ''
  246. const m = row.measureValue
  247. if (m != null && m !== '') return `${m} · ${u || '—'}`
  248. return u || '—'
  249. }
  250. const formatMeasureValue = (v: unknown) => {
  251. if (v == null || v === '') return '-'
  252. const n = Number(v)
  253. if (Number.isNaN(n)) return '-'
  254. return n.toFixed(3).replace(/\.?0+$/, '')
  255. }
  256. const toggleOrderExpand = (ord: any) => {
  257. ordersTableRef.value?.toggleRowExpansion?.(ord)
  258. }
  259. const orderSupplierTotal = (orderRow: any) => {
  260. const children = Array.isArray(orderRow?.children) ? orderRow.children : []
  261. return children.reduce((acc: number, ln: any) => acc + Number(ln?.supplierAmount || 0), 0)
  262. }
  263. const orderSellingTotal = (orderRow: any) => {
  264. const children = Array.isArray(orderRow?.children) ? orderRow.children : []
  265. return children.reduce((acc: number, ln: any) => acc + Number(ln?.sellingAmount || 0), 0)
  266. }
  267. const isVideoUrl = (url: string) => VIDEO_URL_RE.test(url || '')
  268. const imagePreviewVisible = ref(false)
  269. const videoPreviewVisible = ref(false)
  270. const previewImageUrl = ref('')
  271. const previewVideoUrl = ref('')
  272. const openVoucher = (url: string) => {
  273. if (!url) return
  274. if (isVideoUrl(url)) {
  275. previewVideoUrl.value = url
  276. videoPreviewVisible.value = true
  277. } else {
  278. previewImageUrl.value = url
  279. imagePreviewVisible.value = true
  280. }
  281. }
  282. const ORDER_STATUS_LABEL: Record<string, string> = {
  283. pending_payment: '待支付',
  284. pending_review_cancel: '待审核取消',
  285. pending_delivery: '待分配配送',
  286. delivering: '配送中',
  287. partial_delivered: '部分送达',
  288. pending_confirm: '待确认收货',
  289. completed: '已完结',
  290. cancelled: '已取消'
  291. }
  292. const orderStatusLabel = (s: string) => ORDER_STATUS_LABEL[s] || s || '—'
  293. const resolveOrderStatus = (row: any) => {
  294. if (row?.cancelStatus === 'pending_review') return 'pending_review_cancel'
  295. return row?.orderStatus || row?.status || ''
  296. }
  297. const orderStatusTagType = (s: string) => {
  298. if (s === 'completed') return 'success'
  299. if (s === 'cancelled') return 'info'
  300. if (s === 'pending_payment') return 'warning'
  301. return 'primary'
  302. }
  303. const DELIVERY_STATUS_LABEL: Record<string, string> = {
  304. pending_dispatch: '待分配配送',
  305. pending_delivery: '待配送',
  306. delivering: '配送中',
  307. partial_delivered: '部分送达',
  308. delivered: '配送完成',
  309. pending: '待取货',
  310. picking: '取货中',
  311. completed: '已完成'
  312. }
  313. const resolveDeliveryStatus = (row: any) =>
  314. row?.deliveryStatus ||
  315. (['pending_payment', 'pending_dispatch', 'pending_delivery', 'pending_review_cancel'].includes(
  316. resolveOrderStatus(row)
  317. )
  318. ? 'pending_dispatch'
  319. : resolveOrderStatus(row) === 'delivering'
  320. ? 'delivering'
  321. : resolveOrderStatus(row) === 'partial_delivered'
  322. ? 'partial_delivered'
  323. : ['pending_confirm', 'completed'].includes(resolveOrderStatus(row))
  324. ? 'delivered'
  325. : 'pending_dispatch')
  326. const deliveryStatusLabel = (s: string) => DELIVERY_STATUS_LABEL[s] || s || '—'
  327. const deliveryStatusTagType = (s: string) => {
  328. if (s === 'delivered' || s === 'completed') return 'success'
  329. if (s === 'delivering') return 'info'
  330. if (s === 'partial_delivered' || s === 'pending_dispatch' || s === 'pending_delivery') return 'warning'
  331. if (s === 'picking') return 'primary'
  332. return 'info'
  333. }
  334. const resolvePayStatus = (row: any) =>
  335. row?.payStatus || (Number(row?.paidAmount || 0) > 0 ? 'paid' : 'pending_payment')
  336. const payStatusLabel = (s: string) => (s === 'paid' ? '已支付' : s === 'pending_payment' ? '待支付' : s || '—')
  337. const payStatusTagType = (s: string) => (s === 'paid' ? 'success' : s === 'pending_payment' ? 'warning' : 'info')
  338. const resolvePaymentMethod = (row: any) => String(row?.paymentMethod || '').toLowerCase()
  339. const paymentMethodLabel = (m: string) => {
  340. if (['online', 'wechat', 'wx'].includes(m)) return '线上支付'
  341. if (m === 'offline') return '线下支付'
  342. return m || '-'
  343. }
  344. const orderTotalAmount = (row: any) =>
  345. Number(row?.orderAmount ?? row?.totalAmount ?? row?.sellingTotalAmount ?? row?.sellingAmount ?? 0)
  346. const orderReceivableAmount = (row: any) => Number(row?.receivableAmount ?? orderTotalAmount(row))
  347. const paymentLabel = (m: string) => {
  348. if (m === 'offline') return '线下结算'
  349. if (m === 'online') return '线上支付'
  350. return m || '—'
  351. }
  352. </script>
  353. <style scoped lang="scss">
  354. .sheet-detail-panel {
  355. .view-hero {
  356. display: flex;
  357. gap: 16px;
  358. padding: 20px 22px;
  359. background: linear-gradient(135deg, #ecfdf5 0%, #ffffff 55%);
  360. border-bottom: 1px solid var(--mint-border, #d9e8e2);
  361. align-items: center;
  362. }
  363. .view-hero-icon {
  364. width: 72px;
  365. height: 72px;
  366. border-radius: 12px;
  367. border: 1px solid rgba(16, 185, 129, 0.2);
  368. background: rgba(16, 185, 129, 0.08);
  369. color: #059669;
  370. display: inline-flex;
  371. align-items: center;
  372. justify-content: center;
  373. font-size: 28px;
  374. flex: 0 0 auto;
  375. }
  376. .view-hero-main h2 {
  377. margin: 0 0 8px;
  378. font-size: 18px;
  379. font-weight: 700;
  380. color: var(--mint-text, #1e293b);
  381. }
  382. .view-hero-tags {
  383. display: flex;
  384. align-items: center;
  385. gap: 8px;
  386. margin-bottom: 8px;
  387. flex-wrap: wrap;
  388. }
  389. .view-hero-meta {
  390. margin: 0;
  391. font-size: 13px;
  392. color: var(--mint-text-muted, #64748b);
  393. line-height: 1.5;
  394. }
  395. .dot {
  396. margin: 0 6px;
  397. opacity: 0.7;
  398. }
  399. .view-section {
  400. padding: 18px 22px;
  401. border-bottom: 1px solid var(--mint-border, #d9e8e2);
  402. }
  403. .view-section:last-child {
  404. border-bottom: none;
  405. }
  406. .view-section h3 {
  407. margin: 0 0 14px;
  408. font-size: 13px;
  409. font-weight: 700;
  410. letter-spacing: 0.06em;
  411. color: var(--mint-text-muted, #64748b);
  412. }
  413. .amount-text {
  414. color: #dc2626;
  415. font-weight: 700;
  416. }
  417. .detail-block-title {
  418. margin: 18px 0 12px;
  419. font-weight: 600;
  420. font-size: 15px;
  421. color: var(--mint-text, #1e293b);
  422. padding-left: 12px;
  423. border-left: 4px solid #10b981;
  424. }
  425. :deep(.el-descriptions) {
  426. --el-descriptions-border-color: var(--mint-border, #d9e8e2);
  427. border-radius: 10px;
  428. overflow: hidden;
  429. background: #fff;
  430. }
  431. :deep(.el-descriptions__label) {
  432. color: var(--mint-text-muted, #64748b);
  433. font-size: 12px;
  434. font-weight: 600;
  435. background: #f8fafc;
  436. }
  437. :deep(.el-descriptions__content) {
  438. color: var(--mint-text, #1e293b);
  439. font-weight: 500;
  440. }
  441. .voucher-preview-grid {
  442. display: flex;
  443. flex-wrap: wrap;
  444. gap: 12px;
  445. }
  446. .voucher-tile {
  447. position: relative;
  448. width: 120px;
  449. height: 100px;
  450. border-radius: 10px;
  451. overflow: hidden;
  452. cursor: pointer;
  453. border: 1px solid var(--mint-border, #d9e8e2);
  454. box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  455. background: #fff;
  456. &:hover .voucher-tile-play {
  457. opacity: 1;
  458. }
  459. }
  460. .voucher-thumb {
  461. width: 100%;
  462. height: 100%;
  463. object-fit: cover;
  464. display: block;
  465. }
  466. .voucher-tile-play {
  467. position: absolute;
  468. inset: 0;
  469. display: flex;
  470. align-items: center;
  471. justify-content: center;
  472. background: rgba(0, 0, 0, 0.35);
  473. color: #fff;
  474. opacity: 0.8;
  475. transition: opacity 0.2s;
  476. }
  477. .detail-orders-list {
  478. margin-top: 4px;
  479. border: 1px solid var(--mint-border, #d9e8e2);
  480. border-radius: 10px;
  481. overflow: hidden;
  482. background: #fff;
  483. }
  484. .orders-table {
  485. margin-top: 0;
  486. }
  487. .orders-table :deep(th.el-table__cell > .cell),
  488. .orders-table :deep(td.el-table__cell > .cell) {
  489. display: flex;
  490. align-items: center;
  491. justify-content: center;
  492. }
  493. .orders-table :deep(td.el-table__cell.el-table__expand-column > .cell) {
  494. font-size: 0;
  495. line-height: 0;
  496. overflow: hidden;
  497. }
  498. .orders-table :deep(.el-table__expand-icon) {
  499. width: 28px;
  500. height: 28px;
  501. border-radius: 6px;
  502. border: 1px solid var(--mint-border, #d9e8e2);
  503. display: inline-flex;
  504. align-items: center;
  505. justify-content: center;
  506. transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
  507. color: var(--mint-text-muted, #64748b);
  508. background: #fff;
  509. font-size: 0;
  510. line-height: 0;
  511. }
  512. .orders-table :deep(.el-table__expand-icon:hover) {
  513. background: var(--mint-primary-bg, #ecfdf5);
  514. border-color: #10b981;
  515. color: var(--mint-primary-dark, #059669);
  516. }
  517. .orders-table :deep(.el-table__expand-icon--expanded) {
  518. background: var(--mint-primary-bg, #ecfdf5);
  519. border-color: #10b981;
  520. color: var(--mint-primary-dark, #059669);
  521. }
  522. .orders-table :deep(.el-table__expand-icon svg) {
  523. width: 14px;
  524. height: 14px;
  525. transition: transform 0.15s ease;
  526. }
  527. .orders-table :deep(.el-table__expand-icon--expanded svg) {
  528. transform: rotate(180deg);
  529. }
  530. .order-row-expand-wrap {
  531. padding: 0;
  532. background: #f8fafc;
  533. border-radius: 0;
  534. }
  535. :deep(td.el-table__expanded-cell) {
  536. padding: 0 !important;
  537. text-align: left !important;
  538. }
  539. :deep(td.el-table__expanded-cell > .cell) {
  540. display: block !important;
  541. padding: 0 !important;
  542. text-align: left !important;
  543. }
  544. .order-row-expand-table {
  545. width: 100%;
  546. max-width: 100%;
  547. border: 1px solid var(--mint-border, #d9e8e2);
  548. border-radius: 8px;
  549. overflow: hidden;
  550. background: #fff;
  551. :deep(.el-table__body-wrapper) {
  552. overflow-x: auto;
  553. }
  554. :deep(th.el-table__cell) {
  555. background: #e2e8f0 !important;
  556. color: var(--mint-text-muted, #64748b);
  557. font-size: 11px;
  558. font-weight: 600;
  559. }
  560. :deep(.el-table__cell) {
  561. padding: 8px 10px;
  562. }
  563. }
  564. .settlement-row-expand-table-wrap {
  565. display: block;
  566. width: 100%;
  567. max-width: 100%;
  568. overflow: hidden;
  569. border-radius: 0;
  570. text-align: left;
  571. position: relative;
  572. background: #f8fafc;
  573. padding: 12px 384px 14px 16px;
  574. :deep(.el-table__inner-wrapper),
  575. :deep(.el-table__header-wrapper),
  576. :deep(.el-table__body-wrapper) {
  577. width: 100%;
  578. }
  579. }
  580. .settlement-row-expand-table-wrap::before {
  581. content: '';
  582. position: absolute;
  583. left: 0;
  584. top: 0;
  585. bottom: 0;
  586. width: 3px;
  587. background: #10b981;
  588. }
  589. .order-row-expand-summary {
  590. margin-top: 10px;
  591. display: flex;
  592. gap: 20px;
  593. justify-content: flex-end;
  594. color: #606266;
  595. font-size: 13px;
  596. }
  597. .order-row-head {
  598. display: flex;
  599. align-items: center;
  600. gap: 8px;
  601. flex-wrap: wrap;
  602. margin-bottom: 4px;
  603. }
  604. .order-row-meta {
  605. font-size: 12px;
  606. line-height: 1.5;
  607. color: #606266;
  608. &.muted {
  609. color: #909399;
  610. }
  611. }
  612. .expand-product-cell {
  613. display: inline-flex;
  614. align-items: center;
  615. gap: 10px;
  616. max-width: 100%;
  617. min-width: 0;
  618. }
  619. .expand-product-thumb-wrap {
  620. flex: 0 0 auto;
  621. }
  622. .expand-product-thumb {
  623. width: 34px;
  624. height: 34px;
  625. border-radius: 6px;
  626. display: block;
  627. }
  628. .expand-product-thumb.placeholder {
  629. width: 34px;
  630. height: 34px;
  631. border-radius: 6px;
  632. display: flex;
  633. align-items: center;
  634. justify-content: center;
  635. font-size: 11px;
  636. color: #909399;
  637. background: #f5f7fa;
  638. border: 1px dashed #dcdfe6;
  639. }
  640. .expand-product-text {
  641. display: flex;
  642. flex-direction: column;
  643. gap: 2px;
  644. min-width: 0;
  645. }
  646. .expand-product-name {
  647. min-width: 0;
  648. overflow: hidden;
  649. text-overflow: ellipsis;
  650. white-space: nowrap;
  651. font-size: 13px;
  652. }
  653. .expand-product-note {
  654. font-size: 12px;
  655. color: #909399;
  656. min-width: 0;
  657. overflow: hidden;
  658. text-overflow: ellipsis;
  659. white-space: nowrap;
  660. }
  661. .cell-muted {
  662. color: #c0c4cc;
  663. }
  664. .ml-1 {
  665. margin-left: 4px;
  666. }
  667. }
  668. </style>