Browse Source

fix: 配置中心

jcq 2 weeks ago
parent
commit
6781ade6c6

+ 3 - 0
src/i18n/pages/form/zh-cn.ts

@@ -1,3 +1,5 @@
+import { save } from "/@/api/admin/menu";
+
 // 定义通用内容
 export default {
 	common: {
@@ -14,6 +16,7 @@ export default {
 		queryDeptTip: '请输入部门名称',
 		resetBtn: '重置',
 		action: '操作',
+		saveBtn: '保 存',
 		optSuccessText: '操作成功',
 		editSuccessText: '修改成功',
 		addSuccessText: '添加成功',

+ 0 - 152
src/views/marketing/config/components/ipEdit.vue

@@ -1,152 +0,0 @@
-<template>
-  <el-dialog :title="sign === 'domain' ? '修改域名集合' : '修改ip集合'" width="600" v-model="visible"
-             :close-on-click-modal="false" :destroy-on-close="true" draggable>
-    <el-form ref="menuDialogFormRef" :model="state.ruleForm" 
-      label-width="90px" v-loading="loading">
-      <el-form-item :label="sign === 'domain' ? '域名集合' : 'ip集合'" prop="configs">
-        <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 style="width: 300px; margin-right: 20px;" 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>
-        </div>
-      </el-form-item>
-    </el-form>
-    <template #footer>
-			<span class="dialog-footer">
-				<el-button @click="visible = false">{{ t('common.cancelButtonText') }}</el-button>
-				<el-button type="primary" @click="onSubmit" :disabled="loading">{{ t('common.confirmButtonText') }}</el-button>
-			</span>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup name="systemMenuDialog">
-import {useI18n} from 'vue-i18n';
-import {info, getAppList, save} from '/@/api/marketing/config';
-import {useMessage} from '/@/hooks/message';
-import {rule} from '/@/utils/validate';
-
-// 定义子组件向父组件传值/事件
-const emit = defineEmits(['refresh']);
-const { t } = useI18n();
-
-// 定义变量内容
-const visible = ref(false);
-const loading = ref(false);
-const sign = ref('domain')
-const menuDialogFormRef = ref();
-// 定义需要的数据
-const state = reactive({
-  ruleForm: {
-    list: [''], 
-    https: [''], // 域名集合
-    ips: [''], // ip集合
-      // {
-      //   id: '1',
-      //   ip: '美国',
-      //   appId: '1',
-      //   appUrl: 'www.baidu.com',
-      //   appName: 'adsa'
-      // },
-  },
-  appList: [], // 应用下拉框列表
-});
-
-// // 表单校验规则
-// const dataRules = reactive({
-//   domain: [
-//     {required: true, message: '域名不能为空', trigger: 'blur'},
-//     // { validator: rule.url, trigger: 'blur' }
-//   ],
-// });
-
-// 分页参数
-const pagination = reactive({
-  current: 1,
-  size: 10,
-  total: 0
-})
-
-// 打开弹窗
-const openDialog = async (type, row, str = 'domain') => {
-  visible.value = true;
-  sign.value = str;
-  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();
-};
-
-// 获取当条配置信息
-const getConfigDetail = (id) => {
-  info(id).then((res) => {
-    Object.assign(state.ruleForm, res.data);
-  });
-};
-
-// 保存数据
-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);
-  delete state.ruleForm.list;
-  try {
-    loading.value = true;
-    await save(state.ruleForm);
-    useMessage().success(t(state.ruleForm.id ? 'common.editSuccessText' : 'common.addSuccessText'));
-    visible.value = false;
-    emit('refresh');
-  } catch (err) {
-    useMessage().error(err.msg);
-  } finally {
-    loading.value = false;
-  }
-};
-
-// 暴露变量 只有暴漏出来的变量 父组件才能使用
-defineExpose({
-  openDialog,
-});
-</script>
-<style>
-.apps-loadmore.el-select-dropdown .el-scrollbar__wrap {
-  height: 330px !important;
-}
-</style>

+ 86 - 0
src/views/marketing/config/components/ipGroupingEdit.vue

@@ -0,0 +1,86 @@
+<template>
+	<el-dialog
+		:title="type == 'ip'? '添加IP分组':'添加域名分组'"
+		width="600"
+		v-model="props.open"
+		:close-on-click-modal="false"
+		:destroy-on-close="true"
+		@close="onCancel"
+		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>
+		</el-form>
+		<template #footer>
+			<span class="dialog-footer">
+				<el-button @click="onCancel">{{ t('common.cancelButtonText') }}</el-button>
+				<el-button type="primary" @click="onSubmit" :disabled="loading">{{ t('common.confirmButtonText') }}</el-button>
+			</span>
+		</template>
+	</el-dialog>
+</template>
+
+<script setup name="systemMenuDialog">
+import { useI18n } from 'vue-i18n';
+import { info, getAppList, save } from '/@/api/marketing/config';
+import { useMessage } from '/@/hooks/message';
+
+// 定义子组件向父组件传值/事件
+const emit = defineEmits(['update:open', 'onsuccess']);
+const { t } = useI18n();
+
+// 定义变量内容
+const loading = ref(false);
+const menuDialogFormRef = ref();
+
+// 定义需要的数据
+const state = reactive({
+	ruleForm: {
+		listType: '1', // 1: 白名单, 2: 黑名单
+		list: [''],
+		https: [''], // 域名集合
+		ips: [''], // ip集合
+	},
+	appList: [], // 应用下拉框列表
+});
+
+const props = defineProps({
+	open: {
+		type: Boolean,
+		default: false,
+	},
+	type: {
+		type: String,
+		default: 'ip', // 'ip' or 'domain'
+	},
+});
+// // 表单校验规则
+const dataRules = reactive({
+	grouping: [{ required: true, message: '分组名称不能为空', trigger: 'blur' }],
+});
+const onCancel = () => {
+	emit('update:open', false);
+};
+// 保存数据
+const onSubmit = async () => {
+	try {
+		loading.value = true;
+		// await save(state.ruleForm);
+		useMessage().success(t(state.ruleForm.id ? 'common.editSuccessText' : 'common.addSuccessText'));
+		emit('onsuccess');
+		onCancel();
+	} catch (err) {
+		useMessage().error(err.msg);
+	} finally {
+		loading.value = false;
+	}
+};
+</script>
+<style>
+.apps-loadmore.el-select-dropdown .el-scrollbar__wrap {
+	height: 330px !important;
+}
+</style>

+ 136 - 107
src/views/marketing/config/components/ipListEdit.vue

@@ -1,152 +1,181 @@
 <template>
-  <el-dialog :title="sign === 'domain' ? '修改域名集合' : '修改ip集合'" width="600" v-model="visible"
-             :close-on-click-modal="false" :destroy-on-close="true" draggable>
-    <el-form ref="menuDialogFormRef" :model="state.ruleForm" 
-      label-width="90px" v-loading="loading">
-      <el-form-item :label="sign === 'domain' ? '域名集合' : 'ip集合'" prop="configs">
-        <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 style="width: 300px; margin-right: 20px;" 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>
-        </div>
-      </el-form-item>
-    </el-form>
-    <template #footer>
+	<el-dialog
+		:title="sign === 'domain' ? '修改域名集合' : '修改ip集合'"
+		width="600"
+		v-model="visible"
+		:close-on-click-modal="false"
+		:destroy-on-close="true"
+		draggable
+	>
+		<el-form ref="menuDialogFormRef" :model="state.ruleForm" label-width="90px" v-loading="loading">
+			<el-form-item :label="sign === 'domain' ? '域名集合' : 'ip集合'" prop="configs">
+				<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 style="width: 300px; margin-right: 20px" 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>
+				</div>
+			</el-form-item>
+		</el-form>
+		<template #footer>
 			<span class="dialog-footer">
 				<el-button @click="visible = false">{{ t('common.cancelButtonText') }}</el-button>
 				<el-button type="primary" @click="onSubmit" :disabled="loading">{{ t('common.confirmButtonText') }}</el-button>
 			</span>
-    </template>
-  </el-dialog>
+		</template>
+	</el-dialog>
 </template>
 
 <script setup name="systemMenuDialog">
-import {useI18n} from 'vue-i18n';
-import {info, getAppList, save} from '/@/api/marketing/config';
-import {useMessage} from '/@/hooks/message';
-import {rule} from '/@/utils/validate';
+import { useI18n } from 'vue-i18n';
+import { info, getAppList, save } from '/@/api/marketing/config';
+import { useMessage } from '/@/hooks/message';
+import { rule } from '/@/utils/validate';
 
 // 定义子组件向父组件传值/事件
-const emit = defineEmits(['refresh']);
+const emit = defineEmits(['onsuccess']);
 const { t } = useI18n();
 
 // 定义变量内容
 const visible = ref(false);
 const loading = ref(false);
-const sign = ref('domain')
+const sign = ref('domain');
 const menuDialogFormRef = ref();
 // 定义需要的数据
 const state = reactive({
-  ruleForm: {
-    list: [''], 
-    https: [''], // 域名集合
-    ips: [''], // ip集合
-      // {
-      //   id: '1',
-      //   ip: '美国',
-      //   appId: '1',
-      //   appUrl: 'www.baidu.com',
-      //   appName: 'adsa'
-      // },
-  },
-  appList: [], // 应用下拉框列表
+	ruleForm: {
+		list: [{
+            val:'192.168.0.32',
+        }],
+		https: [''], // 域名集合
+		ips: [''], // ip集合
+		// {
+		//   id: '1',
+		//   ip: '美国',
+		//   appId: '1',
+		//   appUrl: 'www.baidu.com',
+		//   appName: 'adsa'
+		// },
+	},
+	appList: [], // 应用下拉框列表
 });
 
 // // 表单校验规则
-// const dataRules = reactive({
-//   domain: [
-//     {required: true, message: '域名不能为空', trigger: 'blur'},
-//     // { validator: rule.url, trigger: 'blur' }
-//   ],
-// });
+const dataRules = reactive({
+  domain: [
+    {required: true, message: sign.value == 'domain' ? '域名':'ip'+'不能为空', trigger: 'blur'},
+    { validator: sign.value == 'domain'?rule.domain : rule.ip, trigger: 'blur' }
+  ],
+});
 
 // 分页参数
 const pagination = reactive({
-  current: 1,
-  size: 10,
-  total: 0
-})
+	current: 1,
+	size: 10,
+	total: 0,
+});
 
 // 打开弹窗
 const openDialog = async (type, row, str = 'domain') => {
-  visible.value = true;
-  sign.value = str;
-  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();
+	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();
 };
 
 // 获取当条配置信息
 const getConfigDetail = (id) => {
-  info(id).then((res) => {
-    Object.assign(state.ruleForm, res.data);
-  });
+	info(id).then((res) => {
+		Object.assign(state.ruleForm, res.data);
+	});
 };
 
 // 保存数据
 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);
