Browse Source

假link学习electron

master
no99 3 weeks ago
parent
commit
9d2e652e88
  1. 2
      .env.development
  2. 2
      .env.production
  3. 6
      README.md
  4. 2
      index.html
  5. 64
      main.js
  6. 9204
      package-lock.json
  7. 18
      package.json
  8. BIN
      public/app.png
  9. BIN
      public/home.png
  10. BIN
      public/left.png
  11. BIN
      public/refresh.png
  12. BIN
      public/right.png
  13. 29
      src/api/dataAPI.js
  14. BIN
      src/assets/img/smallTitle/BigLine.png
  15. BIN
      src/assets/img/smallTitle/title-jn-left.png
  16. BIN
      src/assets/img/smallTitle/title-jn-right.png
  17. BIN
      src/assets/img/smallTitle/右.png
  18. BIN
      src/assets/img/smallTitle/左.png
  19. 6
      src/main.js
  20. 73
      src/router/index.js
  21. 202
      src/store/fakeLink-dataList.js
  22. 129
      src/utils/request.js
  23. 3
      src/views/animation/anima.vue
  24. 3
      src/views/calendar/calendar.vue
  25. 16
      src/views/commponent/backBtn.vue
  26. 91
      src/views/fakeLink/component/smallTitle.vue
  27. 781
      src/views/fakeLink/dbqb/dbqb.vue
  28. 1238
      src/views/fakeLink/dbqb/echarts/EnergyKlineEcharts.vue
  29. 231
      src/views/fakeLink/homepage-two.vue
  30. 471
      src/views/fakeLink/homepage.vue
  31. 163
      src/views/fakeLink/login.vue
  32. 32
      src/views/homepage.vue
  33. 6
      src/views/homework/homework.vue
  34. 161
      src/views/hxl_DZP/dzp1.vue
  35. 79
      src/views/three3D/3D1.vue

2
.env.development

@ -3,7 +3,7 @@ VITE_ENV = 'development'
VITE_OUTPUT_DIR = 'dev'
# public path
VITE_PUBLIC_PATH = /
VITE_APP_API_BASE_URL = "http://39.101.133.168:8828/link"
# Whether to open mock
VITE_USE_MOCK = true

2
.env.production

@ -3,7 +3,7 @@ VITE_ENV = 'production'
VITE_OUTPUT_DIR = 'dist'
# public path
VITE_PUBLIC_PATH = /dazhuanpan
VITE_APP_API_BASE_URL = https://api.homilychart.com/link
# Whether to open mock
VITE_USE_MOCK = true
# Whether to enable gzip or brotli compression

6
README.md

@ -8,3 +8,9 @@ npm install @lucky-canvas/vue@latest 下载转盘插件
npm install element-plus --save 下载element-plus
npm install @element-plus/icons-vue 下载element-plus图标
npm install moment 安装 moment 组件,解决时间处理问题
npm install three
npm install echarts
npm install electron --save-dev
npm install pinia @pinia-plugin-persistedstate/nuxt
npm install -D sass
npm install -D less

2
index.html

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue</title>
<title>Homily Link</title>
</head>
<body>
<div id="app"></div>

64
main.js

@ -0,0 +1,64 @@
// 引入Electron的核心模块
const { app, BrowserWindow, Menu } = require("electron");
const path = require("path");
// 创建窗口的函数
function createWindow() {
// 定义图标路径
const iconPath = path.join(__dirname, "./public/app.png");
// 新建一个窗口(就像打开一个浏览器窗口)
const mainWindow = new BrowserWindow({
width: 800, // 窗口宽度
height: 600, // 窗口高度
icon: iconPath,
...(process.platform === "linux" ? { icon } : {}),
webPreferences: {
// 允许在Vue页面中使用Node.js的功能(可选,按需开启)
nodeIntegration: true,
contextIsolation: false,
},
});
// 告诉窗口要显示的内容:
// 开发阶段,显示Vue3的本地服务地址(就是刚才npm run dev的地址)
mainWindow.loadURL("http://localhost:5173");
// 创建一个简单的菜单(包含前进/后退按钮)
// const menu = Menu.buildFromTemplate([
// {
// label: "", // 菜单名称
// icon: path.join(__dirname, './public/left.png'), // 16x16
// submenu: [
// {
// label: "后退", // 后退按钮
// click: () => mainWindow.webContents.goBack(), // 调用后退API
// },
// {
// label: "前进", // 前进按钮
// click: () => mainWindow.webContents.goForward(), // 调用前进API
// },
// ],
// },
// ]);
const menu = null;
Menu.setApplicationMenu(menu); // 把菜单应用到窗口
// 打开开发者工具(类似浏览器的F12,方便调试,可选)
// mainWindow.webContents.openDevTools()
}
// 当Electron准备好后,创建窗口
app.whenReady().then(() => {
createWindow();
// 对于Mac系统的兼容(不用深究,照抄即可)
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
// 关闭所有窗口时退出应用(Windows和Linux的习惯)
app.on("window-all-closed", () => {
if (process.platform !== "darwin") app.quit();
});

9204
package-lock.json
File diff suppressed because it is too large
View File

18
package.json

@ -1,25 +1,37 @@
{
"name": "dzp",
"main": "main.js",
"private": true,
"version": "0.0.0",
"type": "module",
"author": "hxl",
"description": "学习项目",
"license": "ISC",
"scripts": {
"start": "electron .",
"dev": "vite --host",
"build": "vite build",
"preview": "vite preview"
"preview": "vite preview",
"electron:dev": "electron ."
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@lucky-canvas/vue": "^0.1.11",
"@pinia-plugin-persistedstate/nuxt": "^1.2.1",
"axios": "^1.10.0",
"echarts": "^6.0.0",
"element-plus": "^2.9.8",
"lucky-canvas": "^1.7.27",
"moment": "^2.30.1",
"pinia": "^3.0.3",
"three": "^0.178.0",
"vue": "^3.5.13",
"vue-router": "^4.5.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.2.1",
"electron": "^37.3.1",
"electron-builder": "^26.0.12",
"less": "^4.4.1",
"sass": "^1.92.1",
"vite": "^6.2.6"
}
}

BIN
public/app.png

After

Width: 412  |  Height: 411  |  Size: 90 KiB

BIN
public/home.png

After

Width: 200  |  Height: 200  |  Size: 4.6 KiB

BIN
public/left.png

After

Width: 200  |  Height: 200  |  Size: 2.2 KiB

BIN
public/refresh.png

After

Width: 200  |  Height: 200  |  Size: 7.3 KiB

BIN
public/right.png

After

Width: 200  |  Height: 200  |  Size: 2.3 KiB

29
src/api/dataAPI.js

@ -0,0 +1,29 @@
import request from "../utils/request";
const APIurl = import.meta.env.VITE_APP_API_BASE_URL;
//数据接口
export const dataListAPI = function (params) {
// URLSearchParams只接受全部字符串的数据
// 将传入数据转化成字符串
const StringParams = new URLSearchParams(
Object.entries(params).map(([key, value]) => [key, String(value)])
);
return request({
url: `${APIurl}/api/brain/data`,
method: "post",
data: StringParams,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});
};
// ai情绪大模型的接口
export const aiEmotionAPI = function (params) {
return request({
url: `${APIurl}/api/aiEmotion/client/getAiEmotionData`,
method: "post",
data: params,
});
};

BIN
src/assets/img/smallTitle/BigLine.png

After

Width: 640  |  Height: 2  |  Size: 342 B

BIN
src/assets/img/smallTitle/title-jn-left.png

After

Width: 52  |  Height: 50  |  Size: 545 B

BIN
src/assets/img/smallTitle/title-jn-right.png

After

Width: 52  |  Height: 50  |  Size: 562 B

BIN
src/assets/img/smallTitle/右.png

After

Width: 80  |  Height: 70  |  Size: 4.5 KiB

BIN
src/assets/img/smallTitle/左.png

After

Width: 80  |  Height: 70  |  Size: 4.4 KiB

6
src/main.js

@ -6,11 +6,15 @@ import VueLuckyCanvas from "@lucky-canvas/vue";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
import * as ElementPlusIconsVue from "@element-plus/icons-vue";
import { createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
const app = createApp(App);
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component);
}
app.use(router).use(ElementPlus).use(VueLuckyCanvas).mount("#app");
app.use(router).use(ElementPlus).use(pinia).use(VueLuckyCanvas).mount("#app");

73
src/router/index.js

@ -1,39 +1,66 @@
import { createRouter, createWebHistory } from 'vue-router'
import { createRouter, createWebHistory } from "vue-router";
const routes = [
{
path: '/',
redirect: '/homepage'
path: "/",
redirect: "/homepage",
},
{
path: '/homepage',
name: 'homepage',
component: () => import('../views/homepage.vue')
path: "/homepage",
name: "homepage",
component: () => import("../views/homepage.vue"),
},
{
path: '/hxl_dzp1',
name: 'hxl_dzp1',
component: () => import('../views/hxl_DZP/dzp1.vue')
path: "/hxl_dzp1",
name: "hxl_dzp1",
component: () => import("../views/hxl_DZP/dzp1.vue"),
},
{
path: '/animation',
name: 'animation',
component: () => import('../views/animation/anima.vue')
path: "/animation",
name: "animation",
component: () => import("../views/animation/anima.vue"),
},
{
path: '/homework',
name: 'homework',
component: () => import('../views/homework/homework.vue')
path: "/homework",
name: "homework",
component: () => import("../views/homework/homework.vue"),
},
{
path: '/calendar',
name: 'calendar',
component: () => import('../views/calendar/calendar.vue')
}
]
path: "/calendar",
name: "calendar",
component: () => import("../views/calendar/calendar.vue"),
},
{
path: "/3D1",
name: "3D1",
component: () => import("../views/three3D/3D1.vue"),
},
{
path: "/fakeLink",
name: "fakeLink",
component: () => import("../views/fakeLink/homepage.vue"),
},
{
path: "/fakeLinkLogin",
name: "fakeLinkLogin",
component: () => import("../views/fakeLink/login.vue"),
},
{
path: "/homepageTwo",
name: "homepageTwo",
component: () => import("../views/fakeLink/homepage-two.vue"),
children: [
{
path: "/dbqb",
name: "dbqb",
component: () => import("../views/fakeLink/dbqb/dbqb.vue"),
},
],
},
];
// 创建路由实例
const router = createRouter({
history: createWebHistory(import.meta.env.VITE_PUBLIC_PATH),
routes
})
routes,
});
// 导出
export default router
export default router;

