项目整理--Echarts前端后台的贯通写法
项目整理–Echarts前端后台的贯通写法
注:下面所有内容建立在FH admin开源框架和eharts插件基础上,建议观看本案例者进行了解。
业务逻辑
绘制两张图表。分别显示城市空间库和其它数据仓库的信息(城市空间库单独绘制)。要求:城市空间库显示数据库的实际使用量和剩余用量。其它库显示百分比。
效果展示
默认显示状态
鼠标指向状态
实现过程
1.后台数据处理
表结构设计
数据库数据
注:此处数据为显示数据,并不是项目使用数据,仅作測试使用。
Mapper文件写法
注1:此处在前端页面须要绘制两个图表,因此用两条sql语句。差别为提供查询的type字段不同。此字段也可由传參带入。使用一条sql分别实现查询,此次为了展示直观,採用第一种做法。
注2:因为採用框架,此处数据为採用实体类封装,而是採用HashMap封装。能够依据自己习惯。创建实体类来存储数据库中数据。
<?
xml version="1.0" encoding="UTF-8"?
>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="SjkyxMapper">
<!-- 列表(无实际意义,为以后扩展功能用) -->
<select id="datalist" parameterType="page" resultType="pd">
SELECT
a.id,
a.dept,
a.order,
a.score
FROM
cms_yw_fwxl AS a
ORDER BY
a.order
</select>
<!-- 获取城市空间库的信息 -->
<select id="getcskjcharts" parameterType="page" resultType="pd">
SELECT
c.type,
c.id,
c.`name`,
c.volume_total,
c.volume_total_unit,
c.volume_use,
c.volume_use_unit,
c.create_time,
c.creator,
c.update_time,
c.updater,
c.remark
FROM
cms_yw_sjkyx AS c
WHERE
type = 1
</select>
<!-- 获取其它库的信息 -->
<select id="getothercharts" parameterType="page" resultType="pd">
SELECT
c.type,
c.id,
c.`name`,
c.volume_total,
c.volume_total_unit,
c.volume_use,
c.volume_use_unit,
c.create_time,
c.creator,
c.update_time,
c.updater,
c.remark
FROM
cms_yw_sjkyx AS c
WHERE
type = 2
</select>
</mapper>
Service中写法
注1:此处採用的已有框架,使用已经提供的统一的Dao。假设使用传统的SSM写法。能够自己稍加改动,在此不做赘述。
注2:依据业务逻辑理解代码,当中封装了createData方法来实现不同的业务逻辑。
@Service("sjkyxService")
public class SjkyxService {
@Resource(name = "daoSupport")
private DaoSupport dao;
/*
*数据资源列表
*/
public List<PageData> list(Page page)throws Exception{
return (List<PageData>)dao.findForList("SjkyxMapper.datalist", page);
}
/*
* 用来返回城市空间库使用信息
*/
public Map<String, Object> getcskjcharts(int type)throws Exception{
List<PageData> list = (List<PageData>)dao.findForList("SjkyxMapper.getcskjcharts", null);
return createData(list,type);
}
/*
* 用来返回其它库所用信息
*/
public Map<String, Object> getothercharts(int type)throws Exception{
List<PageData> list = (List<PageData>)dao.findForList("SjkyxMapper.getothercharts", null);
return createData(list,type);
}
/*
* 内部设计的方法。用于封装查询数据
*/
private Map<String, Object> createData(List<PageData> list,int type)throws Exception{
Map<String,Object> resultMap = new HashMap<String,Object>();
//x轴现实的信息
String[] xAxisArr = new String[list.size()];
//总量信息
Integer[] restArr = new Integer[list.size()];
//已使用信息
Integer[] usedArr = new Integer[list.size()];
if(1==type){
for(int i=0;i<list.size();i++){
xAxisArr[i] =(String) list.get(i).get("name");
usedArr[i] = Integer.parseInt(new java.text.DecimalFormat("0").format((Double) list.get(i).get("volume_use")));
double restData = (Double)list.get(i).get("volume_total")-(Double) list.get(i).get("volume_use");
restArr[i] = Integer.parseInt(new java.text.DecimalFormat("0").format(restData));
}
}else if(2==type){
for(int i=0;i<list.size();i++){
xAxisArr[i] =(String) list.get(i).get("name");
double perData = (Double) list.get(i).get("volume_use")/(Double) list.get(i).get("volume_total")*100;
usedArr[i] = Integer.parseInt(new java.text.DecimalFormat("0").format(perData));
double restData = ((Double)list.get(i).get("volume_total")-(Double) list.get(i).get("volume_use"))/(Double) list.get(i).get("volume_total")*100;
restArr[i] = Integer.parseInt(new java.text.DecimalFormat("0").format(restData));
}
}
resultMap.put("xAxisArr", xAxisArr);
resultMap.put("restArr", restArr);
resultMap.put("usedArr", usedArr);
return resultMap;
}
}
Controller中写法
主要用于跳转页面和Ajax传递数据,涉及权限管理的部分能够不用看。
package com.bonc.dgioc.portal.web.controller.portal.operate;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.bonc.dgioc.portal.common.utils.Const;
import com.bonc.dgioc.portal.common.utils.PageData;
import com.bonc.dgioc.portal.domain.entity.Page;
import com.bonc.dgioc.portal.service.portal.operate.FwxlService;
import com.bonc.dgioc.portal.service.portal.operate.SjkyxService;
import com.bonc.dgioc.portal.service.portal.operate.SjzyService;
import com.bonc.dgioc.portal.web.controller.base.BaseController;
/**
* 功 能:运维首页数据库执行情况
* 类名称:SjkyxController
* 创建人:@author Xiaoqi
* 创建时间:2016-03-29
*/
@Controller
@RequestMapping(value="/operate/sjkyx")
public class SjkyxController extends BaseController {
@Resource(name="sjkyxService")
private SjkyxService sjkyxService;
/**
* 获取sjkyx列表
* @author Xiaoqi
* @date 2016-03-30
*/
@RequestMapping(value="/getsjkyxlist")
public ModelAndView list(Page page){
logBefore(logger, "列表sjkyx信息");
ModelAndView mv = this.getModelAndView();
PageData pd = new PageData();
try{
pd = this.getPageData();
page.setPd(pd);
List<PageData> varList = sjkyxService.list(page); //列出sjkyx列表
mv.setViewName("portal/operate/sjkyx_list");
mv.addObject("varList", varList);
mv.addObject("pd", pd);
mv.addObject(Const.SESSION_QX,this.getHC()); //button权限
} catch(Exception e){
logger.error(e.toString(), e);
}
return mv;
}
/**
* 返回城市空间库的图表信息
* @return 返回城市空间库的图表信息
* @date 2016-04-11
*/
@ResponseBody
@RequestMapping(value="/getcskjcharts")
public Map<String,Object> getcskjcharts(){
logBefore(logger, "获取城市空间库图表信息");
Map<String,Object> resultMap = new HashMap<String,Object>();
try{
resultMap = sjkyxService.getcskjcharts(1); //获取其它库图表信息
} catch(Exception e){
logger.error(e.toString(), e);
}
return resultMap;
}
/**
* 返回城市空间库之外的其它库的图表信息
* @return 返回城市空间库之外的其它库的图表信息
* @date 2016-04-11
*/
@ResponseBody
@RequestMapping(value="/getothercharts")
public Map<String,Object> getothercharts(){
logBefore(logger, "获取其它库图表信息");
Map<String,Object> data = new HashMap<String,Object>();
try{
data = sjkyxService.getothercharts(2); //获取其它库图表信息
} catch(Exception e){
logger.error(e.toString(), e);
}
return data;
}
/* ===============================权限================================== */
public Map<String, String> getHC(){
Subject currentUser = SecurityUtils.getSubject(); //shiro管理的session
Session session = currentUser.getSession();
return (Map<String, String>)session.getAttribute(Const.SESSION_QX);
}
/* ===============================权限================================== */
@InitBinder
public void initBinder(WebDataBinder binder){
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(Date.class, new CustomDateEditor(format,true));
}
}
2.前端页面处理
下面为分部代码解读,最下方有前端页面所有代码。
引入echarts和jQuery文件
注:此处bootstrap为前端框架,此处知道当中含有jQuery文件就可以。
<!-- 引入 -->
<%@ include file="../../common/bootstrap_js.jsp"%>
<script type="text/javascript" src="<%=basePath%>/resources/module/echarts/echarts.js"></script><!-- 引入echarts -->
建立div存放不同的图表
注:echarts中一个div仅仅能绘制一张图表
<div>
<div id="chkj" style="height:160px;width:20%;text-align:right;float:left;">
</div>
<div id="other" style="height:160px;width:80%;text-align:right;float:right;">
</div>
</div>
echarts代码解读
引入echarts的主题和各种组件,调用绘制图表的方法drawotherCharts和drawchkjCharts
require.config({
paths:{
echarts:'<%=basePath%>/resources/module/echarts'
}
});
require(
['echarts',
'echarts/theme/macarons',
'echarts/chart/line', //使用折线图,就须要加载line模块,按需加载(柱图:bar;饼图:pie;地图:map;)
'echarts/chart/bar',
'echarts/chart/pie'
],
function (ec,theme) {
drawotherCharts(ec,theme),
drawchkjCharts(ec,theme)
});
绘制图表:
function drawotherCharts(ec,theme){
var myChart = ec.init(document.getElementById("other"),theme);
option = {
tooltip : {
trigger: 'axis',
axisPointer : { // 坐标轴指示器,坐标轴触发有效
type : 'shadow' // 默觉得直线,可选为:'line' | 'shadow'
},
formatter: function (params){ //用来编辑鼠标指向时的文字信息
return params[0].name + '<br/>'
+ params[0].seriesName + ' : ' + params[0].value + '<br/>'
+ params[1].seriesName + ' : ' + (params[1].value + params[0].value);
}
},
legend: { //此处为图例
selectedMode:false,
data:['已使用', '未使用']
},
grid:{ //此处控制图表在div中的位置
x:20,
y:60,
x2:0,
y2:35
},
toolbox: { //此处为控制图表的工具栏,设置show选项为false,能够将show的false改为true来查看效果。
show : false,
feature : {
mark : {show: true},
dataView : {show: true, readOnly: false},
restore : {show: true},
saveAsImage : {show: true}
}
},
calculable : false, //取消加载时的动态效果
xAxis : [ //x轴现实信息配置
{
type : 'category',
data : [],
splitLine:{
show:false
},
axisTick:false,
axisLine:false,
axisLabel:{
rotate:0,
margin:10,
textStyle:{
fontSize : '2px',
fontFamily : '微软雅黑',
color: '#00A3D1'
}
},
}
],
yAxis : [ //y轴数据配置
{
type : 'value',
axisLine:false,
splitLine:{
show:false
},
axisTick:false,
boundaryGap: [0, 0.1],
axisLabel:{
show:false
}
}
],
series : [
{
name:'已使用',
type:'bar',
stack: 'sum',
barCategoryGap: '50%',
barWidth:45,
itemStyle: {
normal: {
color: '#00A3D1',
barBorderColor: '#00A3D1',
barBorderWidth: 4,
barBorderRadius:0,
label : {
show: true, position: 'insideTop'
}
}
},
data:[]
},
{
name:'未使用',
type:'bar',
stack: 'sum',
itemStyle: {
normal: {
color: '#fff',
barBorderColor: '#00A3D1',
barBorderWidth: 3,
barBorderRadius:0,
label : {
show: true,
position: 'top',
textStyle: {
fontSize : '10',
fontFamily : '微软雅黑',
color: '#00A3D1'
}
}
}
},
data:[]
}
]
};
myChart.showLoading({
text: "图表数据正在努力加载..."
});
//通过ajax向后台发送请求。传递数据。
$.ajax({
type: 'GET',
url : '<%=path %>/operate/sjkyx/getothercharts',
dataType: 'json',
success:function(data){
debugger;
option.xAxis[0]['data']=data.xAxisArr;
option.series[0]['data']=data.usedArr;
option.series[1]['data']=data.restArr;
myChart.setOption(option);
},
error:function(){
debugger;
},
complete:function(){
//无论数据接口成功或异常,都最终加载提示
myChart.hideLoading();//停止动画加载提示
}
})
}
echarts完整代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Widgets - Ace Admin</title>
<base href="<%=basePath%>">
<!-- 引入 -->
<%@ include file="../../common/bootstrap_js.jsp"%>
<script type="text/javascript" src="<%=basePath%>/resources/module/echarts/echarts.js"></script><!-- 引入echarts -->
<script type="text/javascript">
require.config({
paths:{
echarts:'<%=basePath%>/resources/module/echarts'
}
});
require(
['echarts',
'echarts/theme/macarons',
'echarts/chart/line', //使用折线图,就须要加载line模块,按需加载(柱图:bar;饼图:pie;地图:map;)
'echarts/chart/bar',
'echarts/chart/pie'
],
function (ec,theme) {
drawotherCharts(ec,theme),
drawchkjCharts(ec,theme)
});
function drawotherCharts(ec,theme){
var myChart = ec.init(document.getElementById("other"),theme);
option = {
tooltip : {
trigger: 'axis',
axisPointer : { // 坐标轴指示器,坐标轴触发有效
type : 'shadow' // 默觉得直线。可选为:'line' | 'shadow'
},
formatter: function (params){ //用来编辑鼠标指向时的文字信息
return params[0].name + '<br/>'
+ params[0].seriesName + ' : ' + params[0].value + '<br/>'
+ params[1].seriesName + ' : ' + (params[1].value + params[0].value);
}
},
legend: { //此处为图例
selectedMode:false,
data:['已使用', '未使用']
},
grid:{ //此处控制图表在div中的位置
x:20,
y:60,
x2:0,
y2:35
},
toolbox: { //此处为控制图表的工具栏,设置show选项为false,能够将show的false改为true来查看效果。
show : false,
feature : {
mark : {show: true},
dataView : {show: true, readOnly: false},
restore : {show: true},
saveAsImage : {show: true}
}
},
calculable : false, //取消加载时的动态效果
xAxis : [ //x轴现实信息配置
{
type : 'category',
data : [],
splitLine:{
show:false
},
axisTick:false,
axisLine:false,
axisLabel:{
rotate:0,
margin:10,
textStyle:{
fontSize : '2px',
fontFamily : '微软雅黑',
color: '#00A3D1'
}
},
}
],
yAxis : [ //y轴数据配置
{
type : 'value',
axisLine:false,
splitLine:{
show:false
},
axisTick:false,
boundaryGap: [0, 0.1],
axisLabel:{
show:false
}
}
],
series : [
{
name:'已使用',
type:'bar',
stack: 'sum',
barCategoryGap: '50%',
barWidth:45,
itemStyle: {
normal: {
color: '#00A3D1',
barBorderColor: '#00A3D1',
barBorderWidth: 4,
barBorderRadius:0,
label : {
show: true, position: 'insideTop'
}
}
},
data:[]
},
{
name:'未使用',
type:'bar',
stack: 'sum',
itemStyle: {
normal: {
color: '#fff',
barBorderColor: '#00A3D1',
barBorderWidth: 3,
barBorderRadius:0,
label : {
show: true,
position: 'top',
textStyle: {
fontSize : '10',
fontFamily : '微软雅黑',
color: '#00A3D1'
}
}
}
},
data:[]
}
]
};
myChart.showLoading({
text: "图表数据正在努力加载..."
});
//通过ajax向后台发送请求。传递数据。
$.ajax({
type: 'GET',
url : '<%=path %>/operate/sjkyx/getothercharts',
dataType: 'json',
success:function(data){
debugger;
option.xAxis[0]['data']=data.xAxisArr;
option.series[0]['data']=data.usedArr;
option.series[1]['data']=data.restArr;
myChart.setOption(option);
},
error:function(){
debugger;
},
complete:function(){
//无论数据接口成功或异常。都最终加载提示
myChart.hideLoading();//停止动画加载提示
}
})
}
function drawchkjCharts(ec,theme){
var myChart = ec.init(document.getElementById("chkj"),theme);
options = {
tooltip : {
show:false,
trigger: 'axis',
axisPointer : { // 坐标轴指示器。坐标轴触发有效
type : 'shadow' // 默觉得直线,可选为:'line' | 'shadow'
},
formatter: function (params){
return params[0].name + '<br/>'
+ params[0].seriesName + ' : ' + params[0].value + '<br/>'
+ params[1].seriesName + ' : ' + (params[1].value + params[0].value);
}
},
grid:{
x:20,
y:50,
x2:0,
y2:35
},
toolbox: {
show : false,
feature : {
mark : {show: true},
dataView : {show: true, readOnly: false},
restore : {show: true},
saveAsImage : {show: true}
}
},
calculable : false,
xAxis : [
{
type : 'category',
data : [],
splitLine:{
show:false
},
axisTick:false,
axisLine:false,
axisLabel:{
rotate:0,
margin:10,
textStyle:{
fontSize : '2px',
fontFamily : '微软雅黑',
color: 'red'
}
},
}
],
yAxis : [
{
type : 'value',
axisLine:false,
splitLine:{
show:false
},
axisTick:false,
boundaryGap: [0, 0.1],
axisLabel:{
show:false
}
}
],
series : [
{
name:'已使用',
type:'bar',
stack: 'sum',
barCategoryGap: '50%',
barWidth:45,
itemStyle: {
normal: {
color: 'red',
barBorderColor: 'red',
barBorderWidth: 4,
barBorderRadius:0,
label : {
show: true, position: 'insideTop',
formatter:'{c}'+'T'
}
}
},
data:[]
},
{
name:'未使用',
type:'bar',
stack: 'sum',
itemStyle: {
normal: {
color: '#fff',
barBorderColor: 'red',
barBorderWidth: 3,
barBorderRadius:0,
label : {
show: true,
position: 'top',
formatter:'{c}'+'T',
textStyle: {
fontSize : '10',
fontFamily : '微软雅黑',
color: 'red'
}
}
}
},
data:[]
}
]
};
myChart.showLoading({
text: "图表数据正在努力加载..."
});
$.ajax({
type: 'GET',
url : '<%=path %>/operate/sjkyx/getcskjcharts',
dataType: 'json',
success:function(data){
debugger;
options.xAxis[0]['data']=data.xAxisArr;
options.series[0]['data']=data.usedArr;
options.series[1]['data']=data.restArr;
myChart.setOption(options);
},
error:function(){
debugger;
},
complete:function(){
//无论数据接口成功或异常,都最终加载提示
myChart.hideLoading();//停止动画加载提示
}
})
}
</script>
</head>
<body style="height:160px;width:450px;text-align:left;">
<div>
<div id="chkj" style="height:160px;width:20%;text-align:right;float:left;">
</div>
<div id="other" style="height:160px;width:80%;text-align:right;float:right;">
</div>
</div>
</body>
</html>
项目整理--Echarts前端后台的贯通写法的更多相关文章
- crm项目整理
crm项目整理 一.开发背景 由于公司人员的增多,原来通过excel表格存取方式过于繁琐,而且对于公司人员的调配和绩效考核等不能做到精确处理,所以开发crm系统,开始开发只是针对销售人员和客户,后 ...
- 前端导出Excel兼容写法
今天整理出在Web前端导出Excel的写法,写了一个工具类,对各个浏览器进行了兼容. 首先,导出的数据来源可能有两种: 1. 页面的HTML内容(一般是table) 2. 纯数据 PS:不同的数据源, ...
- 前端后台以及游戏中使用Google Protocol Buffer详解
前端后台以及游戏中使用Google Protocol Buffer详解 0.什么是protoBuf protoBuf是一种灵活高效的独立于语言平台的结构化数据表示方法,与XML相比,protoBuf更 ...
- 使用前端后台管理模板库admin-lte(转)
使用前端后台管理模板库admin-lte 使用前端后台管理模板库admin-lte 安装 搭建环境 安装 安装admin-lte,可以通过以下几种办法安装,下图是GitHub中admin-lte的主页 ...
- Ztree的简单使用和后台交互的写法(二)
针对Ztree的简单使用和后台交互的写法(一)中的树进行改进 1.增加节点的权限 由页面的当前用户,决定树的根节点 然后动态获取树的详细节点: 初始化函数为: function init(){ //初 ...
- 【转】GitHub平台最火Android开源项目整理——2013-08-25 17
http://game.dapps.net/news/developer/9199.html GitHub在中国的火爆程度无需多言,越来越多的开源项目迁移到GitHub平台上.更何况,基于不要重复造轮 ...
- vue项目使用echarts按需引入实现地图动态显示效果时,报错:TypeError: Cannot read property 'dataToPoint' of undefined
vue项目使用echarts按需引入实现地图动态显示效果时,报错:TypeError: Cannot read property 'dataToPoint' of undefined 借鉴了该大神的文 ...
- idea启动项目连接mysql数据库后台报duplicate name异常
自己写的sql语句在MySQL数据库中运行是没有问题的 但是在使用idea启动项目的时候,后台在运行这行sql语句的时候居然报错了,duplicate name:重复的名字,最后自己经过思考,修改了一 ...
- 内网 Ubuntu 20.04 搭建 docusaurus 项目(或前端项目)的环境(mobaxterm、tigervnc、nfs、node)
内网 Ubuntu 20.04 搭建 docusaurus 项目(或前端项目)的环境 背景 内网开发机是 win7,只能安装 node 14 以下,而 spug 的文档项目采用的是 Facebook ...
随机推荐
- logging模块,程序日志模板
6.11自我总结 1.logging模块 用于程序的运行日志 1.初级 #首先程序运行分会出现5中情况 1.logging.info('info') #程序正常运行级别为10 2.logging.de ...
- linux下ls出现文件的后缀有@,* ,/之类的解释
ls -Fafptool* img_maker* lzcmp@ lzfgrep@ lzma* lzmore* node-pre-gyp@bower@ ...
- git2--常用命令
Git 命令详解及常用命令 Git作为常用的版本控制工具,多了解一些命令,将能省去很多时间,下面这张图是比较好的一张,贴出了看一下: 关于git,首先需要了解几个名词,如下: ? 1 2 3 4 Wo ...
- Java-确定被加载类的路径
如何输出当前类在硬盘的物理路径 package com.tj; import java.net.URL; import java.security.CodeSource; import java.se ...
- log4j动态日志级别调整
1. 针对root logger的设置 log4j.rootLogger=INFO, CONSOLELogger.getRootLogger().setLevel(org.apache.log4j.L ...
- Python requests模块params、data、json的区别
json和dict对比 json的key只能是字符串,python的dict可以是任何可hash对象(hashtable type): json的key可以是有序.重复的:dict的key不可以重复. ...
- 【U+B+D】三层框架 原理+实例
导读:三层的学习,也终于得到收获了.这个过程很艰辛,不止一次的想放弃.在这一个学习过程中,真的很感谢师傅的尽心.耐心.费心.其实真的很脆弱,现在回想起来都很不可思议. 一.基本概况 1,什么是三层 我 ...
- PTA 07-图6 旅游规划 (25分)
题目地址 https://pta.patest.cn/pta/test/15/exam/4/question/717 5-9 旅游规划 (25分) 有了一张自驾旅游路线图,你会知道城市间的高速公路 ...
- RAISERROR 的用法(转)
raiserror 的作用: raiserror 是用于抛出一个错误.[ 以下资料来源于sql server 2005的帮助 ] 其语法如下: RAISERROR ( { msg_id | msg ...
- shell的case-esac
case ... esac 与其他语言中的 switch ... case 语句类似,是一种多分枝选择结构. case 语句匹配一个值或一个模式,如果匹配成功,执行相匹配的命令.case语句格式如下: ...