-  delete state.ruleForm.list;
-  try {
-    loading.value = true;
-    await save(state.ruleForm);
-    useMessage().success(t(state.ruleForm.id ? 'common.editSuccessText' : 'common.addSuccessText'));
-    visible.value = false;
-    emit('refresh');
-  } catch (err) {
-    useMessage().error(err.msg);
-  } finally {
-    loading.value = false;
-  }
+	// 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));
+	// delete state.ruleForm.list;
+	try {
+		loading.value = true;
+		// await save(state.ruleForm);
+		useMessage().success(t(state.ruleForm.id ? 'common.editSuccessText' : 'common.addSuccessText'));
+		visible.value = false;
+		emit('onsuccess');
+	} catch (err) {
+		useMessage().error(err.msg);
+	} finally {
+		loading.value = false;
+	}
 };
 
 // 暴露变量 只有暴漏出来的变量 父组件才能使用
 defineExpose({
-  openDialog,
+	openDialog,
 });
 </script>
 <style>
 .apps-loadmore.el-select-dropdown .el-scrollbar__wrap {
-  height: 330px !important;
+	height: 330px !important;
 }
 </style>

+ 11 - 0
src/views/marketing/config/i18n/zh-cn.ts

@@ -24,5 +24,16 @@ export default {
 		domainTip: '请输入域名',
 		groupingTip: '请选择分组名称',
 		ipTip: '请输入IP',
+		groupingName: '分组名称',
+		groupingNameTip: '请输入分组名称',
+		triggerType: '触发类型',
+		triggerTypeTip: '请选择触发类型',
+		jumpMode: '触发方式',
+		jumpModeTip: '请选择触发方式',
+		jumpLink: '跳转链接',
+		jumpLinkTip: '请输入跳转链接',
+		triggerFrequency: '触发频率',
+		triggerFrequencyTip: '请输入触发频率',
+
 	},
 };

