树形数据增删改查

功能描述:

  1. 默认展示所有项目
  2. 点击项目展示当前项目下的所有区域
  3. 点击区域展示当前区域下的所有工位
  4. 以上以树形图格式展示
  5. 项目,区域,和工位都可进行增加 修改 和删除,每个图标hover时显示对应提示信息
  6. 项目,区域,工位可导入数据,提供下载模板功能
  7. 部门配置单独列出,展示所有部门列表,部门可进行增加,修改和删除

效果示意图
在这里插入图片描述

所有代码:

<template><el-row :gutter="15" justify="center" style="height:100%;"><el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12"><el-main  style="width:100%;margin:0 auto;position:relative; height:100%;padding:0;background:#fff;padding:10px;"><h1 style="text-align:center;margin-top:10px;">项目区域配置</h1><!-- <a style="position:absolute;left:5px;top:8px;color:#3388cc;font-size:12px; text-decoration:underline;" target="_blank" href="#/questionCommit"> <el-icon><Back /></el-icon> 问题提交</a><a style="position:absolute;right:5px;top:8px;color:#3388cc;font-size:12px; text-decoration:underline;" target="_blank" href="#/questionList"> 问题列表 <el-icon><Right /></el-icon></a> --><el-tabs v-model="activeName" class="demo-tabs" ><el-tab-pane label="项目配置" name="first"><div><el-button type="primary" @click="addProject">添加项目</el-button><el-uploadstyle="float:right;"ref="uploadRef":on-change="importProject"class="upload-demo":limit="1"accept=".xlsx":auto-upload="false"action=""><el-button type="primary">导入数据</el-button></el-upload><el-button type="primary" @click="downloadXLSX"   style="float:right;margin-right:10px">下载模板</el-button><ul><li v-for="project in projects" :key="project.projectId"><el-collapse @change="handleChangeProject(project,project.projectId)"><el-collapse-item ><template #title><span v-if="project.editing"><input v-model="project.projectName"  /></span><b v-else> {{ project.projectName }}</b>&nbsp;&nbsp;<el-tooltipclass="box-item"effect="dark":content="project.editing?'保存项目名称':'编辑项目名称'"placement="top-start"><el-icon @click.stop="toggleEditProject(project)" style="color:#3388cc;cursor:pointer;"><SuccessFilled v-if="project.editing" @click.stop="saveProject(project)"/><Edit v-else /></el-icon></el-tooltip>&nbsp;&nbsp;<el-tooltipclass="box-item"effect="dark"content="删除当前项目"placement="top-start"><el-icon @click.stop="confirmRemoveProject(project)" style="color:red;cursor:pointer;"><Delete/></el-icon></el-tooltip>&nbsp;&nbsp;<el-tooltipclass="box-item"effect="dark"content="当前项目下添加区域"placement="top-start"><el-icon @click.stop="addArea(project)" style="cursor:pointer;"><CirclePlusFilled /></el-icon></el-tooltip></template><div><ul><li v-for="area in project.areas" :key="area.regionId"><el-collapse @change="handleChangeRegion(area,area.regionId)"><el-collapse-item><template #title><span v-if="area.editing"><input v-model="area.regionName" /></span><b v-else>{{ area.regionName }}</b>&nbsp;&nbsp;<el-tooltipclass="box-item"effect="dark":content="area.editing?'保存区域名称':'编辑区域名称'"placement="top-start"><el-icon @click.stop="toggleEditArea(area)" style="color:#3388cc;cursor:pointer;"><SuccessFilled v-if="area.editing"  @click.stop="saveArea(project,area)"/><Edit v-else /></el-icon></el-tooltip>&nbsp;&nbsp;<el-tooltipclass="box-item"effect="dark"content="删除当前区域"placement="top-start"><el-icon @click.stop="confirmRemoveArea(project, area)" style="color:red;cursor:pointer;"><Delete/></el-icon></el-tooltip>&nbsp;&nbsp;<el-tooltipclass="box-item"effect="dark"content="当前区域下添加工位"placement="top-start"><el-icon @click.stop="addStation(project, area)" style="cursor:pointer;"><CirclePlusFilled /></el-icon></el-tooltip></template><div><ul><li v-for="station in area.stations" :key="station.stationId" ><div><span v-if="station.editing"><input v-model="station.stationName"  /></span><b v-else>{{ station.stationName }}</b>&nbsp;&nbsp;<el-tooltipclass="box-item"effect="dark":content="station.editing?'保存工位名称':'编辑工位名称'"placement="top-start"><el-icon @click.stop="toggleEditStation(station)" style="color:#3388cc;cursor:pointer;"><SuccessFilled v-if="station.editing" @click.stop="saveStation(project, area, station)" /><Edit v-else /></el-icon></el-tooltip>&nbsp;&nbsp;<el-tooltipclass="box-item"effect="dark"content="删除当前工位"placement="top-start"><el-icon @click.stop="confirmRemoveStation(project, area, station)" style="color:red;cursor:pointer;"><Delete/></el-icon></el-tooltip></div></li></ul></div></el-collapse-item></el-collapse></li></ul></div></el-collapse-item></el-collapse></li></ul></div></el-tab-pane><el-tab-pane label="部门配置" name="second"><el-button type="primary" @click="addDepartmentName">添加部门</el-button><ul><li v-for="department in departmentNameList" :key="department.id"><div  style="height:40px;line-height:40px;border-bottom:1px solid #ddd;"><span v-if="department.editing"><input v-model="department.departmentName" /></span><span v-else>{{ department.departmentName }}</span>&nbsp;&nbsp;<el-tooltipclass="box-item"effect="dark":content="department.editing?'保存部门名称':'编辑部门名称'"placement="top-start"><el-icon @click="toggleEditDepartment(department)" style="color:#3388cc;cursor:pointer;"><SuccessFilled v-if="department.editing"  @click="saveDepartment(department)"/><Edit v-else /></el-icon></el-tooltip>&nbsp;&nbsp;<el-tooltipclass="box-item"effect="dark"content="删除当前部门"placement="top-start"><el-icon @click="confirmRemoveDepartment(department)" style="color:red;cursor:pointer;"><Delete/></el-icon></el-tooltip></div></li></ul></el-tab-pane></el-tabs><el-dialog v-model="showConfirmDialog" title="确认删除" @close="showConfirmDialog = false"><span v-if="itemToDelete" style="margin:20px auto">确定要删除 {{ itemToDelete.type }}{{ itemToDelete.name }} 吗?</span><el-button type="danger" @click="deleteItem">确认删除</el-button></el-dialog></el-main></el-col></el-row></template>
<script lang="ts" setup>
import { ref } from 'vue'
import * as XLSX from 'xlsx';
import type { TabsPaneContext} from 'element-plus'
import {insertDepartment,upload,deleteDeptById,deleteProjectById,deleteAreaById,deleteStationById,updateDepartmentById,insertOrUpdateArea,insertProject,insertOrUpdateStation,queryDepartmentName,queryProject,queryRegionByProject,queryStationName} from '@/api/user'
import { ElMessage } from 'element-plus'
let showConfirmDialog = ref(false)
let itemToDelete = ref(null)
let projects = ref([{projectId: 1,projectName: '项目1',areas: [{regionId: 11,regionName: '区域1',projectId: 1,stations: [{stationId:118,stationName:"H005 机壳上线",regionId:120}],},],},])
let departmentNameList = ref([]);
const activeName = ref('first')let downloadXLSX = ()=>{// 创建一个 XLSX 工作簿const wb = XLSX.utils.book_new();// 创建一个工作表const ws = XLSX.utils.json_to_sheet([// 在这里定义模板的列和初始数据{ '项目名称':'','区域':'','工位名称':'' },// 您可以在这里添加更多的模板数据行]);// 向工作簿添加工作表XLSX.utils.book_append_sheet(wb, ws, '模板数据');// 生成 XLSX 文件XLSX.writeFile(wb, '模板数据.xlsx');}
let importProject : UploadProps['onChange'] = (uploadFile, uploadFiles) => {console.log(uploadFile);let formData = new FormData();formData.append('file', uploadFile.raw)upload(formData).then((data)=>{if(data.status == 200){ElMessage({message: '导入成功',type: 'success',})}
})}let toggleEditProject = (project) => {// 切换项目编辑状态project.editing = !project.editing
}
let toggleEditArea = (area) => {// 切换区域编辑状态area.editing = !area.editing
}
let toggleEditStation = (station) => {// 切换工位编辑状态station.editing = !station.editing
}
let toggleEditDepartment = (department) => {// 切换部门编辑状态department.editing = !department.editing
}const getList = () => {
//获取所有部门列表
queryDepartmentName().then((data)=>{
if(data.status == 200){departmentNameList.value = data.data;
}
})
//获取所有项目列表
queryProject().then((data)=>{
if(data.status == 200){projects.value = data.data;console.log(projects)
}
})
}
//点击项目获取项目下的区域
let handleChangeProject = (project,id)=>{let formData = new FormData();
formData.append('projectId', id);
queryRegionByProject(formData).then((data)=>{
if(data.status == 200){project.areas = data.data;
}
})
}
//点击区域获取区域下面的工位
let handleChangeRegion = (region,id)=>{let formData1 = new FormData();formData1.append('areaId', id);queryStationName(formData1).then((data)=>{if(data.status == 200){region.stations = data.data;}
})
}//添加项目
let addProject = () => {let formData = new FormData();let num =  Math.floor(Math.random() * 1000)formData.append('projectName', '新项目'+num);insertProject(formData).then((data)=>{if(data.status == 200){const newProject = {projectId: Math.floor(data.data),projectName: '新项目'+num,areas: [],}projects.value.push(newProject)ElMessage({message: '添加项目成功,名为 新项目'+num+',可修改',type: 'success',})}else{ElMessage({message: '添加项目失败',type: 'error',})}})}
//添加区域
let addArea = (project) => {let formData = new FormData();formData.append('projectId', project.projectId);let num1 =  Math.floor(Math.random() * 1000)formData.append('regionName', '新区域'+num1);insertOrUpdateArea(formData).then((data)=>{if(data.status == 200){const newArea = {regionId: Math.floor(data.data),regionName: '新区域'+num1,projectId:project.projectId,stations: [],}project.areas.push(newArea)ElMessage({message: '添加区域成功,名为 新区域'+num1+',可修改',type: 'success',})}else{ElMessage({message: '添加区域失败',type: 'error',})}})
}
// 添加工位
let addStation = (project, area) => {let formData = new FormData();formData.append('regionId', area.regionId);//let num2 =  Math.floor(Math.random() * 1000)formData.append('stationName', '新工位'+num2);insertOrUpdateStation(formData).then((data)=>{if(data.status == 200){const newStation = {stationId: Math.floor(data.data),stationName:'新工位'+num2,regionId:area.regionId}area.stations.push(newStation)ElMessage({message: '添加工位成功,名为 新工位'+num2+',可修改',type: 'success',})}else{ElMessage({message: '添加工位失败',type: 'error',})}})
}//添加部门
let addDepartmentName = ()=>{let formData = new FormData();let num3 =  Math.floor(Math.random() * 1000)formData.append('departmentName', '新部门'+num3);insertDepartment(formData).then((data)=>{if(data.status == 200){const newDepartmentName = {id: Math.floor(data.data),departmentName: '新部门'+num3,}departmentNameList.value.push(newDepartmentName)ElMessage({message: '添加部门成功,名为 新部门'+num3+',可修改',type: 'success',})}else{ElMessage({message: '添加部门失败',type: 'error',})}})}// 保存项目编辑
let saveProject = (project) => {let formData = new FormData();formData.append('projectId', project.projectId);formData.append('projectName', project.projectName);insertProject(formData).then((data)=>{if(data.status == 200){project.editing = falseElMessage({message: '修改项目名成功',type: 'success',})}else{ElMessage({message: '修改项目失败',type: 'error',})}})
}// 保存区域编辑
let saveArea = (project, area) => {let formData = new FormData();formData.append('projectId', project.projectId);formData.append('regionId', area.regionId);formData.append('regionName', area.regionName);insertOrUpdateArea(formData).then((data)=>{if(data.status == 200){area.editing = falseElMessage({message: '修改区域名成功',type: 'success',})}else{ElMessage({message: '修改区域名失败',type: 'error',})}})}// 保存工位编辑
let saveStation = (project, area, station) => {let formData = new FormData();formData.append('regionId', area.regionId);formData.append('stationName', station.stationName);formData.append('stationId', station.stationId);insertOrUpdateStation(formData).then((data)=>{if(data.status == 200){station.editing = falseElMessage({message: '修改工位名成功',type: 'success',})}else{ElMessage({message: '修改工位名失败',type: 'error',})}})
}
// 保存部门编辑
let saveDepartment = (department) => {let formData = new FormData();formData.append('id', department.id);formData.append('departmentName',department.departmentName);insertDepartment(formData).then((data)=>{if(data.status == 200){department.editing = falseElMessage({message: '修改部门名成功',type: 'success',})}else{ElMessage({message: '修改部门名失败',type: 'error',})}})
}//删除项目
let confirmRemoveProject = (project) => {itemToDelete.value = { type: '项目',name: project.projectName,project,data: { id: project.projectId } }showConfirmDialog.value = true
}
//删除区域
let confirmRemoveArea = (project, area) => {itemToDelete.value = { type: '区域',  name: area.regionName,project,area,data: { id: area.regionId } }showConfirmDialog.value = true
}
//删除工位
let confirmRemoveStation = (project, area, station) => {itemToDelete.value = { type: '工位', name: station.stationName,project,area, station, data: {  id: station.stationId } }showConfirmDialog.value = true
}
//删除部门
let confirmRemoveDepartment = (department) => {itemToDelete.value = { type: '部门', name: department.departmentName,department,data: { id: department.id } }showConfirmDialog.value = true
}//确认删除
let deleteItem = () => {if (itemToDelete.value) {if (itemToDelete.value.type === '项目') {// 执行删除项目的逻辑let json ={'projectId':itemToDelete.value.data.id}deleteProjectById(json).then((data)=>{if(data.status == 200){const projectIdToDelete = itemToDelete.value.data.id;const indexToDelete = projects.value.findIndex((project) => project.projectId === projectIdToDelete);if (indexToDelete !== -1) {projects.value.splice(indexToDelete, 1);}ElMessage({message: '删除项目成功',type: 'success',})}})} else if (itemToDelete.value.type === '区域') {// 执行删除区域的逻辑let json ={'areaId':itemToDelete.value.data.id}deleteAreaById(json).then((data)=>{if(data.status == 200){// 从项目的区域列表中删除已删除的区域const project = itemToDelete.value.project;const area = itemToDelete.value.area;const areaIdToDelete = itemToDelete.value.data.id;// 查找项目并从它的区域列表中删除区域if (project) {const projectIndex = projects.value.findIndex((p) => p === project);if (projectIndex !== -1 && area) {const areaIndex = project.areas.findIndex((a) => a === area);if (areaIndex !== -1) {project.areas.splice(areaIndex, 1);}}}ElMessage({message: '删除区域成功',type: 'success',})}})} else if (itemToDelete.value.type === '工位') {// 执行删除工位的逻辑let json ={'stationId':itemToDelete.value.data.id}deleteStationById(json).then((data)=>{if(data.status == 200){// 从项目的区域的工位列表中删除已删除的工位// 从项目的区域的工位列表中删除已删除的工位const project = itemToDelete.value.project;const area = itemToDelete.value.area;const stationIdToDelete = itemToDelete.value.data.id;// 查找项目、区域,并从它的工位列表中删除工位if (project && area) {const projectIndex = projects.value.findIndex((p) => p === project);if (projectIndex !== -1) {const areaIndex = project.areas.findIndex((a) => a === area);if (areaIndex !== -1) {const stationIndex = area.stations.findIndex((s) => s.stationId === stationIdToDelete);if (stationIndex !== -1) {area.stations.splice(stationIndex, 1);}}}}ElMessage({message: '删除工位成功',type: 'success',})}})} else if (itemToDelete.value.type === '部门') {// 执行删除部门的逻辑let json ={'id':itemToDelete.value.data.id}deleteDeptById(json).then((data)=>{if(data.status == 200){// 从部门列表中删除已删除的部门const departmentIdToDelete = itemToDelete.value.data.id;const indexToDelete = departmentNameList.value.findIndex((department) => department.id === departmentIdToDelete);if (indexToDelete !== -1) {departmentNameList.value.splice(indexToDelete, 1);}ElMessage({message: '删除部门成功',type: 'success',})}})}showConfirmDialog.value = false}
}onMounted(() => {getList();
})
</script>
<style>
.demo-tabs > .el-tabs__content {padding: 32px;color: #6b778c;font-weight: 600;
}body{background:#ccc;}</style>

提示
当前页面所有请求接口请根据自己项目实际情况修改
当前代码版本基于 vue3 elementplus
下载模板需要安装xlsx插件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/170423.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git(二)版本控制、发展历史、初始化配置、别名

目录 一、版本控制1.1 为什么要使用版本控制&#xff1f;1.2 集中化的版本控制系统1.3 分布式的版本控制系统1.3 两种版本控制系统对比集中式&#xff08;svn&#xff09;分布式&#xff08;git&#xff09; 二、发展历史三、初始化配置3.1 配置文件3.2 配置内容 四、别名 官网…

Mac 超好用的工具推荐

Arc Arc 是 2022 年 4 月发布的浏览器产品&#xff0c;在介绍 Arc 浏览器之前&#xff0c;让我们来看下以 Chrome、FireFox、Edge、Safari 为代表的的传统浏览器&#xff1a; 难怪《浏览器是怎么工作的》作者 Paul Irish 曾说&#xff0c;尽管 W3C 并未规范浏览器界面&#xf…

欧拉图相关的生成与计数问题探究

最近学了一波国家集训队2018论文的最后一个专题。顺便带上了一些我的注解。 先放一波这个论文 1.基本概念 欧拉图问题是图论中的一类特殊的问题。在本文的介绍过程中&#xff0c;我们将会使用一些图 论术语。为了使本文叙述准确&#xff0c;本节将给出一些术语的定义。 定义…

每日一练 | 华为认证真题练习Day122

1、路由器所有的接口属于同一个广播域。 A. 对 B. 错 2、下列配置默认路由的命令中&#xff0c;正确的是&#xff08;&#xff09;。 A. [Huawei]ip route-static 0.0.0.0 0.0.0.0 192.168.1.1 B. [Huawei-Serial0]ip route-static 0.0.0.0 0.0.0.0 0.0.0.0 C. [Huawei]ip…

浅谈余压监控系统电气设计

安科瑞 华楠 摘 要&#xff1a;结合实际的工程设计案例&#xff0c;分析余压监控系统的设计&#xff0c;包括余压探测器、余压控制器、余压监控主机的控制原理等。防止人员在实际的火灾疏散过程中会出现楼梯间和前室之间、前室和室内走道之间防火门两侧压差过大&#xff0c;而…

HackTheBox - Starting Point -- Tier 0 ---Fawn

文章目录 一 题目二 实验过程 一 题目 Tags FTP、Network、Protocols、Reconnaissance、Anonymous/Guest Access译文&#xff1a;文件传输协议、网络、协议、侦察、匿名/访客访问Connect To attack the target machine, you must be on the same network.Connect to the Sta…

数字驱动,营销赋能丨工商职院电子商务专业学生,前往餐饮美食电商新业态基地试岗交流

纸上得来终觉浅&#xff0c;绝知此事要躬行。为了让学生更好的了解自己与所应聘岗位的匹配度&#xff0c;同时也希望在实际业务场景中&#xff0c;发掘自身优势&#xff0c;10月23日&#xff0c;四川产教融创园信息技术有限公司组织四川工商职业技术学院的电子商务专业学生一行…

《红蓝攻防对抗实战》三.内网探测协议出网之HTTP/HTTPS协议探测出网

目录 一. 在 Windows 操作系统中探测 HTTP/HTTPS 出网 1. Bitsadmin 命令 2.Certuil 命令 2.Linux系统探测HTTP/HTTPS出网 1.Curl命令 2.Wget命令 对目标服务器探测 HTTP/HTTPS 是否出网时&#xff0c;要根据目标系统类型执行命令&#xff0c;不同类型的操作系统使用的探…

【30】c++设计模式——>状态模式

状态模式概述 状态模式是一种行为型设计模式&#xff0c;它可以让一个对象在其内部状态发生变化时更改其行为。通过将每个状态封装成一个独立的类&#xff0c;我们可以使状态之间互相独立&#xff0c;并且使得状态的切换变得更加灵活、可扩展。&#xff08;多个状态之间可以相…

uni-app 小宠物 - 会说话的小鸟

在 template 中 <view class"container"><view class"external-shape"><view class"face-box"><view class"eye-box eye-left"><view class"eyeball-box eyeball-left"><span class"…

适合在虚拟化环境中部署 Kubernetes 的三个场景

在《虚拟化 vs. 裸金属&#xff1a;K8s 部署环境架构与特性对比》文章中&#xff0c;我们从架构和特性的角度&#xff0c;对比了在虚拟化和裸金属环境部署 Kubernetes 的优劣势&#xff0c;并在文末列举了两者更适合的应用场景。本文&#xff0c;我们将聚焦以虚拟化环境支持 K8…

ubuntu20.04下安装nc

前言 nc在网络渗透测试中非常好用&#xff0c;这里的主要记一下Ubuntu20.04中nc的安装 编译安装 第一种方式是自己编译安装&#xff0c;先下载安装包 nc.zip wget http://sourceforge.net/projects/netcat/files/netcat/0.7.1/netcat-0.7.1.tar.gz/download -O netcat-0.7.…

线性代数-Python-03:矩阵的变换 - 手写Matrix Transformation及numpy中的用法

文章目录 一、代码仓库二、旋转矩阵的推导及图形学中的矩阵变换2.1 让横坐标扩大a倍&#xff0c;纵坐标扩大b倍2.2 关于x轴翻转2.3 关于y轴翻转2.4 关于原点翻转&#xff08;x轴&#xff0c;y轴均翻转&#xff09;2.5 沿x方向错切2.6 沿y方向错切2.7 旋转2.8 单位矩阵2.9 矩阵的…

ES在企业项目中的实战总结,彻底掌握ES的使用

通过之前两篇文章 了解了ES的核心概念和基础使用学习进阶的DSL语法处理复杂的查询 这段时间通过在本企业代码中对ES框架的使用&#xff0c;总结了不少经验。主要分为三点 企业封装了ES原生的api&#xff0c;需要使用企业项目提供的接口实现 -------简单使用&#xff08;本章节目…

PyCharm中文使用详解

PyCharm是一个Python IDE&#xff0c;可以帮助程序员节省时间&#xff0c;提高生产力。那么具体怎么用呢&#xff1f;本文介绍了PyCharm的安装、插件、外部工具、专业功能等&#xff0c;希望对大家有所帮助。 之前没有系统介绍过PyCharm。如何配置环境&#xff0c;如何DeBug&a…

Go语言入门心法(十四): Go操作Redis实战

Go语言入门心法(一): 基础语法 Go语言入门心法(二): 结构体 Go语言入门心法(三): 接口 Go语言入门心法(四): 异常体系 Go语言入门心法(五): 函数 Go语言入门心法(六): HTTP面向客户端|服务端编程 Go语言入门心法(七): 并发与通道 Go语言入门心法(八): mysql驱动安装报错o…

数据安全小课堂开讲啦!看这里!

数据安全小课堂开讲啦&#xff01;看这里&#xff01; 1、什么是数据&#xff1f; 《数据安全法》第三条明确&#xff0c;本法所称的数据&#xff0c;就是指任何以电子或者其他方式对信息的记录。小到个人使用手机、电脑等电子产品时浏览的网页、下载的应用、存储的文件&…

前端数据可视化之【Echarts下载使用】

目录 &#x1f31f;下载&#x1f31f;浏览器引入&#x1f31f;模块化引入 &#x1f31f;使用&#x1f31f;基本使用步骤 &#x1f31f;绘制一个简单的图表&#x1f31f;写在最后 &#x1f31f;下载 &#x1f31f;浏览器引入 官网下载界面&#xff1a;官方网站 或 Echarts中文…

前端,CSS,背景颜色跟随轮播图片改变而改变(附源码)

首先看效果&#xff01; 比如轮播图时红色&#xff0c;那么背景的底色也是红色&#xff0c;轮播图时黄色&#xff0c;背景的底色也是黄色&#xff0c;这就是根据轮播图的图片切换&#xff0c;而改变背景颜色随轮播图颜色一致 话不多说&#xff0c;直接上代码&#xff01;非常简…