|
@@ -1,11 +1,990 @@
|
|
|
<template>
|
|
|
- 目标管理首页
|
|
|
+ <div class="maturity-game-page">
|
|
|
+ <head-component :headinfo="headinfo"></head-component>
|
|
|
+ <div class="page-content">
|
|
|
+ <div class="pyramid-container">
|
|
|
+ <div class="lbline l1"></div>
|
|
|
+ <div class="lbline l2"></div>
|
|
|
+ <div class="lbline l3"></div>
|
|
|
+ <div class="lbline l4"></div>
|
|
|
+ <div class="lbline l5"></div>
|
|
|
+ <div class="lbline l6"></div>
|
|
|
+ <div class="lbline l7"></div>
|
|
|
+ <div class="lbline l8"></div>
|
|
|
+ <div class="lbline l9"></div>
|
|
|
+ <div class="lbline l10"></div>
|
|
|
+ <div class="lbline l11"></div>
|
|
|
+ <div class="lbline l12"></div>
|
|
|
+ <div class="lbline l13"></div>
|
|
|
+ <div class="lbline l14"></div>
|
|
|
+ <!-- 长期目标层 -->
|
|
|
+ <div class="pyramid-layer layer-1">
|
|
|
+ <div
|
|
|
+ class="goal-box"
|
|
|
+ :class="longTermGoal ? 'filled' : 'empty'"
|
|
|
+ @dragover.prevent
|
|
|
+ @drop="onDrop('longTerm', $event)"
|
|
|
+ :data-drop-target="'longTerm'"
|
|
|
+ >
|
|
|
+ {{ longTermGoal || "长期目标" }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 中期目标层 -->
|
|
|
+ <div class="pyramid-layer layer-2">
|
|
|
+ <div
|
|
|
+ v-for="(goal, index) in midTermGoals"
|
|
|
+ :key="'mid-' + index"
|
|
|
+ class="goal-box"
|
|
|
+ :class="goal ? 'filled' : 'empty'"
|
|
|
+ @dragover.prevent
|
|
|
+ @drop="onDrop('midTerm' + (index + 1), $event)"
|
|
|
+ :data-drop-target="'midTerm' + (index + 1)"
|
|
|
+ >
|
|
|
+ {{ goal || `中期目标${index + 1}` }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 短期目标层 -->
|
|
|
+ <div class="pyramid-layer layer-3">
|
|
|
+ <div
|
|
|
+ v-for="(goal, index) in shortTermGoals"
|
|
|
+ :key="'short-' + index"
|
|
|
+ class="goal-box"
|
|
|
+ :class="goal ? 'filled' : 'empty'"
|
|
|
+ @dragover.prevent
|
|
|
+ @drop="onDrop('shortTerm' + (index + 1), $event)"
|
|
|
+ :data-drop-target="'shortTerm' + (index + 1)"
|
|
|
+ >
|
|
|
+ {{ goal || `短期目标${index + 1}` }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 小目标层 -->
|
|
|
+ <div class="pyramid-layer layer-4">
|
|
|
+ <div
|
|
|
+ v-for="(goal, index) in smallGoals"
|
|
|
+ :key="'small-' + index"
|
|
|
+ class="goal-box"
|
|
|
+ :class="goal ? 'filled' : 'empty'"
|
|
|
+ @dragover.prevent
|
|
|
+ @drop="onDrop('small' + (index + 1), $event)"
|
|
|
+ :data-drop-target="'small' + (index + 1)"
|
|
|
+ >
|
|
|
+ {{ goal || `小目标${index + 1}` }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ style="
|
|
|
+ width: 100%;
|
|
|
+ height: 8px;
|
|
|
+ background: rgb(173 173 173);
|
|
|
+ border-top: 3px solid #fff;
|
|
|
+ "
|
|
|
+ ></div>
|
|
|
+ <div class="action-row">
|
|
|
+ <el-button type="success">返回上一级</el-button>
|
|
|
+ <p class="instruction">
|
|
|
+ 请选择一项你想实现的长期目标,并将其拖拽到目标金字塔中相应位置。
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="goal-options">
|
|
|
+ <div
|
|
|
+ v-for="(option, index) in goalOptions"
|
|
|
+ :key="'goal-option-' + index"
|
|
|
+ class="goal-btn"
|
|
|
+ :class="{ dragging: isDragging && currentDragItem === option.text }"
|
|
|
+ draggable="true"
|
|
|
+ @dragstart="onDragStart($event, option.text)"
|
|
|
+ @touchstart="onTouchStart($event, option.text, option)"
|
|
|
+ @touchmove="onTouchMove($event)"
|
|
|
+ @touchend="onTouchEnd($event, option)"
|
|
|
+ >
|
|
|
+ {{ option.text }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 拖拽时的虚拟图 -->
|
|
|
+ <div
|
|
|
+ v-if="isDragging"
|
|
|
+ class="drag-ghost"
|
|
|
+ :style="ghostStyle"
|
|
|
+ ref="dragGhost"
|
|
|
+ >
|
|
|
+ {{ currentDragItem }}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <drag_component></drag_component>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
+import headComponent from "@/views/xjc-integratedmachine/components/head_component.vue";
|
|
|
+import drag_component from "@/views/xjc-integratedmachine/components/drag_component.vue";
|
|
|
+import { onMounted, watch, nextTick } from "vue";
|
|
|
+
|
|
|
+const router = useRouter();
|
|
|
+
|
|
|
+const headinfo = ref({});
|
|
|
+const draggedItem = ref(null);
|
|
|
+
|
|
|
+// 移动端拖拽相关状态
|
|
|
+const isDragging = ref(false);
|
|
|
+const currentDragItem = ref(null);
|
|
|
+const dragStartPos = ref({ x: 0, y: 0 });
|
|
|
+const currentDropTarget = ref(null);
|
|
|
+const dragGhost = ref(null);
|
|
|
+const ghostStyle = ref({
|
|
|
+ position: "fixed",
|
|
|
+ left: "0px",
|
|
|
+ top: "0px",
|
|
|
+ transform: "translate(-50%, -50%)",
|
|
|
+ zIndex: 9999,
|
|
|
+ pointerEvents: "none",
|
|
|
+});
|
|
|
+
|
|
|
+function dragStart(event) {
|
|
|
+ draggedItem.value = event.target;
|
|
|
+}
|
|
|
+
|
|
|
+function drop(event) {
|
|
|
+ event.preventDefault(); // 防止默认处理(例如打开链接)
|
|
|
+ if (event.target !== draggedItem.value) {
|
|
|
+ const target = event.target; // 获取放置的目标元素
|
|
|
+ const item = draggedItem.value; // 获取被拖拽的元素
|
|
|
+ // 交换位置或进行其他操作
|
|
|
+ item.parentNode.insertBefore(item, target); // 将被拖拽的元素插入到目标元素之前
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function setHeadinfo() {
|
|
|
+ headinfo.value = {
|
|
|
+ title: "目标管理",
|
|
|
+ user: {
|
|
|
+ avatar: "头像路径",
|
|
|
+ nickName: "张三",
|
|
|
+ },
|
|
|
+ backUrl: "/xjc-integratedmachine/wakeup/index",
|
|
|
+ backUrlUse: true,
|
|
|
+ };
|
|
|
+}
|
|
|
+onMounted(() => {
|
|
|
+ setHeadinfo();
|
|
|
+});
|
|
|
+
|
|
|
+function jumpTo(path) {
|
|
|
+ router.push({
|
|
|
+ path: path,
|
|
|
+ query: { name: 123 },
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+// lb
|
|
|
+const longTermGoal = ref("");
|
|
|
+const midTermGoals = ref(["", ""]);
|
|
|
+const shortTermGoals = ref(["", "", "", ""]);
|
|
|
+const smallGoals = ref(["", "", "", "", "", "", "", ""]);
|
|
|
+
|
|
|
+// 目标选项数据
|
|
|
+const goalOptions = ref([
|
|
|
+ {
|
|
|
+ id: 1,
|
|
|
+ text: "考上国内双一流A类高校",
|
|
|
+ category: "education",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 2,
|
|
|
+ text: "健康生活模式",
|
|
|
+ category: "health",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 3,
|
|
|
+ text: "留学",
|
|
|
+ category: "education",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 4,
|
|
|
+ text: "创业成功",
|
|
|
+ category: "career",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 5,
|
|
|
+ text: "学会一门新技能",
|
|
|
+ category: "personal",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 6,
|
|
|
+ text: "财务自由",
|
|
|
+ category: "financial",
|
|
|
+ },
|
|
|
+]);
|
|
|
+
|
|
|
+// 桌面端拖拽
|
|
|
+const onDragStart = (event, goalText) => {
|
|
|
+ event.dataTransfer.setData("text/plain", goalText);
|
|
|
+};
|
|
|
+
|
|
|
+// 移动端触摸拖拽
|
|
|
+const onTouchStart = (event, goalText, obj) => {
|
|
|
+ console.log(event, obj, 33);
|
|
|
+ event.preventDefault();
|
|
|
+ isDragging.value = true;
|
|
|
+ currentDragItem.value = goalText;
|
|
|
+
|
|
|
+ const touch = event.touches[0];
|
|
|
+ dragStartPos.value = {
|
|
|
+ x: touch.clientX,
|
|
|
+ y: touch.clientY,
|
|
|
+ };
|
|
|
+
|
|
|
+ // 初始化虚拟图位置
|
|
|
+ ghostStyle.value.left = touch.clientX + "px";
|
|
|
+ ghostStyle.value.top = touch.clientY + "px";
|
|
|
+
|
|
|
+ // 添加视觉反馈
|
|
|
+ event.currentTarget.style.opacity = "0.5";
|
|
|
+ event.currentTarget.style.transform = "scale(0.95)";
|
|
|
+};
|
|
|
+
|
|
|
+const onTouchMove = (event) => {
|
|
|
+ if (!isDragging.value) return;
|
|
|
+
|
|
|
+ event.preventDefault();
|
|
|
+ const touch = event.touches[0];
|
|
|
+
|
|
|
+ // 更新虚拟图位置
|
|
|
+ ghostStyle.value.left = touch.clientX + "px";
|
|
|
+ ghostStyle.value.top = touch.clientY + "px";
|
|
|
+
|
|
|
+ // 获取触摸点下的元素
|
|
|
+ const elementBelow = document.elementFromPoint(touch.clientX, touch.clientY);
|
|
|
+
|
|
|
+ // 清除之前的高亮
|
|
|
+ document.querySelectorAll(".goal-box.drop-highlight").forEach((el) => {
|
|
|
+ el.classList.remove("drop-highlight");
|
|
|
+ });
|
|
|
|
|
|
+ // 检查是否是有效的放置目标
|
|
|
+ if (
|
|
|
+ elementBelow &&
|
|
|
+ elementBelow.classList.contains("goal-box") &&
|
|
|
+ elementBelow.dataset.dropTarget
|
|
|
+ ) {
|
|
|
+ elementBelow.classList.add("drop-highlight");
|
|
|
+ currentDropTarget.value = elementBelow.dataset.dropTarget;
|
|
|
+ } else {
|
|
|
+ currentDropTarget.value = null;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const onTouchEnd = (event, obj) => {
|
|
|
+ console.log(obj, 22);
|
|
|
+ if (!isDragging.value) return;
|
|
|
+
|
|
|
+ event.preventDefault();
|
|
|
+
|
|
|
+ // 恢复原始样式
|
|
|
+ event.currentTarget.style.opacity = "";
|
|
|
+ event.currentTarget.style.transform = "";
|
|
|
+
|
|
|
+ // 清除高亮
|
|
|
+ document.querySelectorAll(".goal-box.drop-highlight").forEach((el) => {
|
|
|
+ el.classList.remove("drop-highlight");
|
|
|
+ });
|
|
|
+
|
|
|
+ // 如果有有效的放置目标,执行放置逻辑
|
|
|
+ if (currentDropTarget.value && currentDragItem.value) {
|
|
|
+ handleDrop(currentDropTarget.value, currentDragItem.value);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重置状态
|
|
|
+ isDragging.value = false;
|
|
|
+ currentDragItem.value = null;
|
|
|
+ currentDropTarget.value = null;
|
|
|
+};
|
|
|
+
|
|
|
+const handleDrop = (target, goalText) => {
|
|
|
+ console.log(target, goalText, "mobile drop");
|
|
|
+ switch (target) {
|
|
|
+ case "longTerm":
|
|
|
+ longTermGoal.value = goalText;
|
|
|
+ document.querySelector(".l1").style.border = "2px solid #00754d";
|
|
|
+ document.querySelector(".l2").style.border = "2px solid #00754d";
|
|
|
+ break;
|
|
|
+ case "midTerm1":
|
|
|
+ midTermGoals.value[0] = goalText;
|
|
|
+ document.querySelector(".l3").style.border = "2px solid #00754d";
|
|
|
+ document.querySelector(".l4").style.border = "2px solid #00754d";
|
|
|
+ break;
|
|
|
+ case "midTerm2":
|
|
|
+ midTermGoals.value[1] = goalText;
|
|
|
+ document.querySelector(".l5").style.border = "2px solid #00754d";
|
|
|
+ document.querySelector(".l6").style.border = "2px solid #00754d";
|
|
|
+ break;
|
|
|
+ case "shortTerm1":
|
|
|
+ shortTermGoals.value[0] = goalText;
|
|
|
+ document.querySelector(".l7").style.border = "2px solid #00754d";
|
|
|
+ document.querySelector(".l8").style.border = "2px solid #00754d";
|
|
|
+ break;
|
|
|
+ case "shortTerm2":
|
|
|
+ shortTermGoals.value[1] = goalText;
|
|
|
+ document.querySelector(".l9").style.border = "2px solid #00754d";
|
|
|
+ document.querySelector(".l10").style.border = "2px solid #00754d";
|
|
|
+ break;
|
|
|
+ case "shortTerm3":
|
|
|
+ shortTermGoals.value[2] = goalText;
|
|
|
+ document.querySelector(".l11").style.border = "2px solid #00754d";
|
|
|
+ document.querySelector(".l12").style.border = "2px solid #00754d";
|
|
|
+ break;
|
|
|
+ case "shortTerm4":
|
|
|
+ shortTermGoals.value[3] = goalText;
|
|
|
+ document.querySelector(".l13").style.border = "2px solid #00754d";
|
|
|
+ document.querySelector(".l14").style.border = "2px solid #00754d";
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ if (target.startsWith("small")) {
|
|
|
+ const index = parseInt(target.replace("small", "")) - 1;
|
|
|
+ smallGoals.value[index] = goalText;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 输出当前状态
|
|
|
+ console.log("长期目标:", longTermGoal.value);
|
|
|
+ console.log("中期目标:", midTermGoals.value);
|
|
|
+ console.log("短期目标:", shortTermGoals.value);
|
|
|
+ console.log("小目标:", smallGoals.value);
|
|
|
+};
|
|
|
+
|
|
|
+const onDrop = (target, event) => {
|
|
|
+ const goalText = event.dataTransfer.getData("text/plain");
|
|
|
+ handleDrop(target, goalText);
|
|
|
+};
|
|
|
+// ed
|
|
|
</script>
|
|
|
|
|
|
-<style scoped>
|
|
|
+<style scoped lang="scss">
|
|
|
+/* lb */
|
|
|
+.action-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center; // 垂直居中
|
|
|
+ justify-content: flex-start; // 左对齐,可改为 space-between
|
|
|
+ gap: 20px; // 元素之间的间距
|
|
|
+ margin: 30px 0;
|
|
|
+
|
|
|
+ .el-button {
|
|
|
+ margin-left: 32px;
|
|
|
+ padding: 25px 25px;
|
|
|
+ border-radius: 12px;
|
|
|
+ font-size: 20px; // 按钮字体变大
|
|
|
+ }
|
|
|
+
|
|
|
+ .instruction {
|
|
|
+ margin: 0; // 去掉段落默认 margin
|
|
|
+ font-weight: bold;
|
|
|
+ margin-left: 410px;
|
|
|
+
|
|
|
+ font-size: 22px;
|
|
|
+ color: #00a524;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.layer-1 .goal-box.empty {
|
|
|
+ border: 4px dashed #e8d344;
|
|
|
+}
|
|
|
+.layer-1 .goal-box.filled {
|
|
|
+ border: 4px solid #e8d344;
|
|
|
+}
|
|
|
+
|
|
|
+.layer-2 .goal-box.empty {
|
|
|
+ border: 4px dashed #00754d;
|
|
|
+}
|
|
|
+.layer-2 .goal-box.filled {
|
|
|
+ border: 4px solid #e8d344;
|
|
|
+}
|
|
|
+
|
|
|
+.layer-3 .goal-box.empty {
|
|
|
+ border: 4px dashed #00754d;
|
|
|
+}
|
|
|
+.layer-3 .goal-box.filled {
|
|
|
+ border: 4px solid #e8d344;
|
|
|
+}
|
|
|
+
|
|
|
+.layer-4 .goal-box.empty {
|
|
|
+ border: 4px dashed #00754d;
|
|
|
+}
|
|
|
+.layer-4 .goal-box.filled {
|
|
|
+ border: 4px solid #3ff032;
|
|
|
+}
|
|
|
+
|
|
|
+// 移动端拖拽相关样式
|
|
|
+.goal-box.drop-highlight {
|
|
|
+ background: rgba(255, 255, 0, 0.3) !important;
|
|
|
+ border-color: #ffeb3b !important;
|
|
|
+ transform: scale(1.02);
|
|
|
+}
|
|
|
+
|
|
|
+.goal-btn.dragging {
|
|
|
+ opacity: 0.7;
|
|
|
+ transform: scale(1.05);
|
|
|
+}
|
|
|
+
|
|
|
+// 增强移动端触摸体验
|
|
|
+.goal-btn {
|
|
|
+ touch-action: none; // 防止页面滚动
|
|
|
+ user-select: none; // 防止文本选择
|
|
|
+}
|
|
|
+
|
|
|
+.goal-box {
|
|
|
+ touch-action: none;
|
|
|
+ user-select: none;
|
|
|
+}
|
|
|
+
|
|
|
+/* 拖拽虚拟图样式 */
|
|
|
+.drag-ghost {
|
|
|
+ padding: 15px 20px;
|
|
|
+ border: 3px solid #4caf50;
|
|
|
+ border-radius: 25px;
|
|
|
+ background: rgba(76, 175, 80, 0.9);
|
|
|
+ color: white;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: bold;
|
|
|
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
|
|
|
+ backdrop-filter: blur(10px);
|
|
|
+ animation: ghostPulse 1s ease-in-out infinite alternate;
|
|
|
+ white-space: nowrap;
|
|
|
+ max-width: 250px;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes ghostPulse {
|
|
|
+ 0% {
|
|
|
+ transform: translate(-50%, -50%) scale(0.95);
|
|
|
+ box-shadow: 0 8px 25px rgba(76, 175, 80, 0.4);
|
|
|
+ }
|
|
|
+ 100% {
|
|
|
+ transform: translate(-50%, -50%) scale(1.05);
|
|
|
+ box-shadow: 0 12px 35px rgba(76, 175, 80, 0.6);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.lbline {
|
|
|
+ width: 130px;
|
|
|
+ border-top: 4px dashed #00754d;
|
|
|
+ /* transition: revert; */
|
|
|
+ position: absolute;
|
|
|
+}
|
|
|
+.l1 {
|
|
|
+ transform: rotate(-16deg);
|
|
|
+ top: 103px;
|
|
|
+ left: 720px;
|
|
|
+}
|
|
|
+.l2 {
|
|
|
+ transform: rotate(16deg);
|
|
|
+ top: 103px;
|
|
|
+ left: 1050px;
|
|
|
+}
|
|
|
+.l3 {
|
|
|
+ transform: rotate(-16deg);
|
|
|
+ top: 275px;
|
|
|
+ left: 239px;
|
|
|
+}
|
|
|
+.l4 {
|
|
|
+ transform: rotate(16deg);
|
|
|
+ top: 273px;
|
|
|
+ left: 640px;
|
|
|
+}
|
|
|
+.l5 {
|
|
|
+ transform: rotate(-16deg);
|
|
|
+ top: 273px;
|
|
|
+ left: 1140px;
|
|
|
+}
|
|
|
+.l6 {
|
|
|
+ transform: rotate(16deg);
|
|
|
+ top: 273px;
|
|
|
+ left: 1490px;
|
|
|
+}
|
|
|
+.l7 {
|
|
|
+ transform: rotate(-16deg);
|
|
|
+ top: 445px;
|
|
|
+ left: 101px;
|
|
|
+}
|
|
|
+.l8 {
|
|
|
+ transform: rotate(16deg);
|
|
|
+ top: 444px;
|
|
|
+ left: 268px;
|
|
|
+}
|
|
|
+.l9 {
|
|
|
+ transform: rotate(-16deg);
|
|
|
+ top: 444px;
|
|
|
+ left: 568px;
|
|
|
+}
|
|
|
+.l10 {
|
|
|
+ transform: rotate(16deg);
|
|
|
+ top: 444px;
|
|
|
+ left: 737px;
|
|
|
+}
|
|
|
+.l11 {
|
|
|
+ transform: rotate(-16deg);
|
|
|
+ top: 444px;
|
|
|
+ left: 1041px;
|
|
|
+}
|
|
|
+.l12 {
|
|
|
+ transform: rotate(16deg);
|
|
|
+ top: 444px;
|
|
|
+ left: 1208px;
|
|
|
+}
|
|
|
+.l13 {
|
|
|
+ transform: rotate(-16deg);
|
|
|
+ top: 444px;
|
|
|
+ left: 1496px;
|
|
|
+}
|
|
|
+.l14 {
|
|
|
+ transform: rotate(16deg);
|
|
|
+ top: 444px;
|
|
|
+ left: 1673px;
|
|
|
+}
|
|
|
+* {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ box-sizing: border-box;
|
|
|
+ font-family: "Arial", "Microsoft YaHei", sans-serif;
|
|
|
+}
|
|
|
+* {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ box-sizing: border-box;
|
|
|
+ font-family: "Arial", "Microsoft YaHei", sans-serif;
|
|
|
+}
|
|
|
+
|
|
|
+body {
|
|
|
+ background: linear-gradient(135deg, #e0f7fa 0%, #bbdefb 100%);
|
|
|
+ min-height: 100vh;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ padding: 20px;
|
|
|
+ margin: 0; // 确保没有默认边距
|
|
|
+}
|
|
|
+
|
|
|
+// 全局背景覆盖
|
|
|
+html,
|
|
|
+body {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ background: linear-gradient(to right, #bef3fc, #3dd3f5);
|
|
|
+ min-height: 100vh;
|
|
|
+}
|
|
|
+
|
|
|
+.container {
|
|
|
+ width: 100%;
|
|
|
+ max-width: 900px;
|
|
|
+ background: white;
|
|
|
+ border-radius: 20px;
|
|
|
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
|
|
|
+ padding: 30px;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.title {
|
|
|
+ text-align: center;
|
|
|
+ color: #2c3e50;
|
|
|
+ margin-bottom: 30px;
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+/* 金字塔容器 */
|
|
|
+.pyramid-container {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 0px;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+/* 金字塔层 */
|
|
|
+.pyramid-layer {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ margin-bottom: 32px;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+/* 长期目标层 - 页面宽度的三分之一 */
|
|
|
+.layer-1 .goal-box.empty {
|
|
|
+ height: 88px;
|
|
|
+}
|
|
|
+.layer-1 .goal-box.filled {
|
|
|
+ height: 88px;
|
|
|
+}
|
|
|
+.layer-1 {
|
|
|
+ width: 33.33%;
|
|
|
+}
|
|
|
+
|
|
|
+/* 中期目标层 - 页面宽度的二分之一 */
|
|
|
+.layer-2 {
|
|
|
+ width: 85%;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+/* 短期目标层 - 页面宽度的四分之三 */
|
|
|
+.layer-3 {
|
|
|
+ width: 98%;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+/* 小目标层 - 页面宽度的90% */
|
|
|
+.layer-4 {
|
|
|
+ width: 98%;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+/* 目标框样式 */
|
|
|
+.goal-box {
|
|
|
+ border-radius: 33px;
|
|
|
+ background: rgba(255, 255, 255, 0.9);
|
|
|
+ text-align: center;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s;
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ font-size: 22px;
|
|
|
+ color: #555;
|
|
|
+ height: 140px;
|
|
|
+ z-index: 2;
|
|
|
+}
|
|
|
+
|
|
|
+.goal-box:hover {
|
|
|
+ background: rgba(236, 252, 237, 0.9);
|
|
|
+ transform: translateY(-2px);
|
|
|
+}
|
|
|
+
|
|
|
+.goal-box.empty {
|
|
|
+ margin: 0px 9px;
|
|
|
+ color: #95a5a6;
|
|
|
+ border-style: dashed;
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+.layer-2 .goal-box.filled {
|
|
|
+ margin: 0px 9px;
|
|
|
+ width: 100%;
|
|
|
+ color: #fff;
|
|
|
+ border-style: solid;
|
|
|
+ background: #00d89c;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+.layer-3 .goal-box.filled {
|
|
|
+ margin: 0px 9px;
|
|
|
+ width: 100%;
|
|
|
+ color: #fff;
|
|
|
+ border-style: solid;
|
|
|
+ background: #00d89c;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+.layer-4 .goal-box.filled {
|
|
|
+ margin: 0px 9px;
|
|
|
+ width: 100%;
|
|
|
+ color: #fff;
|
|
|
+ border-style: solid;
|
|
|
+ background: #00d89c;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+.goal-box.filled {
|
|
|
+ margin: 0px 9px;
|
|
|
+ width: 100%;
|
|
|
+ color: #fff;
|
|
|
+ border-style: solid;
|
|
|
+ background: #303030;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+/* 连接线容器 */
|
|
|
+.connections {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ z-index: 1;
|
|
|
+ pointer-events: none;
|
|
|
+}
|
|
|
+
|
|
|
+/* 连接线 */
|
|
|
+.connection {
|
|
|
+ position: absolute;
|
|
|
+ background: transparent;
|
|
|
+ border-left: 4px dashed #2c8f30;
|
|
|
+}
|
|
|
+
|
|
|
+/* 长期目标到中期目标的连线 */
|
|
|
+.long-to-mid-1,
|
|
|
+.long-to-mid-2 {
|
|
|
+ height: 60px;
|
|
|
+ top: 60px;
|
|
|
+ left: 50%;
|
|
|
+}
|
|
|
+
|
|
|
+.long-to-mid-1 {
|
|
|
+ transform: translateX(-100%) rotate(-30deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+.long-to-mid-2 {
|
|
|
+ transform: translateX(0) rotate(30deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+/* 中期目标到短期目标的连线 */
|
|
|
+.mid-to-short-1,
|
|
|
+.mid-to-short-2,
|
|
|
+.mid-to-short-3,
|
|
|
+.mid-to-short-4 {
|
|
|
+ height: 60px;
|
|
|
+ top: 180px;
|
|
|
+}
|
|
|
+
|
|
|
+.mid-to-short-1 {
|
|
|
+ left: 25%;
|
|
|
+ transform: translateX(-150%) rotate(-20deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+.mid-to-short-2 {
|
|
|
+ left: 25%;
|
|
|
+ transform: translateX(-50%) rotate(20deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+.mid-to-short-3 {
|
|
|
+ left: 75%;
|
|
|
+ transform: translateX(-150%) rotate(-20deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+.mid-to-short-4 {
|
|
|
+ left: 75%;
|
|
|
+ transform: translateX(-50%) rotate(20deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+/* 短期目标到小目标的连线 */
|
|
|
+.short-to-small-1,
|
|
|
+.short-to-small-2,
|
|
|
+.short-to-small-3,
|
|
|
+.short-to-small-4,
|
|
|
+.short-to-small-5,
|
|
|
+.short-to-small-6,
|
|
|
+.short-to-small-7,
|
|
|
+.short-to-small-8 {
|
|
|
+ height: 60px;
|
|
|
+ top: 300px;
|
|
|
+}
|
|
|
+
|
|
|
+.short-to-small-1 {
|
|
|
+ left: 12.5%;
|
|
|
+ transform: translateX(-175%) rotate(-15deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+.short-to-small-2 {
|
|
|
+ left: 12.5%;
|
|
|
+ transform: translateX(-75%) rotate(15deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+.short-to-small-3 {
|
|
|
+ left: 37.5%;
|
|
|
+ transform: translateX(-175%) rotate(-15deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+.short-to-small-4 {
|
|
|
+ left: 37.5%;
|
|
|
+ transform: translateX(-75%) rotate(15deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+.short-to-small-5 {
|
|
|
+ left: 62.5%;
|
|
|
+ transform: translateX(-175%) rotate(-15deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+.short-to-small-6 {
|
|
|
+ left: 62.5%;
|
|
|
+ transform: translateX(-75%) rotate(15deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+.short-to-small-7 {
|
|
|
+ left: 87.5%;
|
|
|
+ transform: translateX(-175%) rotate(-15deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+.short-to-small-8 {
|
|
|
+ left: 87.5%;
|
|
|
+ transform: translateX(-75%) rotate(15deg);
|
|
|
+ transform-origin: top center;
|
|
|
+}
|
|
|
+
|
|
|
+/* 底部按钮区域 */
|
|
|
+.goal-options {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap; // 允许换行
|
|
|
+ justify-content: flex-start;
|
|
|
+ height: 191px;
|
|
|
+ overflow-y: auto;
|
|
|
+ gap: 20px;
|
|
|
+ margin-top: 40px;
|
|
|
+ padding: 20px;
|
|
|
+
|
|
|
+ // 可选:自适应居中
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.goal-btn {
|
|
|
+ flex: 0 0 calc(33.33% - 13.33px); // 每行3个,减去gap平均值
|
|
|
+ min-width: 200px; // 保持最小宽度
|
|
|
+ padding: 60px 25px;
|
|
|
+ border: 4px solid #95a5a6;
|
|
|
+ border-radius: 40px;
|
|
|
+ background: #fff;
|
|
|
+ color: #95a5a6;
|
|
|
+ font-size: 22px;
|
|
|
+ text-align: center;
|
|
|
+ cursor: grab;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.goal-btn:hover {
|
|
|
+ border: 4px solid #a2d532;
|
|
|
+ color: #2c3e50;
|
|
|
+ transform: translateY(-3px);
|
|
|
+ box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
|
|
|
+}
|
|
|
+
|
|
|
+.goal-btn:active {
|
|
|
+ cursor: grabbing;
|
|
|
+}
|
|
|
+
|
|
|
+.instruction {
|
|
|
+ text-align: center;
|
|
|
+ margin: 30px 0;
|
|
|
+ color: #00a524;
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 22px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 装饰元素 */
|
|
|
+.decoration {
|
|
|
+ position: absolute;
|
|
|
+}
|
|
|
+
|
|
|
+.cartoon {
|
|
|
+ top: 20px;
|
|
|
+ left: 20px;
|
|
|
+ width: 80px;
|
|
|
+ height: 80px;
|
|
|
+ background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="40" r="30" fill="%23FFD54F"/><circle cx="40" cy="35" r="5" fill="white"/><circle cx="60" cy="35" r="5" fill="white"/><path d="M35 55 Q50 65 65 55" stroke="%23E57373" stroke-width="3" fill="none"/></svg>')
|
|
|
+ no-repeat center;
|
|
|
+ background-size: contain;
|
|
|
+}
|
|
|
+
|
|
|
+.robot {
|
|
|
+ bottom: 20px;
|
|
|
+ right: 20px;
|
|
|
+ width: 80px;
|
|
|
+ height: 126px;
|
|
|
+ background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="30" r="20" fill="%234caf50"/><rect x="30" y="50" width="40" height="40" rx="5" fill="%234caf50"/><circle cx="40" cy="60" r="5" fill="white"/><circle cx="60" cy="60" r="5" fill="white"/></svg>')
|
|
|
+ no-repeat center;
|
|
|
+ background-size: contain;
|
|
|
+}
|
|
|
+
|
|
|
+@media (max-width: 768px) {
|
|
|
+ .goal-options {
|
|
|
+ padding: 15px;
|
|
|
+ gap: 15px;
|
|
|
+
|
|
|
+ // 移动端滚动条隐藏
|
|
|
+ scrollbar-width: none; // Firefox
|
|
|
+ -ms-overflow-style: none; // IE
|
|
|
+
|
|
|
+ &::-webkit-scrollbar {
|
|
|
+ display: none; // Chrome/Safari
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .goal-btn {
|
|
|
+ width: 30%; // 移动端也保持原来的宽度
|
|
|
+ min-width: 200px; // 保持原来的最小宽度
|
|
|
+ padding: 40px 20px;
|
|
|
+ font-size: 18px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .layer-2,
|
|
|
+ .layer-3,
|
|
|
+ .layer-4 {
|
|
|
+ flex-wrap: wrap;
|
|
|
+ height: auto;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .goal-box {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 120px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .connections {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+}
|
|
|
+/*ed*/
|
|
|
+
|
|
|
+.maturity-game-page {
|
|
|
+ // background: url("@/assets/images/wakeup/maturity/maturity-game-bg.png")
|
|
|
+ // no-repeat;
|
|
|
+ background: linear-gradient(to right, #bef3fc, #3dd3f5);
|
|
|
+ background-attachment: fixed;
|
|
|
+ z-index: 10;
|
|
|
+ width: 100%;
|
|
|
+ min-height: 100vh;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .page-content {
|
|
|
+ width: 100%;
|
|
|
+ position: relative;
|
|
|
+ padding-top: 123px;
|
|
|
+ min-height: calc(100vh - 123px);
|
|
|
+ padding-bottom: 0px; // 添加底部内边距防止内容贴边
|
|
|
|
|
|
+ .top {
|
|
|
+ width: 100%;
|
|
|
+ height: 212px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ margin-top: 104px;
|
|
|
+ img {
|
|
|
+ width: 864px;
|
|
|
+ height: 212px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .bottom {
|
|
|
+ width: 100%;
|
|
|
+ height: 248px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-around;
|
|
|
+ margin-top: 186px;
|
|
|
+ img {
|
|
|
+ width: 398px;
|
|
|
+ height: 248px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|