+ 111 - 15
src/views/marketing/config/index.vue

@@ -2,11 +2,11 @@
 	<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">
-				<Title :title="t('marketingConfig.ipList')" />
+				<Title class="ml-4" :title="t('marketingConfig.ipList')" />
 				<div class="p-4 rounded">
-					<el-button type="primary" @click="onAddClick">{{ t('marketingConfig.addIpList') }}</el-button>
+					<el-button type="primary" @click="onClickAdd('ip')">{{ t('marketingConfig.addIpList') }}</el-button>
 					<JCollapse
-						@update="(item) => console.log(item)"
+						@update="(item) =>  onClickEdit(item,'ip')"
 						@delete="(item) => console.log(item)"
 						:data="data"
 						:deleteText="t('marketingConfig.deleteListText')"
@@ -15,11 +15,11 @@
 				</div>
 			</el-tab-pane>
 			<el-tab-pane :label="t('marketingConfig.domainList')" name="second" class="layout-padding-auto layout-padding-view">
-				<Title class="" :title="t('marketingConfig.domainList')" />
+				<Title class="ml-4" :title="t('marketingConfig.domainList')" />
 				<div class="p-4 rounded">
-					<el-button type="primary" @click="onAddClick">{{ t('marketingConfig.addDomainList') }}</el-button>
+					<el-button type="primary" @click="onClickAdd('domain')">{{ t('marketingConfig.addDomainList') }}</el-button>
 					<JCollapse
