COLT_CMDB_kingbase.sh

#!/usr/bin/env bash
#IT_BEGIN
#IT_TYPE=1
#IT DATABASE_Kingbase_ip|ip
#IT DATABASE_Kingbase_port|port
#IT DATABASE_Kingbase_version|version
#IT DATABASE_Kingbase_dbusername|dbusername
#IT DATABASE_Kingbase_hostname|hostname
#IT DATABASE_Kingbase_charset|charset
#IT DATABASE_Kingbase_datapath|data_path
#IT DATABASE_Kingbase_maxconnections|maxconnections
#IT DATABASE_Kingbase_passwordencryption|passwordencryption
#IT DATABASE_Kingbase_sharedbuffers|sharedbuffers
#IT DATABASE_Kingbase_maxstackdepth|maxstackdepth
#IT DATABASE_Kingbase_maxwalsize|maxwalsize
#IT DATABASE_Kingbase_minwalsize|minwalsize
#IT DATABASE_Kingbase_logdirectory|logdirectory
#IT DATABASE_Kingbase_installpath|installpath
#IT DATABASE_Kingbase_RunUser|RunUser
#IT DATABASE_Kingbase_CaseSensitive|CaseSensitive
#IT DATABASE_Kingbase_SchemaList|SchemaList
#IT_END

#set -euo pipefail
shname=$(basename "$0")
ATTR="_X(g=$shname,p=cmdb,t=script,f=0)"

# 获取主机名
hostname=$(hostname)

# 获取 IP 地址(优化兼容性)
get_ip() {
    local ip_commands=("ip" "ifconfig" "hostname")
    for cmd in "${ip_commands[@]}"; do
        if command -v "$cmd" >/dev/null 2>&1; then
            case "$cmd" in
                "ip")
                    ip -o addr show | awk '/inet / && !/127\.|inet6/ {print $4}' | cut -d'/' -f1 | tr '\n' ',' | sed 's/,$//'
                    return 0
                    ;;
                "ifconfig")
                    ifconfig -a | awk '/inet / && !/127\.|inet6/ {print $2}' | tr '\n' ',' | sed 's/,$//'
                    return 0
                    ;;
                "hostname")
                    hostname -I | tr ' ' ',' | sed 's/,$//'
                    return 0
                    ;;
            esac
        fi
    done
    echo ""
    return 1
}

ip=$(get_ip)

# 获取Kingbase进程信息(增强准确性)
get_kingbase_info() {
    # 1. 尝试通过pgrep查找
    local pid=$(pgrep -f "kingbase.*-D" | head -n1)
    
    # 2. 如果找不到,尝试通过ps查找
    [[ -z "$pid" ]] && pid=$(ps aux | awk '/[k]ingbase.* -D/ {print $2}' | head -n1)
    
    if [[ -z "$pid" ]]; then
        echo ",,,"
        return 1
    fi
    
    # 获取运行用户(多种方法尝试)
    local user=""
    # 方法1: 标准ps命令
    user=$(ps -o user= -p "$pid" 2>/dev/null | tr -d '[:space:]')
    
    # 方法2: 如果方法1失败,尝试通过/proc获取
    [[ -z "$user" ]] && user=$(stat -c '%U' /proc/$pid/exe 2>/dev/null)
    
    # 方法3: 最后尝试通过ps aux获取
    [[ -z "$user" ]] && user=$(ps aux | awk -v pid="$pid" '$2 == pid {print $1}')
    
    # 获取数据目录
    local data_path=$(ps -p "$pid" -o args= | grep -o -- "-D *[^ ]*" | awk '{print $2}')
    [[ -z "$data_path" ]] && data_path=$(lsof -p "$pid" | awk '/DIR/{print $NF}' | head -n1)
    [[ -z "$data_path" ]] && data_path=""
    
    echo "$pid,$user,$data_path"
}
IFS=',' read -r pid dbusername data_path <<< "$(get_kingbase_info)"

# 获取端口信息(修复多余逗号问题)
get_ports() {
    # 1. 通过ss命令获取
    local ports=$(ss -ltnp 2>/dev/null | awk -v pid="$pid" '$NF ~ pid && /kingbase/ {print $4}' | cut -d':' -f2 | sort -u| tr '\n' ',' | sed 's/,//g')
    
    # 2. 如果ss命令失败,尝试通过netstat
    [[ -z "$ports" ]] && ports=$(netstat -tlnp 2>/dev/null | awk -v pid="$pid" '$6 == pid && /kingbase/ {print $4}' | cut -d':' -f2 | sort -u| tr '\n' ',' | sed 's/,//g')
    
    # 3. 从配置文件中获取
    if [[ -z "$ports" && -f "$data_path/kingbase.conf" ]]; then
        ports=$(grep -E '^[[:space:]]*port[[:space:]]*=' "$data_path/kingbase.conf" | awk -F'=' '{print $2}' | tr -d ' ' | sort -u| tr '\n' ',' | sed 's/,//g')
    fi
    
    # 只返回第一个端口(去掉逗号分隔)
    [[ -n "$ports" ]] && echo "$ports" | head -n1 || echo ""
}

