1690 lines
46 KiB
Vue
1690 lines
46 KiB
Vue
<script setup lang="ts">
|
|
import { useI18n } from 'vue-i18n';
|
|
import { $baseMessage } from '@/utils';
|
|
import { IconPlus, IconEdit, IconDelete, IconSearch } from '@arco-design/web-vue/es/icon';
|
|
|
|
import { useUserStore } from '@/store';
|
|
|
|
const { t } = useI18n();
|
|
import {
|
|
postEditContent,
|
|
getGetDetail,
|
|
postGetContentPage,
|
|
postGetPage,
|
|
postEdit,
|
|
getGetContentDetail,
|
|
} from '@/api/TrackPush/trackPush';
|
|
import { postGetList } from '@/api/TrackContent/trackContent';
|
|
import { getGetList } from '@/api/ApplicationServicesProvider/dictionary';
|
|
import { getAppGetList } from '@/api/ApplicationServices/apps';
|
|
import { getServiceProviderGetServiceProviderDropdownList } from '@/api/ServiceProviderInterface/serviceProvider';
|
|
import CustomLeftMenu from '@/components/CustomLeftMenu/index.vue';
|
|
import dayjs from 'dayjs';
|
|
import ModalForm from '@/components/ModalForm/index.vue';
|
|
import SelectPro from '@/components/SelectPro/index.vue';
|
|
import ModalPro from '@/components/ModalPro/index.vue';
|
|
import useModal from '@/components/ModalPro/useModal';
|
|
import CustomList from '@/components/CustomList/index.vue';
|
|
|
|
type IDialogConfig = {
|
|
show: boolean;
|
|
type: 'add' | 'edit';
|
|
title: string;
|
|
};
|
|
const userStore = useUserStore();
|
|
|
|
/** ???????? */
|
|
const editFormParams = reactive<any>({
|
|
options: 1,
|
|
id: undefined,
|
|
});
|
|
/** ???????????? */
|
|
const editFormRightParams = reactive<any>({
|
|
options: 1,
|
|
id: undefined,
|
|
appKey: userStore.appKey,
|
|
});
|
|
const topFormRef = ref();
|
|
const currentId = ref<API.GetTrackPushConfigPageOutputVO | undefined>();
|
|
const modalFormLeftRef = ref();
|
|
const modalFormRightRef = ref();
|
|
const refHeight = ref();
|
|
|
|
const { contentHeight, calcContentHeight } = useContentHeight(
|
|
refHeight,
|
|
true,
|
|
12
|
|
);
|
|
|
|
/** ???? */
|
|
const searchModel = reactive<any>({});
|
|
/** ??????*/
|
|
const searchKeyword = ref('');
|
|
|
|
const pushListData = ref<any[]>([]);
|
|
const pushLoading = ref(false);
|
|
const appMap = ref<Record<string, string>>({});
|
|
|
|
async function loadAppMap() {
|
|
try {
|
|
const res = (await getAppGetList({ PageIndex: 1, PageSize: 1000 })) as any;
|
|
const apps = res?.data?.items || res?.items || res?.data || [];
|
|
const map: Record<string, string> = {};
|
|
apps.forEach((app: any) => {
|
|
if (app.appKey && app.name) map[app.appKey] = app.name;
|
|
});
|
|
appMap.value = map;
|
|
} catch (e) {
|
|
console.error('加载应用列表失败', e);
|
|
}
|
|
}
|
|
|
|
async function loadPushList() {
|
|
pushLoading.value = true;
|
|
try {
|
|
const params: any = {
|
|
pageIndex: 1,
|
|
pageSize: 200,
|
|
...searchModel,
|
|
};
|
|
if (userStore.appKey) params.appKey = userStore.appKey;
|
|
const res = (await postGetPage(params)) as any;
|
|
const items = res?.data?.items ?? res?.items ?? res?.data ?? [];
|
|
pushListData.value = Array.isArray(items) ? items : [];
|
|
} catch (e) {
|
|
$baseMessage('加载推送配置列表失败', 'error');
|
|
pushListData.value = [];
|
|
} finally {
|
|
pushLoading.value = false;
|
|
}
|
|
}
|
|
|
|
const pushTreeData = computed(() => {
|
|
const list = pushListData.value || [];
|
|
if (list.length === 0) return [];
|
|
return [
|
|
{
|
|
key: 'category-1',
|
|
title: '推送配置',
|
|
children: list.map((item: any) => {
|
|
const time = item.createTime ? dayjs(item.createTime).format('YYYY-MM-DD HH:mm') : '';
|
|
const app = item.appName || (item.appKey != null ? (appMap.value?.[item.appKey] ?? '') : '') || item.appKey || '-';
|
|
const appStr = app ? `【${app}】` : '';
|
|
const customerStr = item.customer ? `【${item.customer}】` : '';
|
|
const codeLine = [time, appStr, customerStr].filter(Boolean).join(' ');
|
|
return {
|
|
key: `item-${item.id}`,
|
|
title: item.customer || item.serviceProviderName || item.serviceProvider || '-',
|
|
isLeaf: true,
|
|
id: item.id,
|
|
code: codeLine,
|
|
...item,
|
|
};
|
|
}),
|
|
},
|
|
];
|
|
});
|
|
|
|
const pushSelectedKeys = computed(() =>
|
|
currentId.value?.id ? [`item-${currentId.value.id}`] : []
|
|
);
|
|
const pushExpandedKeys = ref(['category-1']);
|
|
|
|
function handlePushSelectFromTree(keys: string[], info: any) {
|
|
const node = info?.node;
|
|
if (!node || !node.isLeaf) return;
|
|
const key = node.key;
|
|
const id = key.startsWith('item-') ? Number(key.slice(5)) : null;
|
|
if (id == null) return;
|
|
const item = pushListData.value.find((x: any) => x.id === id);
|
|
if (item) cellClick(item);
|
|
}
|
|
|
|
// 明细列表数据(用于新增空白行后重载)
|
|
const detailListData = ref<any[]>([]);
|
|
|
|
// 自定义表头列(与 CustomList 双向绑定)
|
|
const customColumns = ref<Array<{ field: string; title: string; isEditing?: boolean; isNew?: boolean }>>([]);
|
|
const customListRef = ref<InstanceType<typeof CustomList>>();
|
|
|
|
// ?????????
|
|
const totalCount = ref(0);
|
|
const currentPage = ref(1);
|
|
const pageSize = ref(30);
|
|
const jumpPage = ref('');
|
|
|
|
// 自定义列表:左侧固定列(序号、系统标准轨迹)
|
|
const pushFixedLeftColumns = computed(() => [
|
|
{
|
|
field: 'index',
|
|
title: t('track.push.table.serialNo'),
|
|
width: 60,
|
|
align: 'center',
|
|
fixed: 'left',
|
|
formatter: ({ rowIndex }: any) => rowIndex + 1,
|
|
},
|
|
{
|
|
field: 'standardTrack',
|
|
title: t('track.push.table.systemStandardTrack'),
|
|
width: 280,
|
|
align: 'left',
|
|
fixed: 'left',
|
|
slots: { default: 'standardTrack' },
|
|
showOverflow: 'tooltip',
|
|
},
|
|
]);
|
|
// 自定义列表:右侧固定列(操作)
|
|
const pushFixedRightColumns = computed(() => [
|
|
{
|
|
field: 'action',
|
|
title: t('track.push.table.actions'),
|
|
width: 100,
|
|
align: 'left',
|
|
fixed: 'right',
|
|
slots: { default: 'action' },
|
|
},
|
|
]);
|
|
const pushTableConfigExtra = {
|
|
autoHeight: true,
|
|
height: undefined,
|
|
rowConfig: { useKey: true, keyField: 'id' },
|
|
size: 'small',
|
|
};
|
|
|
|
const leftFormProps = computed(() => {
|
|
return {
|
|
formLayout: 'vertical',
|
|
defaultSpan: 12,
|
|
colProps: {
|
|
span: 12,
|
|
style: { marginBottom: '16px' }
|
|
},
|
|
itemList: [
|
|
{
|
|
label: t('track.push.form.application'),
|
|
field: 'appKey',
|
|
comp: 'SelectPro',
|
|
rules: [
|
|
{
|
|
required: true,
|
|
message: t('track.push.form.applicationRequired'),
|
|
},
|
|
],
|
|
compProps: {
|
|
placeholder: t('track.push.form.applicationPlaceholder'),
|
|
size: 'large',
|
|
api: getAppGetList,
|
|
labelKeys: ['name', 'appKey'],
|
|
separator: '+',
|
|
idKey: 'appKey',
|
|
isPage: true,
|
|
immediate: true,
|
|
defaultValue: userStore.appKey,
|
|
style: { width: '100%', height: '40px' },
|
|
},
|
|
span: 12,
|
|
},
|
|
{
|
|
label: t('track.push.form.customer'),
|
|
field: 'customer',
|
|
comp: 'AInput',
|
|
compProps: {
|
|
placeholder: t('track.push.form.customerPlaceholder'),
|
|
style: { width: '100%', height: '40px' },
|
|
},
|
|
span: 12,
|
|
rules: [{ required: true, message: t('track.push.form.customerRequired') }],
|
|
},
|
|
{
|
|
label: t('track.push.form.serviceProvider'),
|
|
field: 'serviceProviderCode',
|
|
comp: 'SelectPro',
|
|
compProps: ({ formValue }: { formValue: any }) => {
|
|
return {
|
|
immediate: true,
|
|
clearable: true,
|
|
labelKeys: ['name'],
|
|
titleStrs: ['name'],
|
|
placeholder: t('track.push.form.serviceProviderPlaceholder'),
|
|
style: { width: '100%', height: '40px' },
|
|
idKey: 'code',
|
|
isPage: false,
|
|
api: getServiceProviderGetServiceProviderDropdownList,
|
|
extra: { appKey: formValue?.appKey || userStore.appKey },
|
|
allowSearch: true,
|
|
allowCreate: false,
|
|
trigger: 'click',
|
|
};
|
|
},
|
|
span: 12,
|
|
rules: [
|
|
{
|
|
required: true,
|
|
message: t('track.push.form.serviceProviderRequired'),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: t('track.push.form.product'),
|
|
field: 'product',
|
|
comp: 'AInput',
|
|
compProps: {
|
|
placeholder: t('track.push.form.productPlaceholder'),
|
|
style: { width: '100%', height: '40px' },
|
|
},
|
|
span: 12,
|
|
},
|
|
{
|
|
label: t('track.push.form.isAutoPush'),
|
|
field: 'isAutoPush',
|
|
comp: 'ASelect',
|
|
compProps: () => {
|
|
return {
|
|
placeholder: t('track.push.form.isAutoPushPlaceholder'),
|
|
size: 'large',
|
|
defaultValue: true,
|
|
style: { width: '100%', height: '40px' },
|
|
options: [
|
|
{ label: t('track.push.common.yes'), value: true },
|
|
{ label: t('track.push.common.no'), value: false },
|
|
],
|
|
};
|
|
},
|
|
span: 12,
|
|
},
|
|
{
|
|
label: t('track.push.form.supportRepush'),
|
|
field: 'isCanUpdate',
|
|
comp: 'ASelect',
|
|
compProps: () => {
|
|
return {
|
|
placeholder: t('track.push.form.supportRepushPlaceholder'),
|
|
size: 'large',
|
|
defaultValue: false,
|
|
style: { width: '100%', height: '40px' },
|
|
options: [
|
|
{ label: t('track.push.common.yes'), value: true },
|
|
{ label: t('track.push.common.no'), value: false },
|
|
],
|
|
};
|
|
},
|
|
span: 12,
|
|
},
|
|
{
|
|
label: t('track.push.form.supportDelete'),
|
|
field: 'isCanDelete',
|
|
comp: 'ASelect',
|
|
compProps: () => {
|
|
return {
|
|
placeholder: t('track.push.form.supportDeletePlaceholder'),
|
|
size: 'large',
|
|
defaultValue: false,
|
|
style: { width: '100%', height: '40px' },
|
|
options: [
|
|
{ label: t('track.push.common.yes'), value: true },
|
|
{ label: t('track.push.common.no'), value: false },
|
|
],
|
|
};
|
|
},
|
|
span: 12,
|
|
},
|
|
{
|
|
label: t('track.push.form.isFullPush'),
|
|
field: 'isAllPush',
|
|
comp: 'ASelect',
|
|
compProps: () => {
|
|
return {
|
|
placeholder: t('track.push.form.isFullPushPlaceholder'),
|
|
size: 'large',
|
|
defaultValue: false,
|
|
style: { width: '100%', height: '40px' },
|
|
options: [
|
|
{ label: t('track.push.common.yes'), value: true },
|
|
{ label: t('track.push.common.no'), value: false },
|
|
],
|
|
};
|
|
},
|
|
span: 12,
|
|
},
|
|
{
|
|
label: t('track.push.form.isLatestFullPush'),
|
|
field: 'isAllPushWithLatest',
|
|
comp: 'ASelect',
|
|
compProps: () => {
|
|
return {
|
|
placeholder: t('track.push.form.isLatestFullPushPlaceholder'),
|
|
size: 'large',
|
|
defaultValue: false,
|
|
style: { width: '100%', height: '40px' },
|
|
options: [
|
|
{ label: t('track.push.common.yes'), value: true },
|
|
{ label: t('track.push.common.no'), value: false },
|
|
],
|
|
};
|
|
},
|
|
span: 12,
|
|
},
|
|
{
|
|
label: t('track.push.form.pushTimeStyle'),
|
|
field: 'dateTimeFormatType',
|
|
comp: 'SelectPro',
|
|
compProps: {
|
|
idKey: 'value',
|
|
labelKeys: ['label'],
|
|
style: { width: '100%', height: '40px' },
|
|
defaultValue: 0,
|
|
options: [
|
|
{ label: t('track.push.form.pushTimeStyle.none'), value: 0 },
|
|
{ label: t('track.push.form.pushTimeStyle.timestamp'), value: 1 },
|
|
{ label: t('track.push.form.pushTimeStyle.timezone'), value: 2 },
|
|
],
|
|
},
|
|
span: 12,
|
|
},
|
|
{
|
|
label: t('track.push.form.time'),
|
|
field: 'dateTimeFormat',
|
|
comp: 'AInput',
|
|
compProps: {
|
|
placeholder: t('track.push.form.timePlaceholder'),
|
|
style: { width: '100%', height: '40px' },
|
|
},
|
|
span: 12,
|
|
ifShow: ({ model }: { model: any }) => model?.dateTimeFormatType === 2,
|
|
},
|
|
{
|
|
label: t('track.push.form.timezone'),
|
|
field: 'timezoneFormat',
|
|
comp: 'AInput',
|
|
compProps: {
|
|
placeholder: t('track.push.form.timezonePlaceholder'),
|
|
style: { width: '100%', height: '40px' },
|
|
},
|
|
span: 12,
|
|
ifShow: ({ model }: { model: any }) => model?.dateTimeFormatType === 2,
|
|
},
|
|
],
|
|
};
|
|
});
|
|
|
|
const rightFormProps = computed(() => {
|
|
return {
|
|
formLayout: 'vertical',
|
|
|
|
itemList: [
|
|
{
|
|
label: t('track.push.form.trackCode'),
|
|
field: 'trackContentId',
|
|
comp: 'SelectPro',
|
|
compProps: ({ formValue }: { formValue: any }) => {
|
|
return {
|
|
clearable: true,
|
|
immediate: true,
|
|
labelKeys: ['code', 'content', 'enContent'],
|
|
titleStrs: [t('track.push.titleStrs.trackCode'), t('track.push.titleStrs.trackContent'), t('track.push.table.trackContentEn')],
|
|
separator: '-',
|
|
idKey: 'id',
|
|
api: postGetList,
|
|
searchKey: 'keywords',
|
|
extra: { appKey: useUserStore().appKey, pageSize: 100 },
|
|
};
|
|
},
|
|
span: 12,
|
|
rules: [{ required: true, message: t('track.push.form.trackCodeRequired') }],
|
|
},
|
|
|
|
{
|
|
label: t('track.push.form.pushTrackStatus'),
|
|
field: 'trackStatusValue',
|
|
comp: 'AInput',
|
|
compProps: () => {
|
|
return {
|
|
placeholder: t('track.push.form.pushTrackStatusPlaceholder'),
|
|
};
|
|
},
|
|
span: 12,
|
|
},
|
|
{
|
|
label: t('track.push.form.pushTrackCode'),
|
|
field: 'trackContentCodeValue',
|
|
comp: 'AInput',
|
|
compProps: () => {
|
|
return {
|
|
placeholder: t('track.push.form.pushTrackStatusPlaceholder'),
|
|
};
|
|
},
|
|
span: 12,
|
|
},
|
|
{
|
|
label: t('track.push.form.pushTrackContent'),
|
|
field: 'trackContentValue',
|
|
comp: 'AInput',
|
|
compProps: () => {
|
|
return {
|
|
placeholder: t('track.push.form.pushTrackStatusPlaceholder'),
|
|
};
|
|
},
|
|
span: 12,
|
|
},
|
|
{
|
|
label: t('track.push.form.pushTrackContentEn'),
|
|
field: 'trackEnContentValue',
|
|
comp: 'AInput',
|
|
compProps: () => {
|
|
return {
|
|
placeholder: t('track.push.form.pushTrackStatusPlaceholder'),
|
|
};
|
|
},
|
|
|
|
span: 12,
|
|
dynamicRules: () => {
|
|
return [
|
|
{
|
|
pattern: /^[^\u4E00-\u9FA5]{0,3000}$/,
|
|
message: t('track.content.form.trackContentEnNoChinese'),
|
|
trigger: 'change',
|
|
},
|
|
];
|
|
},
|
|
},
|
|
{
|
|
label: t('track.push.form.pushExtendedField'),
|
|
field: 'expandFieldsValue',
|
|
comp: 'AInput',
|
|
compProps: () => {
|
|
return {
|
|
placeholder: t('track.push.form.pushTrackStatusPlaceholder'),
|
|
};
|
|
},
|
|
span: 12,
|
|
},
|
|
{
|
|
label: t('track.push.form.timezone'),
|
|
field: 'trackTimeZone',
|
|
comp: 'Timezone',
|
|
span: 12,
|
|
},
|
|
{
|
|
label: t('track.push.form.swapTrackContent'),
|
|
field: 'swapTrackContentId',
|
|
comp: 'SelectPro',
|
|
|
|
compProps: ({ formValue }: { formValue: any }) => {
|
|
return {
|
|
clearable: true,
|
|
labelKeys: ['code', 'content'],
|
|
titleStrs: [t('track.push.titleStrs.trackCode'), t('track.push.titleStrs.trackContent')],
|
|
idKey: 'contentId',
|
|
api: postGetContentPage,
|
|
disableFn: (id: number) => {
|
|
if (id === formValue?.id) return true;
|
|
return false;
|
|
},
|
|
searchKey: 'keywords',
|
|
extra: { trackPushConfigId: currentId.value?.id },
|
|
};
|
|
},
|
|
span: 12,
|
|
},
|
|
],
|
|
};
|
|
});
|
|
|
|
|
|
// ??????
|
|
type TabItem = {
|
|
key: number;
|
|
value: string;
|
|
};
|
|
|
|
// ????? Tab??????
|
|
const activeTab = ref<number | undefined>(0);
|
|
const tabs = ref<TabItem[]>([]);
|
|
|
|
// ??????
|
|
type OrderTypeDict = {
|
|
[key: number]: string;
|
|
};
|
|
|
|
// ?????????? // function getUnusedOrderTypes(
|
|
// allOrderTypes: TabItem[],
|
|
// usedOrderTypes: TabItem[]
|
|
// ): TabItem[] {
|
|
// return allOrderTypes.filter(
|
|
// (orderType) =>
|
|
// !usedOrderTypes.some((usedType) => usedType.key === orderType.key)
|
|
// );
|
|
// }
|
|
|
|
async function cellClick(rowId: API.GetTrackPushConfigPageOutputVO) {
|
|
currentId.value = rowId;
|
|
const configTagsResponse = await getGetList({
|
|
type: 'TrackOrderType',
|
|
});
|
|
|
|
tabs.value = configTagsResponse as unknown as any[];
|
|
(configTagsResponse as unknown as any[]).length > 0
|
|
? (activeTab.value = (configTagsResponse as unknown as any[])[0].key as number)
|
|
: (activeTab.value = 0);
|
|
currentPage.value = 1;
|
|
jumpPage.value = '1';
|
|
loadTableData();
|
|
}
|
|
|
|
function handleTabClick(tab: any) {
|
|
|
|
activeTab.value = tab;
|
|
const targetTab = tabs.value.find((t: any) => t.key === tab);
|
|
if (targetTab) {
|
|
currentPage.value = 1;
|
|
jumpPage.value = '1';
|
|
loadTableData();
|
|
}
|
|
|
|
nextTick(() => {
|
|
calcContentHeight();
|
|
});
|
|
}
|
|
|
|
// ???? ????????
|
|
function handleOpenModal(type: IDialogConfig['type'], row?: any) {
|
|
|
|
const titleObj: { [x in IDialogConfig['type']]: string } = {
|
|
add: t('track.push.actions.add'),
|
|
edit: t('track.push.actions.edit'),
|
|
};
|
|
editFormParams.options = 1;
|
|
editFormParams.id = undefined;
|
|
|
|
editFormParams.options = 1;
|
|
if (type === 'edit') {
|
|
unref(modalFormLeftRef)?.openModalFn({
|
|
title: titleObj[type],
|
|
id: row?.id,
|
|
});
|
|
|
|
editFormParams.options = 3;
|
|
editFormParams.id = row?.id;
|
|
|
|
return;
|
|
}
|
|
|
|
unref(modalFormLeftRef)?.openModalFn({
|
|
title: titleObj[type],
|
|
id: editFormParams.id,
|
|
});
|
|
|
|
nextTick(() => {
|
|
unref(modalFormLeftRef)?.setFormValue({
|
|
appKey: userStore.appKey,
|
|
isAutoPush: true,
|
|
isCanUpdate: false,
|
|
isAllPush: false,
|
|
isCanDelete: false,
|
|
isAllPushWithLatest: false,
|
|
dateTimeFormatType: 0,
|
|
});
|
|
});
|
|
}
|
|
|
|
// ???? ????????
|
|
function handleOpenRightModal(type: IDialogConfig['type'], row?: any) {
|
|
const titleObj: { [x in IDialogConfig['type']]: string } = {
|
|
add: t('track.push.actions.add'),
|
|
edit: t('track.push.actions.edit'),
|
|
};
|
|
editFormRightParams.options = 1;
|
|
editFormRightParams.id = undefined;
|
|
|
|
editFormRightParams.options = 1;
|
|
if (type === 'edit') {
|
|
unref(modalFormRightRef)?.openModalFn({
|
|
title: titleObj[type],
|
|
id: row?.id,
|
|
});
|
|
|
|
editFormRightParams.options = 3;
|
|
editFormRightParams.id = row?.id;
|
|
return;
|
|
}
|
|
|
|
unref(modalFormRightRef)?.openModalFn({
|
|
title: titleObj[type],
|
|
id: editFormRightParams.id,
|
|
formData: {
|
|
trackPushConfigId: currentId.value?.id,
|
|
orderNoType: activeTab.value,
|
|
},
|
|
});
|
|
}
|
|
|
|
// ????
|
|
function handleDelData(row: any) {
|
|
const id = row?.id ?? row;
|
|
$baseConfirm({
|
|
content: t('track.warningConfig.modal.deletePushConfirm'),
|
|
title: t('track.push.modal.warningTitle'),
|
|
onOk: async () => {
|
|
await postEdit({ options: 2, id, appKey: userStore.appKey });
|
|
onFormSubmitClick();
|
|
$baseMessage(t('track.push.message.deleteSuccess'), 'success');
|
|
if (id === currentId.value?.id) currentId.value = undefined;
|
|
},
|
|
});
|
|
}
|
|
// // ??????
|
|
function handleDelRightData(id: number) {
|
|
$baseConfirm({
|
|
content: t('track.push.modal.deleteConfirm'),
|
|
title: t('track.push.modal.warningTitle'),
|
|
onOk: async () => {
|
|
await postEditContent({ options: 2, id });
|
|
unref(customListRef)?.tableRef?.reload?.();
|
|
$baseMessage(t('track.push.message.deleteSuccess'), 'success');
|
|
},
|
|
});
|
|
}
|
|
|
|
/** ?? */
|
|
function onFormSubmitClick() {
|
|
loadPushList();
|
|
currentId.value = undefined;
|
|
customListRef.value?.reloadData([]);
|
|
}
|
|
|
|
/** ???? */
|
|
function handleSearch() {
|
|
Object.assign(searchModel, { keywords: searchKeyword.value });
|
|
loadPushList();
|
|
currentId.value = undefined;
|
|
customListRef.value?.reloadData([]);
|
|
}
|
|
|
|
/** ???? */
|
|
function handleRefresh() {
|
|
searchKeyword.value = '';
|
|
Object.assign(searchModel, { keywords: '' });
|
|
loadPushList();
|
|
currentId.value = undefined;
|
|
customListRef.value?.reloadData([]);
|
|
}
|
|
|
|
// ??????
|
|
function onSubmitLeft() {
|
|
onFormSubmitClick();
|
|
}
|
|
// ??????
|
|
function onSubmitRight() {
|
|
loadTableData();
|
|
}
|
|
|
|
function caclHeiht() {
|
|
setTimeout(() => {
|
|
calcContentHeight();
|
|
}, 100);
|
|
}
|
|
|
|
watch(
|
|
() => currentId.value,
|
|
(val) => {
|
|
if (val) cellClick(val);
|
|
},
|
|
{
|
|
deep: true,
|
|
}
|
|
);
|
|
|
|
onMounted(() => {
|
|
loadAppMap();
|
|
loadPushList();
|
|
});
|
|
|
|
const loading = ref(false);
|
|
|
|
const loadTableData = async () => {
|
|
if (!currentId.value?.id || !activeTab.value) {
|
|
detailListData.value = [];
|
|
customListRef.value?.reloadData?.([]);
|
|
totalCount.value = 0;
|
|
return;
|
|
}
|
|
loading.value = true;
|
|
try {
|
|
const res = await postGetContentPage({
|
|
trackPushConfigId: currentId.value.id,
|
|
orderNoType: activeTab.value as API.TrackOrderType | undefined,
|
|
pageIndex: currentPage.value,
|
|
pageSize: pageSize.value,
|
|
}) as API.GetTrackPushContentPageOutputVOPagedResult;
|
|
totalCount.value = res?.totalCount || 0;
|
|
const items = res?.items || [];
|
|
items.forEach((r: any) => {
|
|
r.trackContentId = r.trackContentId ?? r.contentId;
|
|
});
|
|
detailListData.value = items;
|
|
customListRef.value?.reloadData?.(items);
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
};
|
|
|
|
// 自定义列下拉建议:取当前列在本表数据中的去重非空值,供 a-auto-complete 使用
|
|
function getCustomColumnSuggestions(field: string): { value: string }[] {
|
|
const set = new Set<string>();
|
|
for (const row of detailListData.value) {
|
|
const v = row[field];
|
|
if (v != null && String(v).trim() !== '') set.add(String(v).trim());
|
|
}
|
|
return Array.from(set).map((v) => ({ value: v }));
|
|
}
|
|
|
|
// 将轨迹内容 id 规范为数字,便于 a-select 与 option value 匹配并正确显示 label
|
|
function normalizeTrackContentId(val: any): number | undefined {
|
|
if (val == null || val === '') return undefined;
|
|
const n = Number(val);
|
|
return Number.isNaN(n) ? undefined : n;
|
|
}
|
|
|
|
// 新增:增加一行空白数据(不打开弹窗)
|
|
function handleAddBlankRow() {
|
|
if (!currentId.value?.id || activeTab.value == null) return;
|
|
const rowKey = `new_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
const blankRow: any = {
|
|
__isNew: true,
|
|
_rowKey: rowKey,
|
|
id: rowKey,
|
|
trackPushConfigId: currentId.value.id,
|
|
orderNoType: activeTab.value,
|
|
};
|
|
customColumns.value.forEach((col) => {
|
|
blankRow[col.field] = '';
|
|
});
|
|
const next = [...detailListData.value, blankRow];
|
|
detailListData.value = next;
|
|
customListRef.value?.reloadData?.(next);
|
|
$baseMessage(t('track.push.actions.add') + ' 一行空白数据');
|
|
}
|
|
|
|
// 删除新增的空白行(未保存的)
|
|
function handleDelNewRow(row: any) {
|
|
const idx = detailListData.value.findIndex((r: any) => r === row || (r._rowKey && r._rowKey === row._rowKey));
|
|
if (idx > -1) {
|
|
detailListData.value.splice(idx, 1);
|
|
const next = [...detailListData.value];
|
|
detailListData.value = next;
|
|
customListRef.value?.reloadData?.(next);
|
|
}
|
|
}
|
|
|
|
const handlePageChange = (page: number) => {
|
|
if (page < 1) return;
|
|
const max = Math.max(1, Math.ceil(totalCount.value / pageSize.value));
|
|
if (page > max) return;
|
|
currentPage.value = page;
|
|
jumpPage.value = String(page);
|
|
loadTableData();
|
|
};
|
|
|
|
const handlePageSizeChange = (size: number) => {
|
|
pageSize.value = size;
|
|
currentPage.value = 1;
|
|
jumpPage.value = '1';
|
|
loadTableData();
|
|
};
|
|
|
|
const handleJumpPage = () => {
|
|
const val = Number(jumpPage.value);
|
|
if (!val || val < 1) return;
|
|
const max = Math.max(1, Math.ceil(totalCount.value / pageSize.value));
|
|
handlePageChange(Math.min(val, max));
|
|
};
|
|
|
|
defineExpose({
|
|
caclHeiht,
|
|
});
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<div ref="refHeight" class="track-layout">
|
|
<BasicLayoutLeftRight :left-width="280">
|
|
<template #left>
|
|
<CustomLeftMenu
|
|
:tree-data="pushTreeData"
|
|
:selected-keys="pushSelectedKeys"
|
|
v-model:expanded-keys="pushExpandedKeys"
|
|
:loading="pushLoading"
|
|
v-model:search-keyword="searchKeyword"
|
|
:search-placeholder="$t('track.push.search.placeholder')"
|
|
:refresh-title="$t('track.push.actions.refresh')"
|
|
:add-title="$t('track.push.actions.addPush')"
|
|
loading-text="加载中..."
|
|
:delete-label="$t('track.push.actions.delete')"
|
|
:show-method="false"
|
|
:show-map-count="false"
|
|
@search="handleSearch"
|
|
@refresh="handleRefresh"
|
|
@add="handleOpenModal('add')"
|
|
@select="handlePushSelectFromTree"
|
|
@delete-node="(nodeData) => handleDelData(nodeData)"
|
|
@node-click="(key) => { const id = key.startsWith('item-') ? Number(key.slice(5)) : null; if (id != null) { const item = pushListData.find((x: any) => x.id === id); if (item) cellClick(item); } }"
|
|
>
|
|
<template #node-menu="{ nodeData }">
|
|
<a-doption @click="handleOpenModal('edit', nodeData)">
|
|
<IconEdit style="margin-right: 8px;" />
|
|
修改
|
|
</a-doption>
|
|
<a-doption @click="handleDelData(nodeData)">
|
|
<IconDelete style="margin-right: 8px;" />
|
|
删除
|
|
</a-doption>
|
|
</template>
|
|
</CustomLeftMenu>
|
|
|
|
<ModalForm
|
|
ref="modalFormLeftRef"
|
|
:form-props="leftFormProps"
|
|
:edit-api="postEdit"
|
|
:add-api="postEdit"
|
|
:info-api="getGetDetail"
|
|
:api-params="editFormParams"
|
|
@on-submit="onSubmitLeft"
|
|
/>
|
|
</template>
|
|
<template #right>
|
|
<div class="right-content-panel">
|
|
<a-tabs
|
|
v-model="activeTab"
|
|
type="line"
|
|
size="large"
|
|
class="left-aligned-tabs"
|
|
:class="{ 'visibility-hidden': !currentId }"
|
|
@tab-click="handleTabClick"
|
|
>
|
|
<a-tab-pane
|
|
v-for="item in tabs"
|
|
:key="item?.key"
|
|
:title="item.value"
|
|
:name="item.key"
|
|
/>
|
|
</a-tabs>
|
|
<!-- ?? Tab???? + ??????+ ?? -->
|
|
<div v-if="currentId && activeTab" class="detail-tab-wrapper">
|
|
<CustomList
|
|
ref="customListRef"
|
|
v-model="customColumns"
|
|
:data="detailListData"
|
|
mode="modal"
|
|
:section-title="$t('track.push.table.customHeader')"
|
|
:add-placeholder="$t('track.push.table.customColumnPlaceholder')"
|
|
:fixed-left-columns="pushFixedLeftColumns"
|
|
:fixed-right-columns="pushFixedRightColumns"
|
|
:table-config-extra="pushTableConfigExtra"
|
|
:table-height="400"
|
|
columns-key="trackPushDetail"
|
|
:custom-header-disabled="!currentId || !currentId.id"
|
|
>
|
|
<template #toolbar-left>
|
|
<TableButtons
|
|
:actions="[
|
|
{
|
|
label: $t('track.push.actions.add'),
|
|
type: 'primary',
|
|
disabled: !currentId || !currentId.id,
|
|
onClick: handleAddBlankRow,
|
|
},
|
|
]"
|
|
class="big-btn"
|
|
/>
|
|
</template>
|
|
<template #toolbar-right>
|
|
<div class="custom-list-toolbar-right-inner">
|
|
<div class="pagination-controls">
|
|
<span class="total-records">
|
|
{{ $t('track.order.pagination.total', { count: totalCount }) }}
|
|
</span>
|
|
<a-button
|
|
size="small"
|
|
:disabled="currentPage <= 1"
|
|
@click="handlePageChange(currentPage - 1)"
|
|
>
|
|
<
|
|
</a-button>
|
|
<span class="current-page">{{ currentPage }}</span>
|
|
<a-button
|
|
size="small"
|
|
:disabled="currentPage >= Math.ceil(totalCount / pageSize)"
|
|
@click="handlePageChange(currentPage + 1)"
|
|
>
|
|
>
|
|
</a-button>
|
|
<a-select
|
|
v-model="pageSize"
|
|
size="small"
|
|
class="page-size-select"
|
|
@change="handlePageSizeChange"
|
|
>
|
|
<a-option :value="10">10</a-option>
|
|
<a-option :value="30">30</a-option>
|
|
<a-option :value="50">50</a-option>
|
|
<a-option :value="100">100</a-option>
|
|
</a-select>
|
|
<span class="page-size-text">{{ $t('track.order.pagination.perPage') }}</span>
|
|
<span class="go-to-text">{{ $t('track.order.pagination.goTo') }}</span>
|
|
<a-input
|
|
v-model="jumpPage"
|
|
size="small"
|
|
class="jump-input"
|
|
@keyup.enter="handleJumpPage"
|
|
/>
|
|
<span class="page-text">{{ $t('track.order.pagination.page') }}</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template #standardTrack="{ row }">
|
|
<SelectPro
|
|
:model-value="normalizeTrackContentId(row.trackContentId ?? row.contentId)"
|
|
:api="postGetList"
|
|
:label-keys="['code', 'content', 'enContent']"
|
|
:title-strs="[$t('track.push.titleStrs.trackCode'), $t('track.push.titleStrs.trackContent'), $t('track.push.table.trackContentEn')]"
|
|
separator="-"
|
|
id-key="id"
|
|
search-key="keywords"
|
|
:extra="{ appKey: userStore.appKey, pageSize: 100 }"
|
|
:is-page="false"
|
|
immediate
|
|
clearable
|
|
class="standard-track-select"
|
|
@update:model-value="(val: number) => { row.trackContentId = val; row.contentId = val; }"
|
|
@select-change="(payload: any) => { if (payload?.item) { row.code = payload.item.code; row.content = payload.item.content; row.enContent = payload.item.enContent; } }"
|
|
/>
|
|
</template>
|
|
<template
|
|
v-for="col in customColumns"
|
|
:key="col.field"
|
|
#[col.field]="{ row }"
|
|
>
|
|
<a-auto-complete
|
|
v-model="row[col.field]"
|
|
:data="getCustomColumnSuggestions(col.field)"
|
|
:filter-option="(inputValue: string, option: { value: string }) => (option.value || '').toLowerCase().includes((inputValue || '').toLowerCase())"
|
|
allow-clear
|
|
placeholder="请输入或选择"
|
|
class="custom-column-autocomplete"
|
|
/>
|
|
</template>
|
|
<template #action="{ row }">
|
|
<div class="action-buttons">
|
|
<a-button
|
|
type="text"
|
|
size="small"
|
|
class="action-btn edit-btn"
|
|
@click="row.__isNew ? handleOpenRightModal('add') : handleOpenRightModal('edit', row)"
|
|
:title="$t('track.push.actions.edit')"
|
|
>
|
|
<IconEdit />
|
|
</a-button>
|
|
<a-button
|
|
type="text"
|
|
size="small"
|
|
class="action-btn delete-btn"
|
|
@click="row.__isNew ? handleDelNewRow(row) : handleDelRightData(row.id)"
|
|
:title="$t('track.push.actions.delete')"
|
|
>
|
|
<IconDelete />
|
|
</a-button>
|
|
</div>
|
|
</template>
|
|
</CustomList>
|
|
</div>
|
|
</div>
|
|
<ModalForm
|
|
ref="modalFormRightRef"
|
|
:edit-api="postEditContent"
|
|
:add-api="postEditContent"
|
|
:info-api="getGetContentDetail"
|
|
:api-params="editFormRightParams"
|
|
:form-props="rightFormProps"
|
|
@on-submit="onSubmitRight"
|
|
/>
|
|
</template>
|
|
</BasicLayoutLeftRight>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="less" scoped>
|
|
/* ?????? - ??????interface-layout?????*/
|
|
.track-layout {
|
|
display: flex;
|
|
height: calc(100vh - 86px);
|
|
max-height: calc(100vh - 86px);
|
|
padding: 16px;
|
|
gap: 16px;
|
|
background-color: var(--color-fill-2);
|
|
overflow: hidden;
|
|
box-sizing: border-box;
|
|
width: 100%;
|
|
}
|
|
|
|
/* ?????? - ????????????????*/
|
|
:deep(.trb-transform-left) {
|
|
background: var(--app-sidebar-bg) !important;
|
|
backdrop-filter: blur(20px) saturate(180%);
|
|
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
|
border: 1px solid rgba(255, 255, 255, 0.18) !important;
|
|
border-top: 1px solid rgba(255, 255, 255, 0.25) !important;
|
|
border-radius: 24px !important;
|
|
box-shadow:
|
|
0 8px 32px rgba(0, 0, 0, 0.4),
|
|
0 2px 8px rgba(0, 0, 0, 0.3),
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.1),
|
|
inset 0 -1px 0 rgba(0, 0, 0, 0.2);
|
|
position: relative;
|
|
color: #fff;
|
|
|
|
&::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 1px;
|
|
background: linear-gradient(90deg,
|
|
transparent 0%,
|
|
rgba(255, 255, 255, 0.3) 50%,
|
|
transparent 100%);
|
|
pointer-events: none;
|
|
z-index: 1;
|
|
}
|
|
}
|
|
|
|
.mx-8px {
|
|
padding: 0;
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.w-full {
|
|
padding: 0;
|
|
}
|
|
|
|
.pb-10px {
|
|
padding-bottom: 0 !important;
|
|
}
|
|
|
|
.serach_header {
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.08) !important;
|
|
padding: 10px 12px !important;
|
|
min-height: 48px !important;
|
|
margin: 0;
|
|
}
|
|
|
|
/* ?????? - ??????interface-tree?????*/
|
|
:deep(.scrollbarplus) {
|
|
padding: 8px 0 0;
|
|
padding-right: 4px;
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.h-full {
|
|
.visibility-hidden {
|
|
visibility: hidden;
|
|
}
|
|
|
|
:deep(.a-tabs) {
|
|
.a-tabs__content {
|
|
display: none;
|
|
}
|
|
|
|
.a-tabs__nav-extra {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
/* ????????tab */
|
|
:deep(.a-tab-pane) {
|
|
background-color: #f0f1f2;
|
|
}
|
|
|
|
:deep(.arco-tabs-content) {
|
|
padding: 0;
|
|
}
|
|
|
|
:deep(.arco-tabs-nav) {
|
|
background-color: #fff;
|
|
}
|
|
}
|
|
|
|
.search-box {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
width: 100%;
|
|
|
|
:deep(.arco-input-wrapper) {
|
|
background: rgba(255, 255, 255, 0.1) !important;
|
|
border: 1px solid rgba(255, 255, 255, 0.2) !important;
|
|
border-radius: 4px !important;
|
|
|
|
&:hover, &:focus-within {
|
|
background: rgba(255, 255, 255, 0.15) !important;
|
|
border-color: rgba(255, 255, 255, 0.3) !important;
|
|
}
|
|
}
|
|
|
|
:deep(.arco-input) {
|
|
background: transparent !important;
|
|
border: none !important;
|
|
color: #fff !important;
|
|
|
|
&::placeholder {
|
|
color: rgba(255, 255, 255, 0.5) !important;
|
|
}
|
|
}
|
|
|
|
:deep(.arco-input-prefix) {
|
|
color: rgba(255, 255, 255, 0.6) !important;
|
|
}
|
|
}
|
|
|
|
.search-actions {
|
|
display: flex;
|
|
gap: 4px;
|
|
}
|
|
|
|
.action-icon-btn {
|
|
width: 28px;
|
|
height: 28px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
transition: all 0.2s ease;
|
|
|
|
&.refresh-btn {
|
|
color: #fff;
|
|
border-radius: 4px;
|
|
|
|
&:hover {
|
|
color: var(--app-primary-color);
|
|
}
|
|
}
|
|
|
|
&.add-btn {
|
|
color: var(--app-primary-color) !important;
|
|
background-color: rgba(73, 186, 179, 0.1) !important;
|
|
border: 1px solid var(--app-primary-color) !important;
|
|
border-radius: 50% !important;
|
|
width: 28px !important;
|
|
height: 28px !important;
|
|
min-width: 28px !important;
|
|
max-width: 28px !important;
|
|
min-height: 28px !important;
|
|
max-height: 28px !important;
|
|
padding: 0 !important;
|
|
line-height: 28px !important;
|
|
|
|
&:hover {
|
|
color: #ffffff !important;
|
|
background-color: var(--app-primary-color) !important;
|
|
border-color: var(--app-primary-color) !important;
|
|
}
|
|
}
|
|
}
|
|
|
|
.action-buttons {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 8px;
|
|
|
|
.action-btn {
|
|
padding: 4px;
|
|
border-radius: 4px;
|
|
transition: all 0.2s ease;
|
|
|
|
&.edit-btn {
|
|
color: var(--color-text-2);
|
|
|
|
&:hover {
|
|
background-color: var(--color-fill-2);
|
|
color: var(--color-text-1);
|
|
}
|
|
}
|
|
|
|
&.delete-btn {
|
|
color: #ff4d4f;
|
|
|
|
&:hover {
|
|
background-color: #fff2f0;
|
|
color: #ff7875;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ?????????? */
|
|
:deep(.arco-btn[disabled]) {
|
|
opacity: 0.5 !important;
|
|
cursor: not-allowed !important;
|
|
background-color: #f5f5f5 !important;
|
|
color: #bfbfbf !important;
|
|
border-color: #d9d9d9 !important;
|
|
}
|
|
|
|
/* ?????? - ?????*/
|
|
.right-content-panel {
|
|
height: 100%;
|
|
background-color: #fff;
|
|
border-radius: 24px;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex-direction: column;
|
|
padding: 0;
|
|
margin: 0;
|
|
}
|
|
|
|
.left-aligned-tabs {
|
|
flex-shrink: 0;
|
|
|
|
:deep(.arco-tabs-nav) {
|
|
border-bottom: 1px solid var(--color-border-2);
|
|
margin: 0;
|
|
padding: 0;
|
|
justify-content: flex-start !important;
|
|
}
|
|
|
|
:deep(.arco-tabs-content) {
|
|
flex: 1;
|
|
padding: 0;
|
|
overflow: hidden;
|
|
background: #fff;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
}
|
|
|
|
:deep(.arco-tabs-pane) {
|
|
height: 100%;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
}
|
|
}
|
|
|
|
.table-toolbar {
|
|
margin-bottom: 8px;
|
|
margin-left: 0;
|
|
margin-right: 0;
|
|
display: flex;
|
|
justify-content: flex-start;
|
|
align-items: center;
|
|
padding: 0 16px;
|
|
width: 100%;
|
|
|
|
.toolbar-left {
|
|
flex: 0 0 auto;
|
|
margin-left: 0;
|
|
padding-left: 0;
|
|
|
|
.left-aligned-buttons {
|
|
justify-content: flex-start;
|
|
margin-left: 0;
|
|
padding-left: 0;
|
|
}
|
|
}
|
|
|
|
.toolbar-right {
|
|
margin-left: auto;
|
|
flex: 0 0 auto;
|
|
}
|
|
}
|
|
|
|
/* CustomList 工具栏右侧:新增 + 分页,整体在列表右上角 */
|
|
.custom-list-toolbar-right-inner {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
flex-wrap: nowrap;
|
|
}
|
|
|
|
.toolbar-right .pagination-controls,
|
|
.custom-list-toolbar-right-inner .pagination-controls {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
white-space: nowrap;
|
|
flex-wrap: nowrap;
|
|
|
|
.total-records,
|
|
.go-to-text,
|
|
.page-size-text,
|
|
.page-text {
|
|
font-size: 12px;
|
|
color: #4e5969;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.current-page {
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
color: #1d2129;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.arco-btn-size-small {
|
|
padding: 0 8px;
|
|
height: 24px;
|
|
min-width: 24px;
|
|
border-radius: 4px;
|
|
color: #4e5969;
|
|
border: 1px solid #e5e6eb;
|
|
background-color: #fff;
|
|
|
|
&:hover {
|
|
background-color: #f2f3f5;
|
|
}
|
|
|
|
&:disabled {
|
|
cursor: not-allowed;
|
|
opacity: 0.6;
|
|
}
|
|
}
|
|
|
|
.arco-select-size-small {
|
|
.arco-select-view {
|
|
height: 24px;
|
|
line-height: 24px;
|
|
font-size: 12px;
|
|
}
|
|
}
|
|
|
|
.arco-input-size-small {
|
|
.arco-input-wrapper {
|
|
height: 24px;
|
|
line-height: 24px;
|
|
font-size: 12px;
|
|
}
|
|
}
|
|
}
|
|
|
|
.page-size-select {
|
|
width: 110px;
|
|
}
|
|
|
|
.jump-input {
|
|
width: 60px;
|
|
}
|
|
|
|
.detail-tab-wrapper {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
padding: 0;
|
|
margin: 0;
|
|
min-height: 0;
|
|
|
|
:deep(.vxe-table) {
|
|
overflow-x: hidden !important;
|
|
|
|
.vxe-table--body-wrapper {
|
|
overflow-x: hidden !important;
|
|
}
|
|
|
|
.vxe-table--header-wrapper {
|
|
overflow-x: hidden !important;
|
|
}
|
|
|
|
.vxe-body--column:first-child,
|
|
.vxe-header--column:first-child {
|
|
&,
|
|
& .vxe-cell,
|
|
& .vxe-cell--title {
|
|
text-align: center !important;
|
|
justify-content: center !important;
|
|
padding-left: 0 !important;
|
|
}
|
|
|
|
.vxe-cell--title {
|
|
display: flex !important;
|
|
align-items: center !important;
|
|
justify-content: center !important;
|
|
}
|
|
}
|
|
|
|
.vxe-body--column:not(:first-child) .vxe-cell,
|
|
.vxe-header--column:not(:first-child) .vxe-cell {
|
|
text-align: left !important;
|
|
justify-content: flex-start !important;
|
|
padding-left: 12px !important;
|
|
}
|
|
|
|
.vxe-cell {
|
|
text-align: left !important;
|
|
justify-content: flex-start !important;
|
|
padding-left: 12px !important;
|
|
}
|
|
|
|
.vxe-header--column {
|
|
text-align: left !important;
|
|
justify-content: flex-start !important;
|
|
padding-left: 12px !important;
|
|
}
|
|
|
|
.vxe-cell--title {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.vxe-table--body-wrapper,
|
|
.vxe-table--header-wrapper {
|
|
width: 100% !important;
|
|
}
|
|
|
|
.vxe-table--main-wrapper {
|
|
width: 100% !important;
|
|
}
|
|
|
|
.vxe-table--body,
|
|
.vxe-table--header {
|
|
width: 100% !important;
|
|
}
|
|
|
|
.vxe-table--body .vxe-body--column:last-child,
|
|
.vxe-table--header .vxe-header--column:last-child {
|
|
padding-right: 0 !important;
|
|
}
|
|
}
|
|
|
|
:deep(.vxe-table--container) {
|
|
overflow-x: hidden !important;
|
|
width: 100% !important;
|
|
padding: 0 !important;
|
|
margin: 0 !important;
|
|
}
|
|
|
|
:deep(.vxe-table) {
|
|
width: 100% !important;
|
|
margin: 0 !important;
|
|
}
|
|
|
|
:deep(.vxe-table--main-wrapper) {
|
|
padding: 0 !important;
|
|
margin: 0 !important;
|
|
}
|
|
}
|
|
|
|
.standard-track-cell {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
max-width: 100%;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.standard-track-select {
|
|
width: 100%;
|
|
}
|
|
|
|
.custom-column-autocomplete {
|
|
width: 100%;
|
|
}
|
|
|
|
/* 自定义表头弹窗 - 标签高度与输入框一致,整体美化 */
|
|
.custom-header-modal :deep(.arco-modal-body) {
|
|
padding: 16px 20px 20px;
|
|
}
|
|
|
|
.column-management-section {
|
|
padding: 16px 0;
|
|
min-width: 320px;
|
|
|
|
.column-list {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 10px;
|
|
max-height: 320px;
|
|
overflow-y: auto;
|
|
padding: 4px 0;
|
|
|
|
.column-item {
|
|
display: flex;
|
|
align-items: center;
|
|
min-height: 28px; /* 与 a-input size="small" 高度一致 */
|
|
|
|
.column-edit {
|
|
display: flex;
|
|
align-items: center;
|
|
min-height: 28px;
|
|
|
|
:deep(.arco-input-wrapper) {
|
|
height: 28px;
|
|
min-height: 28px;
|
|
}
|
|
|
|
.arco-input {
|
|
width: 160px;
|
|
height: 28px;
|
|
}
|
|
}
|
|
|
|
.column-display {
|
|
display: flex;
|
|
align-items: center;
|
|
min-height: 28px;
|
|
height: 28px;
|
|
padding: 0 10px;
|
|
background-color: var(--color-fill-2);
|
|
border: 1px solid var(--color-border-2);
|
|
border-radius: 6px;
|
|
box-sizing: border-box;
|
|
transition: border-color 0.2s, background-color 0.2s;
|
|
|
|
&:hover {
|
|
border-color: var(--color-border-3);
|
|
background-color: var(--color-fill-3);
|
|
}
|
|
|
|
.column-name {
|
|
cursor: pointer;
|
|
margin-right: 6px;
|
|
font-size: 13px;
|
|
line-height: 28px;
|
|
color: var(--color-text-1);
|
|
|
|
&:hover {
|
|
color: rgb(var(--primary-6));
|
|
}
|
|
}
|
|
|
|
.column-delete-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 18px;
|
|
height: 18px;
|
|
min-width: 18px;
|
|
min-height: 18px;
|
|
padding: 0;
|
|
margin: 0;
|
|
color: rgb(var(--danger-6));
|
|
font-size: 14px;
|
|
line-height: 1;
|
|
border-radius: 4px;
|
|
opacity: 0.75;
|
|
transition: opacity 0.2s, background-color 0.2s;
|
|
|
|
&:hover {
|
|
opacity: 1;
|
|
background-color: rgb(var(--danger-6) / 0.12);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.column-add-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
min-height: 28px;
|
|
|
|
.column-add-input {
|
|
width: 220px;
|
|
|
|
:deep(.arco-input-wrapper) {
|
|
height: 28px;
|
|
min-height: 28px;
|
|
}
|
|
}
|
|
|
|
.arco-btn {
|
|
height: 28px;
|
|
min-width: 28px;
|
|
padding: 0 8px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 左侧面板与轨迹拉取一致 */
|
|
:deep(.trb-transform-left) {
|
|
background: transparent !important;
|
|
border: none !important;
|
|
box-shadow: none !important;
|
|
height: 100%;
|
|
min-height: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
position: relative;
|
|
padding: 0 !important;
|
|
margin-right: 16px !important;
|
|
}
|
|
|
|
:deep(.trb-transform-left > *:first-child) {
|
|
flex: 1;
|
|
min-height: 0;
|
|
height: 100%;
|
|
}
|
|
|
|
:deep(.node-code-cell) {
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
:deep(.node-second-row-extra-cell) {
|
|
display: none;
|
|
}
|
|
|
|
/* ??BasicLayoutLeftRight???margin */
|
|
:deep(.trb-transform) {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
</style>
|