Add hierarchical geography and cloud-hosted profile images

This commit is contained in:
Codex
2026-10-04 21:30:30 +08:00
parent a77fcc6671
commit 427fd51e14
27 changed files with 618 additions and 50 deletions
+19 -5
View File
@@ -5,6 +5,7 @@ import re
import secrets
import hashlib
from appearance import png_bytes
import geography
class Households:
@@ -113,7 +114,7 @@ class Households:
account = self.a.get_object('users', uid)
return account.get('name', '') if account else ''
return [dict({k: v for k, v in row.items() if k != 'coverData' and (k != 'leadershipHistory' or self.manager(user))}, ownerName=label(row.get('ownerId')), successorName=label(row.get('successorId')),
coverUrl=('/api/households/cover?id='+row['id']+'&v='+row.get('coverRevision','0')) if row.get('coverData') else '',
coverUrl=('/api/households/cover?id='+row['id']+'&v='+row.get('coverRevision','0')) if row.get('coverData') or row.get('coverRef') else '',
canAssignOwner=user['role'] == 'admin' or row.get('ownerId') == user['id'],
members=sum(self.family_of(u) == row['id'] for u in self.a.objects('users')),
sites=sum(self.family_of(s) == row['id'] for s in self.a.objects('sites'))) for row in rows]
@@ -170,17 +171,30 @@ class Households:
createdAt=old['createdAt'] if old else dt.datetime.now(dt.timezone.utc).isoformat())
for field in ('province','city','district'):
item[field] = a.clean_text(data.get(field, (old or {}).get(field, '')), 60)
geography.apply(item, data, old, a.clean_text, a.Problem)
if 'coverData' in data:
cover = data['coverData']
if not isinstance(cover, str): raise a.Problem('封面图片格式不正确')
if cover:
try: png_bytes(cover, 2*1024*1024)
except ValueError as error: raise a.Problem(str(error).replace('Logo', '封面'))
item['coverData'] = cover
item['coverRevision'] = hashlib.sha256(cover.encode()).hexdigest()[:16]
a.save_object('households', item)
# Network I/O must not hold the database lock or stall unrelated requests.
if 'coverData' in data:
ref=a.CLOUD_IMAGES.put(data['coverData'],item['id'],'封面') if data['coverData'] else None
item.pop('coverData',None);item.pop('coverRef',None)
if ref:item['coverRef']=ref
item['coverRevision']=ref['sha256'][:16] if ref else 'default'
with a.LOCK:
current=a.get_object('households',item['id'])
if (current or {}).get('profileRevision',0)!=(old or {}).get('profileRevision',0):
raise a.Problem('上传期间档案已变化,请重新打开后保存',409)
# Preserve unrelated management/grouping updates made during the upload.
committed=dict(current or {},**{k:v for k,v in item.items() if k not in ('leadershipHistory','ownerId','successorId','leadershipRevision','deviceGrouping')})
if 'coverData' in data:committed.pop('coverData',None);committed.pop('coverRef',None)
if item.get('coverRef'):committed['coverRef']=item['coverRef']
a.save_object('households', committed)
a.audit('保存家庭', item['name'])
return item
return committed
def revision_key(self, user):
family = self.scope(user)