Преглед на файлове

Merge branch 'dev-jcq' into dev-ly

jcq преди 2 седмици
родител
ревизия
9fcecf2d30

+ 17 - 4
src/api/marketing/config.ts

@@ -9,7 +9,7 @@ export const pageListDomain = () => {
 };
 export const pageListIp = (params?: Object) => {
 	return request({
-		url: '/admin/marketing/config/getDomainGroup',
+		url: '/marketing/config/getIpGroup',
 		// url: 'https://m1.apifoxmock.com/m1/6687089-6396408-default/marketing/config/page',
 		method: 'get',
 		params,
@@ -30,9 +30,9 @@ export const info = (id: String) => {
 	});
 };
 
-export const save = (data: Object) => {
+export const saveDomains = (data: Object) => {
 	return request({
-		url: '/admin/marketing/config/save',
+		url: '/marketing/config/modDomainGroup',
 		method: 'post',
 		data: data,
 	});
@@ -45,7 +45,20 @@ export const delObj = (ids: Array<String>) => {
 		data: ids
 	});
 };
-
+export const delGroup = (data: object) => {
+	return request({
+		url: '/marketing/config/delGroup',
+		method: 'post',
+		data: data
+	});
+};
+export const addGroup = (data: object) => {
+	return request({
+		url: '/marketing/config/addGroup',
+		method: 'post',
+		data: data
+	});
+};
 export const getAppList = (params?: Object) => {
 	return request({
 		url: '/admin/marketing/config/apps',

+ 15 - 0
src/utils/ipUpdate.ts

@@ -0,0 +1,15 @@
+// src/utils/ipUpdate.ts
+
+const ipSplicing = (startIp: string, endIp: string | null | undefined): string => {
+  if (!endIp || endIp.trim() === '') {
+    return startIp;
+  }
+
+  const startParts = startIp.split('.');
+  const endParts = endIp.split('.');
+  const lastPartOfEndIp = endParts[endParts.length - 1];
+
+  return `${startIp}/${lastPartOfEndIp}`;
+};
+
+export { ipSplicing };

+ 1 - 1
src/views/marketing/config/components/domainEdit.vue

@@ -30,7 +30,7 @@
 
 <script setup name="systemMenuDialog">
 import { useI18n } from 'vue-i18n';
-import { info, getAppList, save } from '/@/api/marketing/config';
+import { info, getAppList } from '/@/api/marketing/config';
 import { useMessage } from '/@/hooks/message';
 
 // 定义子组件向父组件传值/事件

+ 10 - 11
src/views/marketing/config/components/ipGroupingEdit.vue

@@ -9,8 +9,8 @@
 		draggable
 	>
 		<el-form ref="menuDialogFormRef" :rules="dataRules" :model="state.ruleForm" v-loading="loading">
-			<el-form-item :label="t('marketingConfig.groupingName')" prop="grouping" >
-				<el-input v-model="state.ruleForm.grouping" type="text" :placeholder="t('marketingConfig.groupingNameTip')"></el-input>
+			<el-form-item :label="t('marketingConfig.groupingName')" prop="groupName" >
+				<el-input v-model="state.ruleForm.groupName" type="text" :placeholder="t('marketingConfig.groupingNameTip')"></el-input>
 			</el-form-item>
 		</el-form>
 		<template #footer>
@@ -24,7 +24,7 @@
 
 <script setup name="systemMenuDialog">
 import { useI18n } from 'vue-i18n';
-import { info, getAppList, save } from '/@/api/marketing/config';
+import { addGroup } from '/@/api/marketing/config';
 import { useMessage } from '/@/hooks/message';
 
 // 定义子组件向父组件传值/事件
@@ -38,12 +38,8 @@ const menuDialogFormRef = ref();
 // 定义需要的数据
 const state = reactive({
 	ruleForm: {
-		listType: '1', // 1: 白名单, 2: 黑名单
-		list: [''],
-		https: [''], // 域名集合
-		ips: [''], // ip集合
+		groupName:''
 	},
-	appList: [], // 应用下拉框列表
 });
 
 const props = defineProps({
@@ -58,7 +54,7 @@ const props = defineProps({
 });
 // // 表单校验规则
 const dataRules = reactive({
-	grouping: [{ required: true, message: '分组名称不能为空', trigger: 'blur' }],
+	groupName: [{ required: true, message: '分组名称不能为空', trigger: 'blur' }],
 });
 const onCancel = () => {
 	emit('update:open', false);
@@ -67,8 +63,11 @@ const onCancel = () => {
 const onSubmit = async () => {
 	try {
 		loading.value = true;
-		// await save(state.ruleForm);
-		useMessage().success(t(state.ruleForm.id ? 'common.editSuccessText' : 'common.addSuccessText'));
+		await addGroup({
+			...state.ruleForm,
+			groupType: state.type === 'ip' ? 1 : 2,
+		});
+		useMessage().success(t('common.addSuccessText'));
 		emit('onsuccess');
 		onCancel();
 	} catch (err) {

+ 99 - 116
src/views/marketing/config/components/ipListEdit.vue

@@ -7,58 +7,63 @@
 		:destroy-on-close="true"
 		draggable
 	>
-		<el-form ref="menuDialogFormRef" :model="state.ruleForm" label-width="90px" v-loading="loading">
-            <el-form-item label="名称" prop="name">
-				<el-input class="!w-[300px]" v-model="state.ruleForm.name" placeholder="请输入名称"></el-input>
+		<el-form ref="menuDialogFormRef" :model="state.ruleForm" :rules="dataRules" label-width="90px" v-loading="loading">
+			<el-form-item label="名称" prop="groupName">
+				<el-input class="!w-[300px]" v-model="state.ruleForm.groupName" placeholder="请输入名称"></el-input>
 			</el-form-item>
-			<el-form-item  prop="configs">
+			<el-form-item
+				v-for="(item, index) in state.ruleForm.list"
+				:key="item.id || item.val"
+				:prop="'list.' + index + '.val'"
+				:rules="dataRules.configs"
+			>
 				<template #label>
-					<div class="flex items-center">
-                        <el-tooltip effect="light" content="输入127.0.0.1/24格式代表网段" placement="top">
-						<el-icon><Warning /> </el-icon>
-					</el-tooltip>
-                    {{sign === 'domain' ? '域名集合' : 'ip集合'  }}
-                    </div>
-				</template>
-				<div v-for="(item, index) in state.ruleForm.list" :key="item.index" class="flex items-center mb-2 text-sm font-normal justify-start w-full">
-					<el-input class="!w-[300px] mr-10" v-model="item.val" clearable :placeholder="t('marketingConfig.inputIPTip')"></el-input>
-					<div class="config-actions w-[50px] flex items-center justify-between">
-						<svg
-							v-if="index === state.ruleForm.list.length - 1"
-							@click="state.ruleForm.list.push({ val: '' })"
-							style="cursor: pointer"
-							width="24"
-							height="24"
-							viewBox="0 0 24 24"
-							fill="none"
-							xmlns="http://www.w3.org/2000/svg"
-						>
-							<path
-								d="M19.5 3H4.5C3.67157 3 3 3.67157 3 4.5V19.5C3 20.3284 3.67157 21 4.5 21H19.5C20.3284 21 21 20.3284 21 19.5V4.5C21 3.67157 20.3284 3 19.5 3Z"
-								stroke="#646464"
-								stroke-linejoin="round"
-							/>
-							<path d="M12 8V16" stroke="#646464" stroke-linecap="round" stroke-linejoin="round" />
-							<path d="M8 12H16" stroke="#646464" stroke-linecap="round" stroke-linejoin="round" />
-						</svg>
-						<svg
-							v-if="state.ruleForm.list.length > 1"
-							style="cursor: pointer"
-							@click="state.ruleForm.list.splice(index, 1)"
-							width="24"
-							height="24"
-							viewBox="0 0 24 24"
-							fill="none"
-							xmlns="http://www.w3.org/2000/svg"
-						>
-							<path
-								d="M19.5 3H4.5C3.67157 3 3 3.67157 3 4.5V19.5C3 20.3284 3.67157 21 4.5 21H19.5C20.3284 21 21 20.3284 21 19.5V4.5C21 3.67157 20.3284 3 19.5 3Z"
-								stroke="#646464"
-								stroke-linejoin="round"
-							/>
-							<path d="M8 12H16" stroke="#646464" stroke-linecap="round" stroke-linejoin="round" />
-						</svg>
+					<div v-if="index === 0" class="flex items-center">
+						<el-tooltip v-if="sign === 'ip'" effect="light" content="输入127.0.0.1/24格式代表网段" placement="top">
+							<el-icon><Warning /> </el-icon>
+						</el-tooltip>
+						{{ sign === 'domain' ? '域名集合' : 'ip集合' }}
 					</div>
+				</template>
+				<!-- <div v-for="(item, index) in state.ruleForm.list" :key="item.index" class="flex items-center mb-2 text-sm font-normal justify-start w-full"> -->
+				<el-input class="!w-[300px] mr-10" v-model="item.val" clearable @blur="item.modify = true" :placeholder="inputTip"></el-input>
+				<div class="config-actions w-[50px] flex items-center justify-between">
+					<svg
+						v-if="index === state.ruleForm.list.length - 1"
+						@click="onAddItem"
+						style="cursor: pointer"
+						width="24"
+						height="24"
+						viewBox="0 0 24 24"
+						fill="none"
+						xmlns="http://www.w3.org/2000/svg"
+					>
+						<path
+							d="M19.5 3H4.5C3.67157 3 3 3.67157 3 4.5V19.5C3 20.3284 3.67157 21 4.5 21H19.5C20.3284 21 21 20.3284 21 19.5V4.5C21 3.67157 20.3284 3 19.5 3Z"
+							stroke="#646464"
+							stroke-linejoin="round"
+						/>
+						<path d="M12 8V16" stroke="#646464" stroke-linecap="round" stroke-linejoin="round" />
+						<path d="M8 12H16" stroke="#646464" stroke-linecap="round" stroke-linejoin="round" />
+					</svg>
+					<svg
+						v-if="state.ruleForm.list.length > 1"
+						style="cursor: pointer"
+						@click="onClickDelete(item, index)"
+						width="24"
+						height="24"
+						viewBox="0 0 24 24"
+						fill="none"
+						xmlns="http://www.w3.org/2000/svg"
+					>
+						<path
+							d="M19.5 3H4.5C3.67157 3 3 3.67157 3 4.5V19.5C3 20.3284 3.67157 21 4.5 21H19.5C20.3284 21 21 20.3284 21 19.5V4.5C21 3.67157 20.3284 3 19.5 3Z"
+							stroke="#646464"
+							stroke-linejoin="round"
+						/>
+						<path d="M8 12H16" stroke="#646464" stroke-linecap="round" stroke-linejoin="round" />
+					</svg>
+					<!-- </div> -->
 				</div>
 			</el-form-item>
 		</el-form>
@@ -73,7 +78,7 @@
 
 <script setup name="systemMenuDialog">
 import { useI18n } from 'vue-i18n';
-import { info, getAppList, save } from '/@/api/marketing/config';
+import { saveDomains } from '/@/api/marketing/config';
 import { useMessage } from '/@/hooks/message';
 import { rule } from '/@/utils/validate';
 
@@ -81,6 +86,8 @@ import { rule } from '/@/utils/validate';
 const emit = defineEmits(['onsuccess']);
 const { t } = useI18n();
 
+
+const inputTip = computed(() => t('marketingConfig.inputIPTip'));
 // 定义变量内容
 const visible = ref(false);
 const loading = ref(false);
@@ -89,89 +96,65 @@ const menuDialogFormRef = ref();
 // 定义需要的数据
 const state = reactive({
 	ruleForm: {
-		list: [
-			{
-				val: '192.168.0.32',
-			},
-		],
-		https: [''], // 域名集合
-		ips: [''], // ip集合
-		// {
-		//   id: '1',
-		//   ip: '美国',
-		//   appId: '1',
-		//   appUrl: 'www.baidu.com',
-		//   appName: 'adsa'
-		// },
+		list: [],
+		delList: [], //删除的ip或者域名的id
 	},
 	appList: [], // 应用下拉框列表
 });
 
+//删除的id存入delList中
+const onClickDelete = (item, index) => {
+	if (item.id) {
+		state.ruleForm.delList.push(item.id);
+	}
+	state.ruleForm.list.splice(index, 1);
+};
+const onAddItem = () => {
+	state.ruleForm.list.push({ val: '' });
+};
+
 // // 表单校验规则
-const dataRules = reactive({
-	domain: [
-		{ required: true, message: sign.value == 'domain' ? '域名' : 'ip' + '不能为空', trigger: 'blur' },
-		{ validator: sign.value == 'domain' ? rule.domain : rule.ip, trigger: 'blur' },
+const dataRules = computed(() => ({
+	configs: [
+		{ required: false, message: `${sign.value === 'domain' ? '域名' : 'IP'}不能为空`, trigger: 'blur' },
+		{ validator: sign.value === 'domain' ? rule.url : rule.ip, trigger: 'blur' },
 	],
-});
-
-// 分页参数
-const pagination = reactive({
-	current: 1,
-	size: 10,
-	total: 0,
-});
+}));
 
 // 打开弹窗
-const openDialog = async (type, row, str = 'domain') => {
+const openDialog = async (type, row) => {
 	visible.value = true;
 	sign.value = type;
-	nextTick(() => {
-		menuDialogFormRef.value?.resetFields();
-	});
-	// state.ruleForm = JSON.parse(JSON.stringify(row));
-	// str === 'domain' ? (state.ruleForm.list = row.https.map((e) => ({ val: e }))) : (state.ruleForm.list = row.ips.map((e) => ({ val: e })));
-	// if (row?.id && type === 'edit') {
-	//   await getConfigDetail(row.id);
-	// } else {
-	//   state.ruleForm = {
-	//     id: null,
-	//     domain: '',
-	//     configs: [
-	//       {
-	//         id: '',
-	//         ip: '',
-	//         appId: '',
-	//         appUrl: '',
-	//         appName: ''
-	//       }
-	//     ],
-	//   };
-	// }
-	// pagination.current = 1;
-	// // 获取应用列表
-	// getAllAppData();
+	resetForm();
+	console.log();
+	row = JSON.parse(JSON.stringify(row || {}));
+	state.ruleForm = {
+		...row,
+		list: row.list.length > 0 ? row.list.map((e) => ({ ...e, val: e.value, modify: false })) : [{ val: '' }],
+		delList: [],
+	};
 };
-
-// 获取当条配置信息
-const getConfigDetail = (id) => {
-	info(id).then((res) => {
-		Object.assign(state.ruleForm, res.data);
-	});
+const resetForm = () => {
+	menuDialogFormRef.value?.resetFields();
+	state.ruleForm.delList = [];
 };
 
 // 保存数据
 const onSubmit = async () => {
-	// const valid = await menuDialogFormRef.value.validate().catch(() => {
-	// });
-	// if (!valid) return false;
-	// sign.value === 'domain'
-	// 	? (state.ruleForm.https = state.ruleForm.list.map((e) => e.val))
-	// 	: (state.ruleForm.ips = state.ruleForm.list.map((e) => e.val));
+	const valid = await menuDialogFormRef.value.validate().catch(() => {});
+	if (!valid) return false;
+	console.log(state.ruleForm);
+
+	sign.value === 'domain'
+		? (state.ruleForm.domains = state.ruleForm.list.map((item) => {
+				return { ...item, domain: item.val };
+		  }))
+		: (state.ruleForm.ips = state.ruleForm.list.map((e) => e.val));
 	// delete state.ruleForm.list;
+	// return;
 	try {
 		loading.value = true;
-		// await save(state.ruleForm);
+		await saveDomains(state.ruleForm);
 		useMessage().success(t(state.ruleForm.id ? 'common.editSuccessText' : 'common.addSuccessText'));
 		visible.value = false;
 		emit('onsuccess');
@@ -187,7 +170,7 @@ defineExpose({
 	openDialog,
 });
 </script>
-<style>
+<style scoped>
 .apps-loadmore.el-select-dropdown .el-scrollbar__wrap {
 	height: 330px !important;
 }

+ 1 - 1
src/views/marketing/config/components/listEdit.vue

@@ -36,7 +36,7 @@
 
 <script setup name="systemMenuDialog">
 import { useI18n } from 'vue-i18n';
-import { info, getAppList, save } from '/@/api/marketing/config';
+import { info, getAppList } from '/@/api/marketing/config';
 import { useMessage } from '/@/hooks/message';
 
 // 定义子组件向父组件传值/事件

+ 109 - 35
src/views/marketing/config/index.vue

@@ -1,34 +1,35 @@
 <template>
 	<div class="layout-padding">
 		<el-tabs v-model="activeName" type="card" class="demo-tabs" @tab-click="handleClick">
-			<el-tab-pane :label="t('marketingConfig.ipList')" name="first" class="layout-padding-auto layout-padding-view">
+			<el-tab-pane :label="t('marketingConfig.ipList')" name="IP分组" class="layout-padding-auto layout-padding-view">
 				<Title class="ml-4" :title="t('marketingConfig.ipList')" />
 				<div class="p-4 rounded">
 					<el-button type="primary" @click="onClickAdd('ip')">{{ t('marketingConfig.addIpList') }}</el-button>
 					<JCollapse
 						@update="(item) => onClickEdit(item, 'ip')"
-						@delete="(item) => console.log(item)"
-						:data="data"
-						:activeNames="['1', '2', '3']"
+						@delete="(item) => onOpenDelete(item, 'ip')"
+						:data="ipData"
+						:activeNames="ipActiveId"
 						:deleteText="t('marketingConfig.deleteListText')"
 						:updateText="t('marketingConfig.updateText')"
 					/>
 				</div>
 			</el-tab-pane>
-			<el-tab-pane :label="t('marketingConfig.domainList')" name="second" class="layout-padding-auto layout-padding-view">
+			<el-tab-pane :label="t('marketingConfig.domainList')" name="域名分组" class="layout-padding-auto layout-padding-view">
 				<Title class="ml-4" :title="t('marketingConfig.domainList')" />
 				<div class="p-4 rounded">
 					<el-button type="primary" @click="onClickAdd('domain')">{{ t('marketingConfig.addDomainList') }}</el-button>
 					<JCollapse
 						@update="(item) => onClickEdit(item, 'domain')"
 						:data="domainData"
-						@delete="(item) => console.log(item)"
+						@delete="(item) => onOpenDelete(item, 'domain')"
+						:activeNames="domainActiveId"
 						:deleteText="t('marketingConfig.deleteListText')"
 						:updateText="t('marketingConfig.updateText')"
 					/>
 				</div>
 			</el-tab-pane>
-			<el-tab-pane :label="t('marketingConfig.disposition')" name="third" class="layout-padding-auto layout-padding-view">
+			<el-tab-pane :label="t('marketingConfig.disposition')" name="全局配置" class="layout-padding-auto layout-padding-view">
 				<Title class="ml-4" :title="t('marketingConfig.disposition')" />
 				<div class="p-4 rounded">
 					<JCollapse
@@ -150,17 +151,25 @@
 		<DomainEdit v-model:open="domainEditOpen" />
 		<ListEdit v-model:open="listEditOpen" />
 		<GroupingEdit v-model:open="groupingEditOpen" :type="openType" />
-		<IpListEdit :type="openType" ref="menuDialogRef" />
+		<IpListEdit :type="openType" ref="menuDialogRef" @onsuccess="getDomainData" />
+		<el-dialog v-model="delOpen" title="提示" width="500" @close="delOpen = false">
+			<span>确认删除{{ delObj?.title }} 分组吗?</span>
+			<template #footer>
+				<div class="dialog-footer">
+					<el-button @click="delOpen = false">取消</el-button>
+					<el-button type="primary" :disabled="loading" @click="onDel(delObj)"> 确定 </el-button>
+				</div>
+			</template>
+		</el-dialog>
 	</div>
 </template>
 
 <script lang="ts" name="marketingConfig" setup>
-import { delObj, pageListDomain, update } from '/@/api/marketing/config';
-import { BasicTableProps, useTable } from '/@/hooks/table';
+import { delGroup, pageListDomain, pageListIp } from '/@/api/marketing/config';
 import { useI18n } from 'vue-i18n';
 import { useMessage } from '/@/hooks/message';
 import { rule } from '/@/utils/validate';
-import { identity } from '@vueuse/core';
+import { ipSplicing } from '/@/utils/ipUpdate';
 
 // 引入组件
 const JCollapse = defineAsyncComponent(() => import('/@/components/JCollapse/index.vue'));
@@ -171,7 +180,7 @@ const GroupingEdit = defineAsyncComponent(() => import('./components/ipGroupingE
 const IpListEdit = defineAsyncComponent(() => import('./components/ipListEdit.vue'));
 const { t } = useI18n();
 // 定义变量内容
-const activeName = ref('first');
+const activeName = ref('IP分组');
 //关闭或打开tabs的关闭按钮
 const closeDomainTags = ref(false);
 const closeIpTags = ref(false);
@@ -180,8 +189,20 @@ const closeIpTags = ref(false);
 const domainEditOpen = ref(false);
 const listEditOpen = ref(false);
 const groupingEditOpen = ref(false);
+const delOpen = ref(false);
+const loading = ref(false);
+const menuDialogRef = ref();
+
+
+const domainActiveId = ref([]);
+const ipActiveId = ref([]);
+
+
 // const ipListEditOpen = ref(false);
 const domainData = ref([]);
+const ipData = ref([]);
+const delObj = ref({});
+const openType = ref('ip'); // 'ip' or 'domain'
 
 const listSelect = ref([
 	{
@@ -199,11 +220,11 @@ const listSelect = ref([
 ]);
 const triggerSelect = ref([
 	{
-		value: 'group1',
+		value: '1',
 		label: '仅一次跳转',
 	},
 	{
-		value: 'group2',
+		value: '2',
 		label: '多次跳转',
 	},
 ]);
@@ -216,13 +237,20 @@ const formData = ref({
 	triggerFrequency: '',
 	prompt: '',
 });
+const onOpenDelete = (item: any, type: any) => {
+	console.log(item);
+
+	delObj.value = { ...item, type };
+	console.log(delObj.value);
+
+	delOpen.value = true;
+};
 
 // // 表单校验规则
 const dataRules = reactive({
 	jumpLink: [{ validator: rule.url, trigger: 'blur' }],
 });
 
-const openType = ref('ip'); // 'ip' or 'domain'
 const data = ref([
 	{
 		title: '分组1',
@@ -242,18 +270,40 @@ const data = ref([
 ]);
 const whiteList = ref([{ label: '站大' }, { label: '站而' }, { label: '站撒' }, { label: '站爱' }]);
 
-const menuDialogRef = ref();
-const state = reactive({
-	pageListDomain: pageListDomain(),
-});
-state.pageListDomain;
-
 const onSubmit = () => {
 	useMessage().success(t(formData.value ? 'common.editSuccessText' : 'common.addSuccessText'));
 };
+const handleClick = (data:any) => { 
+	if(data.props.label === 'IP分组'){
+		getIpData();
+	}else if(data.props.label === '域名分组'){
+		getDomainData();
+	}else{
+
+	}
+	
+};
+const onDel = async (data:any) => {
+	try {
+		loading.value = true;
+		await delGroup({
+			ids: [data.id],
+			groupType: data.type === 'ip' ? 1 : 2,
+		});
+		useMessage().success(t('common.delSuccessText'));
+	} catch (err: any) {
+		useMessage().error(err.msg);
+	} finally {
+		loading.value = false;
+		delOpen.value = false;
+		data.type === 'ip' ? getIpData() : getDomainData();
+	}
+};
 
 const onClickAdd = (type: string) => {
 	openType.value = type;
+	console.log(type);
+	
 	groupingEditOpen.value = true;
 };
 const onClickEdit = (item: any, type: string) => {
@@ -266,27 +316,51 @@ const onClickEdit = (item: any, type: string) => {
 const onOpenEditMenu = (type: string, row: any) => {
 	menuDialogRef.value.openDialog(type, row);
 };
-
-onMounted(() => {
-	// 获取域名列表
-	state.pageListDomain.then((val) => {
-		domainData.value = val.data.map((item :any) => {
-			console.log(item);
+const getDomainData = async () => {
+	await pageListDomain().then((val) => {
+		domainActiveId.value = [];
+		domainData.value = val.data.map((item: any) => {
+			domainActiveId.value.push(item.id);
 			return {
+				...item,
 				title: item.groupName,
-				list: item.domains.map((items :any) => {
-					return{
-						id:items.id,
-						value:items.domain
-					}
+				id: item.id,
+				list: item.domains.map((items: any) => {
+					return {
+						...items,
+						id: items.id,
+						value: items.domain,
+					};
 				}),
 			};
 		});
-	console.log(domainData.value);
-
 	});
-	
+};
+const getIpData = async () => {
+	await pageListIp().then((val) => {
+		ipActiveId.value = [];
+		ipData.value = val.data.map((item: any) => {
+			ipActiveId.value.push(item.id);
+			return {
+				...item,
+				title: item.groupName,
+				id: item.id,
+				list: item.ips.map((items: any) => {
+					return {
+						...items,
+						id: items.id,
+						value: ipSplicing(items.startIp,items.endIp),
+					};
+				}),
+			};
+		});
+	});
+};
+
+onMounted(() => {
 	//获取IP列表
+	getIpData();
+
 });
 </script>
 <style  lang="scss">