202
src/store/fakeLink-dataList.js

@ -0,0 +1,202 @@
import { defineStore } from "pinia";
import { ref } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { useRouter } from "vue-router";
const router = useRouter();
import { dataListAPI, aiEmotionAPI } from "../api/dataAPI";
import { version } from "less";
export const fakeLinkDataListStore = defineStore(
"fakeLinkDataListStore",
() => {
const userInfo = ref({});
const getUserInfo = (username, password) => {
if (username == "hxl") {
userInfo.value.nickname = "NikooooHong";
userInfo.value.img =
"https://d31zlh4on95l9h.cloudfront.net/images/9a431843b182c64a05fa3c8f6772b8a4.png";
userInfo.value.token = "DairyQueen";
return 200;
} else {
return 400;
}
};
const getMarket = () => {
let market = "";
const queryMarket = getQueryVariable("market");
if (queryMarket) {
if (
typeof queryMarket === "string" &&
[
"sg",
"my",
"in",
"hk",
"th",
"vi",
"usa",
"can",
"gb",
"cn",
].includes(queryMarket)
) {
return (market = queryMarket);
} else {
switch (queryMarket) {
case "SGX":
return (market = "sg");
case "BMB":
return (market = "my");
case "IDX":
return (market = "in");
case "HKEX":
return (market = "hk");
case "SET":
return (market = "th");
case "HN":
return (market = "vi");
case "HONSE":
return (market = "vi");
case "AMERA":
return (market = "usa");
case "NYSE":
return (market = "usa");
case "NASDAQ":
return (market = "usa");
case "DLD":
return (market = "can");
case "DLDCY":
return (market = "can");
case "GINDEX":
return (market = "gb");
case "BZ":
return (market = "cn");
case "SH":
return (market = "cn");
case "SZ":
return (market = "cn");
default:
return "无市场数据";
}
}
} else {
return (market = "");
}
};
const getQueryVariable = (variable) => {
const query = window.location.search.substring(1);
const vars = query.split("&");
for (let i = 0; i < vars.length; i++) {
const pair = vars[i].split("=");
if (pair[0] === variable) {
return pair[1];
}
}
return "";
};
const dataList = ref({});
const brainDataList = ref(null);
const swordDataList = ref(null);
const priceDataList = ref(null);
const timeDataList = ref(null);
const showALLData = ref(null);
const HomePage = ref(null);
const AIBull = ref(null);
const AIGoldBull = ref(null);
const AIRadar = ref(null);
const fetchChartData = async () => {
const getMarketString = localStorage.getItem("localMarket");
const getCodeString = localStorage.getItem("localCode");
try {
const res = await dataListAPI({
token:
"8Csj5VVX1UbIb4C3oxrnbZi0+fEeMx8pywnIlrmTm45Cb/EllzWACLto9J9+fCFsfdgBOvKvyY94FvqlvM0",
market: getMarket() || getMarketString || "gb",
code: getQueryVariable("code") || getCodeString || "NDX",
language: "cn",
brainPrivilegeState: 1,
swordPrivilegeState: 1,
stockForecastPrivilegeState: 1,
spaceForecastPrivilegeState: 1,
aibullPrivilegeState: 1,
aigoldBullPrivilegeState: 1,
airadarPrivilegeState: 1,
marketList: ["usa", "sg", "my", "hk", "cn", "can", "vi", "th", "in"],
});
// 将涨跌幅改为保留两位小数
let zhangFu = res.data.HomePage.StockInformation.ZhangFu;
let head = zhangFu[0];
let tail = zhangFu[zhangFu.length - 1];
if (zhangFu && zhangFu.length > 2) {
zhangFu = zhangFu.slice(1, -1); // 去掉开头一位和结尾一位
}
zhangFu = Number(zhangFu).toFixed(2);
zhangFu = head + zhangFu + tail;
res.data.HomePage.StockInformation.ZhangFu = zhangFu;
res.data.ShowAll.StockInformation.ZhangFu = zhangFu;
console.log("res", res);
brainDataList.value = res.data.Brain;
swordDataList.value = res.data.Sword;
priceDataList.value = res.data.StockForecast;
timeDataList.value = res.data.SpaceForecast;
showALLData.value = res.data.ShowAll;
HomePage.value = res.data.HomePage;
AIBull.value = res.data.AIBull;
AIGoldBull.value = res.data.AIGoldBull;
AIRadar.value = res.data.AIRadar;
dataList.value = res.data; // 返回获取到的数据
} catch (error) {
console.error("获取图表数据出错:", error);
}
};
const AiEmotinData = ref({});
// 调用aiEmotionAPI获取数据
const getAiEmotinData = async () => {
const getMarketString = localStorage.getItem("localMarket");
const getCodeString = localStorage.getItem("localCode");
console.log(getMarketString, getCodeString);
try {
const res = await aiEmotionAPI({
token:
"8Csj5VVX1UbIb4C3oxrnbZi0+fEeMx8pywnIlrmTm45Cb/EllzWACLto9J9+fCFsfdgBOvKvyY94FvqlvM0",
market: getMarketString || "gb",
code: getCodeString || "NDX",
language: "cn",
version: "1",
});
// 处理响应数据
if (res.data) {
AiEmotinData.value = res.data;
}
} catch (error) {
console.error("获取图表数据出错:", error);
} finally {
console.log("数据获取过程结束");
}
};
return {
userInfo,
getUserInfo,
dataList,
HomePage,
fetchChartData,
AiEmotinData,
getAiEmotinData,
};
},
{
persist: {
key: "userInfo",
storage: sessionStorage,
paths: ["expireData"],
},
}
);

129
src/utils/request.js

