|
@@ -8,25 +8,115 @@
|
|
|
style="margin-bottom: -25px;"
|
|
|
v-loading="loading">
|
|
|
<el-form-item :label="'营销开关'" prop="isMarketing">
|
|
|
- <el-switch v-model="state.ruleForm.isMarketing" style="--el-switch-on-color: rgb(48, 185, 113);" inline-prompt :active-value="1" :inactive-value="0" />
|
|
|
+ <el-switch v-model="state.ruleForm.isMarketing" style="--el-switch-on-color: rgb(48, 185, 113);"
|
|
|
+ inline-prompt :active-value="1" :inactive-value="0" />
|
|
|
</el-form-item>
|
|
|
- <el-form-item :label="'域名限制'" prop="isHttp">
|
|
|
- <el-switch v-model="state.ruleForm.isHttp" style="--el-switch-on-color: rgb(48, 185, 113);" inline-prompt :active-value="1" :inactive-value="0" />
|
|
|
+ <el-form-item :label="'域名限制'" prop="domainLimit">
|
|
|
+ <el-switch v-model="state.ruleForm.domainLimit" style="--el-switch-on-color: rgb(48, 185, 113);"
|
|
|
+ inline-prompt :active-value="true" :inactive-value="false" />
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
- <div class="title">IP集合</div>
|
|
|
- <JCollapse />
|
|
|
- <div class="title">域名集合</div>
|
|
|
- <JCollapse />
|
|
|
+ <JCollapse
|
|
|
+ :data="[
|
|
|
+ { title: 'IP集合', id: '1'},
|
|
|
+ ]"
|
|
|
+ @update="(item: any) => console.log(item)"
|
|
|
+ @delete="(item: any) => ipDeletable = !ipDeletable"
|
|
|
+ :deleteText="t('marketingConfig.deleteText')"
|
|
|
+ :updateText="'新增'"
|
|
|
+ style="margin-top: 30px;"
|
|
|
+ >
|
|
|
+ <template #default>
|
|
|
+ <div class="border-b p-2 items-center flex flex-wrap collapse-group">
|
|
|
+ <div class="collapse-group-name">白名单:</div>
|
|
|
+ <div class="tag-content">
|
|
|
+ <template v-for="item in ips.whitelist" :key="item.id">
|
|
|
+ <!-- 具体IP(段) -->
|
|
|
+ <el-tag v-if="item.sourceType == 2" @click="getIpList(item)" effect="light" :closable="ipDeletable"
|
|
|
+ @close="handleDelectIp(item)"
|
|
|
+ color="#f4f4f4" round class="ml-1 cursor-pointer" style="margin-bottom: 4px;">
|
|
|
+ {{ item.startIp }}{{ item.ipMode == 2 ? (' / ' + item.endIp.split('.').pop()) : '' }}
|
|
|
+ </el-tag>
|
|
|
+ <!-- 分组 -->
|
|
|
+ <el-popover v-else width="200" trigger="hover" placement="top">
|
|
|
+ <div class="flex flex-wrap">
|
|
|
+ <!-- <span v-for="ip in item.ips" :key="ip" class="ml-2">
|
|
|
+ {{ ip }}
|
|
|
+ </span> -->
|
|
|
+ {{ item.groupName }}
|
|
|
+ </div>
|
|
|
+ <template #reference>
|
|
|
+ <el-tag @click="getIpList(item)" effect="light" :closable="ipDeletable"
|
|
|
+ @close="handleDelectIp(item)"
|
|
|
+ color="#f4f4f4" round class="ml-1 cursor-pointer" style="margin-bottom: 4px;">
|
|
|
+ {{ item.groupName }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-popover>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="p-2 items-center flex flex-wrap collapse-group">
|
|
|
+ <div class="collapse-group-name">黑名单:</div>
|
|
|
+ <div class="tag-content">
|
|
|
+ <template v-for="item in ips.blacklist" :key="item.id">
|
|
|
+ <!-- 具体IP(段) -->
|
|
|
+ <el-tag v-if="item.sourceType == 2" @click="getIpList(item)" effect="light" :closable="ipDeletable"
|
|
|
+ @close="handleDelectIp(item)"
|
|
|
+ color="#f4f4f4" round class="ml-1 cursor-pointer" style="margin-bottom: 4px;">
|
|
|
+ {{ item.startIp }}{{ item.ipMode == 2 ? (' / ' + item.endIp.split('.').pop()) : '' }}
|
|
|
+ </el-tag>
|
|
|
+ <!-- 分组 -->
|
|
|
+ <el-popover v-else width="200" trigger="hover" placement="top">
|
|
|
+ <div class="flex flex-wrap">
|
|
|
+ <!-- <span v-for="ip in item.ips" :key="ip" class="ml-2">
|
|
|
+ {{ ip }}
|
|
|
+ </span> -->
|
|
|
+ {{ item.groupName }}
|
|
|
+ </div>
|
|
|
+ <template #reference>
|
|
|
+ <el-tag @click="getIpList(item)" effect="light" :closable="ipDeletable"
|
|
|
+ @close="handleDelectIp(item)"
|
|
|
+ color="#f4f4f4" round class="ml-1 cursor-pointer" style="margin-bottom: 4px;">
|
|
|
+ {{ item.groupName }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-popover>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </JCollapse>
|
|
|
+ <JCollapse
|
|
|
+ :data="[
|
|
|
+ { title: '域名集合', id: '1'},
|
|
|
+ ]"
|
|
|
+ @update="(item: any) => console.log(item)"
|
|
|
+ @delete="(item: any) => domainDeletable = !domainDeletable"
|
|
|
+ :deleteText="t('marketingConfig.deleteText')"
|
|
|
+ :updateText="'新增'"
|
|
|
+ style="margin-top: 30px;"
|
|
|
+ >
|
|
|
+ <template #default>
|
|
|
+ <div class="p-2 items-center flex flex-wrap">
|
|
|
+ <el-tag v-for="item in https" :key="item" effect="light" :closable="domainDeletable"
|
|
|
+ style="margin-bottom: 4px;" color="#f4f4f4" round class="ml-1 cursor-pointer">
|
|
|
+ {{ item.domain }}
|
|
|
+ </el-tag>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </JCollapse>
|
|
|
<div class="title">备注</div>
|
|
|
<el-input
|
|
|
:rows="4"
|
|
|
+ v-model="state.ruleForm.remark"
|
|
|
type="textarea"
|
|
|
+ placeholder="请输入备注"
|
|
|
></el-input>
|
|
|
<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>
|
|
|
+ <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>
|
|
@@ -35,9 +125,20 @@
|
|
|
|
|
|
<script setup lang="ts" name="systemMenuDialog">
|
|
|
import {useI18n} from 'vue-i18n';
|
|
|
-import {save} from '/@/api/marketing/config';
|
|
|
-import {useMessage} from '/@/hooks/message';
|
|
|
import JCollapse from '/@/components/JCollapse/index.vue';
|
|
|
+import { getDetail } from '/@/api/marketing/apps';
|
|
|
+import { ElMessage, messageConfig } from 'element-plus';
|
|
|
+
|
|
|
+interface Item {
|
|
|
+ id: string;
|
|
|
+ title: string;
|
|
|
+ list: string[];
|
|
|
+}
|
|
|
+
|
|
|
+interface Ips {
|
|
|
+ blacklist: String[];
|
|
|
+ whitelist: String[];
|
|
|
+}
|
|
|
|
|
|
// 定义子组件向父组件传值/事件
|
|
|
const emit = defineEmits(['refresh']);
|
|
@@ -46,53 +147,98 @@ const {t} = useI18n();
|
|
|
// 定义变量内容
|
|
|
const visible = ref(false);
|
|
|
const loading = ref(false);
|
|
|
-const sign = ref('domain')
|
|
|
const add = ref(false);
|
|
|
const menuDialogFormRef = ref();
|
|
|
+const ips = ref<Ips>({
|
|
|
+ blacklist: [],
|
|
|
+ whitelist: []
|
|
|
+});
|
|
|
+const https = ref<string[]>([]);
|
|
|
+const ipDeletable = ref(false);// 控制 IP 列表项是否可删除
|
|
|
+const domainDeletable = ref(false);// 控制域名列表项是否可删除
|
|
|
|
|
|
// 定义需要的数据
|
|
|
const state = reactive({
|
|
|
ruleForm: {
|
|
|
- list: [''],
|
|
|
- https: [''], // 域名集合
|
|
|
- ips: [''], // ip集合
|
|
|
+ marketingEnabled: false,
|
|
|
+ domainRestriction: false,
|
|
|
+ ipSets: [''], // ip集合
|
|
|
+ domainSets: [''], // ip集合
|
|
|
+ remark: '',
|
|
|
},
|
|
|
- appList: [] as any[], // 应用下拉框列表
|
|
|
+ domainSets: [] as any[], // 应用下拉框列表
|
|
|
});
|
|
|
|
|
|
-// 分页参数
|
|
|
-const pagination = reactive({
|
|
|
- current: 1,
|
|
|
- size: 10,
|
|
|
- total: 0
|
|
|
-})
|
|
|
+const handleDelect = ()=>{
|
|
|
+ console.log('delect')
|
|
|
+}
|
|
|
+
|
|
|
+const getIpList = (detail) => {
|
|
|
+ if(detail.sourceType == 1) {
|
|
|
+ // 获取ip组
|
|
|
+ console.log(detail.groupId);
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 删除ip
|
|
|
+const handleDelectIp = (delectItem)=>{
|
|
|
+ ips.value.whitelist = ips.value.whitelist.filter((item: any) => item.id != delectItem.id);
|
|
|
+ ips.value.blacklist = ips.value.blacklist.filter((item: any) => item.id != delectItem.id);
|
|
|
+}
|
|
|
+
|
|
|
+// 删除域名
|
|
|
+const handleDelectDomain = (item)=>{
|
|
|
+ console.log('delectDomain')
|
|
|
+}
|
|
|
|
|
|
// 打开弹窗
|
|
|
const openDialog = async (type: string, row: any, str: string = 'domain') => {
|
|
|
+ state.ruleForm = {
|
|
|
+ marketingEnabled: false,
|
|
|
+ domainRestriction: false,
|
|
|
+ ipSets: [''],
|
|
|
+ domainSets: [''],
|
|
|
+ remark: '',
|
|
|
+ };
|
|
|
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}));
|
|
|
+ // loading.value = true;
|
|
|
+ // try {
|
|
|
+ // const res = await getDetail(row.id);
|
|
|
+ // if (res) {
|
|
|
+ // state.ruleForm = res;
|
|
|
+ // console.log(res);
|
|
|
+ // ips.value = res.ipSets;
|
|
|
+ // https.value = res.domainSets;
|
|
|
+ // }
|
|
|
+ // } catch(e) {
|
|
|
+ // console.error(e);
|
|
|
+ // } finally {
|
|
|
+ // loading.value = false;
|
|
|
+ // }
|
|
|
+ state.ruleForm = row;
|
|
|
+ console.log(row);
|
|
|
+ ips.value.whitelist = row.ips.filter((item: any) => item.ipType == '1');
|
|
|
+ ips.value.blacklist = row.ips.filter((item: any) => item.ipType == '2');
|
|
|
+ console.log(ips.value);
|
|
|
+
|
|
|
+ https.value = row.domains;
|
|
|
};
|
|
|
|
|
|
// 保存数据
|
|
|
const onSubmit = async () => {
|
|
|
- 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: any) {
|
|
|
- useMessage().error(err.msg);
|
|
|
- } finally {
|
|
|
- loading.value = false;
|
|
|
- }
|
|
|
+ console.log(state.ruleForm)
|
|
|
+ // 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: any) {
|
|
|
+ // useMessage().error(err.msg);
|
|
|
+ // } finally {
|
|
|
+ // loading.value = false;
|
|
|
+ // }
|
|
|
};
|
|
|
|
|
|
// 暴露变量 只有暴漏出来的变量 父组件才能使用
|
|
@@ -121,6 +267,17 @@ defineExpose({
|
|
|
height: 330px !important;
|
|
|
}
|
|
|
.apps-form {
|
|
|
+ .collapse-group {
|
|
|
+ display: flex;
|
|
|
+ justify-content: start;
|
|
|
+ align-items:first baseline;
|
|
|
+ }
|
|
|
+ .collapse-group-name {
|
|
|
+ // width: 100px;
|
|
|
+ }
|
|
|
+ .tag-content {
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
.el-overlay {
|
|
|
.el-overlay-dialog {
|
|
|
.el-dialog {
|
|
@@ -140,5 +297,9 @@ defineExpose({
|
|
|
color: rgba(18, 18, 18, 1);
|
|
|
margin: 30px 0 12px;
|
|
|
}
|
|
|
+
|
|
|
+ .el-collapse-item__content {
|
|
|
+ padding: 0;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|