Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
XieYongHong 2023-07-11 14:22:11 +08:00
commit bd34de8642
23 changed files with 346 additions and 215 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -202,13 +202,15 @@ const modelRef = reactive({
const property = ref<any>({}); const property = ref<any>({});
const onPropertyChange = (val: string) => { const onPropertyChange = (val: string, flag?: boolean) => {
if (val) { if (val) {
const _item = props.metadata?.properties.find( const _item = props.metadata?.properties.find(
(item: any) => item.id === val, (item: any) => item.id === val,
); );
property.value = _item || {}; property.value = _item || {};
modelRef.message.value = undefined if(!flag){
modelRef.message.value = undefined
}
} }
}; };
@ -227,7 +229,7 @@ watch(
if (newVal) { if (newVal) {
Object.assign(modelRef, newVal); Object.assign(modelRef, newVal);
if (newVal?.message?.properties) { if (newVal?.message?.properties) {
onPropertyChange(newVal?.message?.properties); onPropertyChange(newVal?.message?.properties, true);
} }
} }
}, },
@ -263,6 +265,7 @@ const saveBtn = () =>
resolve(false); resolve(false);
}); });
} }
console.log(_data)
emit('update:modelValue', _data) emit('update:modelValue', _data)
resolve(_data); resolve(_data);
}) })

View File

@ -75,6 +75,7 @@ import { getImage } from '@/utils/comm';
padding: 8px 16px; padding: 8px 16px;
color: #2f54eb; color: #2f54eb;
background-color: rgba(#a7bdf7, 0.2); background-color: rgba(#a7bdf7, 0.2);
word-wrap: break-word;
} }
h1 { h1 {

View File

@ -163,6 +163,7 @@ const columns = [
title: '名称', title: '名称',
dataIndex: 'name', dataIndex: 'name',
key: 'name', key: 'name',
ellipsis: true,
search: { search: {
type: 'string', type: 'string',
}, },
@ -229,7 +230,7 @@ const columns = [
title: '操作', title: '操作',
key: 'action', key: 'action',
fixed: 'right', fixed: 'right',
width: 160, width: 180,
scopedSlots: true, scopedSlots: true,
}, },
]; ];

View File

