v0.1.2 - 认购功能完善(冠字号J0输入框、编辑弹窗、字段完整)
This commit is contained in:
parent
5a5ec0ee2c
commit
a31d6cc153
|
|
@ -36,17 +36,19 @@ class PurchaseGroupResponse(BaseModel):
|
||||||
total_collections: int
|
total_collections: int
|
||||||
total_confirmed: int
|
total_confirmed: int
|
||||||
total_amount: float
|
total_amount: float
|
||||||
avg_price: float
|
avg_price: Optional[float] = None
|
||||||
created_at: Optional[datetime]
|
created_at: Optional[datetime]
|
||||||
|
|
||||||
class PurchaseCollectionCreate(BaseModel):
|
class PurchaseCollectionCreate(BaseModel):
|
||||||
collection_name: str
|
collection_name: Optional[str] = None
|
||||||
number: str
|
collection_code: Optional[str] = None
|
||||||
grading: str
|
number: Optional[str] = None
|
||||||
boss_name: str
|
collection_code: Optional[str] = None
|
||||||
price: float
|
grading: Optional[str] = None
|
||||||
source: str
|
boss_name: Optional[str] = None
|
||||||
paid: bool = False
|
price: Optional[float] = None
|
||||||
|
source: Optional[str] = None
|
||||||
|
paid: Optional[bool] = False
|
||||||
|
|
||||||
class PurchaseCollectionUpdate(BaseModel):
|
class PurchaseCollectionUpdate(BaseModel):
|
||||||
collection_name: Optional[str] = None
|
collection_name: Optional[str] = None
|
||||||
|
|
@ -65,11 +67,12 @@ class PurchaseCollectionResponse(BaseModel):
|
||||||
user_name: Optional[str]
|
user_name: Optional[str]
|
||||||
collection_name: Optional[str]
|
collection_name: Optional[str]
|
||||||
collection_code: Optional[str]
|
collection_code: Optional[str]
|
||||||
number: str
|
number: Optional[str] = None
|
||||||
grading: str
|
collection_code: Optional[str] = None
|
||||||
boss_name: str
|
grading: Optional[str] = None
|
||||||
price: float
|
boss_name: Optional[str] = None
|
||||||
source: str
|
price: Optional[float] = None
|
||||||
|
source: Optional[str] = None
|
||||||
paid: bool
|
paid: bool
|
||||||
status: str
|
status: str
|
||||||
submit_date: Optional[datetime]
|
submit_date: Optional[datetime]
|
||||||
|
|
@ -123,12 +126,18 @@ def get_my_groups(
|
||||||
db: Session = Depends(get_db)
|
db: Session = Depends(get_db)
|
||||||
):
|
):
|
||||||
"""获取我参与的认购群"""
|
"""获取我参与的认购群"""
|
||||||
|
if not current_user:
|
||||||
|
return []
|
||||||
|
|
||||||
member_groups = db.query(PurchaseMember).filter(
|
member_groups = db.query(PurchaseMember).filter(
|
||||||
PurchaseMember.user_id == current_user.f99_90_id,
|
PurchaseMember.user_id == current_user.f99_90_id,
|
||||||
PurchaseMember.status == "approved"
|
PurchaseMember.status == "approved"
|
||||||
).all()
|
).all()
|
||||||
|
|
||||||
group_ids = [m.group_id for m in member_groups]
|
group_ids = [m.group_id for m in member_groups]
|
||||||
|
if not group_ids:
|
||||||
|
return []
|
||||||
|
|
||||||
groups = db.query(PurchaseGroup).filter(
|
groups = db.query(PurchaseGroup).filter(
|
||||||
PurchaseGroup.id.in_(group_ids)
|
PurchaseGroup.id.in_(group_ids)
|
||||||
).all()
|
).all()
|
||||||
|
|
@ -370,16 +379,8 @@ def add_collection(
|
||||||
if not current_user:
|
if not current_user:
|
||||||
raise HTTPException(status_code=401, detail="请先登录")
|
raise HTTPException(status_code=401, detail="请先登录")
|
||||||
|
|
||||||
if not data.number:
|
# All fields now optional - frontend will send what it has
|
||||||
raise HTTPException(status_code=400, detail="冠字号必填")
|
# No validation needed as all fields are Optional in schema
|
||||||
if not data.grading:
|
|
||||||
raise HTTPException(status_code=400, detail="评级必填")
|
|
||||||
if not data.boss_name:
|
|
||||||
raise HTTPException(status_code=400, detail="认购老板必填")
|
|
||||||
if not data.price:
|
|
||||||
raise HTTPException(status_code=400, detail="价格必填")
|
|
||||||
if not data.source:
|
|
||||||
raise HTTPException(status_code=400, detail="来源必填")
|
|
||||||
|
|
||||||
group = db.query(PurchaseGroup).filter(PurchaseGroup.id == group_id).first()
|
group = db.query(PurchaseGroup).filter(PurchaseGroup.id == group_id).first()
|
||||||
if not group:
|
if not group:
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"pages": {
|
"pages": {
|
||||||
"Home": "0.1.0",
|
"Home": "0.1.0",
|
||||||
"Purchase": "0.1.1"
|
"Purchase": "0.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"backend": {
|
"backend": {
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,12 @@ function Purchase() {
|
||||||
const [allGroups, setAllGroups] = useState([])
|
const [allGroups, setAllGroups] = useState([])
|
||||||
const [showCreate, setShowCreate] = useState(false)
|
const [showCreate, setShowCreate] = useState(false)
|
||||||
const [selectedGroup, setSelectedGroup] = useState(null)
|
const [selectedGroup, setSelectedGroup] = useState(null)
|
||||||
|
const [editCollection, setEditCollection] = useState(null)
|
||||||
const [groupMembers, setGroupMembers] = useState([])
|
const [groupMembers, setGroupMembers] = useState([])
|
||||||
const [groupCollections, setGroupCollections] = useState([])
|
const [groupCollections, setGroupCollections] = useState([])
|
||||||
const [showCollectionForm, setShowCollectionForm] = useState(false)
|
const [showCollectionForm, setShowCollectionForm] = useState(false)
|
||||||
const [newGroup, setNewGroup] = useState({ name: '', description: '' })
|
const [newGroup, setNewGroup] = useState({ name: '', description: '' })
|
||||||
const [newCollection, setNewCollection] = useState({ collection_name: '', collection_code: '', number: '', price: '' })
|
const [newCollection, setNewCollection] = useState({ number: 'J0________', price: '' })
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
const [activeTab, setActiveTab] = useState('my') // my/all
|
const [activeTab, setActiveTab] = useState('my') // my/all
|
||||||
|
|
||||||
|
|
@ -132,12 +133,43 @@ function Purchase() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateCollection = async () => {
|
||||||
|
const token = localStorage.getItem('token')
|
||||||
|
if (!token || !editCollection) { return }
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${API_BASE}/api/purchase/groups/${selectedGroup.id}/collections/${editCollection.id}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${token}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
grading: editCollection.grading,
|
||||||
|
boss_name: editCollection.boss_name,
|
||||||
|
price: editCollection.price ? parseFloat(editCollection.price) : null,
|
||||||
|
source: editCollection.source,
|
||||||
|
paid: editCollection.paid
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if (res.ok) {
|
||||||
|
alert('更新成功!')
|
||||||
|
setEditCollection(null)
|
||||||
|
viewGroupDetail(selectedGroup.id)
|
||||||
|
} else {
|
||||||
|
alert('更新失败')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('更新失败:', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const submitCollection = async () => {
|
const submitCollection = async () => {
|
||||||
const token = localStorage.getItem('token')
|
const token = localStorage.getItem('token')
|
||||||
if (!token) { alert('请先登录'); return }
|
if (!token) { alert('请先登录'); return }
|
||||||
if (!selectedGroup) return
|
if (!selectedGroup) return
|
||||||
if (!newCollection.collection_name || !newCollection.price) {
|
if (!newCollection.number || !newCollection.price) {
|
||||||
alert('请填写藏品名称和价格'); return
|
alert('请填写完整信息'); return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -148,16 +180,18 @@ function Purchase() {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
collection_name: newCollection.collection_name,
|
|
||||||
collection_code: newCollection.collection_code,
|
|
||||||
number: newCollection.number,
|
number: newCollection.number,
|
||||||
price: parseFloat(newCollection.price)
|
grading: newCollection.grading,
|
||||||
|
boss_name: newCollection.boss_name,
|
||||||
|
price: parseFloat(newCollection.price),
|
||||||
|
source: newCollection.source,
|
||||||
|
paid: newCollection.paid || false
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
alert('提交成功!')
|
alert('提交成功!')
|
||||||
setNewCollection({ collection_name: '', collection_code: '', number: '', price: '' })
|
setNewCollection({ number: 'J0________', price: '' })
|
||||||
viewGroupDetail(selectedGroup.id)
|
viewGroupDetail(selectedGroup.id)
|
||||||
fetchGroups()
|
fetchGroups()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -362,19 +396,33 @@ function Purchase() {
|
||||||
background: 'rgba(255,255,255,0.05)',
|
background: 'rgba(255,255,255,0.05)',
|
||||||
borderRadius: '8px',
|
borderRadius: '8px',
|
||||||
padding: '12px',
|
padding: '12px',
|
||||||
marginBottom: '8px',
|
marginBottom: '8px'
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
alignItems: 'center'
|
|
||||||
}}>
|
}}>
|
||||||
<div>
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '6px' }}>
|
||||||
<div style={{ color: '#fff', fontSize: '14px' }}>{c.collection_name}</div>
|
<div>
|
||||||
<div style={{ color: 'rgba(255,255,255,0.5)', fontSize: '12px' }}>
|
<span style={{ color: '#fff', fontSize: '14px', fontWeight: 'bold' }}>{c.collection_code}</span>
|
||||||
{c.number} · {c.user_name}
|
<span style={{ color: '#fbbf24', fontSize: '12px', marginLeft: '8px' }}>{c.grading}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div style={{ color: '#34d399', fontSize: '16px', fontWeight: 'bold' }}>{formatMoney(c.price)}</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ color: '#34d399', fontSize: '16px', fontWeight: 'bold' }}>
|
<div style={{ color: 'rgba(255,255,255,0.7)', fontSize: '12px', marginBottom: '4px' }}>
|
||||||
{formatMoney(c.price)}
|
冠字号: {c.number}
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
|
<div style={{ color: 'rgba(255,255,255,0.6)', fontSize: '11px' }}>
|
||||||
|
老板: {c.boss_name} · 来源: {c.source || '-'}
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
|
||||||
|
<span style={{ color: c.paid ? '#10b981' : '#ef4444', fontSize: '11px' }}>
|
||||||
|
{c.paid ? '✓已结清' : '○未结清'}
|
||||||
|
</span>
|
||||||
|
{user && selectedGroup && selectedGroup.creator_id === user.id && (
|
||||||
|
<button
|
||||||
|
onClick={() => setEditCollection({...c})}
|
||||||
|
style={{ background: '#3b82f6', color: '#fff', border: 'none', borderRadius: '4px', padding: '4px 8px', fontSize: '10px' }}
|
||||||
|
>编辑</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
@ -384,6 +432,90 @@ function Purchase() {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 编辑弹窗 */}
|
||||||
|
{editCollection && (
|
||||||
|
<div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.8)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000 }}>
|
||||||
|
<div style={{ background: '#1e293b', borderRadius: '12px', padding: '20px', width: '90%', maxWidth: '400px' }}>
|
||||||
|
<div style={{ color: '#fff', fontSize: '16px', marginBottom: '16px', fontWeight: 'bold' }}>编辑: {editCollection.collection_code}</div>
|
||||||
|
<div style={{ fontSize: '12px', color: '#94a3b8', marginBottom: '4px' }}>冠字号</div>
|
||||||
|
<div style={{ display: 'flex', gap: '1px', marginBottom: '8px' }}>
|
||||||
|
<span style={{ background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.2)', borderRadius: '4px 0 0 4px', padding: '10px 4px', color: '#fff', fontWeight: 'bold', fontSize: '12px' }}>J</span>
|
||||||
|
{[0,1,2,3,4,5,6,7,8].map(i => (
|
||||||
|
<input
|
||||||
|
key={i}
|
||||||
|
ref={el => {
|
||||||
|
if (el) window.__editNumberInputs = window.__editNumberInputs || [];
|
||||||
|
window.__editNumberInputs[i] = el;
|
||||||
|
}}
|
||||||
|
maxLength={1}
|
||||||
|
value={editCollection.number ? editCollection.number[i+1] || '' : ''}
|
||||||
|
onChange={(e) => {
|
||||||
|
const v = e.target.value.slice(-1)
|
||||||
|
if (v) {
|
||||||
|
const num = editCollection.number || 'J0________'
|
||||||
|
const arr = num.split('')
|
||||||
|
arr[i+1] = v
|
||||||
|
setEditCollection({...editCollection, number: arr.join('')})
|
||||||
|
if (i < 8) window.__editNumberInputs?.[i+1]?.focus()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === 'Backspace' && !editCollection.number?.[i+1] && i > 0) window.__editNumberInputs?.[i]?.focus()
|
||||||
|
}}
|
||||||
|
placeholder="_"
|
||||||
|
style={{ flex: 1, background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.2)', borderRadius: '0', padding: '10px 2px', color: '#fff', fontSize: '12px', textAlign: 'center', minWidth: '20px' }}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ marginBottom: '6px', color: 'rgba(255,255,255,0.7)', fontSize: '12px' }}>评级</div>
|
||||||
|
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px', marginBottom: '12px' }}>
|
||||||
|
<select value={editCollection.grading || ''} onChange={(e) => setEditCollection({...editCollection, grading: e.target.value})} style={{ background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.2)', borderRadius: '6px', padding: '10px', color: '#fff' }}>
|
||||||
|
<option value="">选择评级</option>
|
||||||
|
<option value="ACG 67+">ACG 67+</option>
|
||||||
|
<option value="PMG 67+">PMG 67+</option>
|
||||||
|
<option value="ACG 68+">ACG 68+</option>
|
||||||
|
<option value="PMG 68+">PMG 68+</option>
|
||||||
|
<option value="ACG 69+">ACG 69+</option>
|
||||||
|
<option value="PMG 69+">PMG 69+</option>
|
||||||
|
<option value="ACG 70+">ACG 70+</option>
|
||||||
|
<option value="PMG 70+">PMG 70+</option>
|
||||||
|
<option value="ACG 67+">ACG 67+</option>
|
||||||
|
<option value="ACG 68+">ACG 68+</option>
|
||||||
|
<option value="ACG 69+">ACG 69+</option>
|
||||||
|
<option value="ACG 70+">ACG 70+</option>
|
||||||
|
</select>
|
||||||
|
<input value={editCollection.price || ''} onChange={(e) => setEditCollection({...editCollection, price: e.target.value})} placeholder="输入价格" type="number" style={{ background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.2)', borderRadius: '6px', padding: '10px', color: '#fff' }} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ marginBottom: '6px', color: 'rgba(255,255,255,0.7)', fontSize: '12px' }}>认购老板</div>
|
||||||
|
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px', marginBottom: '12px' }}>
|
||||||
|
<select value={editCollection.boss_name || ''} onChange={(e) => setEditCollection({...editCollection, boss_name: e.target.value})} style={{ background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.2)', borderRadius: '6px', padding: '10px', color: '#fff' }}>
|
||||||
|
<option value="">选择老板</option>
|
||||||
|
{groupMembers.map(m => <option key={m.id} value={m.user_name}>{m.user_name}</option>)}
|
||||||
|
</select>
|
||||||
|
<select value={editCollection.source || ''} onChange={(e) => setEditCollection({...editCollection, source: e.target.value})} style={{ background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.2)', borderRadius: '6px', padding: '10px', color: '#fff' }}>
|
||||||
|
<option value="">选择来源</option>
|
||||||
|
<option value="一尘">一尘</option>
|
||||||
|
<option value="直播">直播</option>
|
||||||
|
<option value="群友">群友</option>
|
||||||
|
<option value="其他">其他</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ marginBottom: '6px', color: 'rgba(255,255,255,0.7)', fontSize: '12px' }}>状态</div>
|
||||||
|
<label style={{ display: 'flex', alignItems: 'center', gap: '8px', color: '#fff', marginBottom: '16px' }}>
|
||||||
|
<input type="checkbox" checked={editCollection.paid || false} onChange={(e) => setEditCollection({...editCollection, paid: e.target.checked})} />
|
||||||
|
认购款结清
|
||||||
|
</label>
|
||||||
|
<div style={{ display: 'flex', gap: '8px' }}>
|
||||||
|
<button onClick={() => setEditCollection(null)} style={{ flex: 1, background: '#64748b', color: '#fff', border: 'none', borderRadius: '8px', padding: '12px' }}>取消</button>
|
||||||
|
<button onClick={updateCollection} style={{ flex: 1, background: '#3b82f6', color: '#fff', border: 'none', borderRadius: '8px', padding: '12px' }}>保存</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* 提交认购藏品表单 - 仅群主可提交 */}
|
{/* 提交认购藏品表单 - 仅群主可提交 */}
|
||||||
{selectedGroup && user && selectedGroup.creator_id === user.id && selectedGroup.status === 'active' && showCollectionForm && (
|
{selectedGroup && user && selectedGroup.creator_id === user.id && selectedGroup.status === 'active' && showCollectionForm && (
|
||||||
<div style={{
|
<div style={{
|
||||||
|
|
@ -394,77 +526,118 @@ function Purchase() {
|
||||||
padding: '16px',
|
padding: '16px',
|
||||||
border: '1px solid rgba(255,255,255,0.1)'
|
border: '1px solid rgba(255,255,255,0.1)'
|
||||||
}}>
|
}}>
|
||||||
<div style={{ color: '#fff', fontSize: '14px', marginBottom: '12px' }}>提交认购藏品</div>
|
<div style={{ color: '#fff', fontSize: '16px', marginBottom: '16px', fontWeight: 'bold', textAlign: 'center' }}>提交认购藏品</div>
|
||||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px', marginBottom: '12px' }}>
|
|
||||||
<input
|
{/* 冠字号行 */}
|
||||||
value={newCollection.collection_name}
|
<div style={{ marginBottom: '12px' }}>
|
||||||
onChange={(e) => setNewCollection({...newCollection, collection_name: e.target.value})}
|
<div style={{ fontSize: '12px', color: '#94a3b8', marginBottom: '4px' }}>冠字号 (J0开头8位)</div>
|
||||||
placeholder="藏品名称"
|
<div style={{ display: 'flex', gap: '1px' }}>
|
||||||
style={{
|
<span style={{ background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.2)', borderRadius: '4px 0 0 4px', padding: '10px 6px', color: '#fff', fontWeight: 'bold', fontSize: '14px' }}>J</span>
|
||||||
background: 'rgba(255,255,255,0.1)',
|
{[0,1,2,3,4,5,6,7,8].map(i => (
|
||||||
border: '1px solid rgba(255,255,255,0.2)',
|
<input
|
||||||
borderRadius: '6px',
|
key={i}
|
||||||
padding: '10px',
|
ref={el => {
|
||||||
color: '#fff',
|
if (el) window.__numberInputs = window.__numberInputs || [];
|
||||||
fontSize: '13px'
|
window.__numberInputs[i] = el;
|
||||||
}}
|
}}
|
||||||
/>
|
defaultValue={i === 0 ? '0' : ''}
|
||||||
<input
|
onChange={(e) => {
|
||||||
value={newCollection.number}
|
let v = e.target.value
|
||||||
onChange={(e) => setNewCollection({...newCollection, number: e.target.value})}
|
if (v) {
|
||||||
placeholder="冠字号"
|
v = v.replace(/\D/g, '')
|
||||||
style={{
|
if (v) {
|
||||||
background: 'rgba(255,255,255,0.1)',
|
const num = newCollection.number || 'J0________'
|
||||||
border: '1px solid rgba(255,255,255,0.2)',
|
const arr = num.split('')
|
||||||
borderRadius: '6px',
|
arr[i+1] = v
|
||||||
padding: '10px',
|
setNewCollection({...newCollection, number: arr.join('')})
|
||||||
color: '#fff',
|
if (i < 8 && v) window.__numberInputs[i+1]?.focus()
|
||||||
fontSize: '13px'
|
}
|
||||||
}}
|
}
|
||||||
/>
|
}}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === 'Backspace' && (!newCollection.number || !newCollection.number[i+1]) && i > 0)
|
||||||
|
window.__numberInputs[i]?.focus()
|
||||||
|
}}
|
||||||
|
style={{ flex: 1, background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.2)', borderRadius: '0', padding: '10px 2px', color: '#fff', fontSize: '13px', textAlign: 'center', minWidth: '20px' }}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px', marginBottom: '12px' }}>
|
|
||||||
<input
|
{/* 评级行 */}
|
||||||
value={newCollection.collection_code}
|
<div style={{ marginBottom: '12px' }}>
|
||||||
onChange={(e) => setNewCollection({...newCollection, collection_code: e.target.value})}
|
<div style={{ fontSize: '12px', color: '#94a3b8', marginBottom: '4px' }}>评级</div>
|
||||||
placeholder="编号(可选)"
|
<select
|
||||||
style={{
|
value={newCollection.grading || ''}
|
||||||
background: 'rgba(255,255,255,0.1)',
|
onChange={(e) => setNewCollection({...newCollection, grading: e.target.value})}
|
||||||
border: '1px solid rgba(255,255,255,0.2)',
|
style={{ width: '100%', background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.2)', borderRadius: '6px', padding: '10px', color: '#fff', fontSize: '13px' }}
|
||||||
borderRadius: '6px',
|
>
|
||||||
padding: '10px',
|
<option value="" style={{color:'#666'}}>选择评级</option>
|
||||||
color: '#fff',
|
<option value="ACG 67+">ACG 67+</option>
|
||||||
fontSize: '13px'
|
<option value="ACG 68+">ACG 68+</option>
|
||||||
}}
|
<option value="ACG 69+">ACG 69+</option>
|
||||||
/>
|
<option value="ACG 70+">ACG 70+</option>
|
||||||
|
<option value="PMG 67+">PMG 67+</option>
|
||||||
|
<option value="PMG 68+">PMG 68+</option>
|
||||||
|
<option value="PMG 69+">PMG 69+</option>
|
||||||
|
<option value="PMG 70+">PMG 70+</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 认购老板行 */}
|
||||||
|
<div style={{ marginBottom: '12px' }}>
|
||||||
|
<div style={{ fontSize: '12px', color: '#94a3b8', marginBottom: '4px' }}>认购老板</div>
|
||||||
|
<select
|
||||||
|
value={newCollection.boss_name || ''}
|
||||||
|
onChange={(e) => setNewCollection({...newCollection, boss_name: e.target.value})}
|
||||||
|
style={{ width: '100%', background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.2)', borderRadius: '6px', padding: '10px', color: '#fff', fontSize: '13px' }}
|
||||||
|
>
|
||||||
|
<option value="" style={{color:'#666'}}>选择认购老板</option>
|
||||||
|
{groupMembers.filter(m => m.status === 'approved').map(m => (
|
||||||
|
<option key={m.id} value={m.user_name}>{m.user_name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 价格行 */}
|
||||||
|
<div style={{ marginBottom: '12px' }}>
|
||||||
|
<div style={{ fontSize: '12px', color: '#94a3b8', marginBottom: '4px' }}>价格 (元)</div>
|
||||||
<input
|
<input
|
||||||
value={newCollection.price}
|
value={newCollection.price}
|
||||||
onChange={(e) => setNewCollection({...newCollection, price: e.target.value})}
|
onChange={(e) => setNewCollection({...newCollection, price: e.target.value})}
|
||||||
placeholder="价格"
|
placeholder="输入价格"
|
||||||
type="number"
|
type="number"
|
||||||
style={{
|
style={{ width: '100%', background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.2)', borderRadius: '6px', padding: '10px', color: '#fff', fontSize: '13px' }}
|
||||||
background: 'rgba(255,255,255,0.1)',
|
|
||||||
border: '1px solid rgba(255,255,255,0.2)',
|
|
||||||
borderRadius: '6px',
|
|
||||||
padding: '10px',
|
|
||||||
color: '#fff',
|
|
||||||
fontSize: '13px'
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 来源行 */}
|
||||||
|
<div style={{ marginBottom: '12px' }}>
|
||||||
|
<div style={{ fontSize: '12px', color: '#94a3b8', marginBottom: '4px' }}>来源</div>
|
||||||
|
<select
|
||||||
|
value={newCollection.source || ''}
|
||||||
|
onChange={(e) => setNewCollection({...newCollection, source: e.target.value})}
|
||||||
|
style={{ width: '100%', background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.2)', borderRadius: '6px', padding: '10px', color: '#fff', fontSize: '13px' }}
|
||||||
|
>
|
||||||
|
<option value="" style={{color:'#666'}}>选择来源</option>
|
||||||
|
<option value="一尘">一尘</option>
|
||||||
|
<option value="直播">直播</option>
|
||||||
|
<option value="群友">群友</option>
|
||||||
|
<option value="其他">其他</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 结清行 */}
|
||||||
|
<div style={{ marginBottom: '16px' }}>
|
||||||
|
<label style={{ display: 'flex', alignItems: 'center', gap: '8px', color: '#fff', fontSize: '13px' }}>
|
||||||
|
<input type="checkbox" checked={newCollection.paid || false} onChange={(e) => setNewCollection({...newCollection, paid: e.target.checked})} />
|
||||||
|
认购款已结清
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={submitCollection}
|
onClick={submitCollection}
|
||||||
style={{
|
style={{ width: '100%', background: '#3b82f6', color: '#fff', border: 'none', borderRadius: '8px', padding: '14px', fontSize: '14px', fontWeight: 'bold', cursor: 'pointer' }}
|
||||||
width: '100%',
|
|
||||||
background: '#3b82f6',
|
|
||||||
color: '#fff',
|
|
||||||
border: 'none',
|
|
||||||
borderRadius: '8px',
|
|
||||||
padding: '12px',
|
|
||||||
fontSize: '14px',
|
|
||||||
fontWeight: 'bold',
|
|
||||||
cursor: 'pointer'
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
提交认购
|
提交认购
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue