187 lines
5.3 KiB
Plaintext
187 lines
5.3 KiB
Plaintext
/**
|
||||
|
|
* 家书 FamilyBook · 6×4 服务卡片(观影 · 上概述/新建,下滚动列表)
|
|||
|
|
*
|
|||
|
|
* 用户 2026-10-25:「观影卡片,加4x4,和4x6,上面概述,加新建按钮,
|
|||
|
|
* 下面瀑布流,就跟观影模块类似,可以滑下去看全部电影。」
|
|||
|
|
* ⇒ 上半:标题 + 更新时间 + 「+ 新建」(路由进 app 直开「记一场」);
|
|||
|
|
* 下半:`List`(卡片**不支持 Scroll、只支持 List**,见 FbCard4x4 的注释)
|
|||
|
|
* 装全部观影(数据侧倒序裁到 30 条),整卡可点进模块。
|
|||
|
|
*
|
|||
|
|
* ⚠️ 卡片不能自己发网络请求:只画 `fbMovieCardBuild()` 推过来的字段。
|
|||
|
|
* ⚠️ ForEach key 带 version 前缀(v89 教训,不重绘就是它的锅)。
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
let storageMvB2 = new LocalStorage();
|
|||
|
|
|
|||
|
|
/** 列表一行 */
|
|||
|
|
class FbMovieRow9b {
|
|||
|
|
key: string = '';
|
|||
|
|
title: string = '';
|
|||
|
|
dateText: string = '';
|
|||
|
|
cinema: string = '';
|
|||
|
|
rating: string = '';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@Entry(storageMvB2)
|
|||
|
|
@Component
|
|||
|
|
struct FbMovieCard6x4 {
|
|||
|
|
@LocalStorageProp('state') state: string = 'loading';
|
|||
|
|
@LocalStorageProp('hint') hint: string = '';
|
|||
|
|
@LocalStorageProp('updatedAt') updatedAt: string = '';
|
|||
|
|
@LocalStorageProp('yearCount') yearCount: number = 0;
|
|||
|
|
@LocalStorageProp('totalCount') totalCount: number = 0;
|
|||
|
|
@LocalStorageProp('listJson') listJson: string = '[]';
|
|||
|
|
@LocalStorageProp('version') version: string = '';
|
|||
|
|
|
|||
|
|
private rows(): FbMovieRow9b[] {
|
|||
|
|
try {
|
|||
|
|
const all: FbMovieRow9b[] = JSON.parse(this.listJson) as FbMovieRow9b[];
|
|||
|
|
return all;
|
|||
|
|
} catch (err) {
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private openApp(): void {
|
|||
|
|
postCardAction(this, {
|
|||
|
|
action: 'router',
|
|||
|
|
abilityName: 'EntryAbility',
|
|||
|
|
params: { fbModule: 'movies' }
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 「+ 新建」→ 进 app 直开「记一场」浮层(EntryAbility → modCreate 通道) */
|
|||
|
|
private addOne(): void {
|
|||
|
|
postCardAction(this, {
|
|||
|
|
action: 'router',
|
|||
|
|
abilityName: 'EntryAbility',
|
|||
|
|
params: { fbModule: 'movies', widgetAction: 'add' }
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 列表单行:日期 + 片名/影院(+评分) */
|
|||
|
|
@Builder
|
|||
|
|
listRow(item: FbMovieRow9b) {
|
|||
|
|
Row({ space: 8 }) {
|
|||
|
|
Text(item.dateText !== '' ? item.dateText : '—')
|
|||
|
|
.fontSize(9)
|
|||
|
|
.fontColor('#A8988A')
|
|||
|
|
.width(46)
|
|||
|
|
.maxLines(1)
|
|||
|
|
Column({ space: 2 }) {
|
|||
|
|
Text(item.title)
|
|||
|
|
.fontSize(13)
|
|||
|
|
.fontColor('#2C231D')
|
|||
|
|
.maxLines(1)
|
|||
|
|
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
|||
|
|
if (item.cinema !== '') {
|
|||
|
|
Text(item.cinema)
|
|||
|
|
.fontSize(9)
|
|||
|
|
.fontColor('#A8988A')
|
|||
|
|
.maxLines(1)
|
|||
|
|
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.layoutWeight(1)
|
|||
|
|
.alignItems(HorizontalAlign.Start)
|
|||
|
|
if (item.rating !== '') {
|
|||
|
|
Text(item.rating)
|
|||
|
|
.fontSize(10)
|
|||
|
|
.fontColor('#C08A3E')
|
|||
|
|
.maxLines(1)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.alignItems(VerticalAlign.Center)
|
|||
|
|
.width('100%')
|
|||
|
|
.padding({ left: 8, right: 8, top: 5, bottom: 5 })
|
|||
|
|
.borderRadius(8)
|
|||
|
|
.backgroundColor('#F6F2F7')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 空态 */
|
|||
|
|
@Builder
|
|||
|
|
emptyHint() {
|
|||
|
|
Column() {
|
|||
|
|
Text(this.hint !== '' ? this.hint : '还没有观影记录')
|
|||
|
|
.fontSize(12)
|
|||
|
|
.fontColor(this.hint !== '' ? '#C0533F' : '#A8988A')
|
|||
|
|
.maxLines(3)
|
|||
|
|
.textAlign(TextAlign.Center)
|
|||
|
|
}
|
|||
|
|
.width('100%')
|
|||
|
|
.layoutWeight(1)
|
|||
|
|
.justifyContent(FlexAlign.Center)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
build() {
|
|||
|
|
Column({ space: 6 }) {
|
|||
|
|
// ===== 顶栏:标题 + 更新时间 + + 新建 =====
|
|||
|
|
Row({ space: 6 }) {
|
|||
|
|
Text('观影')
|
|||
|
|
.fontSize(15)
|
|||
|
|
.fontWeight(FontWeight.Bold)
|
|||
|
|
.fontColor('#2C231D')
|
|||
|
|
.maxLines(1)
|
|||
|
|
.layoutWeight(1)
|
|||
|
|
Text(this.updatedAt)
|
|||
|
|
.fontSize(9)
|
|||
|
|
.fontColor('#A8988A')
|
|||
|
|
.maxLines(1)
|
|||
|
|
/* ⭐ 新建按钮(子组件 onClick 优先于整卡,不会连带进 app) */
|
|||
|
|
Button('+')
|
|||
|
|
.fontSize(13)
|
|||
|
|
.fontColor('#FFFFFF')
|
|||
|
|
.width(26)
|
|||
|
|
.height(26)
|
|||
|
|
.borderRadius(13)
|
|||
|
|
.padding(0)
|
|||
|
|
.backgroundColor('#7A4E8C')
|
|||
|
|
.onClick((): void => this.addOne())
|
|||
|
|
}
|
|||
|
|
.width('100%')
|
|||
|
|
|
|||
|
|
// ===== 概述行 =====
|
|||
|
|
Row({ space: 8 }) {
|
|||
|
|
Text(`今年 ${this.yearCount} 场`)
|
|||
|
|
.fontSize(11)
|
|||
|
|
.fontColor('#7A4E8C')
|
|||
|
|
.fontWeight(FontWeight.Medium)
|
|||
|
|
Text(`共 ${this.totalCount} 条`)
|
|||
|
|
.fontSize(10)
|
|||
|
|
.fontColor(this.hint !== '' ? '#C0533F' : '#A8988A')
|
|||
|
|
.maxLines(1)
|
|||
|
|
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
|||
|
|
.layoutWeight(1)
|
|||
|
|
}
|
|||
|
|
.width('100%')
|
|||
|
|
|
|||
|
|
Divider()
|
|||
|
|
.strokeWidth(0.5)
|
|||
|
|
.color('#EFE6D8')
|
|||
|
|
|
|||
|
|
// ===== 全部观影(可滚动)=====
|
|||
|
|
if (this.rows().length === 0) {
|
|||
|
|
this.emptyHint()
|
|||
|
|
} else {
|
|||
|
|
List({ space: 5 }) {
|
|||
|
|
ForEach(this.rows(), (item: FbMovieRow9b) => {
|
|||
|
|
ListItem() {
|
|||
|
|
this.listRow(item)
|
|||
|
|
}
|
|||
|
|
}, (item: FbMovieRow9b): string => `ml_${this.version}_${item.key}`)
|
|||
|
|
}
|
|||
|
|
.width('100%')
|
|||
|
|
.layoutWeight(1)
|
|||
|
|
.scrollBar(BarState.Off)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.width('100%')
|
|||
|
|
.height('100%')
|
|||
|
|
.padding(12)
|
|||
|
|
.backgroundColor('#FFFFFF')
|
|||
|
|
.borderRadius(16)
|
|||
|
|
// ⭐ 整卡可点
|
|||
|
|
.onClick((): void => this.openApp())
|
|||
|
|
}
|
|||
|
|
}
|