filestoraging commit

This commit is contained in:
LeeJu 2026-04-11 10:05:44 +08:00
parent 2d4fa9af26
commit f509cc2ffe
77 changed files with 2573 additions and 0 deletions

21
filestoraging/README.md Normal file
View File

@ -0,0 +1,21 @@
# minesweeping
### 1、项目说明
总体思路扫雷程序项目开发的总体思路如图1.1示意,拟实现交互界面与交互控制、数据结构和扫雷算法等。
图1.1 项目开发的总体思路图
<img src="figs/overall.png" width=80% /></center>
### 2、开发环境说明
1系统版本OpenHarmony 4.0 Release
2SDK版本API 10
3Model类型Stage
4DevEco Studio版本Deveco Studio 4.0 release
5硬件环境Unionpi Whale、RK3566开发板
6预览器参数(1)DeviceType:default;(2)Resolution:560-1280;(3)DPI:240;其余参数自定。
### 3、项目主要函数调用关系图与项目输出界面演进图
图3.1 项目主要函数调用关系图
<img src="figs/relation.png" width=80% /></center>
图3.2 项目输出界面演进图
<img src="figs/evolution.png" width=80% /></center>

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

11
filestoraging/filestorage/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
/node_modules
/oh_modules
/local.properties
/.idea
**/build
/.hvigor
.cxx
/.clangd
/.clang-format
/.clang-tidy
**/.test

View File

@ -0,0 +1,10 @@
{
"app": {
"bundleName": "com.example.filereality",
"vendor": "example",
"versionCode": 1000000,
"versionName": "1.0.0",
"icon": "$media:app_icon",
"label": "$string:app_name"
}
}

View File

@ -0,0 +1,8 @@
{
"string": [
{
"name": "app_name",
"value": "FileReality"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,36 @@
{
"app": {
"signingConfigs": [],
"products": [
{
"name": "default",
"signingConfig": "default",
"compileSdkVersion": 10,
"compatibleSdkVersion": 9,
"runtimeOS": "OpenHarmony",
}
],
"buildModeSet": [
{
"name": "debug",
},
{
"name": "release"
}
]
},
"modules": [
{
"name": "entry",
"srcPath": "./entry",
"targets": [
{
"name": "default",
"applyToProducts": [
"default"
]
}
]
}
]
}

View File

@ -0,0 +1,6 @@
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test

View File

@ -0,0 +1,31 @@
{
"apiType": "stageMode",
"buildOption": {
"arkOptions": {
// "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */
}
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": [
"./obfuscation-rules.txt"
]
}
}
}
},
],
"targets": [
{
"name": "default"
},
{
"name": "ohosTest",
}
]
}

View File

@ -0,0 +1,6 @@
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
}

View File

@ -0,0 +1,18 @@
# Define project specific obfuscation rules here.
# You can include the obfuscation configuration files in the current module's build-profile.json5.
#
# For more details, see
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
# Obfuscation options:
# -disable-obfuscation: disable all obfuscations
# -enable-property-obfuscation: obfuscate the property names
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
# -compact: remove unnecessary blank spaces and all line feeds
# -remove-log: remove all console.* statements
# -print-namecache: print the name cache that contains the mapping from the old names to new names
# -apply-namecache: reuse the given cache file
# Keep options:
# -keep-property-name: specifies property names that you want to keep
# -keep-global-name: specifies names that you want to keep in the global scope

View File

@ -0,0 +1,10 @@
{
"license": "",
"devDependencies": {},
"author": "",
"name": "entry",
"description": "Please describe the basic information.",
"main": "",
"version": "1.0.0",
"dependencies": {}
}

View File

