🧹 清理重复配置文件
- 删除根目录中重复的 NestJS 配置文件 - 删除 tsconfig.json, tsconfig.build.json, eslint.config.mjs, .prettierrc - 保留 wwjcloud-nest/ 目录中的完整配置 - 避免配置冲突,确保项目结构清晰
This commit is contained in:
644
admin-vben/src/app/views/diy/components/edit-rubik-cube.vue
Normal file
644
admin-vben/src/app/views/diy/components/edit-rubik-cube.vue
Normal file
@@ -0,0 +1,644 @@
|
||||
<template>
|
||||
<!-- 内容 -->
|
||||
<div class="content-wrap rubik-cube" v-show="diyStore.editTab == 'content'">
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('selectStyle') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('template')">
|
||||
<span>{{ selectTemplate.name }}</span>
|
||||
</el-form-item>
|
||||
<ul class="selected-template-list">
|
||||
<li v-for="(item,i) in templateList" :key="i"
|
||||
:class="[(item.className == diyStore.editComponent.mode) ? 'selected' : '' ]"
|
||||
@click="changeTemplateList(i)">
|
||||
<icon :name="'iconfont ' + item.src" size="16px" />
|
||||
</li>
|
||||
</ul>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('rubikCubeLayout') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
|
||||
<ul class="layout">
|
||||
<li v-for="(li,i) in selectTemplate.dimensionScale" :key="i" :class="[selectTemplate.className]">
|
||||
<div class="have-preview-image" v-show="diyStore.editComponent.list[i].imageUrl && diyStore.editComponent.list[i].imageUrl != 'static/resource/images/diy/figure.png'">
|
||||
<img :src="img(diyStore.editComponent.list[i].imageUrl)" />
|
||||
</div>
|
||||
<div class="empty" :class="[selectTemplate.className]" v-show="!diyStore.editComponent.list[i].imageUrl || diyStore.editComponent.list[i].imageUrl == 'static/resource/images/diy/figure.png'">
|
||||
<p>{{ li.name }}</p>
|
||||
<p>{{ li.desc }}</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div v-for="(item) in diyStore.editComponent.list" :key="item.id" class="item-wrap p-[10px] pb-0 relative border border-dashed border-gray-300 mb-[16px]">
|
||||
<el-form-item :label="t('image')">
|
||||
<upload-image v-model="item.imageUrl" :limit="1" @change="selectImg" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('link')">
|
||||
<diy-link v-model="item.link" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
</el-form>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 样式 -->
|
||||
<div class="style-wrap" v-show="diyStore.editTab == 'style'">
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('rubikCubeStyle') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('imageGap')">
|
||||
<el-slider v-model="diyStore.editComponent.imageGap" show-input size="small" class="ml-[10px] diy-nav-slider" :max="30" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('topRounded')">
|
||||
<el-slider v-model="diyStore.editComponent.topElementRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('bottomRounded')">
|
||||
<el-slider v-model="diyStore.editComponent.bottomElementRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!-- 组件样式 -->
|
||||
<slot name="style"></slot>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import useDiyStore from '@/stores/modules/diy'
|
||||
import { img } from '@/utils/common'
|
||||
|
||||
const diyStore = useDiyStore()
|
||||
diyStore.editComponent.ignore = [] // 忽略公共属性
|
||||
|
||||
// 组件验证
|
||||
diyStore.editComponent.verify = (index: number) => {
|
||||
const res = { code: true, message: '' }
|
||||
diyStore.value[index].list.forEach((item: any) => {
|
||||
if (item.imageUrl === '') {
|
||||
res.code = false
|
||||
res.message = t('imageUrlTip')
|
||||
return res
|
||||
}
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
const templateList = ref([
|
||||
{
|
||||
name: '1行2个',
|
||||
src: 'iconyihang2gepc1',
|
||||
className: 'row1-of2',
|
||||
dimensionScale: [
|
||||
{
|
||||
desc: '宽度50%',
|
||||
size: '200px * 200px',
|
||||
name: '图一'
|
||||
},
|
||||
{
|
||||
desc: '宽度50%',
|
||||
size: '200px * 200px',
|
||||
name: '图二'
|
||||
}
|
||||
],
|
||||
descAux: '选定布局区域,在下方添加图片,建议添加尺寸一致的图片,宽度最小建议为:200px'
|
||||
},
|
||||
{
|
||||
name: '1行3个',
|
||||
src: 'iconyihang3gepc',
|
||||
className: 'row1-of3',
|
||||
dimensionScale: [
|
||||
{
|
||||
desc: '宽度33.33%',
|
||||
size: '200px * 200px',
|
||||
name: '图一'
|
||||
},
|
||||
{
|
||||
desc: '宽度33.33%',
|
||||
size: '200px * 200px',
|
||||
name: '图二'
|
||||
},
|
||||
{
|
||||
desc: '宽度33.33%',
|
||||
size: '200px * 200px',
|
||||
name: '图三'
|
||||
}
|
||||
],
|
||||
descAux: '选定布局区域,在下方添加图片,建议添加尺寸一致的图片,宽度最小建议为:130px'
|
||||
},
|
||||
{
|
||||
name: '1行4个',
|
||||
src: 'iconyihang4gepc',
|
||||
className: 'row1-of4',
|
||||
dimensionScale: [
|
||||
{
|
||||
desc: '宽度25%',
|
||||
size: '200px * 200px',
|
||||
name: '图一'
|
||||
},
|
||||
{
|
||||
desc: '宽度25%',
|
||||
size: '200px * 200px',
|
||||
name: '图二'
|
||||
},
|
||||
{
|
||||
desc: '宽度25%',
|
||||
size: '200px * 200px',
|
||||
name: '图三'
|
||||
},
|
||||
{
|
||||
desc: '宽度25%',
|
||||
size: '200px * 200px',
|
||||
name: '图四'
|
||||
}
|
||||
],
|
||||
descAux: '选定布局区域,在下方添加图片,建议添加尺寸一致的图片,宽度最小建议为:100px'
|
||||
},
|
||||
{
|
||||
name: '2左2右',
|
||||
src: 'iconliangzuoliangyoupc',
|
||||
className: 'row2-lt-of2-rt',
|
||||
dimensionScale: [
|
||||
{
|
||||
desc: '宽度50%',
|
||||
size: '200px * 200px',
|
||||
name: '图一'
|
||||
},
|
||||
{
|
||||
desc: '宽度50%',
|
||||
size: '200px * 200px',
|
||||
name: '图二'
|
||||
},
|
||||
{
|
||||
desc: '宽度50%',
|
||||
size: '200px * 200px',
|
||||
name: '图三'
|
||||
},
|
||||
{
|
||||
desc: '宽度50%',
|
||||
size: '200px * 200px',
|
||||
name: '图四'
|
||||
}
|
||||
],
|
||||
descAux: '选定布局区域,在下方添加图片,建议添加尺寸一致的图片,宽度最小建议为:200px'
|
||||
},
|
||||
{
|
||||
name: '1左2右',
|
||||
src: 'iconyizuoliangyoupc',
|
||||
className: 'row1-lt-of2-rt',
|
||||
dimensionScale: [
|
||||
{
|
||||
desc: '宽度50% * 高度100%',
|
||||
size: '200px * 400px',
|
||||
name: '图一'
|
||||
},
|
||||
{
|
||||
desc: '宽度50% * 高度50%',
|
||||
size: '200px * 200px',
|
||||
name: '图二'
|
||||
},
|
||||
{
|
||||
desc: '宽度50% * 高度50%',
|
||||
size: '200px * 200px',
|
||||
name: '图三'
|
||||
}
|
||||
],
|
||||
descAux: '选定布局区域,在下方添加图片,宽度最小建议为:200px,右侧两张图片高度一致,左侧图片高度为右侧两张图片高度之和(例:左侧图片尺寸:200px * 300px,右侧两张图片尺寸:200px * 150px)'
|
||||
},
|
||||
{
|
||||
name: '1上2下',
|
||||
src: 'iconyishangliangxiapc',
|
||||
className: 'row1-tp-of2-bm',
|
||||
dimensionScale: [
|
||||
{
|
||||
desc: '宽度100% * 高度50%',
|
||||
size: '400px * 200px',
|
||||
name: '图一'
|
||||
},
|
||||
{
|
||||
desc: '宽度50% * 高度50%',
|
||||
size: '200px * 200px',
|
||||
name: '图二'
|
||||
},
|
||||
{
|
||||
desc: '宽度50% * 高度50%',
|
||||
size: '200px * 200px',
|
||||
name: '图三'
|
||||
}
|
||||
],
|
||||
descAux: '选定布局区域,在下方添加图片,上方一张图片的宽度为下方两张图片宽度之和,下放两张图片尺寸一致,高度可根据实际需求自行确定(例:上方图片尺寸:400px * 150px,下方两张图片尺寸:200px * 150px)'
|
||||
},
|
||||
{
|
||||
name: '1左3右',
|
||||
src: 'iconyizuosanyoupc',
|
||||
className: 'row1-lt-of1-tp-of2-bm',
|
||||
dimensionScale: [
|
||||
{
|
||||
desc: '宽度50% * 高度100%',
|
||||
size: '200px * 400px',
|
||||
name: '图一'
|
||||
},
|
||||
{
|
||||
desc: '宽度50% * 高度50%',
|
||||
size: '200px * 200px',
|
||||
name: '图二'
|
||||
},
|
||||
{
|
||||
desc: '宽度25% * 高度50%',
|
||||
size: '100px * 200px',
|
||||
name: '图三'
|
||||
},
|
||||
{
|
||||
desc: '宽度25% * 高度50%',
|
||||
size: '100px * 200px',
|
||||
name: '图四'
|
||||
}
|
||||
],
|
||||
descAux: '选定布局区域,在下方添加图片,左右两侧内容宽高相同,右侧上下区域高度各占50%,右侧内容下半部分两张图片的宽度相同,各占右侧内容宽度的50%(例:左侧图片尺寸:200px * 400px,右侧上半部分图片尺寸:200px * 200px,右侧下半部分两张图片尺寸:100px * 200px)'
|
||||
}
|
||||
])
|
||||
|
||||
const selectTemplate = computed(() => {
|
||||
let data
|
||||
templateList.value.forEach((item) => {
|
||||
if (item.className == diyStore.editComponent.mode) {
|
||||
data = item
|
||||
}
|
||||
})
|
||||
return data
|
||||
})
|
||||
|
||||
const changeTemplateList = (v: number) => {
|
||||
for (let i = 0; i < templateList.value.length; i++) {
|
||||
if (i == v) {
|
||||
diyStore.editComponent.mode = templateList.value[i].className
|
||||
const count = templateList.value[i].dimensionScale.length
|
||||
|
||||
// 重置当前编辑的图片集合
|
||||
|
||||
// 数量不够,进行添加
|
||||
if (count > diyStore.editComponent.list.length) {
|
||||
for (let j = 0; j < count; j++) {
|
||||
if ((j + 1) > diyStore.editComponent.list.length) {
|
||||
diyStore.editComponent.list.push({
|
||||
imageUrl: '',
|
||||
imgWidth: 0,
|
||||
imgHeight: 0,
|
||||
link: { name: '' }
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 数量不相同时,并且数量超出,减去
|
||||
if (count != diyStore.editComponent.list.length) {
|
||||
for (let j = 0; j < diyStore.editComponent.list.length; j++) {
|
||||
if ((j + 1) > count) {
|
||||
diyStore.editComponent.list.splice(j, 1)
|
||||
j = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const selectImg = (url: string) => {
|
||||
handleHeight(true)
|
||||
}
|
||||
|
||||
// 处理高度
|
||||
const handleHeight = (isCalcHeight: boolean = false) => {
|
||||
diyStore.editComponent.list.forEach((item: any, index: number) => {
|
||||
const image = new Image()
|
||||
image.src = img(item.imageUrl)
|
||||
image.onload = async() => {
|
||||
item.imgWidth = image.width
|
||||
item.imgHeight = image.height
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
watch(() => diyStore.editComponent.list, () => {
|
||||
handleHeight(true)
|
||||
}, { deep: true })
|
||||
|
||||
defineExpose({})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.rubik-cube .selected-template-list {
|
||||
/*padding-left: 15px;*/
|
||||
margin-bottom: 20px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
color: #909399;
|
||||
width: 46px;
|
||||
height: 32px;
|
||||
text-align: center;
|
||||
line-height: 29px;
|
||||
border: 1px solid #e5e5e5;
|
||||
cursor: pointer;
|
||||
background: #ffffff;
|
||||
box-sizing: border-box;
|
||||
border-right: 1px transparent solid;
|
||||
|
||||
&:last-child {
|
||||
border-right: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
color: var(--el-color-primary);
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
img {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
div {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layout {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
margin-bottom: 15px;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
color: #909399;
|
||||
border: 1px solid #e5e5e5;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
|
||||
div.empty {
|
||||
left: 0;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -26px;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
line-height: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
div.have-preview-image {
|
||||
box-sizing: border-box;
|
||||
|
||||
img {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// 1行2个
|
||||
&.row1-of2 {
|
||||
width: 49.2%;
|
||||
height: 160px;
|
||||
border-right: 1px transparent solid;
|
||||
|
||||
&:last-child {
|
||||
border-right: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
div.empty {
|
||||
}
|
||||
|
||||
div.have-preview-image {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 160px;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 1行3个
|
||||
&.row1-of3 {
|
||||
width: 32.5%;
|
||||
height: 100px;
|
||||
border-right: 1px transparent solid;
|
||||
|
||||
&:last-child {
|
||||
border-right: 1px solid #bdf;
|
||||
}
|
||||
|
||||
div.empty {
|
||||
}
|
||||
|
||||
div.have-preview-image {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 100px;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
// 1行4个
|
||||
&.row1-of4 {
|
||||
width: 24.2%;
|
||||
height: 80px;
|
||||
border-right: 1px transparent solid;
|
||||
|
||||
&:last-child {
|
||||
border-right: 1px solid #bdf;
|
||||
}
|
||||
|
||||
div.empty {
|
||||
}
|
||||
|
||||
div.have-preview-image {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 80px;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
// 2左2右
|
||||
&.row2-lt-of2-rt {
|
||||
width: 49.2%;
|
||||
height: 160px;
|
||||
|
||||
&:nth-child(1) {
|
||||
border-right: 1px transparent solid;
|
||||
border-bottom: 1px transparent solid;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
border-bottom: 1px transparent solid;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
border-right: 1px transparent solid;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
div.empty {
|
||||
}
|
||||
|
||||
div.have-preview-image {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 160px;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
// 1左2右
|
||||
&.row1-lt-of2-rt {
|
||||
width: 49.2%;
|
||||
font-size: 12px;
|
||||
|
||||
&:nth-child(1) {
|
||||
height: 322px;
|
||||
border-right: 1px transparent solid;
|
||||
|
||||
div.have-preview-image {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 322px;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
height: 160px;
|
||||
border-bottom: 1px transparent solid;
|
||||
|
||||
div.have-preview-image {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 160px;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
height: 160px;
|
||||
|
||||
div.have-preview-image {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 160px;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
div.empty {
|
||||
}
|
||||
}
|
||||
|
||||
// 1上2下
|
||||
&.row1-tp-of2-bm {
|
||||
height: 160px;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 99.4%;
|
||||
border-bottom: 1px transparent solid;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 49.2%;
|
||||
border-right: 1px transparent solid;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 49.2%;
|
||||
}
|
||||
|
||||
div.empty {
|
||||
}
|
||||
|
||||
div.have-preview-image {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 160px;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
// 1左3右
|
||||
&.row1-lt-of1-tp-of2-bm {
|
||||
&:nth-child(1) {
|
||||
height: 320px;
|
||||
width: 49.2%;
|
||||
border-right: 1px transparent solid;
|
||||
|
||||
div.have-preview-image {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 320px;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
height: 160px;
|
||||
width: 49.2%;
|
||||
border-bottom: 1px transparent solid;
|
||||
|
||||
div.have-preview-image {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 160px;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
height: 160px;
|
||||
width: 24.2%;
|
||||
border-right: 1px transparent solid;
|
||||
|
||||
div.have-preview-image {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 160px;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
height: 160px;
|
||||
width: 24.2%;
|
||||
|
||||
div.have-preview-image {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 160px;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
div.empty {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user