u
This commit is contained in:
1 parent
d1b1aafc57
commit
0f1604c709
58 files changed
+15476
-25
No files matched your search
@@ -0,0 +1,11 @@
|
||||
# Editor configuration, see http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
@@ -0,0 +1,16 @@
|
||||
VITE_BASE_URL=/
|
||||
|
||||
VITE_APP_TITLE=IIBTA-VUE
|
||||
|
||||
# icon图标前缀:iconify库相关
|
||||
VITE_ICON_PREFIX = i
|
||||
# icon本地图标前缀:本地相关
|
||||
VITE_ICON_LOCAL_PREFIX = i-local
|
||||
|
||||
# 上传地址
|
||||
VITE_UPLOAD_BASEURL = ''
|
||||
|
||||
# 是否开启代理 Y 开启 N 不开启
|
||||
VITE_APP_PROXY= 'Y'
|
||||
# 代理地址
|
||||
VITE_APP_PROXY_PREFIX = '/api'
|
||||
@@ -0,0 +1,4 @@
|
||||
ENV = 'prod'
|
||||
|
||||
VITE_SERVER_BASEURL = ''
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
ENV = 'test'
|
||||
|
||||
VITE_SERVER_BASEURL = ''
|
||||
@@ -0,0 +1,28 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
*.tsbuildinfo
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"afzalsayed96.icones",
|
||||
"antfu.iconify",
|
||||
"antfu.unocss",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"editorconfig.editorconfig",
|
||||
"esbenp.prettier-vscode",
|
||||
"mhutchie.git-graph",
|
||||
"mikestead.dotenv",
|
||||
"sdras.vue-vscode-snippets",
|
||||
"vue.volar",
|
||||
]
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.organizeImports": "never"
|
||||
},
|
||||
"editor.formatOnSave": false,
|
||||
"eslint.validate": [
|
||||
"html",
|
||||
"css",
|
||||
"scss",
|
||||
"json",
|
||||
"jsonc",
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"typescript",
|
||||
"typescriptreact",
|
||||
"vue"
|
||||
],
|
||||
"prettier.enable": false,
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"unocss.root": ["./"]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-cmn-Hans">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.svg" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<title>%VITE_APP_TITLE%</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"name": "iibta-vue",
|
||||
"type": "module",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"author": {
|
||||
"name": "ONEAO",
|
||||
"email": "hi_itao@163.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.12.0",
|
||||
"pnpm": ">=8.7.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "vite build --mode prod",
|
||||
"build:test": "vite build --mode test",
|
||||
"dev": "vite --mode test",
|
||||
"dev:prod": "vite --mode prod",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@better-scroll/core": "2.5.1",
|
||||
"@iconify/vue": "4.3.0",
|
||||
"@vueuse/core": "12.4.0",
|
||||
"axios": "^1.7.9",
|
||||
"clipboard": "2.0.11",
|
||||
"dayjs": "1.11.13",
|
||||
"json5": "2.2.3",
|
||||
"nprogress": "0.2.0",
|
||||
"pinia": "2.3.0",
|
||||
"pinia-plugin-persistedstate": "^4.2.0",
|
||||
"qs": "^6.14.0",
|
||||
"tailwind-merge": "2.6.0",
|
||||
"vue": "3.5.13",
|
||||
"vue-router": "4.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/material-symbols": "^1.2.15",
|
||||
"@iconify/json": "2.2.297",
|
||||
"@iconify/utils": "^2.2.1",
|
||||
"@types/node": "22.10.7",
|
||||
"@types/nprogress": "0.2.3",
|
||||
"@unocss/preset-icons": "65.4.2",
|
||||
"@unocss/preset-uno": "65.4.2",
|
||||
"@unocss/transformer-directives": "65.4.2",
|
||||
"@unocss/transformer-variant-group": "65.4.2",
|
||||
"@unocss/vite": "65.4.2",
|
||||
"@vitejs/plugin-vue": "5.2.1",
|
||||
"@vitejs/plugin-vue-jsx": "4.1.1",
|
||||
"globals": "^15.14.0",
|
||||
"sass": "1.83.4",
|
||||
"tsx": "4.19.2",
|
||||
"typescript": "5.7.3",
|
||||
"unplugin-icons": "22.0.0",
|
||||
"unplugin-vue-components": "28.0.0",
|
||||
"vite": "6.0.7",
|
||||
"vite-plugin-progress": "0.0.7",
|
||||
"vite-plugin-svg-icons": "2.0.1",
|
||||
"vite-plugin-vue-devtools": "7.7.0",
|
||||
"vue-tsc": "2.2.0"
|
||||
},
|
||||
"website": "https://user-template.cn"
|
||||
}
|
||||
Generated
+6055
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 160 160" xmlns="http://www.w3.org/2000/svg"><path d="M81.28 55.9c-.1-11.67-2.93-22.55-9.37-32.38-1-1.5-2.14-2.86-2.5-4.71a8.1 8.1 0 014-8.61 7.89 7.89 0 019.3 1.23 35.999 35.999 0 015.9 8.83 75.18 75.18 0 018.44 28.58 83.211 83.211 0 01-5.23 36.74 102.983 102.983 0 01-3 7.28 1.2 1.2 0 000 1.41c9.58 13.3 21.76 23 37.85 27.24a54.37 54.37 0 0019.68 1.57 7.72 7.72 0 018.36 6.9 7.903 7.903 0 01-6.7 9 64.744 64.744 0 01-23-1.33 77.68 77.68 0 01-36.93-19.88 93.628 93.628 0 01-11.91-13.71 2.18 2.18 0 00-2.3-1.06 72.744 72.744 0 00-27.38 7.55c-11.6 6-20.67 14.58-26.4 26.45a10.134 10.134 0 01-3.7 4.7 8 8 0 01-9.19-.7 7.86 7.86 0 01-2.36-9.28 60.324 60.324 0 018.72-14.52c12.2-15.43 28.21-24.59 47.32-28.57A85.085 85.085 0 0173.07 87c.524.015 1-.307 1.18-.8a76.06 76.06 0 006.53-22.3c.351-2.652.518-5.325.5-8z" fill="#646cff"/><path d="M136.26 108.34a44.742 44.742 0 01-11.13-2.87 46.108 46.108 0 01-19.66-13.76 8 8 0 015.72-13.22 7.93 7.93 0 016.54 2.93 33.27 33.27 0 0018.87 10.75c1.546.155 3.058.553 4.48 1.18a8.08 8.08 0 013.84 9.21c-.92 3.52-4.13 5.81-8.66 5.78zm-80.6-75.02a7.61 7.61 0 016.64 5 49.139 49.139 0 013.64 17 46.33 46.33 0 01-2.46 17.28c-2 5.77-8.24 7.79-12.89 4.15a8.1 8.1 0 01-2.39-9 31.679 31.679 0 001.68-12.36 35.77 35.77 0 00-2.43-11c-2.1-5.45 1.75-11.07 8.21-11.07zm22.26 93.25a8 8 0 01-6.68 7.86 32.88 32.88 0 00-19.7 12.19 8.13 8.13 0 01-11.21 1.62 8 8 0 01-1.41-11.58A51.043 51.043 0 0154 123.81a45.842 45.842 0 0114-5.1c5.35-1.04 9.91 2.56 9.92 7.86z" fill="#646cff"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<router-view></router-view>
|
||||
</template>
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,54 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, useAttrs } from 'vue';
|
||||
import { Icon } from '@iconify/vue';
|
||||
|
||||
defineOptions({ name: 'SvgIcon', inheritAttrs: false });
|
||||
|
||||
/**
|
||||
* Props
|
||||
*
|
||||
* - Support iconify and local svg icon
|
||||
* - If icon and localIcon are passed at the same time, localIcon will be rendered first
|
||||
*/
|
||||
interface Props {
|
||||
/** Iconify icon name */
|
||||
icon?: string;
|
||||
/** Local svg icon name */
|
||||
localIcon?: string;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const attrs = useAttrs();
|
||||
|
||||
const bindAttrs = computed<{ class: string; style: string }>(() => ({
|
||||
class: (attrs.class as string) || '',
|
||||
style: (attrs.style as string) || ''
|
||||
}));
|
||||
|
||||
const symbolId = computed(() => {
|
||||
const { VITE_ICON_LOCAL_PREFIX: prefix } = import.meta.env;
|
||||
|
||||
const defaultLocalIcon = 'no-icon';
|
||||
|
||||
const icon = props.localIcon || defaultLocalIcon;
|
||||
|
||||
return `#${prefix}-${icon}`;
|
||||
});
|
||||
|
||||
/** If localIcon is passed, render localIcon first */
|
||||
const renderLocalIcon = computed(() => props.localIcon || !props.icon);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-if="renderLocalIcon">
|
||||
<svg aria-hidden="true" width="1em" height="1em" v-bind="bindAttrs">
|
||||
<use :xlink:href="symbolId" fill="currentColor" />
|
||||
</svg>
|
||||
</template>
|
||||
<template v-else>
|
||||
<Icon v-if="icon" :icon="icon" v-bind="bindAttrs" />
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,136 @@
|
||||
import axios, { AxiosInstance, AxiosResponse, AxiosError, InternalAxiosRequestConfig } from "axios";
|
||||
import { Message } from "@arco-design/web-vue";
|
||||
import { useRouterStore } from "@/store/router";
|
||||
import { useUserStore } from "@/store/user";
|
||||
import { ResponseStatusEnum, ResponseStatusErrorMessageEnum } from "@/types/enums"
|
||||
|
||||
const buildBaseUrl = () => {
|
||||
const isProxy = import.meta.env.VITE_APP_PROXY === "Y";
|
||||
const mode = import.meta.env.MODE;
|
||||
const proxyPrefix = import.meta.env.VITE_APP_PROXY_PREFIX;
|
||||
|
||||
const baseURL = import.meta.env.VITE_SERVER_BASEURL;
|
||||
|
||||
if (mode === "prod") {
|
||||
if (isProxy) {
|
||||
return baseURL + proxyPrefix;
|
||||
} else {
|
||||
return baseURL;
|
||||
}
|
||||
} else {
|
||||
if (isProxy) {
|
||||
return proxyPrefix;
|
||||
} else {
|
||||
return baseURL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const axiosInstance: AxiosInstance = axios.create({
|
||||
baseURL: buildBaseUrl(),
|
||||
timeout: 0
|
||||
});
|
||||
|
||||
|
||||
// 请求拦截器
|
||||
axiosInstance.interceptors.request.use(
|
||||
(config: InternalAxiosRequestConfig) => {
|
||||
const userStore = useUserStore();
|
||||
const noFreePaths = ["/imMessage/**"];
|
||||
const path = config.url || "";
|
||||
|
||||
const needAuth = noFreePaths.some((pattern) => {
|
||||
const regex = new RegExp(
|
||||
pattern
|
||||
.replace(/(\/\*\*)/g, "(/.*)?")
|
||||
.replace(/(\/\*)/g, "(/[^/]*)?")
|
||||
.replace(/\./g, "\\.") + "$"
|
||||
);
|
||||
return regex.test(path);
|
||||
});
|
||||
|
||||
if (needAuth) {
|
||||
userStore.clearUserInfo();
|
||||
return Promise.reject(new Error("尚未登录,请先登录!"));
|
||||
}
|
||||
|
||||
// 如果 token 存在,添加到请求头
|
||||
config.headers["Authorization"] = `Bearer ${userStore.userInfo.token}`;
|
||||
config.headers["id"] = userStore.userInfo.id;
|
||||
|
||||
return config;
|
||||
},
|
||||
(error: AxiosError) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
axiosInstance.interceptors.response.use(
|
||||
(response: AxiosResponse) => {
|
||||
// 判断响应是否为文件下载类型(例如 application/octet-stream)
|
||||
const isDownload = isDownloadResponse(response.headers);
|
||||
// 如果是文件下载,直接返回响应数据,不做其他处理
|
||||
if (isDownload) {
|
||||
return response;
|
||||
}
|
||||
|
||||
// 如果不是文件下载,继续进行错误处理和数据解析
|
||||
if (response.status !== 200) {
|
||||
Message.error("请求错误");
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
const resData = response.data as IResData;
|
||||
|
||||
// 解析返回数据中的字段
|
||||
response.data.data = parseJsonOrReturnString(response.data.data);
|
||||
|
||||
const routerStore = useRouterStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
if (resData.code >= 200 && resData.code < 300) {
|
||||
return Promise.resolve(response.data);
|
||||
} else if (resData.code >= 400 && resData.code <= 500) {
|
||||
Message.error(resData.message || "请求错误");
|
||||
switch (resData.code) {
|
||||
case ResponseStatusEnum.UNAUTHORIZED:
|
||||
if (routerStore.getCurrentPath() !== "/login") {
|
||||
userStore.clearUserInfo();
|
||||
routerStore.toPath("/login");
|
||||
}
|
||||
}
|
||||
return Promise.reject(resData);
|
||||
} else {
|
||||
Message.error(resData.message || "请求错误");
|
||||
return Promise.reject(resData);
|
||||
}
|
||||
},
|
||||
(error: AxiosError) => {
|
||||
// 网络错误处理
|
||||
switch (error.message) {
|
||||
case ResponseStatusErrorMessageEnum.NO_LOGIN:
|
||||
Message.error(ResponseStatusErrorMessageEnum.NO_LOGIN);
|
||||
break;
|
||||
default:
|
||||
// 其他情况提示网络错误
|
||||
Message.error("网络错误,请换个网络试试!");
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function isDownloadResponse(headers: any): boolean {
|
||||
const contentType = headers["content-type"];
|
||||
return /application\/(octet-stream|force-download|pdf|vnd.ms-excel|msexcel|OCTET-STREAM)/.test(contentType || "");
|
||||
}
|
||||
|
||||
function parseJsonOrReturnString(input: any) {
|
||||
try {
|
||||
// 尝试解析输入字符串
|
||||
return JSON.parse(input); // 如果成功,返回解析后的内容
|
||||
} catch {
|
||||
// 如果解析失败,则返回原始字符串
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
export default axiosInstance;
|
||||
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<Topbar></Topbar>
|
||||
<Center></Center>
|
||||
<Footer></Footer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Topbar from "../topbar/index.vue";
|
||||
import Center from "../center/index.vue";
|
||||
import Footer from "../footer/index.vue";
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<router-view></router-view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div class="footer">footer</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.footer {
|
||||
width: 100%;
|
||||
padding-bottom: 20px;
|
||||
margin-top: 88px;
|
||||
background: #efeff1;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<header class="ys-header__top clearfix">
|
||||
<div class="mt-talgm container">
|
||||
<div class="c row">
|
||||
<div class="ww-twybf ys-header_bd clearfix">
|
||||
<div class="tp-gbkrn ys-header__logo" style="padding-top: 5px;">
|
||||
<a class="logo">
|
||||
<img class="img-responsive hidden-xs" src="/static/images/logo.gif" style="width:150px;height:50px"></img>
|
||||
<img class="img-responsive visible-xs" src="/static/images/logo.gif" style="width:120px;height:40px"></img>
|
||||
</a>
|
||||
</div>
|
||||
<ul class="ys-header__menu nav-menu">
|
||||
<li class="hidden-sm hidden-xs"><a>首页</a></li>
|
||||
<li class="visible-inline-lg"><a href="/s/film/">电影</a></li>
|
||||
<li class="visible-inline-lg"><a href="/s/juji/">剧集</a></li>
|
||||
<li class="visible-inline-lg"><a href="/s/variety/">综艺</a></li>
|
||||
<li class="visible-inline-lg"><a href="/s/animation/">动漫</a></li>
|
||||
<li class="visible-inline-lg"><a href="http://xs.iibta.com/">小说</a></li>
|
||||
<li class="dropdown-hover">
|
||||
<a href="javascript:;">频道 <i class="fa fa-angle-down"></i></a>
|
||||
<div class="ho-qgtxn dropdown-box bottom fadeInDown clearfix" style="">
|
||||
<ul class="item nav-list clearfix">
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/">首页</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/film/">电影</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/juji/">剧集</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/variety/">综艺</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/animation/">动漫</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/news/information/">资讯</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/actor/type/id/star.html">明星</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/ancient/">古装</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/adventure/">冒险</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/suspense/">悬疑</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/crime/">犯罪</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/fantasy/">奇幻</a></li>
|
||||
|
||||
|
||||
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/thriller/">惊悚</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/disaster/">灾难</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/micro/">微电影</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/record/">记录</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/ethical/">理伦</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/others/">其它</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/action/">动作</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/comedy/">喜剧</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/s/romance/">爱情</a></li>
|
||||
<li class="col-lg-5 col-md-5 col-sm-5 col-xs-3"><a class="btn btn-sm btn-block btn-default" href="/star/">明星</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@media (width >= 1400px) {
|
||||
.container {
|
||||
padding-right: 120px;
|
||||
padding-left: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1400px) {
|
||||
.container {
|
||||
max-width: 1920px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,17 @@
|
||||
import { createApp } from "vue";
|
||||
import "./plugins/assets";
|
||||
import { setupNProgress } from "./plugins/index";
|
||||
import { setupPinia } from "./store";
|
||||
import { setupRouter } from "./router/index";
|
||||
import App from "./App.vue";
|
||||
|
||||
async function setupApp() {
|
||||
setupNProgress();
|
||||
|
||||
const app = createApp(App);
|
||||
setupPinia(app);
|
||||
setupRouter(app);
|
||||
app.mount("#app");
|
||||
}
|
||||
|
||||
setupApp();
|
||||
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div class="about">
|
||||
<div></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.about {
|
||||
margin-top: 70px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div class="home">Home</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.home {
|
||||
margin-top: 70px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
// import "uno.css";
|
||||
// import "virtual:svg-icons-register";
|
||||
import "../styles/css/global.css";
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./nprocess";
|
||||
@@ -0,0 +1,7 @@
|
||||
import NProgress from "nprogress";
|
||||
|
||||
export function setupNProgress() {
|
||||
NProgress.configure({ easing: "ease", speed: 500 });
|
||||
|
||||
window.NProgress = NProgress;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { App } from "vue";
|
||||
import { createRouter, createWebHashHistory } from "vue-router";
|
||||
import routes from "./routes";
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
strict: true,
|
||||
routes: routes,
|
||||
scrollBehavior: () => ({ left: 0, top: 0 }),
|
||||
});
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
window.NProgress?.start?.();
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
router.afterEach(() => {
|
||||
window.NProgress?.done?.();
|
||||
});
|
||||
|
||||
export function setupRouter(app: App) {
|
||||
app.use(router);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { RouteRecordRaw } from "vue-router";
|
||||
|
||||
import BaseLayout from "@/layouts/base-layout/index.vue";
|
||||
import Home from "@/pages/home/index.vue";
|
||||
import AboutUs from "@/pages/aboutUs/index.vue";
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: "/",
|
||||
component: BaseLayout,
|
||||
redirect: "/home",
|
||||
children: [
|
||||
{
|
||||
path: "/home",
|
||||
component: Home
|
||||
},
|
||||
{
|
||||
path: "/aboutUs",
|
||||
component: AboutUs
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
export default routes;
|
||||
@@ -0,0 +1,11 @@
|
||||
import { httpGet } from "@/utils/http";
|
||||
|
||||
export interface AreaType {
|
||||
label: string;
|
||||
value: number;
|
||||
children?: AreaType[];
|
||||
}
|
||||
|
||||
export const getAreaTreeDataApi = () => {
|
||||
return httpGet<AreaType[]>(`/area/getTreeData`);
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { App } from "vue";
|
||||
import { createPinia } from "pinia";
|
||||
import { createPersistedState } from "pinia-plugin-persistedstate"; // 数据持久化
|
||||
|
||||
export function setupPinia(app: App) {
|
||||
const store = createPinia();
|
||||
store.use(createPersistedState());
|
||||
app.use(store);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useRouter } from "vue-router";
|
||||
export const useRouterStore = defineStore("router", () => {
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const getCurrentPath = () => {
|
||||
return route.path;
|
||||
};
|
||||
const toPath = (path: string) => {
|
||||
router.push(path);
|
||||
};
|
||||
return {
|
||||
getCurrentPath,
|
||||
toPath,
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
import { ref, computed } from "vue";
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
|
||||
const initState = {
|
||||
id: "",
|
||||
account: "",
|
||||
email: "",
|
||||
name: "",
|
||||
token: "",
|
||||
avatar: "",
|
||||
};
|
||||
|
||||
export const useUserStore = defineStore(
|
||||
"user",
|
||||
() => {
|
||||
const userInfo = ref<IUserInfo>({ ...initState });
|
||||
|
||||
const setUserInfo = (val: IUserInfo) => {
|
||||
userInfo.value = { ...userInfo.value, ...val };
|
||||
};
|
||||
|
||||
const clearUserInfo = () => {
|
||||
reset();
|
||||
};
|
||||
// 一般没有reset需求,不需要的可以删除
|
||||
const reset = () => {
|
||||
userInfo.value = {
|
||||
id: "",
|
||||
account: "",
|
||||
email: "",
|
||||
name: "",
|
||||
token: "",
|
||||
avatar: "",
|
||||
};
|
||||
};
|
||||
// ✅ 如果需要同时验证多个字段
|
||||
const isLogined = computed(() => {
|
||||
return !!(
|
||||
(
|
||||
userInfo.value.token && // 用户令牌
|
||||
userInfo.value.id && // 用户ID
|
||||
userInfo.value.account // 账户名
|
||||
)
|
||||
// userInfo.value.name // 名称
|
||||
);
|
||||
});
|
||||
|
||||
return {
|
||||
userInfo,
|
||||
setUserInfo,
|
||||
clearUserInfo,
|
||||
isLogined,
|
||||
reset,
|
||||
};
|
||||
},
|
||||
{
|
||||
persist: true,
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,328 @@
|
||||
@charset "utf-8";
|
||||
/* style */
|
||||
.ys-panel,
|
||||
.ys-panel-box {
|
||||
padding: 0;
|
||||
}
|
||||
.ys-panel.active,
|
||||
.ys-panel_hd {
|
||||
padding: 10px;
|
||||
}
|
||||
.ys-panel-box.active {
|
||||
margin: 0;
|
||||
}
|
||||
/* all */
|
||||
body {
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
/* text */
|
||||
a,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
h1 a,
|
||||
h2 a,
|
||||
h3 a,
|
||||
h4 a,
|
||||
h5 a,
|
||||
h6 a {
|
||||
color: #333;
|
||||
}
|
||||
a:hover {
|
||||
color: cornflowerblue;
|
||||
}
|
||||
a.disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.text-333 {
|
||||
color: #333;
|
||||
}
|
||||
.text-666 {
|
||||
color: #666;
|
||||
}
|
||||
.text-muted {
|
||||
color: #999;
|
||||
}
|
||||
.text-red {
|
||||
color: red;
|
||||
}
|
||||
.text-link {
|
||||
color: blue;
|
||||
}
|
||||
.text-fff {
|
||||
color: #fff;
|
||||
}
|
||||
/* form */
|
||||
.form-control {
|
||||
color: #999999;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
.form-control:focus {
|
||||
border-color: #ff9900;
|
||||
-webkit-box-shadow:
|
||||
inset 0 1px 1px rgba(255, 136, 0, 0.075),
|
||||
0 0 8px rgba(255, 136, 0, 0.6);
|
||||
}
|
||||
/* btn */
|
||||
.btn-default {
|
||||
color: #333;
|
||||
background: linear-gradient(to right, #eeeeee 0, #f6f6f6 100%);
|
||||
background-color: #eee;
|
||||
}
|
||||
.btn-warm {
|
||||
background: linear-gradient(to right, #ff9900 0, #ff9f16 100%);
|
||||
background-color: #ff9900;
|
||||
}
|
||||
.btn-primary {
|
||||
background: linear-gradient(to right, #4fb1f7 0, #6bb8ee 100%);
|
||||
background-color: #4fb1f7;
|
||||
}
|
||||
.btn-danger {
|
||||
background: linear-gradient(to right, #fc000c 0, #f9444d 100%);
|
||||
background-color: #fc000c;
|
||||
}
|
||||
.btn-info {
|
||||
background: linear-gradient(to right, #5bc0de 0, #7cc1d6 100%);
|
||||
background-color: #5bc0de;
|
||||
}
|
||||
.btn-gray {
|
||||
color: #ddd;
|
||||
background: linear-gradient(to right, #282828 0, #3b3b3b 100%);
|
||||
background-color: #282828;
|
||||
}
|
||||
.btn-warm,
|
||||
.btn-primary,
|
||||
.btn-danger,
|
||||
.btn-info {
|
||||
color: #fff;
|
||||
}
|
||||
.btn-warm:hover,
|
||||
.btn-primary:hover,
|
||||
.btn-danger:hover,
|
||||
.btn-info:hover,
|
||||
.btn-gray:hover {
|
||||
color: #fff;
|
||||
box-shadow: 0 5px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.btn.disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
}
|
||||
/* border */
|
||||
.border {
|
||||
border-color: #eee;
|
||||
}
|
||||
.border-primary {
|
||||
border-color: #4fb1f7;
|
||||
}
|
||||
.border-danger {
|
||||
border-color: red;
|
||||
}
|
||||
.border-info {
|
||||
border-color: #5bc0de;
|
||||
}
|
||||
/* line */
|
||||
.spot {
|
||||
border-color: #ff9900;
|
||||
}
|
||||
.split-line {
|
||||
background-color: #eee;
|
||||
}
|
||||
.top-line:before,
|
||||
.bottom-line:after,
|
||||
.top-line-dot:before,
|
||||
.bottom-line-dot:before {
|
||||
border-color: #eee;
|
||||
}
|
||||
/* badge */
|
||||
.badge {
|
||||
color: #333;
|
||||
background-color: #eee;
|
||||
}
|
||||
.badge-first {
|
||||
color: #fff;
|
||||
background-color: #ff4a4a;
|
||||
}
|
||||
.badge-second {
|
||||
color: #fff;
|
||||
background-color: #ff7701;
|
||||
}
|
||||
.badge-third {
|
||||
color: #fff;
|
||||
background-color: #ffb400;
|
||||
}
|
||||
/* dropdown */
|
||||
.dropdown-box .item {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
/* pic-tag */
|
||||
.pic-tag .tag {
|
||||
color: #fff;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
.pic-tag .tag.active,
|
||||
.pic-tag-h {
|
||||
color: #fff;
|
||||
background-color: #ff9900;
|
||||
}
|
||||
.pic-text,
|
||||
.pic-title-bottom {
|
||||
color: #fff;
|
||||
background-image: linear-gradient(transparent, rgba(0, 0, 0, 0.5));
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.pic-text.active {
|
||||
color: #fff;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
.pic-title-top {
|
||||
color: #fff;
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0) 100%);
|
||||
}
|
||||
/* link */
|
||||
.ys-link__pic li img {
|
||||
display: block;
|
||||
padding: 2px 6px;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
/* nav */
|
||||
.nav-tabs > li.active a {
|
||||
color: #ff9900;
|
||||
border-color: #ff9900;
|
||||
}
|
||||
.nav-tabs > li .dropdown-box .item li a {
|
||||
color: #333;
|
||||
}
|
||||
.nav-tabs > li .dropdown-box .item li.active a {
|
||||
color: #ff9900;
|
||||
}
|
||||
.nav-btn > li a {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.nav-btn > li.active a {
|
||||
color: #fff;
|
||||
background-color: #ff9900;
|
||||
}
|
||||
/* header */
|
||||
.ys-header__top {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.ys-header__menu > li > a {
|
||||
color: #333;
|
||||
}
|
||||
.ys-header__menu > li.active > a {
|
||||
color: #ff9900;
|
||||
}
|
||||
.ys-header__search .form-control {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.ys-header__user > li > a,
|
||||
.ys-header__user > li > a .fa {
|
||||
color: #333;
|
||||
}
|
||||
/* panel */
|
||||
.ys-panel-bg {
|
||||
background-color: #fff;
|
||||
}
|
||||
.ys-panel-bg2 {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
/* vodlist */
|
||||
.ys-vodlist__bg {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.ys-vodlist__bg:hover {
|
||||
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
/* text-list */
|
||||
.ys-vodlist__text.striped .striped-head,
|
||||
.ys-vodlist__text.to-color li:nth-of-type(odd) {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
/* table */
|
||||
.ys-table > thead > tr > th,
|
||||
.ys-table > tbody > tr > td,
|
||||
.ys-table > tbody > tr > th,
|
||||
.ys-table > tfoot > tr > td,
|
||||
.ys-table > tfoot > tr > th,
|
||||
.ys-table > thead > tr > td,
|
||||
.ys-table > thead > tr > th {
|
||||
border-color: #ddd;
|
||||
}
|
||||
/* player */
|
||||
.ys-player__video {
|
||||
background-color: #000;
|
||||
}
|
||||
.ys-player__operate > li > a {
|
||||
color: #999;
|
||||
}
|
||||
/* popup */
|
||||
.popup {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
.popup-head {
|
||||
background-color: #fff;
|
||||
}
|
||||
/* content */
|
||||
.ys-content__detail .score .rating li .fa,
|
||||
.ys-content__detail .score .branch {
|
||||
color: #ff9900;
|
||||
}
|
||||
/* flickity */
|
||||
.flickity-page-dots .dot {
|
||||
background-color: #ff9900;
|
||||
}
|
||||
/* carousel */
|
||||
.carousel-indicators-dots li {
|
||||
background-color: #ff9900;
|
||||
}
|
||||
.carousel-indicators-text li.active .title {
|
||||
color: #ff9900;
|
||||
}
|
||||
.carousel-indicators-thumb li.active {
|
||||
border: 3px solid #ff9900;
|
||||
}
|
||||
/* extra */
|
||||
.ys-extra li a {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.ys-extra li a.backtop {
|
||||
color: #fff;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
/* autocomplete */
|
||||
.autocomplete-suggestions {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.autocomplete-suggestion,
|
||||
.autocomplete-suggestions li,
|
||||
.autocomplete-suggestion,
|
||||
.autocomplete-suggestions li a {
|
||||
color: #333;
|
||||
}
|
||||
.autocomplete-suggestions li strong {
|
||||
color: red;
|
||||
}
|
||||
/* tabbar */
|
||||
.ys-nav__tabbar {
|
||||
background-color: #f8f8f8;
|
||||
border-color: #eee;
|
||||
}
|
||||
.ys-nav__tabbar .item .title {
|
||||
color: #999;
|
||||
}
|
||||
/* footer */
|
||||
.ys-foot {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,6 @@
|
||||
@import "./nprogress.css";
|
||||
@import "./font.css";
|
||||
@import "./color.css";
|
||||
@import "./layer.css";
|
||||
@import "./site.css";
|
||||
@import "./ui.css";
|
||||
@@ -0,0 +1,945 @@
|
||||
.layui-layer-imgbar,
|
||||
.layui-layer-imgtit a,
|
||||
.layui-layer-tab .layui-layer-title span,
|
||||
.layui-layer-title {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
html #layuicss-layer {
|
||||
position: absolute;
|
||||
display: none;
|
||||
width: 1989px;
|
||||
}
|
||||
|
||||
.layui-layer,
|
||||
.layui-layer-shade {
|
||||
position: fixed;
|
||||
_position: absolute;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.layui-layer-shade {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.layui-layer {
|
||||
top: 150px;
|
||||
left: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background-color: #fff;
|
||||
-webkit-background-clip: content;
|
||||
border-radius: 2px;
|
||||
box-shadow: 1px 1px 50px rgba(0, 0, 0, 0.3);
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.layui-layer-close {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.layui-layer-content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.layui-layer-border {
|
||||
border: 1px solid #b2b2b2;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.layui-layer-load {
|
||||
background: url(loading-1.gif) center center no-repeat #eee;
|
||||
}
|
||||
|
||||
.layui-layer-ico {
|
||||
background: url(icon.png) no-repeat;
|
||||
}
|
||||
|
||||
.layui-layer-btn a,
|
||||
.layui-layer-dialog .layui-layer-ico,
|
||||
.layui-layer-setwin a {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.layui-layer-move {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 2147483647;
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: move;
|
||||
background-color: #fff;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.layui-layer-resize {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
cursor: se-resize;
|
||||
}
|
||||
|
||||
.layer-anim {
|
||||
-webkit-animation-fill-mode: both;
|
||||
animation-fill-mode: both;
|
||||
-webkit-animation-duration: 0.3s;
|
||||
animation-duration: 0.3s;
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-bounceIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(0.5);
|
||||
transform: scale(0.5);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-bounceIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(0.5);
|
||||
-ms-transform: scale(0.5);
|
||||
transform: scale(0.5);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
-ms-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-00 {
|
||||
-webkit-animation-name: layer-bounceIn;
|
||||
animation-name: layer-bounceIn;
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-zoomInDown {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(0.1) translateY(-2000px);
|
||||
transform: scale(0.1) translateY(-2000px);
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
animation-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
60% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(0.475) translateY(60px);
|
||||
transform: scale(0.475) translateY(60px);
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-zoomInDown {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(0.1) translateY(-2000px);
|
||||
-ms-transform: scale(0.1) translateY(-2000px);
|
||||
transform: scale(0.1) translateY(-2000px);
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
animation-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
60% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(0.475) translateY(60px);
|
||||
-ms-transform: scale(0.475) translateY(60px);
|
||||
transform: scale(0.475) translateY(60px);
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-01 {
|
||||
-webkit-animation-name: layer-zoomInDown;
|
||||
animation-name: layer-zoomInDown;
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-fadeInUpBig {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(2000px);
|
||||
transform: translateY(2000px);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-fadeInUpBig {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(2000px);
|
||||
-ms-transform: translateY(2000px);
|
||||
transform: translateY(2000px);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
-ms-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-02 {
|
||||
-webkit-animation-name: layer-fadeInUpBig;
|
||||
animation-name: layer-fadeInUpBig;
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-zoomInLeft {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(0.1) translateX(-2000px);
|
||||
transform: scale(0.1) translateX(-2000px);
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
animation-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
60% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(0.475) translateX(48px);
|
||||
transform: scale(0.475) translateX(48px);
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-zoomInLeft {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(0.1) translateX(-2000px);
|
||||
-ms-transform: scale(0.1) translateX(-2000px);
|
||||
transform: scale(0.1) translateX(-2000px);
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
animation-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
60% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(0.475) translateX(48px);
|
||||
-ms-transform: scale(0.475) translateX(48px);
|
||||
transform: scale(0.475) translateX(48px);
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-03 {
|
||||
-webkit-animation-name: layer-zoomInLeft;
|
||||
animation-name: layer-zoomInLeft;
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-rollIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateX(-100%) rotate(-120deg);
|
||||
transform: translateX(-100%) rotate(-120deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateX(0) rotate(0);
|
||||
transform: translateX(0) rotate(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-rollIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateX(-100%) rotate(-120deg);
|
||||
-ms-transform: translateX(-100%) rotate(-120deg);
|
||||
transform: translateX(-100%) rotate(-120deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateX(0) rotate(0);
|
||||
-ms-transform: translateX(0) rotate(0);
|
||||
transform: translateX(0) rotate(0);
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-04 {
|
||||
-webkit-animation-name: layer-rollIn;
|
||||
animation-name: layer-rollIn;
|
||||
}
|
||||
|
||||
@keyframes layer-fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-05 {
|
||||
-webkit-animation-name: layer-fadeIn;
|
||||
animation-name: layer-fadeIn;
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-shake {
|
||||
0%,
|
||||
100% {
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
10%,
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90% {
|
||||
-webkit-transform: translateX(-10px);
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
|
||||
20%,
|
||||
40%,
|
||||
60%,
|
||||
80% {
|
||||
-webkit-transform: translateX(10px);
|
||||
transform: translateX(10px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-shake {
|
||||
0%,
|
||||
100% {
|
||||
-webkit-transform: translateX(0);
|
||||
-ms-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
10%,
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90% {
|
||||
-webkit-transform: translateX(-10px);
|
||||
-ms-transform: translateX(-10px);
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
|
||||
20%,
|
||||
40%,
|
||||
60%,
|
||||
80% {
|
||||
-webkit-transform: translateX(10px);
|
||||
-ms-transform: translateX(10px);
|
||||
transform: translateX(10px);
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-06 {
|
||||
-webkit-animation-name: layer-shake;
|
||||
animation-name: layer-shake;
|
||||
}
|
||||
|
||||
@-webkit-keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-layer-title {
|
||||
height: 42px;
|
||||
padding: 0 80px 0 20px;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
line-height: 42px;
|
||||
color: #333;
|
||||
background-color: #f8f8f8;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-radius: 2px 2px 0 0;
|
||||
}
|
||||
|
||||
.layui-layer-setwin {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
font-size: 0;
|
||||
line-height: initial;
|
||||
}
|
||||
|
||||
.layui-layer-setwin a {
|
||||
position: relative;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 10px;
|
||||
_overflow: hidden;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-min cite {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
width: 14px;
|
||||
height: 2px;
|
||||
margin-top: -1px;
|
||||
_overflow: hidden;
|
||||
cursor: pointer;
|
||||
background-color: #2e2d3c;
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-min:hover cite {
|
||||
background-color: #2d93ca;
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-max {
|
||||
background-position: -32px -40px;
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-max:hover {
|
||||
background-position: -16px -40px;
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-maxmin {
|
||||
background-position: -65px -40px;
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-maxmin:hover {
|
||||
background-position: -49px -40px;
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-close1 {
|
||||
cursor: pointer;
|
||||
background-position: 1px -40px;
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-close1:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-close2 {
|
||||
position: absolute;
|
||||
top: -28px;
|
||||
_display: none;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-left: 0;
|
||||
background-position: -149px -31px;
|
||||
}
|
||||
|
||||
.layui-layer-setwin .layui-layer-close2:hover {
|
||||
background-position: -180px -31px;
|
||||
}
|
||||
|
||||
.layui-layer-btn {
|
||||
padding: 0 15px 12px;
|
||||
text-align: right;
|
||||
pointer-events: auto;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.layui-layer-btn a {
|
||||
height: 28px;
|
||||
padding: 0 15px;
|
||||
margin: 5px 5px 0;
|
||||
font-weight: 400;
|
||||
line-height: 28px;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
background-color: #fff;
|
||||
border: 1px solid #dedede;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.layui-layer-btn a:hover {
|
||||
text-decoration: none;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.layui-layer-btn a:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.layui-layer-btn .layui-layer-btn0 {
|
||||
color: #fff;
|
||||
background-color: #1e9fff;
|
||||
border-color: #1e9fff;
|
||||
}
|
||||
|
||||
.layui-layer-btn-l {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.layui-layer-btn-c {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.layui-layer-dialog {
|
||||
min-width: 260px;
|
||||
}
|
||||
|
||||
.layui-layer-dialog .layui-layer-content {
|
||||
position: relative;
|
||||
padding: 20px;
|
||||
overflow: hidden;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.layui-layer-dialog .layui-layer-content .layui-layer-ico {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
_left: -40px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.layui-layer-ico1 {
|
||||
background-position: -30px 0;
|
||||
}
|
||||
|
||||
.layui-layer-ico2 {
|
||||
background-position: -60px 0;
|
||||
}
|
||||
|
||||
.layui-layer-ico3 {
|
||||
background-position: -90px 0;
|
||||
}
|
||||
|
||||
.layui-layer-ico4 {
|
||||
background-position: -120px 0;
|
||||
}
|
||||
|
||||
.layui-layer-ico5 {
|
||||
background-position: -150px 0;
|
||||
}
|
||||
|
||||
.layui-layer-ico6 {
|
||||
background-position: -180px 0;
|
||||
}
|
||||
|
||||
.layui-layer-rim {
|
||||
border: 6px solid #8d8d8d;
|
||||
border: 6px solid rgba(0, 0, 0, 0.3);
|
||||
border-radius: 5px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.layui-layer-msg {
|
||||
min-width: 180px;
|
||||
border: 1px solid #d3d4d3;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.layui-layer-hui {
|
||||
min-width: 100px;
|
||||
color: #fff;
|
||||
background-color: #000;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
filter: alpha(opacity=60);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.layui-layer-hui .layui-layer-content {
|
||||
padding: 12px 25px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.layui-layer-dialog .layui-layer-padding {
|
||||
padding: 20px 20px 20px 55px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.layui-layer-page .layui-layer-content {
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.layui-layer-iframe .layui-layer-btn,
|
||||
.layui-layer-page .layui-layer-btn {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.layui-layer-nobg {
|
||||
background: 0 0;
|
||||
}
|
||||
|
||||
.layui-layer-iframe iframe {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.layui-layer-loading {
|
||||
background: 0 0;
|
||||
border: none;
|
||||
border-radius: 100%;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.layui-layer-loading .layui-layer-content {
|
||||
width: 60px;
|
||||
height: 24px;
|
||||
background: url(loading-0.gif) no-repeat;
|
||||
}
|
||||
|
||||
.layui-layer-loading .layui-layer-loading1 {
|
||||
width: 37px;
|
||||
height: 37px;
|
||||
background: url(loading-1.gif) no-repeat;
|
||||
}
|
||||
|
||||
.layui-layer-ico16,
|
||||
.layui-layer-loading .layui-layer-loading2 {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: url(loading-2.gif) no-repeat;
|
||||
}
|
||||
|
||||
.layui-layer-tips {
|
||||
background: 0 0;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.layui-layer-tips .layui-layer-content {
|
||||
position: relative;
|
||||
_float: left;
|
||||
min-width: 12px;
|
||||
padding: 8px 15px;
|
||||
font-size: 12px;
|
||||
line-height: 22px;
|
||||
color: #fff;
|
||||
background-color: #000;
|
||||
border-radius: 2px;
|
||||
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.layui-layer-tips .layui-layer-close {
|
||||
top: -1px;
|
||||
right: -2px;
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsG {
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-color: transparent;
|
||||
border-style: dashed;
|
||||
border-width: 8px;
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsB,
|
||||
.layui-layer-tips i.layui-layer-TipsT {
|
||||
left: 5px;
|
||||
border-right-color: #000;
|
||||
border-right-style: solid;
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsT {
|
||||
bottom: -8px;
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsB {
|
||||
top: -8px;
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsL,
|
||||
.layui-layer-tips i.layui-layer-TipsR {
|
||||
top: 5px;
|
||||
border-bottom-color: #000;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsR {
|
||||
left: -8px;
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsL {
|
||||
right: -8px;
|
||||
}
|
||||
|
||||
.layui-layer-lan[type="dialog"] {
|
||||
min-width: 280px;
|
||||
}
|
||||
|
||||
.layui-layer-lan .layui-layer-title {
|
||||
color: #fff;
|
||||
background: #4476a7;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.layui-layer-lan .layui-layer-btn {
|
||||
padding: 5px 10px 10px;
|
||||
text-align: right;
|
||||
border-top: 1px solid #e9e7e7;
|
||||
}
|
||||
|
||||
.layui-layer-lan .layui-layer-btn a {
|
||||
color: #333;
|
||||
background: #fff;
|
||||
border-color: #e9e7e7;
|
||||
}
|
||||
|
||||
.layui-layer-lan .layui-layer-btn .layui-layer-btn1 {
|
||||
background: #c9c5c5;
|
||||
}
|
||||
|
||||
.layui-layer-molv .layui-layer-title {
|
||||
color: #fff;
|
||||
background: #009f95;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.layui-layer-molv .layui-layer-btn a {
|
||||
background: #009f95;
|
||||
border-color: #009f95;
|
||||
}
|
||||
|
||||
.layui-layer-molv .layui-layer-btn .layui-layer-btn1 {
|
||||
background: #92b8b1;
|
||||
}
|
||||
|
||||
.layui-layer-iconext {
|
||||
background: url(icon-ext.png) no-repeat;
|
||||
}
|
||||
|
||||
.layui-layer-prompt .layui-layer-input {
|
||||
display: block;
|
||||
width: 230px;
|
||||
height: 36px;
|
||||
padding-left: 10px;
|
||||
margin: 0 auto;
|
||||
line-height: 30px;
|
||||
color: #333;
|
||||
border: 1px solid #e6e6e6;
|
||||
}
|
||||
|
||||
.layui-layer-prompt textarea.layui-layer-input {
|
||||
width: 300px;
|
||||
height: 100px;
|
||||
padding: 6px 10px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.layui-layer-prompt .layui-layer-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.layui-layer-prompt .layui-layer-btn {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.layui-layer-tab {
|
||||
box-shadow: 1px 1px 50px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.layui-layer-tab .layui-layer-title {
|
||||
padding-left: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.layui-layer-tab .layui-layer-title span {
|
||||
position: relative;
|
||||
float: left;
|
||||
min-width: 80px;
|
||||
max-width: 260px;
|
||||
padding: 0 20px;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.layui-layer-tab .layui-layer-title span.layui-this {
|
||||
z-index: 10;
|
||||
height: 43px;
|
||||
background-color: #fff;
|
||||
border-right: 1px solid #eee;
|
||||
border-left: 1px solid #eee;
|
||||
}
|
||||
|
||||
.layui-layer-tab .layui-layer-title span:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.layui-layer-tabmain {
|
||||
clear: both;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.layui-layer-tabmain .layui-layer-tabli {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layui-layer-tabmain .layui-layer-tabli.layui-this {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.layui-layer-photos {
|
||||
-webkit-animation-duration: 0.8s;
|
||||
animation-duration: 0.8s;
|
||||
}
|
||||
|
||||
.layui-layer-photos .layui-layer-content {
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.layui-layer-photos .layui-layer-phimg img {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.layui-layer-imgbar,
|
||||
.layui-layer-imguide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layui-layer-imgnext,
|
||||
.layui-layer-imgprev {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
_width: 44px;
|
||||
height: 44px;
|
||||
margin-top: -22px;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.layui-layer-imgprev {
|
||||
left: 10px;
|
||||
_background-position: -70px -5px;
|
||||
}
|
||||
|
||||
.layui-layer-imgprev:hover {
|
||||
_background-position: -120px -5px;
|
||||
}
|
||||
|
||||
.layui-layer-imgnext {
|
||||
_right: 8px;
|
||||
_background-position: -70px -50px;
|
||||
}
|
||||
|
||||
.layui-layer-imgnext:hover {
|
||||
_background-position: -120px -50px;
|
||||
}
|
||||
|
||||
.layui-layer-imgbar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
overflow: hidden;
|
||||
font-size: 0;
|
||||
line-height: 32px;
|
||||
color: #fff;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
filter: Alpha(opacity=80);
|
||||
}
|
||||
|
||||
.layui-layer-imgtit * {
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.layui-layer-imgtit a {
|
||||
max-width: 65%;
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.layui-layer-imgtit a:hover {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.layui-layer-imgtit em {
|
||||
padding-left: 10px;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@-webkit-keyframes layer-bounceOut {
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(0.7);
|
||||
transform: scale(0.7);
|
||||
}
|
||||
|
||||
30% {
|
||||
-webkit-transform: scale(1.05);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
0% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes layer-bounceOut {
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(0.7);
|
||||
-ms-transform: scale(0.7);
|
||||
transform: scale(0.7);
|
||||
}
|
||||
|
||||
30% {
|
||||
-webkit-transform: scale(1.05);
|
||||
-ms-transform: scale(1.05);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
0% {
|
||||
-webkit-transform: scale(1);
|
||||
-ms-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.layer-anim-close {
|
||||
-webkit-animation-name: layer-bounceOut;
|
||||
animation-name: layer-bounceOut;
|
||||
-webkit-animation-fill-mode: both;
|
||||
animation-fill-mode: both;
|
||||
-webkit-animation-duration: 0.2s;
|
||||
animation-duration: 0.2s;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1100px) {
|
||||
.layui-layer-iframe {
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/* Make clicks pass-through */
|
||||
#nprogress {
|
||||
pointer-events: none;
|
||||
}
|
||||
/* Remove the shadow effect */
|
||||
#nprogress .peg {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
opacity: 1;
|
||||
-webkit-transform: rotate(3deg) translate(0px, -4px);
|
||||
-ms-transform: rotate(3deg) translate(0px, -4px);
|
||||
transform: rotate(3deg) translate(0px, -4px);
|
||||
}
|
||||
/* Remove spinner and its shadow */
|
||||
#nprogress .spinner {
|
||||
position: fixed;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
z-index: 1031;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#nprogress .spinner-icon {
|
||||
box-sizing: border-box;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
|
||||
border: solid 2px transparent;
|
||||
border-top-color: #646cff;
|
||||
border-left-color: #646cff;
|
||||
border-radius: 50%;
|
||||
box-shadow: none; /* Remove spinner shadow */
|
||||
-webkit-animation: nprogress-spinner 300ms linear infinite;
|
||||
animation: nprogress-spinner 300ms linear infinite;
|
||||
}
|
||||
|
||||
.nprogress-custom-parent {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.nprogress-custom-parent #nprogress .spinner,
|
||||
.nprogress-custom-parent #nprogress .bar {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@-webkit-keyframes nprogress-spinner {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes nprogress-spinner {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,4 @@
|
||||
// 通过完整层级穿透确保命中
|
||||
:deep(.arco-badge-dot) {
|
||||
box-shadow: 0 0 0 0;
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
export {}
|
||||
|
||||
/* prettier-ignore */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
AButton: typeof import('@arco-design/web-vue')['Button']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
SvgIcon: typeof import('./../components/svg-icon.vue')['default']
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
export enum ResponseStatusEnum {
|
||||
SUCCESS = 200,
|
||||
ERROR = 500,
|
||||
UNAUTHORIZED = 401,
|
||||
RESOURCE_CREATED_SUCCESS = 201,
|
||||
RESOURCE_CREATED_ERROR = 409,
|
||||
}
|
||||
|
||||
export enum ResponseStatusErrorMessageEnum {
|
||||
NO_LOGIN = "尚未登录,请先登录!",
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// src/env.d.ts
|
||||
declare namespace Env {
|
||||
interface ImportMeta extends ImportMetaEnv {
|
||||
readonly VITE_BASE_URL: string;
|
||||
readonly VITE_APP_TITLE: string;
|
||||
readonly VITE_ICON_PREFIX: string;
|
||||
readonly VITE_ICON_LOCAL_PREFIX: string;
|
||||
readonly VITE_SERVER_BASEURL: string;
|
||||
readonly VITE_UPLOAD_BASEURL: string;
|
||||
readonly VITE_APP_PROXY: string;
|
||||
readonly VITE_APP_PROXY_PREFIX: string;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import { AdminStatusEnum } from "@/types/enums"
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
/** NProgress instance */
|
||||
NProgress?: import("nprogress").NProgress
|
||||
// $message?: import("@arco-design/web-vue/es/Message/interface").MessageMethod;
|
||||
}
|
||||
|
||||
/** Build time of the project */
|
||||
const BUILD_TIME: string
|
||||
|
||||
type IUserInfo = {
|
||||
id: string
|
||||
account?: string
|
||||
email?: string
|
||||
name?: string
|
||||
token?: string
|
||||
avatar?: string
|
||||
}
|
||||
|
||||
type IResData<T = unknown> = {
|
||||
code: number
|
||||
message: string
|
||||
data: T
|
||||
}
|
||||
}
|
||||
|
||||
export {} // 确保 TypeScript 将此文件视为模块,防止全局污染
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
interface BasePageParams {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}
|
||||
|
||||
interface BasePageResult<T> {
|
||||
total: number; // 总条数
|
||||
record: T[]; // 当前页数据列表
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
export function toJson(obj: any): string {
|
||||
try {
|
||||
return JSON.stringify(obj);
|
||||
} catch (error) {
|
||||
console.error("JSON 转换失败", error);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
export function toObject<T>(json: string): T | null {
|
||||
try {
|
||||
return JSON.parse(json) as T;
|
||||
} catch (error) {
|
||||
console.error("JSON 解析失败", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
import { getAliyunKeyApi, insertFileApi } from "@/service/file";
|
||||
import { Message } from "@arco-design/web-vue";
|
||||
|
||||
export interface UploadImageResponse {
|
||||
name: string;
|
||||
size: string;
|
||||
url: string;
|
||||
blob: Blob;
|
||||
}
|
||||
|
||||
export const uploadImage = (
|
||||
options: {
|
||||
quality?: number;
|
||||
mimeType?: string;
|
||||
} = {}
|
||||
): Promise<UploadImageResponse> => {
|
||||
const { quality = 0.8, mimeType = "image/webp" } = options;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (typeof document === "undefined") {
|
||||
reject(new Error("Require browser environment"));
|
||||
return;
|
||||
}
|
||||
|
||||
const input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.accept = "image/*";
|
||||
input.style.display = "none";
|
||||
|
||||
const processImage = (file: File): Promise<UploadImageResponse> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
const objectURL = URL.createObjectURL(file);
|
||||
|
||||
img.onload = () => {
|
||||
try {
|
||||
const canvas = document.createElement("canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (!ctx) throw new Error("Canvas init failed");
|
||||
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
||||
|
||||
URL.revokeObjectURL(objectURL);
|
||||
|
||||
canvas.toBlob(
|
||||
(blob) => {
|
||||
if (!blob) {
|
||||
reject(new Error("Compression failed"));
|
||||
return;
|
||||
}
|
||||
resolve({ name: file.name, size: blob.size.toString(), url: URL.createObjectURL(blob), blob: blob });
|
||||
},
|
||||
mimeType,
|
||||
quality
|
||||
);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
};
|
||||
|
||||
img.onerror = () => {
|
||||
URL.revokeObjectURL(objectURL);
|
||||
reject(new Error("Image load failed"));
|
||||
};
|
||||
|
||||
img.src = objectURL;
|
||||
});
|
||||
};
|
||||
|
||||
input.onchange = async (event) => {
|
||||
const file = (event.target as HTMLInputElement).files?.[0];
|
||||
if (!file) {
|
||||
reject(new Error("No file selected"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!file.type.startsWith("image/")) {
|
||||
throw new Error("Invalid image file");
|
||||
}
|
||||
|
||||
const result = await processImage(file);
|
||||
resolve(result);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
} finally {
|
||||
document.body.removeChild(input);
|
||||
}
|
||||
};
|
||||
|
||||
document.body.appendChild(input);
|
||||
input.click();
|
||||
});
|
||||
};
|
||||
|
||||
export interface UploadToAliyunResponse {
|
||||
url: string;
|
||||
fileName: string;
|
||||
fileSize: string;
|
||||
}
|
||||
|
||||
export function uploadToAliyun(blob: Blob, fileName: string, fileSize: string): Promise<UploadToAliyunResponse> {
|
||||
return new Promise((resolve, reject) => {
|
||||
getAliyunKeyApi()
|
||||
.then(async (res) => {
|
||||
try {
|
||||
const aliyunKey = res.data;
|
||||
const formData = new FormData();
|
||||
|
||||
// 生成唯一文件名(保留原始后缀)
|
||||
const fileExt = fileName.includes(".") ? fileName.slice(fileName.lastIndexOf(".")) : "";
|
||||
const uniqueName = `sl_${Date.now()}_${Math.random().toString(36).slice(2)}${fileExt}`;
|
||||
|
||||
// 构造表单数据
|
||||
formData.append("key", `${aliyunKey.dir}${uniqueName}`);
|
||||
formData.append("OSSAccessKeyId", aliyunKey.accessid);
|
||||
formData.append("policy", aliyunKey.policy);
|
||||
formData.append("Signature", aliyunKey.signature);
|
||||
formData.append("file", blob, uniqueName);
|
||||
|
||||
// 执行上传
|
||||
const response = await fetch(aliyunKey.host, {
|
||||
method: "POST",
|
||||
body: formData
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
throw new Error(`OSS响应错误: ${errorText}`);
|
||||
}
|
||||
|
||||
// 获取完整文件路径
|
||||
const allFilePath = `${aliyunKey.host}/${aliyunKey.dir}${uniqueName}`;
|
||||
|
||||
// 调用插入记录接口
|
||||
await insertFileApi({
|
||||
fileName,
|
||||
fileSize,
|
||||
fileMapName: allFilePath
|
||||
});
|
||||
|
||||
// 返回标准化结果
|
||||
resolve({
|
||||
url: allFilePath,
|
||||
fileName,
|
||||
fileSize
|
||||
});
|
||||
} catch (error) {
|
||||
Message.error("文件上传流程失败");
|
||||
reject(error);
|
||||
}
|
||||
})
|
||||
.catch(reject); // 捕获获取凭证失败的错误
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import axiosInstance from "@/interceptors/http";
|
||||
|
||||
|
||||
export function httpGet<T>(url: string, params?: Record<string, any>): Promise<IResData<T>> {
|
||||
return axiosInstance.get(url, { params });
|
||||
}
|
||||
export function httpPostJson<T>(url: string, data?: Record<string, any>): Promise<IResData<T>> {
|
||||
return axiosInstance.post(url, data, {
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function httpPostForm<T>(url: string, data?: any): Promise<IResData<T>> {
|
||||
return axiosInstance.post(url, data, {
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "vue",
|
||||
"lib": ["DOM", "ESNext"],
|
||||
"baseUrl": ".",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"~/*": ["./*"]
|
||||
},
|
||||
"resolveJsonModule": true,
|
||||
"types": ["vite/client", "node", "unplugin-icons/types/vue"],
|
||||
"strict": true,
|
||||
"strictNullChecks": true,
|
||||
"noUnusedLocals": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true
|
||||
},
|
||||
"include": ["./**/*.ts", "./**/*.tsx", "./**/*.vue"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { defineConfig } from "@unocss/vite";
|
||||
import transformerDirectives from "@unocss/transformer-directives";
|
||||
import transformerVariantGroup from "@unocss/transformer-variant-group";
|
||||
import presetUno from "@unocss/preset-uno";
|
||||
import type { Theme } from "@unocss/preset-uno";
|
||||
export default defineConfig<Theme>({
|
||||
content: {
|
||||
pipeline: {
|
||||
exclude: ["node_modules", "dist"]
|
||||
}
|
||||
},
|
||||
rules: [],
|
||||
theme: {},
|
||||
shortcuts: {},
|
||||
transformers: [transformerDirectives(), transformerVariantGroup()],
|
||||
presets: [presetUno({ dark: "class" })]
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
import { URL, fileURLToPath } from "node:url";
|
||||
import process from "node:process";
|
||||
import { defineConfig, loadEnv } from "vite";
|
||||
import { setupVitePlugins } from "./build/plugins/index";
|
||||
import { getBuildTime } from "./build/config";
|
||||
|
||||
export default defineConfig((configEnv) => {
|
||||
const viteEnv = loadEnv(configEnv.mode, process.cwd()) as unknown as Env.ImportMeta;
|
||||
const { VITE_SERVER_BASEURL, VITE_APP_PROXY, VITE_APP_PROXY_PREFIX } = viteEnv;
|
||||
const buildTime = getBuildTime();
|
||||
|
||||
return {
|
||||
base: viteEnv.VITE_BASE_URL,
|
||||
resolve: {
|
||||
// 使其通过能 ~ 或 @ 导入
|
||||
alias: {
|
||||
"~": fileURLToPath(new URL("./", import.meta.url)),
|
||||
"@": fileURLToPath(new URL("./src", import.meta.url))
|
||||
}
|
||||
},
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
api: "modern-compiler",
|
||||
additionalData: `@use "@/styles/scss/global.scss" as *;`
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: setupVitePlugins(viteEnv, buildTime),
|
||||
//
|
||||
define: {
|
||||
BUILD_TIME: JSON.stringify(buildTime)
|
||||
},
|
||||
server: {
|
||||
host: "0.0.0.0",
|
||||
port: 8080,
|
||||
open: true,
|
||||
// 用于配置开发服务器启动时预加载的一些客户端文件,以提高初次加载的速度。
|
||||
warmup: {
|
||||
clientFiles: ["./index.html", "./src/{pages,components}/*"]
|
||||
},
|
||||
proxy:
|
||||
VITE_APP_PROXY === "Y"
|
||||
? {
|
||||
[VITE_APP_PROXY_PREFIX]: {
|
||||
target: VITE_SERVER_BASEURL,
|
||||
changeOrigin: true, // 跨域
|
||||
rewrite: (path) => path.replace(/^\/api/, "") //路径重写,把'/api'替换为''
|
||||
// rewrite: (path) => path.replace(new RegExp(`^${VITE_APP_PROXY_PREFIX}`), "")
|
||||
}
|
||||
}
|
||||
: undefined
|
||||
},
|
||||
// 用于生产环境,可以使用vite preview预览构建后的应用 pnpm run preview
|
||||
preview: {
|
||||
port: 9725
|
||||
}
|
||||
};
|
||||
});
|
||||
Reference in new issue
Block a user