-						@update="(item) => console.log(item)"
+						@update="(item) => onClickEdit(item,'domain')"
 						:data="data"
 						@delete="(item) => console.log(item)"
 						:deleteText="t('marketingConfig.deleteListText')"
@@ -28,12 +28,12 @@
 				</div>
 			</el-tab-pane>
 			<el-tab-pane :label="t('marketingConfig.disposition')" name="third" class="layout-padding-auto layout-padding-view">
-				<Title class="" :title="t('marketingConfig.disposition')" />
+				<Title class="ml-4" :title="t('marketingConfig.disposition')" />
 				<div class="p-4 rounded">
 					<JCollapse
-						:data="[{title: 'IP集合',id: '1',}]"
-						@update="(item) => listEditOpen = true"
-						@delete="(item) => closeIpTags = !closeIpTags"
+						:data="[{ title: 'IP集合', id: '1' }]"
+						@update="(item) => (listEditOpen = true)"
+						@delete="(item) => (closeIpTags = !closeIpTags)"
 						:deleteText="t('marketingConfig.deleteText')"
 						:updateText="t('marketingConfig.updateText')"
 					>
@@ -72,31 +72,64 @@
 					</JCollapse>
 
 					<JCollapse
-					    class="mt-4"
+						class="mt-4"
 						:data="[
 							{
 								title: '域名集合',
 								id: '1',
 							},
 						]"
-						@update="(item) => domainEditOpen = true"
-						@delete="(item) => closeDomainTags = !closeDomainTags"
+						@update="(item) => (domainEditOpen = true)"
+						@delete="(item) => (closeDomainTags = !closeDomainTags)"
 						:deleteText="closeTags ? t('marketingConfig.cancel') : t('marketingConfig.deleteDomain')"
 						:updateText="t('marketingConfig.addDomain')"
 					>
 						<template #default>
 							<div class="border-b p-2 items-center flex flex-wrap">
-								<el-tag v-for="item in whiteList" :key="item" effect="light" :closable="closeDomainTags" color="#f4f4f4" round class="ml-1 cursor-pointer">
+								<el-tag
+									v-for="item in whiteList"
+									:key="item"
+									effect="light"
+									:closable="closeDomainTags"
+									color="#f4f4f4"
+									round
+									class="ml-1 cursor-pointer"
+								>
 									{{ item.label }}
 								</el-tag>
 							</div>
 						</template>
 					</JCollapse>
 				</div>
