CENTOS 搭建SVN服務器(附自動部署到遠程WEB)


安裝subversion服務端

# 安裝
yum install -y subversion

# 測試是否安裝成功 如果顯示了版本信息則表示安裝成功
svnserve --version;sleep 5s

# svn配置建立svn版本庫目錄可建多個:
PATHSSS="/home/svn"
echo SVN倉庫將創建在:$PATHSSS;sleep 5s

# 新建一個版本庫目錄
mkdir -p $PATHSSS
cd $PATHSSS
# 建立svn版本庫:
svnadmin create $PATHSSS

# 先設置passwd
cat >$PATHSSS/conf/passwd<<ANGIE.K
[users]
jianglinzhi = jianglinzhi
root1 = root
ANGIE.K

# 再設置權限authz
cat >$PATHSSS/conf/authz<<ANGIE.K
[groups] #用戶組
admin = jianglinzhi,root1
coder = coders1,coders2,coders3
ui_and_ue = ui1,ui2,ui3
[/] #/倉庫權限
@admin = rw
@coder = rw
@ui_and_ue = rw
ANGIE.K

# 最后設定svnserve.conf
cat >$PATHSSS/conf/svnserve.conf<<ANGIE.K
[general]
# 使非授權用戶無法訪問
anon-access = none
# 使授權用戶有寫權限
auth-access = write
# 用戶密碼文件
password-db = passwd
# 訪問控制文件
authz-db = authz
# 認證命名空間,subversion會在認證提示里顯示,並且作為憑證緩存的關鍵字。
realm = 姜林志的第一個SNV服務器 歡迎你.
ANGIE.K

# 啟動 默認端口 3690
killall svnserve
svnserve -d -r $PATHSSS

# 加入開機啟動
echo svnserve -d -r $PATHSSS >> /etc/rc.local

配置和管理svn

1). 每個倉庫的配置文件在$repos/conf/下,vi svnserve.conf,
    配置項在[general]下: 
        anon-access:匿名用戶的權限,可以為read,write和none,默認值read。不允許匿名用戶訪問:anon-access = none 
        auth-access:認證用戶的權限,可以為read,write和none,默認值write。 
        password-db:密碼數據庫的路徑,去掉前邊的# 
        authz-db:認證規則庫的路徑,去掉前邊的#。 
  注意:這些配置項的行都要頂格,否則會報錯。修改配置后需要重啟svn才能生效。

2). 配置passwd文件 
    這是每個用戶的密碼文件,比較簡單,就是“用戶名=密碼”,采用的是明碼。如allen=111111 
    
3). 配置authz文件 
    1. [groups] section:為了便於管理,可以將一些用戶放到一個組里邊,比如:owner=allen,ellen 
    2. groups下邊的sections表示對一個目錄的認證規則,比如對根目錄的認證規則的section為[/]。
        設置單用戶的認證規則時一個用戶一行,如: 
            [/] 
            allen=rw  #allen對根目錄的權限為rw 
      ellen=r   #ellen對根目錄的權限為r 
      如果使用group,需要在group名字前加@,如 
      @owner=rw  #group owner中的用戶均為rw,等價於上邊的兩句話 
    啟動時如果從/home/.svn/astar啟動,/就是astar目錄,用如上方式以astar目錄為根設置權限。 
    如果從/home/.svn/啟動,每個倉庫根還是自己的起始目錄。可以采用如上方式設置astar的權限,也可以采用如下方式: 
      [astar:/] 
      @owner=rw 
    設置test的權限如下: 
      [test:/] 
      @harry_and_sally = rw 
            簡言之,每個倉庫的根目錄(/)就是自己的起始目錄;[repos:/]這種方式只適用於多倉庫的情況;[/]適合於單倉庫和單倉庫的方式。 
    3. 不能跨越倉庫設置權限。
配置和管理

導入工程和第一次檢出

導入到倉庫

cd 進入工程目錄上一級
執行:

#導入前先處理下WIN不支持的文件名 如  : * ? " < > |
# find ./ -name "*\?*" #查找
# find ./ -name "*\?*" -print -exec rm -rf {} \; #刪除
# find ./ -name "*\:*" -print -exec rm -rf {} \; #刪除
# find ./ -name "*\"*" -print -exec rm -rf {} \; #刪除
# find ./ -name "*\<*" -print -exec rm -rf {} \; #刪除
# find ./ -name "*\>*" -print -exec rm -rf {} \; #刪除
# find ./ -name "*\|*" -print -exec rm -rf {} \; #刪除

提示:如果你設置了pre-commit鈎子(比如:強制要求注釋,請先解除這個鈎子,以免導入失敗)

svn import 待導入工程路徑(目錄) svn://127.0.0.1/定義工程在倉庫的目錄名字 -m "對於本次操作的注釋"
或者 切換到待導入目錄
svn import ./ svn://127.0.0.1/定義工程在倉庫的目錄名字 -m "對於本次操作的注釋"

將在倉庫中新建工程目錄和文件

檢出到工程

cd 進入工程目錄 執行即可

svn co svn://127.0.0.1 ./

判定程序員是否為補丁添加注釋(per-commit)

這個鈎子腳本,在每次commit之后會執行,格式是SHELL腳本,是從網上收集來的測試可用
這個文件的詳細路徑請看下面的cd命令

cd $PATHSSS/hooks
cp per-commit.tmpl per-commit
chmod 755 per-commit
vi $PATHSSS/hooks/per-commit
###############################################
#!/bin/sh
# PRE-COMMIT HOOK
# .... 中間省略
# http://svn.apache.org/repos/asf/subversion/trunk/contrib/hook-scripts/
REPOS="$1"
TXN="$2"
SVNLOOK=/usr/bin/svnlook

LOGMSG=`$SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA-Z0-9]" | wc -c` 
if [ "$LOGMSG" -lt 8 ];#要求注釋不能少於8個字符,您可自定義 
then 
echo -e "\n======================================================" 1>&2
echo -e "\n請在Commit(提交)前為您的補丁添加必要的注釋。\n本次提交被忽略。" 1>&2
echo -e "\n======================================================" 1>&2 
exit 1 
fi

自動同步到WEB服務器(post-commit)

這個鈎子腳本,在每次commit之后會執行,格式是SHELL腳本,是從網上收集來的測試可用
這個文件的詳細路徑請看下面的cd命令

# 配置自動發布到WEB服務器 編輯 post-commit 文件
cd $PATHSSS/hooks
cp post-commit.tmpl post-commit
chmod 755 post-commit
vi $PATHSSS/hooks/post-commit
###############################################
#!/bin/sh
# -------------------------------------------------------------------------------
# Filename:    post-commit
# Description: WEB server with synchronization code by SVN
# -------------------------------------------------------------------------------
#Version 1.0
#當用戶把代碼提交完成時,把代碼中的最新更改同步到 WEB服務器,同時注意不包括刪除操作。

#Set variable
SVN=/home/svn
SVNUSER=root1
SVNPASD=root
WEB=/home/ftp/svn #待上傳到WEB服務器的文件存放路徑 第一次 需要先到該目錄檢出一次svn co svn://127.0.0.1 ./
 
WEBIP="192.168.0.23"
RSYNC=rsync
LOG=/home/svn/post-commit.log
export LANG=en_US.UTF-8

mkdir -p $SVN
mkdir -p $WEB

#更新文件到本地文件夾
svn update $WEB --username $SVNUSER --password $SVNPASD
#如果前面的代碼成功完成,會繼續執行下面的代碼
if [ $? == 0 ]
then
    echo ""     >> $LOG
    echo `date` >> $LOG
    echo "##############################" >> $LOG
    chown -R nobody:nobody $WEB
    #同步代碼從SVN服務器到WEB服務器 通過RSYNC
    $RSYNC -vaztpH  --timeout=90   --exclude-from=$SVN/exclude.list $WEB root@$WEBIP:$WEB/ >> $LOG
fi

完善后的另外一個版本

