import { BasicType, IBestToast, YTAvoid, yTRouter } from "basic" import { window } from "@kit.ArkUI" import { unifiedDataChannel } from "@kit.ArkData" import { BusinessError } from "@kit.BasicServicesKit" import { undoData } from "../model/Index" @ObservedV2 export class SeatingPlanPageViewModel{ @Trace safeTop: number = 0 // 学生列表 @Trace dataSource: string[] = ['张三', '李四', '王五', '赵六', '孙七', '周八', '吴九', '小十', '张三', '李四', '王五', '赵六', '孙七', '周八', '吴九', '小十'] // 座位表 - 二维数组 8*8 @Trace seatingPlan: Array = new Array(4).fill(new Array(8).fill('')) // 当前显示的模式: 1 - 单列 2 - 双列 @Trace columnMode: number = 1 // 是否保存了 - 上次的操作是否为保存 isSave: boolean = false // 撤销数据 undoDataList: Array = [] // 上下文对象 conText: UIContext // 控制按钮 controlBtn: Array = [ { text: '添加行', click: () => { this._onAddRow() } }, { text: '添加列', click: () => { this._onAddColumn() } }, { text: '删除行', click: () => { this._onDeleteRow() } }, { text: '删除列', click: () => { this._onDeleteColumn() } }, { text: '单、双列切换', message: 'hh', click: () => { this._onChangeColumn() } }, { text: '撤销操作', click: () => { this._onUndo() } }, { text: '保存', click: () => { this._onSave() } }, { text: '返回', click: () => { this._onBackPressed() } } ] // 拖拽结束了吗 isDragEnd: boolean = true constructor(conText: UIContext) { this.safeTop = AppStorage.get(YTAvoid.SAFE_TOP_KEY) as number this.conText = conText window.getLastWindow(this.conText.getHostContext()) .then(res => { res.setPreferredOrientation(window.Orientation.LANDSCAPE) }) } /** * 点击学生 * @param seating 当前维度的学生列表 * @param x * @param y */ _onStudentClick(seating: string[], x : number, y : number){ if(!seating[y]) return let arr = [...seating] let i = arr[y] arr[y] = '' this._addUndoData() this.dataSource.push(i) this.seatingPlan.splice(x, 1, arr) } /** * 接收方 - 接收到拖拽的学生 * @param seat 当前维度的学生列表 * @param x * @param y * @param value 接收到的学生 */ _onDrag(seat: string[], x : number, y : number, value: string){ this.isDragEnd = true let arr = [...seat] // 原位置上有学生 if(arr[y]) { animateToImmediately({ duration: 300 } ,() => { this.dataSource.push(arr[y]) }) } arr[y] = value this.seatingPlan[x] = arr } /** * 数据源 - 拖拽事件结束 * @param event 拖拽事件传递的事件参数 */ _onDragEnd(event: DragEvent){ // 1. 拖拽失败 - 没有在接收方接收到数据, 撤销本次操作 // 2. 拖拽成功 - 但是数据接收是系统控件接收,数据源并没有发生变化, 撤销本次操作 if (event.getResult() === DragResult.DRAG_FAILED || !this.isDragEnd) { this._onUndo() } } /** * 添加行 */ _onAddRow() { let x = this.seatingPlan.length let y = this.seatingPlan[0].length if(x == 8) return this._addUndoData() this.seatingPlan.push(new Array(y).fill('')) } /** * 添加列 */ _onAddColumn() { let x = this.seatingPlan.length let y = this.seatingPlan[0].length if(y == 13) return this._addUndoData() for (let index = 0; index < this.seatingPlan.length; index++) { let arr = [...this.seatingPlan[index]] arr.push('') if(this.columnMode == 2) arr.push('') this.seatingPlan[index] = arr } } /** * 删除行 */ _onDeleteRow() { let x = this.seatingPlan.length let y = this.seatingPlan[0].length if(x == 4){ IBestToast.show('行数不足4行') return } this._addUndoData() this.seatingPlan.splice(x-1, 1) } /** * 删除列 */ _onDeleteColumn() { let x = this.seatingPlan.length let y = this.seatingPlan[0].length if(y == 8) { IBestToast.show('列数不足8列') return } this._addUndoData() for (let index = 0; index < x; index++) { let arr = [...this.seatingPlan[index]] arr.splice(y-1, 1) this.seatingPlan[index] = arr } } /** * 单、双列切换 */ _onChangeColumn() { let x = this.seatingPlan[0].length if(x%2 == 1 && this.columnMode == 1) this._onAddColumn() this._addUndoData() this.columnMode = this.columnMode == 1 ? 2 : 1 } /** * 撤销操作 */ _onUndo() { if(this.undoDataList.length == 0) return const undoDate: undoData = this.undoDataList.pop()! this.seatingPlan = [...undoDate.arr2!] this.dataSource = [...undoDate.arr!] this.columnMode = undoDate.columnMode! } /** * 保存 */ _onSave() { if(this.isSave) return this.isSave = true } /** * 添加 《撤销》 数据 - 仅保存 10 次操作 */ _addUndoData() { this.isSave = false const undoData: undoData = { arr2: [...this.seatingPlan], columnMode: this.columnMode, arr: [...this.dataSource], } this.undoDataList.push(undoData) if(this.undoDataList.length == 10) { this.undoDataList.splice(0, 1) } } /** * 回正屏幕并返回 */ _onBack(){ window.getLastWindow(this.conText.getHostContext()) .then(res => { res.setPreferredOrientation(window.Orientation.UNSPECIFIED) yTRouter.pop('') }) } /** * 重写的返回逻辑 * @returns */ _onBackPressed(){ if(!this.isSave) { yTRouter.router2DoubleConfirmDiaLog({ text: '编辑内容未保存,确定离开吗?', color: '#7186F9' }, (res) => { if(res && res.result == 'true') { this._onBack() } }) } else { this._onBack() } return true; } /******** 拖拽事件用的方法 ***********/ getDataFromUdmf(event: DragEvent, callback: (data: DragEvent) => void) { if (this.getDataFromUdmfRetry(event, callback)) { return; } setTimeout(() => { this.getDataFromUdmfRetry(event, callback); }, 1500); } getDataFromUdmfRetry(event: DragEvent, callback: (data: DragEvent) => void) { try { let data: UnifiedData = event.getData(); if (!data) { return false; } let records: Array = data.getRecords(); if (!records || records.length <= 0) { return false; } callback(event); return true; } catch (e) { console.error("getData failed, code = " + (e as BusinessError).code + ", message = " + (e as BusinessError).message); return false; } } }