@ -25,7 +25,6 @@
:src="url" :src="url"
v-if="!loading" v-if="!loading"
></iframe> ></iframe>
<!-- sandbox="allow-forms allow-scripts allow-same-origin allow-popups" -->
</div> </div>
</j-spin> </j-spin>
</template> </template>
@ -105,7 +104,6 @@ const updateIframeStyle = () => {
) as HTMLIFrameElement; ) as HTMLIFrameElement;
iframe.onload = () => { iframe.onload = () => {
const currentUrl = iframe?.contentWindow?.location?.search || ''; const currentUrl = iframe?.contentWindow?.location?.search || '';
console.log(currentUrl)
let authCode = ''; let authCode = '';
if (currentUrl.startsWith('?')) { if (currentUrl.startsWith('?')) {
currentUrl currentUrl

View File

@ -0,0 +1,129 @@
<template>
<div class="box-item">
<div class="box-item-img">
<j-popover
v-model:visible="popoverVisible"
placement="top"
:trigger="['click']"
>
<div
:class="{
disabled: !notifyChannels?.includes(current?.id),
}"
>
<img
:src="iconMap.get(current?.channelProvider)"
style="width: 32px"
/>
</div>
<template #content>
<PermissionButton
v-if="!notifyChannels?.includes(current?.id)"
type="link"
:hasPermission="true"
@click="onCheckChange(current)"
>
订阅
</PermissionButton>
<template v-else>
<Detail
@unsubscribe="onUnSubscribe"
@save="onSave"
v-if="current?.channelProvider !== 'inside-mail'"
:current="current"
:data="props.data"
@close="popoverVisible = false"
/>
<PermissionButton
v-else
type="link"
:hasPermission="true"
@click="onUnSubscribe(current)"
>
取消订阅
</PermissionButton>
</template>
</template>
</j-popover>
</div>
<div class="box-item-text">
<j-ellipsis style="width: 50px">
{{ current?.name }}
</j-ellipsis>
</div>
</div>
</template>
<script lang="ts" setup>
import { getImage } from '@/utils/comm';
import Detail from './Detail.vue';
const iconMap = new Map();
iconMap.set('notifier-dingTalk', getImage('/notice-rule/dingtalk.png'));
iconMap.set('notifier-weixin', getImage('/notice-rule/wechat.png'));
iconMap.set('notifier-email', getImage('/notice-rule/email.png'));
iconMap.set('notifier-voice', getImage('/notice-rule/voice.png'));
iconMap.set('notifier-sms', getImage('/notice-rule/sms.png'));
iconMap.set('inside-mail', getImage('/notice-rule/inside-mail.png'));
const emit = defineEmits(['save', 'unsubscribe']);
const props = defineProps({
data: {
//
type: Object,
default: () => {},
},
current: {
//
type: Object,
default: () => {},
},
notifyChannels: {
type: Array,
default: () => []
}
});
const popoverVisible = ref<boolean>(false);
const onUnSubscribe = (dt: any) => {
emit('unsubscribe', dt);
popoverVisible.value = false
};
const onCheckChange = (dt: any) => {
emit('save', dt)
popoverVisible.value = false
};
</script>
<style lang="less" scoped>
.box-item {
// margin: 0 5px;
.box-item-img {
width: 50px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
img {
z-index: 1;
cursor: pointer;
}
.disabled {
filter: grayscale(100%);
// filter: brightness(0);
// opacity: 50%;
}
}
.box-item-text {
width: 100%;
text-align: center;
color: #666666;
font-size: 12px;
}
}
</style>

View File

@ -1,16 +1,16 @@
<template> <template>
<j-modal width="350px" visible @cancel="emit('close')" :footer="null"> <div style="width: 300px">
<template v-if="getType === 'notifier-dingTalk'"> <template v-if="getType === 'notifier-dingTalk'">
<div class="tip">绑定账号{{ info }}</div> <div class="tip"><j-ellipsis :lineClamp="2">绑定账号{{ info }}</j-ellipsis></div>
</template> </template>
<template v-else-if="getType === 'notifier-weixin'"> <template v-else-if="getType === 'notifier-weixin'">
<div class="tip">绑定账号{{ info }}</div> <div class="tip"><j-ellipsis :lineClamp="2">绑定账号{{ info }}</j-ellipsis></div>
</template> </template>
<template v-else-if="getType === 'notifier-email'"> <template v-else-if="getType === 'notifier-email'">
<div class="tip">绑定账号{{ user.userInfos?.email }}</div> <div class="tip"><j-ellipsis :lineClamp="2">绑定账号{{ user.userInfos?.email }}</j-ellipsis></div>
</template> </template>
<template v-else> <template v-else>
<div class="tip">绑定账号{{ user.userInfos?.telephone }}</div> <div class="tip"><j-ellipsis :lineClamp="2">绑定账号{{ user.userInfos?.telephone }}</j-ellipsis></div>
</template> </template>
<div class="btn"> <div class="btn">
<j-button @click="emit('unsubscribe', current)">取消订阅</j-button> <j-button @click="emit('unsubscribe', current)">取消订阅</j-button>
@ -20,7 +20,7 @@
>更换绑定账号</j-button >更换绑定账号</j-button
> >
</div> </div>
</j-modal> </div>
<EditInfo <EditInfo
v-if="editInfoVisible" v-if="editInfoVisible"
:data="user.userInfos" :data="user.userInfos"
@ -43,7 +43,7 @@ import EditInfo from '../../EditInfo/index.vue';
import Bind from './Bind.vue'; import Bind from './Bind.vue';
const user = useUserInfo(); const user = useUserInfo();
const emit = defineEmits(['close', 'save', 'unsubscribe']); const emit = defineEmits(['save', 'unsubscribe', 'close']);
const info = ref<any>(null); const info = ref<any>(null);
const props = defineProps({ const props = defineProps({
data: { data: {
@ -75,18 +75,17 @@ const onBind = () => {
} else { } else {
visible.value = true visible.value = true
} }
emit('close')
}; };
const onSave = () => { const onSave = () => {
editInfoVisible.value = false; editInfoVisible.value = false;
user.getUserInfo(); user.getUserInfo();
emit('save', props.current); emit('save', props.current);
emit('close');
}; };
const onBindSave = () => { const onBindSave = () => {
emit('save', props.current); emit('save', props.current);
emit('close');
} }
const handleSearch = async () => { const handleSearch = async () => {
@ -123,7 +122,7 @@ watch(
<style lang="less" scoped> <style lang="less" scoped>
.tip { .tip {
width: 100%; width: 100%;
margin: 30px 0; margin: 20px 0;
} }
.btn { .btn {

View File

@ -7,7 +7,7 @@
<div class="child-item-left-auth" v-if="data?.description"> <div class="child-item-left-auth" v-if="data?.description">
<j-tooltip :title="data.description"> <j-tooltip :title="data.description">
<AIcon <AIcon
style="font-size: 16px; color: rgba(0, 0, 0, .3)" style="font-size: 16px; color: rgba(0, 0, 0, 0.3)"
type="ExclamationCircleOutlined" type="ExclamationCircleOutlined"
/> />
</j-tooltip> </j-tooltip>
@ -16,81 +16,7 @@
<div class="child-item-right"> <div class="child-item-right">
<MCarousel :data="data?.channels"> <MCarousel :data="data?.channels">
<template #card="slotProps"> <template #card="slotProps">
<div class="box-item"> <Card @save="onCheckChange" @unsubscribe="onUnSubscribe" :notifyChannels="notifyChannels" :data="props.data" :current="slotProps" />
<div class="box-item-img">
<j-dropdown placement="top" :trigger="['click']">
<div
:class="{
disabled: !notifyChannels?.includes(
slotProps?.id,
),
}"
>
<img
:src="
iconMap.get(
slotProps?.channelProvider,
)
"
style="width: 32px"
/>
</div>
<template #overlay>
<j-menu>
<j-menu-item
v-if="
!notifyChannels?.includes(
slotProps?.id,
)
"
>
<PermissionButton
type="link"
:hasPermission="true"
@click="
onCheckChange(slotProps)
"
>
订阅
</PermissionButton>
</j-menu-item>
<template v-else>
<j-menu-item>
<PermissionButton
type="text"
:hasPermission="true"
@click="
onUnSubscribe(slotProps)
"
>
取消订阅
</PermissionButton>
</j-menu-item>
<j-menu-item
v-if="
slotProps.channelProvider !==
'inside-mail'
"
>
<PermissionButton
type="link"
:hasPermission="true"
@click="onDetail(slotProps)"
>
查看详情
</PermissionButton>
</j-menu-item>
</template>
</j-menu>
</template>
</j-dropdown>
</div>
<div class="box-item-text">
<j-ellipsis style="width: 50px;">
{{ slotProps?.name }}
</j-ellipsis>
</div>
</div>
</template> </template>
</MCarousel> </MCarousel>
</div> </div>
@ -102,28 +28,19 @@
:current="current" :current="current"
@close="visible = false" @close="visible = false"
/> />
<Detail @unsubscribe="onUnSubscribe" @save="onSave" @close="_visible = false" v-if="_visible" :current="current" :data="props.data" />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { getImage, onlyMessage } from '@/utils/comm'; import { onlyMessage } from '@/utils/comm';
import MCarousel from '@/components/MCarousel/index.vue'; import MCarousel from '@/components/MCarousel/index.vue';
import Unsubscribe from './Unsubscribe.vue'; import Unsubscribe from './Unsubscribe.vue';
import Detail from './Detail.vue'; import Card from './Card.vue';
import { import {
getIsBindThird, getIsBindThird,
save_api, save_api,
} from '@/api/account/notificationSubscription'; } from '@/api/account/notificationSubscription';
import { useUserInfo } from '@/store/userInfo'; import { useUserInfo } from '@/store/userInfo';
const iconMap = new Map();
iconMap.set('notifier-dingTalk', getImage('/notice-rule/dingtalk.png'));
iconMap.set('notifier-weixin', getImage('/notice-rule/wechat.png'));
iconMap.set('notifier-email', getImage('/notice-rule/email.png'));
iconMap.set('notifier-voice', getImage('/notice-rule/voice.png'));
iconMap.set('notifier-sms', getImage('/notice-rule/sms.png'));
iconMap.set('inside-mail', getImage('/notice-rule/inside-mail.png'));
const current = ref<any>({}); const current = ref<any>({});
const visible = ref<boolean>(false); const visible = ref<boolean>(false);
const _visible = ref<boolean>(false); const _visible = ref<boolean>(false);
@ -159,7 +76,7 @@ const onSubscribe = async (obj: any) => {
if (resp.status === 200) { if (resp.status === 200) {
onlyMessage('操作成功'); onlyMessage('操作成功');
emits('refresh'); emits('refresh');
_visible.value = false _visible.value = false;
} else { } else {
onlyMessage('操作失败', 'error'); onlyMessage('操作失败', 'error');
} }
@ -177,7 +94,7 @@ const onUnSubscribe = async (obj: any) => {
}; };
const resp = await save_api(_obj); const resp = await save_api(_obj);
if (resp.status === 200) { if (resp.status === 200) {
_visible.value = false _visible.value = false;
onlyMessage('操作成功'); onlyMessage('操作成功');
emits('refresh'); emits('refresh');
} else { } else {
@ -223,14 +140,9 @@ const onCheckChange = async (_data: any) => {
} }
}; };
const onDetail = (dt: any) => {
current.value = dt;
_visible.value = true
};
const onSave = (dt: any) => { const onSave = (dt: any) => {
onSubscribe(dt); onSubscribe(dt);
} };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@ -260,35 +172,6 @@ const onSave = (dt: any) => {
.child-item-right { .child-item-right {
display: flex; display: flex;
.box-item {
// margin: 0 5px;
.box-item-img {
width: 50px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
img {
z-index: 1;
cursor: pointer;
}
.disabled {
filter: grayscale(100%);
// filter: brightness(0);
// opacity: 50%;
}
}
.box-item-text {
width: 100%;
text-align: center;
color: #666666;
font-size: 12px;
}
}
} }
} }
</style> </style>

View File

@ -3,7 +3,7 @@
<div style="padding: 0 10px"> <div style="padding: 0 10px">
<div class="alert"> <div class="alert">
<AIcon type="InfoCircleOutlined" /> <AIcon type="InfoCircleOutlined" />
注意接收人需要有告警配置页面的查询权限才能收到告警类通知 你可以在该页面选择需要订阅的主题及接收通知的方式
</div> </div>
<div class="content-collapse"> <div class="content-collapse">
<template v-if="dataSource.length"> <template v-if="dataSource.length">

View File

@ -164,8 +164,9 @@ const onSubmit = async () => {
...params, ...params,
firmwareId, firmwareId,
productId, productId,
}); }).finally(() => {
loading.value = false; loading.value = false;
})
resp.success && emit('change', true); resp.success && emit('change', true);
}; };

View File

@ -131,6 +131,7 @@ const formData = ref<FormDataType>({
}); });
const changeType = (value: Array<string>) => { const changeType = (value: Array<string>) => {
formData.value.type = value[0]; formData.value.type = value[0];
formData.value.configuration.location = '';
}; };
const onSubmit = async () => { const onSubmit = async () => {
@ -168,12 +169,6 @@ const handleCancel = () => {
emit('change', false); emit('change', false);
}; };
watch(
() => formData.value.type,
() => {
formData.value.configuration.location = '';
},
);
watch( watch(
() => props.data, () => props.data,
(value) => { (value) => {

View File

@ -8,6 +8,7 @@
okText="确定" okText="确定"
@ok="handleSubmit" @ok="handleSubmit"
@cancel="handleCancel" @cancel="handleCancel"
:confirmLoading="loading"
> >
<j-form ref="formRef" :model="formData" layout="vertical"> <j-form ref="formRef" :model="formData" layout="vertical">
<j-row :gutter="10"> <j-row :gutter="10">
@ -208,6 +209,7 @@ const formData = ref({
media_username: '', media_username: '',
}); });
const loading = ref<boolean>(false)
watch( watch(
() => props.channelData, () => props.channelData,
(val: any) => { (val: any) => {
@ -279,11 +281,11 @@ const validateUrl = async (_rule: Rule, value: string) => {
/** /**
* 提交 * 提交
*/ */
const btnLoading = ref<boolean>(false);
const handleSubmit = () => { const handleSubmit = () => {
formRef.value formRef.value
.validate() .validate()
.then(async () => { .then(async () => {
loading.value = true;
const { const {
media_url, media_url,
media_password, media_password,
@ -299,20 +301,20 @@ const handleSubmit = () => {
media_username, media_username,
}; };
} }
btnLoading.value = true;
const res = formData.value.id const res = formData.value.id
? await ChannelApi.update(formData.value.id, extraFormData) ? await ChannelApi.update(formData.value.id, extraFormData)
: await ChannelApi.save(extraFormData); : await ChannelApi.save(extraFormData);
btnLoading.value = false;
if (res.success) { if (res.success) {
onlyMessage('操作成功'); onlyMessage('操作成功');
_vis.value = false; _vis.value = false;
emit('submit'); emit('submit');
} else { } else {
loading.value = false;
onlyMessage('操作失败', 'error'); onlyMessage('操作失败', 'error');
} }
}) })
.catch((err: any) => { .catch((err: any) => {
loading.value = false;
console.log('err: ', err); console.log('err: ', err);
}); });
}; };

View File

@ -182,6 +182,7 @@ type Emits = {
(e: 'update:productId', data: string): void; (e: 'update:productId', data: string): void;
(e: 'close'): void; (e: 'close'): void;
(e: 'save', data: Record<string, any>): void; (e: 'save', data: Record<string, any>): void;
(e: 'update:password',data:string):void
}; };
const emit = defineEmits<Emits>(); const emit = defineEmits<Emits>();
@ -288,8 +289,10 @@ const handleOk = () => {
.then(async () => { .then(async () => {
btnLoading.value = true; btnLoading.value = true;
const res = await DeviceApi.saveProduct(formData.value); const res = await DeviceApi.saveProduct(formData.value);
console.log(res)
if (res.success) { if (res.success) {
emit('update:productId', res.result.id); emit('update:productId', res.result.id);
emit('update:password', res.result.configuration.access_pwd)
const deployResp = await DeviceApi.deployProductById( const deployResp = await DeviceApi.deployProductById(
res.result.id, res.result.id,
); );

View File

@ -290,6 +290,7 @@
<SaveProduct <SaveProduct
v-model:visible="saveProductVis" v-model:visible="saveProductVis"
v-model:productId="formData.productId" v-model:productId="formData.productId"
v-model:password="formData.others.access_pwd"
:channel="formData.channel" :channel="formData.channel"
@close="getProductList" @close="getProductList"
/> />

View File

@ -413,6 +413,7 @@
formData.template.templateType formData.template.templateType
" "
placeholder="请选择类型" placeholder="请选择类型"
@change="onVoiceTemplateTypeChange"
> >
<j-select-option <j-select-option
v-for="(item, index) in VOICE_TYPE" v-for="(item, index) in VOICE_TYPE"
@ -1019,6 +1020,11 @@ watch(
}, },
); );
const onVoiceTemplateTypeChange = () => {
formData.value.template.ttsmessage = undefined
formData.value.variableDefinitions = []
}
/** /**
* 将需要提取变量的字段值拼接为一个字符串, 用于统一提取变量 * 将需要提取变量的字段值拼接为一个字符串, 用于统一提取变量
*/ */
@ -1205,6 +1211,8 @@ const getSignsList = async () => {
* 表单提交 * 表单提交
*/ */
const btnLoading = ref<boolean>(false); const btnLoading = ref<boolean>(false);
const handleSubmit = () => { const handleSubmit = () => {
// , // ,
if ( if (

View File

@ -51,8 +51,8 @@
<j-descriptions-item label="告警流水" :span="2" <j-descriptions-item label="告警流水" :span="2"
><div style="max-height: 500px; overflow-y: auto"> ><div style="max-height: 500px; overflow-y: auto">
<JsonViewer <JsonViewer
:value="JSON.parse(data?.alarmInfo || '{}')" :value="data"
:expand-depth="5" :expanded="true" :expandDepth="4"
></JsonViewer></div ></JsonViewer></div
></j-descriptions-item> ></j-descriptions-item>
</j-descriptions> </j-descriptions>
@ -67,6 +67,10 @@ const props = defineProps({
data: Object, data: Object,
description: String, description: String,
}); });
const data = computed(()=>{
return JSON.parse(props.data?.alarmInfo);
})
const emit = defineEmits(['close']); const emit = defineEmits(['close']);
const closeModal = () => { const closeModal = () => {
emit('close'); emit('close');

View File

@ -27,7 +27,9 @@
:params="queryParams" :params="queryParams"
:rowSelection="{ :rowSelection="{
selectedRowKeys: table._selectedRowKeys.value, selectedRowKeys: table._selectedRowKeys.value,
onChange: selectChange, onSelect: selectChange,
onSelectNone: ()=> table._selectedRowKeys.value = [],
onSelectAll: selectAll
}" }"
:columns="columns" :columns="columns"
> >
@ -422,14 +424,33 @@ table.init();
// }; // };
// fix: bug#10749 // fix: bug#10749
const selectChange = (record: any,selected: boolean,selectedRows: any,) => { const selectChange = (record: any,selected: boolean,selectedRows: any,) => {
const arr = new Set(table._selectedRowKeys.value);
if(selected){ if(selected){
table._selectedRowKeys.value.push(record?.id) arr.add(record.id)
}else{ }else{
arr.delete(record.id)
} }
console.log(record,selected,selectedRows); table._selectedRowKeys.value = [...arr.values()]
}; };
const selectAll = (selected: Boolean, selectedRows: any,changeRows:any) => {
if (selected) {
changeRows.map((i: any) => {
if (!table._selectedRowKeys.value.includes(i.id)) {
table._selectedRowKeys.value.push(i.id)
}
})
} else {
const arr = changeRows.map((item: any) => item.id)
const _ids: string[] = [];
table._selectedRowKeys.value.map((i: any) => {
if (!arr.includes(i)) {
_ids.push(i)
}
})
table._selectedRowKeys.value = _ids
}
}
const cancel = () => { const cancel = () => {
departmentStore.setProductId() departmentStore.setProductId()
emits('update:visible', false) emits('update:visible', false)

View File

@ -265,7 +265,7 @@ init();
.tree { .tree {
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: auto;
.department-tree-item-content { .department-tree-item-content {
display: flex; display: flex;
@ -274,11 +274,13 @@ init();
.title { .title {
flex: 1; flex: 1;
min-width: 80px; min-width: 80px;
margin-right: 80px;
} }
.func-btns { .func-btns {
display: none; display: none;
font-size: 14px; font-size: 14px;
width: 80px; width: 80px;
margin-left: -80px;
:deep(.ant-btn-link) { :deep(.ant-btn-link) {
padding: 0 4px; padding: 0 4px;
height: 24px; height: 24px;

View File

@ -15,7 +15,13 @@
</j-tooltip> </j-tooltip>
</div> </div>
<div class="child-item-left-auth" :class="{ disabled: !checked }"> <div class="child-item-left-auth" :class="{ disabled: !checked }">
<j-tooltip :title="!update ? '暂无权限,请联系管理员' : ''"> <j-tooltip>
<template #title>
<span v-if="!update">暂无权限请联系管理员</span>
<div v-else>
用于配制外层权限<br />未配置外层权限将执行通知方式中配置的权限<br />配置外层权限后将覆盖所有通知方式中配置的权限
</div>
</template>
<j-button <j-button
:disabled="!update || !checked" :disabled="!update || !checked"
type="text" type="text"

View File

@ -1,33 +1,75 @@
<template> <template>
<div class="role"> <div class="role">
<j-input-search <template v-if="type !== 'add'">
allowClear <j-input-search
@search="onSearch" allowClear
placeholder="请输入名称" @search="onSearch"
/> placeholder="请输入名称"
<div class="role-alert"> />
<j-alert type="info"> <div class="role-alert">
<template #message> <j-alert type="info">
<div class="header"> <template #message>
<j-checkbox <div class="header">
:indeterminate="indeterminate" <j-checkbox
:checked="checked" :indeterminate="indeterminate"
@change="onSelectAll" :checked="checked"
>全选</j-checkbox @change="onSelectAll"
> >全选</j-checkbox
<j-space v-if="_selectedRowKeys.length">
<span>已选择{{ _selectedRowKeys.length }}</span>
<j-button
style="padding: 0; height: 22px"
type="link"
@click="cancelSelect"
>取消选择</j-button
> >
</j-space> <j-space v-if="_selectedRowKeys.length">
</div> <span
</template> >已选择{{ _selectedRowKeys.length }}</span
</j-alert> >
</div> <j-button
style="padding: 0; height: 22px"
type="link"
@click="cancelSelect"
>取消选择</j-button
>
</j-space>
</div>
</template>
</j-alert>
</div>
</template>
<template v-else>
<div class="role-alert" style="margin-bottom: 10px;">
<j-alert type="info">
<template #message>
<div style="justify-content: space-between; display: flex; align-items: center;">
<j-input-search
allowClear
@search="onSearch"
placeholder="请输入名称"
style="width: 300px"
/>
<j-space>
<template v-if="_selectedRowKeys.length">
<span
>已选择{{
_selectedRowKeys.length
}}</span
>
<j-button
style="padding: 0; height: 22px"
type="link"
@click="cancelSelect"
>取消选择</j-button
>
</template>
<j-checkbox
:indeterminate="indeterminate"
:checked="checked"
@change="onSelectAll"
>全选</j-checkbox
>
</j-space>
</div>
</template>
</j-alert>
</div>
</template>
<j-scrollbar height="400px"> <j-scrollbar height="400px">
<j-pro-table <j-pro-table
ref="tableRef" ref="tableRef"
@ -71,8 +113,12 @@ const props = defineProps({
}, },
gridColumn: { gridColumn: {
type: Number, type: Number,
default: 3 default: 3,
} },
type: {
type: String,
default: '',
},
}); });
const emit = defineEmits(['update:modelValue']); const emit = defineEmits(['update:modelValue']);

View File

@ -8,11 +8,18 @@
> >
<div style="background-color: #f8f9fc; padding: 25px 100px"> <div style="background-color: #f8f9fc; padding: 25px 100px">
<j-steps :current="current" size="small" @change="onChange"> <j-steps :current="current" size="small" @change="onChange">
<j-step <j-step v-for="(item, index) in stepList" :key="item">
v-for="(item, index) in stepList" <template #title>
:title="item" {{ item
:key="item" }}<j-tooltip
> v-if="index === 4"
>
<template #title>
<span>内层权限配置<br />外层权限已配置的情况下将取外层权限与当前页面分配权限的交集向对应角色发送通知<br />外层权限未配置的情况下将按此处配置的权限发送通知</span>
</template>
<AIcon type="QuestionCircleOutlined"
/></j-tooltip>
</template>
<template #description> <template #description>
<span v-if="current === index">进行中</span> <span v-if="current === index">进行中</span>
<span v-if="current < index">未开始</span> <span v-if="current < index">未开始</span>
@ -52,7 +59,11 @@
/> />
</template> </template>
<template v-if="current === 4"> <template v-if="current === 4">
<Role v-model="formModel.grant.role.idList" /> <div class="alert">
<AIcon type="InfoCircleOutlined" />
已规定固定收信人的模板在当前页面将被过滤
</div>
<Role type="add" v-model="formModel.grant.role.idList" />
</template> </template>
<template v-if="current === 5"> <template v-if="current === 5">
<div> <div>
@ -235,7 +246,9 @@ const jumpStep = async (val: number) => {
return; return;
} else { } else {
// //
const resp = await Template.getTemplateDetail(formModel.channelConfiguration.templateId); const resp = await Template.getTemplateDetail(
formModel.channelConfiguration.templateId,
);
if (resp.status === 200) { if (resp.status === 200) {
variable.value = resp.result?.variableDefinitions || []; variable.value = resp.result?.variableDefinitions || [];
} }
@ -244,7 +257,7 @@ const jumpStep = async (val: number) => {
if (val >= 4) { if (val >= 4) {
if (variable.value.length) { if (variable.value.length) {
if (_variableDefinitions.value.length) { if (_variableDefinitions.value.length) {
if(variableRef.value) { if (variableRef.value) {
const obj = await variableRef.value?.onSave(); const obj = await variableRef.value?.onSave();
if (obj) { if (obj) {
handleVariable(obj); handleVariable(obj);
@ -253,22 +266,27 @@ const jumpStep = async (val: number) => {
return; return;
} }
} else { } else {
const flag = _variableDefinitions.value.every((item: any) => { const flag = _variableDefinitions.value.every(
const _value = formModel.channelConfiguration.variables[item.id]; (item: any) => {
if(!_value) { const _value =
return false formModel.channelConfiguration.variables[
} item.id
if(_value.source === 'fixed') { ];
return _value.value !== undefined if (!_value) {
} return false;
if(_value.source === 'upper') { }
return _value.upperKey !== undefined if (_value.source === 'fixed') {
} return _value.value !== undefined;
return true }
}) if (_value.source === 'upper') {
if(!flag) { return _value.upperKey !== undefined;
}
return true;
},
);
if (!flag) {
onlyMessage('请配置模版变量', 'error'); onlyMessage('请配置模版变量', 'error');
return return;
} }
} }
} else { } else {
@ -332,4 +350,15 @@ const onSave = async () => {
: []; : [];
emit('save', formModel); emit('save', formModel);
}; };
</script> </script>
<style lang="less" scoped>
.alert {
height: 40px;
padding: 0 20px 0 10px;
margin-bottom: 10px;
color: rgba(0, 0, 0, 0.55);
line-height: 40px;
background-color: #f6f6f6;
}
</style>

View File

@ -112,7 +112,6 @@ const selectAll = (selected: Boolean, selectedRows: any,changeRows:any) => {
}) })
selectedRowKeys.value = _ids selectedRowKeys.value = _ids
} }
} }
</script> </script>