Browse Source

Merge branch 'dev-cmn' into dev-ly

cmy 1 week ago
parent
commit
de978012de

+ 2 - 2
src/utils/ipUpdate.ts

@@ -20,8 +20,8 @@
   const endLastOctet = parseInt(numberStr, 10); // 100
 
   return {
-    start: startIp,
-    end: `${prefix}.${endLastOctet}`,
+    start: `${prefix}.${Math.min(startLastOctet, endLastOctet)}`,
+    end: `${prefix}.${Math.max(startLastOctet, endLastOctet)}`,
   };
 };
 //将ip分开由end和start组成

+ 12 - 11
src/views/marketing/apps/components/domainCell.vue

@@ -4,7 +4,7 @@
       <span class="item" v-for="item in list" :key="item">{{item}}</span>
     </div>
     <div class="action" :style="{ textAlign: list.length > 0 ? 'left' : 'center'}">
-      <el-link type="info" @click="handleEdit" style="color: #167AF0; line-height: 18px;">
+      <el-link type="info" class="btn-more" :class="{disabled: !state}" :disabled="!state" @click="handleEdit" >
         {{ list.length > 0 ? '查看详情' : '添加域名'}}
       </el-link>
     </div>
@@ -15,7 +15,7 @@
 import { ref, watch } from 'vue';
 const DomainForm = defineAsyncComponent(() => import('./domainForm.vue'));
 
-const props = defineProps(['domainList', 'rowData']);
+const props = defineProps(['domainList', 'rowData', 'state']);
 const emit = defineEmits(['refresh']);
 const list = ref([]);
 const DomainFormRef = ref();
@@ -48,6 +48,8 @@ const handleUpdate = () => {
 }
 </script>
 <style scoped lang="scss">