@ -0,0 +1,34 @@
//公共常量
export const boardNum: number = 11 // 行列数
export const gridSize: number = 19 // 格子大小
export const blockSize: number = 17 // 方块大小
// 绘制Fat区域背景
export const settings: RenderingContextSettings = new RenderingContextSettings(true)
export const context: CanvasRenderingContext2D = new CanvasRenderingContext2D(settings)
// 绘制Fat区域信息
export const settings2: RenderingContextSettings = new RenderingContextSettings(true)
export const context2: CanvasRenderingContext2D = new CanvasRenderingContext2D(settings2)
// 绘制Disk区域背景
export const settings3: RenderingContextSettings = new RenderingContextSettings(true)
export const context3: CanvasRenderingContext2D = new CanvasRenderingContext2D(settings3)
// 绘制Disk区域信息
export const settings4: RenderingContextSettings = new RenderingContextSettings(true)
export const context4: CanvasRenderingContext2D = new CanvasRenderingContext2D(settings4)
// 绘制模拟区域信息
export const settings5: RenderingContextSettings = new RenderingContextSettings(true)
export const context5: CanvasRenderingContext2D = new CanvasRenderingContext2D(settings5)
// 绘制文件夹区域信息
export const settings6: RenderingContextSettings = new RenderingContextSettings(true);
export const context6: CanvasRenderingContext2D = new CanvasRenderingContext2D(settings6);
export const img1:ImageBitmap = new ImageBitmap("/common/image/fk1.png")
export const img2:ImageBitmap = new ImageBitmap("/common/image/fk2.png")
export const img3:ImageBitmap = new ImageBitmap("/common/image/fk3.png")

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,744 @@
import {initialize_simdisk,initialize_simfat,drawFatMessage,clearEmulation,draw_blocks,drawDiskText,clearFatMessage,clearBlock,clearDiskText,read_sim_fat,draw_blocks_emulation,
draw_files,
clearFiles
} from '../utils/functions'
// 文件项的唯一集合
let file_name_set: Set<string> = new Set()
// 文件标签的唯一集合
let blocks_label_set: Set<string> = new Set()
// 获取唯一字母标签
function get_unique_tag(): string | null {
for (let ascii_code = 65; ascii_code <= 90; ascii_code++) {
let character = String.fromCharCode(ascii_code)
if (!blocks_label_set.has(character)) {
blocks_label_set.add(character)
return character
}
}
return null
}
function initialize_fileblock(block_num: string, code: string): string[] {
let files: string[] = []
for (let n = 0; n < parseInt(block_num); n++) {
files.push(`${code}${n + 1}`)
}
if (code === "Z") {
blocks_label_set.clear() // 确保blocks_label_set已经声明
}
return files
}
export class InterfaceFile {
messages: string[] // 系统消息队列
sim_fat_copy: string[][] // 拷贝simFAT
ex_disk_oc: boolean // 交替显示保存占用和添加占用标志
ex_disk_la: boolean // 修改保存标签和清除标签的标志
sim_disk_copy: string[][] // 拷贝simDisk
block_modi_tag: boolean // 磁盘块修改标志
block_modi_lb: string // 磁盘块标签值初始化
old_key: number[] // FAT表上一次的记录值
fat_modi_num: string // 打开下一个FAT单元格之前的修改数值
fat_modi_tag: boolean // 修改状态标签为True时进入修改状态
clear_tag: boolean // 清除标签让标签清理和fat清理操作互斥
check: boolean // 检查磁盘条件
code: string // 当前磁盘块标签字母
creating: boolean // 正在创建的状态
simFAT: string[][] // SimFAT 表初始化
simDisk: string[][] // SimDisk 区域初始化
folder_items: any[] // 文件项临时储存
fat_unique_set: Set<string> // fat表去重集合防止在一个位置建立多个磁盘块
file_name_label: string // 输入文件名输入框
blocks_num_label: string // 块数输入框
path_name_label: string // 创建目录项输入框
file_label:string[]
fat_tags: string[][] // FAT删除标志
fat_disks: string[][] // Disk方块删除标志
label_disks: string[][] // Disk标签删除标志
default: string // MessageDialog传参
constructor(len: number) {
this. messages = []
this.sim_fat_copy = null
this.ex_disk_oc = true
this.ex_disk_la = true
this.sim_disk_copy = null
this.block_modi_tag = false
this.block_modi_lb = ''
this.old_key = null
this.fat_modi_num = null
this.fat_modi_tag = false
this.clear_tag = true // 清除标签让标签清理和FAT清理操作互斥
this.check = false // 检查磁盘条件
this.code = null // 当前磁盘块标签字母
this.creating = true // 正在创建的状态
this.simFAT = initialize_simfat() // SimFAT 表初始化
this.simDisk = initialize_simdisk() // SimDisk 区域初始化
this.folder_items = []
this.fat_unique_set = new Set(['0'])
this.file_name_label = ''
this.blocks_num_label = ''
this.path_name_label = ''
this.default = ''
this.file_label= new Array(0)
this.fat_tags = new Array(len)
this.fat_disks = new Array(len)
this.label_disks = new Array(len)
for (let i = 0; i < len; i++) {
this.fat_tags[i] = new Array(len)
this.fat_disks[i] = new Array(len)
this.label_disks[i] = new Array(len)
for (let j = 0; j < 10; j++) {
this.fat_tags[i][j] = ''
this.fat_disks[i][j] = ''
this.label_disks[i][j] = ''
}
}
}
create_file(file_name?: string, f_block?: string, block_num?: string) {
console.log("创建文件")
file_name = file_name ?? this.file_name_label // 输入文件名
block_num = block_num ?? this.blocks_num_label // 块数
f_block = f_block ?? this.select_fat_unique()
this.check = this.check_condition(file_name, f_block, block_num) // 执行数据合规检查
if (this.check) { // 合规时执行
if (this.creating) { // 初始时获取字母
this.code = get_unique_tag()
this.creating = false // 获取后除非触发保存,下次创建不更新字母
}
this.file_label = initialize_fileblock(block_num, this.code!)
this.creat_file_blocks()
this.sys_info("创建文件成功!")
}
}
// 获取唯一的FAT表编号
select_fat_unique(): string | null {
while (true) {
const unique_num = Math.floor(Math.random() * 99).toString()
if (!this.fat_unique_set.has(unique_num)) {
return unique_num
}
if (this.fat_unique_set.size >= 100) {
return null
}
}
}
// 检查创建和保存条件
check_condition(file_name: string, start_block_num: string, block_num: string): boolean {
// 更新唯一SimFAT表
this.simFAT.forEach(row => { // 更新唯一SimFAT表
row.forEach(item => this.fat_unique_set.add(item))
})
if (this.fat_unique_set.has('FF')) { // 判断磁盘空间时,排除掉非位置字符
this.fat_unique_set.delete('FF')
}
this.fat_unique_set.delete('100') // 收藏判断需要删除100这个非位置值
if (this.clear_tag) {
if (file_name !== "" && block_num !== "") { // 文件名和块数不为空才能保存
if (/^\d+$/.test(block_num)) { // 检查块数为正整数
if (!file_name_set.has(file_name)) { // 文件名不重复
if (this.fat_unique_set.size + parseInt(block_num) <= 100) {
if (start_block_num) {
if (!this.fat_unique_set.has(start_block_num)) {
return true
} else {
this.sys_info("首块位置已被占用!")
}
} else {
this.sys_info("磁盘已满!")
}
} else {
this.sys_info("磁盘空间不足!")
}
} else {
this.sys_info("文件名不能重复!")
}
} else {
this.sys_info("请输入正整数!")
}
} else {
this.sys_info("文件名或块数不能为空!")
}
} else {
this.sys_info("正在执行磁盘修改任务!")
}
}
creat_file_start_end_label() {
}
creat_file_blocks(): void {
const left_x: number = 210
const left_y: number = 40
const side: number = 20 // 元素边
const n: number = this.file_label.length
if (n <= 11) {
for (let i = 0; i < n; i++) {
const x: number = left_x - i * side
const y: number = left_y
draw_blocks_emulation(x,y,this.file_label[i])
}
}
else {
let end_i: number = n - 11 // 取最后5块
for (let i = 0; i < n; i++) { // i < 11 确保循环在最后5块内
const x: number = left_x - i * side
const y: number = left_y
if (i < 5) {
draw_blocks_emulation(x,y,this.file_label[i])
} else if (i === 5) {
draw_blocks_emulation(x,y,'...')
} else if (i < 11) {
draw_blocks_emulation(x,y,this.file_label[i+end_i])
}
}
}
}
//显示文件夹
show_files(path_name: any[]){
draw_files(path_name)
}
// 映射显示FAT表
show_fat(row: number, column: number): void {
// 获取FAT表中的值
const num = this.simFAT[row][column]
if (num !== "0") { // 检查FAT表中的值是否为非零
// 定义删除标志
this.fat_tags[row][column] = "fat_tag"
drawFatMessage(num, row, column)
}
}
// 显示整个FAT表
show_all_fat(): void {
// 清空画布上所有的"FAT_tag"标签
for (let i = 0; i < 10; i++) {
for (let n = 0; n < 10; n++) {
if (this.fat_tags[i][n] == "fat_tag") {
clearFatMessage(i,n)
}
}
}
// 遍历FAT表的行和列显示FAT表中的所有元素
for (let i = 0; i < 10; i++) {
for (let n = 0; n < 10; n++) {
this.show_fat(i, n)
}
}
}
show_disk(row: number, column: number, color_tag: boolean | null = null): void {
// 获取磁盘块上的文本内容
const text = this.simDisk[row][column]
if (text !== "0") { // 检查磁盘块内容是否为非零值
console.log("text="+text+"+row="+row+"+column="+column)
// 定义删除标志
this.fat_disks[row][column] = 'fat_disk'
this.label_disks[row][column] = "label_disk"
if (color_tag) {
// 根据颜色标签绘制磁盘块 黄色 初始创建
draw_blocks(row, column, true)
} else {
// 绘制普通磁盘块 灰色 占用
draw_blocks(row, column, false)
}
drawDiskText(text,row,column)
}
}
// 显示所有磁盘块
show_all_disk(): void {
// 清除之前的磁盘块和标签
for (let i = 0; i < 10; i++) {
for (let n = 0; n < 10; n++) {
if (this.fat_disks[i][n] == 'fat_disk') {
clearBlock(i,n)
}
if (this.label_disks[i][n] == "label_disk") {
clearDiskText(i,n)
}
}
}
// 遍历所有行和列,显示每个磁盘块
for (let row = 0; row < 10; row++) {
for (let column = 0; column < 10; column++) {
this.show_disk(row, column)
}
}
}
save_file(file_name: string | null = null, f_block: string | null = null, blocks: string | null = null) {
console.log("保存文件")
file_name = file_name ?? this.file_name_label // 输入文件名
blocks = blocks ?? this.blocks_num_label // 块数
if (this.creating) {
this.create_file(file_name, f_block, blocks)
}
if (this.check) {
let fat_block = f_block ? f_block : this.select_fat_unique()
let fat_arr = this.generate_fat_array(fat_block, parseInt(blocks)) // 生成fat表
this.folder_items.push([file_name, fat_block, blocks, this.code]) // 添加到文件夹
file_name_set.add(file_name) // 添加唯一性文件名集合
fat_arr.forEach((block) => this.fat_unique_set.add(block)) // 将占用的磁盘位置信息添加进唯一集合,防止重复取数
this.load_files_list(fat_arr, this.code) // 根据fat表向磁盘装载文件数据并显示
this.show_path_info() // 保存后显示文件夹
this.creating = true // 上一次保存执行完成后才能开始二次执行
this.sys_info("保存成功")
}
}
generate_fat_array(first_block: string, blockNum: number): string[] {
const fat_arr = [first_block]
// 放入首块信息
this.fat_unique_set.add(first_block)
for (let i = 0; i < blockNum - 1; i++) {
let num: number | null
while (true) {
num = Math.floor(Math.random() * 99) + 1
if (this.fat_unique_set.size >= 101) {
num = null
break
}
if (!this.fat_unique_set.has(num.toString())) {
this.fat_unique_set.add(num.toString())
break
}
}
if (num !== null) {
fat_arr.push(num.toString())
} else {
break
}
}
return fat_arr
}
load_files_list(fat_ls: string[], block_label: string = "default") {
this.show_all_disk() // 更新磁盘显示
fat_ls.forEach((value, index) => {
const row = Math.floor(parseInt(value) / 10)
const column = parseInt(value) % 10
if (block_label == "default") {
block_label = this.simDisk[row][column][0]
}
if (index < fat_ls.length - 1) {
this.simFAT[row][column] = fat_ls[index + 1]
} else {
this.simFAT[row][column] = "FF"
}
this.simDisk[row][column] = `${block_label}${index + 1}`
this.show_disk(row, column, true) // 最后创建颜色才为黄色
})
this.show_all_fat() // 更新fat表显示
}
// 查询文件功能
query_file() {
const file_name = this.file_name_label
if(file_name_set.has(file_name)) {
console.log('folder_items='+this.folder_items)
this.folder_items.forEach((item) => {
if (file_name === item[0]) {
this.file_label = initialize_fileblock(item[2], item[3])
this.creat_file_blocks()
const block_nums = read_sim_fat(item[1], this.simFAT) // 通过首块fat获取全部文件fat
this.load_files_list(block_nums)
}
})
this.sys_info('查询成功')
} else {
console.log('文件夹中无该文件')
this.sys_info('文件夹中无该文件')
}
}
// FAT校验功能
fat_checkout() {
console.log('FAT校验')
if (this.sim_fat_copy) {
let num = 0
let tag = false
for (let i = 0; i < 10; i++) {
for (let n = 0; n < 10; n++) {
num++
if (this.simFAT[i][n] !== this.sim_fat_copy[i][n]) {
this.sys_info(`校验失败\n${i}行${n}列错误`)
tag = true
break
}
}
if (tag) {
break
}
}
if (num === 100) {
this.sys_info('校验正确')
}
} else {
this.sys_info('未进行修改操作,不可校验')
}
}
// 清除表单项
clear_fat_label() {
console.log('清除表单项')
if (this.clear_tag) {
// 清空画布上所有的"fat_tag"标签
for (let i = 0; i < 10; i++) {
for (let n = 0; n < 10; n++) {
if (this.fat_tags[i][n] == "fat_tag") {
clearFatMessage(i,n)
}
}
}
this.clear_tag = false
if (!this.sim_fat_copy) {
this.sim_fat_copy = JSON.parse(JSON.stringify(this.simFAT)) // # 深拷贝simFAT复制一份原正确列表并保存为复制对象
}
this.simFAT = initialize_simfat() // 清空原FAT表
this.sys_info("清除成功!")
} else {
this.sys_info("正在执行标注任务, 无法清除表单项!")
}
}
// 保存表单项
modi_fat_save() {
console.log("保存表单项")
this.fat_modi_tag = false // 关闭修改模式
this.clear_tag = true // 保存后可以清除
if (this.fat_modi_num && this.old_key) {
if (this.fat_modi_num.match(/^\d+$/) || this.fat_modi_num === "FF") {
this.simFAT[this.old_key[0]][this.old_key[1]] = this.fat_modi_num.match(/^\d+$/) ? this.fat_modi_num : "FF"
} else {
this.sys_info("请输入正整数或FF")
}
}
this.show_all_fat()
this.old_key = null
for(let i = 0; i < 10; i++) {
for (let n = 0; n < 10; n++) {
if (this.simFAT[i][n] != '0') {
let num = i * 10 + n
this.fat_unique_set.add(num.toString())
}
}
}
this.sys_info("保存表单成功!")
}
// 修改表单项
modi_fat() {
this.sys_info("正在修改表单项!")
this.fat_modi_tag = true
if (!this.sim_fat_copy) {
this.sim_fat_copy = JSON.parse(JSON.stringify(this.simFAT)) // # 深拷贝simFAT复制一份原正确列表并保存为复制对象
}
}
modi_fat_entry(row: number, column: number) {
if (this.fat_modi_num && this.old_key) {
if (/^\d+$/.test(this.fat_modi_num) || this.fat_modi_num === "FF") {
if (/^\d+$/.test(this.fat_modi_num)) {
this.simFAT[this.old_key[0]][this.old_key[1]] = this.fat_modi_num
} else {
this.simFAT[this.old_key[0]][this.old_key[1]] = "FF"
}
} else {
this.sys_info("请输入正整数,或FF")
}
}
this.old_key = [column, row]
this.show_all_fat()
}
// Disk校验方法
disk_checkout() {
console.log("Disk校验")
if (this.sim_disk_copy) {
let num = 0
let tag = false
for (let i = 0; i < 10; i++) {
for (let n = 0; n < 10; n++) {
num ++
const diskValue = this.simDisk[i][n]
// 匹配 [A-Za-z]开头,后面跟数字的字符串
if (/^[A-Za-z]\d+$/.test(diskValue)) {
if (this.simDisk[i][n] !== this.sim_disk_copy[i][n]) {
this.sys_info(`校验失败\n${i}行${n}列错误`)
tag = true
break
}
}
}
if (tag) {
break
}
}
if (num === 100) {
this.sys_info("校验正确")
}
} else {
this.sys_info("未进行修改操作,不可校验")
}
}
// 添加占用
add_occupy() {
console.log("添加占用")
this.sys_info("正在添加占用...")
}
// 点击添加占用
add_occupy_click(row: number, col: number) {
if (!this.ex_disk_oc) {
this.simDisk[col][row] = '' // 清空simDisk中对应位置的值
console.log(col.toString(), row.toString())
this.show_all_disk() // 假设 show_all_disk 是更新磁盘显示的方法
this.sys_info(`(${[col, row]}) 添加成功`)
}
}
// 保存占用
save_occupy() {
console.log("保存占用")
for (let i = 0; i < 10; i++) {
for (let n = 0; n < 10; n++) {
if (this.simDisk[i][n] != '0') {
let num = i * 10 + n
this.fat_unique_set.add(num.toString()) // 将占用块号添加到 fat_unique_set 中
}
}
}
this.sys_info("保存占用成功!")
}
// 修改标签
modi_block_lb() {
console.info("修改标签")
this.sys_info("正在修改标签...")
this.block_modi_tag = true // 磁盘块修改标志
this.clear_tag = false // 修改磁盘标签时冻结文件分配表的按钮
if (!this.sim_disk_copy) {
this.sim_disk_copy = JSON.parse(JSON.stringify(this.simDisk)) // 深拷贝数组
}
}
// 修改标签条目
modi_block_entry(row: number, column: number) {
let label = this.block_modi_lb
if (this.block_modi_lb) {
if (label !== "0") {
const regex = /^[A-Za-z]\d+$/ // 正则表达式将匹配如 "A1"、"b2"、"Z9" 等形式的字符串
if (regex.test(label)) {
this.simDisk[this.old_key[0]][this.old_key[1]] = label
this.sys_info(`${this.old_key} -> ${label}添加成功!`)
} else {
this.sys_info("请输入正确格式A1")
}
}
}
this.old_key = [column, row]
this.show_all_disk()
}
// 保存标签
modi_block_save() {
console.info("保存标签")
if (this.block_modi_lb) {
let label = this.block_modi_lb
if (label !== "0") {
const regex = /^[A-Za-z]\d+$/
if (regex.test(label)) {
this.simDisk[this.old_key[0]][this.old_key[1]] = label
this.sys_info(`${this.old_key} -> ${label}添加成功!`)
} else {
this.sys_info("请输入正确格式A1")
}
for (let i = 0; i < 10; i++) {
for (let n = 0; n < 10; n++) {
if (this.simDisk[i][n] !== '0' && this.simDisk[i][n] !== '') {
let num = i * 10 + n
let code = this.simDisk[i][n][0] // 取第一个字母
blocks_label_set.add(code) // 添加到唯一集合
this.fat_unique_set.add(num.toString()) // 添加到FAT表
}
}
}
}
}
this.block_modi_lb = '' // 重置 block_modi_lb
this.show_all_disk()
this.block_modi_tag = false // 关闭标签修改状态
this.clear_tag = true
this.sys_info("保存标签成功!")
}
// 清除标签
clear_disk_label() {
console.info("清除标签")
if (this.clear_tag) {
// 清除之前的标签
for (let i = 0; i < 10; i++) {
for (let n = 0; n < 10; n++) {
if (this.label_disks[i][n] == "label_disk") {
clearDiskText(i,n)
}
}
}
this.clear_tag = false // 将清除标志置否,防止其他模块改动
if (!this.sim_disk_copy) {
this.sim_disk_copy = JSON.parse(JSON.stringify(this.simDisk)) // 深拷贝原列表
}
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
if (this.simDisk[i][j] !== '0') {
this.simDisk[i][j] = "" // 清除标签
}
}
}
this.sys_info("清除成功!")
} else {
this.sys_info("正在执行标注任务,无法清除标签")
}
}
show_path_info() {
}
//创建目录项
create_path(path_name:string){
if(this.clear_tag){
const text_list = path_name.split(',')
if(!file_name_set.has(text_list[0])){
if(text_list.length===3 && !isNaN(parseInt(text_list[1])) && !isNaN(parseInt(text_list[2]))){
if(this.check_condition(text_list[0],text_list[1],text_list[2])){
this.save_file(text_list[0],text_list[1],text_list[2])
this.show_files(this.folder_items)
this.sys_info('创建目录成功!')
}
}else{
this.sys_info('请检查输入格式{\'str\',\'int\',\'int\'}')
}
}else{
this.sys_info('文件名重复')
}
}else{
this.sys_info('目前正在执行磁盘修复任务!')
}
}
// 重置功能
reset_path(len:number) {
for (let i = 0; i < 10; i++) {
for (let n = 0; n < 10; n++) {
clearFatMessage(i, n)
clearDiskText(i, n)
clearBlock(i, n)
}
}
clearEmulation()
clearFiles()
file_name_set = new Set()
blocks_label_set = new Set()
this. messages = []
this.sim_fat_copy = null
this.ex_disk_oc = true
this.ex_disk_la = true
this.sim_disk_copy = null
this.block_modi_tag = false
this.block_modi_lb = ''
this.old_key = null
this.fat_modi_num = null
this.fat_modi_tag = false
this.clear_tag = true // 清除标签让标签清理和FAT清理操作互斥
this.check = null // 检查磁盘条件
this.code = null // 当前磁盘块标签字母
this.creating = true // 正在创建的状态
this.simFAT = initialize_simfat() // SimFAT 表初始化
this.simDisk = initialize_simdisk() // SimDisk 区域初始化
this.folder_items = []
this.fat_unique_set = new Set(['0'])
this.default = ''
this.file_label = new Array(0)
this.fat_tags = new Array(len)
this.fat_disks = new Array(len)
this.label_disks = new Array(len)
for (let i = 0; i < len; i++) {
this.fat_tags[i] = new Array(len)
this.fat_disks[i] = new Array(len)
this.label_disks[i] = new Array(len)
for (let j = 0; j < 10; j++) {
this.fat_tags[i][j] = ''
this.fat_disks[i][j] = ''
this.label_disks[i][j] = ''
}
}
this.sys_info('重置成功!')
}
sys_info(message:string) {
if(this.messages.length < 9){
this.messages.unshift(message)
}else{
this.messages.pop()
this.messages.unshift(message)
}
this.messages = [...this.messages]
}
}

