Merge branch 'feature/20231008-tinymce-link-popup'

# Conflicts:
#	src/views/planetDesign/Design/questions/paging/Paging.vue
This commit is contained in:
钱冠学
2023-10-31 13:41:22 +08:00
5 changed files with 103 additions and 17 deletions

View File

@@ -2,7 +2,24 @@
<a-config-provider :autoInsertSpaceInButton="false" :locale="locale">
<Loading v-if="appLoading" :description="appLoadingDescription"/>
<router-view />
<div class="link-action-wrapper" @click="clickAction">
<router-view />
</div>
<a-modal
centered
:width="700"
:visible="show"
:title="title"
:maskClosable="true"
:closable="true"
wrapClassName="custom-modal"
:footer="null"
>
<template #closeIcon>
<i class="iconfont model-close" @click="show=false">&#xe68b;</i>
</template>
<iframe v-if="show" :src="url" class="iframe"></iframe>
</a-modal>
</a-config-provider>
</template>
@@ -23,8 +40,10 @@ export default {
const route = useRoute();
const router = useRouter();
const store = useStore();
const title = ref('');
const show = ref(false);
const url = ref('');
const emitter = useEmitter();
const appLoading = ref(false);
const appLoadingDescription = ref('请您稍候~');
emitter.on('app-loading', (evt) => {
@@ -64,10 +83,22 @@ export default {
// }
// })
// })
const clickAction = (e) => {
if(e.target.getAttribute("data-linkType") === '1'){
show.value = true;
title.value = e.target.innerText;
url.value = e.target.href;
e.preventDefault();
}
}
return {
locale,
appLoading,
appLoadingDescription,
clickAction,
show,
url,
title,
};
},
};
@@ -154,4 +185,16 @@ strong {
.viewer-container {
transition: all 0.01s !important;
}
.iframe {
flex: 1;
width: 100%;
height: 500px;
border: 0;
}
.link-action-wrapper {
width: 100%;
height: 100%;
}
</style>

View File

@@ -29,6 +29,18 @@
<a-form-item label="显示文字">
<a-input v-model:value="linkText" placeholder="请输入显示的文字" />
</a-form-item>
<a-form-item label="打开方式">
<div style="padding-top: 5px">
<a-radio-group class="custom-radio-group" v-model:value="linkType">
<a-radio class="custom-radio" :value="'1'">弹窗</a-radio>
<a-radio class="custom-radio" :value="'2'">新页面</a-radio>
<a-radio class="custom-radio" :value="'3'">当前页面</a-radio>
</a-radio-group>
</div>
<p style="margin-top: 3px;font-size: 13px; color: #979797">{{ `${linkType === '1' ? '链接内容将在当前页面内弹窗显示。' :
linkType === '2' ? '链接内容将在新页签内显示,可切换页面回到问卷答题页。' :
'链接在当前页面打开,覆盖问卷答题页面,建议开启“断点续答”后使用。'}` }}</p>
</a-form-item>
</a-form>
</a-modal>
<a-modal
@@ -372,9 +384,8 @@ export default {
const route = useRoute();
const sn = computed(() => route.query.sn || "");
const fixation = ref(props.isFixation)
const { linkAddress, linkText, linkDialogVisible, linkDiglogOkHandle } =
const { linkAddress, linkText, linkType, linkDialogVisible, linkDiglogOkHandle } =
linkDialog(fixation);
const {
d3Address,
d3Width,
@@ -417,6 +428,7 @@ export default {
context,
linkDialogVisible,
linkAddress,
linkType,
linkText,
d3DialogVisible,
d3Address,
@@ -478,6 +490,7 @@ export default {
editorId,
linkAddress,
linkText,
linkType,
init,
fileInput,
content,
@@ -529,6 +542,7 @@ function initTinymce(data) {
linkDialogVisible,
linkAddress,
linkText,
linkType,
d3DialogVisible,
d3Address,
d3Width,
@@ -652,6 +666,11 @@ function initTinymce(data) {
tinymce.editors[editor.id].selection.select(wrapperNode, true);
linkText.value = wrapperNode.innerText;
linkAddress.value = wrapperNode.href || "";
linkType.value = wrapperNode.getAttribute("data-linkType") || "1";
} else {
linkText.value = "";
linkAddress.value = "";
linkType.value = "1";
}
linkDialogVisible.value = true;
},
@@ -704,6 +723,7 @@ function initTinymce(data) {
paste_data_images: true,
setup: function (editor) {
editorId.value = editor.id;
linkType.value = editor.linkType;
editor.ui.registry.addIcon("linkIcon", link);
editor.ui.registry.addButton("linkButton", {
icon: "linkIcon",
@@ -717,6 +737,11 @@ function initTinymce(data) {
tinymce.editors[editor.id].selection.select(wrapperNode, true);
linkText.value = wrapperNode.innerText;
linkAddress.value = wrapperNode.href || "";
linkType.value = wrapperNode.getAttribute("data-linkType") || "1";
} else {
linkText.value = "";
linkAddress.value = "";
linkType.value = "1";
}
linkDialogVisible.value = true;
},
@@ -849,6 +874,7 @@ function linkDialog(fixation) {
const linkAddress = ref("");
const linkText = ref(""); // 用于显示
const linkDialogVisible = ref(false);
const linkType = ref("1")
const linkDiglogOkHandle = (id) => {
if (!linkAddress.value || !linkText.value) {
message.info("请输入文字和链接地址");
@@ -857,29 +883,43 @@ function linkDialog(fixation) {
if (!linkAddress.value.startsWith("http")) {
linkAddress.value = `https://${linkAddress.value}`;
}
let value = "";
// 插入链接前后加空格
if(fixation.value) {
tinymce.editors[id].execCommand(
"mceInsertContent",
false,
`&nbsp;<a href="${linkAddress.value}">${linkText.value}</a>&nbsp;`
);
}else{
tinymce.editors[id].execCommand(
"mceInsertContent",
false,
`<a href="${linkAddress.value}">${linkText.value}</a>`
);
value = `&nbsp;<a data-linkType="${linkType.value}" href="${linkAddress.value}">${linkText.value}</a>&nbsp;`;
if (linkType.value === '2') {
value = `&nbsp;<a data-linkType="${linkType.value}" href="${linkAddress.value}" target="_blank">${linkText.value}</a>&nbsp;`;
} else if (linkType.value === '1') {
value = `&nbsp;<a data-linkType="${linkType.value}" href="${linkAddress.value}">${linkText.value}</a>&nbsp;`;
}
} else {
value = `<a data-linkType="${linkType.value}" href="${linkAddress.value}">${linkText.value}</a>`;
if(linkType.value === '2'){
value = `<a data-linkType="${linkType.value}" target="_blank" href="${linkAddress.value}">${linkText.value}</a>`;
}else if(linkType.value === '1'){
value = `<a data-linkType="${linkType.value}" href="${linkAddress.value}">${linkText.value}</a>`;
}
}
tinymce.editors[id].execCommand(
"mceInsertContent",
false,
`${value}`,
);
linkDialogVisible.value = false;
linkAddress.value = "";
linkText.value = "";
linkType.value = "1";
};
const clickOutside = () => {
}
return {
linkType,
linkAddress,
linkText,
linkDialogVisible,
linkDiglogOkHandle,
clickOutside,
};
}
/**

View File

@@ -32,6 +32,7 @@ app.use(VXETable);
app.use(VueParticles);
app.use(NutBig);
app.use(lazyPlugin, {});
app.directive("click-outside", {
// 当被绑定的元素挂载到 DOM 中时……
mounted(el, binding) {

View File

@@ -222,6 +222,7 @@
@click.stop=""
@activePage="pitchOnHandle(element)"
@removePage="removePageHandle(index)"
@selectPage="selectPageHandle(index)"
/>
</div>
<template

View File

@@ -10,7 +10,8 @@
<i class="iconfont active-icon" :style="{marginRight: isLastPage ? '0' : '16px'}"
@click="activePage">&#xe86c;</i>
<template v-if="!isLastPage">
<i class="iconfont moverQues" style="margin-right: 16px;">&#xe71b;</i>
<i class="iconfont" style="margin-right: 16px;" @click="selectPaging">&#xe71b;</i>
<i class="iconfont moverQues" style="margin-right: 16px;">&#xe71b;</i>
<i class="iconfont" @click="deleteHandle">&#xe6c5;</i>
</template>
</div>
@@ -21,7 +22,6 @@
<script>
import { computed } from "@vue/reactivity";
import { useStore } from "vuex";
export default {
name: "Paging",
props: {
@@ -49,6 +49,7 @@ export default {
activePage,
deleteHandle,
selectPaging,
};
},
};