index.php 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  1. <script src="/resources/js/html2canvas.min.js"></script>
  2. <!-- 装修所需的数据 -->
  3. <script type="text/javascript" src="/resources/js/diy-util.js"></script>
  4. <script type="text/javascript" src="/resources/js/hotzone.js"></script>
  5. <script>
  6. function getNavData() {
  7. const result = [{
  8. // 顶部导航
  9. "id": getRandomId(),
  10. "data": {
  11. backSrc: "",
  12. contentType: "1",
  13. isShowName: "1",
  14. logoSrc: "",
  15. mainPage: { // 主页面设置
  16. defColor: "#fff",
  17. name: "盲盒分类",
  18. type: "纯色",
  19. imgUrl: ""
  20. },
  21. name: "奖金盲盒",
  22. positionChoose: "1",
  23. hideSearch: true,
  24. isShowSearch: "2",
  25. },
  26. "computedStyle": {
  27. "mode": 1,
  28. "style": 1,
  29. "titleSwitch": true,
  30. "titleMode": 1,
  31. "imageUrl": [],
  32. "position": 1,
  33. "searchSwitch": true,
  34. "searchBgColor": "",
  35. "statusBarColor": "#FFF",
  36. "defaultForm": {
  37. "defColor": "transparent"
  38. },
  39. "titleDistance": {
  40. "fontSize": 16,
  41. "height": 30,
  42. "width": 57,
  43. "marginLeft": 20
  44. },
  45. "statusBar": "1",
  46. "searchMarPad": {
  47. "marginLeft": 20,
  48. "paddingLeft": 14
  49. }
  50. },
  51. "funcListItem": {
  52. "type": "nav",
  53. "title": "顶部导航",
  54. "is_top": 1
  55. },
  56. "isShow": true,
  57. "is_show_permission": false,
  58. "is_drag": false,
  59. "disabled": true,
  60. "is_delete": false,
  61. "is_up": false,
  62. "is_down": false,
  63. "is_copy": false
  64. }, {
  65. // 轮播图
  66. "id": getRandomId(),
  67. "data": {
  68. buttonData: {
  69. typeIndex: 0,
  70. typeItem: null
  71. },
  72. buttonPointData: {
  73. open: true,
  74. pointIndex: 1,
  75. pointItem: {
  76. label: "resources/img/decorate/point-two.png",
  77. value: "two"
  78. },
  79. position: 1
  80. },
  81. carouselImgArr: [{
  82. hotZone: [],
  83. imgUrl: "resources/img/decorate/group-goods/banner.png",
  84. url: "",
  85. urlName: "",
  86. urlType: "",
  87. visible: false
  88. }],
  89. spaceInfo: [{
  90. disabled: false,
  91. hidden: true,
  92. maxValue: 20,
  93. name: "图片间距",
  94. unit: "px",
  95. value: 5
  96. },
  97. {
  98. disabled: false,
  99. hidden: false,
  100. maxValue: 50,
  101. name: "上边距",
  102. unit: "px",
  103. value: 0,
  104. },
  105. {
  106. disabled: false,
  107. hidden: false,
  108. maxValue: 50,
  109. name: "下边距",
  110. unit: "px",
  111. value: 0
  112. },
  113. {
  114. disabled: false,
  115. hidden: false,
  116. maxValue: 50,
  117. name: "左右边距",
  118. unit: "px",
  119. value: 12
  120. }
  121. ]
  122. },
  123. "computedStyle": {
  124. "searchBox": "",
  125. "spaceStyle": {
  126. marginBottom: "0px",
  127. marginLeft: "12px",
  128. marginRight: "12px",
  129. marginTop: "0px",
  130. height: '160px',
  131. },
  132. "searchIpts": {
  133. 'border-bottom-left-radius': "10px",
  134. 'border-bottom-right-radius': "10px",
  135. 'border-top-left-radius': "10px",
  136. 'border-top-right-radius': "10px"
  137. }
  138. },
  139. "permission": [],
  140. "funcListItem": {
  141. is_top: 0,
  142. title: "轮播广告",
  143. type: "carousel-img"
  144. },
  145. "isShow": true,
  146. "is_show_permission": false,
  147. "is_drag": false,
  148. "disabled": true,
  149. "is_delete": false,
  150. "is_up": false,
  151. "is_down": false,
  152. "is_copy": false
  153. }, {
  154. // 按钮组
  155. "id": getRandomId(),
  156. "data": {
  157. "buttonData": {
  158. "line_num": 1,
  159. "pattern": "fixed",
  160. "patternItem": null,
  161. "shape": "square",
  162. "single_line": 3,
  163. "style": 1,
  164. "type": 1,
  165. },
  166. "colorInfos": [{
  167. color: "",
  168. name: "底部背景",
  169. showAlpha: false,
  170. value: "transparent"
  171. },
  172. {
  173. color: "",
  174. name: "组件背景",
  175. showAlpha: false,
  176. value: "transparent"
  177. },
  178. {
  179. color: "#333333",
  180. name: "文字颜色",
  181. showAlpha: false,
  182. value: "#333333",
  183. }
  184. ],
  185. "iconList": [
  186. {
  187. img: 'resources/img/decorate/default_btn1.png',
  188. icon: 'el-icon-setting',
  189. is_show_tag: true,
  190. tags: '热门',
  191. tagsBgColor: '#f83287',
  192. tagsTextColor: '#ffffff',
  193. btnText: '按钮文字',
  194. link_params: null,
  195. },
  196. ],
  197. "sizeInfos": [{
  198. disabled: false,
  199. hidden: false,
  200. maxValue: 50,
  201. name: "上边距",
  202. unit: "px",
  203. value: 8
  204. },
  205. {
  206. disabled: false,
  207. hidden: false,
  208. maxValue: 50,
  209. name: "下边距",
  210. unit: "px",
  211. value: 8
  212. },
  213. {
  214. disabled: false,
  215. hidden: false,
  216. maxValue: 50,
  217. name: "左右边距",
  218. unit: "px",
  219. value: 0
  220. }
  221. ],
  222. defaultTabs: [{name: 'marketing',children:['blind_box_cate']}],
  223. },
  224. "computedStyle": {
  225. "iptBg": "",
  226. "searchBox": "",
  227. "searchIpts": {
  228. "marginBottom": "8px",
  229. "marginLeft": "0px",
  230. "marginRight": "0px",
  231. "marginTop": "8px",
  232. },
  233. "textStyle": "#333333"
  234. },
  235. "permission": [],
  236. "funcListItem": {
  237. is_top: 0,
  238. title: "按钮组",
  239. type: "button-group"
  240. },
  241. "isShow": true,
  242. "is_show_permission": false,
  243. "is_drag": false,
  244. "disabled": true,
  245. "is_delete": false,
  246. "is_up": false,
  247. "is_down": false,
  248. "is_copy": false
  249. },
  250. {
  251. // 商品列表
  252. "id": getRandomId(),
  253. "data": {
  254. titleRadio: 1,
  255. listType: 1,
  256. listShow: true,
  257. dataType: 0,
  258. btnData: {
  259. style: 0,
  260. name: '推荐商家'
  261. },
  262. colorInfos: [
  263. {
  264. name: "底部颜色", //名字
  265. color: "#FAFAFA", //颜色
  266. showAlpha: false, //是否开启透明度
  267. value: "#FAFAFA", //展示的值
  268. },
  269. {
  270. name: "组件颜色", //名字
  271. color: "#FFFFFF", //颜色
  272. showAlpha: false, //是否开启透明度
  273. value: "#FFFFFF", //展示的值
  274. }
  275. ],
  276. sizeInfos: [
  277. {
  278. disabled: false,
  279. hidden: false,
  280. maxValue: 20,
  281. name: "商品间距",
  282. unit: "px",
  283. value: 10,
  284. },
  285. {
  286. disabled: false,
  287. hidden: false,
  288. maxValue: 50,
  289. name: "上边距",
  290. unit: "px",
  291. value: 0,
  292. },
  293. {
  294. disabled: false,
  295. hidden: false,
  296. maxValue: 50,
  297. name: "下边距",
  298. unit: "px",
  299. value: 0,
  300. },
  301. {
  302. disabled: false,
  303. hidden: false,
  304. maxValue: 50,
  305. name: "左右边距",
  306. unit: "px",
  307. value: 12,
  308. }
  309. ],
  310. },
  311. "computedStyle": {
  312. aroundMargin: "0px",
  313. boxBg: "#FAFAFA",
  314. goodsBg: "#FFFFFF",
  315. marginBottom: "0px",
  316. marginTop: "0px",
  317. spacing: "0px"
  318. },
  319. "permission": [],
  320. "funcListItem": {
  321. is_top: 0,
  322. type: "blindbox-goods"
  323. },
  324. "isShow": true,
  325. "is_show_permission": false,
  326. "is_drag": false,
  327. "disabled": true,
  328. "is_delete": false,
  329. "is_up": false,
  330. "is_down": false,
  331. "is_copy": false
  332. }
  333. ]
  334. return result
  335. }
  336. </script>
  337. <?php
  338. use common\helpers\ComponentHelper;
  339. use common\models\diy\DiyComponents;
  340. use common\helpers\AddonHelper;
  341. $diyPath = Yii::$app->viewPath . '/components/common/diy/common';
  342. $stylePath = Yii::$app->viewPath . '/components/common/diy/style-components';
  343. $components = DiyComponents::getDir($diyPath, $diyPath);
  344. $styleComponents = DiyComponents::getDir($stylePath, $stylePath);
  345. // dd($diyPath, $stylePath, $components, $styleComponents);
  346. ComponentHelper::loadComponentView('diy/diy-preview');
  347. ComponentHelper::loadComponentView('diy/diy-style-preview');
  348. foreach ($components as $item) {
  349. ComponentHelper::loadComponentView("diy/common/{$item}");
  350. }
  351. foreach ($styleComponents as $item) {
  352. ComponentHelper::loadComponentView("diy/style-components/{$item}");
  353. }
  354. $currentRoute = Yii::$app->controller->route;
  355. ?>
  356. <div id="app">
  357. <div style="padding-bottom: 10px;padding-right: 20px;background: #F4F6F8;" @click="save" flex="main:right">
  358. <el-button type="primary">保存</el-button>
  359. </div>
  360. <div class="diy-contain flex" v-loading="loading">
  361. <diy-preview :active-index="activeIndex" :list="previewList" @select-item="selectItme" @change-move="changeMove"></diy-preview>
  362. <transition name="fade">
  363. <diy-style-preview :active-item="activeItem" :active-index="activeIndex" :permission="permission" @update="changeDiyItem" v-if="showUpdate"></diy-style-preview>
  364. </transition>
  365. </div>
  366. <!-- 预览弹窗 -->
  367. <el-dialog title="预览弹窗" :modal-append-to-body="false" :visible.sync="dialogFormVisible">
  368. <div class="flex flex-x-center" style="height: 600px;overflow:auto">
  369. <img id="diy-test-preview" :src="previewSrc"></img>
  370. </div>
  371. <div slot="footer" class="dialog-footer">
  372. <el-button @click="dialogFormVisible = false">取 消</el-button>
  373. <el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
  374. </div>
  375. </el-dialog>
  376. </div>
  377. <script>
  378. Vue.prototype.$capitals = []; // 用户信息对象
  379. Vue.prototype.$eventBus = new Vue();
  380. var PageShareData = {
  381. pageIndex: false // 点击页面设置标识 => nav/style
  382. }; // 全局共享数据 - 没有响应式
  383. new Vue({
  384. el: '#app',
  385. data() {
  386. return {
  387. capital: [],
  388. dialogFormVisible: false,
  389. /**
  390. * @descriptions 浮动()、普通()、置顶(isTop)、弹窗(alert)四种显示组件
  391. * @param {string} type // diy组件类型
  392. * @param {string} title // 二级标题
  393. * @param {string} img // diy组件图片
  394. * @param {number} count // 可添加diy组件数量
  395. * @param {boolean} is_top // diy组件是否置顶组件 - 待添加 - 分添加等级 1 2 3 数字靠前权限越高
  396. * @param {object} permission // 组件的不可操作权限 {"is_delete": false,"is_drag": false,"disabled": true, // 禁用操作}
  397. */
  398. pageComponentsList: [],
  399. /**
  400. * @param {boolean} is_show_permission // 显示权限
  401. * @param {boolean} is_delete // 是否可删除
  402. * @param {boolean} is_up // 是否可上移
  403. * @param {boolean} is_down // 是否可下移
  404. * @param {boolean} is_drag // 是否可拖拽
  405. * @param {boolean} is_copy // 是否可复制
  406. * @param {boolean} disabled // 全部禁用操作
  407. */
  408. previewList: [], // 预览数组对象
  409. activeIndex: -1, // 预览激活索引
  410. activeItem: null, // 预览激活对象
  411. type: "add", // add新增 - edit编辑
  412. test: ["a", "b", "c"],
  413. showUpdate: true,
  414. responentData: null, // 详情响应的总数据
  415. permission: [], // 权限数组
  416. isClickPage: false, // 是否点击分页设置
  417. loading: false, // 数据加载
  418. saveLoading: false, // 保存数据
  419. fields: {
  420. upload_type: 'images'
  421. },
  422. previewSrc: "",
  423. }
  424. },
  425. provide() {
  426. return {
  427. capitals: this.capital
  428. }
  429. },
  430. watch: {
  431. activeIndex() {
  432. this.showUpdate = false
  433. setTimeout(() => {
  434. this.showUpdate = true
  435. }, 0)
  436. },
  437. },
  438. created() {
  439. // console.log(this.dynamicImgSrc('/abc/ss'));
  440. // 添加不同的模板nav
  441. this.previewList.push(...getNavData())
  442. this.init()
  443. this.detail()
  444. },
  445. methods: {
  446. savePreview() {
  447. this.activeIndex = -1
  448. this.activeItem = null
  449. this.$nextTick(() => {
  450. const contain = document.getElementById("diy-preview-contain");
  451. this.deepNode(contain);
  452. setTimeout(() => {
  453. this.dialogFormVisible = true
  454. html2canvas(contain, {
  455. useCORS: true
  456. }).then(canvas => {
  457. const src = canvas.toDataURL("image/png")
  458. this.upload(this.dataURLtoFile(src)).then(res => {
  459. if (res.code == 0) {
  460. this.previewSrc = res.data.url
  461. this.save(false)
  462. } else {
  463. this.$message({
  464. message: res.msg,
  465. type: 'warning'
  466. });
  467. }
  468. })
  469. })
  470. }, 0)
  471. })
  472. },
  473. dataURLtoFile(dataurl) { // 生成Blob
  474. var arr = dataurl.split(',');
  475. var mime = arr[0].match(/:(.*?);/)[1];
  476. var bstr = atob(arr[1]);
  477. var n = bstr.length;
  478. var u8arr = new Uint8Array(n);
  479. while (n--) {
  480. u8arr[n] = bstr.charCodeAt(n);
  481. }
  482. return new Blob([u8arr], {
  483. type: mime
  484. });
  485. },
  486. upload(file) {
  487. let formData = new FormData();
  488. const params = {
  489. upload_type: 'images'
  490. };
  491. params['r'] = 'common/file/upload';
  492. for (let i in this.fields) {
  493. formData.append(i, this.fields[i]);
  494. }
  495. formData.append('file', file, "image.png");
  496. return new Promise(successCallback => {
  497. this.$request({
  498. headers: {
  499. 'Content-Type': 'multipart/form-data'
  500. },
  501. params: params,
  502. method: 'post',
  503. data: formData,
  504. }).then(e => {
  505. successCallback(e.data)
  506. }).catch(e => {
  507. file._complete = true;
  508. });
  509. })
  510. },
  511. deepNode(contain) {
  512. if (contain.tagName === "IMG") {
  513. contain.src = contain.src + '?t=' + Date.now()
  514. contain.setAttribute('crossorigin', 'anonymous')
  515. }
  516. if (contain.children && contain.children.length) {
  517. [].forEach.call(contain.children, (item => {
  518. this.deepNode(item)
  519. }))
  520. }
  521. },
  522. pageSet() {
  523. PageShareData.pageIndex = true
  524. this.$eventBus.$emit("onPageClick")
  525. var index = 0;
  526. this.activeIndex = index
  527. this.activeItem = this.previewList[index]
  528. // this.changeDiyItem()
  529. },
  530. detail() {
  531. // 详情
  532. this.loading = true
  533. request({
  534. params: {
  535. r: 'blind-box/diy/index'
  536. },
  537. method: 'get',
  538. }).then(res => {
  539. if(res.data.code == 0){
  540. let previewList = [];
  541. if (res.data.data.content) {
  542. previewList = JSON.parse(res.data.data.content)
  543. }
  544. //调整错误参数
  545. if(!previewList[0].data.hideSearch){
  546. previewList[0].data.hideSearch = true;
  547. previewList[0].data.isShowSearch = "2"
  548. }
  549. console.log(previewList, '---------------')
  550. if(!previewList.length) return
  551. this.previewList = previewList
  552. } else {
  553. this.$message({
  554. message: res.data.msg,
  555. type: 'error'
  556. });
  557. }
  558. }).finally(res => {
  559. this.loading = false
  560. })
  561. },
  562. save: debounce(function(isLoading = true) {
  563. // 对接保存数据接口
  564. if (this.saveFlag) {
  565. console.log("重复提交");
  566. return
  567. }
  568. const title = this.previewList[0].data.name
  569. // if (!title) {
  570. // this.$message({
  571. // message: '请输入标题',
  572. // type: 'warning'
  573. // });
  574. // return
  575. // }
  576. isLoading && (this.saveLoading = true)
  577. this.saveFlag = true // 防止重复提交限制
  578. request({
  579. params: {
  580. r: 'blind-box/diy/index'
  581. },
  582. method: 'post',
  583. data: {
  584. content: JSON.stringify(this.previewList),
  585. }
  586. }).then(res => {
  587. if (res.data.code != 0) {
  588. this.$message({
  589. message: res.data.msg,
  590. type: 'error'
  591. });
  592. } else {
  593. this.$message({
  594. message: res.data.msg,
  595. type: 'success'
  596. });
  597. }
  598. }).finally(res => {
  599. this.saveFlag = false
  600. this.saveLoading = false
  601. })
  602. },400),
  603. init() {
  604. this.$eventBus.$on("diy-preview-copy", (item = {}) => {
  605. this.copy(item)
  606. })
  607. this.$eventBus.$on("diy-preview-operateFn", (item = {}) => {
  608. this.operateFn(item)
  609. })
  610. this.$eventBus.$on("diy-back-set", () => {
  611. this.updateView(null, -1)
  612. })
  613. },
  614. validateCount(e) {
  615. // 校验组件能添加几个
  616. var msg = "";
  617. var list = this.previewList.filter(item => {
  618. return item.funcListItem.type === e.type
  619. });
  620. if (e && e.count && list.length >= e.count) {
  621. msg = `该组件只能添加${e.count}个哦`
  622. }
  623. if (msg) {
  624. this.$message({
  625. message: msg,
  626. type: 'warning'
  627. });
  628. }
  629. return msg
  630. },
  631. getIsTopArrLength() {
  632. return this.previewList.filter(item => {
  633. const e1 = item.funcListItem || {}
  634. return e1.is_top
  635. }).length
  636. },
  637. changeDiyItem(item, index, params = {}) {
  638. var {
  639. type
  640. } = params
  641. var list = deepClone(this.previewList) // 克隆一下
  642. if (type !== "isShow") {
  643. // 显示问题 -- 样式组件不让修改
  644. item.isShow = list[this.activeIndex].isShow;
  645. }
  646. // 直接全部覆盖
  647. list[this.activeIndex] = deepClone(item)
  648. this.activeItem = deepClone(item)
  649. this.previewList = list
  650. },
  651. selectItme(item, index) {
  652. console.info(item);
  653. if (this.activeIndex == index) {
  654. this.activeIndex = -1
  655. this.activeItem = null
  656. } else {
  657. this.activeIndex = index
  658. this.activeItem = item
  659. }
  660. console.info();
  661. this.$forceUpdate()
  662. },
  663. pushItem(list = [], target = {}) {
  664. var result = deepClone(list)
  665. result.push(target)
  666. return result
  667. },
  668. /**
  669. * 两种形式,一种push,追加index
  670. */
  671. addIndexItem(list = [], target = {}, index) { // 往指定的index添加item
  672. var result = deepClone(list)
  673. if (this.activeIndex < 0) {
  674. result.push(target)
  675. } else {
  676. var handleArr = [deepClone(result[index]), target]
  677. result.splice(index, 1, ...handleArr)
  678. }
  679. return result
  680. },
  681. // 操作相关
  682. copy() {
  683. if (!this.activeItem || this.activeItem.disabled || this.activeItem.is_copy === false) {
  684. return
  685. }
  686. var item = deepClone(this.activeItem)
  687. item.id = getRandomId()
  688. this.previewList = this.addIndexItem(this.previewList, item, this.activeIndex)
  689. },
  690. /**
  691. * @params {string} obj.type up - down - show
  692. */
  693. operateFn(obj) {
  694. const methods = {
  695. show: 'showItem',
  696. up: 'upItem',
  697. down: 'downItem',
  698. delete: 'deleteItem'
  699. }
  700. this[methods[obj.type]](obj.index)
  701. },
  702. showItem(index) {
  703. var item = deepClone(this.activeItem);
  704. item.isShow = !item.isShow
  705. this.changeDiyItem(item, index, {
  706. type: "isShow"
  707. })
  708. },
  709. updateView(item, index) {
  710. this.activeItem = item
  711. this.activeIndex = index
  712. },
  713. deleteItem(index) {
  714. if (this.activeItem.disabled || this.activeItem.is_delete === false) {
  715. return false
  716. }
  717. this.previewList.splice(index, 1);
  718. // 删除后失去焦点
  719. this.activeIndex = -1;
  720. this.activeItem = null;
  721. },
  722. upItem(index) {
  723. const topArr = this.previewList.filter(item => {
  724. const e1 = item.funcListItem || {}
  725. return e1.is_top
  726. }) // 操作上限
  727. const topIndex = Math.max(0, topArr.length)
  728. if (index <= 0 || this.activeItem.disabled || this.activeItem.is_up === false) {
  729. return false
  730. } else if (index <= topIndex) {
  731. alert("不可以再操作了噢");
  732. return false
  733. }
  734. var previewList = deepClone(this.previewList);
  735. this.previewList = this.swapItems(previewList, index, index - 1);
  736. this.updateView(this.previewList[index - 1], index - 1);
  737. },
  738. downItem(index) {
  739. if (this.activeItem.disabled || this.activeItem.is_down === false) {
  740. return false
  741. } else if (index === this.previewList.length - 1) {
  742. alert("不可以再操作了噢");
  743. return false
  744. }
  745. var previewList = deepClone(this.previewList);
  746. this.previewList = this.swapItems(previewList, index, index + 1);
  747. this.updateView(this.previewList[index + 1], index + 1);
  748. },
  749. swapItems(arr, index1, index2) {
  750. var item = deepClone(arr[index1]);
  751. arr[index1] = arr[index2]
  752. arr[index2] = item
  753. return arr
  754. },
  755. changeMove(e) {
  756. const {
  757. newIndex,
  758. list
  759. } = e
  760. // 移动拖拽改变索引
  761. this.previewList = deepClone(list);
  762. this.updateView(this.previewList[newIndex], newIndex);
  763. },
  764. // 更新主页面
  765. updateMainPage(item) {
  766. this.mainPage = deepClone(item);
  767. },
  768. // 处理兼容老数据
  769. addIsTop(list, type) {
  770. const obj = {
  771. ['nav']: 1,
  772. ['member-info']: 2
  773. }
  774. const top = obj[type]
  775. list.forEach(item => {
  776. if (item.funcListItem.type === type && !item.funcListItem.is_top) {
  777. item.funcListItem.is_top = top
  778. }
  779. });
  780. return list
  781. }
  782. }
  783. })
  784. // 拦截页面卸载
  785. /* window.onbeforeunload = function(e) {
  786. var e = window.event || e;
  787. e.returnValue = ("确定离开当前页面吗?");
  788. } */
  789. </script>
  790. <style>
  791. #app {
  792. display: flex;
  793. flex-direction: column;
  794. min-width: 1250px;
  795. }
  796. #diy-test-preview {
  797. margin: auto;
  798. }
  799. .diy-header-backs {
  800. cursor: pointer;
  801. }
  802. .fixed {
  803. position: fixed;
  804. left: 0;
  805. top: 0;
  806. width: 100%;
  807. height: 100%;
  808. z-index: 999;
  809. }
  810. .diy-header {
  811. height: 60px;
  812. background: #313131;
  813. opacity: 1;
  814. border-radius: 0px;
  815. justify-content: space-between;
  816. font-size: 13px;
  817. font-family: PingFang SC;
  818. font-weight: bold;
  819. color: #FFFFFF;
  820. padding: 0 30px;
  821. }
  822. .diy-contain {
  823. flex: 1;
  824. overflow: auto;
  825. background: #F4F6F8;
  826. justify-content: space-between;
  827. }
  828. .diy-func-list {
  829. box-sizing: border-box;
  830. width: 354px;
  831. background: #FFFFFF;
  832. border-radius: 0px;
  833. }
  834. .diy-preview {
  835. flex: 1;
  836. background: #F4F6F8;
  837. justify-content: space-around;
  838. }
  839. .fill-box {
  840. position: relative;
  841. width: 467px;
  842. height: 100%;
  843. }
  844. .flex {
  845. display: flex;
  846. }
  847. .flex-x-center {
  848. justify-content: center;
  849. }
  850. .flex-y-center {
  851. align-items: center;
  852. }
  853. /* */
  854. .fade-enter-active,
  855. .fade-leave-active {
  856. transition: opacity 1s;
  857. }
  858. .fade-enter,
  859. .fade-leave-to {
  860. opacity: 0;
  861. }
  862. .diy-text-font {
  863. font-size: 13px;
  864. font-weight: 700;
  865. color: #999999;
  866. }
  867. .fill-border-top {
  868. border-top: 10px solid #F4F6F8;
  869. }
  870. .fill-border-bottom {
  871. border-bottom: 10px solid #F4F6F8;
  872. }
  873. /* 导航栏 */
  874. .custom-page {
  875. width: 181px;
  876. height: 60px;
  877. line-height: 60px;
  878. background: var(--diy-theme);
  879. font-weight: 700;
  880. border-radius: 0px;
  881. text-align: center;
  882. }
  883. .save {
  884. font-size: 24px;
  885. vertical-align: middle;
  886. }
  887. .save+span {
  888. vertical-align: middle;
  889. }
  890. .sava_btn .el-button--primary {
  891. background: var(--diy-theme);
  892. border-color: var(--diy-theme);
  893. padding: 8px 14px;
  894. }
  895. .diy_nav_right>div {
  896. padding: 8px 14px;
  897. }
  898. .diy_nav_right .sava_btn {
  899. padding: 0;
  900. }
  901. .page_set>i {
  902. font-size: 24px;
  903. vertical-align: middle;
  904. }
  905. .page_set>span {
  906. vertical-align: middle;
  907. }
  908. .xiaoshou {
  909. cursor: pointer;
  910. }
  911. :root {
  912. /* 主题色 */
  913. --diy-theme: #F10009;
  914. /* 主要字体颜色 */
  915. --diy-color: #F10009;
  916. }
  917. /* 修改ele默认样式 */
  918. /* slider组件 */
  919. .el-slider__bar {
  920. background-color: var(--diy-theme);
  921. }
  922. .el-slider__button {
  923. border-color: var(--diy-theme);
  924. }
  925. /* input组件 */
  926. .el-input .el-input__inner:focus {
  927. border: 1px solid var(--diy-theme);
  928. }
  929. /* textarea */
  930. .el-textarea .el-textarea__inner:focus {
  931. border: 1px solid var(--diy-theme);
  932. }
  933. /* radio单选组件 */
  934. .el-radio__input.is-checked+.el-radio__label {
  935. color: var(--diy-color);
  936. }
  937. .el-radio__input.is-checked .el-radio__inner {
  938. border-color: var(--diy-theme);
  939. background: var(--diy-theme);
  940. }
  941. .el-radio-button__orig-radio:checked+.el-radio-button__inner {
  942. border-color: var(--diy-theme);
  943. box-shadow: -1px 0 0 0 var(--diy-theme);
  944. }
  945. /* 多选 */
  946. .el-checkbox__input.is-checked+.el-checkbox__label {
  947. color: var(--diy-color);
  948. }
  949. .el-checkbox__input.is-checked .el-checkbox__inner,
  950. .el-checkbox__input.is-indeterminate .el-checkbox__inner {
  951. border-color: var(--diy-theme);
  952. background: var(--diy-theme);
  953. }
  954. </style>