View File

@ -0,0 +1,48 @@
//信息提示弹窗
import { InterfaceFile } from './InterfaceFile'
@CustomDialog
export default struct MessageDialog {
controller: CustomDialogController
@Link File:InterfaceFile
build(){
Column({space:5}){
Text(`${this.File.old_key[0]}行${this.File.old_key[1]}列`)
.fontSize(20)
.height(45)
.textAlign(TextAlign.Center)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
TextInput({placeholder:this.File.default})
.fontSize(20)
.height(45)
.placeholderColor(Color.White)
.placeholderFont({size:20, weight:FontWeight.Bold})
.textAlign(TextAlign.Center)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.onChange((value: string) => {
if(this.File.fat_modi_tag) {
this.File.fat_modi_num = value
}
else if (this.File.block_modi_tag) {
this.File.block_modi_lb = value
}
})
Text('确定')
.fontSize(20)
.textAlign(TextAlign.Center)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.onClick(()=>{
this.controller.close()
})
}
.backgroundColor('#00a5df')
.justifyContent(FlexAlign.Center)
.width(500)
.height(150)
}
}

View File

@ -0,0 +1,159 @@
// 第五章
// 编程7.15
// 产生一个FAT表
function create_sim_fat(): string[][] {
let sim_fat: string[][] = [
['00', '01', 'FF', '03', 'FF', '05', '06', '07', '08', '09'],
['0A', '0B', '0C', '0D', '0E', '0F', '10', '11', '12', '13'],
['14', '15', '16', '17', '18', '19', '1A', '1B', '1C', '1D'],
['1E', '1F', '20', '21', '22', '23', '24', '25', '26', '27'],
['28', '29', '2A', '2B', '2C', '2D', '2E', '2F', '30', '31'],
['32', '33', '34', '35', '36', '37', '38', '39', '3A', '3B'],
['3C', '3D', '3E', '3F', '40', '41', '42', '43', '44', '45'],
['46', '47', '48', '49', '4A', '4B', '4C', '4D', '4E', '4F'],
['50', '51', '52', '53', '54', '55', '56', '57', '58', '59'],
['5A', '5B', '5C', '5D', '5E', '5F', '60', '61', '62', '63']
];
return sim_fat;
}
// 恢复文件夹信息根据FAT表
function restore_folder_by_fat(): string[] {
let sim_fat = create_sim_fat(); // 创建模拟的FAT表
let folder_item: string[] = []; // 用于存储文件夹信息的列表
let last_item: Set<number> = new Set(); // 用于跟踪已经处理过的磁盘块
for (let num = 0; num < 100; num++) { // 主循环,用于分析文件个数
let sim_fat_array: string[] = []; // 清除单个文件的磁盘块
let data: number | null = null; // 用于跟踪当前磁盘块
// 寻找下一个可用的磁盘块作为文件的起始磁盘块
for (let ab = 0; ab < 100; ab++) {
let y = ab % 10;
let x = Math.floor(ab / 10);
if (sim_fat[x][y] === 'FF' && !last_item.has(ab)) {
data = ab;
last_item.add(ab);
break;
}
}
if (data === null) {
break;
}
// 遍历链接的磁盘块,构建文件
while (data !== null) {
let x = Math.floor(data / 10);
let y = data % 10;
sim_fat_array.push(sim_fat[x][y]);
let next_data = parseInt(sim_fat[x][y], 16);
// 如果下一个磁盘块是0xFF表示文件结束
if (next_data === 0xFF) {
break;
}
data = next_data;
}
// 构建文件项,并将其添加到文件夹列表
let fileName = `test${num}`;
let filestr = `<${fileName},${sim_fat_array[0]},${sim_fat_array.length + 1}>`;
folder_item.push(filestr);
}
return folder_item;
}
let folder_item = restore_folder_by_fat();
folder_item.forEach(item => console.log(item));
// ————————————————————————————————————————————————————————————————————————————————
// 编程7.16
// 模拟一个虚拟的磁盘扇区
let virtual_sector_data: number[] = Array.from("This is a simulated disk sector.").map(c => c.charCodeAt(0));
// 将数字数组转换为字符串
function decodeToString(data: number[]): string {
return data.map(byte => String.fromCharCode(byte)).join('');
}
// 读取虚拟扇区内容
function read_zero(data: number[]): void {
// 将二进制数据(数字数组)转换为字符串
let sector_content = decodeToString(data);
// 读取并打印扇区内容
console.log(sector_content);
}
// 主程序执行
read_zero(virtual_sector_data);
// ————————————————————————————————————————————————————————————————————————————————
// 编程7.17
// 模拟一个简单的FAT表的二进制数据
let fat_table_data: Uint8Array = new Uint8Array([
0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
]);
// 读取FAT表数据并转换为十六进制编号字符串
function read_fat_table(data: Uint8Array): string {
let hex_values: string[] = []
for (let i = 0; i < data.length; i += 2) {
// 从二进制数据中提取两个字节作为一个FAT项
let fat_entry = (data[i] | (data[i + 1] << 8))
// 将FAT项转换成十六进制编号并添加到列表中
let hex_value = `0x${fat_entry.toString(16).toUpperCase().padStart(4, '0')}`
hex_values.push(hex_value)
}
// 将十六进制编号字符串列表连接为一个输出字符串
let output_string = hex_values.join(' ')
return output_string
}
let output = read_fat_table(fat_table_data)
console.log(output)
// ————————————————————————————————————————————————————————————————————————————————
// 编程7.18
// 模拟文件夹数据
let folder_data: string[] = [
"File1 TXT 07 1B 00 0A 15 21 02 3E 01 00 00 00 0E 00 00 00", // 文件1
"File2 TXT 07 1B 00 0A 15 21 02 3E 01 00 00 00 0F 00 00 00", // 文件2
"Folder1 DIR 07 1B 00 0A 15 21 02 3E 01 00 00 00 10 00 00 00", // 文件夹1
"File3 TXT 07 1B 00 0A 15 21 02 3E 01 00 00 00 12 00 00 00", // 文件3
"Folder2 DIR 07 1B 00 0A 15 21 02 3E 01 00 00 00 14 00 00 00", // 文件夹2
];
// 读取文件夹数据并解析
function read_folder_parse(data: string[]): void {
data.forEach(line => {
// 解析每一行的信息
// 获取文件名前20个字符为文件名使用trim()去掉额外空白字符
let filename = line.substring(0, 20).trim();
// 获取文件类型接下来的11个字符为文件类型使用trim()去掉额外空白字符
let filetype = line.substring(21, 32).trim();
// 获取创建时间接下来的14个字符为创建时间使用trim()去掉额外空白字符
let create_time = line.substring(32, 46).trim();
// 获取修改时间接下来的14个字符为修改时间使用trim()去掉额外空白字符
let update_time = line.substring(46, 60).trim();
// 打印可读信息
console.log("文件名: " + filename);
console.log("类型: " + filetype);
console.log("创建时间: " + create_time);
console.log("修改时间: " + update_time);
});
}
read_folder_parse(folder_data);

