学习SVN02
代码发布方案:
1,安装,优化 软件环境,(nginx,lvs) 《-------运维工程师
2,程序代码(不断更新)。 《--------开发工程师,(开发,运维都可以发布)
3,配置变更(不断变更)。 《--------运维工程师。
一、版本控制管理工具SVN详解
1.1 什么是SVN(subversion) ?
SVN是近年来非常优秀的版本管理工具,与CSV管理工具一样,SVN是一个跨平台开元版本控制系统,但是SVN与众不同的是,SVN会备份并记录每个文件每一次的修改更新变动。这样我们可以把任意一个时间点档案恢复到想要的某一个旧版本,当然也可以直接浏览指定文件的更新历史记录
SVN的相关站点:
1
2
3
4
|
http: //subversion.tigris.org/ http: //subversion.apache.org/ SVN客户端:http: //tortoisesvn.net/ SVN中文网站:http: //svndoc.iusesvn.com/ |
目前为止:常见的版本管理软件有:vss,CVS,SVN,git
1.1.2 SVN 与git的区别 ?
SVN是一个集中式数据管理中心,存在一个中央版本库,所有开发人员所使用的代码都是来源于版本库,提交代码也是这个中央版本库。
SVN版本控制系统工作流程:
a,在中央库上创建或者从主干复制一个分支
b,从中央库check out下这个分支代码
c,增加自己的代码,修改,删除代码文件
d, commit 代码。假设有人刚刚在分支提交了代码,你就会被提醒代码过期
你需要先update你的代码,然后在提交。
优缺点:
当无法连接到中央版本库的环境下,你无法提交代码,将代码加入版本控制。
你无法查看代码的历史版本以及版本的变化过程。提交到版本控制系统的代码我们都默认通过自测可运行。如果某个模块的代码比较复杂,不能短时间内实现可测试的功能,那么需要更长时间提交自己的代码,因此需要备份存储做备份。这点分布式的版本控制系统比较好点
SVN的备份要备份所有代码数据以及所有更改的新版本记录
1.1.2.2 git分布式版本控制
git中没有了中央分布式,但是为了开发小组的代码共享,我们通常还是会搭建一个远程git仓库,从某种意义上说,本地的git和远程的git仓库没有主从之分.
a.如果你本地创建一个git库,并将其add到远程git库中
b,你在本地添加或者删除文件,然后commit,当然commit操作都是提交到本地的git库中了,(也就是提交到了本地git目录的object目录中去了)
c,将本地的git库的分支push到远程git库的分支,如果这时候远程git库中,以及分别有了别人的push,那么远程git的分支不允许你push,到这个时候需要先pull,然后如果有冲突处理好冲突,commit到本地git,在push到远程git库
1.1.3 运维需要掌握的技术点:
a,安装,部署,维护,排障
b,简单应用,很多公司由开发来管理,包括建立新仓库,添加,删除账号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
1.2.0 svn服务运行方式与访问方式 1.2.1 SVN服务端运行方式 SVN服务常见的运行访问方式有3种: a,独立服务器访问 访问地址:SVN://svn.etiantian.org/sadoc b,借助Apache等http服务 访问地址如: http://svn.etiantian.org/sadoc b1,单独安装Apache+svn 不推荐,比较土 b2,csvn(apache+svn)是一个单独的整合软件,带web界面管理的SVN软件. c,本地直接访问 访问方式file://application/svndata/sadoc 一般在SVN服务器本地使用 我们主要以第一种和第二种的CSVN web 管理方式 1.2.1.1 SVN客户端访问方式 file:// 直接本地磁盘或者网络磁盘访问版本库 http:// 通过webDAV 协议访问subversion的Apache服务器 https:// 与http://相似,但是用ssl加密访问 SVN:// 通过头tcp/ip自定义协议访问SVNsever svn+ssh 通过认证加密tcp/ip自动以协议访问SVNserver服务器, |
1.3.1 SVN档案库数据格式
SVN存储版本数据有2种方式:BDB(一种事务安全型表类型 berkley DB) ,FSFS(一种不需要数据库的存储系统)BDB方式在服务器中断时候,可能锁住数据,所以还是FSFS方式更安全
FSFS 一个专门用于subversion版本库的文件系统后端,可以使用网络文件 系统(NFS,SMBFS)
SVN是一个基于关系型数据库BDB或者一系列二进制文件的FSFS
1.4.1 SVN集中式版本管理系统
SVN是一种集中式文件系统版本管理系统,集中式管理的工作流程如下图
集中式代码管理的核心是svn服务器,所有开发者新来的第一天必须从服务器获取代码,然后开发,最后解决冲突,提交,所有信息都放在svn服务器上。
1.4.2 开发者利用svn版本管理系统工作过程
举例说明:
a,从svn服务器下载项目最新代码。
b,进入自己的 分支,进行开发工作,每隔一段时间,提交一次,
c,下班时间,把自己的分支合并到服务器主分支上,一天的工作完成,并反映给服务器
缺点:
a,由于每次提交都会有一个原始副本,因此svn数据库容量会暴增
b,如果不能连接到svn服务器上,基本上不可以工作
c,不适合开源系统开发,开发人数较多,但是集中式管理非常明确权限管理机制,可以分层次管理
优点:
a,管理方便,逻辑清晰,明确。
b,易于管理,集中式svn服务器更容易保证数据安全性
c,代码一致性非常高
d,适合开发人数不多的项目开发
2.0安装配置svn服务
2.0.1准备操作系统并查看系统环境
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
[root@localhost ~] # cat /etc/redhat-release CentOS release 6.5 (Final) [root@localhost ~] # uname -r 2.6.32-431.el6.x86_64 [root@localhost ~] # yum install subversion -y [root@localhost ~] # rpm -qa | grep subversion subversion-1.6.11-15.el6_7.x86_64 [root@localhost ~] # sed -i 's#keepcache=0#keepcache=1#g' /etc/yum.conf [root@localhost ~] # grep keepcache /etc/yum.conf keepcache=1 rpm包安装后不清除 2.0.2配置并启动svn 建立svn版本数据存储根目录svndata,用户,密码,权限目录 [root@localhost ~] # mkdir -p /application/svndata/ --数据存储的根目录 [root@localhost ~] # mkdir -p /application/svnpasswd --用户,密码权限目录 启动svn服务,指定svn服务的根目录 [root@localhost ~] # svnserve -d -r /application/svndata/ [root@localhost ~] # ps -ef | grep svn root 1838 1 0 16:56 ? 00:00:00 svnserve -d -r /application/svndata/ 2.0.3 建立项目版本库,并且配置版本库 创建一个新的subversion项目sadoc,类似的这样显目可以创建多个,并对于不同的代码、 [root@localhost ~] # svnadmin create /application/svndata/sadoc -创建一个新的项目 2.0.4 修改,调整svn配置文件以及权限文件 配置允许用户wyb读写访问 cd /application/svndata/sadoc/conf [root@localhost conf] # cp svnserve.conf svnserve.conf.bak [root@localhost conf] # vim svnserve.conf 修改完之后如下 [root@localhost conf] # grep -Ev "^#|^$" svnserve.conf [general] anon-access = none auth-access = write password-db = /application/svnpasswd/passwd authz-db = /application/svnpasswd/authz [sasl] 把密码认证文件模块复制到相关的目录,这样方便同意管理 [root@localhost conf] # ls /application/svnpasswd/ [root@localhost conf] # cp passwd authz /application/svnpasswd/ [root@localhost conf] # ls /application/svnpasswd/ authz passwd [root@localhost conf] # ll /application/svnpasswd/ total 8 -rw-r--r-- 1 root root 1080 Oct 22 17:19 authz -rw-r--r-- 1 root root 309 Oct 22 17:19 passwd [root@localhost conf] # chmod 700 /application/svnpasswd/* [root@localhost conf] # ll /application/svnpasswd/ total 8 -rwx------ 1 root root 1080 Oct 22 17:19 authz -rwx------ 1 root root 309 Oct 22 17:19 passwd [root@localhost conf] # 新增用户,密码 提示: 1,等号前为SVN账号,等好后为密码,密码是明晚,注意密码权限700 2,更改svnserve.conf时候,需要重启svn,更改authz, passwd 文件时候不需要重启svn [root@localhost svnpasswd] #vim passwd [root@localhost svnpasswd] # cat passwd [ users ] # harry = harryssecret # sally = sallyssecret wyb = 123456 zhiyan = zhiyan [root@localhost svnpasswd] # [root@localhost svnpasswd] # vim authz 权限配置文件 格式说明 版本库目录格式: [<版本库>:/项目/目录] @<用户组名>=<权限> <用户名>=<权限> [/] 表示根目录。根目录就是svnserver启动时候,我们制定的 /application/svndata [/]就表示对全部版本库设置权限 [repos:/] 表示对版本库repository设置权限 [repos: /sadoc ] 表示对版本库repo中sadoc项目设置权限 [repos: /sadoc/wyb ] 表示对版本库repos中的sadoc项目的wyb目录设置权限 权限主体可以是用户组,用户,* ,用户组前面加@,*表示全部用户 权限可以是w ,r,wr和 空表示没有任何权限 authz 中每个参数都要定格写,开头不能有空格 对于组,要以开头@开头,用户不需要@开头 [root@localhost svnpasswd] #cat authz 新增部分 sagroup = wyb,zhiyan [sadoc:/] wyb = rw zhiyan = r @sagroup = r 注意: * 权限配置文件中出现的用户名必须是用户配置文件中定义 * 对权限配置文件的修改立即生效,不必重启svn 用户格式 [ groups ] 其中,1个用户组可以包含1个或者多个用户,用户可以逗号分隔。 此时svn安装完毕 3.1 windows客户端软件tortoisesSVN 下载地址:http: //tortoisesvn .net /downloads .html 由于目前安装的是svn独立访问方式,所以svn客户端链接服务器的方式如下 svn: //192 .168.2.48 /sadoc 用户名:gongli 密码:123456 3.1.2 linux客户端命令行使用说明 co checkout up update ci commit 3.1.2.1 从svn库提取数据 a, 将文件checkout到本地目录 Linux客户端,是checkout ,而不是update [root@localhost sadoc] # mkdir /svndata /svndata ---项目代码下载到、 /svndata/ 下 svn co svn: //192 .168.2.48 /sadoc/ /svndata/ --username=gongli --password=123456 3.1.2.2-查看服务器端的数据 [root@localhost svndata] # svn ls svn://192.168.2.48/sadoc/ --username=wyb --password=123456 -查看服务器端的数据 svn.txt ww.txt 新建文本文档.txt [root@localhost svndata] # [root@localhost svndata] # svn ls svn://192.168.2.48/sadoc/ --username=wyb --password=123456 --verbose 5 wyb Oct 23 10:59 ./ 1 wyb 8011 Oct 23 09:49 svn.txt 4 wyb 0 Oct 23 10:37 ww.txt 5 wyb 0 Oct 23 10:59 新建文本文档.txt 3.1.2.3 从本地提交到svn服务器 [root@localhost svndata] # touch a.html [root@localhost svndata] # svn add a.html A a.html [root@localhost svndata] # svn commit svn: Commit failed (details follow): svn: Could not use external editor to fetch log message; consider setting the $SVN_EDITOR environment variable or using the --message (-m) or -- file (-F) options svn: None of the environment variables SVN_EDITOR, VISUAL or EDITOR are set , and no 'editor-cmd' run- time configuration option was found [root@localhost svndata] # svn commit -m "svn ci data" Adding a.html Transmitting file data . Committed revision 6. [root@localhost svndata] # [root@localhost svndata] # svn ls svn://192.168.2.48/sadoc/ --username=wyb --password=123456 --verbose 6 wyb Oct 23 11:09 ./ 6 wyb 0 Oct 23 11:09 a.html 1 wyb 8011 Oct 23 09:49 svn.txt 4 wyb 0 Oct 23 10:37 ww.txt 5 wyb 0 Oct 23 10:59 新建文本文档.txt |
###########################################################################################
二、svn hooks
1.1.1钩子脚本:
写法就是系统中shell脚本程序的写法
当svn版本库发生改变时候,hooks就会触发相应作出执行命令 ,根据hooks输出或者返回的状态,hooks程序能够以某种方式执行该动作继续执行,停止或者挂起、
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
-rw-r--r-- 1 root root 2780 Oct 22 17:05 start-commit.tmpl [root@localhost hooks] # pwd /application/svndata/sadoc/hooks [root@localhost hooks] # ll total 36 -rw-r--r-- 1 root root 1977 Oct 22 17:05 post-commit.tmpl -rw-r--r-- 1 root root 1638 Oct 22 17:05 post-lock.tmpl -rw-r--r-- 1 root root 2289 Oct 22 17:05 post-revprop-change.tmpl -rw-r--r-- 1 root root 1567 Oct 22 17:05 post-unlock.tmpl -rw-r--r-- 1 root root 3426 Oct 22 17:05 pre-commit.tmpl -rw-r--r-- 1 root root 2410 Oct 22 17:05 pre-lock.tmpl -rw-r--r-- 1 root root 2786 Oct 22 17:05 pre-revprop-change.tmpl -rw-r--r-- 1 root root 2100 Oct 22 17:05 pre-unlock.tmpl -rw-r--r-- 1 root root 2780 Oct 22 17:05 start-commit.tmpl [root@localhost hooks] # |
对每种subversion版本库支持的钩子都有一个模板,通过查看这些脚本的内容,我们可以看到 的是什么事件触发了脚本以及如何给脚本传递数据
同时,这些模板也是如何使用这些脚本,结合subversion支持的工具来完成任务的例子。
要实际安装一个可用的钩子,你需要在repo/hooks 目录下安装一些与钩子同名的可执行的程序或者脚本
注意:
由于安全原因,subversion版本库在一个空环境中执行钩子脚本就是没有任何环境变量,甚至没有$PATH或者%PATH% 由于这个原因,许多管理员会感到困惑, 他们的钩子脚本手工运行时正常,可以在subversion中却不能运行。 要注意,必须在你的钩子中设置好“环境变量”或者为你的程序制定好“绝对路径”
1.1.2 svn的hooks模板
1.1.2.1常用的钩子脚本
post-commit 在提交完成成功创建版本之后执行该钩子,提交已经完成,不可更改,因此,本脚本的返回值被忽略提交完成时候出发事务
pre-commit 提交完成触发执行该脚本
start-commit
在客户端还没有向服务器提交数据之前,即还没有建立 subversiontransaction之前执行该脚本
1.2 svn hooks生产环境应用场景举例
pre-commit
限制上传文件大小扩展名及大小,控制提交要输入的信息等、
post-commit
svn 更新自动周知,MSN,邮件短信周知
svn更新触发checkout程序,然后实时rsync送到服务器等
1.2.1 svn钩子生产应用实战。
案例一:rsync与svn钩子结合实现数据同步某企业小案例
a,建立同步web目录:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
[root@localhost hooks] # mkdir -p /data/www b,将svn中内容checkout到WEB目录一份 [root@localhost www] # svn co svn://192.168.2.48/sadoc /data/www/ --username=wyb --password=123456 [root@localhost www] # ls a.html b.html c.html svn.txt ww.txt 修改hooks脚本,进行同步 chmod 755 /application/svndata/sadoc/hooks/post-commit [root@localhost svndata] # more /application/svndata/sadoc/hooks/post-commit #!/bin/bash REPOS= "$1" REV= "$2" export LC_CTYPE= "en_US.UTF-8" export LC_ALL= LOGPATH= "app/log" [! -d ${LOGPATH} ] && mkdir ${LOGPATH} -p ##update content from svn SVN= /usr/bin/svn $SVN update --username wyb --password 123456 /data/www/ if [ $? - eq 0 ] then /usr/bin/rsync -az --delete /data/www/ /tmp/ fi [root@localhost svndata] # touch wwwwwwwwwwwwwwwww [root@localhost svndata] # svn add wwwwwwwwwwwwwwwww A wwwwwwwwwwwwwwwww [root@localhost svndata] # svn commit -m "wwwwwwww" Adding wwwwwwwwwwwwwwwww Transmitting file data . Committed revision 13. [root@localhost svndata] # svn ls svn://192.168.2.48/sadoc/ --username=wyb --password=123456 --verbose 13 wyb Oct 23 15:11 ./ 9 wyb 15 Oct 23 11:34 a.html 12 wyb 0 Oct 23 15:09 asd.txt 7 wyb 0 Oct 23 11:28 b.html.txt 8 wyb 0 Oct 23 11:30 c.html.txt 11 wyb 0 Oct 23 15:08 hh.txt 1 wyb 8011 Oct 23 09:49 svn.txt 4 wyb 0 Oct 23 10:37 ww.txt 13 wyb 0 Oct 23 15:11 wwwwwwwwwwwwwwwww [root@localhost svndata] # [root@localhost svndata] # ls /tmp/ a.html asd.txt b.html.txt c.html.txt hh.txt svn.txt ww.txt wwwwwwwwwwwwwwwww |
写钩子脚本的注意事项:
a,钩子脚本的权限要允许svn执行,一般可以设置 chmod 755 post-commit
b,钩子脚本尽可能定义环境变量,主要是用过的命令的路径,因为svn考虑安装的问题,不会调用系统环境变量,所以如果发现手动执行post-
commit没有问题,但是自动还有可能无法执行
c,这个笔记的案例脚本,在svn update之前先要手动checkout一份出来,还有尽可能要加上用户密码,如果只是手动一样会更新,但是如果触
发可能就会不能更新
#####################################################
SVN 远程同步程序代码到远端的WEB服务器参考方法
方法一:http://biancheng.dnbcw.info/linux/345531.html
方法二:http://os.51cto.com/art/201410/454887.htm
#######################################################
案例二:
利用pre-commit 限制上传文件扩展名及大小
.
.
.
.
.
.
.
.
.
###############################################################
代码上线的解决方案,案例
1.1小型格式的代码上线案例
1.2 中型企业上线解决方案:
1.3大型企业上线解决方案:
ITIL BSWx
集群环境中分批更新
代码上线解决方案注意事项:
1,上线的流程里,办公测试环境---》IDC测试环境----》正式生产环境,所有环境软件版本均应统一,否咋后患无穷;
2,开发团队小组办公内部测试环境(该环境由开发小组维护,或者定时自动更新代码),代码有问题返回给某个开发人员
3,有专门的测试工程师,程序有问题直接返回给开发人员
4,IDC测试有测试和运维参与,叫IDCtest,进行程序压力测试,有问题直接返回给开发人员。无问题上生产环境
5,数台服务器代码分发上线方案例子(Java程序)::::::
a,假设同业服务器有6台,分为2组,A组三台,B组三台,先对A进行平滑下线,B组正常提供服务,避免影响业务
b, 下线是通过脚本将A组的服务器从RS池(LVS,NGINX,HAPROXY,F5)等负载均衡器平滑提出,避免负载均衡器将请求送给
A组服务器,(此时在流量低峰期)
学习SVN02的更多相关文章
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- Unity3d学习 制作地形
这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...
- 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...
- 菜鸟Python学习笔记第一天:关于一些函数库的使用
2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
随机推荐
- 【Windows 操作系统】Windows 进程的内核对象句柄表
总结: 1.句柄就是进程句柄表中的索引.2.句柄是对进程范围内一个内核对象地址的引用,一个进程的句柄传给另一个进程是无效的.一个内核对象可用有多个句柄.Windows之所以要设立句柄,根本上源于内存管 ...
- 原生数据类型 nint,nuint,nfloat
原生数据类型根据操作系统32位 64位的不同,用这个关键定义的数据大小也不一样. 比如 nint 在 Xamarin.iOS 中,是 native int(原生整数)的缩写.当设备是 Apple 发布 ...
- Iptables 防火墙常用配置
转至:https://blog.csdn.net/lswzw/article/details/87971259 Iptables 防火墙常用配置 概念 命令行模式 查看 & 命令 -n:直接显 ...
- Java课程设计---新建项目及导入如何jar包
1.新建项目 2.添加lib并导入mysql驱动jar包 3.项目目录结构介绍 为了将项目划分清楚,下面将新建如下几个包
- 基于Lumisoft.NET组件,使用IMAP协议收取邮件
在早期一直使用Lumisoft.NET组件来进行邮件的处理查找,对于邮件的处理非常方便,之前在随笔<基于Lumisoft.NET组件的POP3邮件接收和删除操作>中也介绍过基于POP3和S ...
- WPF优秀组件推荐之MahApps
概述 MahApps是一套基于WPF的界面组件,通过该组件,可以使用较小的开发成本实现一个相对很好的界面效果. 官方网站:MahApps.Metro - Home 开源代码:MahApps · Git ...
- Node.js躬行记(16)——活动配置化
一直想将一些常规活动抽象化,制作成可配置的.原先的计划是做成拖拽的,那种可视化搭建,运营也能自己搭建页面. 这是一个美好的愿景,但是现实不允许我花太多精力去制作这样一个系统.经过权衡后,先设计成一个可 ...
- tp6微信公众号开发者模式自定义菜单
1,参考上篇博客,获取access_token https://www.cnblogs.com/xiaoyantongxue/p/15803334.html 2:控制器写以下代码 /* * 获取普通a ...
- laravel7 路由引入,避免上线路由不统一
1:新建 目录admin,新建文件夹route.php 2:将需要的路由写在route.php中即可. 3:在web.php 引入即可 include base_path('routes/admin ...
- tp 5 三级联动查询(自写)
思路: 1.定义路由 2.查询顶级分类(pid=0)发送至制图 3.循环展示 4.给顶级分类下拉框绑定内容改变事件(JS:onchange.JQ:change) 5.获取到选中的option的valu ...