fix:相关漏洞修复

This commit is contained in:
weiwei committed 2025-08-15 15:55:02 +08:00
1 parent 0e66d461a7
commit 766bdea32a
6 files changed
+370 -294

No files matched your search

+60 -58
View File
@@ -3,7 +3,9 @@
<div v-loading="mainLoading" class="msg-main">
<div id="msg-div" class="msg-div">
<div v-if="!tableLoading">
<div v-if="loadMore" class="el-table__empty-block" @click="loadingMore"><span class="el-table__empty-text">点击加载更多</span></div>
<div v-if="loadMore" class="el-table__empty-block" @click="loadingMore">
<span class="el-table__empty-text">点击加载更多</span>
</div>
<div v-if="!loadMore" class="el-table__empty-block"><span class="el-table__empty-text">没有更多了</span></div>
</div>
<div v-for="item in tableData" :key="item.id" class="execution" id="msgTable">
@@ -109,125 +111,125 @@
</template>
<script setup lang="ts" name="wx-msg">
import { fetchList, addObj } from '/@/api/mp/wx-fans-msg';
import { useMessage } from '/@/hooks/message';
import { getMaterialVideo } from '/@/api/mp/wx-material';
import { fetchList, addObj } from "/@/api/mp/wx-fans-msg"
import { useMessage } from "/@/hooks/message"
import { getMaterialVideo } from "/@/api/mp/wx-material"
const WxReply = defineAsyncComponent(() => import('../wx-reply/index.vue'));
const WxNews = defineAsyncComponent(() => import('../wx-news/index.vue'));
const WxReply = defineAsyncComponent(() => import("../wx-reply/index.vue"))
const WxNews = defineAsyncComponent(() => import("../wx-news/index.vue"))
const NameAvatar = defineAsyncComponent(() => import('/@/components/NameAvatar/index.vue'));
const NameAvatar = defineAsyncComponent(() => import("/@/components/NameAvatar/index.vue"))
const visible = ref(false);
const visible = ref(false)
// 各种loading
const mainLoading = ref(false);
const sendLoading = ref(false);
const mainLoading = ref(false)
const sendLoading = ref(false)
const loadMore = ref(false);
const loadMore = ref(false)
const objData = ref({
repType: 'text',
appId: '',
}) as any;
repType: "text",
appId: "",
}) as any
const page = reactive({
total: 0, // 总页数
currentPage: 1, // 当前页数
pageSize: 10, // 每页显示多少条
ascs: [], //升序字段
descs: 'create_time', //降序字段
});
descs: "create_time", //降序字段
})
const wxData = reactive({
appId: '',
wxUserId: '',
});
appId: "",
wxUserId: "",
})
const sendMsg = () => {
if (objData.value) {
if (objData.value.repType === 'news') {
if (objData.value.repType === "news") {
if (JSON.parse(objData.value.content).length > 1) {
useMessage().error('图文消息条数限制在1条以内,已默认发送第一条');
objData.value.content = JSON.parse(objData.value.content)[0];
useMessage().error("图文消息条数限制在1条以内,已默认发送第一条")
objData.value.content = JSON.parse(objData.value.content)[0]
}
}
sendLoading.value = true;
sendLoading.value = true
addObj(
Object.assign(
{
wxUserId: wxData.wxUserId,
appId: wxData.appId,
},
objData.value
)
objData.value,
),
)
.then(() => {
tableData.value = [];
tableData.value = []
getData().then(() => {
//box-container是添加overflow的父div,也就是出现滚动条的div
var scrollTarget = document.getElementById('msg-div');
var scrollTarget = document.getElementById("msg-div")
//scrollTarget.scrollHeight是获取dom元素的高度,然后设置scrollTop
scrollTarget.scrollTop = scrollTarget.scrollHeight;
});
scrollTarget.scrollTop = scrollTarget.scrollHeight
})
})
.finally(() => {
sendLoading.value = false;
});
sendLoading.value = false
})
}
};
}
const tableData = ref([] as any);
const tableLoading = ref(false);
const tableData = ref([] as any)
const tableLoading = ref(false)
const openDialog = (data: any) => {
wxData.wxUserId = data.wxUserId;
wxData.appId = data.appId;
objData.value.appId = data.appId;
getData();
visible.value = true;
};
wxData.wxUserId = data.wxUserId
wxData.appId = data.appId
objData.value.appId = data.appId
getData()
visible.value = true
}
const getData = () => {
tableLoading.value = true;
tableLoading.value = true
return fetchList({
...page,
...wxData,
}).then((res) => {
const data = res.data.records.reverse();
tableData.value = [...data, ...tableData.value];
page.total = res.data.total;
tableLoading.value = false;
const data = res.data.records.reverse()
tableData.value = [...data, ...tableData.value]
page.total = res.data.total
tableLoading.value = false
if (data.length < page.pageSize || data.length === 0) {
loadMore.value = false;
loadMore.value = false
}
});
};
})
}
const loadVideo = (item) => {
getMaterialVideo({
mediaId: item.repMediaId,
appId: item.appId,
}).then((response) => {
const data = response.data;
window.open(data.downUrl, 'target', '');
});
};
// const data = response.data
// window.open(data.downUrl, 'target', '');
})
}
const loadingMore = () => {
page.currentPage = page.currentPage + 1;
getData();
};
page.currentPage = page.currentPage + 1
getData()
}
// 暴露变量
defineExpose({
openDialog,
});
})
</script>
<style lang="scss" scoped>
@import './comment.scss';
@import './card.scss';
@import "./comment.scss";
@import "./card.scss";
.msg-main {
margin-top: -30px;
+80 -80
View File
@@ -99,136 +99,136 @@
</template>
<script setup lang="ts" name="wx-reply">
import { getMaterialVideo } from '/@/api/mp/wx-material';
import { useMessage } from '/@/hooks/message';
const WxMaterialSelect = defineAsyncComponent(() => import('/@/components/Wechat/wx-material-select/main.vue'));
import { getMaterialVideo } from "/@/api/mp/wx-material"
import { useMessage } from "/@/hooks/message"
const WxMaterialSelect = defineAsyncComponent(() => import("/@/components/Wechat/wx-material-select/main.vue"))
const WxFileUpload = defineAsyncComponent(() => import('/@/components/Wechat/fileUpload/index.vue'));
const WxFileUpload = defineAsyncComponent(() => import("/@/components/Wechat/fileUpload/index.vue"))
const WxNews = defineAsyncComponent(() => import('/@/components/Wechat/wx-news/index.vue'));
const WxNews = defineAsyncComponent(() => import("/@/components/Wechat/wx-news/index.vue"))
const props = defineProps({
objData: {
type: Object,
default: () => {
return {
repType: '',
repContent: '',
repName: '',
repDesc: '',
repUrl: '',
};
repType: "",
repContent: "",
repName: "",
repDesc: "",
repUrl: "",
}
},
},
});
})
const uploadData = reactive({
mediaType: props.objData.repType,
title: '',
introduction: '',
title: "",
introduction: "",
appId: props.objData.appId,
});
})
const tempObj = ref({}) as any;
const tempObj = ref({}) as any
const handleClick = (tab) => {
uploadData.mediaType = tab.paneName;
uploadData.appId = props.objData.appId;
uploadData.mediaType = tab.paneName
uploadData.appId = props.objData.appId
const tempObjItem = tempObj.value[tab.paneName];
const tempObjItem = tempObj.value[tab.paneName]
if (tempObjItem) {
props.objData.repName = tempObjItem.repName ? tempObjItem.repName : null;
props.objData.repMediaId = tempObjItem.repMediaId ? tempObjItem.repMediaId : null;
props.objData.media_id = tempObjItem.media_id ? tempObjItem.media_id : null;
props.objData.repUrl = tempObjItem.repUrl ? tempObjItem.repUrl : null;
props.objData.content = tempObjItem.content ? tempObjItem.content : null;
props.objData.repDesc = tempObjItem.repDesc ? tempObjItem.repDesc : null;
props.objData.repName = tempObjItem.repName ? tempObjItem.repName : null
props.objData.repMediaId = tempObjItem.repMediaId ? tempObjItem.repMediaId : null
props.objData.media_id = tempObjItem.media_id ? tempObjItem.media_id : null
props.objData.repUrl = tempObjItem.repUrl ? tempObjItem.repUrl : null
props.objData.content = tempObjItem.content ? tempObjItem.content : null
props.objData.repDesc = tempObjItem.repDesc ? tempObjItem.repDesc : null
} else {
props.objData.repName = '';
props.objData.repMediaId = '';
props.objData.media_id = '';
props.objData.repUrl = '';
props.objData.content = '';
props.objData.repDesc = '';
props.objData.repName = ""
props.objData.repMediaId = ""
props.objData.media_id = ""
props.objData.repUrl = ""
props.objData.content = ""
props.objData.repDesc = ""
}
};
}
const deleteObj = () => {
props.objData.repName = '';
props.objData.repUrl = '';
props.objData.content = '';
};
props.objData.repName = ""
props.objData.repUrl = ""
props.objData.content = ""
}
const openMaterial = (data: any) => {
dialogNewsRef.value.openDialog(data);
};
dialogNewsRef.value.openDialog(data)
}
const dialogNewsRef = ref();
const dialogNewsRef = ref()
const selectMaterial = (item, appId) => {
let tempObjItem = {
repType: '',
repMediaId: '',
media_id: '',
content: '',
} as any;
repType: "",
repMediaId: "",
media_id: "",
content: "",
} as any
tempObjItem.repType = props.objData.repType;
tempObjItem.repMediaId = item.mediaId;
tempObjItem.media_id = item.mediaId;
tempObjItem.content = item.content;
tempObjItem.repType = props.objData.repType
tempObjItem.repMediaId = item.mediaId
tempObjItem.media_id = item.mediaId
tempObjItem.content = item.content
props.objData.repMediaId = item.mediaId;
props.objData.media_id = item.mediaId;
props.objData.content = item.content;
if (props.objData.repType === 'music') {
tempObjItem.repThumbMediaId = item.mediaId;
tempObjItem.repThumbUrl = item.url;
props.objData.repThumbMediaId = item.mediaId;
props.objData.repThumbUrl = item.url;
props.objData.repMediaId = item.mediaId
props.objData.media_id = item.mediaId
props.objData.content = item.content
if (props.objData.repType === "music") {
tempObjItem.repThumbMediaId = item.mediaId
tempObjItem.repThumbUrl = item.url
props.objData.repThumbMediaId = item.mediaId
props.objData.repThumbUrl = item.url
} else {
tempObjItem.repName = item.name;
tempObjItem.repUrl = item.url;
props.objData.repName = item.name;
props.objData.repUrl = item.url;
tempObjItem.repName = item.name
tempObjItem.repUrl = item.url
props.objData.repName = item.name
props.objData.repUrl = item.url
}
if (props.objData.repType === 'video') {
if (props.objData.repType === "video") {
getMaterialVideo({
mediaId: item.mediaId,
appId: appId,
}).then((response) => {
const data = response.data;
tempObjItem.repDesc = data.description || '';
tempObjItem.repUrl = data.downUrl;
props.objData.repName = data.title;
props.objData.repDesc = data.description || '';
props.objData.repUrl = data.downUrl;
});
const data = response.data
tempObjItem.repDesc = data.description || ""
tempObjItem.repUrl = data.downUrl
props.objData.repName = data.title
props.objData.repDesc = data.description || ""
props.objData.repUrl = data.downUrl
})
}
if (props.objData.repType === 'news') {
props.objData.content = JSON.stringify(item.content.newsItem);
if (props.objData.repType === "news") {
props.objData.content = JSON.stringify(item.content.newsItem)
}
tempObj.value[props.objData.repType] = tempObjItem;
};
tempObj.value[props.objData.repType] = tempObjItem
}
const handelUpload = (response) => {
if (response.code === 0) {
const item = response.data;
selectMaterial(item, props.objData.appId);
const item = response.data
selectMaterial(item, props.objData.appId)
} else {
useMessage().error('上传错误' + response.msg);
useMessage().error("上传错误" + response.msg)
}
};
}
const loadVideo = (item) => {
getMaterialVideo({
mediaId: item.repMediaId,
appId: item.appId,
}).then((response) => {
const data = response.data;
window.open(data.downUrl, 'target', '');
});
};
// const data = response.data
// window.open(data.downUrl, 'target', '');
})
}
</script>
<style scoped lang="scss">
+41 -38
View File
@@ -28,74 +28,77 @@
</template>
<script setup lang="ts" name="layoutBreadcrumbSearch">
import { useI18n } from 'vue-i18n';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import { useI18n } from "vue-i18n"
import { useTagsViewRoutes } from "/@/stores/tagsViewRoutes"
// 定义变量内容
const storesTagsViewRoutes = useTagsViewRoutes();
const { tagsViewRoutes } = storeToRefs(storesTagsViewRoutes);
const layoutMenuAutocompleteRef = ref();
const { t } = useI18n();
const router = useRouter();
const storesTagsViewRoutes = useTagsViewRoutes()
const { tagsViewRoutes } = storeToRefs(storesTagsViewRoutes)
const layoutMenuAutocompleteRef = ref()
const { t } = useI18n()
const router = useRouter()
const state = reactive<SearchState>({
isShowSearch: false,
menuQuery: '',
menuQuery: "",
tagsViewList: [],
});
})
// 搜索弹窗打开
const openSearch = () => {
state.menuQuery = '';
state.isShowSearch = true;
initTageView();
state.menuQuery = ""
state.isShowSearch = true
initTageView()
nextTick(() => {
setTimeout(() => {
layoutMenuAutocompleteRef.value.focus();
});
});
};
layoutMenuAutocompleteRef.value.focus()
})
})
}
// 搜索弹窗关闭
const closeSearch = () => {
state.isShowSearch = false;
};
state.isShowSearch = false
}
// 菜单搜索数据过滤
const menuSearch = (queryString: string, cb: Function) => {
let results = queryString ? state.tagsViewList.filter(createFilter(queryString)) : state.tagsViewList;
cb(results);
};
let results = queryString ? state.tagsViewList.filter(createFilter(queryString)) : state.tagsViewList
cb(results)
}
// 菜单搜索过滤
const createFilter = (queryString: string) => {
return (restaurant: RouteItem) => {
return restaurant.path.toLowerCase().indexOf(queryString.toLowerCase()) > -1 || t(restaurant!.name!).indexOf(queryString.toLowerCase()) > -1;
};
};
return (
restaurant.path.toLowerCase().indexOf(queryString.toLowerCase()) > -1 || t(restaurant!.name!).indexOf(queryString.toLowerCase()) > -1
)
}
}
// 初始化菜单数据
const initTageView = () => {
if (state.tagsViewList.length > 0) return false;
if (state.tagsViewList.length > 0) return false
tagsViewRoutes.value.map((v: RouteItem) => {
if (!v.meta?.isHide) state.tagsViewList.push({ ...v });
});
};
if (!v.meta?.isHide) state.tagsViewList.push({ ...v })
})
}
// 当前菜单选中时
const onHandleSelect = (item: RouteItem) => {
let { path, redirect } = item;
if (item.meta?.isLink && !item.meta?.isIframe) window.open(item.meta?.isLink);
else if (redirect) router.push(redirect);
else router.push(path);
closeSearch();
};
let { path, redirect } = item
if (item.meta?.isLink && !item.meta?.isIframe) {
// window.open(item.meta?.isLink)
} else if (redirect) router.push(redirect)
else router.push(path)
closeSearch()
}
// 暴露变量
defineExpose({
openSearch,
});
})
</script>
<style scoped lang="scss">
.layout-search-dialog {
position: relative;
:deep(.el-dialog) {
width: 560px;
width: 560px;
.el-dialog__header,
.el-dialog__body {
display: none;
@@ -108,8 +111,8 @@ defineExpose({
}
}
:deep(.el-autocomplete) {
position: absolute;
width: 560px;
position: absolute;
width: 560px;
top: 53vh;
left: 50%;
transform: translateX(-50%);
+16 -13
View File
@@ -14,31 +14,34 @@
</template>
<script setup lang="ts" name="layoutLinkView">
import { verifyUrl } from '/@/utils/toolsValidate';
import { verifyUrl } from "/@/utils/toolsValidate"
// 定义变量内容
const route = useRoute();
const route = useRoute()
const state = reactive<LinkViewState>({
title: '',
isLink: '',
});
title: "",
isLink: "",
})
// 立即前往
const onGotoFullPage = () => {
if (verifyUrl(<string>state.isLink)) window.open(state.isLink);
else window.open(`${state.isLink}`);
};
if (verifyUrl(<string>state.isLink)) {
window.open(state.isLink)
} else {
window.open(`${state.isLink}`)
}
}
// 监听路由的变化,设置内容
watch(
() => route.path,
() => {
state.title = <string>route.name;
state.isLink = <string>route.meta.isLink;
state.title = <string>route.name
state.isLink = <string>route.meta.isLink
},
{
immediate: true,
}
);
},
)
</script>
<style scoped lang="scss">
@@ -56,7 +59,7 @@ watch(
color: var(--el-color-primary);
&::after {
content: '';
content: "";
position: absolute;
left: 50px;
top: 0;
+93 -25
View File
@@ -167,13 +167,13 @@ export const openWindow = (url: string, title: string, w: number, h: number) =>
const width = window.innerWidth
? window.innerWidth
: document.documentElement.clientWidth
? document.documentElement.clientWidth
: screen.width
? document.documentElement.clientWidth
: screen.width
const height = window.innerHeight
? window.innerHeight
: document.documentElement.clientHeight
? document.documentElement.clientHeight
: screen.height
? document.documentElement.clientHeight
: screen.height
const left = width / 2 - w / 2 + dualScreenLeft
const top = height / 2 - h / 2 + dualScreenTop
@@ -181,13 +181,13 @@ export const openWindow = (url: string, title: string, w: number, h: number) =>
url,
title,
"toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=" +
w +
", height=" +
h +
", top=" +
top +
", left=" +
left,
w +
", height=" +
h +
", top=" +
top +
", left=" +
left,
)
}
@@ -290,25 +290,93 @@ export function postDownBlobFile(url: any, data: any, fileName: string) {
*/
export function handleBlobFile(response: any, fileName: string) {
// 处理返回的文件流
const blob = response
if (blob && blob.size === 0) {
useMessage().error("内容为空,无法下载")
// const blob = response
// if (blob && blob.size === 0) {
// useMessage().error("内容为空,无法下载")
// return
// }
// const link = document.createElement("a")
// // 兼容一下 入参不是 File Blob 类型情况
// var binaryData = [] as any
// binaryData.push(response)
// link.href = window.URL.createObjectURL(new Blob(binaryData))
// link.download = fileName
// document.body.appendChild(link)
// link.click()
// window.setTimeout(function () {
// // @ts-ignore
// URL.revokeObjectURL(blob)
// document.body.removeChild(link)
// }, 0)
// 1. 验证response类型和结构
if (!response || typeof response !== "object" || response.size === 0) {
useMessage().error("无效的响应数据")
return
}
const link = document.createElement("a")
// 兼容一下 入参不是 File Blob 类型情况
var binaryData = [] as any
binaryData.push(response)
link.href = window.URL.createObjectURL(new Blob(binaryData))
link.download = fileName
// 2. 验证blob类型
let blob: Blob
try {
if (response instanceof Blob) {
blob = response
} else if (response instanceof File) {
blob = response
} else if (response.data && response.data instanceof Blob) {
blob = response.data
} else {
// 尝试构造安全的blob
const safeData = Array.isArray(response) ? response : [response]
blob = new Blob(safeData, { type: "application/octet-stream" })
}
} catch (error) {
useMessage().error("文件数据格式错误")
return
}
// 3. 验证文件大小 (防止过大文件)
const MAX_FILE_SIZE = 100 * 1024 * 1024 // 100MB限制
if (blob.size > MAX_FILE_SIZE) {
useMessage().error("文件过大,无法下载")
return
}
// 4. 验证文件类型 (白名单)
const allowedTypes = [
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"text/plain",
"image/jpeg",
"image/png",
]
if (!allowedTypes.includes(blob.type) && blob.type !== "") {
useMessage().error("不支持的文件类型")
return
}
// 5. 安全的文件下载
const link = document.createElement("a")
link.href = window.URL.createObjectURL(blob)
link.download = fileName.replace(/[<>:"/\\|?*]/g, "_").substring(0, 255) // 文件名清理,移除危险字符
link.style.display = "none" // 隐藏链接
document.body.appendChild(link)
link.click()
window.setTimeout(function () {
// @ts-ignore
URL.revokeObjectURL(blob)
document.body.removeChild(link)
}, 0)
// 6. 安全的清理操作
setTimeout(() => {
try {
window.URL.revokeObjectURL(link.href)
document.body.removeChild(link)
} catch (error) {
// 静默处理清理错误
}
}, 10)
}
/**
+80 -80
View File
@@ -133,117 +133,117 @@
</template>
<script setup lang="ts" name="wx-material">
import {fetchAccountList} from '/@/api/mp/wx-account';
import {useMessage, useMessageBox} from '/@/hooks/message';
import {BasicTableProps, useTable} from '/@/hooks/table';
import {delObj, getMaterialOther, getMaterialVideo, getPage} from '/@/api/mp/wx-material';
import { fetchAccountList } from "/@/api/mp/wx-account"
import { useMessage, useMessageBox } from "/@/hooks/message"
import { BasicTableProps, useTable } from "/@/hooks/table"
import { delObj, getMaterialOther, getMaterialVideo, getPage } from "/@/api/mp/wx-material"
const QueryTree = defineAsyncComponent(() => import('/@/components/QueryTree/index.vue'));
const NewsForm = defineAsyncComponent(() => import('./components/news-form.vue'));
const WxFileUpload = defineAsyncComponent(() => import('/@/components/Wechat/fileUpload/index.vue'));
const WxNews = defineAsyncComponent(() => import('/@/components/Wechat/wx-news/index.vue'));
const QueryTree = defineAsyncComponent(() => import("/@/components/QueryTree/index.vue"))
const NewsForm = defineAsyncComponent(() => import("./components/news-form.vue"))
const WxFileUpload = defineAsyncComponent(() => import("/@/components/Wechat/fileUpload/index.vue"))
const WxNews = defineAsyncComponent(() => import("/@/components/Wechat/wx-news/index.vue"))
const deptData = reactive({
queryList: (name?: string) => {
return fetchAccountList({
name: name,
});
})
},
});
})
const checkAppId = ref();
const checkAppId = ref()
const uploadData = ref({
appId: '',
mediaType: 'image',
title: '',
introduction: '',
});
appId: "",
mediaType: "image",
title: "",
introduction: "",
})
const materialType = ref('image');
const materialType = ref("image")
// 点击树
const handleNodeClick = (data: any) => {
checkAppId.value = data.appid;
uploadData.value.appId = data.appid;
state.queryForm.appId = data.appid;
state.queryForm.type = materialType.value;
getDataList();
};
checkAppId.value = data.appid
uploadData.value.appId = data.appid
state.queryForm.appId = data.appid
state.queryForm.type = materialType.value
getDataList()
}
const handleClick = (tab) => {
if (checkAppId.value) {
// getPage(this.page)
} else {
useMessage().error('请选择公众号');
useMessage().error("请选择公众号")
}
materialType.value = tab.paneName;
uploadData.value.mediaType = tab.paneName;
state.queryForm.type = materialType.value;
getDataList();
};
materialType.value = tab.paneName
uploadData.value.mediaType = tab.paneName
state.queryForm.type = materialType.value
getDataList()
}
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {
appId: '',
type: '',
appId: "",
type: "",
},
pageList: getPage,
createdIsNeed: false,
props: {
item: 'items',
totalCount: 'totalCount',
item: "items",
totalCount: "totalCount",
},
});
})
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
const delMaterial = (item: any) => {
useMessageBox()
.confirm('此操作将永久删除该文件, 是否继续?')
.confirm("此操作将永久删除该文件, 是否继续?")
.then(() => {
delObj({
id: item.mediaId,
appId: checkAppId.value,
})
.then(() => {
getDataList();
getDataList()
})
.catch((err) => {
useMessage().error(err.msg);
});
});
};
useMessage().error(err.msg)
})
})
}
// 视频
const dialogVideoVisible = ref(false);
const dialogVideoVisible = ref(false)
const addMaterialLoading = ref(false);
const addMaterialLoading = ref(false)
const handleAddVideo = () => {
dialogVideoVisible.value = true;
};
dialogVideoVisible.value = true
}
const uploadRules = reactive({
title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
introduction: [{ required: true, message: '请输入描述', trigger: 'blur' }],
});
title: [{ required: true, message: "请输入标题", trigger: "blur" }],
introduction: [{ required: true, message: "请输入描述", trigger: "blur" }],
})
const uploadForm = ref();
const uploadForm = ref()
const uploadFileVideo = ref();
const uploadFileVideo = ref()
const subVideo = () => {
uploadForm.value.validate((valid: boolean) => {
if (!valid) {
return false;
return false
}
uploadFileVideo.value.submit().then(() => {
dialogVideoVisible.value = false;
});
});
};
dialogVideoVisible.value = false
})
})
}
const handleDown = (row: any) => {
getMaterialOther({
@@ -251,25 +251,25 @@ const handleDown = (row: any) => {
fileName: row.name,
appId: checkAppId.value,
}).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.style.display = 'none';
link.href = url;
link.setAttribute('download', row.name);
document.body.appendChild(link);
link.click();
});
};
const url = window.URL.createObjectURL(new Blob([response.data]))
const link = document.createElement("a")
link.style.display = "none"
link.href = url
link.setAttribute("download", row.name)
document.body.appendChild(link)
link.click()
})
}
// 图文
const dialogNewsRef = ref();
const dialogNewsRef = ref()
const handleAddNews = () => {
dialogNewsRef.value.openDialog({
accountId: checkAppId.value,
});
};
})
}
const handleEditNews = (item) => {
dialogNewsRef.value.openDialog(
@@ -278,9 +278,9 @@ const handleEditNews = (item) => {
},
JSON.parse(JSON.stringify(item.content.newsItem)),
item.mediaId,
'edit'
);
};
"edit",
)
}
const handleInfo = (row) => {
getMaterialVideo({
@@ -288,21 +288,21 @@ const handleInfo = (row) => {
appId: checkAppId.value,
})
.then((response) => {
const downUrl = response.data.downUrl;
window.open(downUrl, '_blank');
// const downUrl = response.data.downUrl
// window.open(downUrl, '_blank');
})
.catch((err) => {
useMessage().error(err.msg);
});
};
useMessage().error(err.msg)
})
}
// 默认选择第一个公众号
onMounted(async () => {
const { data } = await deptData.queryList();
if (data?.length > 0) {
handleNodeClick(data[0]);
}
});
const { data } = await deptData.queryList()
if (data?.length > 0) {
handleNodeClick(data[0])
}
})
</script>
<style lang="scss" scoped>