View File

@ -0,0 +1,204 @@
// 第一章
// 编程7.1
// 定义文件块数组
let FOLDER_ITEM: any[] = []
let SIM_FAT: string[][] = Array.from({ length: 3 }, () => Array(5).fill("0"))
// 初始化基本数组
export function init_base_array(): string[] {
let xy: number = Math.floor(Math.random() * 101)
let num: number = Math.floor(Math.random() * 28)
let sim_fat_back: string[] = [xy.toString()]
let flag: number = 0
for (let i = 0; i < num; i++) {
xy = Math.floor(Math.random() * 101)
let ab = xy.toString()
if (!sim_fat_back.includes(ab)) {
sim_fat_back.push(ab)
flag += 1
if (sim_fat_back.length === num) {
break
}
}
}
return sim_fat_back
}
// 生成数据块
export function create_file_block(): string[] {
let num = Math.floor(Math.random() * 28) // 取随机数据
const zm: string[] = ['A', 'B', 'C', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] // 定义字母数组
let file_block: string[] = zm.slice(0, num) // 截取数组字符串
return file_block
}
// 生成仿真目录/文件夹
export function create_folder_item(): any[] {
let file_name: string = "测试文件" // 定义文件名称
let xy: number = Math.floor(Math.random() * 101) // 定义100以内的随机数据
let num: number = Math.floor(Math.random() * 28) // 定义字符串标签数组
let folder_item: any[] = [file_name, xy, num] // 定义文件目录项
return folder_item
}
// 仿真磁盘区域
export function create_sim_disk(): string[][] {
const zm: string[] = ['A', 'B', 'C', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] // 定义字母数组
let base_array: string[] = init_base_array() // 初始生成数组
let sim_disk: string[][] = [] // 定义磁盘仿真区域数组
let flag: number = 0 // 定义数组序号
for (let i = 0; i < 10; i++) { // 定义数组序号
let element: string[] = []
for (let j = 0; j < 10; j++) {
let ab: string = i.toString() + j.toString()
if (base_array.includes(ab)) {
element.push(zm[flag])
flag += 1
}
else {
element.push("0")
}
}
sim_disk.push(element)
}
return sim_disk
}
// 仿真文件分配表
export function create_sim_fat(): string[][] {
let sim_fat: string[][] = []
let base_array: string[] = init_base_array() // 初始生成数组
for (let i = 0; i < 10; i++) { // 循环仿真文件分配二维数组
let element: string[] = []
for (let j = 0; j < 10; j++) {
let ab: string = i.toString() + j.toString()
if (base_array.includes(ab)) {
if (base_array.indexOf(ab) + 1 === base_array.length) {
element.push("FF")
} else {
element.push(base_array[base_array.indexOf(ab) + 1])
}
} else {
element.push("0")
}
}
sim_fat.push(element)
}
return sim_fat
}
// 总函数创建
export function createData(): void {
console.log('create_file_block()='+create_file_block()) // 文件块
console.log('create_folder_item()='+create_folder_item()) // 文件目录项
console.log('create_sim_disk()='+create_sim_disk()) // 文件磁盘区域
console.log('create_sim_fat()='+create_sim_fat()) // 仿真文件分配表
}
// ——————————————————————————————————————————————————————————————————————————————————
// 编程7.2
// 统计磁盘空间大小
export function count_sim_fat_size(): void {
let n: number = 0
for (let element of SIM_FAT) {
console.log('element='+element) // 打印每一行的内容
for (let i of element) {
if (i === "0") {
n += 1 // 统计空闲扇区数量
}
}
}
let size: string = (64 * n) + " KB" // 计算总的空闲磁盘空间大小
console.log(size)
}
// ——————————————————————————————————————————————————————————————————————————————————
// 编程7.3
// 创建FAT表
export function create_fat(): string[][] {
let sim_fat_array = init_base_array()
console.log('sim_fat_array='+sim_fat_array)
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
let ab: string = i.toString() + j.toString()
if (sim_fat_array.includes(ab)) {
if (sim_fat_array.indexOf(ab) + 1 === sim_fat_array.length) {
SIM_FAT[i][j] = "FF" // 注意数组越界问题
}
else {
SIM_FAT[i][j] = sim_fat_array[sim_fat_array.indexOf(ab) + 1]
}
}
}
}
return SIM_FAT
}
// ——————————————————————————————————————————————————————————————————————————————————
// 编程7.4
// 定义FAT链表和第一块FAT位置
let sim_fat_chain: { [key: string]: string }[] = [
{ '08': '02' },
{ '02': '56' },
{ '56': '31' },
{ '31': '55' },
{ '55': '67' },
{ '67': '74' },
{ '74': 'FF' }
]
const FIRST_BLOCK: string = '08'
// 获取磁盘块顺序
export function get_disk_block_order(): string[] {
let disk_order: string[] = [FIRST_BLOCK]
let current_block: string = FIRST_BLOCK
while (current_block !== 'FF') {
let next_block: string = null
for (let item of sim_fat_chain) {
if (current_block in item) {
next_block = item[current_block]
break
}
}
if (next_block === null) {
break
}
disk_order.push(next_block)
current_block = next_block
}
return disk_order
}
// ——————————————————————————————————————————————————————————————————————————————————
// 编程7.5
// 插入一个目录项
export function add_folder_item(item: any): any[] {
FOLDER_ITEM.push(item)
return FOLDER_ITEM
}
// 删除一个目录项
export function del_folder_item(item: any): any[] {
const index = FOLDER_ITEM.indexOf(item)
if (index !== -1) {
FOLDER_ITEM.splice(index, 1)
console.log("删除成功")
}
else {
console.log("删除失败,元素不在目录项中")
}
return FOLDER_ITEM
}

