@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"next/core-web-vitals",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"plugin:prettier/recommended",
|
||||||
|
"eslint-config-prettier"
|
||||||
|
],
|
||||||
|
"plugins": ["prettier"],
|
||||||
|
"rules": {
|
||||||
|
"@typescript-eslint/no-explicit-any": ["off"], // 允许使用any
|
||||||
|
"@typescript-eslint/ban-ts-comment": "off", // 允许使用@ts-ignore
|
||||||
|
"@typescript-eslint/no-non-null-assertion": "off", // 允许使用非空断言
|
||||||
|
"@typescript-eslint/no-var-requires": "off", // 允许使用CommonJS的写法
|
||||||
|
"no-console": ["warn", { "allow": ["warn", "error"] }], // 提交时不允许有console.log
|
||||||
|
"no-debugger": "warn",
|
||||||
|
"import/order": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"groups": ["builtin", "external", "parent", "sibling", "index", "internal", "object", "type"], // 按照分组顺序进行排序
|
||||||
|
// 通过路径自定义分组
|
||||||
|
"pathGroups": [
|
||||||
|
{
|
||||||
|
"pattern": "react*",
|
||||||
|
"group": "builtin",
|
||||||
|
"position": "before"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pattern": "@/components/**",
|
||||||
|
"group": "parent",
|
||||||
|
"position": "before"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pattern": "@/utils/**",
|
||||||
|
"group": "parent",
|
||||||
|
"position": "after"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pattern": "@/apis/**",
|
||||||
|
"group": "parent",
|
||||||
|
"position": "after"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pathGroupsExcludedImportTypes": ["react"],
|
||||||
|
"newlines-between": "always", // 每个分组之间换行
|
||||||
|
// 根据字母顺序对每个组内的顺序进行排序
|
||||||
|
"alphabetize": {
|
||||||
|
"order": "asc",
|
||||||
|
"caseInsensitive": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
.yarn/install-state.gz
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
@ -0,0 +1,3 @@
|
|||||||
|
/.next/
|
||||||
|
/node_modules
|
||||||
|
.env*.local
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"endOfLine": "auto",
|
||||||
|
"printWidth": 120,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"bracketSpacing": true
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
First, run the development server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm i
|
||||||
|
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Open [http://localhost:3001](http://localhost:3001) with your browser to see the result.
|
||||||
|
|
||||||
|
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||||
|
|
||||||
|
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
||||||
|
|
||||||
|
## Learn More
|
||||||
|
|
||||||
|
To learn more about Next.js, take a look at the following resources:
|
||||||
|
|
||||||
|
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||||
|
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||||
|
|
||||||
|
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||||
|
|
||||||
|
## Deploy on Vercel
|
||||||
|
|
||||||
|
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||||
|
|
||||||
|
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
extends: ['@commitlint/config-conventional'],
|
||||||
|
};
|
@ -0,0 +1,6 @@
|
|||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {
|
||||||
|
output: 'export',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nextConfig;
|
@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"name": "queyue-h5",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev -p 3001",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start -p 3001",
|
||||||
|
"lint": "eslint src --fix --ext .ts,.tsx,.js,.jsx,.mdx,.md,.json,.mjs --max-warnings 0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"next": "14.1.3",
|
||||||
|
"react": "^18",
|
||||||
|
"react-dom": "^18"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@commitlint/cli": "^19.1.0",
|
||||||
|
"@commitlint/config-conventional": "^19.1.0",
|
||||||
|
"@types/node": "^20",
|
||||||
|
"@types/react": "^18",
|
||||||
|
"@types/react-dom": "^18",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||||
|
"@unocss/postcss": "^0.58.6",
|
||||||
|
"autoprefixer": "^10.0.1",
|
||||||
|
"eslint": "^8",
|
||||||
|
"eslint-config-next": "14.1.3",
|
||||||
|
"eslint-config-prettier": "^9.1.0",
|
||||||
|
"eslint-plugin-import": "^2.29.1",
|
||||||
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
|
"husky": "^9.0.11",
|
||||||
|
"lint-staged": "^15.2.2",
|
||||||
|
"postcss": "^8",
|
||||||
|
"postcss-flexbugs-fixes": "^5.0.2",
|
||||||
|
"postcss-preset-env": "^9.5.1",
|
||||||
|
"prettier": "^3.2.5",
|
||||||
|
"typescript": "^5.2.2",
|
||||||
|
"unocss": "^0.58.6"
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"src/**/*.{js,jsx,ts,tsx,json}": [
|
||||||
|
"npm run lint",
|
||||||
|
"prettier --write"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"iOS >= 7",
|
||||||
|
"Android >= 4"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
'@unocss/postcss': {
|
||||||
|
content: ['**/*.{html,js,ts,jsx,tsx}'],
|
||||||
|
},
|
||||||
|
autoprefixer: {},
|
||||||
|
'postcss-flexbugs-fixes': {},
|
||||||
|
'postcss-preset-env': {
|
||||||
|
autoprefixer: {
|
||||||
|
flexbox: 'no-2009',
|
||||||
|
},
|
||||||
|
stage: 3,
|
||||||
|
features: {
|
||||||
|
'custom-properties': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 1.9 MiB |
After Width: | Height: | Size: 678 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1,8 @@
|
|||||||
|
// This File is only needed if you use Attributify
|
||||||
|
// Learn more: https://unocss.dev/presets/attributify
|
||||||
|
import type { AttributifyAttributes } from 'unocss/preset-attributify';
|
||||||
|
|
||||||
|
declare module 'react' {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
interface HTMLAttributes<T> extends AttributifyAttributes {}
|
||||||
|
}
|
After Width: | Height: | Size: 25 KiB |
@ -0,0 +1,24 @@
|
|||||||
|
@import '@unocss/reset/tailwind.css';
|
||||||
|
@unocss all;
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--body-bg-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: var(--body-bg-color);
|
||||||
|
font-family: 'PingFang SC-Regular', Helvetica;
|
||||||
|
/* padding-bottom: constant(safe-area-inset-bottom);
|
||||||
|
padding-bottom: env(safe-area-inset-bottom); */
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer utilities {
|
||||||
|
.text-balance {
|
||||||
|
text-wrap: balance;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
import Footer from '@/components/Footer';
|
||||||
|
import Header from '@/components/Header';
|
||||||
|
|
||||||
|
import type { Metadata, Viewport } from 'next';
|
||||||
|
|
||||||
|
import './globals.css';
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: '雀乐',
|
||||||
|
description: '独立 不独于世',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const viewport: Viewport = {
|
||||||
|
width: 'device-width',
|
||||||
|
initialScale: 1,
|
||||||
|
maximumScale: 1,
|
||||||
|
minimumScale: 1,
|
||||||
|
userScalable: false,
|
||||||
|
viewportFit: 'cover',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
|
||||||
|
return (
|
||||||
|
<html lang="zn-ch" className="relative">
|
||||||
|
<Header />
|
||||||
|
<body>{children}</body>
|
||||||
|
<Footer />
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
export default function Home() {
|
||||||
|
return <main />;
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<footer className="absolute bottom-0 flex flex-col items-center w-full justify-center text-center text-[12px] leading-[12.6px]">
|
||||||
|
<p className="absolute bottom-[69px] text-[rgba(0,0,0,0.4)]">
|
||||||
|
粤ICP备2024190175号-1 深圳雀乐文化科技有限责任公司 Shenzhen QueYue Culture Technology Co., Ltd.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p className="absolute bottom-[40px] text-[rgba(0,0,0,0.7)]">
|
||||||
|
<a href="">服务条款</a>
|
||||||
|
<a href="">版权声明</a>
|
||||||
|
<a href="">许可协议</a>
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
import Logo from '@/components/Logo';
|
||||||
|
|
||||||
|
export default function Header() {
|
||||||
|
const menuList = [
|
||||||
|
{
|
||||||
|
name: '首页',
|
||||||
|
path: '/',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'APP下载',
|
||||||
|
path: '/download',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '关于我们',
|
||||||
|
path: '/about',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<header className="absolute top-0 w-full h-[80px] flex items-center">
|
||||||
|
<Logo />
|
||||||
|
|
||||||
|
<ul className="absolute right-[377px] flex flex-row items-center">
|
||||||
|
{menuList.map(({ name, path }) => (
|
||||||
|
<li
|
||||||
|
key={path}
|
||||||
|
className={`px-[25px] text-[18px] leading-[25.2px] text-[rgba(0,0,0,0.4)] hover:text-[rgba(0,0,0,0.95)]`}
|
||||||
|
>
|
||||||
|
<a href={path}>{name}</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<button className="absolute right-[263px] w-[74px] h-[36px] border-[#000] border-[1.5px] rounded-[60px] text-[17px]">
|
||||||
|
登录
|
||||||
|
</button>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
export default function AppLogo() {
|
||||||
|
return (
|
||||||
|
<h1 className="absolute top-[20px] left-[264px] w-[104px] h-[40px] pl-[52px] bg-[url(/img/logo.svg)] bg-left bg-no-repeat cursor-pointer" />
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
import { Hosting } from '@/utils/ua';
|
||||||
|
|
||||||
|
export default function useUA() {
|
||||||
|
const [inWX, setInWX] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setInWX(Hosting.isWX(window?.navigator?.userAgent?.toLowerCase()));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { inWX };
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
declare module 'lib-flexible';
|
@ -0,0 +1,9 @@
|
|||||||
|
import { Hosting } from '@/utils/ua';
|
||||||
|
|
||||||
|
// 下载
|
||||||
|
export const download = () => {
|
||||||
|
const ua = window?.navigator?.userAgent?.toLowerCase();
|
||||||
|
if (!Hosting.isWX(ua)) {
|
||||||
|
window.open('//cdn.indie.cn/release/queyue.apk', '__blank');
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,31 @@
|
|||||||
|
import localFont from 'next/font/local';
|
||||||
|
|
||||||
|
export const RegularFont = localFont({
|
||||||
|
src: '../../public/fonts/ping-fang-hei-ti-zhun-jian.ttf',
|
||||||
|
display: 'swap',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const MediumFont = localFont({
|
||||||
|
src: '../../public/fonts/pingfang-sc-medium.otf',
|
||||||
|
display: 'swap',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const SemiboldFont = localFont({
|
||||||
|
src: '../../public/fonts/pingfangsc-semibold.otf',
|
||||||
|
display: 'swap',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const AbhayaFont = localFont({
|
||||||
|
src: '../../public/fonts/AlibabaPuHuiTi-3-65-Medium.woff2',
|
||||||
|
display: 'swap',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const AbhayaSemiboldFont = localFont({
|
||||||
|
src: '../../public/fonts/abhayalibre-semibold.ttf',
|
||||||
|
display: 'swap',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const XinYiJiXiangSongFont = localFont({
|
||||||
|
src: '../../public/fonts/Fontquan-XinYiJiXiangSong.ttf',
|
||||||
|
display: 'swap',
|
||||||
|
});
|
@ -0,0 +1,8 @@
|
|||||||
|
// 判断 H5 宿主环境
|
||||||
|
export const Hosting = {
|
||||||
|
isAndroid: (ua: any) => ua.indexOf('android') > -1 || ua.indexOf('linux') > -1,
|
||||||
|
isIPhone: (ua: any) => ua.indexOf('iphone') > -1,
|
||||||
|
isIPad: (ua: any) => ua.indexOf('ipad') > -1,
|
||||||
|
isIPod: (ua: any) => ua.indexOf('ipod') > -1,
|
||||||
|
isWX: (ua: any) => ua.indexOf('micromessenger') > -1,
|
||||||
|
};
|
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
import { defineConfig, presetUno, presetAttributify, presetIcons } from 'unocss';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
presets: [
|
||||||
|
presetUno(),
|
||||||
|
presetAttributify(),
|
||||||
|
presetIcons({
|
||||||
|
extraProperties: {
|
||||||
|
display: 'inline-block',
|
||||||
|
'vertical-align': 'middle',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|