@ -0,0 +1,129 @@
import axios from 'axios'
import { ElMessage } from 'element-plus'
const ERROR_MESSAGES = {
badRequest: '请求错误(400)',
unauthorized: '未授权,请登录(401)',
forbidden: '拒绝访问(403)',
notFound: `请求地址出错: ${'[具体 URL 将在这里被替换]'}`,
methodNotAllowed: '请求方法未允许(405)',
requestTimeout: '请求超时(408)',
internalServerError: '服务器内部错误(500)',
notImplemented: '服务未实现(501)',
badGateway: '网络错误(502)',
serviceUnavailable: '服务不可用(503)',
gatewayTimeout: '网络超时(504)',
httpVersionNotSupported: 'HTTP 版本不受支持(505)',
defaultConnectionError: '连接错误: [原始错误消息]',
networkError: '网络异常,请检查后重试!',
serverFailure: '连接到服务器失败,请联系管理员'
}
const service = axios.create({
baseURL: '', // url = base url + request url+
// timeout: 50000,
withCredentials: false // send cookies when cross-domain requests
// headers: {
// // clear cors
// 'Cache-Control': 'no-cache',
// Pragma: 'no-cache'
// }
})
const setErrorMsg = (error) => {
if (error && error.response) {
switch (error.response.status) {
case 400:
error.message = ERROR_MESSAGES.badRequest
break
case 401:
error.message = ERROR_MESSAGES.unauthorized
break
case 403:
error.message = ERROR_MESSAGES.forbidden
break
case 404:
error.message = ERROR_MESSAGES.notFound.replace(
'[具体 URL 将在这里被替换]',
error.response.config.url
)
break
case 405:
error.message = ERROR_MESSAGES.methodNotAllowed
break
case 408:
error.message = ERROR_MESSAGES.requestTimeout
break
case 500:
error.message = ERROR_MESSAGES.internalServerError
break
case 501:
error.message = ERROR_MESSAGES.notImplemented
break
case 502:
error.message = ERROR_MESSAGES.badGateway
break
case 503:
error.message = ERROR_MESSAGES.serviceUnavailable
break
case 504:
error.message = ERROR_MESSAGES.gatewayTimeout
break
case 505:
error.message = ERROR_MESSAGES.httpVersionNotSupported
break
default:
error.message = ERROR_MESSAGES.defaultConnectionError.replace(
'[原始错误消息]',
error.message
)
}
} else {
if (error.message === 'Network Error') {
error.message = ERROR_MESSAGES.networkError
} else {
error.message = ERROR_MESSAGES.serverFailure
}
}
return error.message
}
// Request interceptors
service.interceptors.request.use(
(config) => {
// 在此处添加请求头等,如添加 token
// if (store.state.token) {
// config.headers['Authorization'] = `Bearer ${store.state.token}`
// }
return config
},
(error) => {
return Promise.reject(error)
}
)
// Response interceptors
service.interceptors.response.use(
async (response) => {
// await new Promise(resovle => setTimeout(resovle, 3000));
// if (response.config.loadingInstance) {
// response.config.loadingInstance.close();
// }
const res = response.data
if (res.code !== 200) {
const errorMsg = res.msg || 'Unkonw error'
// ElMessage.error(errorMsg)
// return Promise.reject(new Error(res.msg || 'Error'))
return response.data
} else {
return response.data
}
},
(error) => {
const errorMessage = setErrorMsg(error)
ElMessage.error(errorMessage)
return Promise.reject(error)
}
)
export default service

3
src/views/animation/anima.vue

@ -1,4 +1,6 @@
<template>
<backBtn></backBtn>
<div class="total">
<div class="box" :class="{ 'box-animaToR': isAnimating, 'box-animaToL': !isAnimating }" @click="startAnimation">
<div v-if="!isTextAnimating">
@ -51,6 +53,7 @@
<script setup>
import { ref, onMounted } from 'vue';
import backBtn from '../commponent/backBtn.vue'
const firstAnimating=ref(false);
const isAnimating = ref(false);

3
src/views/calendar/calendar.vue