View File

@ -0,0 +1,43 @@
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import hilog from '@ohos.hilog';
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}
onDestroy(): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground(): void {
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground(): void {
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
}

View File

@ -0,0 +1,468 @@
import *as CommonConstant from '../common/constants/CommonConstants'
import {drawFatLine,drawFatLabels,drawDiskLabels,draw_blocks_background} from '../utils/functions'
import {InterfaceFile} from '../components/InterfaceFile'
import MessageDialog from '../components/MessageDialog'
import {createData,count_sim_fat_size,create_fat,get_disk_block_order, init_base_array,create_folder_item,add_folder_item,del_folder_item} from '../components/one'
@Entry
@Component
struct Index {
@State File:InterfaceFile=new InterfaceFile(10)
//弹窗控制器
MessageDialogController: CustomDialogController = new CustomDialogController({
builder: MessageDialog({
File: $File
})
})
build() {
Row() {
Column() {
Row() {
Column() {
Row({space:4}) {
Text('输入文件名')
.fontSize(8)
.fontColor(Color.White)
TextInput()
.height(20)
.width(35)
.backgroundColor(Color.White)
.fontColor('#000')
.textAlign(TextAlign.Start)
.align(Alignment.Center)
.fontSize(12)
.borderRadius(0)
.padding({
top: 0
, right: 0
, bottom: 0
, left: 0
})
.onChange((value: string) => {
this.File.file_name_label = value;
})
Text('块数')
.fontSize(8)
.fontColor(Color.White)
TextInput()
.height(20)
.width(35)
.backgroundColor(Color.White)
.fontColor('#000')
.textAlign(TextAlign.Start)
.align(Alignment.Center)
.fontSize(12)
.borderRadius(0)
.padding({
top: 0
, right: 0
, bottom: 0
, left: 0
})
.onChange((value: string) => {
this.File.blocks_num_label = value;
})
Image($r('app.media.createFile'))
.width(30)
.height(15)
.onClick(()=>{
this.File.create_file()
})
Image($r('app.media.save'))
.width(30)
.height(15)
.onClick(()=>{
this.File.save_file()
this.File.show_files(this.File.folder_items)
})
Image($r('app.media.query'))
.width(30)
.height(15)
.onClick(()=>{
this.File.query_file()
})
}
.height(12)
.width('100%')
.margin({top:6,left:5})
Column() {
// 文字区域
Row() {
Text('初始文件模拟区:')
.fontSize(8)
.fontColor(Color.White)
}
.width('100%')
.height('20%')
.margin({left:5})
// 绘制区域
Column() {
Stack() {
Canvas(CommonConstant.context5) // 初始文件模拟区域
.width('100%')
.height('100%')
.margin({top: 15})
.onReady(() => {
// 方块部分
this.File.creat_file_blocks()
})
}
}
.width('100%')
}
}
.width('47%')
.height('100%')
.margin({top:5,left:10 })
.backgroundImage($r('app.media.pink_bg'))
.backgroundImageSize({width:270, height:140})
// 文件夹(目录)
Column() {
Row({space:2}) {
Text('文件夹(目录)')
.fontSize(8)
.fontColor(Color.White)
TextInput()
.height(20)
.width(60)
.backgroundColor(Color.White)
.fontColor('#000')
.textAlign(TextAlign.Start)
.align(Alignment.Center)
.fontSize(12)
.borderRadius(0)
.padding({
top: 0
, right: 0
, bottom: 0
, left: 0
})
.onChange((value:string)=>{
this.File.path_name_label = value
})
Image($r('app.media.createDirectory'))
.width(50)
.height(20)
.margin({left:5,right:5})
.onClick(()=>{
this.File.create_path(this.File.path_name_label)
})
Image($r('app.media.reset'))
.width(30)
.height(20)
.margin({left:5})
.onClick(()=>{
this.File.reset_path(10)
})
}
.height(12)
.width('100%')
.margin({top:4,left:10})
Column() {
// 文字区域
Row({space:10}) {
Text('文件名')
.fontSize(8)
.fontColor(Color.White)
Text('首块')
.fontSize(8)
.fontColor(Color.White)
Text('块数')
.fontSize(8)
.fontColor(Color.White)
Text('标签')
.fontSize(8)
.fontColor(Color.White)
}
.width('100%')
.height('15%')
.margin({left:5})
// .backgroundColor(Color.Black)
.alignItems(VerticalAlign.Bottom)
// 绘制区域
Row(){
Canvas(CommonConstant.context6) // 初始文件模拟区域
.width('100%')
.height('100%')
// .margin({top: 15})
// .backgroundColor(Color.Black)
.onReady(() => {
// 方块部分
this.File.show_files(this.File.folder_items)
})
}
.width('100%')
.height('75%')
}
.justifyContent(FlexAlign.Center)
}
.width('47%')
.height('100%')
.margin({top:5,left:10 })
.backgroundImage($r('app.media.purple_bg'))
.backgroundImageSize({width:270, height:140})
}
.height('35%')
.width('100%')
Row() {
// 文件分配表FAT
Column() {
Row({space:2}) {
Text('文件分配表FAT')
.fontSize(8)
.fontColor(Color.White)
Image($r("app.media.check1"))
.width(30)
.height(15)
.onClick(()=>{
this.File.fat_checkout()
})
Image($r('app.media.clearFormItem'))
.width(45)
.height(15)
.onClick(()=>{
this.File.clear_fat_label()
})
Image($r('app.media.saveFormItem'))
.width(45)
.height(15)
.onClick(()=>{
this.File.modi_fat_save()
})
Image($r('app.media.changeFormItem'))
.width(45)
.height(15)
.onClick(()=>{
this.File.modi_fat()
})
}
.height(15)
.width('100%')
.margin({top:4,left:5})
Column() {
Stack() {
Canvas(CommonConstant.context) // Fat区域
.width('100%')
.height('100%')
.margin({top: 15})
.onReady(() => {
// Fat区域背景
drawFatLine()
// 数字标签
drawFatLabels()
})
Canvas(CommonConstant.context2) // 文字
.width('100%')
.height('100%')
.margin({top: 15})
.onClick((event)=>{
//计算点击的的画布横纵坐标
let playX = event.x - CommonConstant.gridSize
let playY = event.y - CommonConstant.gridSize
//计算行列数 横纵坐标/格子大小
let row: number = Math.floor(playX / CommonConstant.gridSize)
let col: number = Math.floor(playY / CommonConstant.gridSize)
if (this.File.fat_modi_tag) {
this.File.modi_fat_entry(row, col)
this.File.default = this.File.simFAT[this.File.old_key[0]][this.File.old_key[1]]
this.MessageDialogController.open()
}
})
}
}
.width('100%')
.padding({left:10})
}
.width('47%')
.height('100%')
.margin({top:10,left:10 })
.backgroundImage($r('app.media.jade_blue_bg'))
.backgroundImageSize({width:270, height:240})
// 磁盘模块
Column() {
Row({space:2}) {
Text('磁盘模块')
.fontSize(8)
.fontColor(Color.White)
Image($r("app.media.check2"))
.width(30)
.height(15)
.onClick(()=>{
this.File.disk_checkout()
})
Image(this.File.ex_disk_oc ? $r('app.media.add') : $r("app.media.saveOccupy"))
.width(45)
.height(15)
.onClick(()=>{
if (this.File.ex_disk_oc) {
this.File.ex_disk_oc = false
}
else {
this.File.ex_disk_oc = true
}
if (this.File.ex_disk_oc == false) {
this.File.add_occupy()
}
else {
this.File.save_occupy()
}
})
Image(this.File.ex_disk_la ? $r("app.media.changeLabel") : $r("app.media.saveLabel"))
.width(45)
.height(15)
.onClick(()=>{
if (this.File.ex_disk_la) {
this.File.ex_disk_la = false
}
else {
this.File.ex_disk_la = true
}
if (this.File.ex_disk_la == false) {
this.File.modi_block_lb()
}
else {
this.File.modi_block_save()
}
})
Image($r('app.media.clearLabel'))
.width(45)
.height(15)
.onClick(()=>{
this.File.clear_disk_label()
})
}
.height(12)
.width('100%')
.margin({top:4,left:5})
Column() {
Stack() {
Canvas(CommonConstant.context3) // Disk区域
.width('100%')
.height('100%')
.margin({top: 15})
.onReady(() => {
// 数字标签部分
drawDiskLabels()
// 方块部分
draw_blocks_background()
})
Canvas(CommonConstant.context4) // 编号
.width('100%')
.height('100%')
.margin({top: 5})
.onClick((event)=>{
//计算点击的的画布横纵坐标
let playX = event.x - CommonConstant.blockSize
let playY = event.y - CommonConstant.blockSize
//计算行列数 横纵坐标/格子大小
let row: number = Math.floor(playX / CommonConstant.gridSize)
let col: number = Math.floor(playY / CommonConstant.gridSize)
this.File.add_occupy_click(row, col)
if (this.File.block_modi_tag) {
this.File.modi_block_entry(row, col)
this.File.default = this.File.simDisk[this.File.old_key[0]][this.File.old_key[1]]
this.MessageDialogController.open()
}
})
}
}
.width('100%')
.padding({left:15})
}
.width('47%')
.height('100%')
.margin({top:10,left:10 })
.backgroundImage($r('app.media.sky_blue_bg'))
.backgroundImageSize({width:270, height:240})
}
.height('65%')
.width('100%')
}
.width('80%')
.height('100%')
Column() {
Column() {
Text('系统消息框')
.fontSize(12)
.fontColor(Color.White)
.margin({top:3})
}
.width('100%')
.height('6%')
.margin({top:2})
.backgroundImage($r('app.media.rightbgtop'))
Column() {
ForEach(this.File.messages,message=>{
Text(message)
.fontSize(10).textAlign(TextAlign.Center)
.fontColor(Color.White)
.margin({top:4})
.backgroundImage($r('app.media.messagebg'))
.width('100%')
.height('11%')
})
}
.width('100%')
.height('90%')
.backgroundImage($r('app.media.rightbg'))
}
.width('20%')
.height('100%')
}
.width('100%')
.height('100%')
.backgroundImage($r('app.media.bg2'))
.backgroundImageSize(ImageSize.Cover)
}
}

View File

@ -0,0 +1,198 @@
// 功能函数
import * as CommonConstant from '../common/constants/CommonConstants'
// 初始化FAT矩阵
export function initialize_simfat(): string[][] {
// 创建一个10x10的二维数组每个元素都初始化为字符串 "0"
const simFat: string[][] = Array.from({ length: 10 }, () => Array(10).fill("0"))
simFat[0][0] = "100"; // 将第一个元素(第一行第一列)设置为字符串 "100"
return simFat; // 返回初始化的FAT矩阵
}
// 初始化磁盘矩阵
export function initialize_simdisk(): string[][] {
// 创建一个10x10的二维数组每个元素都初始化为字符串 "0"
const simDisk: string[][] = Array.from({ length: 10 }, () => Array(10).fill("0"))
return simDisk // 返回初始化的磁盘矩阵
}
// 绘制Fat区域线条
export function drawFatLine() {
CommonConstant.context.strokeStyle = '#fff' //线条颜色
CommonConstant.context.lineWidth = 1 //线条宽
for (let i = 0; i < CommonConstant.boardNum; i++) {
// 横线
CommonConstant.context.beginPath()
CommonConstant.context.moveTo(CommonConstant.gridSize, i * CommonConstant.gridSize + CommonConstant.gridSize)
CommonConstant.context.lineTo(CommonConstant.gridSize * (CommonConstant.boardNum - 1) + CommonConstant.gridSize, i * CommonConstant.gridSize + CommonConstant.gridSize)
CommonConstant.context.stroke()
// 竖线
CommonConstant.context.beginPath()
CommonConstant.context.moveTo(i * CommonConstant.gridSize + CommonConstant.gridSize, CommonConstant.gridSize)
CommonConstant.context.lineTo(i * CommonConstant.gridSize + CommonConstant.gridSize, CommonConstant.gridSize * (CommonConstant.boardNum - 1) + CommonConstant.gridSize)
CommonConstant.context.stroke()
}
}
// 绘制Fat区域边框外侧数字
export function drawFatLabels() {
CommonConstant.context.fillStyle = 'white' // 设置文字颜色为白色
CommonConstant.context.font = '25px Arial' // 设置字体和大小
CommonConstant.context.textAlign = 'center' // 设置文字对齐方式为居中
CommonConstant.context.textBaseline = 'middle' // 设置文字基线为居中
// 绘制数字标签
for (let i = 0; i < CommonConstant.boardNum - 1; i++) {
CommonConstant.context.fillText(i.toString(), i * CommonConstant.gridSize + CommonConstant.gridSize + CommonConstant.gridSize / 2, CommonConstant.gridSize / 2) // 上边标签
CommonConstant.context.fillText(i.toString(), CommonConstant.gridSize / 2, i * CommonConstant.gridSize + CommonConstant.gridSize + CommonConstant.gridSize / 2) // 左边标签
}
}
// 绘制Disk区域边框外侧数字
export function drawDiskLabels() {
CommonConstant.context3.fillStyle = 'white' // 设置文字颜色为白色
CommonConstant.context3.font = '25px Arial' // 设置字体和大小
CommonConstant.context3.textAlign = 'center' // 设置文字对齐方式为居中
CommonConstant.context3.textBaseline = 'middle' // 设置文字基线为居中
// 绘制数字标签
for (let i = 0; i < CommonConstant.boardNum - 1; i++) {
CommonConstant.context3.fillText(i.toString(), i * CommonConstant.gridSize + CommonConstant.blockSize * 1.5, CommonConstant.blockSize / 2) // 上边标签
CommonConstant.context3.fillText(i.toString(), CommonConstant.blockSize / 2, i * CommonConstant.gridSize + CommonConstant.blockSize * 1.5) // 左边标签
}
}
//绘制模拟区方块
export function draw_blocks_emulation(x:number,y:number,list_label:string) {
CommonConstant.context5.fillStyle = 'black' // 设置文字颜色为黑色
CommonConstant.context5.font = '20px Arial' // 设置字体和大小
CommonConstant.context5.textAlign = 'center' // 设置文字对齐方式为居中
CommonConstant.context5.textBaseline = 'middle' // 设置文字基线为居中
CommonConstant.context5.clearRect(0,0,x,y+20)
CommonConstant.context5.drawImage(CommonConstant.img3, x, y, CommonConstant.gridSize, CommonConstant.gridSize)
CommonConstant.context5.fillText(list_label, x + CommonConstant.gridSize / 2, y + CommonConstant.gridSize / 2)
CommonConstant.context5.fillStyle = 'white'
CommonConstant.context5.fillText('起始', x + CommonConstant.gridSize / 2, y - CommonConstant.gridSize)
CommonConstant.context5.clearRect(0,0, 210, 40)
CommonConstant.context5.fillText('尾部',x + CommonConstant.gridSize / 2,y - CommonConstant.gridSize/2)
CommonConstant.context5.clearRect(x + CommonConstant.gridSize+2,y - 13, 210, CommonConstant.gridSize/2)
for (let index = 0; index < (230-x)/20; index++) {
CommonConstant.context5.fillText('—', 230-index*4, y - CommonConstant.gridSize/2)
}
CommonConstant.context5.fillText('<',230-(230-x)/5 , y - CommonConstant.gridSize/2)
}
export function clearEmulation(){
CommonConstant.context5.clearRect(0,0,300,300)
}
export function draw_files(text_list:any[]){
CommonConstant.context6.fillStyle = 'white'; // 设置文字颜色为白色
CommonConstant.context6.font = '30px Arial'; // 设置字体和大小
CommonConstant.context6.textAlign = 'center'; // 设置文字对齐方式为居中
CommonConstant.context6.textBaseline = 'middle'; // 设置文字基线为居中
CommonConstant.context6.clearRect(0,0,300,300)
console.log('text_list.length='+text_list.length)
for (let index = 0; index < text_list.length; index++) {
const x = 10
const y = 10
CommonConstant.context6.fillText(text_list[index][0],x,y+index*20)
CommonConstant.context6.fillText(text_list[index][1],x+30,y+index*20)
CommonConstant.context6.fillText(text_list[index][2],x+60,y+index*20)
CommonConstant.context6.fillText(text_list[index][3],x+90,y+index*20)
}
}
export function clearFiles(){
CommonConstant.context6.clearRect(0,0,300,300)
}
// 绘制Disk区域初始方块
export function draw_blocks_background() {
for (let row = 0; row < CommonConstant.boardNum - 1; row++) {
for (let col = 0; col < CommonConstant.boardNum - 1; col++) {
const x = col * CommonConstant.gridSize + CommonConstant.blockSize
const y = row * CommonConstant.gridSize + CommonConstant.blockSize
CommonConstant.context3.clearRect(x,y, CommonConstant.blockSize, CommonConstant.blockSize)
CommonConstant.context3.drawImage(CommonConstant.img1, x, y, CommonConstant.blockSize, CommonConstant.blockSize)
}
}
}
// 绘制Disk区域方块
export function draw_blocks(row:number, col:number, color_tag:boolean) {
const x = col * CommonConstant.gridSize + CommonConstant.blockSize
const y = row * CommonConstant.gridSize + CommonConstant.blockSize
CommonConstant.context3.clearRect(x,y, CommonConstant.blockSize, CommonConstant.blockSize)
if (color_tag) {
CommonConstant.context3.drawImage(CommonConstant.img3, x, y, CommonConstant.blockSize, CommonConstant.blockSize)
}
else {
CommonConstant.context3.drawImage(CommonConstant.img2, x, y, CommonConstant.blockSize, CommonConstant.blockSize)
}
}
export function drawFatMessage(num: string, row: number, clown: number) {
CommonConstant.context2.fillStyle = 'white' // 设置文字颜色为白色
CommonConstant.context2.font = '20px Arial' // 设置字体和大小
CommonConstant.context2.textAlign = 'center' // 设置文字对齐方式为居中
CommonConstant.context2.textBaseline = 'middle' // 设置文字基线为居中
const x = clown * CommonConstant.gridSize + 1.5 * CommonConstant.gridSize
const y = row * CommonConstant.gridSize + 1.5 * CommonConstant.gridSize
CommonConstant.context2.fillText(num, x, y)
}
export function clearFatMessage(row: number, clown: number) {
const x = clown * CommonConstant.gridSize + CommonConstant.gridSize
const y = row * CommonConstant.gridSize + CommonConstant.gridSize
CommonConstant.context2.clearRect(x, y, CommonConstant.gridSize, CommonConstant.blockSize)
}
export function drawDiskText(text: string, row: number, clown: number) {
CommonConstant.context4.fillStyle = 'black' // 设置文字颜色为白色
CommonConstant.context4.font = '20px Arial' // 设置字体和大小
const x = clown * CommonConstant.gridSize + CommonConstant.gridSize
const y = row * CommonConstant.gridSize + 2 * CommonConstant.blockSize
CommonConstant.context4.clearRect(x,y, CommonConstant.gridSize, CommonConstant.gridSize)
CommonConstant.context4.fillText(text, x, y)
}
export function clearBlock(row: number, col: number) {
const x = col * CommonConstant.gridSize + CommonConstant.blockSize;
const y = row * CommonConstant.gridSize + CommonConstant.blockSize;
CommonConstant.context3.clearRect(x,y, CommonConstant.blockSize, CommonConstant.blockSize)
CommonConstant.context3.drawImage(CommonConstant.img1, x, y, CommonConstant.blockSize, CommonConstant.blockSize)
}
export function clearDiskText(row: number, col: number) {
const x = col * CommonConstant.gridSize + CommonConstant.gridSize;
const y = row * CommonConstant.gridSize + CommonConstant.gridSize;
CommonConstant.context4.clearRect(x,y, CommonConstant.gridSize, CommonConstant.gridSize)
}
export function read_sim_fat(first_block: string, sim_fat: string[][]): string[] {
const block_nums: Array<string> = []; // 创建一个空数组来存储块号
block_nums.push(first_block)
while (true) {
const row = Math.floor(parseInt(first_block) / 10);
const clown = parseInt(first_block) % 10;
const b_num = sim_fat[row][clown];
if (b_num !== "FF") {
block_nums.push(b_num) // 添加下一个块号
first_block = b_num // 更新 first_block 以继续查找下一个块
} else {
break; // 如果找到 "FF",则退出循环
}
}
return block_nums
}

View File

@ -0,0 +1,37 @@
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"default",
"tablet"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:icon",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
]
}
}

