plateDetail.vue 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180
  1. <template>
  2. <div class="mainBox">
  3. <div class="layerBox">
  4. <tableTitle :name="tableDivTitle" />
  5. <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="170px" class="demo-ruleForm">
  6. <div class="dialogText">
  7. <el-form-item label="通栏名称:" prop="sectorName">
  8. <el-input v-model="ruleForm.sectorName" placeholder="输入通栏名称"></el-input>
  9. </el-form-item>
  10. <el-form-item label="通栏编号:" prop="sectorId">
  11. <el-input v-model="ruleForm.sectorId" placeholder="输入通栏编号"></el-input>
  12. </el-form-item>
  13. <el-form-item label="所属皮肤:" prop="templateStyle">
  14. <el-select v-model="ruleForm.templateStyle" placeholder="请选择所属皮肤">
  15. <el-option v-for="item in template_options" :key="item.template_id"
  16. :label="item.template_name" :value="item.template_id">
  17. </el-option>
  18. </el-select>
  19. </el-form-item>
  20. <el-form-item label="皮肤id:" prop="templateStyle">
  21. <el-input v-model="ruleForm.templateStyle" placeholder="所属皮肤id"
  22. disabled></el-input>
  23. </el-form-item>
  24. <el-form-item label="通栏关键词:" prop="sectorKeyword" class="custom-align-right">
  25. <template #label>
  26. <span class="askBox">
  27. 通栏关键词:
  28. <el-tooltip class="item" effect="dark" content="皮肤关键词,如:黑色、卡通、英雄。" placement="top">
  29. <i class="el-icon-question"></i>
  30. </el-tooltip>
  31. </span>
  32. </template>
  33. <tagInput :initialTags="tags" @tags-updated="updateTags"></tagInput>
  34. </el-form-item>
  35. <el-form-item label="通栏类别:" prop="sectorType">
  36. <el-select v-model="ruleForm.sectorType" placeholder="请选择通栏类别" :disabled="this.dialogName === '编辑'">
  37. <!-- 通栏分类:1:资讯类:2:通栏广告类;3:混合类;4:搜索框类;5:导航类;6:头条类;7:轮播图类; -->
  38. <el-option v-for="item in this.typeList" :label="item.label" :value="item.value" :key="item.value">{{item.label}}</el-option>
  39. </el-select>
  40. </el-form-item>
  41. <el-form-item label="页面类型:" prop="pageType">
  42. <el-checkbox-group v-model="ruleForm.pageType" @change="changeCheckbox"
  43. :disabled="this.dialogName === '编辑'">
  44. <el-checkbox v-for="(item, index) in checkList" :key="index" :label="item.value">{{item.label}}</el-checkbox>
  45. </el-checkbox-group>
  46. </el-form-item>
  47. <el-form-item label="通栏缩略图:" prop="image" :label-width="formLabelWidth"
  48. :class="['custom-form-item']" class="custom-align-right">
  49. <div class="uploaderBox">
  50. <!--图片上传组件 start ------------------------------------------------------------>
  51. <div class="avatar-upload-container" @mouseenter="hovering = true"
  52. @mouseleave="hovering = false">
  53. <!-- 上传组件 -->
  54. <el-upload class="avatar-uploader" action="#" :show-file-list="false"
  55. :before-upload="beforeAvatarUpload">
  56. <!-- 预览图片 -->
  57. <img v-if="this.logoUrl" :src="this.logoUrl" class="avatar">
  58. <!-- 上传图标 -->
  59. <div v-else class="chooseImgDiv">
  60. <div>
  61. <img src="@/assets/public/upload/noImage.png">
  62. <div>选择图片</div>
  63. </div>
  64. </div>
  65. <input type="hidden" name="logo" v-model="ruleForm.image">
  66. </el-upload>
  67. <!-- 删除按钮,当鼠标悬浮时显示 -->
  68. <div v-if="hovering && logoUrl" class="delete-button" @click="handleDelete">
  69. <i class="el-icon-delete"></i>
  70. </div>
  71. </div>
  72. <!--图片上传组件 end ------------------------------------------------------------>
  73. </div>
  74. </el-form-item>
  75. <el-form-item label="组件数量:" prop="component_num">
  76. <el-input v-model.number="ruleForm.component_num" id="component_num" placeholder="输入组件数量" type="number"
  77. min="1" @change="getPlaceList(ruleForm.component_num)">
  78. </el-input>
  79. </el-form-item>
  80. <el-form-item label="通栏模版类型:" prop="sectorPlace">
  81. <el-select v-model="ruleForm.sectorPlace" placeholder="请选择通栏模版类型" @change="changeStyleSort">
  82. <el-option v-for="item in sectorPlace_options" :key="item.sector_type" :label="item.name+'('+item.width+'*'+item.height+')'" :value="item.sector_type">{{item.name+'('+item.width+'*'+item.height+')'}}
  83. </el-option>
  84. </el-select>
  85. </el-form-item>
  86. <el-form-item label="尺寸:" prop="sizeList" v-if="this.ruleForm.sectorPlace != ''">
  87. <p style="margin-top: 0px;">{{ruleForm.sizeList}}</p>
  88. </el-form-item>
  89. <el-form-item label="通栏版式预览图:" prop="sector_img" v-if="this.ruleForm.sectorPlace != ''">
  90. <img :src="ruleForm.sector_img" alt="" width="300px" height="150px">
  91. </el-form-item>
  92. <div class="boxes-container" v-if="this.ruleForm.sizeList != '' && this.ruleForm.sectorPlace">
  93. <el-row class="layout-3" >
  94. <el-row v-if="checkPlace" style="width: 100%;height: 100%;">
  95. <el-col v-for="(col,index) in JSON.parse(checkPlace.map)" :key="index" :style="{width:col.col_data.col_width,height:'100%',marginRight:'1.2%'}">
  96. <el-row class="box" v-for="(row,rowIndex) in col.col_data.row_data" :key="rowIndex" :style="{height:row.row_height,width:'100%',marginBottom:'2.35%'}">
  97. {{ component_option.find(item => item.sort_id == row.component_sort) ? `位置${component_option.find(item => item.sort_id == row.component_sort).sort_id}
  98. (${component_option.find(item => item.sort_id == row.component_sort).width}*${component_option.find(item => item.sort_id == row.component_sort).height})` : '' }}
  99. </el-row>
  100. </el-col>
  101. </el-row>
  102. </el-row>
  103. </div>
  104. <div v-for="(item, index) in component_option" :key="index" class="componentChoose">
  105. <el-form-item :label="item.name+':'" :prop="`${index}`" class="componentOptions">
  106. <el-select v-model="ruleForm.component_code[index]" multiple clearable placeholder="请选择组件" class="componentOption_one">
  107. <el-option v-for="(compItem,comIndex) in item.component" :key="compItem.component_type" :label="compItem.component_name" :value="compItem.component_type">
  108. {{ compItem.component_name }}
  109. </el-option>
  110. </el-select>
  111. </el-form-item>
  112. </div>
  113. </div>
  114. <div class="dialogBtn">
  115. <el-button type="info" @click="cancelForm">取消</el-button>
  116. <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
  117. </div>
  118. </el-form>
  119. </div>
  120. </div>
  121. </template>
  122. <script>
  123. //表格标题
  124. import tableTitle from './components/tableTitle.vue';
  125. import tagInput from '../../components/InputTag/index.vue';
  126. //引入公用样式
  127. import '@/styles/global.less';
  128. // import { getSectorList, addSector, delSector, updateSector, getSectorInfo } from '@/api/plate'
  129. // import { getTemplateClass } from '@/api/style'
  130. export default {
  131. components: {
  132. tableTitle,//表格标题-
  133. tagInput
  134. },
  135. data() {
  136. const validateEmpty = (rule, value, callback) => {
  137. if (value.length == 0) {
  138. callback(new Error('该项不能为空!'))
  139. } else {
  140. callback()
  141. }
  142. }
  143. const validateArray = (rule, value, callback) => {
  144. if (value.length == 0) {
  145. callback(new Error('该项不能为空!'))
  146. } else {
  147. callback()
  148. }
  149. }
  150. return {
  151. // 0.0画布及多选组件输入框相关----------start
  152. component : true, //验证组件是否有空数组
  153. name: '编辑', //备份dialogName来判断是否执行添加和编辑的异步
  154. tableData: [{}], // 添加空数据使表格正常显示
  155. // 初始化时设置默认值为 1,确保有初始布局
  156. component_num: 1,
  157. activeBoxes: [false], // 初始化激活状态数组
  158. selectedComponents: { 0: [] }, // 初始化组件选择对象
  159. // 0.0画布及多选组件输入框相关----------end
  160. //1.1 初始化信息
  161. tableDivTitle: "通栏列表", //列表标题
  162. dialogTableVisible: false, //编辑弹框
  163. dialogName: '编辑', //编辑弹窗名称
  164. plateLoading: true, //表格内容加载中
  165. tableData: [],//表格数据
  166. class_options: [],//风格下拉列表
  167. template_options: [],//皮肤下拉列表
  168. // componen_code: [],//组件版式及组件下拉列表
  169. sectorPlace_options: [],//通栏模版类型下拉列表
  170. component_option: [],
  171. tags: [],//标签数据
  172. templateStyle: '',//风格
  173. plateName: '',
  174. pageType: '',//页面类型
  175. value: '',
  176. checkList: [
  177. {
  178. value: 1,
  179. label: '首页',
  180. },
  181. {
  182. value: 2,
  183. label: '分类页',
  184. },
  185. {
  186. value: 3,
  187. label: '列表页',
  188. },
  189. {
  190. value: 4,
  191. label: '详情页',
  192. },
  193. {
  194. value: 5,
  195. label: '搜索页',
  196. },
  197. {
  198. value: 6,
  199. label: '单页(列表)',
  200. },
  201. {
  202. value: 7,
  203. label: '单页(详情)',
  204. },
  205. ],
  206. typeList: [
  207. {
  208. value: 1,
  209. label: '资讯类',
  210. },
  211. {
  212. value: 2,
  213. label: '广告类',
  214. },
  215. {
  216. value: 3,
  217. label: '混合类',
  218. },
  219. {
  220. value: 4,
  221. label: '搜索框类',
  222. },
  223. {
  224. value: 5,
  225. label: '导航类',
  226. },
  227. {
  228. value: 6,
  229. label: '头条类',
  230. },
  231. {
  232. value: 7,
  233. label: '轮播图类',
  234. },
  235. {
  236. value: 8,
  237. label: '静态资源类',
  238. },
  239. {
  240. value: 9,
  241. label: '底部导航(列表)类',
  242. },
  243. {
  244. value: 10,
  245. label: '底部导航(详情)类',
  246. },
  247. ],
  248. //活动id
  249. activeid: "",
  250. newArr: [],
  251. // 1.3 分页相关
  252. page: 1,
  253. pageSize: 10,
  254. total: 0,
  255. formLabelWidth: '', //广告示例图相关
  256. //1.4 弹框相关数据
  257. ruleForm: {
  258. sectorName: '', //通栏名称
  259. sectorPlace: null, //通栏模版类型
  260. component_num: null, //组件数量
  261. sectorId: null, //通栏编号id
  262. templateStyle: '', //所属皮肤
  263. pageType: '', //页面类型
  264. sizeList: '', //尺寸
  265. sectorType: null, //通栏类别
  266. pageType: [], //页面类型
  267. sectorKeyword: '', //通栏关键词
  268. image: '', //通栏展示图
  269. sector_img:'', //通栏版式预览图
  270. component_code: [], //所选择位置的组件
  271. sector_width:'',
  272. sector_height:'',
  273. },
  274. rules: {
  275. sectorName: [{ required: true, trigger: 'blur', validator: validateEmpty }],
  276. component_num: [{ required: true, trigger: 'blur', validator: validateEmpty }],
  277. sectorId: [{ required: true, trigger: 'blur', validator: validateEmpty }],
  278. templateStyle: [{ required: true, trigger: 'blur', validator: validateEmpty }], //关联皮肤名称
  279. sectorType: [{ required: true, trigger: 'blur', validator: validateEmpty }],
  280. // pageType: [{ required: true, trigger: 'blur', validator: validateArray }],
  281. image: [{ required: true, trigger: 'blur', validator: validateEmpty }],
  282. sectorPlace: [{ required: true, trigger: 'blur', validator: validateEmpty }],
  283. // sectorPlace: [{ required: true, trigger: 'blur', validator: validateEmpty }],
  284. component_code: [{ required: true, trigger: 'blur', validator: validateArray }],
  285. },
  286. logoUrl: '',
  287. hovering: false, // 鼠标悬浮状态 悬浮时显示删除
  288. }
  289. },
  290. computed: {
  291. // 计算激活的方块索引
  292. activeBoxIndices() {
  293. return this.activeBoxes
  294. .map((active, index) => active ? index : null)
  295. .filter(index => index !== null);
  296. },
  297. checkPlace(){
  298. // 检查 sectorPlace_options 是否为数组,避免调用 find 方法时报错
  299. if (Array.isArray(this.sectorPlace_options)) {
  300. return this.sectorPlace_options.find(item => item.sector_type == this.ruleForm.sectorPlace);
  301. }
  302. return null;
  303. }
  304. },
  305. methods: {
  306. //1.列表和分页相关 start ------------------------------------------------------------>
  307. //1.1 开始请求列表信息方法
  308. // 获取版式列表
  309. getPlaceList(sectorType) {
  310. this.component_option = []
  311. this.ruleForm.component_code = []
  312. this.ruleForm.sectorPlace = ''
  313. let data = {
  314. component_num : this.ruleForm.component_num,
  315. type_id: 1,
  316. }
  317. this.$store.dispatch('plate/getAllSectorPlace',data).then(res => {
  318. this.sectorPlace_options = res.data
  319. }).catch(() => {
  320. this.$message({
  321. type: 'error',
  322. message: '网络错误,请重试!'
  323. });
  324. })
  325. // console.log("回显-22222",this.sectorPlace_options);
  326. },
  327. //获取风格列表
  328. getStyleList() {
  329. this.$store.dispatch('genre/getTemplateClass').then(res => {
  330. this.class_options = res.data
  331. // console.log(res.data);
  332. }).catch(() => {
  333. this.$message({
  334. type: 'error',
  335. message: '网络错误,请重试!'
  336. });
  337. })
  338. },
  339. //获取皮肤列表
  340. getSkinList() {
  341. let data = [];
  342. this.$store.dispatch('plate/getAllTemplate').then(res => {
  343. this.template_options = res.data
  344. console.log(res.data);
  345. }).catch(() => {
  346. this.$message({
  347. type: 'error',
  348. message: '网络错误,请重试!'
  349. });
  350. })
  351. },
  352. // //1.3 多选按钮发生变化
  353. changeCheckbox(val) {
  354. console.log(val)
  355. this.newArr = []
  356. val.forEach(item => {
  357. if (typeof item !== 'object' || !item.hasOwnProperty('__ob__')) {
  358. this.newArr.push(item)
  359. }
  360. });
  361. this.pageType = JSON.stringify(this.newArr)
  362. // console.log(this.pageType);
  363. },
  364. // 通栏版式发生变化
  365. changeStyleSort(val) {
  366. let num = 0;
  367. this.component_option = []
  368. this.activeBoxes = []
  369. this.selectedComponents = {}
  370. this.ruleForm.component_code = []
  371. if ( this.sectorPlace_options && Array.isArray(this.sectorPlace_options)) {
  372. this.sectorPlace_options.forEach(item => {
  373. if(item.sector_type == val){
  374. this.ruleForm.sizeList = item.width + ' * ' + item.height
  375. this.ruleForm.sector_img = item.sector_img
  376. this.ruleForm.size_id = item.size_id
  377. this.ruleForm.sector_width = item.width
  378. this.ruleForm.sector_height = item.height
  379. this.ruleForm.component_num = item.component_num;
  380. }
  381. })
  382. }
  383. let data = {
  384. sector_type : this.ruleForm.sectorPlace,
  385. type_id: 2,
  386. }
  387. this.$store.dispatch('plate/getAllSectorPlace',data).then(res => {
  388. this.component_option = res.data
  389. if(this.component_option && Array.isArray(this.component_option)){
  390. this.component_option.forEach(item => {
  391. item.name = '位置'+item.sort_id+'('+item.width+'*'+item.height+')'
  392. })
  393. }
  394. }).catch(() => {
  395. this.$message({
  396. type: 'error',
  397. message: '网络错误,请重试!'
  398. });
  399. })
  400. },
  401. getStyleSort(val) {
  402. console.log('this.ruleForm.sectorPlace2222', this.ruleForm.sectorPlace);
  403. console.log('val', val);
  404. let data = {
  405. sector_type : this.ruleForm.sectorPlace,
  406. type_id: 2,
  407. }
  408. this.$store.dispatch('plate/getAllSectorPlace',data).then(res => {
  409. this.component_option = res.data
  410. this.component_option.forEach(item => {
  411. item.name = '位置'+item.sort_id+'('+item.width+'*'+item.height+')';
  412. })
  413. }).catch(() => {
  414. this.$message({
  415. type: 'error',
  416. message: '网络错误,请重试!'
  417. });
  418. })
  419. },
  420. //列表和分页相关 end ------------------------------------------------------------>
  421. // 验证关联组件(每一个位置必须至少有一个组件)
  422. checkComponent() {
  423. this.component = true
  424. if (this.ruleForm.component_code && Array.isArray(this.ruleForm.component_code)) {
  425. const component = '';
  426. this.ruleForm.component_code.forEach(component => {
  427. if (component.length == 0) {
  428. this.component = false,
  429. console.log('component', component);
  430. this.$message({
  431. message: '请关联组件!',
  432. type: 'error'
  433. })
  434. }
  435. });
  436. // return this.component;
  437. }
  438. return true;
  439. },
  440. //1.9 编辑
  441. goEdit(id, val) {
  442. // console.log(id)
  443. let data = {
  444. id: this.$route.query.id
  445. };
  446. this.$store.dispatch('plate/getSectorInfo', data).then(res => {
  447. console.log('res回显', this.typeList)
  448. this.ruleForm.sectorName = res.data.sector_name //通栏名称
  449. this.ruleForm.sectorId = res.data.sector_id //通栏编号id
  450. this.ruleForm.templateStyle = res.data.template_id //关联皮肤名称
  451. this.ruleForm.component_num = res.data.component_num //组件数量
  452. this.ruleForm.sizeList = res.data.sector_width + ' * ' + res.data.sector_height //通栏尺寸
  453. this.ruleForm.sectorType = parseInt(res.data.place_type) //通栏类别
  454. this.ruleForm.pageType = JSON.parse(res.data.page_type) // 通栏页面类型,根据符号|划分字符串为数组
  455. this.tags = JSON.parse(res.data.sector_keyword)
  456. this.ruleForm.plateCode = res.data.sector_code //通栏代码
  457. this.ruleForm.sectorKeyword = this.tags //通栏关键词
  458. this.ruleForm.image = res.data.sector_img //通栏展示图
  459. this.logoUrl = res.data.sector_img
  460. this.ruleForm.sector_img = res.data.place.sector_img
  461. this.sectorPlace_options = this.getPlaceList(res.data.component_num)
  462. this.ruleForm.sectorPlace = parseInt(res.data.place_type)
  463. this.getStyleSort(res.data.sectorPlace)
  464. // this.ruleForm.size_id = res.data.size_id;
  465. this.ruleForm.sector_width = res.data.sector_width
  466. this.ruleForm.sector_height = res.data.sector_height
  467. this.ruleForm.component_code = JSON.parse(res.data.component_code)
  468. console.log('回显表单', this.ruleForm)
  469. console.log('回显表单', this.tags)
  470. }).catch(() => {
  471. this.$message({
  472. type: 'error',
  473. message: '网络错误,请重试!'
  474. });
  475. })
  476. },
  477. //1.7 添加
  478. addPlate() {
  479. this.dialogTableVisible = true
  480. this.dialogName = "添加"
  481. this.name = "添加"
  482. this.name = this.dialogName
  483. //添加时清空回显回来的数据
  484. this.ruleForm.sectorName = '' //通栏名称
  485. this.ruleForm.sectorId = null //通栏编号id
  486. this.ruleForm.templateStyle = '' //关联皮肤名称
  487. this.ruleForm.sizeList = '' //通栏尺寸
  488. this.ruleForm.sectorType = null //通栏类别
  489. this.ruleForm.pageType = [] //通栏页面类型
  490. this.ruleForm.plateCode = '' //通栏代码
  491. this.ruleForm.sectorKeyword = '' //通栏关键词
  492. this.ruleForm.component_num = null //组件数量
  493. this.ruleForm.image = '' //通栏展示图
  494. this.ruleForm.sector_img = '' //通栏展示图
  495. // this.ruleForm.size_id = '' //通栏尺寸
  496. this.ruleForm.sectorPlace = '' //通栏版式编号
  497. this.logoUrl = ''
  498. this.ruleForm.image = ''
  499. this.tags = []
  500. this.ruleForm.component_code = []
  501. this.component_option = []
  502. this.ruleForm.sector_width = ''
  503. this.ruleForm.sector_height = ''
  504. // this.getPlaceList();
  505. this.selectedComponents = []
  506. this.activeBoxes = []
  507. },
  508. // 弹出层相关方法
  509. // 提交表单
  510. submitForm(formName) {
  511. console.log('this.ruleForm', this.dialogName)
  512. // this.name = this.dialogName
  513. console.log('this.ruleForm111', this.dialogName)
  514. console.log('this.ruleForm222', this.name)
  515. this.checkComponent()
  516. console.log('this.component', this.component)
  517. if (!this.component) {
  518. this.dialogName = ""
  519. return
  520. }else{
  521. this.dialogName = this.name
  522. }
  523. console.log('this.ruleForm121', this.dialogName)
  524. console.log('this.ruleForm242', this.name)
  525. if (this.dialogName == "添加") {
  526. const data = {
  527. sector_name: this.ruleForm.sectorName, //通栏名称
  528. sector_id: this.ruleForm.sectorId, //通栏编号
  529. template_id: this.ruleForm.templateStyle, //所属皮肤
  530. // size_id: this.ruleForm.size_id, //通栏尺寸
  531. sector_type: this.ruleForm.sectorType, //通栏类别
  532. sector_code: this.ruleForm.plateCode, //通栏代码
  533. page_type: this.ruleForm.pageType, //页面类型
  534. component_num: this.ruleForm.component_num, //组件数量
  535. sector_keyword: JSON.stringify(this.ruleForm.sectorKeyword), //通栏关键词
  536. sector_img: this.logoUrl, //通栏展示图
  537. place_type: this.ruleForm.sectorPlace, //通栏版式id
  538. component_code: JSON.stringify(this.ruleForm.component_code), //通栏所选组件
  539. sector_width: this.ruleForm.sector_width, //通栏宽度
  540. sector_height: this.ruleForm.sector_height, //通栏高度
  541. }
  542. console.log('添加表单--------data', data);
  543. this.$store.dispatch('plate/addSector',data).then(data => {
  544. if (data.code == 200) {
  545. this.$message({
  546. message: '添加成功',
  547. type: 'success'
  548. })
  549. this.$router.push({
  550. path: '/plate',
  551. });
  552. }else{
  553. this.$message({
  554. message: data.message,
  555. type: 'error'
  556. })
  557. }
  558. })
  559. }
  560. if (this.dialogName == "编辑") {
  561. const data = {
  562. id: this.$route.query.id,
  563. sector_name: this.ruleForm.sectorName, //通栏名称
  564. sector_id: this.ruleForm.sectorId, //通栏编号
  565. template_id: this.ruleForm.templateStyle, //所属皮肤
  566. // size_id: this.ruleForm.size_id, //通栏尺寸
  567. sector_type: this.ruleForm.sectorType, //通栏类别
  568. sector_code: this.ruleForm.plateCode, //通栏代码
  569. page_type: this.ruleForm.pageType, //页面类型
  570. component_num: this.ruleForm.component_num, //组件数量
  571. sector_keyword: JSON.stringify(this.ruleForm.sectorKeyword), //通栏关键词
  572. sector_img: this.ruleForm.image, //通栏展示图
  573. place_type: this.ruleForm.sectorPlace, //通栏版式id
  574. component_code: JSON.stringify(this.ruleForm.component_code), //通栏所选组件
  575. sector_width: this.ruleForm.sector_width, //通栏宽度
  576. sector_height: this.ruleForm.sector_height, //通栏高度
  577. }
  578. console.log('编辑表单---data', data);
  579. this.$store.dispatch('plate/updateSector', data).then(data => {
  580. if (data.code == 200) {
  581. this.$message({
  582. message: '编辑成功',
  583. type: 'success'
  584. })
  585. this.$router.push({
  586. path: '/plate',
  587. });
  588. }else{
  589. this.$message({
  590. message: data.message,
  591. type: 'error'
  592. })
  593. }
  594. })
  595. }
  596. },
  597. //取消添加或编辑
  598. cancelForm() {
  599. this.$router.push({
  600. path: '/plate',
  601. });
  602. },
  603. // 验证输入的数量
  604. validateCount() {
  605. // 确保是数字且在1-3范围内(因为输入框min为1,移除小于0的判断)
  606. let count = parseInt(this.component_num, 10);
  607. if (isNaN(count)) count = 1;
  608. if (count > 3) count = 3;
  609. this.component_num = count;
  610. // 初始化激活状态数组
  611. this.activeBoxes = Array(count).fill(false);
  612. // 初始化组件选择对象
  613. this.selectedComponents = {};
  614. for (let i = 0; i < count; i++) {
  615. this.selectedComponents[i] = [];
  616. }
  617. },
  618. // 切换方块激活状态
  619. toggleBox(index) {
  620. this.$set(this.activeBoxes,index, this.component_option[index])
  621. // this.activeBoxes[index] = this.component_option[index];
  622. // console.log('this.activeBoxes', this.activeBoxes);
  623. // console.log('this.selectedComponents', this.component_option);
  624. },
  625. //3.6 上传图片操作
  626. beforeAvatarUpload(file) {
  627. const isJPG = file.type === 'image/jpeg';
  628. const isPNG = file.type === 'image/png';
  629. const isLt2M = file.size / 1024 / 1024 < 2;
  630. if (!isJPG && !isPNG) {
  631. this.$message.error('上传图片只能是 JPG 或 PNG 格式!');
  632. return false;
  633. }
  634. if (!isLt2M) {
  635. this.$message.error('上传图片大小不能超过 2MB!');
  636. return false;
  637. }
  638. const formData = new FormData();
  639. formData.append('file', file);
  640. this.$store.dispatch('pool/uploadFile', formData).then(res => {
  641. this.logoUrl = res.data.imgUrl;//显示缩略图
  642. this.ruleForm.image = res.data.imgUrl;//提供表单地址
  643. console.log(res.data.imgUrl)
  644. }).catch(() => {
  645. this.$message({
  646. type: 'info',
  647. message: '网络错误,请重试!'
  648. });
  649. })
  650. // 阻止默认的上传行为
  651. return false;
  652. },
  653. handleDelete() {
  654. // 删除图片
  655. this.logoUrl = ''; // 清空图片 URL
  656. },
  657. // 关键词标签
  658. updateTags(newTags) {
  659. // this.foem.seo_keywords = newTags;
  660. this.tags = newTags;
  661. this.ruleForm.sectorKeyword = newTags;
  662. },
  663. },
  664. mounted() {
  665. if(this.$route.query.id && this.$route.query.id != 0) {
  666. this.dialogName = '编辑',
  667. this.goEdit()
  668. }else{
  669. this.dialogName = '添加',
  670. this.addPlate()
  671. }
  672. // this.getData()
  673. this.getStyleList()
  674. this.getSkinList()
  675. },
  676. watch:{
  677. // 监听数量变化,重新初始化
  678. component_num(newVal) {
  679. this.validateCount();
  680. },
  681. 'ruleForm.component_num':{
  682. handler(oldVal,newVal){
  683. console.log('监听val',oldVal);
  684. console.log('监听newval',newVal);
  685. // 清空组件代码数组
  686. // handler(oldval){
  687. // 清空组件代码数组
  688. if (!(this.newVal !== null && this.dialogName == '编辑')) {
  689. this.component_option = [];
  690. this.ruleForm.component_code = [];
  691. this.ruleForm.sectorPlace = '';
  692. }
  693. },
  694. deep: true
  695. }
  696. }
  697. }
  698. </script>
  699. <style scoped lang="less">
  700. input[aria-hidden=true] {
  701. display: none !important;
  702. }
  703. // 提示信息
  704. .tips {
  705. margin: 30px;
  706. background-color: #e9ecf9;
  707. border-radius: 11px;
  708. .tipsIcon {
  709. margin: 10px 15px;
  710. display: inline-block;
  711. width: 24px;
  712. height: 24px;
  713. background: url("../../assets/advertise/Info Circle.png") no-repeat;
  714. vertical-align: middle;
  715. }
  716. .tipsText {
  717. font-size: 14px;
  718. color: #666666;
  719. }
  720. }
  721. // 头部
  722. .title {
  723. margin: 30px 30px 20px 30px;
  724. padding: 30px 30px 40px 30px;
  725. background-color: #fff;
  726. border-radius: 20px 20px 20px 20px;
  727. border: 1px solid #E9EDF7;
  728. .left {
  729. float: left;
  730. }
  731. .right {
  732. float: right;
  733. }
  734. .searchBox {
  735. ::v-deep .el-input {
  736. position: relative;
  737. font-size: 14px;
  738. display: inline-block;
  739. width: 80%;
  740. }
  741. .searchTitle {
  742. padding-bottom: 10px;
  743. font-family: Microsoft YaHei, Microsoft YaHei;
  744. font-weight: 400;
  745. font-size: 14px;
  746. color: #999999;
  747. line-height: 16px;
  748. }
  749. .el-select {
  750. width: 100%;
  751. display: inline-block;
  752. position: relative;
  753. }
  754. }
  755. .btnList {
  756. float: right;
  757. padding-top: 28px;
  758. button {
  759. height: 38px;
  760. border: none;
  761. border-radius: 8px;
  762. padding: 0 30px;
  763. }
  764. .search {
  765. background-color: #5570f1;
  766. color: #fff;
  767. margin-right: 20px;
  768. }
  769. .reset {
  770. font-family: Microsoft YaHei, Microsoft YaHei;
  771. font-weight: 400;
  772. font-size: 16px;
  773. color: #333333;
  774. background: #F5F7FB;
  775. border-radius: 8px 8px 8px 8px;
  776. border: 1px solid rgba(85, 112, 241, 0.11);
  777. }
  778. }
  779. }
  780. .layerBox {
  781. padding: 30px 20px;
  782. position: relative;
  783. .btn {
  784. position: absolute;
  785. top: 30px;
  786. right: 20px;
  787. height: 38px;
  788. color: #fff;
  789. background-color: #5570f1;
  790. border: none;
  791. border-radius: 8px;
  792. padding: 8px 28px 9px;
  793. box-sizing: border-box;
  794. }
  795. .listBtnBox {
  796. justify-content: left;
  797. }
  798. .listDeleteBtn,
  799. .listEditBtn {
  800. margin-left: 0px;
  801. padding-left: 0px;
  802. margin-right: 20px;
  803. width: 76px;
  804. height: 36px;
  805. line-height: 36px;
  806. }
  807. ::v-deep .el-form-item {
  808. margin-bottom: 50px;
  809. }
  810. ::v-deep .el-select {
  811. width: 100%;
  812. }
  813. ::v-deep .el-input--medium,
  814. ::v-deep .el-form-item__label {
  815. line-height: 36px;
  816. font-size: 16px;
  817. }
  818. }
  819. /* 方块容器样式 */
  820. .boxes-container {
  821. margin-left: 170px;
  822. width:700px;
  823. height: 350px;
  824. margin-bottom: 25px;
  825. border: 1px dashed #d1d5db;
  826. border-radius: 6px;
  827. overflow: hidden;
  828. }
  829. /* 通用方块样式 */
  830. .box {
  831. display: flex;
  832. align-items: center;
  833. justify-content: center;
  834. color: white;
  835. font-weight: 600;
  836. cursor: pointer;
  837. transition: all 0.2s ease;
  838. }
  839. .box:hover {
  840. filter: brightness(1.1);
  841. }
  842. .box.active {
  843. background-color: #1e40af;
  844. box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
  845. }
  846. /* 数量=3的布局 */
  847. .layout-3 {
  848. display: flex;
  849. height: 100%; /* 固定高度确保左右等高 */
  850. gap: 10px;
  851. padding: 10px;
  852. }
  853. .layout-3-left {
  854. flex: 1.5;
  855. display: flex;
  856. flex-direction: column;
  857. gap: 10px;
  858. height: 100%;
  859. }
  860. .layout-3-right {
  861. flex: 1;
  862. height: 100%;
  863. }
  864. .layout-3-left .box {
  865. height: 50%; /* 左侧两个方块各占一半高度 */
  866. }
  867. .layout-3 .box {
  868. background-color: #3b82f6;
  869. border-radius: 6px;
  870. height: 100%;
  871. }
  872. .layout-3-1 .box{
  873. background-color: #3b82f6;
  874. border-radius: 6px;
  875. height: 100%;
  876. }
  877. .layout-3-1-left {
  878. flex: 3;
  879. height: 100%;
  880. }
  881. .layout-3-1-right {
  882. flex: 1;
  883. display: flex;
  884. flex-direction: column;
  885. gap: 10px;
  886. height: 100%;
  887. }
  888. .layout-3-1-right .box {
  889. height: 50%; /* 左侧两个方块各占一半高度 */
  890. }
  891. .layout-3-1-left .box {
  892. height: 100%; /* 左侧两个方块各占一半高度 */
  893. }
  894. .layout-3-1{
  895. display: flex;
  896. height: 100%; /* 固定高度确保左右等高 */
  897. gap: 10px;
  898. padding: 10px;
  899. }
  900. /* 数量=2的布局 */
  901. .layout-2 {
  902. display: flex;
  903. height: 100%;
  904. gap: 10px;
  905. padding: 10px;
  906. }
  907. .layout-2-left {
  908. flex: 5; /* 30%宽度 */
  909. height: 100%;
  910. }
  911. .layout-2-right {
  912. flex: 5; /* 70%宽度 */
  913. height: 100%;
  914. }
  915. .layout-2 .box {
  916. background-color: #3b82f6;
  917. border-radius: 6px;
  918. height: 100%;
  919. width: 100%;
  920. }
  921. /* 数量=1的布局 */
  922. .layout-1 {
  923. height: 100%;
  924. padding: 10px;
  925. }
  926. .layout-1 .box {
  927. background-color: #3b82f6;
  928. border-radius: 6px;
  929. height: 100%;
  930. width: 100%;
  931. }
  932. /* 输入框区域样式 */
  933. .input-fields {
  934. display: flex;
  935. flex-direction: column;
  936. gap: 15px;
  937. margin-top: 20px;
  938. }
  939. .field-item {
  940. display: flex;
  941. align-items: center;
  942. gap: 15px;
  943. padding: 12px;
  944. background-color: #f9fafb;
  945. border-radius: 6px;
  946. }
  947. .field-label {
  948. width: 120px;
  949. font-weight: 600;
  950. color: #374151;
  951. }
  952. .size-select {
  953. flex: 1;
  954. padding: 8px;
  955. border: 1px solid #d1d5db;
  956. border-radius: 4px;
  957. height: 100px;
  958. background-color: white;
  959. }
  960. .size-select option {
  961. padding: 4px 0;
  962. }
  963. // 弹出层内容
  964. .dialogText {
  965. margin: 0 7px 0 3px;
  966. padding-bottom: 1px;
  967. padding: 30px 60px 1px 20px;
  968. background-color: #f5f7fb;
  969. .adImage {
  970. width: 140px;
  971. height: 140px;
  972. line-height: 210px;
  973. border-radius: 12px;
  974. border: 1px solid rgba(85, 112, 241, 0.11);
  975. img {
  976. width: 140px;
  977. height: 80px;
  978. }
  979. }
  980. ::v-deep .avatar {
  981. width: 140px;
  982. height: auto;
  983. }
  984. .price {
  985. ::v-deep .el-input {
  986. width: 29%;
  987. }
  988. }
  989. .example {
  990. font-family: Microsoft YaHei;
  991. color: #5570F1;
  992. }
  993. .el_btnList {
  994. margin-right: 15px;
  995. margin-top: 20px;
  996. }
  997. //日期时间选择器的宽
  998. ::v-deep .el-date-editor.el-input {
  999. width: 48%;
  1000. }
  1001. ::v-deep .el-button+.el-button {
  1002. margin-left: 0px;
  1003. }
  1004. ::v-deep .el-select {
  1005. width: 100%;
  1006. }
  1007. ::v-deep .el-form-item {
  1008. margin-bottom: 50px;
  1009. }
  1010. }
  1011. // 弹出层按钮
  1012. .dialogBtn {
  1013. text-align: center;
  1014. margin: 50px auto 20px;
  1015. clear: both;
  1016. button {
  1017. width: 184px;
  1018. padding: 16px;
  1019. font-family: Microsoft YaHei, Microsoft YaHei;
  1020. font-weight: 400;
  1021. font-size: 20px;
  1022. border: none;
  1023. border-radius: 12px 12px 12px 12px;
  1024. }
  1025. // 取消
  1026. .cancel {
  1027. color: #333333;
  1028. background-color: #f5f7fb;
  1029. border: 2px solid rgba(85, 112, 241, 0.11);
  1030. }
  1031. // 提交
  1032. .submit {
  1033. color: #fff;
  1034. background-color: #5570F1;
  1035. margin-left: 40px;
  1036. }
  1037. }
  1038. //审核弹出框
  1039. .radioGroup {
  1040. ::v-deep .el-form-item {
  1041. margin-top: 40px;
  1042. margin-bottom: 0;
  1043. }
  1044. }
  1045. .graph {
  1046. background-color: #f5f7fb;
  1047. padding: 60px 100px;
  1048. overflow: hidden;
  1049. li {
  1050. float: left;
  1051. }
  1052. >li:first-child {
  1053. margin-right: 100px;
  1054. }
  1055. }
  1056. .dialog-footer {
  1057. margin: 0 auto;
  1058. }
  1059. .rowMargin {
  1060. margin-top: 20px;
  1061. }
  1062. .componentChoose{
  1063. background-color: #f5f7fb;
  1064. overflow: hidden;
  1065. }
  1066. .componentOptions{
  1067. float: left;
  1068. margin-right: 30px;
  1069. width: 100%;
  1070. }
  1071. .componentOption_one{
  1072. width: 100%;
  1073. }
  1074. </style>