add psap version
This commit is contained in:
16
src/api/agentManage/callback.ts
Normal file
16
src/api/agentManage/callback.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { request } from '@/plugins/http-fetch';
|
||||
|
||||
|
||||
/**
|
||||
* 查询定时任务调度列表
|
||||
* @param query 查询参数
|
||||
* @returns object
|
||||
*/
|
||||
export function listCallBack(query: Record<string, any>) {
|
||||
return request({
|
||||
url: '/psap/v1/mf/ticket/list',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -358,6 +358,15 @@ export default {
|
||||
answeredTime:'Answered Time',
|
||||
callDuration:'Call Duration',
|
||||
msdData:'MSD Info',
|
||||
},
|
||||
callback:{
|
||||
callerIdNumber:'Caller Number',
|
||||
calleeIdNumber:'Callee Number',
|
||||
status:'Status',
|
||||
ticketId:'Ticket ID',
|
||||
startTime:'Start Time',
|
||||
msdData:'MSD Info',
|
||||
agentName: 'Agent Name',
|
||||
}
|
||||
},
|
||||
dashboard: {
|
||||
|
||||
@@ -358,6 +358,15 @@ export default {
|
||||
answeredTime:'接听时间',
|
||||
callDuration:'通话时长',
|
||||
msdData:'MSD内容',
|
||||
},
|
||||
callback:{
|
||||
callerIdNumber:'主叫号码',
|
||||
calleeIdNumber:'被叫号码',
|
||||
status:'状态',
|
||||
ticketId:'工单编号',
|
||||
startTime:'开始时间',
|
||||
msdData:'MSD内容',
|
||||
agentName: '座席名称',
|
||||
}
|
||||
},
|
||||
dashboard: {
|
||||
|
||||
227
src/views/agentManage/callback/index.vue
Normal file
227
src/views/agentManage/callback/index.vue
Normal file
@@ -0,0 +1,227 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, onMounted, toRaw } from 'vue';
|
||||
import { PageContainer } from 'antdv-pro-layout';
|
||||
import { SizeType } from 'ant-design-vue/es/config-provider';
|
||||
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
|
||||
import { ColumnsType } from 'ant-design-vue/es/table';
|
||||
import { parseDateToStr,parseStrToDate } from '@/utils/date-utils';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { listCallBack } from '@/api/agentManage/callback';
|
||||
import useNeInfoStore from '@/store/modules/neinfo';
|
||||
import useDictStore from '@/store/modules/dict';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
const { getDict } = useDictStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
|
||||
|
||||
|
||||
/**查询参数 */
|
||||
let queryParams = reactive({
|
||||
/**网元类型 */
|
||||
neId: '001',
|
||||
/**记录时间 */
|
||||
beginTime: '',
|
||||
endTime: '',
|
||||
/**当前页数 */
|
||||
pageNum: 1,
|
||||
/**每页条数 */
|
||||
pageSize: 20,
|
||||
});
|
||||
|
||||
|
||||
/**表格状态类型 */
|
||||
type TabeStateType = {
|
||||
/**加载等待 */
|
||||
loading: boolean;
|
||||
/**紧凑型 */
|
||||
size: SizeType;
|
||||
/**搜索栏 */
|
||||
seached: boolean;
|
||||
/**记录数据 */
|
||||
data: object[];
|
||||
};
|
||||
|
||||
/**表格状态 */
|
||||
let tableState: TabeStateType = reactive({
|
||||
loading: false,
|
||||
size: 'middle',
|
||||
seached: true,
|
||||
data: [],
|
||||
});
|
||||
|
||||
/**表格字段列 */
|
||||
let tableColumns: ColumnsType = [
|
||||
{
|
||||
title: t('views.agentManage.callback.ticketId'),
|
||||
dataIndex: 'ticketId',
|
||||
align: 'center',
|
||||
width: 5,
|
||||
},
|
||||
{
|
||||
title: t('views.agentManage.callback.agentName'),
|
||||
dataIndex: 'agentName',
|
||||
align: 'center',
|
||||
width: 5,
|
||||
},
|
||||
{
|
||||
title: t('views.agentManage.callback.callerIdNumber'),
|
||||
dataIndex: 'callerNumber',
|
||||
align: 'center',
|
||||
width: 5,
|
||||
},
|
||||
{
|
||||
title: t('views.agentManage.callback.calleeIdNumber'),
|
||||
dataIndex: 'calleeNumber',
|
||||
align: 'center',
|
||||
width: 5,
|
||||
},
|
||||
{
|
||||
title: t('views.agentManage.callback.startTime'),
|
||||
dataIndex: 'createdAt',
|
||||
align: 'center',
|
||||
width: 6,
|
||||
customRender(opt) {
|
||||
if (!opt.value) return '';
|
||||
return parseDateToStr(opt.value/1000);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('views.agentManage.callback.status'),
|
||||
dataIndex: 'status',
|
||||
align: 'center',
|
||||
width: 4,
|
||||
},
|
||||
{
|
||||
title: t('views.agentManage.callback.msdData'),
|
||||
dataIndex: 'msdData',
|
||||
align: 'center',
|
||||
width: 6,
|
||||
},
|
||||
];
|
||||
|
||||
/**表格分页器参数 */
|
||||
let tablePagination = reactive({
|
||||
/**当前页数 */
|
||||
current: 1,
|
||||
/**每页条数 */
|
||||
pageSize: 20,
|
||||
/**默认的每页条数 */
|
||||
defaultPageSize: 20,
|
||||
/**指定每页可以显示多少条 */
|
||||
pageSizeOptions: ['10', '20', '50', '100'],
|
||||
/**只有一页时是否隐藏分页器 */
|
||||
hideOnSinglePage: false,
|
||||
/**是否可以快速跳转至某页 */
|
||||
showQuickJumper: true,
|
||||
/**是否可以改变 pageSize */
|
||||
showSizeChanger: true,
|
||||
/**数据总数 */
|
||||
total: 0,
|
||||
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
|
||||
onChange: (page: number, pageSize: number) => {
|
||||
tablePagination.current = page;
|
||||
tablePagination.pageSize = pageSize;
|
||||
queryParams.pageNum = page;
|
||||
queryParams.pageSize = pageSize;
|
||||
fnGetList();
|
||||
},
|
||||
});
|
||||
|
||||
/**表格紧凑型变更操作 */
|
||||
function fnTableSize({ key }: MenuInfo) {
|
||||
tableState.size = key as SizeType;
|
||||
}
|
||||
|
||||
/**查询备份信息列表, pageNum初始页数 */
|
||||
function fnGetList(pageNum?: number) {
|
||||
if (tableState.loading) return;
|
||||
tableState.loading = true;
|
||||
if (pageNum) {
|
||||
queryParams.pageNum = pageNum;
|
||||
}
|
||||
|
||||
|
||||
listCallBack(toRaw(queryParams)).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
tablePagination.total = res.total;
|
||||
tableState.data = res.data;
|
||||
if (tablePagination.total <= (queryParams.pageNum - 1) * tablePagination.pageSize && queryParams.pageNum !== 1) {
|
||||
tableState.loading = false;
|
||||
fnGetList(queryParams.pageNum - 1);
|
||||
}
|
||||
}
|
||||
tableState.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 获取列表数据
|
||||
fnGetList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PageContainer>
|
||||
|
||||
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title> </template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.reloadText') }}</template>
|
||||
<a-button type="text" @click.prevent="fnGetList()">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.sizeText') }}</template>
|
||||
<a-dropdown trigger="click" placement="bottomRight">
|
||||
<a-button type="text">
|
||||
<template #icon>
|
||||
<ColumnHeightOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
<template #overlay>
|
||||
<a-menu :selected-keys="[tableState.size as string]" @click="fnTableSize">
|
||||
<a-menu-item key="default">
|
||||
{{ t('common.size.default') }}
|
||||
</a-menu-item>
|
||||
<a-menu-item key="middle">
|
||||
{{ t('common.size.middle') }}
|
||||
</a-menu-item>
|
||||
<a-menu-item key="small">
|
||||
{{ t('common.size.small') }}
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
<a-table class="table" row-key="id" :columns="tableColumns" :loading="tableState.loading"
|
||||
:data-source="tableState.data" :size="tableState.size" :pagination="tablePagination"
|
||||
:scroll="{ x: 1500, y: 400 }">
|
||||
</a-table>
|
||||
</a-card>
|
||||
</PageContainer>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.table :deep(.ant-pagination) {
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.alarmTitleText {
|
||||
max-width: 300px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@@ -54,7 +54,7 @@ function updateChartData(newValue: number, dataArray: any) {
|
||||
const isFirstLoadUser = ref(true);
|
||||
function updateUserChartData(newValue: number, dataArray: any) {
|
||||
// 如果是第一次加载,用当前值填充整个数组
|
||||
if (isFirstLoad.value) {
|
||||
if (isFirstLoadUser.value) {
|
||||
dataArray.value = Array(7).fill(newValue);
|
||||
} else {
|
||||
// 非第一次加载,正常更新数据(移除第一个,添加新值)
|
||||
@@ -272,7 +272,6 @@ function fnGetList() {
|
||||
prevFailedCallsCount.value = failedCallsCount.value;
|
||||
|
||||
|
||||
// 更新 activeCallsData 和 mosData
|
||||
failedCallsCount.value = res.total; // 数组长度
|
||||
|
||||
failedCallsCountChange.value = prevFailedCallsCount.value ? prevFailedCallsCount.value - failedCallsCount.value : 0;
|
||||
@@ -323,7 +322,7 @@ onBeforeUnmount(() => {
|
||||
<div class="row-title">{{ t('views.dashboard.overview.userTitle') }}</div>
|
||||
<a-row :gutter="[48, 48]">
|
||||
<a-col :xs="24" :sm="24" :lg="8">
|
||||
<a-card :bordered="false" class="metric-card">
|
||||
<a-card :bordered="false" class="metric-card" @click="fnToRouter('NeConfig_2146',{neType:'MF',treeName:'agents'})">
|
||||
<div class="card-title">{{ t('views.dashboard.overview.totalUser') }}</div>
|
||||
<div class="card-content">
|
||||
<div class="trend-chart">
|
||||
@@ -342,7 +341,7 @@ onBeforeUnmount(() => {
|
||||
</a-col>
|
||||
|
||||
<a-col :xs="24" :sm="24" :lg="8">
|
||||
<a-card :bordered="false" class="metric-card">
|
||||
<a-card :bordered="false" class="metric-card" @click="fnToRouter('NeConfig_2146',{neType:'MF',treeName:'agents'})">
|
||||
<div class="card-title">{{ t('views.dashboard.overview.onlineUser') }}</div>
|
||||
<div class="card-content">
|
||||
<div class="trend-chart">
|
||||
|
||||
@@ -13,6 +13,9 @@ import useConfigList from './hooks/useConfigList';
|
||||
import useConfigArray from './hooks/useConfigArray';
|
||||
import useConfigArrayChild from './hooks/useConfigArrayChild';
|
||||
import { getAllNeConfig, getNeConfigData } from '@/api/ne/neConfig';
|
||||
import { useRoute } from 'vue-router';
|
||||
const route = useRoute();
|
||||
|
||||
const neInfoStore = useNeInfoStore();
|
||||
const { t } = useI18n();
|
||||
const { ruleVerification, smfByUPFIdLoadData, smfByUPFIdOptions } = useOptions({
|
||||
@@ -76,6 +79,7 @@ function fnSelectConfigNode(_: any, info: any) {
|
||||
if (treeState.selectNode.paramName == key) {
|
||||
return;
|
||||
}
|
||||
|
||||
fnActiveConfigNode(key);
|
||||
}
|
||||
|
||||
@@ -168,15 +172,44 @@ function fnActiveConfigNode(key: string | number) {
|
||||
// 列表字段
|
||||
const columns: Record<string, any>[] = [];
|
||||
for (const rule of arrayState.dataRule.record) {
|
||||
columns.push({
|
||||
title: rule.display,
|
||||
dataIndex: rule.name,
|
||||
align: 'left',
|
||||
resizable: true,
|
||||
width: 150,
|
||||
minWidth: 100,
|
||||
maxWidth: 350,
|
||||
});
|
||||
if (rule.name === 'name') {
|
||||
columns.push({
|
||||
title: rule.display,
|
||||
dataIndex: rule.name,
|
||||
align: 'left',
|
||||
resizable: true,
|
||||
width: 150,
|
||||
minWidth: 100,
|
||||
maxWidth: 350,
|
||||
customFilterDropdown: true,
|
||||
onFilter: (value: any, record: any) => {
|
||||
const regex = new RegExp('^[0-9]{4,8}$');
|
||||
const name = record.name.value?.toString().trim() || '';
|
||||
const filterValue = value?.toString().trim();
|
||||
return regex.test(name) && name.includes(filterValue); // 正则匹配且模糊查询
|
||||
},
|
||||
onFilterDropdownOpenChange: (visible: any) => {
|
||||
if (visible) {
|
||||
setTimeout(() => {
|
||||
searchInput.value.focus();
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
columns.push({
|
||||
title: rule.display,
|
||||
dataIndex: rule.name,
|
||||
align: 'left',
|
||||
resizable: true,
|
||||
width: 150,
|
||||
minWidth: 100,
|
||||
maxWidth: 350,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
columns.push({
|
||||
title: t('common.operate'),
|
||||
@@ -203,7 +236,7 @@ function fnActiveConfigNode(key: string | number) {
|
||||
}
|
||||
|
||||
/**查询配置可选属性值列表 */
|
||||
function fnGetNeConfig() {
|
||||
function fnGetNeConfig(routeSelect?: string) {
|
||||
const neType = neTypeSelect.value[0];
|
||||
if (!neType) {
|
||||
message.warning({
|
||||
@@ -240,7 +273,8 @@ function fnGetNeConfig() {
|
||||
const item = JSON.parse(JSON.stringify(treeState.data[0]));
|
||||
treeState.selectNode = item;
|
||||
treeState.selectLoading = false;
|
||||
fnActiveConfigNode(item.key);
|
||||
// fnActiveConfigNode(((route.query.treeName as string)||item.key));
|
||||
fnActiveConfigNode(routeSelect || item.key);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -362,6 +396,25 @@ const {
|
||||
arrayEditClose,
|
||||
});
|
||||
|
||||
const state = reactive({
|
||||
searchText: '',
|
||||
searchedColumn: '',
|
||||
});
|
||||
|
||||
const searchInput = ref();
|
||||
|
||||
const handleSearch = (selectedKeys: any, confirm: any, dataIndex: any) => {
|
||||
confirm();
|
||||
state.searchText = selectedKeys[0];
|
||||
state.searchedColumn = dataIndex;
|
||||
};
|
||||
|
||||
const handleReset = (clearFilters: any) => {
|
||||
clearFilters({ confirm: true });
|
||||
state.searchText = '';
|
||||
};
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
// 获取网元网元列表
|
||||
neInfoStore.fnNelist().then(res => {
|
||||
@@ -381,7 +434,7 @@ onMounted(() => {
|
||||
return;
|
||||
}
|
||||
// 默认选择AMF
|
||||
const item = neCascaderOptions.value.find(s => s.value === 'AMF');
|
||||
const item = neCascaderOptions.value.find(s => s.value === ((route.query.neType as string) || 'MF'));
|
||||
if (item && item.children) {
|
||||
const info = item.children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
@@ -389,7 +442,7 @@ onMounted(() => {
|
||||
const info = neCascaderOptions.value[0].children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
}
|
||||
fnGetNeConfig();
|
||||
fnGetNeConfig((route.query.treeName as string));
|
||||
}
|
||||
} else {
|
||||
message.warning({
|
||||
@@ -404,13 +457,7 @@ onMounted(() => {
|
||||
<template>
|
||||
<PageContainer>
|
||||
<a-row :gutter="16">
|
||||
<a-col
|
||||
:lg="6"
|
||||
:md="6"
|
||||
:xs="24"
|
||||
style="margin-bottom: 24px"
|
||||
v-show="collapsible"
|
||||
>
|
||||
<a-col :lg="6" :md="6" :xs="24" style="margin-bottom: 24px" v-show="collapsible">
|
||||
<!-- 网元类型 -->
|
||||
<a-card size="small" :bordered="false" :loading="treeState.loading">
|
||||
<template #title>
|
||||
@@ -418,37 +465,22 @@ onMounted(() => {
|
||||
</template>
|
||||
<a-form layout="vertical" autocomplete="off">
|
||||
<a-form-item name="neId ">
|
||||
<a-cascader
|
||||
v-model:value="neTypeSelect"
|
||||
:options="neCascaderOptions"
|
||||
:allow-clear="false"
|
||||
@change="fnGetNeConfig"
|
||||
/>
|
||||
<a-cascader v-model:value="neTypeSelect" :options="neCascaderOptions" :allow-clear="false"
|
||||
@change="fnGetNeConfig()" />
|
||||
</a-form-item>
|
||||
<a-form-item name="treeStateData">
|
||||
<a-tree
|
||||
:tree-data="treeState.data"
|
||||
:selected-keys="[treeState.selectNode.paramName]"
|
||||
@select="fnSelectConfigNode"
|
||||
>
|
||||
<a-tree :tree-data="treeState.data" :selected-keys="[treeState.selectNode.paramName]"
|
||||
@select="fnSelectConfigNode">
|
||||
</a-tree>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :lg="collapsible ? 18 : 24" :md="collapsible ? 18 : 24" :xs="24">
|
||||
<a-card
|
||||
size="small"
|
||||
:bordered="false"
|
||||
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
|
||||
:loading="treeState.selectLoading"
|
||||
>
|
||||
<a-card size="small" :bordered="false" :body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
|
||||
:loading="treeState.selectLoading">
|
||||
<template #title>
|
||||
<a-button
|
||||
type="text"
|
||||
size="small"
|
||||
@click.prevent="changeCollapsible()"
|
||||
>
|
||||
<a-button type="text" size="small" @click.prevent="changeCollapsible()">
|
||||
<template #icon>
|
||||
<MenuFoldOutlined v-show="collapsible" />
|
||||
<MenuUnfoldOutlined v-show="!collapsible" />
|
||||
@@ -466,11 +498,7 @@ onMounted(() => {
|
||||
<a-space :size="8" align="center" v-show="!treeState.selectLoading">
|
||||
<a-tooltip placement="topRight">
|
||||
<template #title>{{ t('common.reloadText') }}</template>
|
||||
<a-button
|
||||
type="default"
|
||||
size="small"
|
||||
@click.prevent="fnActiveConfigNode('#')"
|
||||
>
|
||||
<a-button type="default" size="small" @click.prevent="fnActiveConfigNode('#')">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
@@ -480,17 +508,9 @@ onMounted(() => {
|
||||
</template>
|
||||
|
||||
<!-- 单列表格列表 -->
|
||||
<a-table
|
||||
v-if="treeState.selectNode.paramType === 'list'"
|
||||
class="table"
|
||||
row-key="name"
|
||||
:size="listState.size"
|
||||
:columns="listState.columns"
|
||||
:data-source="listState.data"
|
||||
:pagination="tablePagination"
|
||||
:bordered="true"
|
||||
:scroll="{ x: true, y: '500px' }"
|
||||
>
|
||||
<a-table v-if="treeState.selectNode.paramType === 'list'" class="table" row-key="name" :size="listState.size"
|
||||
:columns="listState.columns" :data-source="listState.data" :pagination="tablePagination" :bordered="true"
|
||||
:scroll="{ x: true, y: '500px' }">
|
||||
<template #bodyCell="{ column, text, record }">
|
||||
<template v-if="column.dataIndex === 'value'">
|
||||
<a-tooltip placement="topLeft">
|
||||
@@ -498,68 +518,30 @@ onMounted(() => {
|
||||
{{ record.comment }}
|
||||
</template>
|
||||
<div class="editable-cell">
|
||||
<div
|
||||
v-if="
|
||||
listState.editRecord['display'] === record['display']
|
||||
"
|
||||
class="editable-cell__input-wrapper"
|
||||
>
|
||||
<a-input-number
|
||||
v-if="record['type'] === 'int'"
|
||||
v-model:value="listState.editRecord['value']"
|
||||
:disabled="listState.confirmLoading"
|
||||
style="width: 100%"
|
||||
></a-input-number>
|
||||
<a-switch
|
||||
v-else-if="record['type'] === 'bool'"
|
||||
v-model:checked="listState.editRecord['value']"
|
||||
:checked-children="t('common.switch.open')"
|
||||
:un-checked-children="t('common.switch.shut')"
|
||||
:disabled="listState.confirmLoading"
|
||||
></a-switch>
|
||||
<a-select
|
||||
v-else-if="record['type'] === 'enum'"
|
||||
v-model:value="listState.editRecord['value']"
|
||||
:allow-clear="true"
|
||||
:disabled="listState.confirmLoading"
|
||||
style="width: 100%"
|
||||
>
|
||||
<a-select-option
|
||||
:value="+v"
|
||||
:key="+v"
|
||||
v-for="(k, v) in JSON.parse(record['filter'])"
|
||||
>
|
||||
<div v-if="
|
||||
listState.editRecord['display'] === record['display']
|
||||
" class="editable-cell__input-wrapper">
|
||||
<a-input-number v-if="record['type'] === 'int'" v-model:value="listState.editRecord['value']"
|
||||
:disabled="listState.confirmLoading" style="width: 100%"></a-input-number>
|
||||
<a-switch v-else-if="record['type'] === 'bool'" v-model:checked="listState.editRecord['value']"
|
||||
:checked-children="t('common.switch.open')" :un-checked-children="t('common.switch.shut')"
|
||||
:disabled="listState.confirmLoading"></a-switch>
|
||||
<a-select v-else-if="record['type'] === 'enum'" v-model:value="listState.editRecord['value']"
|
||||
:allow-clear="true" :disabled="listState.confirmLoading" style="width: 100%">
|
||||
<a-select-option :value="+v" :key="+v" v-for="(k, v) in JSON.parse(record['filter'])">
|
||||
{{ k }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-input
|
||||
v-else
|
||||
v-model:value="listState.editRecord['value']"
|
||||
:disabled="listState.confirmLoading"
|
||||
></a-input>
|
||||
<a-space
|
||||
:size="8"
|
||||
align="center"
|
||||
direction="horizontal"
|
||||
style="margin-left: 18px"
|
||||
>
|
||||
<a-input v-else v-model:value="listState.editRecord['value']"
|
||||
:disabled="listState.confirmLoading"></a-input>
|
||||
<a-space :size="8" align="center" direction="horizontal" style="margin-left: 18px">
|
||||
<a-tooltip placement="bottomRight">
|
||||
<template #title> {{ t('common.ok') }} </template>
|
||||
<a-popconfirm
|
||||
:title="
|
||||
t('views.ne.neConfig.editOkTip', {
|
||||
num: record['display'],
|
||||
})
|
||||
"
|
||||
placement="topRight"
|
||||
:disabled="listState.confirmLoading"
|
||||
@confirm="listEditOk()"
|
||||
>
|
||||
<a-button
|
||||
type="text"
|
||||
class="editable-cell__icon-edit"
|
||||
:disabled="listState.confirmLoading"
|
||||
>
|
||||
<a-popconfirm :title="t('views.ne.neConfig.editOkTip', {
|
||||
num: record['display'],
|
||||
})
|
||||
" placement="topRight" :disabled="listState.confirmLoading" @confirm="listEditOk()">
|
||||
<a-button type="text" class="editable-cell__icon-edit" :disabled="listState.confirmLoading">
|
||||
<template #icon>
|
||||
<CheckOutlined />
|
||||
</template>
|
||||
@@ -568,12 +550,8 @@ onMounted(() => {
|
||||
</a-tooltip>
|
||||
<a-tooltip placement="bottomRight">
|
||||
<template #title> {{ t('common.cancel') }} </template>
|
||||
<a-button
|
||||
type="text"
|
||||
class="editable-cell__icon-edit"
|
||||
:disabled="listState.confirmLoading"
|
||||
@click.prevent="listEditClose()"
|
||||
>
|
||||
<a-button type="text" class="editable-cell__icon-edit" :disabled="listState.confirmLoading"
|
||||
@click.prevent="listEditClose()">
|
||||
<template #icon>
|
||||
<CloseOutlined />
|
||||
</template>
|
||||
@@ -581,24 +559,16 @@ onMounted(() => {
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="editable-cell__text-wrapper"
|
||||
@dblclick="listEdit(record)"
|
||||
>
|
||||
<div v-else class="editable-cell__text-wrapper" @dblclick="listEdit(record)">
|
||||
<template v-if="record['type'] === 'enum'">
|
||||
{{ JSON.parse(record['filter'])[text] || ' ' }}
|
||||
</template>
|
||||
<template v-else>{{ `${text}` || ' ' }}</template>
|
||||
<EditOutlined
|
||||
class="editable-cell__icon"
|
||||
@click="listEdit(record)"
|
||||
style="margin-left: 18px"
|
||||
<EditOutlined class="editable-cell__icon" @click="listEdit(record)" style="margin-left: 18px"
|
||||
v-if="
|
||||
!listState.confirmLoading &&
|
||||
!['read-only', 'read', 'ro'].includes(record.access)
|
||||
"
|
||||
/>
|
||||
" />
|
||||
</div>
|
||||
</div>
|
||||
</a-tooltip>
|
||||
@@ -608,65 +578,77 @@ onMounted(() => {
|
||||
|
||||
<!-- array类型 -->
|
||||
<template v-else-if="treeState.selectNode.paramType === 'array'">
|
||||
<a-table
|
||||
class="table"
|
||||
row-key="index"
|
||||
:columns="treeState.selectNode.paramPerms.includes('get') ? arrayState.columnsDnd.filter((s:any)=>s.key !== 'index') : arrayState.columnsDnd"
|
||||
:data-source="arrayState.columnsData"
|
||||
:size="arrayState.size"
|
||||
:pagination="tablePagination"
|
||||
:bordered="true"
|
||||
:scroll="{ x: arrayState.columnsDnd.length * 200, y: 480 }"
|
||||
@resizeColumn="(w:number, col:any) => (col.width = w)"
|
||||
:show-expand-column="false"
|
||||
v-model:expanded-row-keys="arrayState.arrayChildExpandKeys"
|
||||
>
|
||||
<a-table class="table" row-key="index"
|
||||
:columns="treeState.selectNode.paramPerms.includes('get') ? arrayState.columnsDnd.filter((s: any) => s.key !== 'index') : arrayState.columnsDnd"
|
||||
:data-source="arrayState.columnsData" :size="arrayState.size" :pagination="tablePagination"
|
||||
:bordered="true" :scroll="{ x: arrayState.columnsDnd.length * 200, y: 480 }"
|
||||
@resizeColumn="(w: number, col: any) => (col.width = w)" :show-expand-column="false"
|
||||
v-model:expanded-row-keys="arrayState.arrayChildExpandKeys">
|
||||
<!-- 多列新增操作 -->
|
||||
<template #title>
|
||||
<a-space :size="16" align="center">
|
||||
<a-button
|
||||
type="primary"
|
||||
@click.prevent="arrayAdd()"
|
||||
size="small"
|
||||
v-if="treeState.selectNode.paramPerms.includes('post')"
|
||||
>
|
||||
<template #icon> <PlusOutlined /> </template>
|
||||
<a-button type="primary" @click.prevent="arrayAdd()" size="small"
|
||||
v-if="treeState.selectNode.paramPerms.includes('post')">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
{{ t('common.addText') }}
|
||||
</a-button>
|
||||
<TableColumnsDnd
|
||||
type="ghost"
|
||||
:cache-id="treeState.selectNode.key"
|
||||
:columns="treeState.selectNode.paramPerms.includes('get') ? [...arrayState.columns.filter((s:any)=>s.key !== 'index')] : arrayState.columns"
|
||||
v-model:columns-dnd="arrayState.columnsDnd"
|
||||
></TableColumnsDnd>
|
||||
<TableColumnsDnd type="ghost" :cache-id="treeState.selectNode.key"
|
||||
:columns="treeState.selectNode.paramPerms.includes('get') ? [...arrayState.columns.filter((s: any) => s.key !== 'index')] : arrayState.columns"
|
||||
v-model:columns-dnd="arrayState.columnsDnd"></TableColumnsDnd>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<template #customFilterDropdown="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }">
|
||||
<div style="padding: 8px">
|
||||
<a-input ref="searchInput" :placeholder="`Search ${column.dataIndex}`" :value="selectedKeys[0]"
|
||||
style="width: 188px; margin-bottom: 8px; display: block"
|
||||
@change="e => setSelectedKeys(e.target.value ? [e.target.value] : [])"
|
||||
@pressEnter="handleSearch(selectedKeys, confirm, column.dataIndex)" />
|
||||
<a-button type="primary" size="small" style="width: 90px; margin-right: 8px"
|
||||
@click="handleSearch(selectedKeys, confirm, column.dataIndex)">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
Search
|
||||
</a-button>
|
||||
<a-button size="small" style="width: 90px" @click="handleReset(clearFilters)">
|
||||
Reset
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #customFilterIcon="{ filtered }">
|
||||
<search-outlined :style="{ color: filtered ? '#108ee9' : undefined }" />
|
||||
</template>
|
||||
|
||||
<!-- 多列数据渲染 -->
|
||||
<template #bodyCell="{ column, text, record }">
|
||||
|
||||
<template v-if="column?.key === 'index'">
|
||||
<a-space :size="16" align="center">
|
||||
<a-tooltip
|
||||
v-if="treeState.selectNode.paramPerms.includes('put')"
|
||||
>
|
||||
<a-tooltip v-if="treeState.selectNode.paramPerms.includes('put')">
|
||||
<template #title>{{ t('common.editText') }}</template>
|
||||
<a-button type="link" @click.prevent="arrayEdit(text)">
|
||||
<template #icon><FormOutlined /></template>
|
||||
<template #icon>
|
||||
<FormOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
v-if="
|
||||
treeState.selectNode.paramPerms.includes('delete') &&
|
||||
!(
|
||||
neTypeSelect[0] === 'IMS' &&
|
||||
treeState.selectNode.paramName === 'plmn' &&
|
||||
text['value'] === 0
|
||||
)
|
||||
"
|
||||
>
|
||||
<a-tooltip v-if="
|
||||
treeState.selectNode.paramPerms.includes('delete') &&
|
||||
!(
|
||||
neTypeSelect[0] === 'IMS' &&
|
||||
treeState.selectNode.paramName === 'plmn' &&
|
||||
text['value'] === 0
|
||||
)
|
||||
">
|
||||
<template #title>{{ t('common.deleteText') }}</template>
|
||||
<a-button type="link" @click.prevent="arrayDelete(text)">
|
||||
<template #icon><DeleteOutlined /></template>
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
@@ -678,28 +660,24 @@ onMounted(() => {
|
||||
</template>
|
||||
<div class="editable-cell">
|
||||
<template v-if="text.array">
|
||||
<a-button
|
||||
type="default"
|
||||
size="small"
|
||||
@click.prevent="
|
||||
arrayChildExpand(record['index'], text)
|
||||
"
|
||||
>
|
||||
<template #icon><BarsOutlined /></template>
|
||||
<a-button type="default" size="small" @click.prevent="
|
||||
arrayChildExpand(record['index'], text)
|
||||
">
|
||||
<template #icon>
|
||||
<BarsOutlined />
|
||||
</template>
|
||||
{{ t('views.ne.neConfig.arrayMore') }}
|
||||
</a-button>
|
||||
<!--特殊字段拓展显示-->
|
||||
<span
|
||||
v-if="
|
||||
text.name === 'dnnList' && Array.isArray(text.value)
|
||||
"
|
||||
>
|
||||
<span v-if="
|
||||
text.name === 'dnnList' && Array.isArray(text.value)
|
||||
">
|
||||
({{
|
||||
text.value.length > 4
|
||||
? `${text.value
|
||||
.slice(0, 3)
|
||||
.map((s: any) => s.dnn)
|
||||
.join()}...${text.value.length}`
|
||||
.slice(0, 3)
|
||||
.map((s: any) => s.dnn)
|
||||
.join()}...${text.value.length}`
|
||||
: text.value.map((s: any) => s.dnn).join()
|
||||
}})
|
||||
</span>
|
||||
@@ -720,37 +698,23 @@ onMounted(() => {
|
||||
|
||||
<!-- 多列嵌套类型 -->
|
||||
<template #expandedRowRender>
|
||||
<a-table
|
||||
class="table"
|
||||
row-key="index"
|
||||
:columns="arrayChildState.columnsDnd"
|
||||
:data-source="arrayChildState.columnsData"
|
||||
:size="arrayChildState.size"
|
||||
:pagination="tablePagination"
|
||||
:bordered="true"
|
||||
:scroll="{
|
||||
<a-table class="table" row-key="index" :columns="arrayChildState.columnsDnd"
|
||||
:data-source="arrayChildState.columnsData" :size="arrayChildState.size" :pagination="tablePagination"
|
||||
:bordered="true" :scroll="{
|
||||
x: arrayChildState.columnsDnd.length * 200,
|
||||
y: 200,
|
||||
}"
|
||||
@resizeColumn="(w:number, col:any) => (col.width = w)"
|
||||
>
|
||||
}" @resizeColumn="(w: number, col: any) => (col.width = w)">
|
||||
<template #title>
|
||||
<a-space :size="16" align="center">
|
||||
<a-button
|
||||
type="primary"
|
||||
@click.prevent="arrayChildAdd"
|
||||
size="small"
|
||||
>
|
||||
<template #icon> <PlusOutlined /> </template>
|
||||
<a-button type="primary" @click.prevent="arrayChildAdd" size="small">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
{{ t('common.addText') }} {{ arrayChildState.title }}
|
||||
</a-button>
|
||||
<TableColumnsDnd
|
||||
type="ghost"
|
||||
:cache-id="`${treeState.selectNode.key}:${arrayChildState.loc}`"
|
||||
:columns="[...arrayChildState.columns]"
|
||||
v-model:columns-dnd="arrayChildState.columnsDnd"
|
||||
v-if="arrayChildState.loc"
|
||||
></TableColumnsDnd>
|
||||
<TableColumnsDnd type="ghost" :cache-id="`${treeState.selectNode.key}:${arrayChildState.loc}`"
|
||||
:columns="[...arrayChildState.columns]" v-model:columns-dnd="arrayChildState.columnsDnd"
|
||||
v-if="arrayChildState.loc"></TableColumnsDnd>
|
||||
</a-space>
|
||||
</template>
|
||||
<template #bodyCell="{ column, text, record }">
|
||||
@@ -758,22 +722,20 @@ onMounted(() => {
|
||||
<a-space :size="8" align="center">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.editText') }}</template>
|
||||
<a-button
|
||||
type="link"
|
||||
@click.prevent="arrayChildEdit(text)"
|
||||
>
|
||||
<template #icon><FormOutlined /></template>
|
||||
<a-button type="link" @click.prevent="arrayChildEdit(text)">
|
||||
<template #icon>
|
||||
<FormOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip>
|
||||
<template #title>
|
||||
{{ t('common.deleteText') }}
|
||||
</template>
|
||||
<a-button
|
||||
type="link"
|
||||
@click.prevent="arrayChildDelete(text)"
|
||||
>
|
||||
<template #icon><DeleteOutlined /></template>
|
||||
<a-button type="link" @click.prevent="arrayChildDelete(text)">
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
@@ -786,7 +748,9 @@ onMounted(() => {
|
||||
<div class="editable-cell">
|
||||
<template v-if="text.array">
|
||||
<a-button type="default" size="small">
|
||||
<template #icon><BarsOutlined /></template>
|
||||
<template #icon>
|
||||
<BarsOutlined />
|
||||
</template>
|
||||
{{ t('views.ne.neConfig.arrayMore') }}
|
||||
</a-button>
|
||||
</template>
|
||||
@@ -816,97 +780,46 @@ onMounted(() => {
|
||||
</a-row>
|
||||
|
||||
<!-- 新增框或修改框 -->
|
||||
<ProModal
|
||||
:drag="true"
|
||||
:width="800"
|
||||
:destroyOnClose="true"
|
||||
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
|
||||
:keyboard="false"
|
||||
:mask-closable="false"
|
||||
:open="modalState.open"
|
||||
:title="modalState.title"
|
||||
:confirm-loading="modalState.confirmLoading"
|
||||
@ok="fnModalOk"
|
||||
@cancel="fnModalCancel"
|
||||
>
|
||||
<a-form
|
||||
class="form"
|
||||
layout="horizontal"
|
||||
autocomplete="off"
|
||||
:validate-on-rule-change="false"
|
||||
:validateTrigger="[]"
|
||||
:label-col="{ span: 6 }"
|
||||
:labelWrap="true"
|
||||
>
|
||||
<a-form-item
|
||||
v-for="item in modalState.data"
|
||||
:label="item.display"
|
||||
:name="item.name"
|
||||
:required="item.optional === 'false'"
|
||||
style="margin-bottom: 4px"
|
||||
>
|
||||
<ProModal :drag="true" :width="800" :destroyOnClose="true"
|
||||
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }" :keyboard="false" :mask-closable="false"
|
||||
:open="modalState.open" :title="modalState.title" :confirm-loading="modalState.confirmLoading" @ok="fnModalOk"
|
||||
@cancel="fnModalCancel">
|
||||
<a-form class="form" layout="horizontal" autocomplete="off" :validate-on-rule-change="false" :validateTrigger="[]"
|
||||
:label-col="{ span: 6 }" :labelWrap="true">
|
||||
<a-form-item v-for="item in modalState.data" :label="item.display" :name="item.name"
|
||||
:required="item.optional === 'false'" style="margin-bottom: 4px">
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title v-if="item.comment">
|
||||
{{ item.comment }}
|
||||
</template>
|
||||
|
||||
<div>
|
||||
<div
|
||||
v-if="
|
||||
!Array.isArray(item.array) &&
|
||||
modalState.from[item.name] !== undefined
|
||||
"
|
||||
>
|
||||
<div v-if="
|
||||
!Array.isArray(item.array) &&
|
||||
modalState.from[item.name] !== undefined
|
||||
">
|
||||
<!-- 特殊SMF-upfid选择 -->
|
||||
<a-select
|
||||
v-if="
|
||||
neTypeSelect[0] === 'SMF' &&
|
||||
modalState.from[item.name]['name'] === 'upfId'
|
||||
"
|
||||
v-model:value="modalState.from[item.name]['value']"
|
||||
:options="smfByUPFIdOptions"
|
||||
:disabled="['read-only', 'read', 'ro'].includes(item.access)"
|
||||
:token-separators="[',', ';']"
|
||||
mode="multiple"
|
||||
:max-tag-count="5"
|
||||
:allow-clear="true"
|
||||
style="width: 100%"
|
||||
>
|
||||
<a-select v-if="
|
||||
neTypeSelect[0] === 'SMF' &&
|
||||
modalState.from[item.name]['name'] === 'upfId'
|
||||
" v-model:value="modalState.from[item.name]['value']" :options="smfByUPFIdOptions"
|
||||
:disabled="['read-only', 'read', 'ro'].includes(item.access)" :token-separators="[',', ';']"
|
||||
mode="multiple" :max-tag-count="5" :allow-clear="true" style="width: 100%">
|
||||
</a-select>
|
||||
<!-- 常规 -->
|
||||
<a-input-number
|
||||
v-else-if="item['type'] === 'int'"
|
||||
v-model:value="modalState.from[item.name]['value']"
|
||||
:disabled="['read-only', 'read', 'ro'].includes(item.access)"
|
||||
style="width: 100%"
|
||||
></a-input-number>
|
||||
<a-switch
|
||||
v-else-if="item['type'] === 'bool'"
|
||||
v-model:checked="modalState.from[item.name]['value']"
|
||||
:checked-children="t('common.switch.open')"
|
||||
:un-checked-children="t('common.switch.shut')"
|
||||
:disabled="['read-only', 'read', 'ro'].includes(item.access)"
|
||||
></a-switch>
|
||||
<a-select
|
||||
v-else-if="item['type'] === 'enum'"
|
||||
v-model:value="modalState.from[item.name]['value']"
|
||||
:disabled="['read-only', 'read', 'ro'].includes(item.access)"
|
||||
:allow-clear="true"
|
||||
style="width: 100%"
|
||||
>
|
||||
<a-select-option
|
||||
:value="+v"
|
||||
:key="+v"
|
||||
v-for="(k, v) in JSON.parse(item['filter'])"
|
||||
>
|
||||
<a-input-number v-else-if="item['type'] === 'int'" v-model:value="modalState.from[item.name]['value']"
|
||||
:disabled="['read-only', 'read', 'ro'].includes(item.access)" style="width: 100%"></a-input-number>
|
||||
<a-switch v-else-if="item['type'] === 'bool'" v-model:checked="modalState.from[item.name]['value']"
|
||||
:checked-children="t('common.switch.open')" :un-checked-children="t('common.switch.shut')"
|
||||
:disabled="['read-only', 'read', 'ro'].includes(item.access)"></a-switch>
|
||||
<a-select v-else-if="item['type'] === 'enum'" v-model:value="modalState.from[item.name]['value']"
|
||||
:disabled="['read-only', 'read', 'ro'].includes(item.access)" :allow-clear="true" style="width: 100%">
|
||||
<a-select-option :value="+v" :key="+v" v-for="(k, v) in JSON.parse(item['filter'])">
|
||||
{{ k }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-input
|
||||
v-else
|
||||
v-model:value="modalState.from[item.name]['value']"
|
||||
:disabled="['read-only', 'read', 'ro'].includes(item.access)"
|
||||
></a-input>
|
||||
<a-input v-else v-model:value="modalState.from[item.name]['value']"
|
||||
:disabled="['read-only', 'read', 'ro'].includes(item.access)"></a-input>
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ `${item.value || ' '}` }}
|
||||
@@ -925,19 +838,24 @@ onMounted(() => {
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&__icon:hover {
|
||||
color: var(--ant-primary-color);
|
||||
}
|
||||
|
||||
&__icon-edit:hover {
|
||||
color: var(--ant-primary-color);
|
||||
}
|
||||
|
||||
&__text-wrapper {
|
||||
font-size: 16px;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
&__text-wrapper:hover &__icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&__input-wrapper {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
|
||||
Reference in New Issue
Block a user