View File

@ -0,0 +1,8 @@
{
"color": [
{
"name": "start_window_background",
"value": "#FFFFFF"
}
]
}

View File

@ -0,0 +1,16 @@
{
"string": [
{
"name": "module_desc",
"value": "module description"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "label"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 711 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,5 @@
{
"src": [
"pages/Index"
]
}

View File

@ -0,0 +1,16 @@
{
"string": [
{
"name": "module_desc",
"value": "module description"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "label"
}
]
}

View File

@ -0,0 +1,16 @@
{
"string": [
{
"name": "module_desc",
"value": "模块描述"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "label"
}
]
}

View File

@ -0,0 +1,35 @@
import hilog from '@ohos.hilog';
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function abilityTest() {
describe('ActsAbilityTest', () => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
})
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
})
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
})
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
})
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
})
})
}

View File

@ -0,0 +1,5 @@
import abilityTest from './Ability.test';
export default function testsuite() {
abilityTest();
}

View File

@ -0,0 +1,50 @@
import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
import hilog from '@ohos.hilog';
import { Hypium } from '@ohos/hypium';
import testsuite from '../test/List.test';
import window from '@ohos.window';
import Want from '@ohos.app.ability.Want';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
export default class TestAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate');
hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? '');
hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? '');
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator;
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs;
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments();
hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!');
Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite);
}
onDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage) {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate');
windowStage.loadContent('testability/pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s',
JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy');
}
onForeground() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground');
}
onBackground() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground');
}
}

View File

@ -0,0 +1,17 @@
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}

View File

@ -0,0 +1,47 @@
import hilog from '@ohos.hilog';
import TestRunner from '@ohos.application.testRunner';
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
import Want from '@ohos.app.ability.Want';
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator | undefined = undefined
let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs | undefined = undefined
async function onAbilityCreateCallback() {
hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback');
}
async function addAbilityMonitorCallback(err : Error) {
hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? '');
}
export default class OpenHarmonyTestRunner implements TestRunner {
constructor() {
}
onPrepare() {
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare ');
}
async onRun() {
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run');
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
const bundleName = abilityDelegatorArguments.bundleName;
const testAbilityName = 'TestAbility';
let lMonitor: AbilityDelegatorRegistry.AbilityMonitor = {
abilityName: testAbilityName,
onAbilityCreate: onAbilityCreateCallback,
};
abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
const want: Want = {
bundleName: bundleName,
abilityName: testAbilityName
};
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
abilityDelegator.startAbility(want, (err, data) => {
hilog.info(0x0000, 'testTag', 'startAbility : err : %{public}s', JSON.stringify(err) ?? '');
hilog.info(0x0000, 'testTag', 'startAbility : data : %{public}s',JSON.stringify(data) ?? '');
})
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end');
}
}

View File

@ -0,0 +1,37 @@
{
"module": {
"name": "entry_test",
"type": "feature",
"description": "$string:module_test_desc",
"mainElement": "TestAbility",
"deviceTypes": [
"default",
"tablet"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:test_pages",
"abilities": [
{
"name": "TestAbility",
"srcEntry": "./ets/testability/TestAbility.ets",
"description": "$string:TestAbility_desc",
"icon": "$media:icon",
"label": "$string:TestAbility_label",
"exported": true,
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"skills": [
{
"actions": [
"action.system.home"
],
"entities": [
"entity.system.home"
]
}
]
}
]
}
}

View File

@ -0,0 +1,8 @@
{
"color": [
{
"name": "start_window_background",
"value": "#FFFFFF"
}
]
}

View File

@ -0,0 +1,16 @@
{
"string": [
{
"name": "module_test_desc",
"value": "test ability description"
},
{
"name": "TestAbility_desc",
"value": "the test ability"
},
{
"name": "TestAbility_label",
"value": "test label"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -0,0 +1,5 @@
{
"src": [
"testability/pages/Index"
]
}

View File

@ -0,0 +1,5 @@
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}

View File

@ -0,0 +1,33 @@
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function localUnitTest() {
describe('localUnitTest',() => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
});
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
});
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
});
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
});
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
});
});
}

View File

@ -0,0 +1,18 @@
{
"hvigorVersion": "3.0.9",
"dependencies": {
"@ohos/hvigor-ohos-plugin": "3.0.9"
},
"execution": {
// "daemon": true, /* Enable daemon compilation. Default: true */
// "incremental": true, /* Enable incremental compilation. Default: true */
// "parallel": true, /* Enable parallel compilation. Default: true */
// "typeCheck": false, /* Enable typeCheck. Default: false */
},
"logging": {
// "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */
},
"debugging": {
// "stacktrace": false /* Disable stacktrace compilation. Default: false */
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
import { appTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
}

View File

@ -0,0 +1,48 @@
#!/bin/bash
# ----------------------------------------------------------------------------
# Hvigor startup script, version 1.0.0
#
# Required ENV vars:
# ------------------
# NODE_HOME - location of a Node home dir
# or
# Add /usr/local/nodejs/bin to the PATH environment variable
# ----------------------------------------------------------------------------
HVIGOR_APP_HOME="`pwd -P`"
HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js
warn() {
echo ""
echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
}
error() {
echo ""
echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
}
fail() {
error "$@"
exit 1
}
# Determine node to start hvigor wrapper script
if [ -n "${NODE_HOME}" ];then
EXECUTABLE_NODE="${NODE_HOME}/bin/node"
if [ ! -x "$EXECUTABLE_NODE" ];then
fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed"
fi
else
EXECUTABLE_NODE="node"
which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path"
fi
# Check hvigor wrapper script
if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then
fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}"
fi
# start hvigor-wrapper script
exec "${EXECUTABLE_NODE}" \
"${HVIGOR_WRAPPER_SCRIPT}" "$@"

View File

@ -0,0 +1,64 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Hvigor startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js
set NODE_EXE=node.exe
goto start
:start
@rem Find node.exe
if defined NODE_HOME goto findNodeFromNodeHome
%NODE_EXE% --version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
echo.
echo Please set the NODE_HOME variable in your environment to match the
echo location of your NodeJs installation.
goto fail
:findNodeFromNodeHome
set NODE_HOME=%NODE_HOME:"=%
set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE%
if exist "%NODE_EXE_PATH%" goto execute
echo.
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
echo.
echo Please set the NODE_HOME variable in your environment to match the
echo location of your NodeJs installation.
goto fail
:execute
@rem Execute hvigor
"%NODE_EXE%" "%WRAPPER_MODULE_PATH%" %*
if "%ERRORLEVEL%" == "0" goto hvigorwEnd
:fail
exit /b 1
:hvigorwEnd
if "%OS%" == "Windows_NT" endlocal
:end

View File

@ -0,0 +1,13 @@
{
"lockfileVersion": 1,
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
"specifiers": {
"@ohos/hypium@1.0.11": "@ohos/hypium@1.0.11"
},
"packages": {
"@ohos/hypium@1.0.11": {
"resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.11.tgz",
"integrity": "sha512-KawcLnv43C3QIYv1UbDnKCFX3MohtDxGuFvzlUxT/qf2DBilR56Ws6zrj90LdH6PjloJQwOPESuBQIHBACAK7w=="
}
}
}

View File

@ -0,0 +1,12 @@
{
"license": "",
"devDependencies": {
"@ohos/hypium": "1.0.11"
},
"author": "",
"name": "filereality",
"description": "Please describe the basic information.",
"main": "",
"version": "1.0.0",
"dependencies": {}
}