+				<div class="w-[66%] ml-4">
+					<el-form ref="menuDialogFormRef" :model="formData" :rule="dataRules" label-width="90px" class="flex flex-wrap">
+						<el-form-item :label="t('marketingConfig.jumpMode')" prop="jumpMode" class="w-1/3">
+							<el-select v-model="formData.jumpMode" :placeholder="t('marketingConfig.jumpModeTip')" clearable>
+								<el-option v-for="item in listSelect" :key="item.value" :label="item.label" :value="item.value" />
+							</el-select>
+						</el-form-item>
+						<el-form-item :label="t('marketingConfig.triggerType')" prop="triggerType" class="w-1/3">
+							<el-select v-model="formData.triggerType" :placeholder="t('marketingConfig.triggerTypeTip')" clearable>
+								<el-option v-for="item in triggerSelect" :key="item.value" :label="item.label" :value="item.value" />
+							</el-select>
+						</el-form-item>
+						<el-form-item :label="t('marketingConfig.triggerFrequency')" prop="triggerFrequency" class="w-1/3">
+							<el-input v-model="formData.triggerFrequency" type="text" :placeholder="t('marketingConfig.triggerFrequencyTip')"></el-input>
+						</el-form-item>
+						<el-form-item :label="t('marketingConfig.jumpLink')" prop="jumpLink" class="w-1/3">
+							<el-input v-model="formData.jumpLink" type="text" :placeholder="t('marketingConfig.jumpLinkTip')"></el-input>
+						</el-form-item>
+						<div class="w-full">
+							<el-button type="primary" @click="onSubmit" class="w-[80px]">{{ t('common.saveBtn') }}</el-button>
+						</div>
+					</el-form>
+				</div>
 			</el-tab-pane>
 		</el-tabs>
 		<DomainEdit v-model:open="domainEditOpen" />
 		<ListEdit v-model:open="listEditOpen" />
+		<GroupingEdit v-model:open="groupingEditOpen" :type="openType" />
+		<IpListEdit :type="openType"  ref="menuDialogRef"/>
 	</div>
 </template>
 
@@ -104,19 +137,69 @@
 import { delObj, pageList, update } from '/@/api/marketing/config';
 import { BasicTableProps, useTable } from '/@/hooks/table';
 import { useI18n } from 'vue-i18n';
+import { useMessage } from '/@/hooks/message';
+import {rule} from '/@/utils/validate';
+
 
 // 引入组件
 const JCollapse = defineAsyncComponent(() => import('/@/components/JCollapse/index.vue'));
 const Title = defineAsyncComponent(() => import('/@/components/Title/index.vue'));
 const DomainEdit = defineAsyncComponent(() => import('./components/domainEdit.vue'));
 const ListEdit = defineAsyncComponent(() => import('./components/listEdit.vue'));
+const GroupingEdit = defineAsyncComponent(() => import('./components/ipGroupingEdit.vue'));
+const IpListEdit = defineAsyncComponent(() => import('./components/ipListEdit.vue'));
 const { t } = useI18n();
 // 定义变量内容
 const activeName = ref('first');
+//关闭或打开tabs的关闭按钮
 const closeDomainTags = ref(false);
 const closeIpTags = ref(false);
+
+// 弹窗
 const domainEditOpen = ref(false);
 const listEditOpen = ref(false);
+const groupingEditOpen = ref(false);
+const ipListEditOpen = ref(false);
+
+const listSelect = ref([
+	{
+		value: 'group1',
+		label: '跳转链接',
+	},
+	{
+		value: 'group2',
+		label: '提示信息',
+	},
+	{
+		value: 'group3',
+		label: '提示并跳转',
+	},
+]);
+const triggerSelect = ref([
+	{
+		value: 'group1',
+		label: '仅一次跳转',
+	},
+	{
+		value: 'group2',
+		label: '多次跳转',
+	},
+]);
+
+const menuDialogFormRef = ref();
+const formData = ref({
+	jumpMode: '',
+	triggerType: '',
+	jumpLink: '',
+	triggerFrequency:''
+});
+
+// // 表单校验规则
+const dataRules = reactive({
+	jumpLink: [{ validator: rule.url, trigger: 'blur' }],
+});
+
+const openType = ref('ip'); // 'ip' or 'domain'
 const data = ref([
 	{
 		title: '分组1',
@@ -138,11 +221,24 @@ const whiteList = ref([{ label: '站大' }, { label: '站而' }, { label: '站
 
 const menuDialogRef = ref();
 const state: BasicTableProps = reactive<BasicTableProps>({
-	pageList: pageList, // H
+	// pageList: pageList, // H
 	queryForm: {
 		domain: '',
 	},
 });
+const onSubmit = () => {
+	useMessage().success(t(formData.value ? 'common.editSuccessText' : 'common.addSuccessText'));
+};
+
+const onClickAdd = (type: string) => {
+	openType.value = type;
+	groupingEditOpen.value = true;
+};
+const onClickEdit = (item: any,type: string) => {
+	openType.value = type;
+	// ipListEditOpen.value = true;
+	onOpenEditMenu(type,item)
+};
 
 const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);