|
|
@@ -1,15 +1,77 @@
|
|
|
-import { YTAvoid, yTRouter } from "basic"
|
|
|
+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: number[] = [0, 1, 1, 0, 0, 1, 0, 1, 0, 0]
|
|
|
- // 座位表
|
|
|
- @Trace seatingPlan: string[][] = []
|
|
|
+ @Trace dataSource: string[] = ['张三', '李四', '王五', '赵六', '孙七', '周八', '吴九', '小十', '张三', '李四', '王五', '赵六', '孙七', '周八', '吴九', '小十']
|
|
|
+ // 座位表 - 二维数组
|
|
|
+ @Trace seatingPlan: Array<string[]> = new Array(4).fill(new Array(8).fill(''))
|
|
|
+ // 当前显示的模式: 1 - 单列 2 - 双列
|
|
|
+ @Trace columnMode: number = 1
|
|
|
|
|
|
+ // 是否保存了 - 上次的操作是否为保存
|
|
|
+ isSave: boolean = false
|
|
|
+ // 撤销数据
|
|
|
+ undoDataList: Array<undoData> = []
|
|
|
+ // 上下文对象
|
|
|
conText: UIContext
|
|
|
+ // 控制按钮
|
|
|
+ controlBtn: Array<BasicType> = [
|
|
|
+ {
|
|
|
+ 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()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
|
|
|
constructor(conText: UIContext) {
|
|
|
this.safeTop = AppStorage.get(YTAvoid.SAFE_TOP_KEY) as number
|
|
|
@@ -21,18 +83,224 @@ export class SeatingPlanPageViewModel{
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+ /**
|
|
|
+ * 点击学生
|
|
|
+ * @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)
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
- * 重写的返回逻辑
|
|
|
- * @returns
|
|
|
+ * 接收方 - 接收到拖拽的学生
|
|
|
+ * @param seat 当前维度的学生列表
|
|
|
+ * @param x
|
|
|
+ * @param y
|
|
|
+ * @param value 接收到的学生
|
|
|
*/
|
|
|
- _onBackPressed(){
|
|
|
+ _onDrag(seat: string[], x : number, y : number, value: string){
|
|
|
+ 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){
|
|
|
+ // onDragEnd里取到的result值在接收方onDrop设置
|
|
|
+ if (event.getResult() === DragResult.DRAG_SUCCESSFUL) {
|
|
|
+
|
|
|
+ } else if (event.getResult() === DragResult.DRAG_FAILED) {
|
|
|
+ // 拖拽结束 - 没有在接收方接收到数据, 撤销本次操作
|
|
|
+ this._onUndo()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加行
|
|
|
+ */
|
|
|
+ _onAddRow() {
|
|
|
+ let x = this.seatingPlan.length
|
|
|
+ let y = this.seatingPlan[0].length
|
|
|
+
|
|
|
+ this._addUndoData()
|
|
|
+ this.seatingPlan.push(new Array(y).fill(''))
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加列
|
|
|
+ */
|
|
|
+ _onAddColumn() {
|
|
|
+ let x = this.seatingPlan.length
|
|
|
+ let y = this.seatingPlan[0].length
|
|
|
+ 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 == 1){
|
|
|
+ IBestToast.show('行数不足1行')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this._addUndoData()
|
|
|
+ this.seatingPlan.splice(x-1, 1)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除列
|
|
|
+ */
|
|
|
+ _onDeleteColumn() {
|
|
|
+ let x = this.seatingPlan.length
|
|
|
+ let y = this.seatingPlan[0].length
|
|
|
+
|
|
|
+ if(y == 1) {
|
|
|
+ IBestToast.show('列数不足1列')
|
|
|
+ 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() {
|
|
|
+ // todo 在切换的时候判断一下列数是否可以足够显示 双列, 如果不行则在后方补齐
|
|
|
+ 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.seatingPlan!]
|
|
|
+ this.dataSource = [...undoDate.student!]
|
|
|
+ this.columnMode = undoDate.columnMode!
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存
|
|
|
+ */
|
|
|
+ _onSave() {
|
|
|
+ if(this.isSave) return
|
|
|
+ this.isSave = true
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加 《撤销》 数据 - 仅保存 10 次操作
|
|
|
+ */
|
|
|
+ _addUndoData() {
|
|
|
+ this.isSave = false
|
|
|
+ const undoData: undoData = {
|
|
|
+ seatingPlan: [...this.seatingPlan],
|
|
|
+ columnMode: this.columnMode,
|
|
|
+ student: [...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<unifiedDataChannel.UnifiedRecord> = 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|