port=$(get_ports)

# 获取安装路径(规范化路径)
get_install_path() {
    # 1. 通过进程exe链接获取
    local exe_path=$(readlink -f "/proc/$pid/exe" 2>/dev/null)
    if [[ -n "$exe_path" ]]; then
        dirname "$(dirname "$exe_path")"
        return 0
    fi
    
    # 2. 通过which查找
    exe_path=$(which kingbase 2>/dev/null)
    if [[ -n "$exe_path" ]]; then
        dirname "$(dirname "$exe_path")"
        return 0
    fi
    
    # 3. 通过常见安装路径查找
    local common_paths=(
        "/opt/Kingbase"
        "/usr/local/Kingbase"
        "/home/$dbusername/Kingbase"
    )
    
    for path in "${common_paths[@]}"; do
        if [[ -d "$path" ]]; then
            echo "$path"
            return 0
        fi
    done
    
    echo ""
}

installpath=$(get_install_path)

# 获取版本信息(多种方式尝试)
get_kingbase_version() {
    # 1. 尝试直接调用kingbase命令
    if command -v kingbase &>/dev/null; then
        kingbase -V 2>/dev/null | awk '{print $NF}'
        return $?
    fi
    
    # 2. 尝试通过安装路径查找
    if [[ "$installpath" != "" ]]; then
        "$installpath/bin/kingbase" -V 2>/dev/null | awk '{print $NF}'
        return $?
    fi
    
    # 3. 尝试通过数据库用户环境
    if [[ "$dbusername" != "" ]]; then
        su - "$dbusername" -c 'kingbase -V 2>/dev/null | awk "{print \$NF}"' 2>/dev/null
        return $?
    fi
    
    # 4. 最后尝试通过数据库连接查询
    if [[ "$port" != "" ]]; then
        psql -U "$dbusername" -p "$port" -d "template1" -t -c "SELECT version()" 2>/dev/null | awk '{print $2}'
        return $?
    fi
    
    echo ""
    return 1
}

version=$(get_kingbase_version)

# 定位配置文件(多种方式尝试)
find_config_file() {
    # 1. 优先使用data目录
    if [[ -f "$data_path/kingbase.conf" ]]; then
        echo "$data_path/kingbase.conf"
        return 0
    fi
    
    # 2. 在常见位置查找
    local search_paths=(
        "/etc/kingbase"
        "/etc"
        "$installpath/data"
        "/var/lib/kingbase"
        "/home/$dbusername"
    )
    
    for path in "${search_paths[@]}"; do
        local config=$(find "$path" -name "kingbase.conf" 2>/dev/null | head -n1)
        if [[ -n "$config" ]]; then
            echo "$config"
            return 0
        fi
    done
    
    echo ""
    return 1
}

configfile=$(find_config_file)

