feat: 开票项目支持关联费用项目拖动排序与级联选择
This commit is contained in:
+295
-82
@@ -8,9 +8,6 @@
|
|||||||
:data="data"
|
:data="data"
|
||||||
:table-loading="loading"
|
:table-loading="loading"
|
||||||
:permission="permissionList"
|
:permission="permissionList"
|
||||||
:before-open="beforeOpen"
|
|
||||||
@row-save="rowSave"
|
|
||||||
@row-update="rowUpdate"
|
|
||||||
@row-del="rowDel"
|
@row-del="rowDel"
|
||||||
@search-change="searchChange"
|
@search-change="searchChange"
|
||||||
@search-reset="searchReset"
|
@search-reset="searchReset"
|
||||||
@@ -20,11 +17,21 @@
|
|||||||
@refresh-change="refreshChange"
|
@refresh-change="refreshChange"
|
||||||
@on-load="onLoad"
|
@on-load="onLoad"
|
||||||
>
|
>
|
||||||
|
<template #menu-left>
|
||||||
|
<el-button
|
||||||
|
v-if="permission.invoice_item_add"
|
||||||
|
type="primary"
|
||||||
|
icon="el-icon-plus"
|
||||||
|
@click="openDialog()"
|
||||||
|
>
|
||||||
|
新增
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
<template #menu="scope">
|
<template #menu="scope">
|
||||||
<el-link
|
<el-link
|
||||||
v-if="permission.invoice_item_edit"
|
v-if="permission.invoice_item_edit"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="$refs.crud.rowEdit(scope.row, scope.index)"
|
@click="openDialog(scope.row)"
|
||||||
>
|
>
|
||||||
修改
|
修改
|
||||||
</el-link>
|
</el-link>
|
||||||
@@ -37,9 +44,36 @@
|
|||||||
</el-link>
|
</el-link>
|
||||||
</template>
|
</template>
|
||||||
<template #defaultTaxRate="scope">{{ scope.row.defaultTaxRate }}%</template>
|
<template #defaultTaxRate="scope">{{ scope.row.defaultTaxRate }}%</template>
|
||||||
<template #defaultTaxRate-form>
|
</avue-crud>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
v-model="dialog.visible"
|
||||||
|
:title="dialog.title"
|
||||||
|
width="900px"
|
||||||
|
append-to-body
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
>
|
||||||
|
<el-form ref="dialogForm" :model="dialog.form" label-width="130px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="货物或服务简称" required prop="shortName">
|
||||||
|
<el-input v-model="dialog.form.shortName" maxlength="100" clearable placeholder="请输入货物或服务简称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="税收分类编码" required prop="taxClassificationCode">
|
||||||
|
<el-input v-model="dialog.form.taxClassificationCode" maxlength="30" clearable placeholder="请输入税收分类编码" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="商品和服务分类名称" required prop="categoryName">
|
||||||
|
<el-input v-model="dialog.form.categoryName" maxlength="200" clearable placeholder="请输入商品和服务分类名称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="默认税率" required prop="defaultTaxRate">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="form.defaultTaxRate"
|
v-model="dialog.form.defaultTaxRate"
|
||||||
inputmode="decimal"
|
inputmode="decimal"
|
||||||
maxlength="6"
|
maxlength="6"
|
||||||
clearable
|
clearable
|
||||||
@@ -48,13 +82,87 @@
|
|||||||
>
|
>
|
||||||
<template #append>%</template>
|
<template #append>%</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-form-item label="关联费用项目">
|
||||||
|
<div class="fee-item-box">
|
||||||
|
<span class="fee-item-tip">可拖动排序,发票冲抵费用项目时,按设置的顺序冲抵费用</span>
|
||||||
|
<el-button type="primary" size="small" @click="addFeeItem">添加</el-button>
|
||||||
|
<table class="fee-item-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th width="36"></th>
|
||||||
|
<th width="60">序号</th>
|
||||||
|
<th>费用类型</th>
|
||||||
|
<th>费用项目</th>
|
||||||
|
<th width="60">操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr
|
||||||
|
v-for="(item, index) in dialog.form.feeItems"
|
||||||
|
:key="index"
|
||||||
|
draggable="true"
|
||||||
|
@dragstart="onFeeDragStart(index, $event)"
|
||||||
|
@dragover.prevent
|
||||||
|
@drop="onFeeDrop(index, $event)"
|
||||||
|
@dragend="onFeeDragEnd"
|
||||||
|
>
|
||||||
|
<td class="fee-item-drag" :class="{ 'is-dragging': feeDragIndex === index }">≡</td>
|
||||||
|
<td>{{ index + 1 }}</td>
|
||||||
|
<td>
|
||||||
|
<el-select v-model="item.feeCategory" placeholder="请选择" clearable filterable @change="() => onFeeCategoryChange(item)">
|
||||||
|
<el-option
|
||||||
|
v-for="category in feeCategoryOptions"
|
||||||
|
:key="category.value"
|
||||||
|
:label="category.label"
|
||||||
|
:value="category.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<el-select
|
||||||
|
v-model="item.feeItemId"
|
||||||
|
placeholder="请先选择费用类型"
|
||||||
|
:disabled="!item.feeCategory"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
@change="onFeeItemChange(item)"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="fee in feeItemsOfCategory(item.feeCategory)"
|
||||||
|
:key="fee.id"
|
||||||
|
:label="fee.name"
|
||||||
|
:value="fee.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<el-link type="danger" @click="removeFeeItem(index)">删除</el-link>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-if="!dialog.form.feeItems.length">
|
||||||
|
<td colspan="5" class="fee-item-empty">暂无数据</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="dialog.visible = false">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="dialog.saving" @click="saveDialog">保存</el-button>
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</el-dialog>
|
||||||
</basic-container>
|
</basic-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getList, getDetail, submit, remove } from '@/api/base/invoice-item';
|
import { getList, getDetail, submit, remove } from '@/api/base/invoice-item';
|
||||||
|
import { getList as getFeeItemList } from '@/api/base/fee-item';
|
||||||
|
import { getDictionaryAll } from '@/api/system/dictbiz';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -65,6 +173,16 @@ export default {
|
|||||||
loading: true,
|
loading: true,
|
||||||
query: {},
|
query: {},
|
||||||
selectionList: [],
|
selectionList: [],
|
||||||
|
feeItemOptions: [],
|
||||||
|
// 费用类型字典选项(fee_category 字典:dictKey-编码A01,dictValue-名称运输)
|
||||||
|
feeCategoryDictOptions: [],
|
||||||
|
feeDragIndex: null,
|
||||||
|
dialog: {
|
||||||
|
visible: false,
|
||||||
|
title: '新增',
|
||||||
|
saving: false,
|
||||||
|
form: this.emptyForm(),
|
||||||
|
},
|
||||||
page: {
|
page: {
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
pageSizes: [10, 30, 50, 100, 200],
|
pageSizes: [10, 30, 50, 100, 200],
|
||||||
@@ -81,13 +199,11 @@ export default {
|
|||||||
indexLabel: '序号',
|
indexLabel: '序号',
|
||||||
indexWidth: 70,
|
indexWidth: 70,
|
||||||
selection: false,
|
selection: false,
|
||||||
addBtn: true,
|
addBtn: false,
|
||||||
editBtn: false,
|
editBtn: false,
|
||||||
delBtn: false,
|
delBtn: false,
|
||||||
viewBtn: false,
|
viewBtn: false,
|
||||||
menuWidth: 140,
|
menuWidth: 140,
|
||||||
dialogWidth: 900,
|
|
||||||
dialogClickModal: false,
|
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
labelWidth: 'auto',
|
labelWidth: 'auto',
|
||||||
searchShow: true,
|
searchShow: true,
|
||||||
@@ -100,49 +216,22 @@ export default {
|
|||||||
label: '货物或服务简称',
|
label: '货物或服务简称',
|
||||||
prop: 'shortName',
|
prop: 'shortName',
|
||||||
minWidth: 160,
|
minWidth: 160,
|
||||||
span: 12,
|
|
||||||
maxlength: 100,
|
|
||||||
rules: [{ required: true, message: '请输入货物或服务简称', trigger: 'blur' }],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '税收分类编码',
|
label: '税收分类编码',
|
||||||
prop: 'taxClassificationCode',
|
prop: 'taxClassificationCode',
|
||||||
minWidth: 190,
|
minWidth: 190,
|
||||||
span: 12,
|
|
||||||
maxlength: 30,
|
|
||||||
rules: [{ required: true, message: '请输入税收分类编码', trigger: 'blur' }],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '商品和服务分类名称',
|
label: '商品和服务分类名称',
|
||||||
prop: 'categoryName',
|
prop: 'categoryName',
|
||||||
minWidth: 220,
|
minWidth: 220,
|
||||||
span: 12,
|
|
||||||
maxlength: 200,
|
|
||||||
rules: [{ required: true, message: '请输入商品和服务分类名称', trigger: 'blur' }],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '默认税率',
|
label: '默认税率',
|
||||||
prop: 'defaultTaxRate',
|
prop: 'defaultTaxRate',
|
||||||
type: 'input',
|
|
||||||
formslot: true,
|
|
||||||
slot: true,
|
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
span: 12,
|
slot: true,
|
||||||
rules: [
|
|
||||||
{ required: true, message: '请输入默认税率', trigger: 'blur' },
|
|
||||||
{
|
|
||||||
validator: (rule, value, callback) => {
|
|
||||||
const text = String(value ?? '');
|
|
||||||
const rate = Number(text);
|
|
||||||
if (!/^\d+(\.\d+)?$/.test(text) || rate < 0 || rate > 100) {
|
|
||||||
callback(new Error('默认税率必须是0到100之间的数字'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
},
|
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '税收项目',
|
label: '税收项目',
|
||||||
@@ -193,27 +282,131 @@ export default {
|
|||||||
delBtn: false,
|
delBtn: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
// 费用类型下拉选项:优先字典(显示"名称/编码"),无字典数据时兜底费用项目库提取
|
||||||
|
feeCategoryOptions() {
|
||||||
|
if (this.feeCategoryDictOptions.length) return this.feeCategoryDictOptions;
|
||||||
|
return [...new Set(this.feeItemOptions.map(fee => fee.feeCategory).filter(Boolean))]
|
||||||
|
.map(category => ({ label: category, value: category }));
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
rowSave(row, done, loading) {
|
emptyForm() {
|
||||||
submit(this.normalizeTaxRateRow(row)).then(
|
return {
|
||||||
() => {
|
id: null,
|
||||||
this.onLoad(this.page);
|
shortName: '',
|
||||||
|
taxClassificationCode: '',
|
||||||
|
categoryName: '',
|
||||||
|
defaultTaxRate: 0,
|
||||||
|
feeItems: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
openDialog(row) {
|
||||||
|
this.dialog.form = this.emptyForm();
|
||||||
|
this.dialog.title = row ? '编辑' : '新增';
|
||||||
|
this.dialog.visible = true;
|
||||||
|
this.loadFeeItemOptions();
|
||||||
|
this.initFeeCategoryOptions();
|
||||||
|
if (row) {
|
||||||
|
// 编辑回填:后端 detail 返回关联费用项目(按排序号升序)
|
||||||
|
getDetail(row.id).then(res => {
|
||||||
|
const detail = res.data.data || {};
|
||||||
|
this.dialog.form = {
|
||||||
|
...this.emptyForm(),
|
||||||
|
...detail,
|
||||||
|
defaultTaxRate: detail.defaultTaxRate ?? 0,
|
||||||
|
feeItems: (detail.feeItems || []).map(item => ({
|
||||||
|
feeItemId: item.feeItemId,
|
||||||
|
feeItemName: item.feeItemName,
|
||||||
|
feeCategory: item.feeCategory,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loadFeeItemOptions() {
|
||||||
|
if (this.feeItemOptions.length) return;
|
||||||
|
getFeeItemList(1, 1000, { status: 1 }).then(res => {
|
||||||
|
this.feeItemOptions = (res.data.data?.records) || [];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 费用类型字典:code=fee_category(dictKey-编码如A01,dictValue-名称如运输),label 显示"名称/编码"与费用项目页一致
|
||||||
|
initFeeCategoryOptions() {
|
||||||
|
if (this.feeCategoryDictOptions.length) return;
|
||||||
|
getDictionaryAll().then(res => {
|
||||||
|
this.feeCategoryDictOptions = (res.data.data || [])
|
||||||
|
.filter(item => item.code === 'fee_category' && Number(item.parentId) > 0)
|
||||||
|
.sort((first, second) => Number(first.sort || 0) - Number(second.sort || 0))
|
||||||
|
.map(item => ({
|
||||||
|
label: `${item.dictValue}/${item.dictKey}`,
|
||||||
|
value: String(item.dictKey),
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 级联:该费用类型下的费用项目选项
|
||||||
|
feeItemsOfCategory(feeCategory) {
|
||||||
|
if (!feeCategory) return [];
|
||||||
|
return this.feeItemOptions.filter(fee => fee.feeCategory === feeCategory);
|
||||||
|
},
|
||||||
|
// 先选费用类型:清空原费用项目(原项目可能不属于新类型)
|
||||||
|
onFeeCategoryChange(item) {
|
||||||
|
item.feeItemId = null;
|
||||||
|
item.feeItemName = '';
|
||||||
|
},
|
||||||
|
// 后选费用项目:带出名称(费用类型已由上级确定)
|
||||||
|
onFeeItemChange(item) {
|
||||||
|
const fee = this.feeItemsOfCategory(item.feeCategory).find(option => option.id === item.feeItemId);
|
||||||
|
item.feeItemName = fee ? fee.name : '';
|
||||||
|
},
|
||||||
|
addFeeItem() {
|
||||||
|
this.dialog.form.feeItems.push({ feeItemId: null, feeItemName: '', feeCategory: '' });
|
||||||
|
},
|
||||||
|
removeFeeItem(index) {
|
||||||
|
this.dialog.form.feeItems.splice(index, 1);
|
||||||
|
},
|
||||||
|
onFeeDragStart(index, event) {
|
||||||
|
this.feeDragIndex = index;
|
||||||
|
event.dataTransfer.effectAllowed = 'move';
|
||||||
|
},
|
||||||
|
onFeeDrop(index) {
|
||||||
|
const from = this.feeDragIndex;
|
||||||
|
if (from === null || from === index) return;
|
||||||
|
const items = this.dialog.form.feeItems;
|
||||||
|
items.splice(index, 0, items.splice(from, 1)[0]);
|
||||||
|
this.feeDragIndex = null;
|
||||||
|
},
|
||||||
|
onFeeDragEnd() {
|
||||||
|
this.feeDragIndex = null;
|
||||||
|
},
|
||||||
|
saveDialog() {
|
||||||
|
const formItem = this.dialog.form;
|
||||||
|
if (!formItem.shortName) return this.$message.warning('请输入货物或服务简称');
|
||||||
|
if (!formItem.taxClassificationCode) return this.$message.warning('请输入税收分类编码');
|
||||||
|
if (!formItem.categoryName) return this.$message.warning('请输入商品和服务分类名称');
|
||||||
|
const rate = Number(formItem.defaultTaxRate);
|
||||||
|
if (!/^\d+(\.\d+)?$/.test(String(formItem.defaultTaxRate ?? '')) || rate < 0 || rate > 100) {
|
||||||
|
return this.$message.warning('默认税率必须是0到100之间的数字');
|
||||||
|
}
|
||||||
|
if (formItem.feeItems.some(item => !item.feeItemId)) {
|
||||||
|
return this.$message.warning('请选择关联费用项目');
|
||||||
|
}
|
||||||
|
this.dialog.saving = true;
|
||||||
|
submit({
|
||||||
|
...formItem,
|
||||||
|
defaultTaxRate: rate,
|
||||||
|
feeItems: formItem.feeItems.map(item => ({
|
||||||
|
feeItemId: item.feeItemId,
|
||||||
|
feeItemName: item.feeItemName,
|
||||||
|
feeCategory: item.feeCategory,
|
||||||
|
})),
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
this.$message.success('操作成功');
|
this.$message.success('操作成功');
|
||||||
done();
|
this.dialog.visible = false;
|
||||||
},
|
|
||||||
() => loading()
|
|
||||||
);
|
|
||||||
},
|
|
||||||
rowUpdate(row, index, done, loading) {
|
|
||||||
submit(this.normalizeTaxRateRow(row)).then(
|
|
||||||
() => {
|
|
||||||
this.onLoad(this.page);
|
this.onLoad(this.page);
|
||||||
this.$message.success('操作成功');
|
})
|
||||||
done();
|
.finally(() => {
|
||||||
},
|
this.dialog.saving = false;
|
||||||
() => loading()
|
});
|
||||||
);
|
|
||||||
},
|
},
|
||||||
rowDel(row) {
|
rowDel(row) {
|
||||||
this.$confirm('确定将选择数据删除?', '提示', { type: 'warning' })
|
this.$confirm('确定将选择数据删除?', '提示', { type: 'warning' })
|
||||||
@@ -223,27 +416,11 @@ export default {
|
|||||||
this.$message.success('操作成功');
|
this.$message.success('操作成功');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
beforeOpen(done, type) {
|
|
||||||
if (['edit', 'view'].includes(type)) {
|
|
||||||
getDetail(this.form.id).then(res => {
|
|
||||||
this.form = res.data.data || {};
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.form = { defaultTaxRate: 0 };
|
|
||||||
done();
|
|
||||||
},
|
|
||||||
handleTaxRateInput(value) {
|
handleTaxRateInput(value) {
|
||||||
let normalized = String(value || '').replace(/[^\d.]/g, '');
|
let normalized = String(value || '').replace(/[^\d.]/g, '');
|
||||||
normalized = normalized.replace(/(\..*)\./g, '$1');
|
normalized = normalized.replace(/(\..*)\./g, '$1');
|
||||||
if (normalized.startsWith('.')) normalized = `0${normalized}`;
|
if (normalized.startsWith('.')) normalized = `0${normalized}`;
|
||||||
this.form.defaultTaxRate = normalized;
|
this.dialog.form.defaultTaxRate = normalized;
|
||||||
},
|
|
||||||
normalizeTaxRateRow(row) {
|
|
||||||
const values = { ...row };
|
|
||||||
values.defaultTaxRate = Number(values.defaultTaxRate);
|
|
||||||
return values;
|
|
||||||
},
|
},
|
||||||
searchChange(params, done) {
|
searchChange(params, done) {
|
||||||
this.query = {
|
this.query = {
|
||||||
@@ -292,17 +469,53 @@ export default {
|
|||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoice-item-page :deep(.avue-crud__dialog .el-form-item) {
|
|
||||||
margin-bottom: 28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoice-item-page :deep(.avue-crud__dialog .el-form-item__error) {
|
|
||||||
position: relative;
|
|
||||||
line-height: 20px;
|
|
||||||
white-space: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoice-item-page :deep(.avue-crud__menu .el-link) {
|
.invoice-item-page :deep(.avue-crud__menu .el-link) {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fee-item-box {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fee-item-tip {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 12px;
|
||||||
|
color: #f56c6c;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fee-item-table {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 8px;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fee-item-table th,
|
||||||
|
.fee-item-table td {
|
||||||
|
padding: 8px;
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fee-item-table th {
|
||||||
|
background: #f8f8f9;
|
||||||
|
color: #515a6e;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fee-item-drag {
|
||||||
|
cursor: move;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 16px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fee-item-drag.is-dragging {
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fee-item-empty {
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user