#!/bin/sh

# POST-COMMIT HOOK
# ... 省略
# http://svn.apache.org/repos/asf/subversion/trunk/contrib/hook-scripts/

# mailer.py commit "$REPOS" "$REV" /path/to/mailer.conf
echo -e "[1 fo 6]================================\n`date`:這次更新將發布到測試和WEB。" 1>&2 

# 庫的路徑
REPOS="$1"

# 新提交的版本號
REV="$2"

changed=$(svnlook changed -r $REV $REPOS)
echo $changed > /home/svn/hooks/last_changed
echo $REPOS >> /home/svn/hooks/last_changed
echo $REV >> /home/svn/hooks/last_changed


######################################################################################
# 配置自動發布到WEB服務器 編輯 post-commit 文件 ######################################
######################################################################################
# -------------------------------------------------------------------------------
# Filename:    post-commit
# Description: WEB server with synchronization code by SVN
# -------------------------------------------------------------------------------
#Version 1.1
#當用戶把代碼提交完成時,把代碼中的最新更改同步到 WEB服務器,同時注意不包括刪除操作。

#Set variable
SVN=/home/svn
SVNUSER=root1
SVNPASD=root

# 測試服務器路徑
WEB1=/home/ftp/e/ecshop_2013/wwwroot
WEB2=/home/ftp/c/customer/wwwroot

# 遠端服務器IP
WEBIP="192.168.1.1"

# 同步方式
RSYNC=rsync

# 同步日志
LOG=/home/svn/post-commit.log

# 避免亂碼
export LANG=en_US.UTF-8

mkdir -p $SVN

#更新文件到本地文件夾
svn update $WEB1  --username $SVNUSER --password $SVNPASD
svn update $WEB2  --username $SVNUSER --password $SVNPASD



# 必須要檢出成功才開始執行下面的 #####################################################
if [ $? == 0 ]
then
    echo -e "[2 fo 6]================================\n`date`:文件順利檢出到測試項目。" 1>&2 