@ -1,4 +1,6 @@
<template>
<backBtn></backBtn>
<div class="bk">
<div class="bk1">
<div class="border1">
@ -61,6 +63,7 @@ import biaoti from "../../assets/img/标题.png";
import jiaobiao from "../../assets/img/角标.png";
import suoding from "../../assets/img/锁定.png";
import moment from "moment";
import backBtn from '../commponent/backBtn.vue'
const color = ref([
"#32A3FF",

16
src/views/commponent/backBtn.vue

@ -0,0 +1,16 @@
<template>
<div>
<el-button type="primary" @click="goBack">返回首页</el-button>
</div>
</template>
<script setup>
import { useRouter } from "vue-router";
const router = useRouter();
const goBack = () => {
router.push("/homepage");
};
</script>
<style scoped>
</style>

91
src/views/fakeLink/component/smallTitle.vue

@ -0,0 +1,91 @@
<template>
<header class="title">
<div class="title-text" :style="fontSize">
<img
v-if="props.colorBgc"
:src="titleLeft"
alt=""
class="title-text-img"
/>
<div v-if="props.colorBgc">{{ props.titleKey }}</div>
<img
v-if="props.colorBgc"
:src="titleRight"
alt=""
class="title-text-img"
/>
<img v-if="!props.colorBgc" :src="left" alt="" class="title-text-img" />
<div v-if="!props.colorBgc">{{ props.titleKey }}</div>
<img v-if="!props.colorBgc" :src="right" alt="" class="title-text-img" />
</div>
<div class="title-line">
<img :src="bigLine" class="title-line-img" />
</div>
</header>
</template>
<script setup>
import { defineProps, computed } from "vue";
import right from "../../../assets/img/smallTitle/右.png";
import left from "../../../assets/img/smallTitle/左.png";
import titleRight from "../../../assets/img/smallTitle/title-jn-right.png";
import titleLeft from "../../../assets/img/smallTitle/title-jn-left.png";
import bigLine from "../../../assets/img/smallTitle/BigLine.png";
// props
const props = defineProps({
titleKey: {
type: String,
required: true,
},
colorBgc: {
type: String,
required: true,
},
});
// fontSize computed
const fontSize = computed(() => {
//
if (window.innerWidth < 768) {
return { fontSize: "3.5vw" };
} else {
return { fontSize: "1.5vw" };
}
});
</script>
<style scoped lang="less">
.title {
position: relative;
.title-text {
font-size: 3vw;
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: center;
color: white;
.title-text-img {
width: 10%;
}
}
.title-line {
text-align: center;
position: absolute;
bottom: -1vw;
left: 50%; /* 将左边距设置为 50% */
transform: translateX(-50%); /* 使用 transform 来将元素水平居中 */
width: 85%;
.title-line-img {
width: 100%;
height: auto;
}
}
}
@media (min-width: 768px) {
.title-text-img {
width: 6% !important;
}
}
</style>

781
src/views/fakeLink/dbqb/dbqb.vue

@ -0,0 +1,781 @@
<template>
<div class="energyconverter">
<div>
<smallTitle titleKey="情绪能量转化器" />
</div>
<!-- k线图部分 -->
<div class="pricePrediction">
<section class="price-Prediction">
<div class="CanvsbackgroundImg">
<div class="trapezoid" ref="stockNameContainer">
<el-scrollbar v-if="isTextOverflow" class="stock-scrollbar">
<div class="stock-marquee" :data-text="StockInformation.Name">
<span
class="stock-name stock-name1"
style="white-space: nowrap; cursor: pointer"
>{{ StockInformation.Name }} {{ StockInformation.Code }}</span
>
</div>
</el-scrollbar>
<span
v-else
class="stock-name stock-name1"
style="white-space: nowrap; cursor: pointer"
>{{ StockInformation.Name }} {{ StockInformation.Code }}</span
>
</div>
<!-- k线图部分图纸 -->
<EnergyKlineEcharts class="k"></EnergyKlineEcharts>
</div>
</section>
</div>
<div class="smtcTitle">
<smallTitle titleKey="功能介绍" />
</div>
<div class="emotionDecoder" style="color: white">
<div class="functionIntroduce" :class="currentLang">
<ol>
<li>
<span class="area1" style="color: #ff9f9f">情绪冰点区</span
><span class="area1text"
>市场极度悲观绝望后的末端恐慌弥漫投资者信心崩溃普遍绝望对利好麻木对利空极度敏感割肉离场意愿强烈</span
>
</li>
<li>
<span class="area2" style="color: #ffcb75">认知潜伏区</span
><span class="area2text"
>聪明资金建仓期此时股票会呈现抗跌性但缺乏上涨动力市场情绪低迷悲观缺乏信心负面解读占主导潜在利好逻辑被忽视或质疑</span
>
</li>
<li>
<span class="area3" style="color: #d7e95d">多空消化区</span
><span class="area3text"
>市场从单边下跌转向震荡企稳多空力量从失衡转向初步平衡恐慌情绪缓解但信心依然脆弱多空分歧加大观望气氛浓厚对利好利空反应不一</span
>
</li>
<li>
<span class="area4" style="color: #a0f56f">共识加速区</span
><span class="area4text"
>市场或个股形成上涨共识进入主升浪乐观情绪快速升温并扩散信心高涨看多成为主流投资者追涨意愿强烈对利空选择性忽视或解读为利好</span
>
</li>
<li>
<span class="area5" style="color: #87f3cd">情绪临界区</span
><span class="area5text"
>市场情绪达到极度亢奋非理性的顶峰上涨动能接近衰竭的临界点狂热贪婪情绪主导估值体系失效风险意识被抛诸脑后</span
>
</li>
<li>
<span class="area6" style="color: #51c3f9">杠杆失衡区</span
><span class="area6text"
>市场系统脆弱性急剧上升价格波动被显著放大情绪高度敏感且脆弱波动剧烈引发恐慌参与者普遍焦虑对下跌的耐受度极低</span
>
</li>
<li>
<span class="area7" style="color: #d0a7ff">情绪熔断区</span
><span class="area7text"
>市场在极端负面情绪和恐慌抛售下触发交易机制熔断或出现类似熔断效应的流动性瞬间枯竭状态极度恐慌绝望非理性信心彻底崩溃</span
>
</li>
</ol>
</div>
</div>
<div class="smtcTitle">
<smallTitle titleKey="功能亮点" />
</div>
<div class="emotionDecoder" style="color: white">
<div class="functionlight">
<span
class="lighttitle"
:style="{
color: '#f8e71c',
whiteSpace: isChineseLanguage ? 'nowrap' : 'normal',
}"
>实现财富裂变情绪炼金炉</span
>
<br />
<span class="content">
股市中蕴藏着巨大的情绪能量恐惧与贪婪的碰撞产生市场波动势能股市本质是亿万股民的情绪熔炉情绪能量转化器首次运用行为金融物理模型将多空情绪的对冲转化为可定向输出的交易动能通过情绪炼金炉将这种交易动能划分为七种反应堆让每一场情绪风暴都成为你财富裂变的催化剂
</span>
<br />
</div>
</div>
</div>
</template>
<script setup>
import { computed, ref, onMounted, onUnmounted, watch } from "vue";
import { ElMessage } from "element-plus";
import EnergyKlineEcharts from "./echarts/EnergyKlineEcharts.vue";
import { fakeLinkDataListStore } from "../../../store/fakeLink-dataList";
const dataListStore = fakeLinkDataListStore();
import smallTitle from "../component/smallTitle.vue";
import { useRouter, useRoute } from "vue-router";
const router = useRouter();
const StockInformation = ref({});
//
onMounted(() => {
new Promise((data, emotionData) => {
dataListStore.fetchChartData();
dataListStore.getAiEmotinData();
});
StockInformation.value = dataListStore.AiEmotinData.StockInformation;
});
</script>
<style scoped lang="less">
.energyconverter {
border: 1px solid rgba(28, 99, 206, 0.8);
background-color: rgba(255, 255, 255, 0.1);
border-radius: 8px;
min-height: 100%;
// height: 100%;
width: 69%;
margin: 0vw auto;
margin-top: 20px;
}
/* 标题样式 */
.title {
color: white;
text-align: center;
margin-top: 1vw;
margin-bottom: 2vw;
font-size: 2vw;
}
/* 功能介绍样式 */
.functionIntroduce {
width: 100%;
font-size: 1.6vw;
position: relative;
line-height: 1.8;
margin-bottom: 0.8rem;
ol {
padding-left: 2.5rem;
margin: 0;
counter-reset: item;
@media (max-width: 768px) {
padding-left: 1.5rem;
}
}
li {
@media (min-width: 769px) and (max-width: 1024px) {
padding: 0.8rem 1rem;
font-size: 1.5rem !important;
}
@media (max-width: 768px) {
padding: 0.3rem 0.8rem;
}
}
.area {
display: inline-block;
font-size: clamp(1.2rem, 3vw, 1.6rem);
font-weight: bold;
margin-right: 0.8rem;
position: relative;
z-index: 12;
letter-spacing: 0.5px;
@media (min-width: 769px) and (max-width: 1024px) {
font-size: 6rem !important;
}
@media (max-width: 768px) {
font-size: clamp(1rem, 3.5vw, 1.2rem);
display: block;
}
}
.text {
font-size: clamp(1.1rem, 2.5vw, 1.3rem);
color: rgba(255, 255, 255, 0.95);
position: relative;
z-index: 12;
letter-spacing: 0.5px;
@media (min-width: 769px) and (max-width: 1024px) {
font-size: clamp(1.2rem, 2.8vw, 1.4rem);
line-height: 1.6;
}
@media (max-width: 768px) {
font-size: clamp(0.9rem, 3vw, 1.1rem);
display: block;
line-height: 1.4;
}
}
br {
margin-top: 0.8rem;
display: block;
content: "";
}
@media (min-width: 769px) and (max-width: 1024px) {
padding: 1.5rem 1.2rem;
}
}
.functionlight {
width: 100%;
padding: 2rem;
position: relative;
.lighttitle {
display: block;
font-size: clamp(1.4rem, 3vw, 1.8rem);
margin-top: -0.5rem;
line-height: 1.5;
letter-spacing: 0.8px;
text-align: center;
width: 100%;
font-weight: bold;
@media (min-width: 769px) and (max-width: 1024px) {
font-size: clamp(1.5rem, 3.2vw, 1.9rem);
margin-bottom: 0.5rem;
letter-spacing: 0.6px;
}
@media (max-width: 768px) {
font-size: clamp(1rem, 3.5vw, 1.3rem);
margin-bottom: 0.8rem;
letter-spacing: 0.5px;
padding: 0rem !important;
word-break: break-word;
}
}
.content {
display: block;
font-size: 1.6vw;
line-height: 1.8;
color: rgba(255, 255, 255, 0.95);
margin-bottom: 0.8rem;
text-indent: 2em;
@media (min-width: 769px) and (max-width: 1024px) {
font-size: clamp(1.2rem, 2.8vw, 1.4rem);
line-height: 1.5;
padding: 0.8rem 0.5rem;
text-align: justify;
}
@media (max-width: 768px) {
font-size: 0.9rem;
padding: 0.3rem 0.5rem;
text-align: justify;
}
}
br {
margin-top: 0.8rem;
display: block;
content: "";
}
/* 响应式调整 - 平板设备 */
@media (min-width: 769px) and (max-width: 1024px) {
padding: 1.5rem 1.2rem;
}
/* 响应式调整 - 手机设备 */
@media (max-width: 768px) {
padding: 1.2rem 0.8rem;
}
}
/* k线图部分 样式*/
.pricePrediction {
color: white;
.price-Prediction {
position: relative;
/* 标题 */
.trapezoid {
position: absolute;
top: 9%;
left: 7%;
color: #a7691c;
font-weight: bold;
font-size: 2vw;
z-index: 999;
}
/* 滚动条样式 */
.stock-scrollbar {
width: 70%;
height: auto;
}
.stock-marquee {
display: inline-block;
white-space: nowrap;
animation: marquee 10s linear infinite;
position: relative;
}
.stock-marquee::after {
content: "  " attr(data-text); /* 使用全角空格让中间空出来 */
position: absolute;
left: 100%;
white-space: nowrap;
color: #a7691c;
}
@keyframes marquee {
0% {
transform: translateX(0%);
}
100% {
transform: translateX(-120%);
}
}
.scrollbar-flex-content {
display: flex;
width: 130px;
}
.stock-name {
/* margin-top: 5px; */
/* display: flex; */
width: 100%;
cursor: pointer;
white-space: nowrap;
text-align: center;
/* align-items: center; */
/* justify-content: center; */
}
/* 背景 */
.CanvsbackgroundImg {
background-image: url("https://d31zlh4on95l9h.cloudfront.net/images/892dc6e2755ecc9cf6fb41561c287acf.png");
background-repeat: no-repeat;
background-size: 100% 100%;
height: 44vw;
max-width: 95%; //
padding: 20px 0px; // 10px 5px
box-sizing: border-box; // border-box
position: relative;
margin: 3vw auto 5vw auto; // auto
// margin-left: 30px; //
// margin-right: 30px; //
}
}
}
.smtcTitle {
margin-top: -1rem;
margin-bottom: 1rem;
position: relative;
z-index: 5;
/* 响应式调整 */
@media (max-width: 768px) {
margin-top: -0.5rem;
margin-bottom: 0.5rem;
}
}
/* 情绪解码器解释样式 - 响应式优化 */
.emotionDecoder {
/* 透明背景,方形边框样式 */
background-image: url("https://d31zlh4on95l9h.cloudfront.net/images/03e7df3bde2e80f71718b25fee3d4b98.png");
background-repeat: no-repeat;
background-size: 100% 100%;
height: auto;
position: relative;
display: flex;
padding: clamp(1.5rem, 3vw, 2.5rem);
/* 确保左右边距完全相等 */
width: 92%;
max-width: 1200px;
margin: clamp(1.5rem, 4vw, 3rem) auto;
/* 使用 auto 确保左右边距相等 */
letter-spacing: 0.5px;
// min-height: 220px;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
overflow-x: hidden;
/* 响应式调整 */
@media (max-width: 768px) {
padding: clamp(1rem, 2vw, 1.5rem);
width: 95%;
min-height: 180px;
margin: clamp(1rem, 2vw, 1.5rem) auto;
}
.box {
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
gap: clamp(1.5rem, 3vw, 2.5rem);
position: relative;
z-index: 5;
/* 响应式调整 */
@media (max-width: 768px) {
flex-direction: column;
gap: clamp(1rem, 2vw, 1.5rem);
}
}
// .message1,
// .message2 {
// color: white;
// padding: clamp(0.75rem, 1.5vw, 1.5rem);
// position: relative;
// flex: 1;
// border-radius: 4px;
// background: rgba(255, 255, 255, 0.05);
// backdrop-filter: blur(10px);
// }
.message1-en {
margin-left: 10px !important;
}
.title1-en,
.title2-en {
font-size: clamp(0.875rem, 1.2vw, 1.125rem);
color: #f8e71c;
font-weight: 600;
margin-bottom: clamp(0.5rem, 1vw, 1rem);
letter-spacing: 0.3px;
}
.message2-en {
color: white;
padding: clamp(0.75rem, 1.5vw, 1.5rem);
font-size: clamp(0.75rem, 1vw, 0.95rem);
line-height: 1.6;
}
.cycle-stage-table {
margin-top: clamp(1rem, 2vw, 2rem);
width: 100%;
overflow-x: auto;
table {
width: 100%;
border-collapse: collapse;
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
border-radius: 8px;
overflow: hidden;
border: 1px solid rgba(74, 144, 226, 0.3);
th,
td {
padding: clamp(0.75rem, 1.5vw, 1rem);
text-align: center;
border: 1px solid rgba(74, 144, 226, 0.2);
color: white;
font-size: clamp(0.8rem, 1vw, 1rem);
line-height: 1.4;
}
th {
background: rgba(74, 144, 226, 0.3);
color: white;
font-weight: 600;
letter-spacing: 0.5px;
}
tbody tr:nth-child(even) {
background: rgba(255, 255, 255, 0.02);
}
tbody tr:hover {
background: rgba(74, 144, 226, 0.1);
transition: background 0.3s ease;
}
td:first-child {
font-weight: 600;
color: white;
}
}
}
/* 温度区间表格样式 */
.temperature-table {
margin-top: clamp(1rem, 2vw, 2rem);
width: 100%;
overflow-x: auto;
table {
width: 100%;
border-collapse: collapse;
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
border-radius: 8px;
overflow: hidden;
border: 1px solid rgba(74, 144, 226, 0.3);
th,
td {
padding: clamp(0.75rem, 1.5vw, 1rem);
text-align: center;
border: 1px solid rgba(74, 144, 226, 0.2);
color: white;
font-size: clamp(0.8rem, 1vw, 1rem);
line-height: 1.4;
}
th {
background: rgba(74, 144, 226, 0.3);
color: white;
font-weight: 600;
letter-spacing: 0.5px;
}
tbody tr:nth-child(even) {
background: rgba(255, 255, 255, 0.02);
}
tbody tr:hover {
background: rgba(74, 144, 226, 0.1);
transition: background 0.3s ease;
}
td:first-child {
font-weight: 600;
color: white;
}
}
}
}
/* 在当前组件的style标签中添加以下代码 */
:deep(.echarts-container) {
background-color: #ffffff !important; //
}
/* pc端 */
/* 媒体查询(与原页面保持一致) */
@media (min-width: 768px) {
}
@media (min-width: 768px) and (max-width: 1024px) {
}
/* 大屏幕设备响应式 - message1和message2竖着排 */
@media (min-width: 1025px) {
.emotionDecoder {
.box {
flex-direction: column;
gap: clamp(1rem, 2vw, 2rem);
}
}
}
/* 平板设备响应式 */
@media (max-width: 1024px) {
.emotionDecoder {
// margin: clamp(0.75rem, 2vw, 1.5rem);
// padding: clamp(0.75rem, 1.5vw, 1.5rem);
.box {
flex-direction: column;
gap: clamp(0.75rem, 1.5vw, 1.25rem);
}
}
}
/* 移动设备响应式 */
@media (max-width: 768px) {
.functionIntroduce {
font-size: 0.9rem !important;
padding: 0 !important;
padding-left: 0rem !important;
/* 非中文语言在移动设备上的上下边距 */
&.en,
&.th,
&.kr {
padding-top: 2rem !important;
padding-bottom: 2rem !important;
/* 确保英文版本与中文版本字体大小一致 */
.area1,
.area2,
.area3,
.area4,
.area5,
.area6,
.area7 {
font-size: clamp(1rem, 3.5vw, 1.2rem) !important;
}
.area1text,
.area2text,
.area3text,
.area4text,
.area5text,
.area6text,
.area7text {
font-size: clamp(0.9rem, 3vw, 1.1rem) !important;
}
}
}
.pricePrediction .price-Prediction {
margin-bottom: 2rem;
.trapezoid {
font-size: 25px !important;
text-align: center;
top: 4.5%;
.scrollbar-flex-content {
display: flex;
width: 260px;
}
}
.CanvsbackgroundImg {
background-image: url(https://d31zlh4on95l9h.cloudfront.net/images/a3db9928e5e0b50e781ada5d4fa8dc43.png);
// padding: 40vw 5vw;
margin-top: 5vw !important;
background-size: 100% 100%;
width: 100%;
max-width: 95%;
height: 120vw;
}
}
.emotionDecoder {
margin-bottom: 2rem;
.box {
flex-direction: column;
gap: 1rem;
}
.message1-en {
margin-left: 20px !important;
}
.title1-en,
.title2-en {
font-size: 1rem;
margin-bottom: 0.5rem;
}
.message2-en {
font-size: 0.875rem;
padding: 0.75rem;
margin: 0.5rem 0;
}
}
.title {
font-size: 4vw !important;
}
.title1 {
font-size: 2.8vw !important;
}
.title1-en {
font-size: 2.8vw !important; /* 统一与中文版本相同的字体大小 */
top: -20px !important;
}
.message2 {
font-size: 3vw !important;
}
.message2-en {
font-size: 3vw !important;
margin: 35px 0px 20px 0px !important;
}
/* 获取报告图按钮样式 */
// .getReport {
// height: 25vw;
// bottom: -5vw;
// }
.title2 {
font-size: 2.8vw !important;
// margin-top: -4%;
}
.title2-en {
font-size: 2.8vw !important; /* 统一与中文版本相同的字体大小 */
// margin-top: -4%;
}
}
/* 小屏幕设备响应式 */
@media (max-width: 480px) {
.pricePrediction {
.price-Prediction {
.trapezoid {
font-size: 25px !important;
text-align: center;
}
}
}
.emotionDecoder {
.message1,
.message2 {
padding: 0.5rem;
}
.message2-en {
font-size: 0.8rem;
}
.cycle-stage-table {
margin: 0.5rem 0;
table {
th,
td {
padding: 0.5rem 0.25rem;
font-size: 0.75rem;
line-height: 1.3;
}
th {
font-size: 0.8rem;
}
}
}
/* 移动端表格样式 */
.temperature-table {
margin: 0.5rem 0;
table {
th,
td {
padding: 0.5rem 0.25rem;
font-size: 0.75rem;
line-height: 1.3;
}
th {
font-size: 0.8rem;
}
}
}
}
}
</style>

1238
src/views/fakeLink/dbqb/echarts/EnergyKlineEcharts.vue
File diff suppressed because it is too large
View File

231
src/views/fakeLink/homepage-two.vue

@ -0,0 +1,231 @@
<template>
<div class="container">
<div class="head">
<div class="head1">
<div class="head1Btn">
<img class="headImg" src="../../../public/left.png" alt="" />
</div>
<div class="head1Btn">
<img class="headImg" src="../../../public/right.png" alt="" />
</div>
<div class="head1Btn">
<img class="headImg" src="../../../public/refresh.png" alt="" />
</div>
<div class="head1Btn">
<img class="headImg" src="../../../public/home.png" alt="" />
</div>
</div>
<div class="head2">
<div class="rightGroup">
<div class="head2Btn">产品下载</div>
</div>
<div class="leftGroup">
<div class="head2Btn">消息</div>
<div class="head2Btn">精网原创</div>
<div class="head2Btn" v-if="dataListStore.userInfo.token">
<el-popover :width="150">
<template #reference>
<div class="userInfo">
<img :src="dataListStore.userInfo.img" alt="头像" />
<span class="nickname">{{
dataListStore.userInfo.nickname
}}</span>
</div>
</template>
<template #default>
<div class="userInfoBtn myAccount">我的账户</div>
<div class="userInfoBtn coupon">优惠券</div>
<div class="userInfoBtn myOrder">我的订单</div>
<div class="userInfoBtn" @click="logout">退出登录</div>
</template>
</el-popover>
</div>
<div class="head2Btn" v-else @click="login">登录</div>
<div class="head2Btn">多语言</div>
<div class="head2Btn">市场</div>
<div class="head2Btn">反馈帮助中心</div>
</div>
</div>
<div class="head3">
<img
src="https://d31zlh4on95l9h.cloudfront.net/assets/heimaxunzhang/blueHomliyLink.png"
alt="logo"
class="logo"
@click="router.push('/fakeLink')"
/>
<div class="breadCrumb">
<div @click="router.push('/fakeLink')" class="homePage">首页</div>
<span class="separator">/</span>
<div @click="router.push('/dbqb')" class="dbqb">夺宝奇兵</div>
</div>
</div>
</div>
<div class="body">
<div class="bodyContent">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, nextTick } from "vue";
import { fakeLinkDataListStore } from "../../store/fakeLink-dataList.js";
const dataListStore = fakeLinkDataListStore();
import { useRouter } from "vue-router";
const router = useRouter();
const login = () => {
router.push("/fakeLinkLogin");
};
const logout = () => {
router.push("/fakeLinkLogin");
};
</script>
<style scoped>
.container {
width: 100%;
height: 100%;
overflow: hidden;
}
.head {
width: 100%;
position: fixed;
top: 0px;
}
.head1 {
width: 100%;
height: 40px;
background-color: white;
display: flex;
align-items: center;
color: white;
}
.head2 {
width: 100%;
height: 45px;
background-color: #222222;
display: flex;
align-items: center;
color: white;
}
.head3 {
padding: 0 60px;
width: 100%;
height: 60px;
color: #808080;
display: flex;
align-items: center;
}
.logo {
width: 142px;
height: 24px;
margin-right: 100px;
cursor: pointer;
}
.breadCrumb {
display: flex;
}
.homePage {
cursor: pointer;
}
.separator {
margin: 0 5px;
}
.dbqb {
cursor: pointer;
}
.body {
padding: 145px 0 0 0;
box-sizing: border-box;
height: 100%;
overflow: hidden;
}
.bodyContent {
background-image: url("https://d31zlh4on95l9h.cloudfront.net/images/fba08457e53a11186eee9dacab51e344.png");
background-size: 100% 100%;
height: 100%;
overflow: auto;
}
.headImg {
height: 30px;
width: 30px;
}
.head1Btn {
height: 100%;
padding: 0 10px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.head1Btn:hover {
background-color: #d3d3d3;
}
.head2Btn {
height: 100%;
padding: 0 10px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.head2Btn:hover {
background-color: #333333;
}
.rightGroup {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.leftGroup {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-left: auto;
}
.userInfo {
display: flex;
justify-content: center;
}
.nickname {
display: flex;
justify-content: center;
align-items: center;
}
.userInfoBtn {
color: #409eff;
font-size: 14px;
padding: 0 20px;
white-space: nowrap;
overflow: hidden;
height: 34px;
line-height: 34px;
box-sizing: border-box;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
}
</style>

471
src/views/fakeLink/homepage.vue

@ -0,0 +1,471 @@
<template>
<div class="container">
<div class="head">
<div class="head1">
<div class="head1Btn">
<img class="headImg" src="../../../public/left.png" alt="" />
</div>
<div class="head1Btn">
<img class="headImg" src="../../../public/right.png" alt="" />
</div>
<div class="head1Btn">
<img class="headImg" src="../../../public/refresh.png" alt="" />
</div>
<div class="head1Btn">
<img class="headImg" src="../../../public/home.png" alt="" />
</div>
</div>
<div class="head2">
<div class="rightGroup">
<div class="head2Btn">产品下载</div>
</div>
<div class="leftGroup">
<div class="head2Btn">消息</div>
<div class="head2Btn">精网原创</div>
<div class="head2Btn" v-if="dataListStore.userInfo.token">
<el-popover :width="150">
<template #reference>
<div class="userInfo">
<img :src="dataListStore.userInfo.img" alt="头像" />
<span class="nickname">{{
dataListStore.userInfo.nickname
}}</span>
</div>
</template>
<template #default>
<div class="userInfoBtn myAccount">我的账户</div>
<div class="userInfoBtn coupon">优惠券</div>
<div class="userInfoBtn myOrder">我的订单</div>
<div class="userInfoBtn" @click="logout">退出登录</div>
</template>
</el-popover>
</div>
<div class="head2Btn" v-else @click="login">登录</div>
<div class="head2Btn">多语言</div>
<div class="head2Btn">市场</div>
<div class="head2Btn">反馈帮助中心</div>
</div>
</div>
</div>
<div class="body">
<el-container>
<el-aside width="150px">
<img
src="https://d31zlh4on95l9h.cloudfront.net/assets/homily-jingwangHw.png"
alt="logo"
class="logo"
/>
<div
v-for="item in leftList"
:key="item"
class="leftItem"
:class="{ leftItemActive: nowLeftItem == item }"
@click="clickLeftItem(item)"
>
{{ item }}
</div>
</el-aside>
<el-main class="bodyMain">
<div class="oneLine">
<el-carousel
height="150px"
direction="vertical"
:autoplay="true"
indicator-position="outside"
>
<el-carousel-item v-for="item in middleList" :key="item">
<img :src="item.img" alt="" class="carouselImg" />
</el-carousel-item>
</el-carousel>
</div>
<div class="twoLine">
<div class="search">
<input
type="text"
class="searchBox"
placeholder="请输入要搜索的内容"
/>
<div class="searchBtn">搜索</div>
</div>
<div class="dbqb">
<div class="dbqbTitle">夺宝奇兵</div>
<img
class="dbqbUrl"
src="https://d31zlh4on95l9h.cloudfront.net/images/4abaf213-6ced-4605-aca7-d7ff97c4d311.gif"
alt=""
@click="toDbqb"
/>
</div>
</div>
</el-main>
</el-container>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, nextTick } from "vue";
import { fakeLinkDataListStore } from "../../store/fakeLink-dataList.js";
const dataListStore = fakeLinkDataListStore();
import { useRouter } from "vue-router";
const router = useRouter();
const leftList = ref([
"关注",
"推荐",
"频道",
"资讯",
"轻松一刻",
"公司达人动态",
"剧场",
"任务中心",
"静态专区",
"视频",
"心愿池",
"电子书",
"弘历软件",
"征文",
"Homily Chart",
"炒股心理",
"技术分析新得",
"更多",
]);
const middleList = ref([
{
img: "https://d31zlh4on95l9h.cloudfront.net/images/5iujc501000dcoq046ryswk8p0qyj36t.jpg",
name: "今日直播",
},
{
img: "https://d31zlh4on95l9h.cloudfront.net/images/5iujc501000dco901dbcdjc7b04pl1k3.jpg",
name: "智见未来",
},
{
img: "https://d31zlh4on95l9h.cloudfront.net/images/5iujc501000dco7vaxmzf8e6v0o0yu14.jpg",
name: "课程安排",
},
{
img: "https://d31zlh4on95l9h.cloudfront.net/images/5iujc501000dcktw5n7cy7a17zrvf0cv.jpg",
name: "财神香港",
},
{
img: "https://d31zlh4on95l9h.cloudfront.net/images/5iujc501000dco8a40jtj9v6y0lba30k.png",
name: "情绪周期",
},
{
img: "https://d31zlh4on95l9h.cloudfront.net/images/5iujc501000dcncaw58dwlt5603ezwpz.jpg",
name: "MY线下",
},
]);
const login = () => {
router.push("/fakeLinkLogin");
};
const logout = () => {
router.push("/fakeLinkLogin");
};
const nowLeftItem = ref("推荐");
const clickLeftItem = (item) => {
nowLeftItem.value = item;
console.log(item);
};
const carouselRef = ref(null);
onMounted(async () => {
await nextTick();
//
const indicators = document.querySelectorAll(".el-carousel__button");
//
indicators.forEach((button, index) => {
console.log(button);
if (middleList.value[index]) {
//
button.textContent = middleList.value[index].name;
}
});
});
const toDbqb = () => {
router.push("/dbqb");
};
</script>
<style scoped>
.container {
width: 100%;
height: 100%;
}
.head {
width: 100%;
position: fixed;
top: 0px;
}
.head1 {
width: 100%;
height: 40px;
background-color: white;
display: flex;
align-items: center;
color: white;
}
.head2 {
width: 100%;
height: 45px;
background-color: #222222;
display: flex;
align-items: center;
color: white;
}
.body {
padding: 100px 380px 0 380px;
box-sizing: border-box;
}
.headImg {
height: 30px;
width: 30px;
}
.head1Btn {
height: 100%;
padding: 0 10px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.head1Btn:hover {
background-color: #d3d3d3;
}
.head2Btn {
height: 100%;
padding: 0 10px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.head2Btn:hover {
background-color: #333333;
}
.rightGroup {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.leftGroup {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-left: auto;
}
.userInfo {
display: flex;
justify-content: center;
}
.nickname {
display: flex;
justify-content: center;
align-items: center;
}
.userInfoBtn {
color: #409eff;
font-size: 14px;
padding: 0 20px;
white-space: nowrap;
overflow: hidden;
height: 34px;
line-height: 34px;
box-sizing: border-box;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
}
/* .userInfoBtn:hover{
} */
.myAccount {
}
.logo {
width: 80%;
/* height: 100%; */
}
.leftItem {
width: 80%;
height: 38px;
line-height: 38px;
border-radius: 4px;
font-size: 16px;
color: black;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 1.5px;
}
.leftItem:hover {
background-color: rgb(69, 131, 254);
color: white;
}
.leftItemActive {
background-color: rgb(69, 131, 254);
color: white;
}
.bodyMain {
padding: 0;
display: flex;
}
.oneLine {
/* border: 1px solid red; */
width: 65%;
}
.carouselImg {
width: 100%;
height: 300px;
}
.twoLine {
/* border: 1px solid blue; */
width: 35%;
}
.search {
width: 100%;
height: 44px;
display: flex;
background-color: rgba(142, 142, 142, 0.05);
font-size: 16px;
}
.searchBox {
background-color: rgba(245, 246, 247);
width: 78%;
padding: 10px;
border: 0.2px #76767618 solid;
font-size: 14px;
color: rgb(85, 85, 85) !important;
outline: none;
}
.searchBox:hover {
border: 1px solid #409eff;
}
.searchBox:focus {
border: 1px solid #409eff; /* 聚焦时的边框颜色 */
}
.searchBtn {
color: white;
background-color: rgb(32, 142, 218);
cursor: pointer;
margin-left: auto;
width: 22%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.dbqb {
box-sizing: border-box;
width: 100%;
padding: 15px;
font-size: 14px;
margin-top: 15px;
border-radius: 4px;
background-color: rgba(142, 142, 142, 0.05);
}
.dbqbTitle {
font-size: 18px;
color: rgb(34, 34, 34);
font-weight: bold;
margin-bottom: 30px;
}
.dbqbUrl {
width: 100%;
}
</style>
<style>
.el-carousel--vertical {
display: flex;
}
.el-carousel__container {
width: 91%;
height: 300px !important;
}
.el-carousel__indicators--outside {
background-color: black;
width: 9%;
display: flex;
flex-direction: column;
justify-content: center;
}
.el-carousel__indicator--vertical {
height: 50px;
width: 100%;
box-sizing: border-box;
color: white;
cursor: pointer;
font-size: 14px;
padding: 5px 0;
transition: all 0.3s ease-out;
/* background-color: rgb(0, 0, 0) !important; */
overflow: hidden;
}
/* .el-carousel__indicator--vertical .el-carousel__button{
} */
.el-carousel__button {
margin: 0;
height: 100% !important;
width: 100% !important;
border-radius: 0 !important;
color: white;
outline: none;
}
.el-carousel__indicators--outside button {
opacity: 1 !important;
background-color: transparent !important;
}
.is-active {
background-color: #fa2c19;
}
button {
outline: none;
}
</style>

163
src/views/fakeLink/login.vue

@ -0,0 +1,163 @@
<template>
<div class="container">
<div class="loginContainer">
<img
class="backgroundImg"
src="https://d31zlh4on95l9h.cloudfront.net/assets/registerHw.png"
alt=""
/>
<div class="loginWindow">
<input type="text" class="username" v-model="userInfo.username" />
<input type="password" class="password" v-model="userInfo.password" />
<div class="policy">
<el-checkbox-group v-model="agree">
<el-checkbox value="1" />
</el-checkbox-group>
<span class="hasAgreed">我已阅读并同意</span>
<span class="privacy">隐私条款</span>
</div>
<div class="login" @click="login">登录</div>
</div>
</div>
</div>
</template>
<script setup>
import { useRouter } from "vue-router";
import { ref, watch } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { fakeLinkDataListStore } from "../../store/fakeLink-dataList";
const fakeLinkDataStore = fakeLinkDataListStore();
const router = useRouter();
const agree = ref([]);
const userInfo = ref({
username: "",
password: "",
});
const login = () => {
if (!userInfo.value.username) {
ElMessage.error("请输入用户名");
return;
}
if (!userInfo.value.password) {
ElMessage.error("请输入密码");
return;
}
if (agree.value.length !== 1) {
ElMessage.error("请同意协议");
return;
}
const res = fakeLinkDataStore.getUserInfo(
userInfo.value.username,
userInfo.value.password
);
if (res == 200) {
ElMessage.success("登录成功");
router.push("fakeLink");
} else {
ElMessage.error("用户名或密码不正确");
}
};
</script>
<style scoped>
.container {
width: 100%;
height: 100%;
background-image: url("https://cdn.legu168.com/jtzy/Product/pcjingwang/images/login_bg_7584f6a.png");
background-size: 100% 100%;
background-repeat: no-repeat;
/* padding-top: 100px; */
}
.loginContainer {
position: relative;
display: flex;
/* width: 100%; */
/* height: 50%; */
justify-content: center;
padding-top: 30px;
}
.backgroundImg {
width: 630px;
height: auto;
position: absolute;
}
.loginWindow {
margin-top: 230px;
background-color: rgba(255, 255, 255, 0.9);
padding: 28px 50px;
width: 400px;
box-sizing: border-box;
display: flex;
flex-direction: column;
z-index: 2;
}
.username {
width: 300px;
height: 38px;
margin-bottom: 10px;
box-sizing: border-box;
font-size: 16px;
padding-left: 10px;
border: 1px solid rgb(221, 221, 221);
outline: none;
}
.username:focus {
border: 1px solid #409eff; /* 聚焦时的边框颜色 */
}
.password {
width: 300px;
height: 38px;
margin-bottom: 10px;
box-sizing: border-box;
font-size: 16px;
padding-left: 10px;
border: 1px solid rgb(221, 221, 221);
outline: none;
}
.password:focus {
border: 1px solid #409eff; /* 聚焦时的边框颜色 */
}
.policy {
display: flex;
align-items: center;
font-size: 14px;
}
.hasAgreed {
margin-right: 5px;
}
.privacy {
color: rgb(64, 101, 153);
cursor: pointer;
}
.privacy:hover {
color: red;
}
.login {
width: 100%;
height: 38px;
color: white;
background-color: rgb(248, 89, 89);
font-size: 18px;
margin: 20px 0px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
</style>

32
src/views/homepage.vue

@ -1,28 +1,36 @@
<template>
<h1 style="width:100%;text-align:center;margin:20px 0px 10px 0px">练习首页</h1>
<h1 style="width: 100%; text-align: center; margin: 20px 0px 10px 0px">
练习首页
</h1>
<el-divider>
<el-icon><star-filled /></el-icon>
</el-divider>
<div class="btns">
<div v-for="button in buttons" :key="button.text" :type="button.type" class="btn" @click="router.push(button.path)">
<div
v-for="button in buttons"
:key="button.text"
:type="button.type"
class="btn"
@click="router.push(button.path)"
>
{{ button.text }}
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
import { ref } from "vue";
import { useRouter } from "vue-router";
const router = useRouter();
const buttons = [
{ type: 'primary', text: '转盘',path:'/hxl_dzp1' },
{ type: 'success', text: '动画',path:'/animation' },
{ type: 'success', text: '作业',path:'/homework' },
{ type: 'success', text: '日历',path:'/calendar' },
]
{ type: "primary", text: "转盘", path: "/hxl_dzp1" },
{ type: "success", text: "动画", path: "/animation" },
{ type: "success", text: "作业", path: "/homework" },
{ type: "success", text: "日历", path: "/calendar" },
{ type: "success", text: "3D1", path: "/3D1" },
{ type: "success", text: "HomilyLink", path: "/fakeLink" },
];
</script>
<style scoped>

6
src/views/homework/homework.vue

@ -1,4 +1,6 @@
<template>
<backBtn></backBtn>
<div class="total">
<el-card class="card">
<div class="title">作业</div>
@ -55,6 +57,8 @@
<script setup>
import { ref } from 'vue'
import backBtn from '../commponent/backBtn.vue'
const qLists = ref([]);
const qIndex = ref(0)
const danxun = () => {
@ -169,6 +173,8 @@ const submit = () => {
.qLists {
width: 500px;
min-height: 200px;
max-height: 600px;
overflow: auto;
margin-top: 20px;
background-color: #f0f0f0;
display: flex;

161
src/views/hxl_DZP/dzp1.vue

@ -1,81 +1,124 @@
<script setup>
import { ref, onMounted } from 'vue'
import { ref, onMounted } from "vue";
import backBtn from "../commponent/backBtn.vue";
const showPopup = ref(false);
const popupMessage = ref('');
const totalScore = ref(4000) //
const myLucky = ref()
const popupMessage = ref("");
const totalScore = ref(4000); //
const myLucky = ref();
//
const spinCount = ref(0)
const isSpinning = ref(false)
const spinCount = ref(0);
const isSpinning = ref(false);
//
//const baseScore = 4000
const wheelConfig = ref({
})
const wheelConfig = ref({});
const prizes = ref([
{ fonts: [{ text: '-199', top: '10%', fontColor: '#FF2C29', fontSize: '40px' }], background: '#FAF9F0' }, //0
{ fonts: [{ text: '-55', top: '10%', fontColor: '#FF2C29', fontSize: '40px' }], background: '#F5D7AD' }, //1
{ fonts: [{ text: '+200', top: '10%', fontColor: '#FF2C29', fontSize: '40px' }], background: '#FAF9F0' }, //2
{ fonts: [{ text: '-88', top: '10%', fontColor: '#FF2C29', fontSize: '40px' }], background: '#F5D7AD' }, //3
{ fonts: [{ text: '-11', top: '10%', fontColor: '#FF2C29', fontSize: '40px' }], background: '#FAF9F0' }, //4
{ fonts: [{ text: '-299', top: '10%', fontColor: '#FF2C29', fontSize: '40px' }], background: '#F5D7AD' }, //5
{ fonts: [{ text: '+200', top: '10%', fontColor: '#FF2C29', fontSize: '40px' }], background: '#FAF9F0' }, //6
{ fonts: [{ text: '-66', top: '10%', fontColor: '#FF2C29', fontSize: '40px' }], background: '#F5D7AD' }, //7
])
const blocks = ref([{ padding: '13px', background: ' #FF2A00' }])
{
fonts: [
{ text: "-199", top: "10%", fontColor: "#FF2C29", fontSize: "40px" },
],
background: "#FAF9F0",
}, //0
{
fonts: [
{ text: "-55", top: "10%", fontColor: "#FF2C29", fontSize: "40px" },
],
background: "#F5D7AD",
}, //1
{
fonts: [
{ text: "+200", top: "10%", fontColor: "#FF2C29", fontSize: "40px" },
],
background: "#FAF9F0",
}, //2
{
fonts: [
{ text: "-88", top: "10%", fontColor: "#FF2C29", fontSize: "40px" },
],
background: "#F5D7AD",
}, //3
{
fonts: [
{ text: "-11", top: "10%", fontColor: "#FF2C29", fontSize: "40px" },
],
background: "#FAF9F0",
}, //4
{
fonts: [
{ text: "-299", top: "10%", fontColor: "#FF2C29", fontSize: "40px" },
],
background: "#F5D7AD",
}, //5
{
fonts: [
{ text: "+200", top: "10%", fontColor: "#FF2C29", fontSize: "40px" },
],
background: "#FAF9F0",
}, //6
{
fonts: [
{ text: "-66", top: "10%", fontColor: "#FF2C29", fontSize: "40px" },
],
background: "#F5D7AD",
}, //7
]);
const blocks = ref([{ padding: "13px", background: " #FF2A00" }]);
const buttons = ref([
{ radius: '50%', background: '#617df2' },
{ radius: '45%', background: '#afc8ff' },
{ radius: "50%", background: "#617df2" },
{ radius: "45%", background: "#afc8ff" },
{
radius: '40%', background: '#869cfa', pointer: true,
fonts: [{ text: '开始\n抽奖', top: '-20px' }]
}])
radius: "40%",
background: "#869cfa",
pointer: true,
fonts: [{ text: "开始\n抽奖", top: "-20px" }],
},
]);
//
const customOrder = ref([0, 4, 3, 1, 2, 4, 5, 7, 3, 4, 0])
const customOrder = ref([0, 4, 3, 1, 2, 4, 5, 7, 3, 4, 0]);
let orderIndex = 0;
function startCallback() {
//
if (spinCount.value >= 11) { // 01112
alert('已达最大转动次数!')
return
if (spinCount.value >= 11) {
// 01112
alert("已达最大转动次数!");
return;
}
isSpinning.value = true
spinCount.value++
isSpinning.value = true;
spinCount.value++;
//
//totalScore.value = baseScore
// play
myLucky.value.play()
myLucky.value.play();
//
setTimeout(() => {
//
console.log(orderIndex, 'orderIndex')
console.log(orderIndex, "orderIndex");
const index = orderIndex
const index = orderIndex;
console.log(customOrder.value[index], 'custome')
console.log(customOrder.value[index], "custome");
// stop
myLucky.value.stop(customOrder.value[index])
myLucky.value.stop(customOrder.value[index]);
//()
orderIndex = (index + 1) % customOrder.value.length;
}, 3000)
}, 3000);
}
const scoreAnimation = ref(false)
const scoreAnimation = ref(false);
// end
function endCallback(prize) {
const result = Number(prize.fonts[0].text)
console.log(prize.fonts[0].text)
const result = Number(prize.fonts[0].text);
console.log(prize.fonts[0].text);
//
setTimeout(() => {
totalScore.value = totalScore.value + result
totalScore.value = totalScore.value + result;
}, 1000);
//
animateScoreChange()
animateScoreChange();
//
popupMessage.value = "";
showPopup.value = true;
@ -92,28 +135,37 @@ function endCallback(prize) {
}
//
const animateScoreChange = () => {
scoreAnimation.value = true
scoreAnimation.value = true;
setTimeout(() => {
scoreAnimation.value = false
}, 3000)
}
scoreAnimation.value = false;
}, 3000);
};
onMounted(() => {
console.log(import.meta.env.MODE, '1111')
console.log(process.env.NODE_ENV, '2222')
})
console.log(import.meta.env.MODE, "1111");
console.log(process.env.NODE_ENV, "2222");
});
</script>
<template>
<backBtn></backBtn>
<div style="display: flex; height: 100%; width: 100%">
<el-card class="manageCard">
管理台
</el-card>
<el-card class="manageCard"> 管理台 </el-card>
<el-card class="wheelCard">
<div class="luckyWheel">
<LuckyWheel class="lucky" ref="myLucky" width="434px" height="434px" :default-config="wheelConfig"
:prizes="prizes" :blocks="blocks" :buttons="buttons" @start="startCallback" @end="endCallback" />
<LuckyWheel
class="lucky"
ref="myLucky"
width="434px"
height="434px"
:default-config="wheelConfig"
:prizes="prizes"
:blocks="blocks"
:buttons="buttons"
@start="startCallback"
@end="endCallback"
/>
</div>
</el-card>
</div>
@ -128,5 +180,4 @@ onMounted(() => {
width: auto;
flex: 1;
}
</style>

79
src/views/three3D/3D1.vue

@ -0,0 +1,79 @@
<template>
<backBtn></backBtn>
<div>3D1</div>
<div id="webgl" style="margin-top: 200px; margin-left: 100px"></div>
</template>
<script setup>
// three.js
import * as THREE from "three";
// OrbitControls.js
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import backBtn from '../commponent/backBtn.vue'
import { ref, onMounted } from "vue";
onMounted(() => {
create3D1();
});
const create3D1 = () => {
// 3DScene
const scene = new THREE.Scene();
//Geometry
const geometry = new THREE.BoxGeometry(100, 100, 100);
//Material
const material = new THREE.MeshBasicMaterial({
color: 0xff0000, //0xff0000
});
// geometrymaterial
const mesh = new THREE.Mesh(geometry, material); //Mesh
//
mesh.position.set(0, 0, 0);
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);
scene.add(mesh);
// (:px)
const width = 800; //
const height = 500; //
//
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
//Three.js
//
camera.position.set(200, 200, 200);
camera.lookAt(mesh.position); //mesh
//
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //three.js(px)
// renderer.render(scene, camera); //
document.getElementById("webgl").appendChild(renderer.domElement);
const clock = new THREE.Clock();
//
function render() {
const spt = clock.getDelta() * 1000; //
// console.log("()", spt);
// console.log("FPS", 1000 / spt);
renderer.render(scene, camera); //
mesh.rotateY(0.01); //y0.01
requestAnimationFrame(render); //render
}
render();
// OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// OrbitControls
controls.addEventListener("change", function () {
renderer.render(scene, camera); //
}); //
};
</script>
<style scoped>
</style>
Loading…
Cancel
Save