# 解析配置文件(增强健壮性)
parse_config() {
    local config_file=$1
    [[ ! -f "$config_file" ]] && { echo ""; return; }

    declare -A config
    # 使用临时文件代替进程替换
    local temp_file=$(mktemp)
    grep -E '^[[:space:]]*[^#]+=' "$config_file" > "$temp_file"

    while IFS='=' read -r key value; do
        key=${key%%#*}    # 移除注释
        key=$(awk '{gsub(/^[ \t]+|[ \t]+$/, ""); print}' <<< "$key")
        value=${value%%#*} # 移除值中的注释
        value=$(awk '{gsub(/^[ \t]+|[ \t]+$/, ""); print}' <<< "$value")
        [[ -n "$key" ]] && config["$key"]="$value"
    done < "$temp_file"

    rm -f "$temp_file"

    # 输出配置项
    declare -A defaults=(
        [max_connections]=100
        [password_encryption]="scram-sha-256"
        [shared_buffers]="128MB"
        [max_stack_depth]="2MB"
        [max_wal_size]="1GB"
        [min_wal_size]="80MB"
        [log_directory]="log"
        [encoding]="UTF8"
    )

    echo "${config[max_connections]:-${defaults[max_connections]}}"
    echo "${config[password_encryption]:-${defaults[password_encryption]}}"
    echo "${config[shared_buffers]:-${defaults[shared_buffers]}}"
    echo "${config[max_stack_depth]:-${defaults[max_stack_depth]}}"
    echo "${config[max_wal_size]:-${defaults[max_wal_size]}}"
    echo "${config[min_wal_size]:-${defaults[min_wal_size]}}"
    echo "${config[log_directory]:-${defaults[log_directory]}}"
    echo "${config[encoding]:-${defaults[encoding]}}"
}

# 获取配置项
if [[ "$configfile" != "" ]]; then
    config_values=($(parse_config "$configfile"))
else
    config_values=("" "" "" "" "" "" "" "")
fi

max_connections=${config_values[0]}
password_encryption=${config_values[1]}
shared_buffers=${config_values[2]}
max_stack_depth=${config_values[3]}
max_wal_size=${config_values[4]}
min_wal_size=${config_values[5]}
log_directory=${config_values[6]}
charset=${config_values[7]}

# 获取数据库额外信息(最终修复版)
get_db_extra_info() {
    # 直接使用dbusername作为run_user
    local run_user="$dbusername"
    
    # 如果dbusername为空(虽然不应该发生),使用备选方案
    if [[ -z "$run_user" && -n "$pid" ]]; then
        # 方法1: 使用进程用户
        run_user=$(ps -o user= -p "$pid" 2>/dev/null | tr -d '[:space:]')
        
        # 方法2: 使用数据目录所有者
        [[ -z "$run_user" && -n "$data_path" ]] && run_user=$(stat -c '%U' "$data_path" 2>/dev/null)
        
        # 最终保障
        [[ -z "$run_user" ]] && run_user="kingbase"
    fi
    
    # 获取其他信息
    local case_sensitive=""
    local schema_list=""
    
    if [[ -n "$port" && -n "$dbusername" ]]; then
        export PGCONNECT_TIMEOUT=3
        
        # 获取大小写敏感性
        case_sensitive=$(psql -U "$dbusername" -p "$port" -d "template1" -t -c "SHOW case_sensitive" 2>/dev/null | tr -d '[:space:]')
        
        # 获取模式列表
        schema_list=$(psql -U "$dbusername" -p "$port" -d "template1" -t -c "SELECT nspname FROM pg_catalog.pg_namespace WHERE nspname NOT LIKE 'pg\\_%' AND nspname != 'information_schema'" 2>/dev/null | tr '\n' ',' | sed 's/,$//')
    fi
    # 返回结果(确保格式正确)
    printf "%s,%s,%s" "${case_sensitive:-}" "${schema_list:-}" "$run_user"
}
# 调用并解析函数输出
db_extra_info=$(get_db_extra_info 2>/dev/null)  # 静默调试输出
IFS=',' read -r case_sensitive schema_list run_user <<< "$db_extra_info"
# 最终保障:如果run_user仍为空,使用dbusername
[[ -z "$run_user" ]] && run_user="$dbusername"
# 输出采集结果
echo "COL_DETAIL_START:"
echo "version[$ATTR]|+|$version"
echo "ip[$ATTR]|+|$ip"
echo "port[$ATTR]|+|$port"
echo "dbusername[$ATTR]|+|$dbusername"
echo "hostname[$ATTR]|+|$hostname"
echo "charset[$ATTR]|+|$charset"
echo "datapath[$ATTR]|+|$data_path"
echo "maxconnections[$ATTR]|+|$max_connections"
echo "passwordencryption[$ATTR]|+|$password_encryption"
echo "sharedbuffers[$ATTR]|+|$shared_buffers"
echo "maxstackdepth[$ATTR]|+|$max_stack_depth"
echo "maxwalsize[$ATTR]|+|$max_wal_size"
echo "minwalsize[$ATTR]|+|$min_wal_size"
echo "logdirectory[$ATTR]|+|$log_directory"
echo "installpath[$ATTR]|+|$installpath"
echo "RunUser[$ATTR]|+|$run_user"
echo "CaseSensitive[$ATTR]|+|$case_sensitive"
echo "SchemaList[$ATTR]|+|$schema_list"
echo "COL_DETAIL_END:"

10.14.1.4服务器运行结果如下:

[root@dmzneo4j02 ~]# sh kingbase_new.sh 
COL_DETAIL_START:
version[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|V008R006C009B0014
ip[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|10.14.1.4
port[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|54321
dbusername[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|kingbase
hostname[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|dmzneo4j02
charset[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|UTF8
datapath[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|/home/kingbase/DB/data1
maxconnections[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|500
passwordencryption[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|scram-sha-256
sharedbuffers[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|128MB
maxstackdepth[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|3MB
maxwalsize[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|1GB
minwalsize[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|80MB
logdirectory[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|'sys_log'
installpath[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|/home/kingbase/DB/KESRealPro/V008R006C009B0014/Server
RunUser[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|kingbase
CaseSensitive[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|
SchemaList[_X(g=kingbase_new.sh,p=cmdb,t=script,f=0)]|+|
COL_DETAIL_END:

-------20250512-------------只要基础指标

#!/usr/bin/env bash
#IT_BEGIN
#IT_TYPE=1
#IT DATABASE_Kingbase_ip|ip
#IT DATABASE_Kingbase_version|version
#IT DATABASE_Kingbase_port|port
#IT DATABASE_Kingbase_hostname|hostname
#IT DATABASE_Kingbase_RunUser|RunUser
#IT DATABASE_Kingbase_installpath|installpath
#IT DATABASE_Kingbase_datapath|data_path
#IT DATABASE_Kingbase_logdirectory|logdirectory
#IT DATABASE_Kingbase_charset|charset
#IT DATABASE_Kingbase_sharedbuffers|sharedbuffers
#IT DATABASE_Kingbase_maxconnections|maxconnections
#IT_END

shname=$(basename "$0")
ATTR="_X(g=$shname,p=cmdb,t=script,f=0)"

# 获取主机名
hostname=$(hostname)

# 获取IP地址(优化兼容性)
get_ip() {
    local ip
    if command -v ip >/dev/null; then
        ip=$(ip -o addr show | awk '/inet / && !/127\.|inet6/ {print $4}' | cut -d'/' -f1 | head -n1)
    elif command -v hostname >/dev/null; then
        ip=$(hostname -I | awk '{print $1}')
    else
        ip=$(ifconfig -a | awk '/inet / && !/127\.|inet6/ {print $2}' | head -n1)
    fi
    echo "$ip"
}
ip=$(get_ip)

# 获取Kingbase进程信息
get_kingbase_info() {
    local pid=$(pgrep -f "kingbase.*-D" | head -n1)
    [[ -z "$pid" ]] && { echo ",,,"; return 1; }

    # 获取运行用户
    local user=$(ps -o user= -p "$pid" 2>/dev/null | tr -d ' ')
    [[ -z "$user" ]] && user=$(stat -c '%U' "/proc/$pid/exe" 2>/dev/null)

    # 获取数据目录
    local data_path=$(ps -p "$pid" -o args= | grep -o -- "-D *[^ ]*" | awk '{print $2}')
    [[ -z "$data_path" ]] && data_path=""

    echo "$pid,$user,$data_path"
}
IFS=',' read -r pid dbusername data_path <<< "$(get_kingbase_info)"
# 获取端口信息(修复多余逗号问题)
get_ports() {
    # 1. 通过ss命令获取
    local ports=$(ss -ltnp 2>/dev/null | awk -v pid="$pid" '$NF ~ pid && /kingbase/ {print $4}' | cut -d':' -f2 | sort -u| tr '\n' ',' | sed 's/,//g')
    
    # 2. 如果ss命令失败,尝试通过netstat
    [[ -z "$ports" ]] && ports=$(netstat -tlnp 2>/dev/null | awk -v pid="$pid" '$6 == pid && /kingbase/ {print $4}' | cut -d':' -f2 | sort -u| tr '\n' ',' | sed 's/,//g')
    
    # 3. 从配置文件中获取
    if [[ -z "$ports" && -f "$data_path/kingbase.conf" ]]; then
        ports=$(grep -E '^[[:space:]]*port[[:space:]]*=' "$data_path/kingbase.conf" | awk -F'=' '{print $2}' | tr -d ' ' | sort -u| tr '\n' ',' | sed 's/,//g')
    fi
    
    # 只返回第一个端口(去掉逗号分隔)
    [[ -n "$ports" ]] && echo "$ports" | head -n1 || echo ""
}

port=$(get_ports)
# 获取安装路径(规范化路径)
get_install_path() {
    # 1. 通过进程exe链接获取
    local exe_path=$(readlink -f "/proc/$pid/exe" 2>/dev/null)
    if [[ -n "$exe_path" ]]; then
        dirname "$(dirname "$exe_path")"
        return 0
    fi
    
    # 2. 通过which查找
    exe_path=$(which kingbase 2>/dev/null)
    if [[ -n "$exe_path" ]]; then
        dirname "$(dirname "$exe_path")"
        return 0
    fi
    
    # 3. 通过常见安装路径查找
    local common_paths=(
        "/opt/Kingbase"
        "/usr/local/Kingbase"
        "/home/$dbusername/Kingbase"
    )
    
    for path in "${common_paths[@]}"; do
        if [[ -d "$path" ]]; then
            echo "$path"
            return 0
        fi
    done
    
    echo ""
}

installpath=$(get_install_path)

# 获取版本信息
# 获取版本信息(多种方式尝试)
get_kingbase_version() {
    # 1. 尝试直接调用kingbase命令
    if command -v kingbase &>/dev/null; then
        kingbase -V 2>/dev/null | awk '{print $NF}'
        return $?
    fi
    
    # 2. 尝试通过安装路径查找
    if [[ "$installpath" != "" ]]; then
        "$installpath/bin/kingbase" -V 2>/dev/null | awk '{print $NF}'
        return $?
    fi
    
    # 3. 尝试通过数据库用户环境
    if [[ "$dbusername" != "" ]]; then
        su - "$dbusername" -c 'kingbase -V 2>/dev/null | awk "{print \$NF}"' 2>/dev/null
        return $?
    fi
    
    # 4. 最后尝试通过数据库连接查询
    if [[ "$port" != "" ]]; then
        psql -U "$dbusername" -p "$port" -d "template1" -t -c "SELECT version()" 2>/dev/null | awk '{print $2}'
        return $?
    fi
    
    echo ""
    return 1
}
version=$(get_kingbase_version)
# 定位配置文件
find_config_file() {
    [[ -f "$data_path/kingbase.conf" ]] && { echo "$data_path/kingbase.conf"; return; }
    find /etc /opt "$installpath" -name "kingbase.conf" 2>/dev/null | head -n1
}
configfile=$(find_config_file)

# 解析关键配置项(修复单引号问题)
parse_config() {
    local config_file=$1
    [[ ! -f "$config_file" ]] && { echo ""; return; }

    declare -A config
    local tmpfile=$(mktemp)
    grep -E '^[[:space:]]*[^#]+=' "$config_file" > "$tmpfile"

    while IFS='=' read -r key value; do
        key=${key%%#*}
        key=$(awk '{gsub(/^[[:blank:]]+|[[:blank:]]+$/, ""); print}' <<< "$key")
        value=${value%%#*}
        value=$(awk '{gsub(/^[[:blank:]\047"]+|[[:blank:]\047"]+$/, "", $0); print}' <<< "$value")  # 去除首尾空格和引号
        [[ -n "$key" ]] && config["$key"]="$value"
    done < "$tmpfile"
    rm -f "$tmpfile"

    # 输出关键配置项(带默认值)
    echo "${config[shared_buffers]:-128MB}"
    echo "${config[max_connections]:-100}"
    echo "${config[log_directory]:-log}"
    echo "${config[encoding]:-UTF8}"
}

# 获取配置值
if [[ -n "$configfile" ]]; then
    IFS=$'\n' read -r -d '' shared_buffers max_connections log_directory charset <<< "$(parse_config "$configfile")"
else
    shared_buffers="128MB"
    max_connections="100"
    log_directory="log"
    charset="UTF8"
fi

# 输出采集结果
echo "COL_DETAIL_START:"
echo "ip[$ATTR]|+|$ip"
echo "version[$ATTR]|+|$version"
echo "port[$ATTR]|+|$port"
echo "hostname[$ATTR]|+|$hostname"
echo "RunUser[$ATTR]|+|$dbusername"
echo "installpath[$ATTR]|+|$installpath"
echo "datapath[$ATTR]|+|$data_path"
echo "logdirectory[$ATTR]|+|$log_directory"
echo "charset[$ATTR]|+|$charset"
echo "sharedbuffers[$ATTR]|+|$shared_buffers"
echo "maxconnections[$ATTR]|+|$max_connections"
echo "COL_DETAIL_END:"

 10.14.1.4服务器执行结果如下:

[root@dmzneo4j02 ~]# sh COLT_CMDB_Kinbase_20250512.sh 
COL_DETAIL_START:
ip[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|10.14.1.4
version[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|V008R006C009B0014
port[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|54321
hostname[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|dmzneo4j02
RunUser[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|kingbase
installpath[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|/home/kingbase/DB/KESRealPro/V008R006C009B0014/Server
datapath[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|/home/kingbase/DB/data1
logdirectory[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|sys_log
charset[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|UTF8
sharedbuffers[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|128MB
maxconnections[_X(g=COLT_CMDB_Kinbase_20250512.sh,p=cmdb,t=script,f=0)]|+|500
COL_DETAIL_END:

同步109环境版本号2 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值