+@import '/@/theme/mixins/index.scss';
+
 .cell {
   padding: 10px 0;
   .item {
@@ -61,16 +63,15 @@ const handleUpdate = () => {
   .action {
     width: 100%;
   }
-
   .ellipsis {
-    display: -webkit-box;          /* 使用弹性盒子布局 */
-    -webkit-box-orient: vertical;  /* 垂直方向排列 */
-    -webkit-line-clamp: 2;         /* 限制显示的行数 */
-    overflow: hidden;              /* 隐藏超出部分 */
-    text-overflow: ellipsis;       /* 超出时显示省略号 */
-    word-break: break-word;        /* 允许单词断行(可选) */
-
-    
+    @include text-ellipsis(2);
+  }
+  .btn-more {
+    color: #167AF0;
+    line-height: 18px;
+    &.disabled {
+      opacity: 0.68;
+    }
   }
 }
 </style>

+ 30 - 34
src/views/marketing/apps/components/domainCollapse.vue

@@ -7,18 +7,18 @@
       <div class="p-2 items-center flex flex-wrap">
         <template v-for="item in domains" >
           <!-- 具体域名 -->
-            <el-tag v-if="item.sourceType == 2" @click="getDomainList(item)" effect="light" :closable="domainDeletable"
+            <el-tag v-if="item.sourceType == 2" effect="light" :closable="domainDeletable"
             @close="handleDeleteDomain(item, 'domain')" color="#f4f4f4" round class="ml-1 cursor-pointer"
             style="margin-bottom: 4px;">
               <span class="ellipsis">{{ item.domain }}</span>
           </el-tag>
           <!-- 分组域名 -->
-          <el-popover v-else width="200" trigger="hover" placement="top">
+          <el-popover v-else width="200" trigger="hover" placement="top" @show="onLoadDetail(item)">
             <div class="flex flex-wrap">
               {{ item.domains && item.domains.length ? item.domains.map(i=>i.domain).join(',') : '暂无数据' }}
             </div>
             <template #reference>
-              <el-tag @click="getDomainList(item)" effect="light" :closable="domainDeletable"
+              <el-tag effect="light" :closable="domainDeletable"
                 @close="handleDeleteDomain(item, 'group')" color="#f4f4f4" round class="ml-1 cursor-pointer"
                 style="margin-bottom: 4px;">
                 <span class="ellipsis">{{ item.groupName }}</span>
@@ -36,19 +36,23 @@
 </template>
 
 <script setup lang="ts" name="domainCollapse">
-import { useI18n } from 'vue-i18n';
-import { useMessage } from '/@/hooks/message';
 const JCollapse = defineAsyncComponent(() => import('/@/components/JCollapse/index.vue'));
 const DomainEdit = defineAsyncComponent(() => import('./domainEdit.vue'));
+import { useI18n } from 'vue-i18n';
+import { useMessage } from '/@/hooks/message';
+import { getGroupDetail } from '/@/api/marketing/config';
 
 interface DomianItem {
-  id?: String;
-  domain: String;
-  sourceType: Number; // 1:分组 2:具体域名
-  groupId: String;
-  groupName: String;
+  id?: string;
+  domain: string;
+  sourceType: number; // 1:分组 2:具体域名
+  groupId: string;
+  groupName: string;
   modify: boolean; // 是否被修改/新增
-  domains: string[];
+  domains: {
+    domain: string;
+    id: string;
+  }[];
 }
 
 const props = defineProps(['data']);
@@ -60,7 +64,7 @@ const { t } = useI18n();
 // 定义变量内容
 const domainDeletable = ref(false);// 控制域名列表项是否可删除
 const domainEditOpen = ref(false);
-const delDomains = ref<String[]>([]);
+const delDomains = ref<string[]>([]);
 const domains = ref<DomianItem[]>([]);
 
 watch(() => props.data, (newVal = []) => {
@@ -79,21 +83,11 @@ watch(delDomains, (newVal) => {
   emit('delDomains', newVal);
 }, { deep: true, immediate: true });
 
-const getDomainList = (detail: DomianItem) => {
-  if (detail.sourceType == 1) {
-    // 获取ip组
-    console.log(detail.groupId);
-  }
-}
-
 // 删除域名
 const handleDeleteDomain = (deleteItem: DomianItem, type: 'group' | 'domain') => {
-  console.log(deleteItem)
-  console.log('domains.value', domains.value);
-  
   domains.value = domains.value.filter(i=>{
-    if(!i.modify && i.id == deleteItem.id && !delDomains.value.includes(i.id)) {
-      delDomains.value = [...delDomains.value, i.id];
+    if(!i.modify && i.id == deleteItem.id && !delDomains.value.includes(i.id as string)) {
+      delDomains.value = [...delDomains.value, i.id as string];
     }
     if(type == 'group') {
       return i.groupId != deleteItem.groupId
@@ -106,15 +100,14 @@ const handleDeleteDomain = (deleteItem: DomianItem, type: 'group' | 'domain') =>
 // 分组去重
 function addGroupsUnique(newGroups: DomianItem[]) {
   const existIds = new Set([
-    // ...domains.value.map(item => item.id),
     ...domains.value.map(item => item.groupId),
   ]);
-  const filtered = newGroups.filter(item => !existIds.has(item.id))
+  const filtered:DomianItem[] = newGroups.filter(item => !existIds.has(item.id as string))
     .map(item=>{
       return {
         "sourceType": 1,
         "modify": true,
-        "groupId": item.id,
+        "groupId": item.id?.toString() || '',
         "groupName": item.groupName,
         "domains": item.domains,
         "domain": "",
@@ -162,18 +155,21 @@ const addDomain = (data: DomianItem[], type: 'group' | 'domain') => {
   }
 }
 
+const onLoadDetail = async (item: any) => {
+	if (item?.domains && item?.domains?.length !== 0) return;
+	await getGroupDetail({ id: item.groupId }).then((val) => {
+		item.domains = val.data.domains
+	});
+};
+
 </script>
 <style lang="scss">
+@import '/@/theme/mixins/index.scss';
+
 .el-collapse-item__content {
   padding: 0;
 }
 .ellipsis {
-  max-width: 780px;
-  display: -webkit-box;          /* 使用弹性盒子布局 */
-  -webkit-box-orient: vertical;  /* 垂直方向排列 */
-  -webkit-line-clamp: 1;         /* 限制显示的行数 */
-  overflow: hidden;              /* 隐藏超出部分 */
-  text-overflow: ellipsis;       /* 超出时显示省略号 */
-  word-break: break-word;        /* 允许单词断行(可选) */
+  @include text-ellipsis(1);
 }
 </style>

+ 4 - 4
src/views/marketing/apps/components/domainEdit.vue

@@ -43,9 +43,9 @@ const emit = defineEmits(['update:open', 'onsuccess']);
 const { t } = useI18n();
 
 interface DomainItem {
-	domains: String[];
-	groupName: String;
-	id: String;
+	domains: string[];
+	groupName: string;
+	id: string;
 }
 
 // 定义变量内容
@@ -59,7 +59,7 @@ const selectedObjects = ref<DomainItem[]>([]);
 // 定义需要的数据
 const state = reactive({
 	ruleForm: {
-		selectedIds: [] as String[], // 选中域名分组
+		selectedIds: [] as string[], // 选中域名分组
 		domain: [],
 	},
 });

+ 15 - 13
src/views/marketing/apps/components/domainForm.vue

@@ -23,11 +23,11 @@ import { updateModDomains } from '/@/api/marketing/apps';
 const DomainCollapse = defineAsyncComponent(() => import('./domainCollapse.vue'));
 
 interface DomianItem {
-  id: String;
-  domain: String;
-  sourceType: Number; // 1:分组 2:具体域名
-  groupId: String;
-  groupName: String;
+  id: string;
+  domain: string;
+  sourceType: number; // 1:分组 2:具体域名
+  groupId: string;
+  groupName: string;
 }
 
 // 定义子组件向父组件传值/事件
@@ -39,7 +39,7 @@ const visible = ref(false);
 const loading = ref(false);
 const domains = ref<DomianItem[]>([]);
 const childDomains = ref();
-const delDomains = ref<String[]>([]);
+const delDomains = ref<string[]>([]);
 const rowData = ref();
 
 // 打开弹窗
@@ -54,19 +54,21 @@ const openDialog = async (data: any, row) => {
 const updateDomains = (data: DomianItem[])=>{
   childDomains.value = data;
 }
-const updateDelDomains = (data: String[]) => {
+const updateDelDomains = (data: string[]) => {
   delDomains.value = data;
 }
 
 // 保存数据
 const onSubmit = async () => {
-  ElMessage.success('提交成功!');
-  visible.value = false;
-  console.log(childDomains.value);
-  console.log(delDomains.value);
-  updateModDomains({ domains: childDomains.value, delDomains: delDomains.value, id: rowData.value.id}).then((res) => {
+  try {
+    updateModDomains({ domains: childDomains.value, delDomains: delDomains.value, id: rowData.value.id})
     emit('refresh');
-  })
+    ElMessage.success('提交成功!');
+    visible.value = false;
+  } catch (error) {
+    ElMessage.error('提交失败!');
+    console.error(error);
+  }
 };
 
 // 暴露变量 只有暴漏出来的变量 父组件才能使用

+ 35 - 35
src/views/marketing/apps/components/form.vue

@@ -59,48 +59,48 @@
 </template>
 
 <script setup lang="ts" name="systemMenuDialog">
+const DomainCollapse = defineAsyncComponent(() => import('./domainCollapse.vue'));
+const IpCollapse = defineAsyncComponent(() => import('./ipCollapse.vue'));
 import { ElMessage } from 'element-plus';
 import { useI18n } from 'vue-i18n';
 import { appUpdate } from '/@/api/marketing/apps';
-import { useMessage } from '/@/hooks/message';
-const DomainCollapse = defineAsyncComponent(() => import('./domainCollapse.vue'));
-const IpCollapse = defineAsyncComponent(() => import('./ipCollapse.vue'));
 
 interface IpItem {
-  id: String;
-  ipMode: Number;
-  ipType: Number;
-  sourceType: Number; // 1:分组 2:具体Ip(段)
-  startIp: String;
-  endIp: String;
-  groupId: String;
-  groupName: String;
+  id: string;
+  ipMode: number;
+  ipType: number;
+  sourceType: number; // 1:分组 2:具体Ip(段)
+  startIp: string;
+  endIp: string;
+  groupId: string;
+  groupName: string;
 }
 
 interface DomianItem {
-  id: String;
-  domain: String;
-  sourceType: Number; // 1:分组 2:具体域名
-  groupId: String;
-  groupName: String;
+  id: string;
+  domain: string;
+  sourceType: number; // 1:分组 2:具体域名
+  groupId: string;
+  groupName: string;
 }
 
 interface Form {
-  id?: String;
-  appId?: String;
-  appName?: String;
-  appImg?: String;
-  appUrl?: String;
-  backUpUrl?: String;
-  domainType?: String;
-  domainLimit: Boolean;
-  launch: Boolean;
-  triggerRule: Number;
-  triggerNum: String;
-  remark: String;
+  id?: string;
+  appId?: string;
+  appName?: string;
+  appImg?: string;
+  appUrl?: string;
+  backUpUrl?: string;
+  domainType?: string;
+  domainLimit: boolean;
+  launch: boolean;
+  triggerRule: number;
+  triggerNum: string;
+  remark: string;
   ips?: IpItem[];
   domains?: DomianItem[];
   delDomains?: string[];
+  delIps?: string[];
 }
 
 // 定义子组件向父组件传值/事件
@@ -112,9 +112,9 @@ const visible = ref(false);
 const loading = ref(false);
 const appDialogFormRef = ref();
 const domains = ref();
-const delDomains = ref<String[]>([]);
+const delDomains = ref<string[]>([]);
 const childIps = ref();
-const delIps = ref<String[]>([]);
+const delIps = ref<string[]>([]);
 // 批量操作
 const rows = ref<Form[]>([]);
 
@@ -147,14 +147,14 @@ watch(() => state.ruleForm, async (val) => {
 const updateIps = (data: IpItem[]) => {
   childIps.value = data;
 }
-const updateDelIps = (data: String[]) => {
+const updateDelIps = (data: string[]) => {
   delIps.value = data;
 }
 
 const updateDomains = (data: DomianItem[]) => {
   domains.value = data;
 }
-const updateDelDomains = (data: String[]) => {
+const updateDelDomains = (data: string[]) => {
   delDomains.value = data;
 }
 
@@ -251,7 +251,7 @@ const onSubmit = async () => {
         remark: state.ruleForm.remark,
         domainLimit: state.ruleForm.domainLimit,
         launch: state.ruleForm.launch,
-        triggerNum: processNumberString(state.ruleForm.triggerNum) + '',
+        triggerNum: `${processNumberString(state.ruleForm.triggerNum)}`,
         triggerRule: state.ruleForm.triggerRule,
       })
     })
@@ -259,11 +259,11 @@ const onSubmit = async () => {
     
     await appUpdate(data);
     ElMessage.success('提交成功!');
-    
     visible.value = false;
     emit('refresh');
   } catch (err: any) {
-    useMessage().error(err.msg);
+    ElMessage.error('提交失败!');
+    console.error(err);
   } finally {
     loading.value = false;
   }

+ 15 - 16
src/views/marketing/apps/components/ipCell.vue

@@ -6,8 +6,8 @@
       <span class="item" v-if="list.length <= 0">--</span>
     </div>
     <div class="action">
-      <el-link type="info" @click="handleEdit" style="color: #167AF0; line-height: 18px;" >
-        {{ blacklist.length > 0 ? '查看详情' : '添加IP'}}
+      <el-link type="info" class="btn-more" :class="{disabled: !state}" :disabled="!state" @click="handleEdit" >
+        {{ ipList.length > 0 ? '查看详情' : '添加IP'}}
       </el-link>
     </div>
   </div>
@@ -16,8 +16,9 @@
 <script setup>
 import { ref, watch } from 'vue';
 const IpForm = defineAsyncComponent(() => import('./ipForm.vue'));
+import { ipSplicing } from '/@/utils/ipUpdate';
 
-const props = defineProps(['ipList', 'rowData']);
+const props = defineProps(['ipList', 'rowData', 'state']);
 const emit = defineEmits(['refresh']);
 
 const blacklist = ref([]);
@@ -32,7 +33,7 @@ watch(
     let temp = '';
     (newVal || []).forEach(item => {
       if (item.sourceType == 2) {
-        temp = item.startIp + (item.endIp ? '/' + item.endIp.split('.').pop() : '');
+        temp = ipSplicing(item.startIp, item.endIp);
       } else {
         temp = item.groupName;
       }
@@ -52,13 +53,10 @@ const handleUpdate = () => {
 }
 </script>
 <style scoped lang="scss">
+@import '/@/theme/mixins/index.scss';
+
 .cell {
   padding: 10px 0;
-  // .flex {
-  //   display: flex;
-  //   flex-wrap: wrap;
-  //   margin-bottom: 5px;
-  // }
   .title {
     text-align: left;
     line-height: 14px;
@@ -79,14 +77,15 @@ const handleUpdate = () => {
     width: 100%;
     text-align: left;
   }
-
   .ellipsis {
-    display: -webkit-box;          /* 使用弹性盒子布局 */
-    -webkit-box-orient: vertical;  /* 垂直方向排列 */
-    -webkit-line-clamp: 2;         /* 限制显示的行数 */
-    overflow: hidden;              /* 隐藏超出部分 */
-    text-overflow: ellipsis;       /* 超出时显示省略号 */
-    word-break: break-word;        /* 允许单词断行(可选) */
+    @include text-ellipsis(2);
+  }
+  .btn-more {
+    color: #167AF0;
+    line-height: 18px;
+    &.disabled {
+      opacity: 0.68;
+    }
   }
 }
 </style>

+ 55 - 58
src/views/marketing/apps/components/ipCollapse.vue

@@ -8,10 +8,12 @@
         <div class="collapse-group-name">{{ type === 1 ? '白名单' : '黑名单' }}:</div>
         <div class="tag-content" v-if="getTargetList(type).length > 0">
           <template v-for="item in getTargetList(type)" :key="item.id">
+            <!-- 单个 -->
             <el-tag v-if="item.sourceType == 2" effect="light" :closable="ipDeletable" @close="handleDeleteIp(item)"
               color="#f4f4f4" round class="ml-1 cursor-pointer" style="margin-bottom: 4px;">
               <span class="ellipsis">{{ ipSplicing(item.startIp, item.endIp) }}</span>
             </el-tag>
+            <!-- 分组 -->
             <el-popover v-else width="200" trigger="hover" placement="top" @show="onLoadDetail(item)">
               <div v-if="item.list.length > 0" class="flex flex-wrap break-all">
                 <span v-for="ip in item.list" :key="String(ip)" class="mr-2">{{ ip }}</span>
@@ -20,7 +22,8 @@
               <template #reference>
                 <el-tag effect="light" :closable="ipDeletable" @close="handleDeleteIp(item)" color="#f4f4f4" round
                   class="ml-1 cursor-pointer" style="margin-bottom: 4px;">
-                <span class="ellipsis">{{ item.groupName.length > 30 ? item.groupName.substring(0, 30) + '...' : item.groupName }}</span>
+                  <span class="ellipsis" v-if="item.groupName">{{ item.groupName.length > 30 ?
+                    item.groupName.substring(0, 30) + '...' : item.groupName }}</span>
                 </el-tag>
               </template>
             </el-popover>
@@ -41,7 +44,7 @@ import { ipSplicing } from '/@/utils/ipUpdate';
 import { useMessage } from '/@/hooks/message';
 
 interface IpItem {
-  id: string;
+  id?: string;
   ipMode: number;
   ipType: number; // 1: 白名单, 2: 黑名单
   sourceType: number;
@@ -60,7 +63,7 @@ const { t } = useI18n();
 const ips = ref<IpItem[]>([]);
 const ipDeletable = ref(false);
 const listEditOpen = ref(false);
-const delIps = ref<String[]>([]);
+const delIps = ref<string[]>([]);
 
 watch(ips, (newVal) => emit('ips', newVal), { deep: true, immediate: true });
 watch(delIps, (newVal) => emit('delIps', newVal), { deep: true, immediate: true });
@@ -81,8 +84,8 @@ watchEffect(() => {
 });
 
 const handleDeleteIp = (deleteItem: IpItem) => {
-  if (!deleteItem.modify && !delIps.value.includes(deleteItem.id)) {
-    delIps.value.push(deleteItem.id);
+  if (!deleteItem.modify && !delIps.value.includes(deleteItem.id as string)) {
+    delIps.value.push(deleteItem.id as string);
   }
   ips.value = ips.value.filter(i => {
     if (i.id !== deleteItem.id) return true;
@@ -104,31 +107,30 @@ function addGroupsUnique(newGroups: IpItem[], ipType: number) {
   const existIds = new Set(targetList.filter(i => i.sourceType === 1).map(i => i.groupId));
   const conflictIds = new Set(conflictList.filter(i => i.sourceType === 1).map(i => i.groupId));
 
-  const conflict = newGroups.find(i => conflictIds.has(i.id));
+  const conflict = newGroups.find(i => conflictIds.has(i.id as string));
   if (conflict) {
-    useMessage().warning(`分组 ${ conflict.groupName } 已存在于 ${ ipType === 1 ? '黑名单' : '白名单'} 中`);
-  return;
-}
+    useMessage().warning(`分组 ${conflict.groupName} 已存在于 ${ipType === 1 ? '黑名单' : '白名单'} 中`);
+    return;
+  }
 
-const filtered = newGroups.filter(i => !existIds.has(i.id));
-
-if (filtered.length) {
-  const processedGroups = filtered.map(item => ({
-    ipType,
-    sourceType: 1,
-    groupId: item.id,
-    groupName: item.groupName,
-    isMode: 1,
-    startIp: '',
-    endIp: '',
-    modify: true,
-    list: item.list || []
-  }));
-  setTargetList(ipType, [...targetList, ...processedGroups]);
-  useMessage().success(t('common.addSuccessText'));
-} else {
-  useMessage().warning('该分组已添加到IP集合,无需重复添加');
-}
+  const filtered = newGroups.filter(i => !existIds.has(i.id as string));
+
+  if (filtered.length) {
+    const processedGroups = filtered.map(item => ({
+      ipType,
+      sourceType: 1,
+      groupId: item.id as string,
+      groupName: item.groupName,
+      ipMode: 1,
+      startIp: '',
+      endIp: '',
+      modify: true,
+      list: item.list || [],
+    }));
+    setTargetList(ipType, [...targetList, ...processedGroups]);
+  } else {
+    useMessage().warning('该分组已添加到IP集合,无需重复添加');
+  }
 }
 
 function addSinglesUnique(newSingles: IpItem[], ipType: number) {
@@ -142,30 +144,28 @@ function addSinglesUnique(newSingles: IpItem[], ipType: number) {
   const conflict = newSingles.find(i => conflictIps.has(i.startIp));
   if (conflict) {
     console.log(conflict);
-    useMessage().warning(`IP ${ conflict.startIp } 已存在于 ${ ipType === 1 ? '黑名单' : '白名单'} 中`);
-  return;
-}
+    useMessage().warning(`IP ${conflict.startIp} 已存在于 ${ipType === 1 ? '黑名单' : '白名单'} 中`);
+    return;
+  }
 
-const filtered = newSingles.filter(i => !existIps.has(i.startIp));
-
-if (filtered.length) {
-  const processedSingles = filtered.map(i => ({
-    // id: i.id,
-    endIp: i.endIp,
-    groupId: '0',
-    groupName: '',
-    ipMode: i.endIp ? 2 : 1,
-    startIp: i.startIp,
-    sourceType: 2,
-    modify: true,
-    ipType,
-    list: []
-  }));
-  setTargetList(ipType, [...targetList, ...processedSingles]);
-  useMessage().success(t('common.addSuccessText'));
-} else {
-  useMessage().warning('该IP已存在于集合中,无需重复添加');
-}
+  const filtered = newSingles.filter(i => !existIps.has(i.startIp));
+
+  if (filtered.length) {
+    const processedSingles = filtered.map(i => ({
+      endIp: i.endIp,
+      groupId: '',
+      groupName: '',
+      ipMode: i.endIp ? 2 : 1,
+      startIp: i.startIp,
+      sourceType: 2,
+      modify: true,
+      ipType,
+      list: []
+    }));
+    setTargetList(ipType, [...targetList, ...processedSingles]);
+  } else {
+    useMessage().warning('该IP已存在于集合中,无需重复添加');
+  }
 }
 
 const addIp = (data: IpItem[], sourceType: 1 | 2, ipType: '1' | '2') => {
@@ -178,16 +178,13 @@ const addIp = (data: IpItem[], sourceType: 1 | 2, ipType: '1' | '2') => {
 };
 </script>
 <style lang="scss">
+@import '/@/theme/mixins/index.scss';
+
 .el-collapse-item__content {
   padding: 0;
 }
+
 .ellipsis {
-  max-width: 780px;
-  display: -webkit-box;          /* 使用弹性盒子布局 */
-  -webkit-box-orient: vertical;  /* 垂直方向排列 */
-  -webkit-line-clamp: 1;         /* 限制显示的行数 */
-  overflow: hidden;              /* 隐藏超出部分 */
-  text-overflow: ellipsis;       /* 超出时显示省略号 */
-  word-break: break-word;        /* 允许单词断行(可选) */
+  @include text-ellipsis(1);
 }
 </style>

+ 12 - 13
src/views/marketing/apps/components/ipEdit.vue

@@ -61,17 +61,17 @@ import { rule } from '/@/utils/validate';
 import { parseIpRange } from '/@/utils/ipUpdate';
 
 interface IpItem {
-	id: Number;
-	groupId: Number;
-	groupName: String;
-	ipMode: Number;
-	ip: String;
-	startIp: String;
-	endIp: String;
-	sourceType: Number;
+	id: number;
+	groupId: number;
+	groupName: string;
+	ipMode: number;
+	ip: string;
+	startIp: string;
+	endIp: string;
+	sourceType: number;
 	list: {
-		id: Number;
-		value: String;
+		id: number;
+		value: string;
 	}[];
 }
 
@@ -81,7 +81,7 @@ const { t } = useI18n();
 
 // 定义变量内容
 const loading = ref(false);
-const type = ref('add'); // 'add' or 'edit'
+const type = ref('Edit');
 const formRef = ref();
 const selectData = ref<IpItem[]>([]);
 const selectedObjects = ref<IpItem[]>([]);
@@ -181,8 +181,7 @@ const onSubmit = async () => {
 		}
 		onCancel();
 	} catch (err) {
-		console.log(err);
-		useMessage().error(err.msg);
+		useMessage().error(err);
 	} finally {
 		loading.value = false;
 	}

+ 15 - 11
src/views/marketing/apps/components/ipForm.vue

@@ -22,11 +22,11 @@ import { updateModIp } from '/@/api/marketing/apps';
 const IpCollapse = defineAsyncComponent(() => import('./ipCollapse.vue'));
 
 interface IpItem {
-  id: String;
-  ip: String;
-  sourceType: Number; // 1:分组 2:具体域名
-  groupId: String;
-  groupName: String;
+  id: string;
+  ip: string;
+  sourceType: number; // 1:分组 2:具体域名
+  groupId: string;
+  groupName: string;
 }
 
 // 定义子组件向父组件传值/事件
@@ -38,7 +38,7 @@ const visible = ref(false);
 const loading = ref(false);
 const ips = ref<IpItem[]>([]);
 const childIps = ref();
-const delIps = ref<String[]>([]);
+const delIps = ref<string[]>([]);
 const rowData = ref();
 
 // 打开弹窗
@@ -51,17 +51,21 @@ const openDialog = async (data: any, row) => {
 const updateIps = (data: IpItem[])=>{
   childIps.value = data;
 }
-const updateDelIps = (data: String[]) => {
+const updateDelIps = (data: string[]) => {
   delIps.value = data;
 }
 
 // 保存数据
 const onSubmit = async () => {
-  ElMessage.success('提交成功!');
-  visible.value = false;
-  updateModIp({ ips: childIps.value, delIps: delIps.value, id: rowData.value.id}).then((res) => {
+  try {
+    await updateModIp({ ips: childIps.value, delIps: delIps.value, id: rowData.value.id});
     emit('refresh');
-  })
+    ElMessage.success('提交成功!');
+    visible.value = false;
+  } catch (error) {
+    ElMessage.error('提交失败!');
+    console.error(error);
+  }
 };
 
 // 暴露变量 只有暴漏出来的变量 父组件才能使用

+ 2 - 2
src/views/marketing/apps/index.vue

@@ -80,12 +80,12 @@
         </el-table-column>
         <el-table-column :label="'域名集合'" prop="domains" width="280">
           <template #default="{ row }">
-            <DomainCell :domainList="row.domains" :rowData="row" @refresh="getDataList()" />
+            <DomainCell :domainList="row.domains" :state="activeName=='tab1'" :rowData="row" @refresh="getDataList()" />
           </template>
         </el-table-column>
         <el-table-column :label="'IP集合'" prop="ips" width="320">
           <template #default="{ row }">
-            <IpCell :ipList="row.ips" :rowData="row" @refresh="getDataList()" />
+            <IpCell :ipList="row.ips" :state="activeName=='tab1'" :rowData="row" @refresh="getDataList()" />
           </template>
         </el-table-column>
         <el-table-column :label="'触发频率'" prop="triggerNum" width="120" show-overflow-tooltip>