sd-designer.vue 7.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. <script>
  2. /* eslint-disable */
  3. // sd-skip-auto-import
  4. import cloneDeep from"lodash.clonedeep";import flowForm from"@/webflow/sd-flow-form.vue";import pinyinUtil from"../../lib-external/pinyinUtil.js";import util from"./util";import components from"./_import-components/sd-designer-import";var _render=function t(){var e=this,s=e._self._c;return s("a-layout",{class:e.$style.wrapper,attrs:{"has-sider":true}},[s("a-layout-sider",{class:e.$style.left,attrs:{theme:"light",width:300}},[e.formProps?s("sd-component-library",{on:{itemDblClick:t=>e.$refs.main.addComponent(t)}},[!e.layoutable?s("a-collapse-panel",{key:"columns",attrs:{header:"布局列数"}},[s("a-menu",{attrs:{"selected-keys":[e.formProps.attrFD.columns],mode:"inline"},on:{select:e.columnsSelect}},e._l(4,(function(t){return s("a-menu-item",{key:t,attrs:{title:"一行 "+t+" 个字段"}},[s("sd-layout-preview",{attrs:{columns:t}})],1)})),1)],1):e._e()],1):e._e()],1),e.formProps?s("sd-main",{ref:"main",class:{[e.$style.invalid]:!e.isValid},on:{selectionChange:e.selectionChange},scopedSlots:e._u([{key:"header",fn:function(){return[s("span",{class:e.$style.toolbarLeft},[s("a-button",{attrs:{type:"link",title:e.undoMsg,disabled:!e.canUndo},on:{click:e.undo}},[s("a-icon",{attrs:{type:"sd-back-curve",theme:"filled"}}),e._v("撤销 ")],1),s("a-button",{attrs:{type:"link",disabled:!e.canRedo,title:e.redoMsg},on:{click:e.redo}},[s("a-icon",{class:e.$style.redoIcon,attrs:{type:"sd-back-curve",theme:"filled"}}),e._v("恢复 ")],1)],1),e._t("toolbar")]},proxy:true}],null,true)}):e._e(),s("a-layout-sider",{class:e.$style.right,attrs:{theme:"light",width:300}},[s("a-tabs",{class:e.$style.tabs,model:{value:e.propTabsIndex,callback:function(t){e.propTabsIndex=t},expression:"propTabsIndex"}},[s("a-tab-pane",{key:"1",attrs:{tab:"字段属性",disabled:!e.isValid}},[e.selected&&e.selected.attr?s("sd-component-props",{on:{validate:t=>{e.isValid=t;e.propTabsIndex="1"}}}):e._e()],1),e.showFormProps?s("a-tab-pane",{key:"2",attrs:{tab:"表单属性",disabled:!e.isValid}},[s("sd-form-props",{attrs:{"show-table-name":e.showTableName},on:{validate:t=>e.isValid=t}})],1):e._e()],1)],1)],1)};var staticRenderFns=[];_render._withStripped=true;export default{name:"SdDesigner",metaInfo(){return{title:this.formProps?.tableTxt}},components:{[flowForm.name]:flowForm,...components},model:{prop:"value",event:"change"},props:{value:{type:Object,default:void 0},showTableName:{type:Boolean,default:true},showFormProps:{type:Boolean,default:true}},data(){return{isValid:true,selectedID:void 0,visibleComponents:[],hiddenComponents:[],formProps:void 0,propTabsIndex:"1",singletonCids:[],snapshotLength:void 0,snapshotIndex:void 0}},computed:{selected(){return this.componentInstances.find((t=>t.attrFD.id===this.selectedID))},isPublished(){return this.formProps?.isDbSynch},componentInstances(){return this.visibleComponents.concat(this.componentInstancesInLayout).concat(this.hiddenComponents)},componentInstancesInLayout(){const t=[];util.processChildrenInLayout(this.visibleComponents,(e=>{t.push(e)}));return t},componentInstancesWithHiddenFlag(){return this.visibleComponents.map((t=>({...t,attrFD:{...t.attrFD,hidden:void 0}}))).concat(this.hiddenComponents.map((t=>({...t,attrFD:{...t.attrFD,hidden:true}}))))},disabledCids(){const t=[];this.componentInstances.forEach((e=>{if(this.singletonCids.includes(e.attrFD.cid))t.push(e.attrFD.cid)}));return t},layoutable(){return this.formProps?.attrFD.layoutable},canUndo(){return this.snapshotIndex>0},canRedo(){return this.snapshotLength-1>this.snapshotIndex},undoMsg(){if(!this.canUndo)return"无法撤销";return"撤销 "+this.snapshots[this.snapshotIndex].description},redoMsg(){if(!this.canRedo)return"无法恢复";return"恢复 "+this.snapshots[this.snapshotIndex+1].description}},watch:{value:{handler(t){this.updateData(t)},immediate:true},selected(t){if(!t)this.isValid=true},"hiddenComponents.length":{handler(t){this.hiddenComponents.forEach((t=>{this.$set(t,"required",false);this.$set(t,"mobileVisible",false)}))}}},created(){this.util=util;this.initSnapshot()},provide:function(){return{designer:this}},methods:{updateData(t){t=util.mergeTransientFields(t);const e=this.selected?.name;const s=[];const n=[];t.fields.map((e=>util.createInstance(e,{formProps:t.head}))).forEach((t=>{if(t.attrFD.hidden)s.push(t);else n.push(t)}));this.hiddenComponents=s;this.visibleComponents=n;this.formProps=t.head;if(e){const t=this.componentInstances.find((t=>t.name===e));this.selectedID=t.attrFD.id}else this.selectedID=n[0]?.attrFD.id},selectionChange(t){this.selectedID=t},getSaveData(){return util.getSaveData(this.componentInstancesWithHiddenFlag,this.formProps)},columnsSelect(t){const e=t.key;this.formProps.attrFD.columns=e;this.updateComponentsColumns(e)},updateComponentsColumns(t){["hiddenComponents","visibleComponents"].forEach((e=>{this[e].forEach((e=>{if(e.attrFD.columns>t)e.attrFD.columns=t}))}))},getCurrentComponentWrapper(){const t=this.$el.querySelector(".selected_sd-component-wrapper_form-designer");return t?.__vue__},deleteCurrentComponent(){this.getCurrentComponentWrapper()?.deleteComponent()},setComponentName(t){const e=this.componentInstances.find((e=>e.attrFD.id===t));if(!e||e.isDbSynch||"title"===e.dataType||this.formProps?.attrFD?.devMode||"currentNumber"===e.name||!e.name.startsWith(e.attrFD.cid.replace("sd-","").replace("xm-","")))return;const s=Array.from(e.caption);let n="";if(s.length<=2)n=pinyinUtil.getPinyin(e.caption).replace(/ /g,"");else n=s.map((t=>pinyinUtil.getPinyin(t)[0])).join("");n=n.replace(/[^0-9_a-zA-Z]/g,"").match(/[a-zA-Z]+.*/)?.[0];if(!n)n=e.name;n=n.substr(0,28);while(this.componentInstances.some((t=>t.name===n))){const t=n.match(/[0-9]+$/);if(null!=t)n=n.replace(/[0-9]+$/,"")+(Number(t[0])+1);else n+=1}e.name=n},initSnapshot(){this.snapshots=[];this.takeSnapshot("初始状态");this.snapshotIndex=0},syncSnapshotInfo(){this.snapshotLength=this.snapshots.length},getSnapshot(t){return cloneDeep({formProps:this.formProps,visibleComponents:this.visibleComponents,hiddenComponents:this.hiddenComponents,description:t})},takeSnapshot(t){const e=10;this.snapshots.splice(this.snapshotIndex+1,Number.MAX_SAFE_INTEGER,this.getSnapshot(t));if(this.snapshots.length>e)this.snapshots.shift();this.syncSnapshotInfo();this.snapshotIndex=this.snapshotLength-1;if(this.snapshots.length>1)this.$emit("change")},replaceSnapshot(){this.snapshots[this.snapshots.length-1]=this.getSnapshot(this.snapshots[this.snapshots.length-1].description)},revertToSnapshot(t){const e=cloneDeep(this.snapshots[t]);this.formProps=e.formProps;this.visibleComponents=e.visibleComponents;this.hiddenComponents=e.hiddenComponents;this.snapshotIndex=t},undo(){this.revertToSnapshot(this.snapshotIndex-1)},redo(){this.revertToSnapshot(this.snapshotIndex+1)}},render:_render,staticRenderFns:staticRenderFns};</script>
  5. <style module lang="scss">
  6. @use '@/common/design' as *;
  7. .wrapper {
  8. height: 100%;
  9. .left {
  10. overflow: auto;
  11. border-right: 1px solid $border-color-base;
  12. }
  13. .right {
  14. border-left: 1px solid $border-color-base;
  15. :global(.ant-form-item) {
  16. margin-bottom: $form-item-margin-bottom / 2;
  17. }
  18. }
  19. .card {
  20. display: flex;
  21. flex-direction: column;
  22. height: 100%;
  23. :global(.ant-card-head-title) {
  24. padding: 10px 0;
  25. text-align: center;
  26. }
  27. :global(.ant-card-body) {
  28. overflow: auto;
  29. }
  30. }
  31. .tabs {
  32. display: flex;
  33. flex-direction: column;
  34. height: 100%;
  35. padding-top: 1px;
  36. :global(.ant-tabs-bar) {
  37. margin: 0;
  38. :global(.ant-tabs-nav) {
  39. width: 100%;
  40. }
  41. :global(.ant-tabs-tab) {
  42. width: 50%;
  43. margin: 0;
  44. text-align: center;
  45. }
  46. }
  47. :global(.ant-tabs-content) {
  48. padding: $padding-md;
  49. overflow: auto;
  50. }
  51. }
  52. .invalid::after {
  53. position: absolute;
  54. top: 0;
  55. right: 0;
  56. bottom: 0;
  57. left: 0;
  58. cursor: not-allowed;
  59. content: '';
  60. background-color: $white;
  61. opacity: 0.5;
  62. }
  63. .toolbar-left {
  64. float: left;
  65. }
  66. .redo-icon {
  67. transform: scaleX(-1);
  68. }
  69. }
  70. </style>