@ -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',
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|