mirror of
https://github.com/Powerful-517/yys-editor.git
synced 2025-05-24 03:45:22 +00:00
Merge pull request #6 from Powerful-517/develop
v2.3.0 新增式神,御魂名称,新增御魂搜索
This commit is contained in:
commit
91af045923
@ -5,6 +5,15 @@
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>yys-editor</title>
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
(function () {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?8d59439a417b1eb4bc99d62ddca7e072";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 173 KiB After Width: | Height: | Size: 25 KiB |
21
src/App.vue
21
src/App.vue
@ -2,10 +2,11 @@
|
||||
import Yys from './components/Yys.vue';
|
||||
import Toolbar from './components/Toolbar.vue';
|
||||
import ProjectExplorer from './components/ProjectExplorer.vue';
|
||||
import { computed, ref, onMounted, onUnmounted } from "vue";
|
||||
import { useFilesStore } from "@/ts/files";
|
||||
import {computed, ref, onMounted, onUnmounted} from "vue";
|
||||
import {useFilesStore} from "@/ts/files";
|
||||
import Vue3DraggableResizable from 'vue3-draggable-resizable';
|
||||
import { TabPaneName, TabsPaneContext } from "element-plus";
|
||||
import {TabPaneName, TabsPaneContext} from "element-plus";
|
||||
import YysRank from "@/components/YysRank.vue";
|
||||
|
||||
const filesStore = useFilesStore();
|
||||
|
||||
@ -42,8 +43,8 @@ const handleTabsEdit = (
|
||||
label: newFileName,
|
||||
name: newFileName,
|
||||
visible: true,
|
||||
type:'PVE',
|
||||
groups:[
|
||||
type: 'PVE',
|
||||
groups: [
|
||||
{
|
||||
shortDescription: " ",
|
||||
groupInfo: [{}, {}, {}, {}, {}],
|
||||
@ -85,7 +86,7 @@ const activeFileGroups = computed(() => {
|
||||
<div class="main-content">
|
||||
<!-- 侧边栏 -->
|
||||
<aside class="sidebar">
|
||||
<ProjectExplorer :allFiles="filesStore.fileList" />
|
||||
<ProjectExplorer :allFiles="filesStore.fileList"/>
|
||||
</aside>
|
||||
|
||||
<!-- 工作区 -->
|
||||
@ -104,7 +105,8 @@ const activeFileGroups = computed(() => {
|
||||
:name="file.name.toString()"
|
||||
>
|
||||
<main id="main-container" :style="{ height: contentHeight, overflow: 'auto' }">
|
||||
<Yys :groups="activeFileGroups"/>
|
||||
<Yys class="yys" :groups="activeFileGroups" v-if="file.type === 'PVE' "/>
|
||||
<YysRank :groups="activeFileGroups" v-else-if="file.type === 'PVP' "/>
|
||||
</main>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
@ -141,7 +143,7 @@ const activeFileGroups = computed(() => {
|
||||
}
|
||||
|
||||
.workspace {
|
||||
//flex: 1; /* 占据剩余空间 */
|
||||
flex: 1; /* 占据剩余空间 */
|
||||
overflow: hidden; /* 防止内容溢出 */
|
||||
display: inline-block;
|
||||
}
|
||||
@ -151,7 +153,8 @@ const activeFileGroups = computed(() => {
|
||||
height: 100%; /* 确保内容区域占满父容器 */
|
||||
overflow-y: auto; /* 允许内容滚动 */
|
||||
min-height: 100vh; /* 允许容器扩展 */
|
||||
display: inline-block;
|
||||
//display: inline-block;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
@ -28,13 +28,14 @@
|
||||
>
|
||||
<div style="max-height: 600px; overflow-y: auto;">
|
||||
<el-space wrap size="large">
|
||||
<div v-for="i in filterShikigamiByRarityAndSearch(rarity.name,searchText)" :key="i.name">
|
||||
<div style="display: flex;flex-direction: column;justify-content: center" v-for="i in filterShikigamiByRarityAndSearch(rarity.name,searchText)" :key="i.name">
|
||||
<el-button
|
||||
style="width: 100px; height: 100px;"
|
||||
@click.stop="confirm(i)"
|
||||
>
|
||||
<img :src="i.avatar" style="width: 99px; height: 99px;">
|
||||
</el-button>
|
||||
<span style="text-align: center; display: block;">{{i.name}}</span>
|
||||
</div>
|
||||
</el-space>
|
||||
</div>
|
||||
|
@ -264,7 +264,18 @@ const prepareCapture = async () => {
|
||||
|
||||
// 创建临时样式
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `.ql-container.ql-snow { border: none !important; }`;
|
||||
style.textContent = `
|
||||
.ql-container.ql-snow {
|
||||
border: none !important;
|
||||
}
|
||||
#main-container {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
min-height: 100vh;
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
}`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
// 获取目标元素
|
||||
|
@ -4,14 +4,22 @@
|
||||
<span>当前选择:{{ current.name }}</span>
|
||||
<el-button type="danger" icon="Delete" round @click="remove()"></el-button>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center;">
|
||||
<el-input
|
||||
placeholder="请输入内容"
|
||||
v-model="searchText"
|
||||
style="width: 200px; margin-right: 10px;"
|
||||
/>
|
||||
</div>
|
||||
<el-tabs v-model="activeName" type="card" class="demo-tabs" @tab-click="handleTabClick">
|
||||
<el-tab-pane v-for="type in yuhunTypes" :key="type.name" :label="type.label" :name="type.name">
|
||||
<div style="max-height: 500px; overflow-y: auto;">
|
||||
<el-space wrap size="large" style="">
|
||||
<div v-for="yuhun in filterYuhunByType(activeName)" :key="yuhun.name">
|
||||
<div v-for="yuhun in filterYuhunByTypeAndSearch(activeName,searchText)" :key="yuhun.name">
|
||||
<el-button style="width: 100px; height: 100px;" @click="confirm(yuhun)">
|
||||
<img :src="yuhun.avatar" style="width: 99px; height: 99px;">
|
||||
</el-button>
|
||||
<span style="text-align: center; display: block;">{{yuhun.name}}</span>
|
||||
</div>
|
||||
</el-space>
|
||||
</div>
|
||||
@ -20,7 +28,7 @@
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import {ref, watch, computed} from 'vue';
|
||||
import shikigamiData from '../data/Shikigami.json';
|
||||
import yuhunData from '../data/Yuhun.json';
|
||||
@ -39,6 +47,7 @@ const props = defineProps({
|
||||
|
||||
const emit = defineEmits(['updateYuhunSelect', 'closeYuhunSelect']);
|
||||
|
||||
const searchText = ref('') // 新增搜索文本
|
||||
const show = ref(false);
|
||||
const activeName = ref('ALL');
|
||||
const current = ref(props.currentShikigami);
|
||||
@ -66,9 +75,24 @@ const handleTabClick = (tab) => {
|
||||
console.log(tab.paneName);
|
||||
};
|
||||
|
||||
const filterYuhunByType = (type) => {
|
||||
if (type.toLowerCase() === 'all') return yuhunData;
|
||||
return yuhunData.filter(yuhun => yuhun.type.toLowerCase() === type.toLowerCase());
|
||||
const filterYuhunByTypeAndSearch = (type: string, search: string) => {
|
||||
let filteredList = yuhunData;
|
||||
|
||||
// 按类型过滤
|
||||
if (type.toLowerCase() !== 'all') {
|
||||
filteredList = filteredList.filter(item =>
|
||||
item.type.toLowerCase() === type.toLowerCase()
|
||||
);
|
||||
}
|
||||
|
||||
// 按搜索关键字过滤
|
||||
if (search.trim() !== '') {
|
||||
filteredList = filteredList.filter(item =>
|
||||
item.name.toLowerCase().includes(search.toLowerCase())
|
||||
);
|
||||
}
|
||||
|
||||
return filteredList;
|
||||
};
|
||||
|
||||
const cancel = () => {
|
||||
@ -77,6 +101,8 @@ const cancel = () => {
|
||||
|
||||
const confirm = (item) => {
|
||||
emit('updateYuhunSelect', JSON.parse(JSON.stringify(item)), 'Update');
|
||||
searchText.value=''
|
||||
activeName.value = 'ALL'
|
||||
};
|
||||
|
||||
const remove = () => {
|
||||
|
267
src/components/YysRank.vue
Normal file
267
src/components/YysRank.vue
Normal file
@ -0,0 +1,267 @@
|
||||
<template>
|
||||
<ShikigamiSelect
|
||||
:showSelectShikigami="state.showSelectShikigami"
|
||||
:currentShikigami="state.currentShikigami"
|
||||
@closeSelectShikigami="closeSelectShikigami"
|
||||
@updateShikigami="updateShikigami"
|
||||
/>
|
||||
|
||||
<ShikigamiProperty
|
||||
:showProperty="state.showProperty"
|
||||
:currentShikigami="state.currentShikigami"
|
||||
@closeProperty="closeProperty"
|
||||
@updateProperty="updateProperty"
|
||||
/>
|
||||
|
||||
|
||||
<div class="yys-rank">
|
||||
<div class="pvp-mindmap">
|
||||
|
||||
</div>
|
||||
<div class="pvp-shikigami-editor">
|
||||
<el-button type="primary" @click="addGroupElement()">{{ t('AddShikigami') }}</el-button>
|
||||
|
||||
<div style="max-height: 600px; overflow-y: auto;">
|
||||
<el-space wrap size="large">
|
||||
<draggable :list="props.groups[0].groupInfo" item-key="name" class="body-content">
|
||||
<template #item="{element : position, index:positionIndex}">
|
||||
<div class="group-card">
|
||||
<div class="opt-btn" data-html2canvas-ignore="true">
|
||||
<!-- Add delete button here -->
|
||||
<el-button type="danger" icon="Delete" circle @click="removeGroupElement(positionIndex)"/>
|
||||
<!-- <el-button type="primary" icon="Plus" circle @click="addGroupElement(groupIndex)"/> -->
|
||||
</div>
|
||||
<div class="avatar-container">
|
||||
<!-- 头像图片 -->
|
||||
<img :src="position.avatar || '/assets/Shikigami/default.png'"
|
||||
style="cursor: pointer; vertical-align: bottom;"
|
||||
class="avatar-image"
|
||||
@click="editShikigami(positionIndex)"/>
|
||||
|
||||
<!-- 文字图层 -->
|
||||
<!-- <span v-if="position.properties">{{ position.properties.levelRequired }}级 {{ position.properties.skillRequired.join('') }}</span>-->
|
||||
</div>
|
||||
<div class="opt-foot">
|
||||
<div class="property-wrap">
|
||||
<div style="display: flex; justify-content: center;" data-html2canvas-ignore="true">
|
||||
<span>{{ position.name || "" }}</span>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: center;" class="bottom" data-html2canvas-ignore="true">
|
||||
<el-button @click="editProperty(positionIndex)">{{ t('editProperties') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="position.properties">
|
||||
<div style="display: flex; justify-content: center;">
|
||||
<span
|
||||
style="width: 100px;height: 50px;background-color: #666;
|
||||
border-radius: 5px; margin-right: 5px; color: white;
|
||||
text-align: center; white-space: pre-wrap; display: flex; align-items: center; justify-content: center; flex-direction: column ">
|
||||
{{ getYuhunNames(position.properties.yuhun.yuhunSetEffect) }}<br/>{{
|
||||
t('yuhun_target.shortName.' + position.properties.yuhun.target)
|
||||
}}·{{ getYuhunPropertyNames(position.properties.yuhun) }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
style="display: inline-block; width: 100px; height: 30px; border-radius: 5px; margin-right: 5px; color: red; text-align: center; white-space: pre-wrap; display: flex; align-items: center; justify-content: center; flex-direction: column ">
|
||||
{{ position.properties.desc }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</el-space>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {ref, reactive, onMounted} from 'vue';
|
||||
import shikigami from "../data/Shikigami.json"
|
||||
import ShikigamiSelect from "@/components/ShikigamiSelect.vue";
|
||||
import ShikigamiProperty from "@/components/ShikigamiProperty.vue";
|
||||
import _ from "lodash";
|
||||
import {useI18n} from "vue-i18n";
|
||||
import draggable from 'vuedraggable';
|
||||
|
||||
|
||||
const {t} = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
groups: any[];
|
||||
}>();
|
||||
|
||||
const state = reactive({
|
||||
showSelectShikigami: false,
|
||||
showProperty: false,
|
||||
groupIndex: 0,
|
||||
positionIndex: 0,
|
||||
currentShikigami: {},
|
||||
previewImage: null, // 用于存储预览图像的数据URL
|
||||
previewVisible: false, // 控制预览弹窗的显示状态
|
||||
});
|
||||
|
||||
const addGroupElement = () => {
|
||||
props.groups[0].groupInfo.push({});
|
||||
editShikigami(props.groups[0].groupInfo.length - 1);
|
||||
};
|
||||
|
||||
const editShikigami = (positionIndex) => {
|
||||
// console.log("==== 选择式神 ===", groupIndex, positionIndex);
|
||||
state.showSelectShikigami = true;
|
||||
state.positionIndex = positionIndex;
|
||||
// state.currentShikigami = props.groups[groupIndex].groupInfo[positionIndex];
|
||||
};
|
||||
|
||||
const closeSelectShikigami = () => {
|
||||
console.log("close select ====");
|
||||
state.showSelectShikigami = false;
|
||||
state.currentShikigami = {};
|
||||
};
|
||||
|
||||
const updateShikigami = (shikigami) => {
|
||||
state.showSelectShikigami = false;
|
||||
|
||||
const oldProperties = props.groups[0].groupInfo[state.positionIndex].properties;
|
||||
props.groups[0].groupInfo[state.positionIndex] = _.cloneDeep(shikigami);
|
||||
props.groups[0].groupInfo[state.positionIndex].properties = oldProperties;
|
||||
|
||||
};
|
||||
|
||||
const closeProperty = () => {
|
||||
state.showProperty = false;
|
||||
state.currentShikigami = {};
|
||||
};
|
||||
|
||||
const updateProperty = (property) => {
|
||||
state.showProperty = false;
|
||||
state.currentShikigami = {};
|
||||
props.groups[0].groupInfo[state.positionIndex].properties = _.cloneDeep(property);
|
||||
};
|
||||
|
||||
const editProperty = (positionIndex) => {
|
||||
state.showProperty = true;
|
||||
state.positionIndex = positionIndex;
|
||||
state.currentShikigami = props.groups[0].groupInfo[positionIndex];
|
||||
};
|
||||
|
||||
const getYuhunNames = (yuhunSetEffect) => {
|
||||
const names = yuhunSetEffect.map(item => item.name).join('');
|
||||
if (names.length <= 6) {
|
||||
return names;
|
||||
} else {
|
||||
return yuhunSetEffect.map(item => item.shortName || item.name).join('');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const getYuhunPropertyNames = (yuhun) => {
|
||||
// 根据条件处理 yuhun.property2
|
||||
let property2Value, property4Value, property6Value;
|
||||
if (yuhun.property2.length >= 4) {
|
||||
property2Value = 'X';
|
||||
} else {
|
||||
property2Value = t('yuhun_property.shortName.' + yuhun.property2[0]);
|
||||
}
|
||||
|
||||
if (yuhun.property4.length >= 5) {
|
||||
property4Value = 'X';
|
||||
} else {
|
||||
property4Value = t('yuhun_property.shortName.' + yuhun.property4[0]);
|
||||
}
|
||||
|
||||
if (yuhun.property6.length >= 5) {
|
||||
property6Value = 'X';
|
||||
} else {
|
||||
property6Value = t('yuhun_property.shortName.' + yuhun.property6[0]);
|
||||
}
|
||||
// 构建 propertyNames 字符串
|
||||
const propertyNames =
|
||||
property2Value + property4Value + property6Value
|
||||
|
||||
return propertyNames;
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.yys-rank {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pvp-mindmap {
|
||||
flex: 1;
|
||||
border: 2px solid red;
|
||||
min-height: 400px;
|
||||
min-width: 500px;
|
||||
height: 50%;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.pvp-shikigami-editor {
|
||||
|
||||
border: 2px solid black;
|
||||
height: 50%;
|
||||
width: 80%;
|
||||
min-height: 400px;
|
||||
min-width: 500px;
|
||||
}
|
||||
|
||||
.group-card {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.avatar-container {
|
||||
position: relative;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.avatar-container span {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(50%);
|
||||
font-size: 24px;
|
||||
color: white;
|
||||
text-shadow: -1px -1px 0 black, 1px -1px 0 black, -1px 1px 0 black, 1px 1px 0 black;
|
||||
white-space: nowrap;
|
||||
padding: 0 8px;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.opt-btn {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
z-index: 10;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 当鼠标悬停在容器上时显示按钮 */
|
||||
.group-card:hover .opt-btn {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 图片样式 */
|
||||
.avatar-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover; /* 关键属性:保持比例填充容器 */
|
||||
object-position: center; /* 居中显示 */
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
@ -1,4 +1,12 @@
|
||||
[
|
||||
{
|
||||
"version": "2.3.0",
|
||||
"date": "2025-03-31",
|
||||
"changes": [
|
||||
"支持御魂搜索",
|
||||
"显示式神和御魂名称"
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.2.0",
|
||||
"date": "2025-03-21",
|
||||
|
Loading…
x
Reference in New Issue
Block a user