######################################################################################
# 這里是解析本次操作的文件名 用於提高修改權限的速度 ##################################
######################################################################################
    echo -e "[3 fo 6]================================\n`date`:正在改變文件歸屬,為上傳到WEB服務器准備。" 1>&2 
    str=$changed

    # 字符串變成類似數組的東西,下面的for可以一次打印一個出來
    var=`echo $str | awk -F',' '{print $0}' | sed "s/,/ /g"`

    # list為文件名和SVN標記碼一次搞一個出來
    for list in $var
    do
        # 獲取每次list字符串的長度
        filesneme_len=`expr length $list`
        # 這個if對長度小於1的文件名過濾掉>符號需要轉義
        if [ "$filesneme_len" \> "1" ]
        then
            # 這里取得的是字符串的第一個/前后的字符串 分別為倉庫名字和帶路徑文件名
            #echo 倉庫:${list%%/*}
            #echo 文件:/${list#*/}
        
            # 根據倉庫名字給文件分派權限
            if [ "${list%%/*}" == "ec_qiuyi" ]
            then 
                #設定檢出文件為用戶組1
                echo 設定檢出文件為用戶組1
                echo 倉庫:${list%%/*}
                echo 文件:/${list#*/}
                chown 1000:1100 $WEB1/${list#*/}
                # 只同步修改的內容
                rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB1/${list#*/}" "root@$WEBIP:$WEB1\_svn/${list#*/}" >> $LOG
            fi
            
            if [ "${list%%/*}" == "customer" ]
            then
                #設定檢出文件為用戶組2
                echo 設定檢出文件為用戶組2
                echo 倉庫:${list%%/*}
                echo 文件:/${list#*/}
                chown 1002:1100 $WEB2/${list#*/}
                # 只同步修改的內容
                rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB2/${list#*/}" "root@$WEBIP:$WEB2\_svn/${list#*/}" >> $LOG
            fi
        fi
    done
    echo -e "[4 fo 6]================================\n`date`:文件歸屬修改完成。" 1>&2 


######################################################################################
# 記錄日志和上傳文件 #################################################################
######################################################################################

    echo ""     >> $LOG;echo `date` >> $LOG;echo "##############################" >> $LOG 
# 修改新檢出文件的權限
# chown -R 1000:1100 $WEB
# chown -R 1002:1100 $WEB2
#同步代碼從SVN服務器到WEB服務器 通過RSYNC
#$RSYNC -vaztpH  --timeout=90   --exclude-from=$SVN/exclude.list $WEB root@$WEBIP:$WEB/ >> $LOG

    echo -e "[5 fo 6]================================\n`date`:正上傳到WEB服務器,並檢查文件完整。" 1>&2


    # 同步完整內容 如目錄刪除文件刪除之類..
    
    rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB1/" "root@$WEBIP:$WEB1\_svn/" >> $LOG
    rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB2/" "root@$WEBIP:$WEB2\_svn/" >> $LOG


    echo -e "[6 fo 6]================================\n`date`:代碼已經發布到遠端WEB。" 1>&2 
    
fi
# 利用鈎子錯誤退出 輸出過程信息
exit 1
View Code

完善后的另外二個版本

#!/bin/sh

######################################################################################
# 配置自動發布到WEB服務器 編輯 post-commit 文件 ######################################
######################################################################################
# -------------------------------------------------------------------------------
# Filename:    post-commit
# Description: WEB server with synchronization code by SVN
# -------------------------------------------------------------------------------
#Version 1.0
#當用戶把代碼提交完成時,把代碼中的最新更改同步到 WEB服務器,同時注意不包括刪除操作。


echo -e "[1 fo 6]================================\n`date`:這次更新將發布到測試和WEB。" 1>&2 

# 庫的路徑
REPOS="$1"

# 新提交的版本號
REV="$2"

changed=$(svnlook changed -r $REV $REPOS)
echo $changed > /home/svn/hooks/last_changed
echo $REPOS >> /home/svn/hooks/last_changed
echo $REV >> /home/svn/hooks/last_changed


#Set variable
SVN=/home/svn
SVNUSER=本地管理員ID
SVNPASD=本地管理員密碼

mkdir -p $SVN

# 測試服務器路徑
WEB1=/home/ftp/e/ecshop_2013/wwwroot
WEB2=/home/ftp/c/customer/wwwroot
WEB3=/home/ftp/u/ugg_ecshop_2013/wwwroot
WEB4=/home/ftp/l/luck_ecshop_2013/wwwroot

# 同步標記
WEB1_SYNC=NO
WEB2_SYNC=NO
WEB3_SYNC=NO
WEB4_SYNC=NO

# 待同步操作數
WEB1_SYNC_NUM=0
WEB2_SYNC_NUM=0
WEB3_SYNC_NUM=0
WEB4_SYNC_NUM=0


# 同步方式
RSYNC=rsync




# 同步日志
LOG=/home/svn/post-commit.log
echo "================================================" > $LOG
echo `date`:這是最近一次SVN提交的信息。>> $LOG
echo "================================================" >> $LOG


mkdir -p $WEB1
mkdir -p $WEB2
mkdir -p $WEB3
mkdir -p $WEB4

# 第一次需要檢出
# svn co svn://127.0.0.1/ec_ugg ./

# 遠端服務器IP
WEBIP_QY="192.168.1.1"
WEBIP_UG="192.168.1.2"
WEBIP_LU="192.168.1.3"



# 避免亂碼
export LANG=en_US.UTF-8

#更新文件到本地文件夾
echo "================================================" >> $LOG
echo "更新文件到本地文件夾" >> $LOG
svn update $WEB1  --username $SVNUSER --password $SVNPASD >> $LOG
svn update $WEB2  --username $SVNUSER --password $SVNPASD >> $LOG
svn update $WEB3  --username $SVNUSER --password $SVNPASD >> $LOG
svn update $WEB4  --username $SVNUSER --password $SVNPASD >> $LOG
echo "================================================" >> $LOG

# 必須要檢出成功才開始執行下面的 #####################################################
if [ $? != 0 ] ; then
    echo -e "項目檢出失敗,同步終止!" 1>&2
    exit $?
fi
echo -e "[2 fo 6]================================\n`date`:文件順利檢出到測試項目。" 1>&2

######################################################################################
# 這里是解析本次操作的文件名 用於提高修改權限的速度 ##################################
######################################################################################
echo -e "[3 fo 6]================================\n`date`:正在改變文件歸屬,為上傳到WEB服務器准備。" 1>&2 
str=$changed

# 字符串變成類似數組的東西,下面的for可以一次打印一個出來
var=`echo $str | awk -F',' '{print $0}' | sed "s/,/ /g"`

# list為文件名和SVN標記碼一次搞一個出來
for list in $var
do
    # 獲取每次list字符串的長度
    filesneme_len=`expr length $list`
    # 這個if對長度小於1的文件名過濾掉>符號需要轉義
    if [ "$filesneme_len" \> "1" ]
    then
        # 這里取得的是字符串的第一個/前后的字符串 分別為倉庫名字和帶路徑文件名
        #echo 倉庫:${list%%/*}
        #echo 文件:/${list#*/}
    
        # 根據倉庫名字給文件分派權限
        
        # 項目0
        if [ "${list%%/*}" == "ec_qiuyi" ]
        then 
            # 設定同步標記
            WEB1_SYNC="YES"
            # 累加標記
            WEB1_SYNC_NUM=$[$WEB1_SYNC_NUM+1]
            #設定檢出文件為用戶組1
            echo 設定檢出文件為用戶組1
            echo 倉庫:${list%%/*}
            echo 文件:/${list#*/}
            chown 1000:1100 $WEB1/${list#*/}
            # 只同步修改的內容
            #rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB1/${list#*/}" "root@$WEBIP_QY:$WEB1\_svn/${list#*/}" >> $LOG
            # 同步完整內容 如目錄刪除文件刪除之類..
            #rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB1/" "root@$WEBIP_QY:$WEB1\_svn/" >> $LOG # 項目0
        fi
        
        # 項目1
        if [ "${list%%/*}" == "customer" ]
        then
            # 設定同步標記
            WEB2_SYNC="YES"
            # 累加標記
            WEB2_SYNC_NUM=$[$WEB1_SYNC_NUM+1]
            #設定檢出文件為用戶組2
            echo 設定檢出文件為用戶組2
            echo 倉庫:${list%%/*}
            echo 文件:/${list#*/}
            chown 1002:1100 $WEB2/${list#*/}
            # 只同步修改的內容
            #rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB2/${list#*/}" "root@$WEBIP_QY:$WEB2\_svn/${list#*/}" >> $LOG
            # 同步完整內容 如目錄刪除文件刪除之類..
            #rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB2/" "root@$WEBIP_QY:$WEB2\_svn/" >> $LOG # 項目1
        fi
        
        # 項目2
        if [ "${list%%/*}" == "ec_ugg" ]
        then    
            # 設定同步標記
            WEB3_SYNC="YES"
            # 累加標記
            WEB3_SYNC_NUM=$[$WEB1_SYNC_NUM+1]
            #設定檢出文件為用戶組3
            echo 設定檢出文件為用戶組3
            echo 倉庫:${list%%/*}
            echo 文件:/${list#*/}
            chown 1000:1100 $WEB3/${list#*/}
            # 只同步修改的內容
            #rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB3/${list#*/}" "root@$WEBIP_UG:$WEB3\_svn/${list#*/}" >> $LOG
            # 同步完整內容 如目錄刪除文件刪除之類..
            #rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB3/" "root@$WEBIP_UG:$WEB3\_svn/" >> $LOG # 項目2

        fi
        
        # 項目3
        if [ "${list%%/*}" == "ec_luck" ]
        then
            # 設定同步標記
            WEB4_SYNC="YES"
            # 累加標記
            WEB4_SYNC_NUM=$[$WEB1_SYNC_NUM+1]
            #設定檢出文件為用戶組4
            echo 設定檢出文件為用戶組4
            echo 倉庫:${list%%/*}
            echo 文件:/${list#*/}
            chown 1000:1100 $WEB4/${list#*/}
            # 只同步修改的內容
            #rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB4/${list#*/}" "root@$WEBIP_LU:$WEB1\_svn/${list#*/}" >> $LOG
            # 同步完整內容 如目錄刪除文件刪除之類..
            #rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB4/" "root@$WEBIP_LU:$WEB1\_svn/" >> $LOG # 項目3
        fi        


    fi
done
echo -e "[4 fo 6]================================\n`date`:文件歸屬修改完成。" 1>&2 


######################################################################################
# 記錄日志和上傳文件 #################################################################
######################################################################################

echo ""     >> $LOG;echo `date` >> $LOG;echo "##############################" >> $LOG 
# 修改新檢出文件的權限
# chown -R 1000:1100 $WEB
# chown -R 1002:1100 $WEB2
#同步代碼從SVN服務器到WEB服務器 通過RSYNC
#$RSYNC -vaztpH  --timeout=90   --exclude-from=$SVN/exclude.list $WEB root@$WEBIP:$WEB/ >> $LOG

echo -e "[5 fo 6]================================\n`date`:正上傳到WEB服務器,並檢查文件完整。" 1>&2


# 同步完整內容 如目錄刪除文件刪除之類..
echo "================================================" >> $LOG
echo "同步完整內容 如目錄刪除文件刪除之類.." >> $LOG

if [ "$WEB1_SYNC" == "YES" ]
then
    echo -e "正同步($WEB1_SYNC_NUM個操作記錄)到 球衣服務器" 1>&2
    time rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB1/" "root@$WEBIP_QY:$WEB1\_svn/" >> $LOG # 球衣
fi

if [ "$WEB2_SYNC" == "YES" ]
then    
    echo -e "正同步($WEB2_SYNC_NUM個操作記錄)到 客服系統服務器" 1>&2
    time rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB2/" "root@$WEBIP_QY:$WEB2\_svn/" >> $LOG # 客服系統
fi

if [ "$WEB3_SYNC" == "YES" ]
then
    echo -e "正同步($WEB3_SYNC_NUM個操作記錄)到 UGG孩子服務器" 1>&2
    time rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB3/" "root@$WEBIP_UG:$WEB3\_svn/" >> $LOG # UGG鞋子
fi

if [ "$WEB4_SYNC" == "YES" ]
then
    echo -e "正同步($WEB4_SYNC_NUM個操作記錄)到 吉祥符服務器" 1>&2
    time rsync -vzurtopg '-e ssh -p 10079' --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB4/" "root@$WEBIP_LU:$WEB1\_svn/" >> $LOG # 吉祥符
fi

echo -e "[6 fo 6]================================\n`date`:代碼已經發布到遠端WEB。" 1>&2
echo "================================================" >> $LOG


# 利用鈎子錯誤退出 輸出過程信息
exit 1
View Code

一個強制要求程序員為自己的上傳注釋的鈎子(pre-commit)

REPOS="$1"
TXN="$2"

# Make sure that the log message contains some text.
SVNLOOK=/usr/bin/svnlook
# $SVNLOOK log -t "$TXN" "$REPOS" | \
# grep "[a-zA-Z0-9]" > /dev/null || exit 1


LOGMSG=`$SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA-Z0-9]" | wc -c` 
if [ "$LOGMSG" -lt 8 ];#要求注釋不能少於8個字符,您可自定義 
then 
echo -e "\n======================================================" 1>&2
echo -e "\n請在Commit(提交)前為您的補丁添加必要的注釋。\n本次提交被忽略。" 1>&2
echo -e "\n======================================================" 1>&2 
exit 1 
fi

# Check that the author of this commit has the rights to perform
# the commit on the files and directories being modified.
# commit-access-control.pl "$REPOS" "$TXN" commit-access-control.cfg || exit 1

# All checks passed, so allow the commit.
# exit 0
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM