收藏 分销(赏)

模拟二级文件管理系统.doc

上传人:快乐****生活 文档编号:4814386 上传时间:2024-10-13 格式:DOC 页数:20 大小:433.50KB 下载积分:10 金币
下载 相关 举报
模拟二级文件管理系统.doc_第1页
第1页 / 共20页
模拟二级文件管理系统.doc_第2页
第2页 / 共20页


点击查看更多>>
资源描述
青岛理工大学 操作系统课程设计报告 院(系): 计算机工程学院 专 业: 计算机科学与技术专业 学生姓名: OOOOOO __ 班级: OOOOOOO 学号: OOOOOOOOO 题目: __ 模拟二级文件管理系统 起迄日期: 设计地点: 指 导 教 师: OOOOOOO 一. 课程设计目的 通过研究Linux的文件系统结构,模拟设计一个简单的二级文件系统,第一级为主目录文件,第二级为用户文件。 进行操作系统课程设计主要是在学习操作系统课程的基础上,在完成操作系统各部分实验的基础上,对操作系统的整体进行一个模拟,通过实践加深对各个部分的管理功能的认识,还能进一步分析各个部分之间的联系,最后达到对完整系统的理解。同时,可以提高运用操作系统知识解决实际问题的能力;锻炼实际的编程能力、创新能力及团队组织、协作开发软件的能力;还能提高调查研究、查阅技术文献、资料以及编写软件设计文档的能力。 二. 课程设计内容与要求 1. 设计要求 1) 运行时根据输入的用户数目创建主目录 2) 设定一个超级用户,可以查看整个二级文件系统结构 3) 普通用户只能根据自己的用户名与密码访问自己的文件与共享的文件 4) 能够实现下列命令: Login 用户登录;Dir 列文件目录;Create 创建文件;Delete 删除文件 Open 打开文件;Close 关闭文件;Read 读文件;Write 写文件 5) 系统能检查键入命令的正确性,出错时应能显示出错原因 6) 创建文件时需设定文件保护码的内容 7) 列目录时要列出文件目录、文件名、保护码(只执行、只读、只写、共享)和文件长度 8) 不允许对打开的文件执行重复打开操作或执行删除操作 9) 对于共享文件,除了文件的创建者,其他人只有查看权,不能进行写入与删除操作 10) 对于文件的越权操作,要有相应的错误提示 2. 设计内容 采用二级目录结构时,第一级为主文件目录MFD,第二级为用户文件目录UFD。假定系统可同时管理N个用户的文件,每个用户最多在磁盘上保存L个文件。约定用户把文件都组织成记录式文件,文件中每个记录都是定长的,文件在磁盘上的组织形式为链接结构。 用户名 用户文件目录 文件名 文件属性 记录长度 文件地址 整个系统只有一张主文件目录表,但有N张用户文件目录表。用户文件目录UFD中的“文件属性”规定文件的使用权限为“只执行”、“只读”、“只写”、“共享”,指组成该文件的逻辑记录长度,“文件地址”指文件存放在磁盘上的首块地址。 设计用户创建、用户删除、文件创建、文件删除、写文件、读文件等函数,对这个数据结构进行处理,并作出交互式界面。 三. 系统分析与设计 1. 系统分析 本次设计的“模拟二级文件管理系统”利用的是二级目录管理方式,分别由用户文件目录UFD(User File Directory)、主文件目录MFD(Master File Directory)构成。其中UFD由用户的所有文件块组成,在MFD中每个用户目录文件占用一个目录项,其中目录项中包含用户名、用户密码以及指向用户文件目录文件链表的指针。 用户文件目录项的基本信息包括基本信息、地址信息、访问控制信息、使用信息。 基本信息:文件名、文件属性(共享、只读、只写、只执行) 地址信息:文件长度(文件可容纳数据的最大量)、存放位置(在虚拟磁盘中的起始位置) 使用信息:文件使用状态(打开、关闭) 文件系统中文件管理的基本操作: 创建文件:创建一个新文件时,系统首先要为新文件申请必要的外存空间,并在用户文件目录UFD中为文件分配一个目录项。目录项中应记录新建文件的文件名、文件总容量、当前已经使用的容量、文件属性、文件在磁盘中的起始位置。 删除文件:当已不在需要某文件时,可将它从文件系统中删除。在删除时,首先在UFD的文件链表中找到与该文件对应的文件结点,然后确认文件是否处于关闭状态,若以上条件都满足,则系统就可以把结点从文件链表中删除,然后回收改结点对应的磁盘空间。 打开文件:只有处于打开状态的文件才能被读取、写入、重复关闭且不能被删除。 关闭文件:只有处于关闭状态的文件才能被删除,且不能被重复关闭。 列文件目录:普通用户只能获取自己建立的文件或其他用户共享的文件的列表;超级用户(管理员)可以查看所用户建立的文件列表。 写文件:用户可以把相关数据写入到用户自定义的文件中(磁盘上);待写文件必须处于打开状态,且不能是其他用户共享的文件。 读文件:用户可以把文件中存储的数据读取出来;待读文件必须处于打开状态;用户既可以读取自己建立的文件,也可以读取其他用户共享的文件。 文件系统中用户管理的基本操作: 创建用户:用户可以创建自己的账号,用户名、密码长度均不能超过10个字符。 用户登录:用户可以以普通用户身份登录,也可以作为管理员身份登录;若登录时输入的密码有误,最大重试次数为3次,若连续错误三次,管理系统会自动退出。 2. 系统设计 2.1 模块设计 WinMain() DialogProc_MAIN(主程对话框初始化) (WM_INITDIALOG) DialogProc_LOGIN (用户登录对话框过程) UserCreate (用户创建过程) Login (用户登录过程) InitDisk (磁盘初始化) DialogProc_MAIN(主程序对话框过程) Logout() (用户注销) FileCreate() (创建文件) FileDelete() (删除文件) FileOpen() (打开文件) FileClose() (关闭文件) FileWrite() (写文件) FileRead() (读文件) FileDir() (列文件目录) 根据用户在主程序界面点击的按钮触发不同的函数执行。 2.2 数据结构说明 typedef struct _DiskTable //磁盘块结构体 { int maxlength; int start; int useFlag; struct _DiskTable *next; }DiskNode, *DiskHead; /* 文件块数据结构 */ typedef struct _FileTable { TCHAR FileName[10]; int strat; //文件在磁盘存储空间的起始地址 int length; //文件内容长度 int maxlength; //文件的最大长度 TCHAR FileKind[3]; //文件的属性——读写方式 //struct tm *timeinfo; BOOL openFlag; //判断是否有进程打开了该文件 //struct _fileTable *next; }FileTable; /* 两级目录数据结构: 用户文件目录文件UFD */ typedef struct _UserFileDirectory { FileTable *FileLink; struct _UserFileDirectory *next; }UFD; /* 两级目录数据结构: 主文件目录MFD */ typedef struct _MasterFileDirectory { TCHAR UserName[MAX_USERNAME_PWD_LENGTH]; //用户名 TCHAR Password[MAX_USERNAME_PWD_LENGTH]; //密码 UFD *CurrentUserFileDirectory; //用户目录链表 }MFD; 2.3 算法流程图 (1) 程序整体结构框图 开始 初始化磁盘 MFD中有该用户? 登录/注册? 注册新用户 注册 登录 分析命令 Y 显示:无此用户 N 创建 文件 打开 文件 关闭 文件 读文件 写文件 列文件 目录 删除 文件 注销 用户 退出系统 end 提示错误 指令成功 执行? Y N 框图1:程序整体框架 (2) 建立文件流程框图 框图2:建立文件流程图 开始 查找该用户的MFD UFD中有该文件? 在UFD中的文件分配表中登记新文件项 在文件项中记录长度、文件属性、文件名、文件起始位置、文件打开标记 找一块磁盘空闲块,将其标记为已使用 显示:“建立”成功 返 回 显示:同名文件不能建立 修改全局磁盘数据结构: 1.修改硬盘未用空间的起始地址 2.修改硬盘剩余的空间大小 N Y (3) 打开文件流程框图 框图3:打开文件流程图 开始 在用户的UDF中查找文件 文件为“打开”状态? 错误提示:文件已打开 设置文件打开标记为FALSE 返回 用户文件存在? 错误提示:文件不存在 Y (4)写文件流程框图 上开始 从用户UFD中查找待写入的文件 文件已打开? 根据文件目录表中记录的文件起始地址,把数据写入到虚拟磁盘中。 文件存在? 返回 错误提示:文件未打开 错误提示:文件不存在 N Y N 文件长度够大? 错误提示: 文件长度不够 N Y 框图4:写文件流程框图 四. 系统测试与调试分析 1. 系统测试 测 试 说 明 测试名称 模拟二级文件管理系统程序 测试目的 验证系统对于系统登录的处理流程 测试技术 单元测试 测试方法 黑盒测试法 测 试 用 例 测试内容 用户登录功能——用户名 测试步骤 输入正确的用户名与密码 输入正确用户名与错误密码 输入错误用户名与密码 测试数据 Admin, 正确密码 Admin,错误密码 错误用户名、密码 预期结果 正常进入系统 显示密码错误,并提示重试 显示用户不存在 测试结果 与预期相符 与预期相符 与预期相符 测 试 说 明 测试名称 模拟二级文件管理系统程序 测试目的 验证系统对于文件管理的处理流程 测试技术 单元测试 测试方法 黑盒测试法 测 试 用 例 测试内容 文件管理功能——创建文件 测试步骤 输入文件名,正常文件大小 输入文件名,超过磁盘容量大小的文件长度 测试数据 FILE, 300 FILE, 99999999999 预期结果 提示创建成功 提示错误:试图创建一个超大文件 测试结果 与预期相符 与预期相符 测 试 说 明 测试名称 模拟二级文件管理系统程序 测试目的 验证系统对于文件管理的处理流程 测试技术 单元测试 测试方法 黑盒测试法 测 试 用 例 测试内容 文件管理功能——打开文件 测试步骤 打开不存在的文件 打开存在的且处于关闭状态的文件 打开已经处于打开状态的文件 测试数据 FILE999 FILE1 FILE1 预期结果 提示未找到文件 提示打开文件成功 提示文件已打开 测试结果 与预期相符 与预期相符 与预期相符 测 试 说 明 测试名称 模拟二级文件管理系统程序 测试目的 验证系统对于文件管理的处理流程 测试技术 单元测试 测试方法 黑盒测试法 测 试 用 例 测试内容 文件管理功能——关闭文件 测试步骤 关闭不存在的文件 关闭存在的且处于打开状态的文件 关闭已经处于关闭状态的文件 测试数据 FILE999 FILE1 FILE1 预期结果 提示未找到文件 提示文件关闭成功 提示文件已关闭 测试结果 与预期相符 与预期相符 与预期相符 测 试 说 明 测试名称 模拟二级文件管理系统程序 测试目的 验证系统对于文件管理的处理流程 测试技术 单元测试 测试方法 黑盒测试法 测 试 用 例 测试内容 文件管理功能——列文件目录 测试步骤 以普通用户A身份列举文件目录 以超级用户身份查看整个二级文件系统结构 测试数据 用户A创建FILE文件,用户B创建FILE2文件(共享属性) 用户A创建FILE文件,用户B创建FILE2文件(共享属性) 预期结果 列出用户自己创建的文件,以及其它用户共享的文件 列出所有用户建立的所有文件 测试结果 与预期相符 与预期相符 测 试 说 明 测试名称 模拟二级文件管理系统程序 测试目的 验证系统对于文件管理的处理流程 测试技术 单元测试 测试方法 黑盒测试法 测 试 用 例 测试内容 文件管理功能——删除文件 测试步骤 删除自己建立的处于关闭状态的文件 删除自己建立的处于打开状态的文件 删除别人共享的文件或不存在的文件 测试数据 FILE USERFILE FILE9878 预期结果 提示删除成功 提示该文件已被进程打开 提示文件不存在或试图删除别人共享的文件 测试结果 与预期相符 与预期相符 测 试 说 明 测试名称 模拟二级文件管理系统程序 测试目的 验证系统对于文件管理的处理流程 测试技术 单元测试 测试方法 黑盒测试法 测 试 用 例 测试内容 文件管理功能——写文件 测试步骤 向不存在的文件里写字符串 向已关闭的文件里写字符串 向已打开的文件里写超出文件最大长度的字符串 向已打开的文件里写小于文件最大长度的字符串 测试数据 FILE9676 USERFILE FILETEST, I’M BEST FILETEST2,I’M BEST! 预期结果 提示文件不存在 提示文件未打开,写入失败 提示超出文件最大长度 提示写入成功 测试结果 与预期相符 与预期相符 与预期相符 与预期相符 2. 调试分析 文件管理——创建文件: 程序通过EDIT控件获取用户输入的文件长度,然后将其转换到整型变量INT中,起初测试时发现,如果输入的数据超过INT型变量所能表达的范围,本应该提示文件太大不能创建,但发现会创建出长度为0的文件。经调试发现:若超出INT型范围,则变量就会被赋值0,且文件长度为0的文件在程序中是允许被创建的,导致产生了BUG。经过改进,禁止用户创建长度为0的文件,也避免了超出INT型范围大小的文件。 这个错误提醒我,在以后的程序设计中,要充分考虑到各种可能会发生的情况。 五. 用户手册 1. 使用平台 最低系统要求:Windows XP 2. 用户注册、登录 在“用户登录”对话框中的“操作选项”里,选择“用户注册”,然后在用户名、密码栏里填入需要注册的用户名以及密码。 在“用户登录”对话框中的“操作选项”里,选择“用户登录”,然后在用户名、密码栏里填入的已经成功注册的用户信息。 注意:超级用户的账号、密码分别为 Admin Admin 图表 1 创建用户USER1 图表 2 以超级用户身份登录系统 3. 注销当前用户 在程序主界面的“文件系统操作”中点击“注销当前用户”按钮,即可注销当前用户,用户可以在登录窗口中注册新的用户或者用已存在的账号登录。 图表 3 注销当前用户按钮 图表 4 用户重新登录界面 4. 列文件目录 管理系统中的“列文件目录”,可以在文件列表框控件中列出当前用户创建的文件的所有信息。 只有超级管理员可以查看所有用户建立的二级文件系统结构。(非管理员登录时,“列文件目录”对话框中的“查看整个二级文件系统结构”按钮会处于不可用状态)。 图表 5 当前用户创建的文件信息 图表 6 “列文件目录”对话框 5. 打开文件、关闭文件 管理系统中的“打开文件”、“关闭文件”选项可以控制用户所创建的文件的“打开\关闭”状态。 在“打开文件”或“关闭文件”对话框中的文本框中输入待打开、关闭文件的文件名,然后点击确定按钮,即可打开、关闭文件。 注意:不能重复打开已处于“打开”状态的文件;不能删除已处于“打开”状态的文件。 图表 7 打开文件对话框 图表 8 关闭文件对话框 6. 创建文件 在主程序界面中点击“创建文件”按钮,在随后弹出的“创建文件”对话框中设置待创建文件的各种属性。 文件名:任意字符,最大长度10个字符 密码:任意字符,最大长度10个字符 文件属性:只执行、只写、只读、共享 7. 删除文件 在主程序界面中点击“删除文件”按钮,在随后弹出的“删除文件”对话框中,填入待删除文件的名字,然后点击确定按钮。 注意:不能删除处于“打开”状态的文件; 不能删除其他用户所创建的共享文件(其他用户创建的共享文件在列文件目录的时候也会一并列出来)。 图表 9 创建文件对话框 图表 10 删除文件对话框 8. 读取文件、写文件 若要在建立的文件中写入内容,可以在主程序窗口的“文件内容输入”区输入待写入内容的文件的名字及内容,然后点击“写文件”按钮。 若要读取文件中的内容,可在“文件内容输出”区填入文件名,然后点击“读文件”按钮。相应的文件内容就会显示在右边的文本框中。 注意:只能写已处于打开状态的文件; 只能读取已处于打开状态的文件; 图表 11 写入FILE_TEST文件 图表 12 读取FILE_TEST文件 六. 程序清单 1. 创建文件函数 BOOL FileCreate(TCHAR *FileName, int Length, TCHAR *FileKind) { /* 判定文件是是不是过大或者为0 */ if (Length == 0){ MessageBox(…,TEXT("您试图创建总长度为零的文件!\n或者您试图创建一个超大文件!"),…); return FALSE; } /* 判定是否有重名文件 */ for(p=UserTable[CurrentLoginUserID].CurrentUserFileDirectory; p!=NULL; p=p->next){ if(!lstrcmp(p->FileLink->FileName, FileName)){ MessageBox(…,TEXT("文件重名,创建文件失败!"), TEXT("错误!"),…); return FALSE; } } if((retVal = RequestDisk(&startPos, Length))){ /* 创建新的用户文件目录结点 */ NewFileNode=(UFD *)malloc(sizeof(UFD)); NewFileNode->FileLink = (FileTable *)malloc(sizeof(FileTable)); /* 设置结点值 */ lstrcpy(NewFileNode->FileLink->FileName, FileName); ………… //设置文件名、文件属性、文件当前长度(未使用时为0)、文件最大长度(用户申请的空间大小) ………… //设置文件在虚拟磁盘上的起始位置、文件打开标记 /* 把新的结点链到用户文件目录链表结尾 */ if(UserTable[CurrentLoginUserID].CurrentUserFileDirectory == NULL){ UserTable[CurrentLoginUserID].CurrentUserFileDirectory = NewFileNode; } else { p = UserTable[CurrentLoginUserID].CurrentUserFileDirectory; while(p->next)p = p->next; p->next = NewFileNode; }MessageBox(…,TEXT("创建文件成功!"), TEXT("操作成功!"),…); } else{ MessageBox(…,TEXT("磁盘空间已满或所创建文件超出磁盘空闲容量!"),…); return FALSE;} return TRUE; } 2. 磁盘空间申请函数 BOOL RequestDisk(int *UsableStartPostion, int RequestMaxLength) { while(tmpPointer) if(tmpPointer->useFlag==0&&tmpPointer->maxlength>RequestMaxLength){ *UsableStartPostion = tmpPointer->start; /* 创建新的磁盘结点 */ tmpDiskNode = (DiskHead)malloc(sizeof(DiskNode)); tmpDiskNode->start = tmpPointer->start; ………… //设置磁盘最大长度:用户申请的长度、设置磁盘使用标记(已使用) ………… //修改磁盘数据结构: 1. 磁盘可用空间起始地址 2.磁盘剩余空间的大小 LocalDiskHead->start = tmpPointer->start+RequestMaxLength; LocalDiskHead->maxlength = tmpPointer->maxlength - RequestMaxLength; /* 核心: 把新的磁盘结点追加到磁盘链表最后 */ if(LocalDiskHead->next == NULL)LocalDiskHead->next = tmpDiskNode; else{ while(IndexPoint->next)IndexPoint = IndexPoint->next; IndexPoint->next = tmpDiskNode;}break; }tmpPointer = tmpPointer->next; } return retVal; } 3. 写文件函数 BOOL FileWrite(HWND hwndDlg, TCHAR *FileName) { q=UserTable[CurrentLoginUserID].CurrentUserFileDirectory; for(p=q; p!=NULL; p=p->next)if(!lstrcmp(p->FileLink->FileName, FileName))break; if(p)/* 判断是否找到了文件 */ { /* 只有具有只写属性的文件才能读写 */ if(lstrcmp(p->FileLink->FileKind, TEXT("只写")) != 0){ MessageBox(……,TEXT("该文件不可写, 写入失败!"),……); return FALSE;} /* 若文件是关闭状态,则不允许写 */ if (p->FileLink->openFlag == FALSE){ MessageBox(……,TEXT("文件未打开, 写入失败!"),……);return FALSE;} /* 1. 获取用户输入 2. 判定数据长度是否越界*/ if(p->FileLink->length > p->FileLink->maxlength){ MessageBox(……,TEXT("写入字符串长度大于该文件的总长度,写入失败!"),…….); return FALSE;} /* 把数据写入虚拟硬盘,文件的起始地址与硬盘的起始地址相对应 */ for(i=startPos,k=0; k<(int)lstrlen(szStringInput); i++,k++){ LocalHardDisk[i] = szStringInput[k];} } else{/* 没有找到文件,提示错误 */ MessageBox(……TEXT("没有找到该文件,请检查输入的文件名是否正确!"),……); return FALSE;}return TRUE; } 4. 创建用户函数 BOOL UserCreate(HWND hwndDlg, HWND *hwndArray) { if (CurrentUserNums < MaxUser) {/* 处理用户名重复问题 */ for(loopcnt=0; loopcnt<CurrentUserNums; loopcnt++){ if(!lstrcmp(UserTable[loopcnt].UserName, UserName)){ MessageBox(……,TEXT("该用户名已存在,创建用户失败!"),……);return FALSE;} } /* 保存用户设置的密码 */ lstrcpy(UserTable[CurrentUserNums].Password, UserPwd); /* 初始化用户文件链表,置为空 */ UserTable[CurrentUserNums].CurrentUserFileDirectory = NULL; /* 增加当前存在用户数目变量值 */ CurrentUserNums++; } else{/* 人数已达上限 */ MessageBox(…TEXT("创建用户失败,用户已达到上限!"),…); returnFALSE;} return TRUE;} 七. 体会与自我评价 经过二个星期的上机实践学习,使我对操作系统这门课程有了更进一步的认识和了解,要想学好它重要在实践,要通过不断的上机操作才能更好地学习它,通过实践,我也发现了我的好多不足之处,首先是SDK编程基础没有打好,一些基本常识性的东西都忘了,再有操作时有很多比较生疏的东西,虽然在学习课本知识时感觉什么东西都很简单,但真正操作起来确实是如此之难。通过实践,是我在这几个方面的认识有所提高。通过实践的学习,我认识到学好计算机要重视实践操作,不仅仅是学习操作系统,还是其它的课程,以及其它的计算机方面的知识都要重在实践,所以以后再学习过程中,我会更加注重实践操作,使自己更好地学好计算机。回顾起此次操作系统课程设计,感触颇多,从选题到定稿,从理论到实践,再整整2个星期的日子里,可以说是苦多于甜,但是可以学到很多很多的东西,同时不仅可以工具了以前所学过的知识,而且学到了很多在书本上所没有学过的知识。 在做本次课程设计的过程中,我感触最深的当属查阅大量的设计资料了。为了让自己的设计更加完善,查阅这方面的资料是十分必要的,同时也是不可缺少的。在用SDK实现LISTVIEW控件用户界面时,遇到了不小的困难,但是通过网络、通过MSDN,终于解决了问题。 其次,在这次课程设计中,我们运用了以前所学的专业课知识,如:数据结构、C语言等。虽然过去独立应用它们的机会很少,但是在学习的过程中带着问题去学我发现效率很高,这是我做这次课程设计的又一收获。以后,要做好一个课程设计,就必须做到:在设计程序之前,对所有操作系统的知识有一个整体的认识,要有一个清晰的设计思路和一个比较完整的软件流程图;在设计程序时,不能妄想一次就将整个程序设计好,反复修改、不断改进是程序设计的必经之路;要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现的功能,而应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方便; 觉得课程设计反映的是一个从理论到实际应用的过程,但是更远一点可以联系到以后毕业之后从学校踏上社会的一个过程。 八. 参考文献 [1] 屠立德.计算机操作系统基础. 北京:清华大学出版社 [2] 申利民. 操作系统常见题解析及模拟题.北京:国防工业出版社.2004 [3] 申利民,何海涛等.操作系统课程设计指导书. 燕山大学课程与教材建设项目,2007 [4] 汤子瀛 编著,《计算机操作系统(修订版)》,西安电子科技大学出版社,2001年 [5] 陆丽娜,齐勇主编,计算机操作系统原理与技术,西安:西安交通大学出版社,1995 [6] 李大友主编,操作系统,北京:机械工业出版社,2000 [7] 王万森等. 计算机操作系统原理. 北京: 高等教育出版社, 2001 [8] 刘坤起. 操作系统学习辅导与习题详解. 北京: 电子工业出版社, 2003 [9] 孙钟秀等编著,操作系统教程,高等教育出版社,2003 [10]孟庆昌编著,操作系统教程 - Linux实例分析,西安电子科技大学出版社,2004 九. 课程设计评价 课 程 设 计 评 价 成绩: 教师: 年 月 日 20
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服