| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- <template>
- <div style="display: flex; justify-content: center;">
- <div ref="stencilContainer" class="stencil" />
- <div ref="container" class="content" />
- <div style="z-index: 999; padding: 5px; width: 300px; background-color: #f5f5f5;">
- <a-form :model="formState">
- <a-form-item v-show="formState.height != null" label="高">
- <a-input v-model:value="formState.height" @change="heightChange" />
- </a-form-item>
- <a-form-item v-show="formState.width != null" label="宽">
- <a-input v-model:value="formState.width" @change="widthChange" />
- </a-form-item>
- <a-form-item v-show="formState.text != null" label="内容">
- <a-input v-model:value="formState.text" @change="textChange" />
- </a-form-item>
- <a-form-item v-show="formState.type != null" label="节点类型">
- <a-input v-model:value="formState.type" disabled @change="typeChange" />
- </a-form-item>
- <a-form-item v-show="formState.textColor != null" label="文字颜色">
- <a-input v-model:value="formState.textColor" type="color" @change="textColorChange" />
- </a-form-item>
- <a-form-item v-show="formState.border != null" label="边框颜色">
- <a-input v-model:value="formState.border" type="color" @change="borderChange" />
- </a-form-item>
- <a-form-item v-show="formState.imgUrl != null" label="图片地址">
- <a-input v-model:value="formState.imgUrl" @change="imgUrlChange" />
- </a-form-item>
- </a-form>
- </div>
- </div>
- <a-divider />
- <div style="display: flex; justify-content: space-between; width: 100%">
- <a-button @click="before">上一步</a-button>
- <div>
- <a-button @click="output">保存模版</a-button>
- <a-modal
- v-model:visible="visible" title="请填写模版名称" ok-text="确认"
- cancel-text="取消" @ok="handleOk"
- >
- <a-input v-model:value="TempName" placeholder="请输入模版名称" />
- </a-modal>
- <a-button @click="getPng">预览图片</a-button>
- <a-modal
- v-model:visible="imgVisible" title="预览图片" ok-text="确认"
- cancel-text="取消" @ok="imgHandleOk"
- >
- <div style=" display: flex; justify-content: center;"><img style="border: 1px solid #000;" :src="imgBase64" alt="" /></div>
- </a-modal>
- </div>
- </div>
- </template>
- <script setup>
- import { ref, h ,onMounted , computed } from 'vue';
- import { Graph, Shape, Addon, DataUri } from '@antv/x6';
- import { useRoute,useRouter} from 'vue-router';
- import { useStore } from 'vuex';
- import { Modal } from 'ant-design-vue';
- import Common from '../../common/Common.js';
- const route = useRoute();
- const router = useRouter();
- const store = useStore();
- const { Stencil ,Dnd} = Addon;
- let dnd = null;
- const CreateDnd = () =>{
- dnd = new Dnd({
- target:graph,
- });
- };
- const { Rect, Image } = Shape;
- let cellTem = null;
- const TemText = computed(()=> store.state.downloadStore.tempText );
- const TempId = computed(()=> store.state.downloadStore.templateId );
- const TempName = ref('');
- const imgBase64 = ref('');
- let graph = null;
- const formState = ref({
- text: null,
- textColor: null,
- border: null,
- imgUrl: null,
- height: null,
- width: null,
- type: null,
- });
- const container = ref(null);
- const stencilContainer = ref(null);
- const visible = ref(false);
- const handleOk = () => {
- if (TempName.value == '') {
- Modal.info({
- title: '提示',
- content: h('div', {}, [h('p', '模版名称不能为空')]),
- onOk() {
- console.log('ok');
- },
- });
- return;
- }
- visible.value = false;
- let json = graph.toJSON();
- console.log(json.cells);
- $.ajax({
- url:'/api/printPageResource/uploadCustomerPrintTemplateX6',
- type: 'post',
- // contentType: 'application/json',
- dataType:'json',
- data:{
- no:moment(new Date()).format('YYYY-MM-DD HH:mm'),
- name:TempName.value,
- contentX6:JSON.stringify(json),
- type:'X6',
- id:TempId.value,
- },
- beforeSend: function(request) {
- Common.addTokenToRequest(request);
- },
- success:res=>{
- // console.log(res);
- if (res) {
- Modal.info({
- title: '提示',
- content: h('div', {}, [h('p', '上传成功!')]),
- onOk() {
- },
- });
- }else{
- Modal.info({
- title: '提示',
- content: h('div', {}, [h('p', res)]),
- onOk() {
- },
- });
- }
- },
- error:e=>{
- Common.processException(e);
- },
- });
- console.log('发请求');
- };
- const imgVisible = ref(false);
- const imgHandleOk = () => {
- imgVisible.value = false;
- };
- const before = () =>{
- store.commit('changeStep',0);
- };
- const textChange = () => {
- cellTem.attr('label/text', formState.value.text);
- };
- const output = () => {
- visible.value = true;
- // console.log(graph.toJSON());
- // console.log(JSON.stringify(graph.toJSON()));
- };
- const getPng = () => {
- graph.toJPEG(dataUri => {
- // 下载
- imgVisible.value = true;
- imgBase64.value = dataUri;
- console.log(dataUri);
- // DataUri.downloadDataUri(dataUri, 'temp.jpeg');
- }, {
- serializeImages: true,
- quality: 1,
- });
- };
- const textColorChange = () => {
- cellTem.attr('text/fill', formState.value.textColor);
- };
- const borderChange = () => {
- cellTem.attr('rect/stroke', formState.value.border);
- };
- const imgUrlChange = () => {
- cellTem.attr('image/xlink:href', formState.value.imgUrl);
- };
- const typeChange = e =>{
- cellTem.data.type = e.target.value;
- };
- const widthChange = () => {
- cellTem.size(formState.value.width, formState.value.height);
- };
- const heightChange = () => {
- cellTem.size(formState.value.width, formState.value.height);
- };
- const setGraph = () => {
- graph = new Graph({
- container: container.value,
- width: 400,
- height: 400,
- background: {
- color: '#ddd',
- },
- grid: {
- size: 10,
- visible: true,
- },
- history: true,
- resizing: {
- enabled: true,
- restricted: true,
- // 让节点成为另一个节点的子节点
- // embedding: {
- // enabled: true,
- // findParent({ node }) {
- // const bbox = node.getBBox()
- // return this.getNodes().filter((node) => {
- // // 只有 data.parent 为 true 的节点才是父节点
- // const data = node.getData()
- // if (data && data.parent) {
- // const targetBBox = node.getBBox()
- // return bbox.isIntersectWithRect(targetBBox)
- // }
- // return false
- // })
- // }
- // }
- },
- });
- graph.on('cell:mouseenter', ({ cell }) => {
- if (cell.data.parent) {
- return;
- }
- if (cell.isNode()) {
- cell.addTools([
- {
- name: 'button-remove',
- args: {
- x: 0,
- y: 0,
- offset: { x: 10, y: 10 },
- },
- },
- ]);
- }
- });
- graph.on('cell:mouseleave', ({ cell }) => {
- cell.removeTools();
- });
- graph.on('cell:click', ({ cell }) => {
- console.log(cell);
- formState.value.text = null;
- formState.value.textColor = null;
- formState.value.border = null;
- formState.value.imgUrl = null;
- formState.value.type = null;
- cellTem = null;
- cellTem = cell;
- if (cell.attrs.label != undefined && cell.attrs.label.text != null) {
- formState.value.text = cell.attrs.label.text;
- }
- if (cell.attrs.text != undefined && cell.attrs.text.fill != null) {
- formState.value.textColor = cell.attrs.text.fill;
- }
- if (cell.attrs.rect != undefined && cell.attrs.rect.stroke != null) {
- formState.value.border = cell.attrs.rect.stroke;
- }
- if (cell.data.type) {
- formState.value.type = cell.data.type;
- }
- if (cell.attrs.image != undefined && cell.attrs.image['xlink:href'] != null) {
- formState.value.imgUrl = cellTem.attrs.image['xlink:href'];
- }
- formState.value.height = cellTem.size().height;
- formState.value.width = cellTem.size().width;
- });
- // 创建节点
- const Box = new Shape.Rect({
- x: 100,
- y: 200,
- width: 200,
- height: 100,
- // angle: 30,
- attrs: {
- rect: {
- stroke: '#FFFFFF',
- },
- },
- data: {
- parent: true,
- type:'根节点',
- },
- });
- // 添加到画布
- graph.addNode(Box);
- };
- const setStencil = () => {
- const stencil = new Stencil({
- // title: '节点',
- target: graph,
- stencilGraphWidth: 300,
- // collapsable: true,
- groups: [
- {
- name: 'group',
- title: TemText.value,
- graphWidth: 300,
- graphHeight: 200,
- },
- ],
- });
- const tem1 = new Rect({
- width: 100,
- height: 50,
- stroke:'#FFFFFF',
- attrs: {
- label: {
- fontSize: 12,
- text: '文本',
- refX: 0,
- // refY: 5,
- textAnchor: 'start',
- textVerticalAnchor: 'middle',
- },
- rect: {
- stroke: '#FFFFFF',
- },
- },
- data:{
- type:'静态文本',
- },
- });
- const tem2 = new Rect({
- width: 100,
- height: 50,
- attrs: {
- label: {
- fontSize: 12,
- text: '动态文本:',
- refX: 0,
- // refY: 5,
- textAnchor: 'start',
- textVerticalAnchor: 'middle',
- },
- rect: {
- stroke: '#FFFFFF',
- },
- },
- data:{
- type:'动态文本',
- },
- });
- const tem3 = new Image({
- width: 96,
- height: 30,
- data:{
- type:'图片',
- },
- imageUrl: 'data:image/png;base64,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',
- });
- const tem4 = new Image({
- width: 50,
- height: 50,
- data:{
- type:'二维码',
- },
- imageUrl: `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQAQAAAACoxAthAAAABGdBTUEAALGPC/xhBQ
- AAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAd2KE6QAAAAJcEhZcwAAFxEAABcRA
- com8z8AAADvSURBVHja7dZBbgQhDARA/v/pRNHIQwOz2d2zyydsKG4tGD9f10AQBEGQj8hY6q+v2bmHIEgEaFufewiCZLyu2Xixh
- yDI+hwlRRDk/4hVhyDIE6lKklGLPQRpTrLWZ2nfQ5Du5KzxYo4gSB3aIzZpdgiCrN+1eWRegiDItczv2/1V2+J19wjSnOxxml0+V
- EvEEKQxSboG61ghSGuy1zx2zhCkOxlLPV2RFyBId7Ju731diyBIHbuGk9R0zrZfH4IgEbr5SGXwEAR5iliSD1OJIC1IVa5rcoG7
- R5DmJKvg/QQ9RwxBmpLvCkEQBEHe1i8/Fy+ejOFn3QAAAABJRU5ErkJggg==`,
- });
- stencil.load([tem1, tem2, tem3, tem4], 'group');
- stencilContainer.value.appendChild(stencil.container);
- };
- onMounted(() => {
- console.log('加载完毕');
- setGraph();
- setStencil();
- CreateDnd();
- dnd.start();
- let temp = store.state.downloadStore.templateVal;
- if (temp != '') {
- console.log(temp);
- console.log('非空');
- graph.fromJSON(JSON.parse(temp));
- }
- });
- </script>
- <style>
- .stencil {
- width: 300px;
- position: relative;
- }
- </style>
|