//0.自助建站的接口 start----------------------------------------> import { getSiteInfo, getSiteCategory, getFooterCategoryList} from '@/api/cms' import { getWebsiteintel, checkWebsiteBuild, getAdminSiteInfo, upWebsiteTemplateintel, getAllTemplateClass, getWebsiteTemplateList, chooseWebsiteTemplate, getWebsiteTemplateclassintel, saveWebsiteTemplate, getWebsiteTemplateInfo, getWebsiteTemplateData, getAdminWebsiteFootAll, addTwinAdPlace, getWebPageType, addWebPageType, checkWebsiteEdit, getWebsiteTemplate } from '@/api/template' //0.自助建站的接口 end----------------------------------------> //1.引入必备方法 start----------------------------------------> //导入Vue因为我们要进行深层次的json修改,必须调用Vue.Set,否则深拷贝的数据无法令视图更新 import { Message } from 'element-ui'; import Vue from 'vue'; //1.引入必备方法 end----------------------------------------> //2.引入随机模板json后期删除 start----------------------------------------> //首页 风格1 import randomIndex1 from '@/utils/templateJson/index/style1/1.js'; //首页 风格2 import randomIndex2 from '@/utils/templateJson/index/style1/2.js'; //2.引入随机模板json后期删除 end----------------------------------------> const state = { //0.全局配置 start------------------------------------------------------------> editWebsiteId: "",//网站id adKey: "",//网站缩写 editWebsiteClass: "",//网站风格 stepStatus: true,//是否显示现在进行到哪一步:true=显示 false=不显示 componentMenuStatus: 1,//组件菜单是否显示 1=显示 0=隐藏 //0.全局配置 end------------------------------------------------------------> //1.画布数据 start------------------------------------------------------------> pageStatus: 1,//当前编辑哪个页面 1=首页 2=分类页 3=列表页 4=详情页 5=搜索页 6=底部列表页 7=底部详情页 menuType: 1, //当前菜单显示板块还是组件 1=板块 2=组件 previewStatus: false,//是否预览 gridKey: 0,//使用gridKey来强制更新视图 loading: false,//是否显示加载中 showPage: { //哪些页面可以被展示 index: true, class: true, list: true, article: true, search: true, aloneList: true, aloneArticle: true }, pageData: { //自助建站拖拽板块的数据,注意,这里并不是提交到后台的数据 index: [],//首页 class: [],//分类页 list: [],//列表页 article: [],//详情页 search: [],//搜索页 aloneList: [],//自定义列表页 aloneArticle: [],//自定义详情页 }, editSectorY: 0,//当前组件在画布中的位置 mouseXY: {//鼠标位置 "x": 12, "y": 33 }, DragPos: {//创建的占位符大小 "x": null, "y": null, "w": 12, "h": 2, "i": null }, gridlayoutObj: null,//画布gridlayout对象 //1.画布数据 end------------------------------------------------------------> //2.全局模板数据 start------------------------------------------------------------> webSiteInfo: "",//网站信息 webSiteMenu: "",//网站包含的导航池 webSiteFooterInfo: "",//网站底部信息 area: {//地区 economize: [],//省区 market: [],//市区 county: []//县区 }, departmentList: [],//职能部门 //2.全局模板数据 end------------------------------------------------------------> //3.构造的模板json数据 start------------------------------------------------------------> pageDataStatus:{//页面数据完整度 index:{ sector:0,//当前板块数量,为0表示一个都没有 cid:0,//缺少的导航池id 为0表示没有缺少 ad:0,//缺少的广告名称,为0表示没有缺少 adPrice:0//缺少的广告价格,为0表示没有缺少 }, class:{ sector:0, cid:0, ad:0, adPrice:0 }, list:{ sector:0, cid:0, ad:0, adPrice:0 }, article:{ sector:0, cid:0, ad:0, adPrice:0 }, search:{ sector:0, cid:0, ad:0, adPrice:0 }, aloneList:{ sector:0, cid:0, ad:0, adPrice:0 }, aloneArticle:{ sector:0, cid:0, ad:0, adPrice:0 } }, ad_id: "",//生成储存的广告标识 pageName:{ //页面名称 1:"index", 2:"class", 3:"list", 4:"article", 5:"search", 6:"aloneList", 7:"aloneArticle" }, pageRoute:{ //数据路径 1:"state.pageData.index", 2:"state.pageData.class", 3:"state.pageData.list", 4:"state.pageData.article", 5:"state.pageData.search", 6:"state.pageData.aloneList", 7:"state.pageData.aloneArticle" }, editWindowStatus: false,//编辑组件弹出框是否显示 editComponentWindowStatus: false,//选择组件样式弹出框是否显示 editWebsiteTemplateJsonWindow: false,//当前准备提交的数据 后期删除 editWindowTitle: "",//编辑弹出框标题 editSectorId: 0,//当前正在编辑的板块id editDataSort: 0,//当前正在编辑的数据位置 editComponentSort: 0,//当前正在编辑的组件id editComponentType: 0,//当前正在编辑的组件类型 editComponentSize: 0,//当前组件文字新闻数量 editComponentSizeImg:0,//当前组件图片新闻数量 editComponentStyle: 0,//当前编辑的组件样式 editWebsiteCategory: [],//当前网站全部关联导航 webSiteData: { //1.base网站基本信息 base: { websiteId: "",//网站id }, //2.style信息 style: { styleId: "",//风格id }, //3.板块信息 header,menu,footer 是页面自带的无需构建 template: { //index = 首页 class=分类页 list=列表页 article=详情页 search=搜索页 aloneList=自定义列表页 aloneArticle=自定义详情页 index: [], class: [],//分类页 list: [],//列表页 article: [],//详情页 search: [],//搜索页 aloneList: [],//自定义列表页 aloneArticle: []//自定义详情页 }, //4.广告位 ad: { top:{ "width": 830,//宽度 "height": 110,//高度 "name": "",//广告名称 "price": 0,//价格 "introduce":"",//介绍 "website_id": "",//网站id "thumb": "https://img.bjzxtw.org.cn/pre/image/png/20250530/1748588901281358.png",//示例图 - 默认值 "typeid": 2,//广告类型 - 2 图片 "ad_tag": ""//广告标识 - 网站标识 + 页面名称 + sort }, index: [], class: [], list: [], article: [], search: [], aloneList: [], aloneArticle: [] } }, canSubmit: false,//当前数据是否可以被提交 //3.构造的模板json数据 end------------------------------------------------------------> //4.组件回显数据 start------------------------------------------------------------> componentViewData: { pid_arr: [],//导航池 pageSize: "",//展示文字新闻条数 pageSizeImg: "",//展示图片新闻条数 adName: "",//广告名称 titleName: "",//标题名称 windowKey:0,//级联选择器的key price:0//广告价格 } //4.组件回显数据 start------------------------------------------------------------> } const mutations = { //0.全局配置 start------------------------------------------------------------> //设置网站的id setEditWebsiteId(state, id) { state.editWebsiteId = id; }, //设置网站缩写 setAdKey(state, key) { state.adKey = key; }, //设置网站的风格 setClassNumber(state, id) { state.editWebsiteClass = id; }, //展示步骤 showStepStatus(state) { state.stepStatus = true; }, //隐藏步骤 hiddenStepStatus(state) { state.stepStatus = false; }, //设置步骤 setPageStatus(state, num) { state.pageStatus = num; }, //设置预览状态 setPreviewStatus(state) { state.previewStatus = !state.previewStatus; }, //打开编辑组件弹出框 setEditWindowStatus(state, data) { state.editWindowStatus = true; state.editSectorId = data.id; state.editSectorY = data.y; state.editDataSort = data.dataSort; state.editComponentSort = data.sort; state.editComponentType = data.type; state.editComponentSize = data.size; state.editComponentSizeImg = data.sizeImg; }, //更新编辑窗口中的数据 updateWindowData(state) { state.componentViewData.windowKey++; }, //关闭编辑组件弹出框 closeEditWindowStatus(state) { state.editWindowStatus = false; }, //打开选择组件样式弹出框 setComponentStyleStatus(state, data) { state.editComponentWindowStatus = true; state.editSectorId = data.id; state.editDataSort = data.dataSort; state.editComponentSort = data.sort; state.editComponentType = data.type; state.editComponentStyle = data.style; }, //关闭选择组件样式弹出框 closeComponentStyleStatus(state) { state.editComponentWindowStatus = false; }, //关闭提交数据弹出框 closeEditWebsiteTemplateJsonWindow(state) { state.editWebsiteTemplateJsonWindow = false; }, //选择组件样式 selectComponentStyleNumber(state, data) { state.editComponentStyle = data; }, //设置组件回显数据 setComponentViewData(state, data) { //获取当前页面名称 const currentPageName = state.pageName[state.pageStatus]; //如果页面名称不存在,直接返回 if (!currentPageName) {return;} //获取当前页面的数据 const currentPageData = state.pageData[currentPageName]; //找到要修改的板块 const targetModuleIndex = currentPageData.findIndex(module => module.i === data.id); //如果找不到目标模块,直接返回 if (targetModuleIndex === -1) {return;} //获取目标模块 const targetModule = currentPageData[targetModuleIndex]; //获取目标模块的组件类型 //判断组件类型 1=新闻 2=广告 if (state.editComponentType === 1) { // 新闻组件:设置导航id if (targetModule.content.componentList && targetModule.content.componentList[data.sort]) { const componentData = targetModule.content.componentList[data.sort].componentData; state.componentViewData.pid_arr = componentData.category_arr; state.componentViewData.pageSize = state.editComponentSize; state.componentViewData.pageSizeImg = state.editComponentSizeImg; } } else if (state.editComponentType === 2) { // 广告组件:设置广告名称和价格 if (targetModule.content.ad) { state.componentViewData.adName = targetModule.content.ad.name; state.componentViewData.price = targetModule.content.ad.price; } } }, //清空广告位 clearAd(state) { state.webSiteData.ad.index = []; state.webSiteData.ad.class = []; state.webSiteData.ad.list = []; state.webSiteData.ad.article = []; state.webSiteData.ad.search = []; state.webSiteData.ad.aloneList = []; state.webSiteData.ad.aloneArticle = []; }, //设置组件菜单是否显示 setComponentMenuStatus(state, data) { state.componentMenuStatus = data; }, //0.全局配置 start------------------------------------------------------------> //1.配置模块 start------------------------------------------------------------> //获得gridlayout对象 setGridlayoutObj(state, data) { state.gridlayoutObj = data; }, //添加板块 - 此代码无需优化,每个页面的规则都不一样 addModule(state, data) { //pageStatus==1 首页 index if (state.pageStatus == 1) { if (state.pageData.index.length >= 10) { Message.error('最多只能添加10个通栏!'); return; } else { this.commit('template/pushModule', data); } } //pageStatus==2 分类页 class if (state.pageStatus == 2) { if (state.pageData.class.length >= 10) { Message.error('最多只能添加10个通栏!'); return; } else { this.commit('template/pushModule', data); } } //pageStatus==3 列表页 list if (state.pageStatus == 3) { if (state.pageData.list.length >= 10) { Message.error('最多只能添加10个通栏!'); return; } else { this.commit('template/pushModule', data); } } //pageStatus==4 详情页 article if (state.pageStatus == 4) { if (state.pageData.article.length >= 10) { Message.error('最多只能添加10个通栏!'); return; } else { this.commit('template/pushModule', data); } } //pageStatus==5 搜索页 search if (state.pageStatus == 5) { if (state.pageData.search.length >= 10) { Message.error('最多只能添加10个通栏!'); return; } else { this.commit('template/pushModule', data); } } //pageStatus==6 自定义列表页 aloneList if (state.pageStatus == 6) { if (state.pageData.aloneList.length >= 10) { Message.error('最多只能添加10个通栏!'); return; } else { this.commit('template/pushModule', data); } } //pageStatus==7 自定义详情页 aloneArticle if (state.pageStatus == 7) { if (state.pageData.aloneArticle.length >= 10) { Message.error('最多只能添加10个通栏!'); return; } else { this.commit('template/pushModule', data); } } }, //该数据可以添加到画布 pushModule(state, data) { //获取当前页面名称 const currentPageName = state.pageName[state.pageStatus]; if (!currentPageName) { console.error('无效的页面状态:', state.pageStatus); return; } //获取当前页面数据 const currentPageData = state.pageData[currentPageName]; if (!currentPageData) { console.error('未找到页面数据:', currentPageName); return; } console.log(data.jsonData); console.log(`通过${data.source === 'click' ? '点击' : '拖拽'}添加一个板块`); //通过时间戳生成唯一id const currentTimestamp = Date.now(); const moduleId = currentTimestamp; //计算当前布局的最大 y 值 const maxY = Math.max(...currentPageData.map(item => item.y), 0); //设置数据在构建json中的位置 const dataSort = currentPageData.length; //根据source类型设置y坐标 const yPosition = data.source === 'click' ? maxY + 1 : data.y; // 创建新模块 const newModule = { i: moduleId, x: 0, y: yPosition, w: 12, h: data.h, type: data.type, content: data.jsonData, dataSort: dataSort, }; //添加模块到当前页面数据 currentPageData.push(newModule); console.log(`当前添加模块的dataSort为:${dataSort}`); console.log('当前的页面构建数据:', currentPageData); //拖拽特殊处理 if (data.source === 'drag') { // 调用gridlayout的拖拽结束事件 state.gridlayoutObj.dragEvent('dragend', data.i, data.x, data.y, 1, 1); // 尝试显示占位符 try { const targetIndex = currentPageData.length; if (state.gridlayoutObj.$children && state.gridlayoutObj.$children[targetIndex] && state.gridlayoutObj.$children[targetIndex].$refs && state.gridlayoutObj.$children[targetIndex].$refs.item) { state.gridlayoutObj.$children[targetIndex].$refs.item.style.display = "block"; } } catch (error) { console.log("没有找到占位符:", error); } } }, //删除板块 deleteModule(state, data) { //data.i = id //data.dataSort = dataSort try { // 获取当前页面名称 const currentPageName = state.pageName[state.pageStatus]; if (!currentPageName) { Message.warning('无效的页面状态!'); return; } // 获取当前页面的数据数组 const currentPageData = state.pageData[currentPageName]; if (!currentPageData) { Message.warning('未找到页面数据!'); return; } //找到要删除的模块 const indexToRemove = currentPageData.findIndex(item => item.i === data.i); if (indexToRemove === -1) { Message.warning('未找到要删除的模块!'); return; } //创建新的数组,不包含要删除的模块 const newModules = currentPageData.filter(item => item.i !== data.i); //重新计算所有模块的 dataSort newModules.forEach((module, index) => { module.dataSort = index; }); //使用 Vue.set 更新整个数组 Vue.set(state.pageData, currentPageName, newModules); //清理 $children 数组 if (state.gridlayoutObj && state.gridlayoutObj.$children) { //清空$children 数组 state.gridlayoutObj.$children.length = 0; //强制重新渲染 state.gridKey += 1; //等待 DOM 更新后重新设置gridlayout对象 Vue.nextTick(() => { //通知父组件重新设置gridlayout对象 //这里可以通过事件总线或其他方式通知 if (state.gridlayoutObj && state.gridlayoutObj.$parent) { //尝试重新获取gridlayout对象 const newGridLayout = state.gridlayoutObj.$parent.$refs.gridlayout; if (newGridLayout) { state.gridlayoutObj = newGridLayout; } } }); } Message.success('模块已删除!'); console.log(`模块已删除,当前${currentPageName}页面的构建数据为:`, newModules); } catch (error) { console.error('删除模块时发生错误:', error); Message.error('删除模块时发生错误,请重试!'); } }, //设置组件样式 setComponentStyleNumber(state, data) { const id = state.editSectorId; const dataSort = state.editDataSort; const sort = state.editComponentSort; const num = state.editComponentStyle; console.log(id, dataSort, sort, num); //获取当前页面名称 const currentPageName = state.pageName[state.pageStatus]; if (!currentPageName) { console.error('无效的页面状态:', state.pageStatus); return; } //获取当前页面的数据数组 const currentPageData = state.pageData[currentPageName]; if (!currentPageData || !currentPageData[dataSort]) { console.error('未找到页面数据:', currentPageName, dataSort); return; } //获取当前模块数据并进行深拷贝 const module = JSON.parse(JSON.stringify(currentPageData[dataSort])); //确保修改属性时 Vue 能监控到变化 Vue.set(module.content.componentList, sort, { ...module.content.componentList[sort], component_style: num }); //使用Vue.set来强制视图更新 Vue.set(currentPageData, dataSort, module); console.log(`当前${currentPageName}页面的板块数据为:`); console.log(currentPageData); }, //保存全局广告的数据 saveAdData(state, data) { state.webSiteData.ad.top.name = data.data.name; state.webSiteData.ad.top.introduce = data.data.introduce; state.webSiteData.ad.top.price = data.data.price; }, //保存组件设置的数据 saveComponentData(state, data) { //传入的板块id console.log("当前编辑板块:" + data.id); //获取当前页面名称 const currentPageName = state.pageName[state.pageStatus]; if (!currentPageName) { console.error('无效的页面状态:', state.pageStatus); return; } //获取当前页面的数据数组 const currentPageData = state.pageData[currentPageName]; if (!currentPageData) { console.error('未找到页面数据:', currentPageName); return; } //找到要修改的板块 const targetModuleIndex = currentPageData.findIndex(module => module.i === data.id); if (targetModuleIndex === -1) { console.error('未找到要修改的模块:', data.id); return; } console.log("要修改的模块索引:", targetModuleIndex); console.log("组件排序:", data.sort); //组件类型 1=新闻 2=广告 //注意:Vue有一个特性,当修改复杂对象内部数组时,可能无法检测到变化 //解决办法是通过Vue.set方法将整个对象进行深拷贝,然后修改完再替换回去 // 获取当前模块数据并进行深拷贝 let module = JSON.parse(JSON.stringify(currentPageData[targetModuleIndex])); if (state.editComponentType === 1) { //1=新闻组件 const componentData = module.content.componentList[data.sort].componentData; componentData.category_id = data.data.pid_id; // 设置 category_id componentData.category_arr = data.data.pid_arr; // 设置 category_arr 用于显示 componentData.name = data.data.name; // 设置导航池名字 componentData.textSize = state.editComponentSize; // 设置文字新闻数量 componentData.imgSize = state.editComponentSizeImg; // 设置图片新闻数量 } else if (state.editComponentType === 2) { //2=广告组件 module.content.ad.name = data.data.adName; module.content.ad.introduce = data.data.adName; module.content.ad.price = data.data.price; //设置用于回显的广告名,否则会导致回显的广告名和实际的广告名不一致 //因为广告名没有默认值,这会导致watch监听不到,所以这里需要手动设置 state.componentViewData.adName = data.data.adName; } // 使用Vue.set来强制视图更新 Vue.set(currentPageData, targetModuleIndex, module); console.log(`当前${currentPageName}页面的板块数据为:`); console.log(currentPageData); }, //从外部拖拽板块 drag(state, data) { //获取当前页面名称 const currentPageName = state.pageName[state.pageStatus]; if (!currentPageName) { console.error('无效的页面状态:', state.pageStatus); return; } //获取当前页面的数据 const currentPageData = state.pageData[currentPageName]; if (!currentPageData) { console.error('未找到页面数据:', currentPageName); return; } //获取画布尺寸并判断鼠标是否在画布内 let parentRect = document.getElementById('content').getBoundingClientRect(); let mouseInGrid = false; if (((state.mouseXY.x > parentRect.left) && (state.mouseXY.x < parentRect.right)) && ((state.mouseXY.y > parentRect.top) && (state.mouseXY.y < parentRect.bottom))) { mouseInGrid = true; } //如果没有占位符就创建一个 if (mouseInGrid === true && (currentPageData.findIndex(item => item.i === 'drop')) === -1) { currentPageData.push({ x: (currentPageData.length * 2) % (this.colNum || 12), y: currentPageData.length + (this.colNum || 12), w: 12, h: 2, i: 'drop', }); } //如果已经存在占位符 let index = currentPageData.findIndex(item => item.i === 'drop'); if (index !== -1) { try { console.log(`当前 ${currentPageName} 页面数据长度:`, currentPageData.length); console.log('当前 gridlayoutObj.$children.length:', state.gridlayoutObj.$children.length); //计算目标索引 const targetIndex = currentPageData.length; console.log('尝试隐藏的索引:', targetIndex); //安全访问并隐藏占位符 if (state.gridlayoutObj.$children && targetIndex >= 0 && targetIndex < state.gridlayoutObj.$children.length && state.gridlayoutObj.$children[targetIndex] && state.gridlayoutObj.$children[targetIndex].$refs && state.gridlayoutObj.$children[targetIndex].$refs.item) { //调试信息:确认要隐藏的是drop元素 const targetChild = state.gridlayoutObj.$children[targetIndex]; console.log('要隐藏的元素ID:', targetChild.i || (targetChild.$props && targetChild.$props.i)); state.gridlayoutObj.$children[targetIndex].$refs.item.style.display = "none"; console.log('成功隐藏占位符,索引:', targetIndex); } else { console.log('无法安全访问占位符,索引:', targetIndex); } } catch (error) { console.log('处理占位符时出错:', error); } //拖拽逻辑处理 if (state.gridlayoutObj.$children[index]) { let el = state.gridlayoutObj.$children[index]; el.dragging = { "top": state.mouseXY.y - parentRect.top, "left": state.mouseXY.x - parentRect.left }; let new_pos = el.calcXY(state.mouseXY.y - parentRect.top, state.mouseXY.x - parentRect.left); if (mouseInGrid === true) { state.gridlayoutObj.dragEvent('dragstart', 'drop', new_pos.x, new_pos.y, 2, 12); state.DragPos.i = String(index); state.DragPos.x = currentPageData[index].x; state.DragPos.y = currentPageData[index].y; } if (mouseInGrid === false) { state.gridlayoutObj.dragEvent('dragend', 'drop', new_pos.x, new_pos.y, 2, 12); // 使用 Vue.set 确保响应式更新 Vue.set(state.pageData, currentPageName, currentPageData.filter(obj => obj.i !== 'drop')); } } else { console.log('无法找到拖拽元素,索引:', index); } } }, //拖拽结束 定位落点 dragend(state, data) { //获取当前页面名称 const currentPageName = state.pageName[state.pageStatus]; if (!currentPageName) { console.error('无效的页面状态:', state.pageStatus); return; } //获取画布尺寸 let parentRect = document.getElementById('content').getBoundingClientRect(); //判断是否在画布内 let mouseInGrid = false; if (((state.mouseXY.x > parentRect.left) && (state.mouseXY.x < parentRect.right)) && ((state.mouseXY.y > parentRect.top) && (state.mouseXY.y < parentRect.bottom))) { mouseInGrid = true; } //如果在画布内,开始创建元素 if (mouseInGrid === true) { //alert(`Dropped element props:\n${JSON.stringify(state.DragPos, ['x', 'y', 'w', 'h'], 2)}`); state.gridlayoutObj.dragEvent('dragend', 'drop', state.DragPos.x, state.DragPos.y, 1, 1); //动态过滤当前页面的 drop 元素 state.pageData[currentPageName] = state.pageData[currentPageName].filter(obj => obj.i !== 'drop'); let sendData = { source: "drag",//添加时判断此模块来自外部拖拽,而不是点击 type: data.type, h: data.h, jsonData: data.jsonData, x: state.DragPos.x, y: state.DragPos.y, w: 12, } //调用 addModule 来添加模块 this.commit('template/addModule', sendData); } }, //格式化模板信息 formatTemplateInfo(state, data) { //1.处理广告位 //先把广告位的数据清空,再重新获取 //this.commit('template/clearAd'); // 深拷贝数据,避免直接修改原数据 let clonedData = JSON.parse(JSON.stringify(data)); // 按照 clonedData.data.y 的大小排序 clonedData.data.sort((a, b) => a.y - b.y); //获取当前页面名称 let getPageName = () =>{ if(state.pageStatus==1){return "index";} if(state.pageStatus==2){return "category";} if(state.pageStatus==3){return "list";} if(state.pageStatus==4){return "detail";} if(state.pageStatus==5){return "search";} if(state.pageStatus==6){return "page";} if(state.pageStatus==7){return "page";} } // 取出每个通栏中的广告,并保存到state.webSiteData.ad中 for (let index in clonedData.data) { if(clonedData.data[index].content.ad){ let ad_index = Number(index)+1; let ad_tag = `${state.adKey}_${data.type}_${ad_index}`; clonedData.data[index].content.ad.website_id = state.editWebsiteId; clonedData.data[index].content.ad.ad_tag = ad_tag; state.webSiteData.ad[data.type].push(clonedData.data[index].content.ad); } } //设置全局的广告位名称 state.webSiteData.ad.top.website_id = state.editWebsiteId; state.webSiteData.ad.top.ad_tag = `${state.adKey}_top` let websiteData = []; // 获取板块的 sort for (let index = 0; index < clonedData.data.length; index++) { console.log(clonedData.data[index].content); // 使用 Vue.set 来确保属性变更能被 Vue 追踪 Vue.set(clonedData.data[index].content, 'sort', Number(index) + 1); websiteData.push(clonedData.data[index].content); } // 保存到对应的页面 json 中 if (data.type == "index") {state.webSiteData.template.index = websiteData;} if (data.type == "class") {state.webSiteData.template.class = websiteData;} if (data.type == "list") {state.webSiteData.template.list = websiteData;} if (data.type == "article") {state.webSiteData.template.article = websiteData;} if (data.type == "search") {state.webSiteData.template.search = websiteData;} if (data.type == "aloneList") {state.webSiteData.template.aloneList = websiteData;} if (data.type == "aloneArticle") {state.webSiteData.template.aloneArticle = websiteData;} }, //保存模板 saveTemplate(state) { //1.保存网站id和模板风格id state.webSiteData.base.websiteId = state.editWebsiteId; state.webSiteData.style.styleId = state.editWebsiteClass; //2.格式化数据 //2.1 清理广告位数据 this.commit('template/clearAd'); //2.2 格式化index页面数据 this.commit('template/formatTemplateInfo', { data: state.pageData.index, type: "index" }); //2.2 格式化class页面数据 this.commit('template/formatTemplateInfo', { data: state.pageData.class, type: "class" }); //2.3 格式化list的信息 this.commit('template/formatTemplateInfo', { data: state.pageData.list, type: "list" }); //2.4 格式化article的信息 this.commit('template/formatTemplateInfo', { data: state.pageData.article, type: "article" }); //2.5 格式化search的信息 this.commit('template/formatTemplateInfo', { data: state.pageData.search, type: "search" }); //2.6 格式化aloneList的信息 this.commit('template/formatTemplateInfo', { data: state.pageData.aloneList, type: "aloneList" }); //2.7 格式化aloneArticle的信息 this.commit('template/formatTemplateInfo', { data: state.pageData.aloneArticle, type: "aloneArticle" }); //3.展示构造json 后期移除 state.editWebsiteTemplateJsonWindow = true; //4.检测模板数据完整度,如果不完整阻止用户保存 this.commit('template/pageCheck', {data: state.pageData}); }, //检测模板完整度 pageCheck(state, data) { // 遍历所有页面进行检测 Object.values(state.pageName).forEach(pageName => { // 获得当前页面板块数量 state.pageDataStatus[pageName].sector = data.data[pageName].length; // 获得当前页面没有设置导航池的板块数量 - 只检查首页 let noCid = 0; if (pageName === 'index') { for(let index in data.data[pageName]){ for(let i in data.data[pageName][index].content.componentList){ if(data.data[pageName][index].content.componentList[i].componentData.category_id != undefined){ if(data.data[pageName][index].content.componentList[i].componentData.category_id == ""){ noCid++; } } } } } state.pageDataStatus[pageName].cid = noCid; // 获得当前页面没有设置广告名称的组件数量 let noAd = 0; for(let index in data.data[pageName]){ if(data.data[pageName][index].content.ad != undefined){ if(data.data[pageName][index].content.ad.name == ""){ noAd++; } } } state.pageDataStatus[pageName].ad = noAd; // 获得当前页面没有设置广告价格的组件数量 let noAdPrice = 0; for(let index in data.data[pageName]){ if(data.data[pageName][index].content.ad != undefined){ if(data.data[pageName][index].content.ad.price == 0){ noAdPrice++; } } } state.pageDataStatus[pageName].adPrice = noAdPrice; }); // 全局广告特殊处理(只处理一次) 全局广告是算到首页里面的 if(state.webSiteData.ad.top.name == ""){ state.pageDataStatus.index.ad++; } if(state.webSiteData.ad.top.price == 0){ state.pageDataStatus.index.adPrice++; } }, //清理画布内容 clearWebsiteTemplate(state,data){ //每次进入的时候先清理再回显 //清理state.webSiteData Vue.set(state.webSiteData, 'template', { index: [], class: [], list: [], article: [], search: [], aloneList: [], aloneArticle: [] }); Vue.set(state, 'pageData', { index: [], class: [], list: [], article: [], search: [], aloneList: [], aloneArticle: [] }); Vue.set(state.webSiteData.ad, 'top', { "width": 830,//宽度 "height": 110,//高度 "name": "",//广告名称 "price": 0,//价格 "introduce":"",//介绍 "website_id": "",//网站id "thumb": "https://img.bjzxtw.org.cn/pre/image/png/20250530/1748588901281358.png",//示例图 - 默认值 "typeid": 2,//广告类型 - 2 图片 "ad_tag": ""//广告标识 - 网站标识 + 页面名称 + sort }); Vue.set(state, 'pageStatus', 1); }, //回显模板内容 setWebsiteTemplate(state, data) { if(data==null){ this.commit('template/clearWebsiteTemplate'); console.log("第一次添加模板,无需回显!") }else{ this.commit('template/clearWebsiteTemplate'); console.log("编辑模板,开始回显模板内容!") console.log(data) state.webSiteData.ad.top = data.topAd; state.pageData = data.template; } }, //随机生成模板 randomTemplate(state) { state.loading = true; const randomIndex = Math.floor(Math.random() * 2); console.log(`随机生成的数字是: ${randomIndex}`); // pageStatus == 1 首页 if (state.pageStatus == 1) { // 先清空里面的内容 Vue.set(state.pageData, 'index', []); // 深拷贝 randomIndex1 和 randomIndex2 const newData1 = JSON.parse(JSON.stringify(randomIndex1)); const newData2 = JSON.parse(JSON.stringify(randomIndex2)); if (randomIndex == 0) { Vue.set(state.pageData, 'index', newData1); } if (randomIndex == 1) { Vue.set(state.pageData, 'index', newData2); } state.loading = false; } // pageStatus == 2 分类页 if (state.pageStatus == 2) { } // pageStatus == 3 列表页 if (state.pageStatus == 3) { } // pageStatus == 4 详情页 if (state.pageStatus == 4) { } // pageStatus == 5 搜索页 if (state.pageStatus == 5) { } // pageStatus == 6 自定义列表页 if (state.pageStatus == 6) { } // pageStatus == 7 自定义详情页 if (state.pageStatus == 7) { } }, //1.配置模块 end------------------------------------------------------------> //2.获取站点信息 start------------------------------------------------------------> //获取站点顶部详情 setWebsiteInfo(state, data) { state.webSiteInfo = data; }, setWebsiteFooterInfo(state, data) { state.webSiteFooterInfo = data; }, //获取站点导航池 setGetSiteCategory(state, data) { let allData = [] for (let index in data) { //导航最多只显示24个,超出部分不显示 if (index < 24) { allData.push(data[index]) } } state.webSiteMenu = allData; }, //设置地区 setArea(state, data) { //都没有的时候返回的是省 if (data.province == undefined) { state.area.economize = data; } //没有region的时候返回的是市 if (data.province != undefined && data.city != undefined && data.region == undefined) { state.area.market = data.city; } //有region的时候返回的是县 if (data.province != undefined && data.city != undefined && data.region != undefined) { state.area.county = data.region; } }, //设置职能 setDepartment(state, data) { for (let item of data) { let options = { value: item.id, label: item.name } state.departmentList.push(options) } console.log(state.departmentList) }, //获取全部导航 setWebsiteCategory(state, data) { let arrayData = [] for (let item of data) { let options = { key: item.id, label: item.name, value: item.id } arrayData.push(options); } state.editWebsiteCategory = arrayData; }, //2.获取站点信息 end------------------------------------------------------------> //3.提示信息 start------------------------------------------------------------> alertMessage(state, data) { Message({ message: "配置阶段仅展示,无法真实调用该功能!", type: 'warning', duration: 0, showClose: true }); } //3.提示信息 end------------------------------------------------------------> } const actions = { //1.显示画板组件数据 start------------------------------------------------------------> //1.1 获取网站基本信息 getSiteInfo({ commit }, data) { return new Promise((resolve, reject) => { getSiteInfo(data).then(response => { commit('setWebsiteInfo', response.data); resolve(response) }).catch(error => { reject(error) }) }) }, //1.2 获取网站导航池 getSiteCategory({ commit }, data) { return new Promise((resolve, reject) => { getSiteCategory(data).then(response => { commit('setGetSiteCategory', response.data); resolve(response) }).catch(error => { reject(error) }) }) }, //1.3 获取网站底部导航 getFooterCategoryList({ commit }, data) { return new Promise((resolve, reject) => { getFooterCategoryList(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //1.4 获得页面类型 getWebPageType({ commit }, data) { return new Promise((resolve, reject) => { getWebPageType(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //1.5 选择页面类型 - 是否添加搜索页 addWebPageType({ commit }, data) { return new Promise((resolve, reject) => { addWebPageType(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //1.显示画板组件数据 end------------------------------------------------------------> //2.构建网站json start------------------------------------------------------------> //2.1 搜索网站 getWebsiteintel({ commit }, data) { return new Promise((resolve, reject) => { getWebsiteintel(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //2.2 添加网站基本信息 如果只传入website_id,则验证是否已经关联导航池 checkWebsiteBuild({ commit }, data) { return new Promise((resolve, reject) => { checkWebsiteBuild(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //2.3 获取网站基本信息 getAdminSiteInfo({ commit }, data) { return new Promise((resolve, reject) => { getAdminSiteInfo(data).then(response => { commit('setWebsiteInfo', response.data); commit('setAdKey', response.data.ad_key); resolve(response) }).catch(error => { reject(error) }) }) }, //2.4 修改网站基本信息 upWebsiteTemplateintel({ commit }, data) { return new Promise((resolve, reject) => { upWebsiteTemplateintel(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //2.5 获取所有风格 getAllTemplateClass({ commit }, data) { return new Promise((resolve, reject) => { getAllTemplateClass(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //2.6 搜索并获取所有网站风格 getWebsiteTemplateList({ commit }, data) { return new Promise((resolve, reject) => { getWebsiteTemplateList(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //2.7 保存用户选择的风格 chooseWebsiteTemplate({ commit }, data) { return new Promise((resolve, reject) => { chooseWebsiteTemplate(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //2.8 获取用户选择的风格 getWebsiteTemplateclassintel({ commit }, data) { return new Promise((resolve, reject) => { getWebsiteTemplateclassintel(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //2.9 保存模板 saveWebsiteTemplate({ commit }, data) { return new Promise((resolve, reject) => { saveWebsiteTemplate(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //2.10 获取模板配置 getWebsiteTemplateInfo({ commit }, data) { return new Promise((resolve, reject) => { getWebsiteTemplateInfo(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //2.11 预览模板信息 getWebsiteTemplateData({ commit }, data) { return new Promise((resolve, reject) => { getWebsiteTemplateData(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //2.12 获得网站底部信息 getAdminWebsiteFootAll({ commit }, data) { return new Promise((resolve, reject) => { getAdminWebsiteFootAll(data).then(response => { commit('setWebsiteFooterInfo', response.data); resolve(response) }).catch(error => { reject(error) }) }) }, //2.13 批量创建广告位 addTwinAdPlace({ commit }, data) { return new Promise((resolve, reject) => { addTwinAdPlace(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //2.14 验证该网站是否有未结束的订单 checkWebsiteEdit({ commit }, data) { return new Promise((resolve, reject) => { checkWebsiteEdit(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) }, //2.15 回显模板 getWebsiteTemplate({ commit }, data) { return new Promise((resolve, reject) => { getWebsiteTemplate(data).then(response => { resolve(response) }).catch(error => { reject(error) }) }) } //2.构建网站json end------------------------------------------------------------> } export default { namespaced: true, state, mutations, actions }