调整结算模块

This commit is contained in:
2026-09-07 19:37:27 +08:00
parent 0d070d4b34
commit a7315b4491
21 changed files with 1876 additions and 635 deletions
@@ -1,6 +1,14 @@
<template>
<el-dialog v-model="visible" :title="title" width="98%" top="2vh" append-to-body destroy-on-close>
<div v-loading="loading" class="reconciliation-editor">
<component
:is="editorContainer"
v-bind="editorContainerProps"
@update:model-value="visible = $event"
>
<div
v-loading="loading"
class="reconciliation-editor"
:class="{ 'reconciliation-editor--page': pageMode }"
>
<section-card title="导入外部账单,与内部账单核对">
<el-form
ref="formRef"
@@ -98,17 +106,34 @@
</div>
</div>
<div class="reconciliation-editor__filter">
<el-input v-model="internalQuery.documentNo" placeholder="单据号" clearable />
<el-input v-model="internalQuery.vehicleNo" placeholder="车号" clearable />
<el-input v-model="internalQuery.batchNo" placeholder="批次号" clearable />
<el-input v-model="internalQuery.cargoName" placeholder="货物名称" clearable />
<div class="reconciliation-editor__filter-item">
<span class="reconciliation-editor__filter-label">单据号</span>
<el-input v-model="internalQuery.documentNo" placeholder="请输入" clearable />
</div>
<div class="reconciliation-editor__filter-item">
<span class="reconciliation-editor__filter-label">车号</span>
<el-input v-model="internalQuery.vehicleNo" placeholder="请输入" clearable />
</div>
<div class="reconciliation-editor__filter-item">
<span class="reconciliation-editor__filter-label">批次号</span>
<el-input v-model="internalQuery.batchNo" placeholder="请输入" clearable />
</div>
<div class="reconciliation-editor__filter-item">
<span class="reconciliation-editor__filter-label">货物名称</span>
<el-input v-model="internalQuery.cargoName" placeholder="请输入" clearable />
</div>
<el-button @click="resetInternalQuery">重置</el-button>
<el-button type="primary" @click="internalFilterTick++">查询</el-button>
</div>
<el-table :data="filteredInternalRows" border max-height="420">
<el-table
:data="filteredInternalRows"
border
max-height="420"
:row-class-name="internalRowClassName"
>
<el-table-column type="index" label="序号" width="64" fixed="left" align="center" />
<el-table-column
v-for="column in internalColumns"
v-for="column in internalTableColumns"
:key="column.prop"
v-bind="column"
align="center"
@@ -133,6 +158,9 @@
<span v-else-if="column.prop === 'transportQuantity'">
{{ formatTransportQuantity(row.transportQuantity) }}
</span>
<span v-else-if="column.feeItemName">
{{ formatMoney(getFeeItemAmount(row, column.feeItemName)) }}
</span>
<span v-else-if="column.prop === 'mileage'">{{ formatMileage(row.mileage) }}</span>
<span
v-else-if="
@@ -149,17 +177,11 @@
<div class="reconciliation-editor__links">
<el-link v-if="editable" type="primary" @click="openAdjust(row)">调整</el-link>
<el-link
v-if="editable && row.matchResult === 'matched'"
v-if="editable && ['matched', 'partial'].includes(row.matchResult)"
type="primary"
@click="handleUnmatch(row)"
>取消匹配</el-link
>
<el-link
v-if="editable && row.matchResult !== 'matched'"
type="primary"
@click="openManualMatch(row)"
>人工匹配</el-link
>
</div>
</template>
</el-table-column>
@@ -192,7 +214,12 @@
<el-tab-pane :label="`导入明细(${externalDetails.length}`" name="all" />
<el-tab-pane :label="`疑似重复(${duplicateRows.length}`" name="duplicate" />
</el-tabs>
<el-table :data="visibleExternalRows" border max-height="420">
<el-table
:data="visibleExternalRows"
border
max-height="420"
:row-class-name="externalRowClassName"
>
<el-table-column
v-for="column in externalColumns"
:key="column.prop"
@@ -204,12 +231,57 @@
<el-tag v-if="column.prop === 'matchStatus'" :type="matchTagType(row.matchStatus)" class="status-text">{{
matchName(row.matchStatus)
}}</el-tag>
<template v-else-if="isExternalRowEditing(row) && isExternalEditableColumn(column.prop)">
<el-input-number
v-if="column.feeItemName"
v-model="row.feeItems[column.feeItemName]"
:min="0"
:precision="2"
:controls="false"
size="small"
/>
<el-date-picker
v-else-if="isExternalDateColumn(column.prop)"
v-model="row[column.prop]"
type="date"
value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
size="small"
placeholder="请选择"
/>
<el-input-number
v-else-if="isExternalNumberColumn(column.prop)"
v-model="row[column.prop]"
:min="0"
:precision="2"
:controls="false"
size="small"
/>
<el-select
v-else-if="column.prop === 'transportType'"
v-model="row[column.prop]"
size="small"
clearable
placeholder="请选择"
>
<el-option
v-for="item in transportTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-input v-else v-model="row[column.prop]" size="small" />
</template>
<span v-else-if="column.prop === 'transportType'">
{{ transportTypeLabel(row.transportType) }}
</span>
<span v-else-if="column.prop === 'transportQuantity'">
{{ formatTransportQuantity(row.transportQuantity) }}
</span>
<span v-else-if="column.feeItemName">
{{ formatMoney(getFeeItemAmount(row, column.feeItemName)) }}
</span>
<span v-else-if="column.prop === 'mileage'">{{ formatMileage(row.mileage) }}</span>
<span
v-else-if="
@@ -221,21 +293,24 @@
<span v-else>{{ displayValue(row[column.prop]) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="90" fixed="right" align="center">
<template #default="{ row }"
><el-link
v-if="editable && row.matchStatus !== 'matched'"
type="primary"
@click="openManualMatchByExternal(row)"
>匹配</el-link
></template
>
<el-table-column label="操作" width="150" fixed="right" align="center">
<template #default="{ row }">
<div class="reconciliation-editor__links">
<template v-if="editable && isExternalRowEditing(row)">
<el-link type="primary" @click="finishExternalAdjust(row)">完成</el-link>
<el-link type="primary" @click="cancelExternalAdjust(row)">取消</el-link>
</template>
<el-link v-else-if="editable" type="primary" @click="openExternalAdjust(row)">
调整
</el-link>
</div>
</template>
</el-table-column>
</el-table>
</section-card>
</div>
<template #footer>
<template v-if="!pageMode" #footer>
<el-button @click="visible = false">取消</el-button>
<template v-if="editable">
<el-button type="primary" plain :loading="saving" @click="handleSave">保存草稿</el-button>
@@ -248,6 +323,18 @@
</template>
</template>
<div v-if="pageMode" class="reconciliation-editor__page-actions">
<el-button @click="visible = false">取消</el-button>
<template v-if="editable">
<el-button type="primary" plain :loading="actionLoading" @click="handleUpdate">
按匹配结果更新账单
</el-button>
<el-button type="primary" :loading="actionLoading" @click="handleComplete">
完成对账
</el-button>
</template>
</div>
<el-dialog v-model="formalDialog.visible" title="选择正式结算单" width="84%" append-to-body>
<el-form :model="formalDialog.query" inline label-position="right" label-width="88px">
<el-form-item label="正式结算单号"
@@ -335,34 +422,7 @@
>
</el-dialog>
<el-dialog v-model="manualDialog.visible" title="选择外部账单明细" width="86%" append-to-body>
<el-table :data="unmatchedExternalRows" border @row-click="manualDialog.selected = $event">
<el-table-column type="index" label="序号" width="64" />
<el-table-column prop="externalLineNo" label="外部行号" width="90" />
<el-table-column prop="vehicleNo" label="车牌号" width="110" />
<el-table-column prop="cargoName" label="货物名称" min-width="140" />
<el-table-column prop="transportQuantity" label="运输量" width="110"
><template #default="{ row }">{{
formatTransportQuantity(row.transportQuantity)
}}</template></el-table-column
>
<el-table-column prop="settlementAmount" label="结算金额" width="130"
><template #default="{ row }">{{
formatMoney(row.settlementAmount)
}}</template></el-table-column
>
<el-table-column label="选择" width="80"
><template #default="{ row }"
><el-radio v-model="manualDialog.selected" :label="row">&nbsp;</el-radio></template
></el-table-column
>
</el-table>
<template #footer
><el-button @click="manualDialog.visible = false">取消</el-button
><el-button type="primary" @click="confirmManualMatch">确定</el-button></template
>
</el-dialog>
</el-dialog>
</component>
</template>
<script>
@@ -385,6 +445,7 @@ export default {
recordId: [String, Number],
settlementType: { type: String, default: 'payable' },
readonly: Boolean,
pageMode: Boolean,
},
emits: ['update:modelValue', 'success'],
data() {
@@ -411,7 +472,9 @@ export default {
page: { current: 1, size: 10, total: 0 },
},
adjustDialog: { visible: false, saving: false, rows: [], reason: '' },
manualDialog: { visible: false, internal: null, selected: null },
externalEditing: {},
externalEditSnapshots: {},
matchingStarted: false,
rules: {
formalSettlementNo: [{ required: true, message: '请选择正式结算单', trigger: 'change' }],
reconciliationMode: [{ required: true, message: '请选择对账模式', trigger: 'change' }],
@@ -429,6 +492,22 @@ export default {
this.$emit('update:modelValue', value);
},
},
editorContainer() {
return this.pageMode ? 'div' : 'el-dialog';
},
editorContainerProps() {
if (this.pageMode) {
return { class: 'reconciliation-editor-shell reconciliation-editor-shell--page' };
}
return {
modelValue: this.visible,
title: this.title,
width: '98%',
top: '2vh',
appendToBody: true,
destroyOnClose: true,
};
},
editable() {
return !this.readonly;
},
@@ -442,7 +521,7 @@ export default {
filteredInternalRows() {
void this.internalFilterTick;
const query = this.internalQuery;
return this.internalDetails.filter(
return this.groupedInternalRows.filter(
row =>
(!query.documentNo || String(row.documentNo || '').includes(query.documentNo)) &&
(!query.vehicleNo || String(row.vehicleNo || '').includes(query.vehicleNo)) &&
@@ -450,10 +529,62 @@ export default {
(!query.cargoName || String(row.cargoName || '').includes(query.cargoName))
);
},
groupedInternalRows() {
const groups = new Map();
this.internalDetails.forEach((row, index) => {
const key = row.documentNo ? String(row.documentNo) : `__row_${index}`;
if (!groups.has(key)) groups.set(key, []);
groups.get(key).push(row);
});
return [...groups.values()].map(rows => this.mergeInternalRows(rows));
},
internalFeeItemNames() {
const names = new Set();
this.internalDetails.forEach(row => {
Object.keys(row.feeItems || this.parseFeeItems(row.feeItemsJson)).forEach(name => {
if (name) names.add(name);
});
});
return [...names];
},
internalTableColumns() {
const columns = internalColumns.filter(column => column.prop !== 'freightAmount');
const settlementIndex = columns.findIndex(column => column.prop === 'settlementAmount');
const feeColumns = this.internalFeeItemNames.map((name, index) => ({
prop: `feeItem_${index}`,
label: name,
minWidth: 120,
money: true,
feeItemName: name,
}));
columns.splice(settlementIndex < 0 ? columns.length : settlementIndex, 0, ...feeColumns);
return columns;
},
externalColumns() {
return this.form.reconciliationMode === 'cargo'
? externalCargoColumns
: externalVehicleColumns;
const columns = [
...(this.form.reconciliationMode === 'cargo'
? externalCargoColumns
: externalVehicleColumns),
];
const settlementIndex = columns.findIndex(column => column.prop === 'settlementAmount');
const feeColumns = this.externalFeeItemNames.map((name, index) => ({
prop: `externalFeeItem_${index}`,
label: name,
minWidth: 120,
money: true,
feeItemName: name,
}));
columns.splice(settlementIndex < 0 ? columns.length : settlementIndex, 0, ...feeColumns);
return columns;
},
externalFeeItemNames() {
const names = new Set();
this.externalDetails.forEach(row => {
Object.keys(row.feeItems || this.parseFeeItems(row.feeItemsJson)).forEach(name => {
if (name) names.add(name);
});
});
return [...names];
},
duplicateRows() {
return this.externalDetails.filter(
@@ -466,15 +597,13 @@ export default {
visibleExternalRows() {
return this.externalTab === 'duplicate' ? this.duplicateRows : this.externalDetails;
},
unmatchedExternalRows() {
return this.externalDetails.filter(
row => row.matchStatus !== 'matched' && !row.suspectedDuplicate
);
},
},
watch: {
modelValue(value) {
if (value) this.initialize();
modelValue: {
immediate: true,
handler(value) {
if (value) this.initialize();
},
},
},
methods: {
@@ -484,6 +613,7 @@ export default {
reconciliationMode: 'vehicle',
formalSettlementId: null,
formalSettlementNo: '',
customerName: '',
payerName: '',
payeeName: '',
projectName: '',
@@ -512,6 +642,9 @@ export default {
this.form = this.emptyForm();
this.internalDetails = [];
this.externalDetails = [];
this.externalEditing = {};
this.externalEditSnapshots = {};
this.matchingStarted = false;
this.externalTab = 'all';
this.internalQuery = { documentNo: '', vehicleNo: '', batchNo: '', cargoName: '' };
if (!this.currentId) {
@@ -530,11 +663,27 @@ export default {
},
async loadDetail() {
const data = this.unwrapData(await api.getDetail(this.currentId)) || {};
this.form = { ...this.emptyForm(), ...data };
this.internalDetails =
data.internalDetails || data.internalBillDetails || data.internals || [];
this.externalDetails =
data.externalDetails || data.externalBillDetails || data.externals || [];
this.form = {
...this.emptyForm(),
...data,
customerName:
data.customerName ||
((data.settlementType || this.settlementType) === 'receivable'
? data.payerName
: data.payeeName) ||
'',
};
const internalRows = data.internalDetails || data.internalBillDetails || data.internals || [];
this.internalDetails = internalRows.map(row => this.normalizeInternalRow(row));
const externalRows = data.externalDetails || data.externalBillDetails || data.externals || [];
this.externalDetails = externalRows.map((row, index) =>
this.normalizeExternalRow(row, index)
);
this.matchingStarted =
this.matchingStarted ||
data.matchStatus === 'partial' ||
this.internalDetails.some(row => row.matchResult === 'matched') ||
this.externalDetails.some(row => row.matchStatus === 'matched');
},
openFormalDialog() {
if (!this.editable) return;
@@ -542,6 +691,80 @@ export default {
this.formalDialog.page.current = 1;
this.loadFormalOptions();
},
parseFeeItems(value) {
if (!value) return {};
if (typeof value === 'object' && !Array.isArray(value)) return value;
try {
const parsed = JSON.parse(value);
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};
} catch {
return {};
}
},
normalizeInternalRow(row) {
const feeItems =
row.feeItems && typeof row.feeItems === 'object' && Object.keys(row.feeItems).length
? row.feeItems
: this.parseFeeItems(row.feeItemsJson);
return { ...row, feeItems };
},
normalizeExternalRow(row, index) {
const feeItems =
row.feeItems && typeof row.feeItems === 'object' && Object.keys(row.feeItems).length
? row.feeItems
: this.parseFeeItems(row.feeItemsJson);
return {
...row,
feeItems,
_externalKey: row.id || row.externalLineNo || `external-${index}`,
};
},
mergeInternalRows(rows) {
const firstRow = rows[0] || {};
const feeItems = {};
rows.forEach(row => {
Object.entries(row.feeItems || this.parseFeeItems(row.feeItemsJson)).forEach(
([name, amount]) => {
feeItems[name] = Number(feeItems[name] || 0) + Number(amount || 0);
}
);
});
const matchResults = rows.map(row => row.matchResult);
const updateResults = rows.map(row => row.updateResult);
return {
...firstRow,
cargoName: this.joinInternalValues(rows, 'cargoName'),
cargoType: this.joinInternalValues(rows, 'cargoType'),
transportQuantity: this.sumInternalValues(rows, 'transportQuantity'),
settlementAmount: this.sumInternalValues(rows, 'settlementAmount'),
feeItems,
matchedExternalLineNo: this.joinInternalValues(rows, 'matchedExternalLineNo'),
matchResult: matchResults.every(value => value === 'matched')
? 'matched'
: matchResults.some(value => value === 'matched')
? 'partial'
: 'unmatched',
updateResult: updateResults.every(value => value === updateResults[0])
? updateResults[0]
: 'partial_updated',
_sourceRows: rows,
};
},
joinInternalValues(rows, prop) {
return [
...new Set(
rows
.map(row => row[prop])
.filter(value => value !== null && value !== undefined && value !== '')
),
].join('、');
},
sumInternalValues(rows, prop) {
return rows.reduce((total, row) => total + Number(row[prop] || 0), 0);
},
getFeeItemAmount(row, name) {
return (row.feeItems || this.parseFeeItems(row.feeItemsJson))[name] ?? 0;
},
async loadFormalOptions() {
this.formalDialog.loading = true;
try {
@@ -586,25 +809,35 @@ export default {
...selected,
formalSettlementId: selected.id,
formalSettlementNo: selected.formalSettlementNo,
customerName:
selected.customerName ||
((selected.settlementType || this.settlementType) === 'receivable'
? selected.payerName
: selected.payeeName) ||
'',
reconciliationNo: this.form.reconciliationNo,
};
if (formalSettlementChanged) this.externalDetails = [];
if (formalSettlementChanged) {
this.externalDetails = [];
this.matchingStarted = false;
}
await this.loadFormalInternalPreview(selected.id);
this.formalDialog.visible = false;
},
async loadFormalInternalPreview(formalSettlementId) {
const formal = this.unwrapData(await formalSettlementApi.getDetail(formalSettlementId));
const details = formal.details || [];
const buildInternalRow = (detail, overrides = {}, index = 0) => ({
...detail,
...overrides,
id: null,
lineNo: index + 1,
formalSettlementDetailId: detail.id,
settlementAmount: overrides.settlementAmount ?? detail.settlementAmountTax ?? 0,
matchResult: 'unmatched',
updateResult: 'not_updated',
});
const buildInternalRow = (detail, overrides = {}, index = 0) =>
this.normalizeInternalRow({
...detail,
...overrides,
id: null,
lineNo: index + 1,
formalSettlementDetailId: detail.id,
settlementAmount: overrides.settlementAmount ?? detail.settlementAmountTax ?? 0,
matchResult: 'unmatched',
updateResult: 'not_updated',
});
if (this.form.reconciliationMode === 'cargo') {
const feeGroups = await Promise.all(
details.map(async detail => ({
@@ -688,7 +921,7 @@ export default {
await this.loadDetail();
if (!silent) {
this.$message.success('草稿保存成功');
this.$emit('success');
this.$emit('success', this.currentId);
}
return data;
} finally {
@@ -701,6 +934,7 @@ export default {
try {
await api.match(this.currentId);
await this.loadDetail();
this.matchingStarted = true;
this.$message.success('匹配完成');
} finally {
this.actionLoading = false;
@@ -740,7 +974,7 @@ export default {
await this.loadDetail();
this.$message.success('对账完成');
this.visible = false;
this.$emit('success');
this.$emit('success', this.currentId);
} finally {
this.actionLoading = false;
}
@@ -773,7 +1007,9 @@ export default {
if (result.code !== 200) throw new Error(result.msg || '导入失败');
this.$message.success('外部账单导入成功');
}
this.matchingStarted = false;
await this.loadDetail();
this.matchingStarted = false;
} catch (error) {
this.$message.error(error.message || '外部账单导入失败');
}
@@ -794,9 +1030,9 @@ export default {
visible: true,
saving: false,
reason: '',
rows: this.internalDetails
.filter(item => item.formalSettlementDetailId === row.formalSettlementDetailId)
.map(item => ({ ...item })),
rows: (row._sourceRows || this.internalDetails.filter(
item => item.formalSettlementDetailId === row.formalSettlementDetailId
)).map(item => ({ ...item })),
};
},
async saveAdjust() {
@@ -817,26 +1053,85 @@ export default {
}
},
async handleUnmatch(row) {
await api.unmatch(row.id);
const matchedRows = (row._sourceRows || [row]).filter(item => item.matchResult === 'matched');
for (const item of matchedRows) await api.unmatch(item.id);
await this.loadDetail();
},
openManualMatch(row) {
this.manualDialog = { visible: true, internal: row, selected: null };
internalRowClassName({ row }) {
return this.matchingStarted && row.matchResult !== 'matched'
? 'reconciliation-editor__row--unmatched'
: '';
},
openManualMatchByExternal(row) {
this.manualDialog = { visible: true, internal: null, selected: row };
externalRowClassName({ row }) {
return this.matchingStarted && row.matchStatus !== 'matched'
? 'reconciliation-editor__row--unmatched'
: '';
},
async confirmManualMatch() {
if (!this.manualDialog.selected) return this.$message.warning('请选择外部账单明细');
if (!this.manualDialog.internal) return this.$message.warning('请从内部账单行发起人工匹配');
await api.manualMatch({
reconciliationId: this.currentId,
internalId: this.manualDialog.internal.id,
externalId: this.manualDialog.selected.id,
});
this.manualDialog.visible = false;
await this.loadDetail();
this.$message.success('人工匹配成功');
externalRowKey(row) {
return String(row.id || row.externalLineNo || row._externalKey || '');
},
isExternalRowEditing(row) {
return Boolean(this.externalEditing[this.externalRowKey(row)]);
},
isExternalEditableColumn(prop) {
return !['externalLineNo', 'matchStatus'].includes(prop);
},
isExternalDateColumn(prop) {
return ['actualDepartureTime', 'actualCompletionTime'].includes(prop);
},
isExternalNumberColumn(prop) {
return ['transportQuantity', 'mileage', 'unitPrice', 'freightAmount', 'settlementAmount'].includes(prop);
},
openExternalAdjust(row) {
const key = this.externalRowKey(row);
this.externalEditSnapshots = {
...this.externalEditSnapshots,
[key]: { ...row },
};
this.externalEditing = { ...this.externalEditing, [key]: true };
},
cancelExternalAdjust(row) {
const key = this.externalRowKey(row);
const snapshot = this.externalEditSnapshots[key];
if (snapshot) Object.assign(row, snapshot);
const editing = { ...this.externalEditing };
const snapshots = { ...this.externalEditSnapshots };
delete editing[key];
delete snapshots[key];
this.externalEditing = editing;
this.externalEditSnapshots = snapshots;
},
finishExternalAdjust(row) {
row.feeItemsJson = JSON.stringify(row.feeItems || {});
const key = this.externalRowKey(row);
const editing = { ...this.externalEditing };
const snapshots = { ...this.externalEditSnapshots };
delete editing[key];
delete snapshots[key];
this.externalEditing = editing;
this.externalEditSnapshots = snapshots;
this.refreshExternalStats();
},
refreshExternalStats() {
const externalQuantity = this.externalDetails.reduce(
(total, item) => total + Number(item.transportQuantity || 0),
0
);
const externalAmount = this.externalDetails.reduce(
(total, item) => total + Number(item.settlementAmount || 0),
0
);
const matchedCount = this.externalDetails.filter(item => item.matchStatus === 'matched').length;
this.form = {
...this.form,
externalBillCount: this.externalDetails.length,
externalQuantity,
externalAmount,
differenceQuantity: Math.abs(Number(this.form.internalQuantity || 0) - externalQuantity),
differenceAmount: Math.abs(Number(this.form.internalAmount || 0) - externalAmount),
matchedCount,
unmatchedCount: Math.max(Number(this.form.internalBillCount || 0), this.externalDetails.length) - matchedCount,
};
},
matchName(value) {
return (
@@ -863,6 +1158,7 @@ export default {
updated: '已更新',
skipped_multi_cargo: '跳过更新',
manually_adjusted: '手工调整',
partial_updated: '部分更新',
not_updated: '未更新',
}[value] ||
value ||
@@ -872,7 +1168,7 @@ export default {
updateTagType(value) {
return value === 'updated' || value === 'manually_adjusted'
? 'success'
: value === 'skipped_multi_cargo'
: value === 'skipped_multi_cargo' || value === 'partial_updated'
? 'warning'
: 'info';
},
@@ -956,11 +1252,50 @@ export default {
gap: 8px;
margin-bottom: 12px;
}
.reconciliation-editor__filter-item {
display: flex;
align-items: center;
min-width: 0;
}
.reconciliation-editor__filter-label {
flex: 0 0 auto;
margin-right: 8px;
color: #606266;
white-space: nowrap;
}
.reconciliation-editor__filter-item :deep(.el-input) {
min-width: 0;
}
.reconciliation-editor__pagination {
display: flex;
justify-content: flex-end;
margin-top: 12px;
}
.reconciliation-editor-shell--page {
display: block;
}
.reconciliation-editor--page {
padding-bottom: 12px;
}
.reconciliation-editor__page-actions {
position: fixed;
z-index: 20;
right: 0;
bottom: 0;
left: 230px;
display: flex;
align-items: center;
justify-content: flex-end;
min-height: 64px;
box-sizing: border-box;
padding: 12px 24px;
background: #fff;
border-top: 1px solid #eff1f7;
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
}
.reconciliation-editor__page-actions .el-button + .el-button {
margin-left: 12px;
}
.reconciliation-editor__help {
color: #606266;
line-height: 1.8;
@@ -980,6 +1315,20 @@ export default {
.reconciliation-editor :deep(.el-table__body tr:nth-child(even) > td.el-table__cell) {
background: #fafafa;
}
.reconciliation-editor :deep(.el-table__body tr.reconciliation-editor__row--unmatched > td.el-table__cell) {
color: #f56c6c;
background: #fff1f0 !important;
}
.reconciliation-editor
:deep(.el-table__body tr.reconciliation-editor__row--unmatched > td.el-table__cell .cell) {
color: #f56c6c;
}
.reconciliation-editor
:deep(.el-table__body tr.reconciliation-editor__row--unmatched .status-text) {
color: #f56c6c;
background: #fde2e2;
border-color: #fbc4c4;
}
@media (max-width: 1200px) {
.reconciliation-editor__stats {
grid-template-columns: repeat(3, minmax(150px, 1fr));