| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- <template>
- <div>
- <div class="right-top">
- <div class="flex align-middle px-[8px]">
- <Lang/>
- </div>
- <div>
- <!-- <el-button text>分享</el-button>-->
- <el-button type="primary" @click="exportFile">下载</el-button>
- <el-button type="success" @click="onSaveTemplate">保存</el-button>
- <!-- <el-button text href="https://github.com/dromara/sd-designer" tag="a" target="_blank" rel="noopener noreferrer">-->
- <!-- <!– <a href="https://github.com/dromara/sd-designer" target="_blank" rel="noopener noreferrer"> –>-->
- <!-- <!– <el-tooltip placement="top" :hide-after="0" :content="t('message.github')"> –>-->
- <!-- <IconGithub class="footer-button"></IconGithub>-->
- <!-- <!– </el-tooltip> –>-->
- <!-- <!– </a> –>-->
- <!-- </el-button>-->
- </div>
- </div>
- <div class="right-bottom">
- <div class="right-tabs">
- <div
- class="tab"
- :class="[ tab.value === rightState && currentTabs.length > 1 ? 'active' : 'no-active' ]"
- v-for="tab in currentTabs"
- :key="tab.value"
- @click="setRightState(tab.value)"
- >
- {{ tab.label }}
- </div>
- </div>
- <div class="right-content">
- <component :is="currentPanelComponent"></component>
- </div>
- </div>
- <FileExport v-model:visible="exportFileDialog" @close="exportFileHide" @save="exportFileHandle"/>
- <el-dialog
- v-model="showSaveDlg"
- title="保存模板"
- width="580px"
- @close="closeSaveDlg">
- <el-form
- ref="formRef"
- :model="formData"
- :rules="rules"
- label-width="120px"
- >
- <el-row>
- <el-col :span="24">
- <el-form-item prop="templateName" label="模板名称">
- <el-input v-model.trim="formData.templateName"/>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
- <el-form-item prop="productIdentities" label="产品ID">
- <el-tag
- v-for="tag in productIdentities"
- :key="tag"
- closable
- :disable-transitions="false"
- @close="handleDeleteProductId(tag)"
- >
- {{ tag }}
- </el-tag>
- <el-input
- v-if="productInputVisible"
- ref="productInputRef"
- v-model.trim="productInputValue"
- style="width: 80px !important;"
- size="small"
- @keyup.enter="handleProductInputConfirm"
- @blur="handleProductInputConfirm"
- />
- <el-button v-else size="small" @click="showProductInput">
- + 产品ID
- </el-button>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="handleSubmit"
- >确 定
- </el-button>
- <el-button @click="showSaveDlg = false">取 消</el-button>
- </div>
- </template>
- </el-dialog>
- </div>
- </template>
- <script lang="ts" setup>
- import {computed, watch} from "vue";
- import {RightStates, ElementNames} from "@/types/elements";
- import {storeToRefs} from "pinia";
- import {useMainStore} from "@/store/modules/main";
- import Lang from "@/components/Lang/index.vue";
- import CanvasStylePanel from "./CanvasStylePanel/index.vue";
- import ElemnetStylePanel from "./ElementStylePanel/index.vue";
- import EffectStylePanel from "./EffectStylePanel/index.vue";
- import LayerStylePanel from "./LayerStylePanel/index.vue";
- import useI18n from "@/hooks/useI18n";
- import {useTemplatesStore} from "@/store";
- import useCanvasExport from "@/hooks/useCanvasExport";
- import {updateDesignTemplate} from "@/api/template";
- import {ElMessage, FormInstance} from "element-plus";
- import {getToken} from "@/utils/js-cookie";
- import useCanvas from "@/views/Canvas/useCanvas";
- const templatesStore = useTemplatesStore()
- const {getJSONData} = useCanvasExport()
- const {t} = useI18n();
- const mainStore = useMainStore();
- const {canvasObject, rightState} = storeToRefs(mainStore);
- const exportFileDialog = ref(false)
- const showSaveDlg = ref(false)
- const formRef = ref<FormInstance>();
- const productIdentities = ref([])
- const productInputVisible = ref(false)
- const productInputRef = ref()
- const productInputValue = ref("")
- const rules = reactive({
- templateName: [{required: true, message: "请输入名称", trigger: "blur"}],
- });
- const formData = reactive({
- templateName: '',
- productIdentity: '',
- jsonContent: '',
- id: 0,
- });
- const showProductInput = () => {
- productInputVisible.value = true
- nextTick(() => {
- productInputRef.value!.input!.focus()
- })
- }
- const handleDeleteProductId = (tag) => {
- productIdentities.value.splice(productIdentities.value.indexOf(tag), 1)
- }
- const handleProductInputConfirm = () => {
- if (productInputValue.value) {
- productIdentities.value.push(productInputValue.value)
- }
- productInputVisible.value = false
- productInputValue.value = ''
- }
- const exportFileHide = () => {
- exportFileDialog.value = false
- }
- const exportFileHandle = () => {
- exportFileDialog.value = false
- }
- const exportFile = () => {
- exportFileDialog.value = true
- }
- const onSaveTemplate = () => {
- if (!getToken('token')) {
- ElMessage.error('当前用户未登录,设计无法保存')
- return
- }
- //检查一下是否每个元素都给了itemName
- const [canvas] = useCanvas()
- const objects = canvas.getObjects().filter((object) => !["WorkSpaceMaskType", "WorkSpaceClipType", "WorkSpaceSafeType", "WorkSpaceClipType"].includes(object.id));
- if (objects.findIndex((object) => !object.itemName) >= 0) {
- ElMessage.error('部分元素未设置名称,请设置元素名称后保存')
- return
- }
- const groupByItemName = objects.reduce((acc, item) => {
- if (!acc[item.itemName]) {
- acc[item.itemName] = [];
- }
- acc[item.itemName].push(item);
- return acc;
- }, {});
- if (Object.keys(groupByItemName).length < objects.length) {
- ElMessage.error('部分元素名称重复,请保证各个元素名称唯一')
- return
- }
- formData.templateName = templatesStore.templateName
- productIdentities.value = templatesStore.productIdentity
- showSaveDlg.value = true
- }
- const handleSubmit = () => {
- formRef.value.validate((valid: any) => {
- if (valid) {
- formData.id = templatesStore.templateId
- formData.productIdentity = productIdentities.value ? productIdentities.value.join(",") : ""
- formData.jsonContent = getJSONData()
- updateDesignTemplate(JSON.stringify(formData)).then((res) => {
- if (res.httpCode == 200) {
- ElMessage.success('保存成功')
- showSaveDlg.value = false
- }
- })
- }
- })
- }
- const closeSaveDlg = () => {
- formData.id = 0
- formData.templateName = templatesStore.templateName
- formData.jsonContent = ''
- }
- const canvasTabs = [
- {label: t("style.canvas"), value: RightStates.ELEMENT_CANVAS},
- // { label: t("style.layer"), value: RightStates.ELEMENT_LAYER },
- ];
- const styleTabs = [
- {label: t("style.style"), value: RightStates.ELEMENT_STYLE},
- // { label: t("style.layer"), value: RightStates.ELEMENT_LAYER },
- ];
- const setRightState = (value: RightStates) => {
- mainStore.setRightState(value);
- };
- const currentTabs = computed(() => {
- if (!canvasObject.value) return canvasTabs;
- if (canvasObject.value.type.toLowerCase() === ElementNames.REFERENCELINE) return canvasTabs;
- return styleTabs;
- });
- watch(currentTabs, () => {
- const currentTabsValue: RightStates[] = currentTabs.value.map(
- (tab) => tab.value
- );
- if (!currentTabsValue.includes(rightState.value)) {
- mainStore.setRightState(currentTabsValue[0]);
- }
- });
- const currentPanelComponent = computed(() => {
- const panelMap = {
- [RightStates.ELEMENT_CANVAS]: CanvasStylePanel,
- [RightStates.ELEMENT_STYLE]: ElemnetStylePanel,
- [RightStates.ELEMENT_EFFECT]: EffectStylePanel,
- [RightStates.ELEMENT_LAYER]: LayerStylePanel,
- };
- return panelMap[rightState.value as RightStates.ELEMENT_STYLE];
- });
- </script>
- <style lang="scss" scoped>
- .right-top {
- height: 40px;
- width: 100%;
- display: flex;
- align-items: center;
- border-bottom: 1px solid $borderColor;
- }
- .right-bottom {
- height: calc(100% - 40px);
- }
- .right-tabs {
- height: 32px;
- font-size: 12px;
- flex-shrink: 0;
- display: flex;
- user-select: none;
- }
- .tab {
- flex: 1;
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: $lightGray;
- border-bottom: 1px solid $borderColor;
- cursor: pointer;
- &.active {
- background-color: #fff;
- border-bottom-color: #fff;
- }
- & + .tab {
- border-left: 1px solid $borderColor;
- }
- }
- .right-content {
- padding: 10px 5px 10px 10px;
- font-size: 13px;
- overflow-y: scroll;
- overflow-x: hidden;
- height: 100%;
- // @include overflow-overlay();
- }
- </style>
|