v0.2.7 - 新增龙钞宣传功能:分享海报+百科页面
This commit is contained in:
parent
02711d73c9
commit
98b3917acc
|
|
@ -1,5 +1,28 @@
|
||||||
# 版本更新记录
|
# 版本更新记录
|
||||||
|
|
||||||
|
## v0.2.7 (2026-07-19) - 龙钞宣传功能
|
||||||
|
|
||||||
|
### 前端更新
|
||||||
|
- **Wiki.jsx (新增)**
|
||||||
|
- 龙钞百科页面,包含:什么是龙钞、号码分类、术语解释、评级知识、保养指南、交易指南
|
||||||
|
- 新手入门必备指南
|
||||||
|
|
||||||
|
- **SharePoster.jsx (新增)**
|
||||||
|
- 藏品分享海报组件
|
||||||
|
- 一键生成精美海报,朋友圈分享
|
||||||
|
|
||||||
|
- **List.jsx**
|
||||||
|
- 新增分享按钮,每个藏品卡片右上角显示"📤 分享"按钮
|
||||||
|
- 点击生成精美海报,保存到相册
|
||||||
|
|
||||||
|
- **Home.jsx**
|
||||||
|
- 快捷操作新增"📚 龙钞百科"入口
|
||||||
|
|
||||||
|
### 依赖更新
|
||||||
|
- 新增 html2canvas 库,用于生成海报图片
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## v0.2.5 (2026-05-13)
|
## v0.2.5 (2026-05-13)
|
||||||
|
|
||||||
### 前端更新
|
### 前端更新
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
{
|
{
|
||||||
"version": "0.2.6",
|
"version": "0.2.7",
|
||||||
"updated": "2026-06-13",
|
"updated": "2026-07-19",
|
||||||
"modules": {
|
"modules": {
|
||||||
"frontend": {
|
"frontend": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"pages": {
|
"pages": {
|
||||||
"Login": "0.0.2",
|
"Login": "0.0.2",
|
||||||
"Add": "0.0.2",
|
"Add": "0.0.2",
|
||||||
"News": "0.1.2",
|
"News": "0.1.2",
|
||||||
"YichensBoard": "0.0.5"
|
"YichensBoard": "0.0.5",
|
||||||
|
"Wiki": "1.0.0",
|
||||||
|
"SharePoster": "1.0.0",
|
||||||
|
"List": "0.1.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"backend": {
|
"backend": {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
"version": "1.2.82",
|
"version": "1.2.82",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-router-dom": "^7.1.0"
|
"react-router-dom": "^7.1.0"
|
||||||
|
|
@ -1239,6 +1240,15 @@
|
||||||
"proxy-from-env": "^1.1.0"
|
"proxy-from-env": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/base64-arraybuffer": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/baseline-browser-mapping": {
|
"node_modules/baseline-browser-mapping": {
|
||||||
"version": "2.10.8",
|
"version": "2.10.8",
|
||||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.8.tgz",
|
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.8.tgz",
|
||||||
|
|
@ -1352,6 +1362,15 @@
|
||||||
"url": "https://opencollective.com/express"
|
"url": "https://opencollective.com/express"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/css-line-break": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"utrie": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.4.3",
|
"version": "4.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||||
|
|
@ -1673,6 +1692,19 @@
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/html2canvas": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"css-line-break": "^2.1.0",
|
||||||
|
"text-segmentation": "^1.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
|
@ -1998,6 +2030,15 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/text-segmentation": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"utrie": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tinyglobby": {
|
"node_modules/tinyglobby": {
|
||||||
"version": "0.2.15",
|
"version": "0.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
||||||
|
|
@ -2046,6 +2087,15 @@
|
||||||
"browserslist": ">= 4.21.0"
|
"browserslist": ">= 4.21.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/utrie": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"base64-arraybuffer": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "6.4.2",
|
"version": "6.4.2",
|
||||||
"resolved": "https://registry.npmmirror.com/vite/-/vite-6.4.2.tgz",
|
"resolved": "https://registry.npmmirror.com/vite/-/vite-6.4.2.tgz",
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-router-dom": "^7.1.0"
|
"react-router-dom": "^7.1.0"
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import Login from './pages/Login'
|
||||||
import Detail from './pages/Detail'
|
import Detail from './pages/Detail'
|
||||||
import Edit from './pages/Edit'
|
import Edit from './pages/Edit'
|
||||||
import Admin from './pages/Admin'
|
import Admin from './pages/Admin'
|
||||||
|
import Wiki from './pages/Wiki'
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const [path, setPath] = useState(window.location.hash.slice(1) || '/')
|
const [path, setPath] = useState(window.location.hash.slice(1) || '/')
|
||||||
|
|
@ -38,6 +39,7 @@ export default function App() {
|
||||||
if (basePath === '/login') return <Login />
|
if (basePath === '/login') return <Login />
|
||||||
if (basePath === '/settings') return <Settings />
|
if (basePath === '/settings') return <Settings />
|
||||||
if (basePath === '/admin') return <Admin />
|
if (basePath === '/admin') return <Admin />
|
||||||
|
if (basePath === '/wiki') return <Wiki />
|
||||||
if (basePath.startsWith('/edit')) return <Edit />
|
if (basePath.startsWith('/edit')) return <Edit />
|
||||||
if (basePath.startsWith('/detail')) return <Detail />
|
if (basePath.startsWith('/detail')) return <Detail />
|
||||||
return <Home />
|
return <Home />
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,404 @@
|
||||||
|
/**
|
||||||
|
* SharePoster - 藏品分享海报组件
|
||||||
|
* 生成精美的藏品分享图片,用于朋友圈分享
|
||||||
|
* Version: 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useState, useRef } from 'react'
|
||||||
|
import html2canvas from 'html2canvas'
|
||||||
|
|
||||||
|
export default function SharePoster({ collection, onClose }) {
|
||||||
|
const posterRef = useRef(null)
|
||||||
|
const [generating, setGenerating] = useState(false)
|
||||||
|
const [generated, setGenerated] = useState(false)
|
||||||
|
|
||||||
|
// 获取号码分类颜色
|
||||||
|
const getNumberCategoryColor = (cat) => {
|
||||||
|
const colors = {
|
||||||
|
'圆圆号': '#ef4444',
|
||||||
|
'倒置号': '#f97316',
|
||||||
|
'金马王': '#eab308',
|
||||||
|
'金马号': '#84cc16',
|
||||||
|
'金山王': '#22c55e',
|
||||||
|
'天马王': '#14b8a6',
|
||||||
|
'金山号': '#06b6d4',
|
||||||
|
'天马号': '#0ea5e9',
|
||||||
|
'朦胧王': '#3b82f6',
|
||||||
|
'朦胧号': '#6366f1',
|
||||||
|
'如意号': '#8b5cf6',
|
||||||
|
'钻石号': '#a855f7',
|
||||||
|
'永恒号': '#d946ef',
|
||||||
|
'带7号': '#ec4899',
|
||||||
|
'带4号': '#f43f5e',
|
||||||
|
}
|
||||||
|
return colors[cat] || '#94a3b8'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态颜色
|
||||||
|
const getStatusColor = (status) => {
|
||||||
|
const colors = {
|
||||||
|
'in_collection': '#22c55e',
|
||||||
|
'selling': '#f59e0b',
|
||||||
|
'sold': '#ef4444',
|
||||||
|
'grading': '#06b6d4',
|
||||||
|
'repairing': '#8b5cf6',
|
||||||
|
'transit': '#6366f1',
|
||||||
|
'seeking': '#f97316',
|
||||||
|
'other': '#94a3b8'
|
||||||
|
}
|
||||||
|
return colors[status] || '#94a3b8'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态文字
|
||||||
|
const getStatusText = (status) => {
|
||||||
|
const texts = {
|
||||||
|
'in_collection': '收藏中',
|
||||||
|
'selling': '出售中',
|
||||||
|
'sold': '已售',
|
||||||
|
'grading': '送评中',
|
||||||
|
'repairing': '修复中',
|
||||||
|
'transit': '在途中',
|
||||||
|
'seeking': '寻号中',
|
||||||
|
'other': '其他'
|
||||||
|
}
|
||||||
|
return texts[status] || status
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化冠字号
|
||||||
|
const formatPrefixSerial = (ps) => {
|
||||||
|
if (!ps) return '-'
|
||||||
|
const match = ps.match(/^([A-Z]+)(\d+)$/i)
|
||||||
|
if (match) {
|
||||||
|
return match[1].toUpperCase() + ' ' + match[2].match(/.{1,4}/g).join(' ')
|
||||||
|
}
|
||||||
|
return ps
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成海报图片
|
||||||
|
const generatePoster = async () => {
|
||||||
|
if (!posterRef.current) return
|
||||||
|
|
||||||
|
setGenerating(true)
|
||||||
|
try {
|
||||||
|
const canvas = await html2canvas(posterRef.current, {
|
||||||
|
scale: 2,
|
||||||
|
backgroundColor: '#0f172a',
|
||||||
|
useCORS: true,
|
||||||
|
allowTaint: true
|
||||||
|
})
|
||||||
|
|
||||||
|
// 转换为图片并下载
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.download = `龙钞-${collection.code || collection.prefixSerial || '藏品'}.png`
|
||||||
|
link.href = canvas.toDataURL('image/png')
|
||||||
|
link.click()
|
||||||
|
|
||||||
|
setGenerated(true)
|
||||||
|
} catch (e) {
|
||||||
|
console.error('生成海报失败:', e)
|
||||||
|
alert('生成海报失败,请重试')
|
||||||
|
}
|
||||||
|
setGenerating(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
position: 'fixed',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
background: 'rgba(0,0,0,0.9)',
|
||||||
|
zIndex: 1000,
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
padding: '20px'
|
||||||
|
}}>
|
||||||
|
{/* 标题栏 */}
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
width: '100%',
|
||||||
|
maxWidth: '400px',
|
||||||
|
marginBottom: '20px'
|
||||||
|
}}>
|
||||||
|
<h3 style={{ color: '#fff', margin: 0, fontSize: '18px' }}>📤 生成分享海报</h3>
|
||||||
|
<button
|
||||||
|
onClick={onClose}
|
||||||
|
style={{
|
||||||
|
background: 'rgba(255,255,255,0.1)',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '50%',
|
||||||
|
width: '36px',
|
||||||
|
height: '36px',
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: '18px',
|
||||||
|
cursor: 'pointer'
|
||||||
|
}}
|
||||||
|
>✕</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 海报预览区域 */}
|
||||||
|
<div ref={posterRef} style={{
|
||||||
|
width: '320px',
|
||||||
|
minHeight: '480px',
|
||||||
|
background: 'linear-gradient(135deg, #1e293b 0%, #0f172a 100%)',
|
||||||
|
borderRadius: '16px',
|
||||||
|
padding: '20px',
|
||||||
|
boxSizing: 'border-box',
|
||||||
|
position: 'relative',
|
||||||
|
overflow: 'hidden'
|
||||||
|
}}>
|
||||||
|
{/* 背景装饰 */}
|
||||||
|
<div style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: '-50%',
|
||||||
|
right: '-30%',
|
||||||
|
width: '200px',
|
||||||
|
height: '200px',
|
||||||
|
background: 'radial-gradient(circle, rgba(251,191,36,0.15) 0%, transparent 70%)',
|
||||||
|
borderRadius: '50%'
|
||||||
|
}} />
|
||||||
|
|
||||||
|
{/* 头部 */}
|
||||||
|
<div style={{ textAlign: 'center', marginBottom: '20px', position: 'relative' }}>
|
||||||
|
<div style={{
|
||||||
|
fontSize: '28px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
background: 'linear-gradient(135deg, #fbbf24, #f59e0b)',
|
||||||
|
WebkitBackgroundClip: 'text',
|
||||||
|
WebkitTextFillColor: 'transparent',
|
||||||
|
marginBottom: '4px'
|
||||||
|
}}>
|
||||||
|
🐉 甲辰龙钞
|
||||||
|
</div>
|
||||||
|
<div style={{ color: '#94a3b8', fontSize: '11px' }}>
|
||||||
|
一甲辰藏品管理系统
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 分割线 */}
|
||||||
|
<div style={{
|
||||||
|
height: '1px',
|
||||||
|
background: 'linear-gradient(90deg, transparent, rgba(251,191,36,0.3), transparent)',
|
||||||
|
marginBottom: '20px'
|
||||||
|
}} />
|
||||||
|
|
||||||
|
{/* 藏品信息 */}
|
||||||
|
<div style={{ marginBottom: '16px' }}>
|
||||||
|
{/* 冠字号 - 大字体 */}
|
||||||
|
<div style={{
|
||||||
|
textAlign: 'center',
|
||||||
|
marginBottom: '16px',
|
||||||
|
padding: '12px',
|
||||||
|
background: 'rgba(251,191,36,0.1)',
|
||||||
|
borderRadius: '12px',
|
||||||
|
border: '1px solid rgba(251,191,36,0.2)'
|
||||||
|
}}>
|
||||||
|
<div style={{ color: '#94a3b8', fontSize: '10px', marginBottom: '4px' }}>冠字号</div>
|
||||||
|
<div style={{
|
||||||
|
color: '#fbbf24',
|
||||||
|
fontSize: '24px',
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
letterSpacing: '2px'
|
||||||
|
}}>
|
||||||
|
{formatPrefixSerial(collection.prefixSerial)}
|
||||||
|
</div>
|
||||||
|
{collection.code && (
|
||||||
|
<div style={{ color: '#64748b', fontSize: '12px', marginTop: '4px' }}>
|
||||||
|
编号: {collection.code}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 基本信息网格 */}
|
||||||
|
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px', marginBottom: '16px' }}>
|
||||||
|
<div style={{ background: 'rgba(255,255,255,0.03)', padding: '10px', borderRadius: '8px' }}>
|
||||||
|
<div style={{ color: '#64748b', fontSize: '10px' }}>版别</div>
|
||||||
|
<div style={{ color: '#fff', fontSize: '13px', fontWeight: 'bold' }}>{collection.version || '-'}</div>
|
||||||
|
</div>
|
||||||
|
<div style={{ background: 'rgba(255,255,255,0.03)', padding: '10px', borderRadius: '8px' }}>
|
||||||
|
<div style={{ color: '#64748b', fontSize: '10px' }}>包装</div>
|
||||||
|
<div style={{ color: '#fff', fontSize: '13px', fontWeight: 'bold' }}>{collection.packaging || '-'}</div>
|
||||||
|
</div>
|
||||||
|
<div style={{ background: 'rgba(255,255,255,0.03)', padding: '10px', borderRadius: '8px' }}>
|
||||||
|
<div style={{ color: '#64748b', fontSize: '10px' }}>珍惜度</div>
|
||||||
|
<div style={{ color: '#a78bfa', fontSize: '13px', fontWeight: 'bold' }}>{collection.rarity || '-'}</div>
|
||||||
|
</div>
|
||||||
|
<div style={{ background: 'rgba(255,255,255,0.03)', padding: '10px', borderRadius: '8px' }}>
|
||||||
|
<div style={{ color: '#64748b', fontSize: '10px' }}>状态</div>
|
||||||
|
<div style={{ color: getStatusColor(collection.status), fontSize: '13px', fontWeight: 'bold' }}>
|
||||||
|
{getStatusText(collection.status)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 号码分类标签 */}
|
||||||
|
{collection.numberCategory && (
|
||||||
|
<div style={{
|
||||||
|
textAlign: 'center',
|
||||||
|
marginBottom: '16px',
|
||||||
|
padding: '8px',
|
||||||
|
background: getNumberCategoryColor(collection.numberCategory) + '20',
|
||||||
|
borderRadius: '8px',
|
||||||
|
border: `1px solid ${getNumberCategoryColor(collection.numberCategory)}40`
|
||||||
|
}}>
|
||||||
|
<span style={{
|
||||||
|
color: getNumberCategoryColor(collection.numberCategory),
|
||||||
|
fontSize: '16px',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>
|
||||||
|
⭐ {collection.numberCategory}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 评级信息 */}
|
||||||
|
{collection.isGraded && (
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
gap: '8px',
|
||||||
|
marginBottom: '16px',
|
||||||
|
justifyContent: 'center'
|
||||||
|
}}>
|
||||||
|
{collection.gradingCompany && (
|
||||||
|
<span style={{
|
||||||
|
background: 'rgba(6,182,212,0.15)',
|
||||||
|
color: '#06b6d4',
|
||||||
|
padding: '4px 10px',
|
||||||
|
borderRadius: '6px',
|
||||||
|
fontSize: '11px'
|
||||||
|
}}>
|
||||||
|
{collection.gradingCompany}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{collection.gradingScore && (
|
||||||
|
<span style={{
|
||||||
|
background: 'rgba(249,115,22,0.2)',
|
||||||
|
color: '#f97316',
|
||||||
|
padding: '4px 10px',
|
||||||
|
borderRadius: '6px',
|
||||||
|
fontSize: '14px',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>
|
||||||
|
{collection.gradingScore}分
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{collection.threeStar && (
|
||||||
|
<span style={{
|
||||||
|
background: 'rgba(6,182,212,0.15)',
|
||||||
|
color: '#06b6d4',
|
||||||
|
padding: '4px 10px',
|
||||||
|
borderRadius: '6px',
|
||||||
|
fontSize: '11px'
|
||||||
|
}}>
|
||||||
|
★★★
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 价格信息 */}
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-around',
|
||||||
|
padding: '12px',
|
||||||
|
background: 'rgba(255,255,255,0.03)',
|
||||||
|
borderRadius: '8px'
|
||||||
|
}}>
|
||||||
|
<div style={{ textAlign: 'center' }}>
|
||||||
|
<div style={{ color: '#64748b', fontSize: '10px' }}>成本</div>
|
||||||
|
<div style={{ color: '#e2e8f0', fontSize: '14px' }}>
|
||||||
|
{collection.costPrice ? `¥${collection.costPrice}` : '-'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={{ textAlign: 'center' }}>
|
||||||
|
<div style={{ color: '#64748b', fontSize: '10px' }}>目标价</div>
|
||||||
|
<div style={{ color: '#fbbf24', fontSize: '14px' }}>
|
||||||
|
{collection.targetPrice ? `¥${collection.targetPrice}` : '-'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={{ textAlign: 'center' }}>
|
||||||
|
<div style={{ color: '#64748b', fontSize: '10px' }}>售价</div>
|
||||||
|
<div style={{ color: '#4ade80', fontSize: '14px' }}>
|
||||||
|
{collection.goalPrice ? `¥${collection.goalPrice}` : '-'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 底部 */}
|
||||||
|
<div style={{
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: '15px',
|
||||||
|
left: '20px',
|
||||||
|
right: '20px',
|
||||||
|
textAlign: 'center'
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
color: '#64748b',
|
||||||
|
fontSize: '10px',
|
||||||
|
marginBottom: '4px'
|
||||||
|
}}>
|
||||||
|
长按识别二维码了解更多
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '8px'
|
||||||
|
}}>
|
||||||
|
<span style={{ fontSize: '20px' }}>🐉</span>
|
||||||
|
<span style={{ color: '#94a3b8', fontSize: '11px' }}>jiachenlong.com</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 操作按钮 */}
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
gap: '12px',
|
||||||
|
marginTop: '20px',
|
||||||
|
width: '100%',
|
||||||
|
maxWidth: '400px'
|
||||||
|
}}>
|
||||||
|
<button
|
||||||
|
onClick={onClose}
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
padding: '14px',
|
||||||
|
background: 'rgba(255,255,255,0.1)',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '12px',
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: '15px',
|
||||||
|
cursor: 'pointer'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={generatePoster}
|
||||||
|
disabled={generating}
|
||||||
|
style={{
|
||||||
|
flex: 2,
|
||||||
|
padding: '14px',
|
||||||
|
background: generating ? '#94a3b8' : 'linear-gradient(135deg, #fbbf24, #f59e0b)',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '12px',
|
||||||
|
color: '#1e293b',
|
||||||
|
fontSize: '15px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
cursor: generating ? 'not-allowed' : 'pointer'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{generating ? '生成中...' : generated ? '已保存 ✓' : '保存到相册'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -241,6 +241,21 @@ export default function Home() {
|
||||||
<div style={{ color: '#3b82f6', fontSize: '18px', fontWeight: '600', whiteSpace: 'nowrap' }}>我的认购</div>
|
<div style={{ color: '#3b82f6', fontSize: '18px', fontWeight: '600', whiteSpace: 'nowrap' }}>我的认购</div>
|
||||||
<div style={{ color: 'rgba(255,255,255,0.5)', fontSize: '10px', marginTop: '2px' }}>认购群入口</div>
|
<div style={{ color: 'rgba(255,255,255,0.5)', fontSize: '10px', marginTop: '2px' }}>认购群入口</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div onClick={() => window.location.hash = '#/wiki'} style={{
|
||||||
|
background: 'linear-gradient(135deg, rgba(251,191,36,0.15) 0%, rgba(251,191,36,0.05) 100%)',
|
||||||
|
borderRadius: '12px',
|
||||||
|
padding: '12px 16px',
|
||||||
|
border: '1px solid rgba(251,191,36,0.2)',
|
||||||
|
cursor: 'pointer',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
textAlign: 'center'
|
||||||
|
}}>
|
||||||
|
<div style={{ color: '#fbbf24', fontSize: '18px', fontWeight: '600', whiteSpace: 'nowrap' }}>📚 龙钞百科</div>
|
||||||
|
<div style={{ color: 'rgba(255,255,255,0.5)', fontSize: '10px', marginTop: '2px' }}>新手入门指南</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
/**
|
/**
|
||||||
* List - 藏品列表页面
|
* List - 藏品列表页面
|
||||||
* Version: 0.1.6
|
* Version: 0.1.7
|
||||||
* 更新:新增成交行情页面筛选功能(版别、包装类型、号码分类)
|
* 更新:新增分享海报功能
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import { APP_VERSION } from '../config/version'
|
import { APP_VERSION } from '../config/version'
|
||||||
|
import SharePoster from '../components/SharePoster'
|
||||||
const API_BASE = localStorage.getItem('API_BASE') || ''
|
const API_BASE = localStorage.getItem('API_BASE') || ''
|
||||||
|
|
||||||
export default function List() {
|
export default function List() {
|
||||||
|
|
@ -34,6 +35,7 @@ export default function List() {
|
||||||
const [dealVersionFilter, setDealVersionFilter] = useState('') // 版别筛选
|
const [dealVersionFilter, setDealVersionFilter] = useState('') // 版别筛选
|
||||||
const [dealPackagingFilter, setDealPackagingFilter] = useState('') // 包装类型筛选
|
const [dealPackagingFilter, setDealPackagingFilter] = useState('') // 包装类型筛选
|
||||||
const [dealNumberCatFilter, setDealNumberCatFilter] = useState('') // 号码分类筛选
|
const [dealNumberCatFilter, setDealNumberCatFilter] = useState('') // 号码分类筛选
|
||||||
|
const [shareCollection, setShareCollection] = useState(null) // 分享弹窗
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 检查是否管理员
|
// 检查是否管理员
|
||||||
|
|
@ -497,7 +499,26 @@ export default function List() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ListItem = ({ item }) => (
|
const ListItem = ({ item }) => (
|
||||||
<div onClick={() => goDetail(item.id)} style={{ background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(255,255,255,0.05)', borderRadius: '12px', padding: '10px', marginBottom: '8px', cursor: 'pointer' }}>
|
<div onClick={() => goDetail(item.id)} style={{ background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(255,255,255,0.05)', borderRadius: '12px', padding: '10px', marginBottom: '8px', cursor: 'pointer', position: 'relative' }}>
|
||||||
|
{/* 分享按钮 */}
|
||||||
|
<button
|
||||||
|
onClick={(e) => { e.stopPropagation(); setShareCollection(item) }}
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: '8px',
|
||||||
|
right: '8px',
|
||||||
|
background: 'rgba(251, 191, 36, 0.15)',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '6px',
|
||||||
|
padding: '4px 8px',
|
||||||
|
fontSize: '12px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
color: '#fbbf24',
|
||||||
|
zIndex: 10
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
📤 分享
|
||||||
|
</button>
|
||||||
{/* 第1行:编号 + 冠字号 + 包装(蓝色) | 状态 + 持仓类型 + 珍惜度(紫色) */}
|
{/* 第1行:编号 + 冠字号 + 包装(蓝色) | 状态 + 持仓类型 + 珍惜度(紫色) */}
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '4px' }}>
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '4px' }}>
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: '6px', flexWrap: 'wrap' }}>
|
<div style={{ display: 'flex', alignItems: 'center', gap: '6px', flexWrap: 'wrap' }}>
|
||||||
|
|
@ -1116,6 +1137,14 @@ function DealListItem({ deal, onRefresh }) {
|
||||||
|
|
||||||
{/* 版本号显示 */}
|
{/* 版本号显示 */}
|
||||||
<div style={{ position: 'fixed', bottom: '70px', right: '12px', color: 'rgba(255,255,255,0.2)', fontSize: '10px' }}>v0.0.1</div>
|
<div style={{ position: 'fixed', bottom: '70px', right: '12px', color: 'rgba(255,255,255,0.2)', fontSize: '10px' }}>v0.0.1</div>
|
||||||
|
|
||||||
|
{/* 分享海报弹窗 */}
|
||||||
|
{shareCollection && (
|
||||||
|
<SharePoster
|
||||||
|
collection={shareCollection}
|
||||||
|
onClose={() => setShareCollection(null)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,401 @@
|
||||||
|
/**
|
||||||
|
* Wiki - 龙钞百科页面
|
||||||
|
* Version: 1.0.0
|
||||||
|
* 新手入门知识、号码分类、术语解释
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import { APP_VERSION } from '../config/version'
|
||||||
|
|
||||||
|
export default function Wiki() {
|
||||||
|
const [activeSection, setActiveSection] = useState('intro')
|
||||||
|
|
||||||
|
// 百科内容数据
|
||||||
|
const sections = {
|
||||||
|
intro: {
|
||||||
|
title: '🐉 什么是龙钞',
|
||||||
|
content: `
|
||||||
|
## 中国人民银行龙钞纪念钞
|
||||||
|
|
||||||
|
**龙钞**(全称:第24届冬季奥林匹克运动会纪念钞)是中国人民银行于2022年发行的纪念钞,包含**冰上运动**和**雪上运动**两枚一套。
|
||||||
|
|
||||||
|
### 基本信息
|
||||||
|
|
||||||
|
| 项目 | 内容 |
|
||||||
|
|------|------|
|
||||||
|
| 发行时间 | 2022年12月 |
|
||||||
|
| 发行量 | 2亿套 |
|
||||||
|
| 面值 | 20元 |
|
||||||
|
| 规格 | 145mm × 70mm |
|
||||||
|
|
||||||
|
### 收藏价值
|
||||||
|
|
||||||
|
1. **题材热门** - 冬奥会是国际大型赛事,题材热度高
|
||||||
|
2. **发行量适中** - 2亿的发行量在纪念钞中属于中等
|
||||||
|
3. **设计精美** - 首次采用塑料基片+纸基的组合设计
|
||||||
|
4. **号码玩法多** - 冠字号+8位数字,组合丰富多样
|
||||||
|
`
|
||||||
|
},
|
||||||
|
category: {
|
||||||
|
title: '🔢 号码分类',
|
||||||
|
content: `
|
||||||
|
## 龙钞号码分类大全
|
||||||
|
|
||||||
|
### 顶级号码(收藏价值最高)
|
||||||
|
|
||||||
|
| 分类 | 条件 | 优先级 |
|
||||||
|
|------|------|--------|
|
||||||
|
| 🏆 圆圆号 | 不含0、1、2、3、4、5、7 | 1 |
|
||||||
|
| 🔄 倒置号 | 不含2、3、4、5、7 | 2 |
|
||||||
|
| 🐎 金马王 | 不含1、2、3、4、7 | 3 |
|
||||||
|
| 🐎 金马号 | 不含2、3、4、7 | 4 |
|
||||||
|
| ⛰️ 金山王 | 不含1、2、4、5、7 | 5 |
|
||||||
|
| ⛰️ 天马王 | 不含1、2、4、7 | 6 |
|
||||||
|
|
||||||
|
### 高级号码
|
||||||
|
|
||||||
|
| 分类 | 条件 | 备注 |
|
||||||
|
|------|------|------|
|
||||||
|
| 🏔️ 金山号 | 不含2、4、5、7 | |
|
||||||
|
| 🐎 天马号 | 不含2、4、7 | |
|
||||||
|
| 🌫️ 朦胧王 | 不含1、3、4、5、7 | |
|
||||||
|
| 🌫️ 朦胧号 | 不含3、4、5、7 | |
|
||||||
|
| 💎 如意号 | 不含1、3、4、7 | |
|
||||||
|
| 💎 钻石号 | 不含3、4、7 | |
|
||||||
|
| ♾️ 永恒号 | 不含4、7 | |
|
||||||
|
|
||||||
|
### 普通号码
|
||||||
|
|
||||||
|
| 分类 | 条件 | 备注 |
|
||||||
|
|------|------|------|
|
||||||
|
| 🔥 带7号 | 不含4 | 不带4的号码 |
|
||||||
|
| ⚠️ 带4号 | 包含4 | 传统说法带4不太好 |
|
||||||
|
|
||||||
|
### 分类说明
|
||||||
|
|
||||||
|
- **"无X"规则**:号码中不包含数字X
|
||||||
|
- **就高不就低**:同时满足多个条件时,按最高价值分类
|
||||||
|
- **散钞看8位**:散钞看全部8位数字
|
||||||
|
- **标十看7位**:标十看后7位
|
||||||
|
- **标百看6位**:标百看后6位
|
||||||
|
`
|
||||||
|
},
|
||||||
|
terms: {
|
||||||
|
title: '📖 术语解释',
|
||||||
|
content: `
|
||||||
|
## 收藏术语大全
|
||||||
|
|
||||||
|
### 基础术语
|
||||||
|
|
||||||
|
| 术语 | 解释 |
|
||||||
|
|------|------|
|
||||||
|
| 冠字号 | J+8位数字,如J01234567 |
|
||||||
|
| 散钞 | 单张收藏的钞票 |
|
||||||
|
| 标十 | 10连号,一刀 |
|
||||||
|
| 标百 | 100连号,一捆 |
|
||||||
|
| 整刀 | 100张连号 |
|
||||||
|
| 整捆 | 1000张连号 |
|
||||||
|
|
||||||
|
### 评级术语
|
||||||
|
|
||||||
|
| 术语 | 解释 |
|
||||||
|
|------|------|
|
||||||
|
| 评级 | 由专业机构鉴定真伪、品相 |
|
||||||
|
| 评级公司 | PCGS、NGC、PMG等 |
|
||||||
|
| 分数 | 评级公司给出的品相分数(70-100) |
|
||||||
|
| 69+ | 顶级分数,收藏价值高 |
|
||||||
|
| 68 | 高分,品相极佳 |
|
||||||
|
| 67 | 不错,品相良好 |
|
||||||
|
|
||||||
|
### 状态术语
|
||||||
|
|
||||||
|
| 术语 | 解释 |
|
||||||
|
|------|------|
|
||||||
|
| 自持 | 自己收藏 |
|
||||||
|
| 寄存 | 存放在别人那里 |
|
||||||
|
| 寄售 | 委托他人代卖 |
|
||||||
|
| 送评 | 送去评级公司评级 |
|
||||||
|
| 修复 | 经过专业修复 |
|
||||||
|
|
||||||
|
### 价格术语
|
||||||
|
|
||||||
|
| 术语 | 解释 |
|
||||||
|
|------|------|
|
||||||
|
| 成本价 | 入手的价格 |
|
||||||
|
| 目标价 | 预期出售价格 |
|
||||||
|
| 成交价 | 实际交易价格 |
|
||||||
|
| 行情 | 当前市场的买卖价格 |
|
||||||
|
`
|
||||||
|
},
|
||||||
|
grade: {
|
||||||
|
title: '⭐ 评级知识',
|
||||||
|
content: `
|
||||||
|
## 评级公司介绍
|
||||||
|
|
||||||
|
### 国际三大评级公司
|
||||||
|
|
||||||
|
#### 1. PCGS(美国)
|
||||||
|
- 成立于1986年
|
||||||
|
- 业界权威,评级标准严格
|
||||||
|
- 特别擅长现代币评级
|
||||||
|
|
||||||
|
#### 2. NGC(美国)
|
||||||
|
- 成立于1987年
|
||||||
|
- 评级数量大
|
||||||
|
- 封装设计美观
|
||||||
|
|
||||||
|
#### 3. PMG(美国)
|
||||||
|
- 专注于纸币评级
|
||||||
|
- 评级标准清晰
|
||||||
|
- 国内认知度高
|
||||||
|
|
||||||
|
### 评分标准
|
||||||
|
|
||||||
|
| 分数 | 描述 | 等级 |
|
||||||
|
|------|------|------|
|
||||||
|
| 70 | 完美未流通 | Gem MS |
|
||||||
|
| 69 | 接近完美 | Gem MS |
|
||||||
|
| 68 | 极美 | MS |
|
||||||
|
| 67 | 精美 | MS |
|
||||||
|
| 66 | 优美 | MS |
|
||||||
|
| 65 | 精美 | MS |
|
||||||
|
|
||||||
|
### 评级建议
|
||||||
|
|
||||||
|
1. **高端收藏** - 建议送评69分以上
|
||||||
|
2. **普通收藏** - 67-68分性价比高
|
||||||
|
3. **投资需求** - 选择68分以上的评级钞
|
||||||
|
|
||||||
|
### 注意事项
|
||||||
|
|
||||||
|
- 评级有风险,可能降级
|
||||||
|
- 评级费用几十到几百元不等
|
||||||
|
- 评级周期通常2-4周
|
||||||
|
`
|
||||||
|
},
|
||||||
|
care: {
|
||||||
|
title: '💎 保养指南',
|
||||||
|
content: `
|
||||||
|
## 龙钞保养指南
|
||||||
|
|
||||||
|
### 存放环境
|
||||||
|
|
||||||
|
#### 温度与湿度
|
||||||
|
- **最佳温度**:18-25°C
|
||||||
|
- **最佳湿度**:40-55%
|
||||||
|
- 避免温差大的环境
|
||||||
|
- 避免潮湿(易发霉)
|
||||||
|
|
||||||
|
#### 存放方式
|
||||||
|
- 使用专用纸币保护套
|
||||||
|
- 避免直接用手触摸
|
||||||
|
- 远离阳光直射
|
||||||
|
- 远离热源(暖气、空调)
|
||||||
|
|
||||||
|
### 注意事项
|
||||||
|
|
||||||
|
#### ❌ 禁止行为
|
||||||
|
- 用手指直接触摸钞面
|
||||||
|
- 折叠、弯曲钞票
|
||||||
|
- 在钞面上写字
|
||||||
|
- 暴露在潮湿环境中
|
||||||
|
- 靠近化学物品
|
||||||
|
|
||||||
|
#### ✅ 正确做法
|
||||||
|
- 佩戴手套操作
|
||||||
|
- 使用镊子夹取
|
||||||
|
- 平放保存
|
||||||
|
- 定期检查状态
|
||||||
|
- 使用干燥剂
|
||||||
|
|
||||||
|
### 常见问题
|
||||||
|
|
||||||
|
**Q: 钞票有折痕怎么办?**
|
||||||
|
A: 建议送专业修复,或评级遮盖瑕疵
|
||||||
|
|
||||||
|
**Q: 钞票发黄怎么办?**
|
||||||
|
A: 避免潮湿环境,可使用干燥剂
|
||||||
|
|
||||||
|
**Q: 如何判断品相?**
|
||||||
|
A: 对光查看是否有磨损、污渍、折痕
|
||||||
|
`
|
||||||
|
},
|
||||||
|
platform: {
|
||||||
|
title: '🛒 交易指南',
|
||||||
|
content: `
|
||||||
|
## 交易注意事项
|
||||||
|
|
||||||
|
### 交易平台
|
||||||
|
|
||||||
|
1. **专业钱币交易平台**
|
||||||
|
- 一尘网
|
||||||
|
- 华夏收藏网
|
||||||
|
- 钱币天堂
|
||||||
|
|
||||||
|
2. **二手交易平台**
|
||||||
|
- 闲鱼(需谨慎)
|
||||||
|
|
||||||
|
3. **微信群交易**
|
||||||
|
- 诚信商家直供
|
||||||
|
- 群内私下交易
|
||||||
|
|
||||||
|
### 防骗指南
|
||||||
|
|
||||||
|
#### ⚠️ 常见骗局
|
||||||
|
- 低价诱惑先款后货
|
||||||
|
- 假称货在朋友处
|
||||||
|
- 改号、换号
|
||||||
|
- 假评级假分数
|
||||||
|
|
||||||
|
#### ✅ 安全交易
|
||||||
|
1. **走平台交易**
|
||||||
|
- 使用有保障的平台
|
||||||
|
- 保留交易凭证
|
||||||
|
|
||||||
|
2. **先看后买**
|
||||||
|
- 要求实拍视频
|
||||||
|
- 确认号码无误
|
||||||
|
|
||||||
|
3. **金额较大**
|
||||||
|
- 建议走中介
|
||||||
|
- 或面交交易
|
||||||
|
|
||||||
|
### 价格参考
|
||||||
|
|
||||||
|
- **散钞**:面值+10~50元
|
||||||
|
- **标十**:150-300元
|
||||||
|
- **标百**:1500-3000元
|
||||||
|
- **特殊号码**:价格面议
|
||||||
|
|
||||||
|
### 投资建议
|
||||||
|
|
||||||
|
1. 理性投资,量力而行
|
||||||
|
2. 注重品相,号码为辅
|
||||||
|
3. 长期持有,静待升值
|
||||||
|
4. 分散投资,不要all in
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 渲染Markdown内容(简化版)
|
||||||
|
const renderContent = (content) => {
|
||||||
|
const lines = content.trim().split('\n')
|
||||||
|
return lines.map((line, idx) => {
|
||||||
|
// 标题
|
||||||
|
if (line.startsWith('## ')) {
|
||||||
|
return <h3 key={idx} style={{ color: '#fbbf24', fontSize: '16px', marginTop: '20px', marginBottom: '10px', borderLeft: '3px solid #fbbf24', paddingLeft: '10px' }}>{line.replace('## ', '')}</h3>
|
||||||
|
}
|
||||||
|
// 小标题
|
||||||
|
if (line.startsWith('### ')) {
|
||||||
|
return <h4 key={idx} style={{ color: '#fff', fontSize: '14px', marginTop: '16px', marginBottom: '8px' }}>{line.replace('### ', '')}</h4>
|
||||||
|
}
|
||||||
|
// 表格
|
||||||
|
if (line.startsWith('|') && !line.startsWith('|---')) {
|
||||||
|
const cells = line.split('|').filter(c => c.trim())
|
||||||
|
if (cells.length > 1) {
|
||||||
|
const isHeader = idx > 0 && lines[idx-1]?.includes('---')
|
||||||
|
return (
|
||||||
|
<div key={idx} style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))', gap: '4px', padding: '8px 0', borderBottom: '1px solid rgba(255,255,255,0.05)' }}>
|
||||||
|
{cells.map((cell, i) => (
|
||||||
|
<div key={i} style={{ color: isHeader ? '#94a3b8' : '#e2e8f0', fontSize: '12px', padding: '4px', background: isHeader ? 'rgba(255,255,255,0.02)' : 'transparent' }}>
|
||||||
|
{cell.trim()}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
// 无序列表
|
||||||
|
if (line.startsWith('- ') || line.startsWith('1. ')) {
|
||||||
|
const text = line.replace(/^[-1-9.]\s*/, '')
|
||||||
|
return <div key={idx} style={{ color: '#cbd5e1', fontSize: '13px', paddingLeft: '16px', marginBottom: '6px', position: 'relative' }}><span style={{ position: 'absolute', left: '4px', color: '#fbbf24' }}>•</span>{text}</div>
|
||||||
|
}
|
||||||
|
// 普通段落
|
||||||
|
if (line.trim()) {
|
||||||
|
// 处理加粗
|
||||||
|
let text = line.replace(/\*\*(.*?)\*\*/g, '<strong style="color:#fbbf24">$1</strong>')
|
||||||
|
return <p key={idx} style={{ color: '#cbd5e1', fontSize: '13px', lineHeight: '1.8', marginBottom: '8px' }} dangerouslySetInnerHTML={{ __html: text }} />
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ minHeight: '100vh', background: '#0f172a', paddingBottom: '80px' }}>
|
||||||
|
{/* 头部 */}
|
||||||
|
<div style={{ padding: '20px', background: 'linear-gradient(135deg, #1e293b 0%, #0f172a 100%)', borderBottom: '1px solid rgba(251,191,36,0.2)' }}>
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '16px' }}>
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||||
|
<button onClick={() => window.location.hash = '#/home'} style={{ background: 'none', border: 'none', color: '#fbbf24', fontSize: '18px', cursor: 'pointer' }}>←</button>
|
||||||
|
<h1 style={{ color: '#fff', fontSize: '20px', margin: 0 }}>📚 龙钞百科</h1>
|
||||||
|
</div>
|
||||||
|
<span style={{ color: 'rgba(255,255,255,0.3)', fontSize: '11px' }}>v{APP_VERSION}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 简介文字 */}
|
||||||
|
<p style={{ color: '#94a3b8', fontSize: '13px', margin: 0 }}>
|
||||||
|
新手入门指南 · 号码分类 · 术语解释 · 保养知识
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 导航标签 */}
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
gap: '6px',
|
||||||
|
padding: '12px 16px',
|
||||||
|
overflowX: 'auto',
|
||||||
|
background: 'rgba(255,255,255,0.02)'
|
||||||
|
}}>
|
||||||
|
{Object.entries(sections).map(([key, section]) => (
|
||||||
|
<button
|
||||||
|
key={key}
|
||||||
|
onClick={() => setActiveSection(key)}
|
||||||
|
style={{
|
||||||
|
padding: '8px 14px',
|
||||||
|
borderRadius: '20px',
|
||||||
|
border: 'none',
|
||||||
|
fontSize: '12px',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
cursor: 'pointer',
|
||||||
|
background: activeSection === key ? '#fbbf24' : 'rgba(255,255,255,0.08)',
|
||||||
|
color: activeSection === key ? '#1e293b' : '#94a3b8',
|
||||||
|
fontWeight: activeSection === key ? 'bold' : 'normal',
|
||||||
|
transition: 'all 0.2s'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{section.title}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 内容区域 */}
|
||||||
|
<div style={{ padding: '16px' }}>
|
||||||
|
<div style={{
|
||||||
|
background: 'rgba(255,255,255,0.03)',
|
||||||
|
borderRadius: '12px',
|
||||||
|
padding: '16px',
|
||||||
|
border: '1px solid rgba(255,255,255,0.05)'
|
||||||
|
}}>
|
||||||
|
{renderContent(sections[activeSection].content)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 底部提示 */}
|
||||||
|
<div style={{
|
||||||
|
position: 'fixed',
|
||||||
|
bottom: '70px',
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translateX(-50%)',
|
||||||
|
background: 'rgba(251,191,36,0.1)',
|
||||||
|
padding: '8px 16px',
|
||||||
|
borderRadius: '20px',
|
||||||
|
border: '1px solid rgba(251,191,36,0.2)'
|
||||||
|
}}>
|
||||||
|
<span style={{ color: '#fbbf24', fontSize: '12px' }}>
|
||||||
|
💡 了解更多,请访问 jiachenlong.com
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue