redis常用操作工具类

直接上代码吧,那些发帖子提供下载,切收费的简直不讲码德

import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.data.redis.connection.RedisConnection
import org.springframework.data.redis.core.DefaultTypedTuple
import org.springframework.data.redis.core.RedisCallback
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.data.redis.core.ZSetOperations.TypedTuple
import org.springframework.stereotype.Component
import java.util.concurrent.TimeUnit
import javax.annotation.Resource

/**

  • @program: aos-project

  • @description: RedisUtil

  • @author: loulvlin

  • @create: 2020-07-22 15:01
    **/
    @Component
    class RedisUtil {

    /** logger */
    val logger: Logger = LoggerFactory.getLogger(this.javaClass)

    @Resource
    lateinit var redisTemplate: RedisTemplate<String, Any>

    /**

    • 指定缓存失效时间
    • @param key 键
    • @param time 时间(秒)
    • @return
      */
      fun expire(key: String, time: Long): Boolean {
      return try {
      if (time > 0) {
      redisTemplate.expire(key, time, TimeUnit.SECONDS)
      }
      true
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • 根据key 获取过期时间
    • @param key 键 不能为null
    • @return 时间(秒) 返回0代表为永久有效
      */
      fun getExpire(key: String): Long {
      return redisTemplate.getExpire(key, TimeUnit.SECONDS)
      }

    /**

    • 判断key是否存在
    • @param key 键
    • @return true 存在 false不存在
      */
      fun hasKey(key: String): Boolean {
      return try {
      redisTemplate.hasKey(key)
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • 删除缓存
    • @param key 可以传一个值 或多个
      */
      fun del(vararg key: String): Boolean {
      return if (key.isNotEmpty()) {
      if (key.size == 1) {
      redisTemplate.delete(key[0])
      } else {
      redisTemplate.delete(key.toList())
      true
      }
      }else {
      false
      }
      }

    // String=
    /**

    • 普通缓存获取
    • @param key 键
    • @return 值
      */
      operator fun get(key: String?): Any? {
      return if (key == null) null else redisTemplate.opsForValue().get(key)
      }

    /**

    • 普通缓存放入
    • @param key 键
    • @param value 值
    • @return true成功 false失败
      */
      operator fun set(key: String, value: Any): Boolean {
      return try {
      redisTemplate.opsForValue().set(key, value)
      true
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • 普通缓存放入并设置时间
    • @param key 键
    • @param value 值
    • @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
    • @return true成功 false 失败
      */
      operator fun set(key: String, value: Any, time: Long): Boolean {
      return try {
      if (time > 0) {
      redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS)
      } else {
      set(key, value)
      }
      true
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • 递增
    • @param key 键
    • @param delta 要增加几(大于0)
    • @return
      */
      fun incr(key: String, delta: Long): Long {
      if (delta < 0) {
      throw RuntimeException(“递增因子必须大于0”)
      }
      return redisTemplate.opsForValue().increment(key, delta)!!
      }

    /**

    • 递减
    • @param key 键
    • @param delta 要减少几(小于0)
    • @return
      */
      fun decr(key: String, delta: Long): Long {
      if (delta < 0) {
      throw RuntimeException(“递减因子必须大于0”)
      }
      return redisTemplate.opsForValue().increment(key, -delta)!!
      }

    // Map=
    /**

    • HashGet
    • @param key 键 不能为null
    • @param item 项 不能为null
    • @return 值
      */
      fun hget(key: String, item: String): Any? {
      return redisTemplate.opsForHash<Any, Any>().get(key, item)
      }

    /**

    • HashGet
    • @param key 键 不能为null
    • @param item 项 不能为null
    • @return 值
      */
      fun hgetAll(key: String): Map<Any, Any> {
      return redisTemplate.opsForHash<Any, Any>().entries(key)
      }

    /**

    • 获取hashKey对应的所有键值
    • @param key 键
    • @return 对应的多个键值
      */
      fun hmget(key: String): Map<Any, Any> {
      return redisTemplate.opsForHash<Any, Any>().entries(key)
      }

    /**

    • HashSet
    • @param key 键
    • @param map 对应多个键值
    • @return true 成功 false 失败
      */
      fun hmset(key: String, map: Map<String, Any>): Boolean {
      return try {
      redisTemplate.opsForHash<Any, Any>().putAll(key, map)
      true
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • HashSet 并设置时间
    • @param key 键
    • @param map 对应多个键值
    • @param time 时间(秒)
    • @return true成功 false失败
      */
      fun hmset(key: String, map: Map<String, Any>, time: Long): Boolean {
      return try {
      redisTemplate.opsForHash<Any, Any>().putAll(key, map)
      if (time > 0) {
      expire(key, time)
      }
      true
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • 向一张hash表中放入数据,如果不存在将创建
    • @param key 键
    • @param item 项
    • @param value 值
    • @return true 成功 false失败
      */
      fun hset(key: String, item: String, value: Any): Boolean {
      return try {
      redisTemplate.opsForHash<Any, Any>().put(key, item, value)
      true
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • 向一张hash表中放入数据,如果不存在将创建
    • @param key 键
    • @param item 项
    • @param value 值
    • @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
    • @return true 成功 false失败
      */
      fun hset(key: String, item: String, value: Any, time: Long): Boolean {
      return try {
      redisTemplate.opsForHash<Any, Any>().put(key, item, value)
      if (time > 0) {
      expire(key, time)
      }
      true
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • 删除hash表中的值
    • @param key 键 不能为null
    • @param item 项 可以使多个 不能为null
      */
      fun hdel(key: String, vararg item: Any):Boolean {
      return try {
      var result= redisTemplate.opsForHash<Any, Any>().delete(key, *item)
      result == 1L
      } catch (e: Exception) {
      logger.error("RedisUtil hdel error: ",e)
      false
      }

    }

    /**

    • 判断hash表中是否有该项的值
    • @param key 键 不能为null
    • @param item 项 不能为null
    • @return true 存在 false不存在
      */
      fun hHasKey(key: String, item: String): Boolean {
      return redisTemplate.opsForHash<Any, Any>().hasKey(key, item)
      }

    /**

    • hash递增 如果不存在,就会创建一个 并把新增后的值返回
    • @param key 键
    • @param item 项
    • @param by 要增加几(大于0)
    • @return
      */
      fun hincr(key: String, item: String, by: Double): Double {
      return redisTemplate.opsForHash<Any, Any>().increment(key, item, by)
      }

    /**

    • hash递减
    • @param key 键
    • @param item 项
    • @param by 要减少记(小于0)
    • @return
      */
      fun hdecr(key: String, item: String, by: Double): Double {
      return redisTemplate.opsForHash<Any, Any>().increment(key, item, -by)
      }

    // set=
    /**

    • 根据key获取Set中的所有值
    • @param key 键
    • @return
      */
      fun sGet(key: String): Set? {
      return try {
      redisTemplate.opsForSet().members(key)
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      null
      }

    }

    /**

    • 根据value从一个set中查询,是否存在
    • @param key 键
    • @param value 值
    • @return true 存在 false不存在
      */
      fun sHasKey(key: String, value: Any): Boolean {
      return try {
      redisTemplate.opsForSet().isMember(key, value)!!
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • 将数据放入set缓存
    • @param key 键
    • @param values 值 可以是多个
    • @return 成功个数
      */
      fun sSet(key: String, vararg values: Any): Long {
      return try {
      redisTemplate.opsForSet().add(key, *values)!!
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      0
      }

    }

    /**

    • 将set数据放入缓存
    • @param key 键
    • @param time 时间(秒)
    • @param values 值 可以是多个
    • @return 成功个数
      */
      fun sSetAndTime(key: String, time: Long, vararg values: Any): Long {
      return try {
      val count = redisTemplate.opsForSet().add(key, *values)
      if (time > 0)
      expire(key, time)
      count!!
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      0
      }

    }

    /**

    • 获取set缓存的长度
    • @param key 键
    • @return
      */
      fun sGetSetSize(key: String): Long {
      return try {
      redisTemplate.opsForSet().size(key)!!
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      0
      }

    }

    /**

    • 移除值为value的
    • @param key 键
    • @param values 值 可以是多个
    • @return 移除的个数
      */
      fun setRemove(key: String, vararg values: Any): Long {
      return try {
      val count = redisTemplate.opsForSet().remove(key, *values)
      count!!
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      0
      }

    }
    // =list===
    /**

    • 获取list缓存的内容
    • @param key 键
    • @param start 开始
    • @param end 结束 0 到 -1代表所有值
    • @return
      */
      fun lGet(key: String, start: Long, end: Long): List? {
      return try {
      redisTemplate.opsForList().range(key, start, end)
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      null
      }

    }

    /**

    • 获取list缓存的长度
    • @param key 键
    • @return
      */
      fun lGetListSize(key: String): Long {
      return try {
      redisTemplate.opsForList().size(key)!!
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      0
      }

    }

    /**

    • 通过索引 获取list中的值
    • @param key 键
    • @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
    • @return
      */
      fun lGetIndex(key: String, index: Long): Any? {
      return try {
      redisTemplate.opsForList().index(key, index)
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      null
      }

    }

    /**

    • 将list放入缓存
    • @param key 键
    • @param value 值
    • @param time 时间(秒)
    • @return
      */
      fun lSet(key: String, value: Any): Boolean {
      return try {
      redisTemplate.opsForList().rightPush(key, value)
      true
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • 将list放入缓存
    • @param key 键
    • @param value 值
    • @param time 时间(秒)
    • @return
      */
      fun lSet(key: String, value: Any, time: Long): Boolean {
      return try {
      redisTemplate.opsForList().rightPush(key, value)
      if (time > 0)
      expire(key, time)
      true
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • 将list放入缓存
    • @param key 键
    • @param value 值
    • @param time 时间(秒)
    • @return
      */
      fun lSet(key: String, value: List): Boolean {
      return try {
      redisTemplate.opsForList().rightPushAll(key, *value.toTypedArray())
      true
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • 将list放入缓存
    • @param key 键
    • @param value 值
    • @param time 时间(秒)
    • @return
      */
      fun lSet(key: String, value: List, time: Long): Boolean {
      return try {
      redisTemplate.opsForList().rightPushAll(key, *value.toTypedArray())
      if (time > 0)
      expire(key, time)
      true
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • 根据索引修改list中的某条数据
    • @param key 键
    • @param index 索引
    • @param value 值
    • @return
      */
      fun lUpdateIndex(key: String, index: Long, value: Any): Boolean {
      return try {
      redisTemplate.opsForList().set(key, index, value)
      true
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      false
      }

    }

    /**

    • 移除N个值为value
    • @param key 键
    • @param count 移除多少个
    • @param value 值
    • @return 移除的个数
      */
      fun lRemove(key: String, count: Long, value: Any): Long {
      return try {
      val remove = redisTemplate.opsForList().remove(key, count, value)
      remove!!
      } catch (e: Exception) {
      logger.error("RedisUtil get error: ",e)
      0
      }

    }

    // =BitMap===
    /**

    • 将指定offset偏移量的值设置为1;
    • @param key bitmap结构的key
    • @param offset 指定的偏移量。
    • @param value true:即该位设置为1,否则设置为0
    • @return 返回设置该value之前的值。
      */
      fun setBit(key: String, offset: Long, value: Boolean): Boolean {
      return redisTemplate.opsForValue().setBit(key, offset, value)!!
      }

    /**

    • 将指定offset偏移量的值设置为0;
    • @param key bitmap结构的key
    • @param offset 指定的偏移量。
    • @return 若偏移位上的值为1,那么返回true。
      */
      fun getBit(key: String, offset: Long): Boolean {
      return redisTemplate.opsForValue().getBit(key, offset)!!
      }

    /**

    • 统计对应的bitmap上value为1的数量
    • @param key bitmap的key
    • @return value等于1的数量
      */
      fun bitCount(key: String): Int {
      return redisTemplate.execute(RedisCallback { con: RedisConnection -> con.bitCount(key.toByteArray()) } as RedisCallback)!!
      }

    /**

    • 统计指定范围中value为1的数量
    • @param key bitMap中的key
    • @param start 该参数的单位是byte(1byte=8bit),setBit(key,7,true);进行存储时,单位是bit。那么只需要统计[0,1]便可以统计到上述set的值。
    • @param end 该参数的单位是byte。
    • @return 在指定范围[start8,end8]内所有value=1的数量
      */
      fun bitCount(key: String, start: Int, end: Int): Long? {
      return redisTemplate.execute(RedisCallback { con: RedisConnection -> con.bitCount(key.toByteArray(), start.toLong(), end.toLong()) } as RedisCallback<Long?>)
      }

    //Zset 根据 socre 排序 不重复 每个元素附加一个 socre double类型的属性(double 可以重复)
    /**

    • 添加 ZSet 元素
    • @param key
    • @param value
    • @param score
      */
      fun zadd(key: String, value: Any, score: Double): Boolean {
      return redisTemplate.opsForZSet().add(key, value, score)!!
      }

    /**

    • 批量添加 Zset
    • Set> tuples = new HashSet<>();
    • TypedTuple objectTypedTuple1 = new DefaultTypedTuple(“zset-5”,9.6);
    • tuples.add(objectTypedTuple1);
    • @param key
    • @param tuples
    • @return
      */
      fun batchAddZset(key: String, tuples: Set<TypedTuple>): Long {
      return redisTemplate.opsForZSet().add(key, tuples)!!
      }

    /**

    • Zset 删除一个或多个元素
    • @param key
    • @param values
    • @return
      */
      fun removeZset(key: String, vararg values: Any): Long {
      return redisTemplate.opsForZSet().remove(key, *values)!!
      }

    /**

    • 对指定的 zset 的 value 值 , socre 属性做增减操作
    • @param key
    • @param value
    • @param score
    • @return
      */
      fun incrementScore(key: String, value: Any, score: Double): Double {
      return redisTemplate.opsForZSet().incrementScore(key, value, score)!!
      }

    /**

    • 获取 key 中指定 value 的排名(从0开始,从小到大排序)
    • @param key
    • @param value
    • @return
      */
      fun rank(key: String, value: Any): Long {
      return redisTemplate.opsForZSet().rank(key, value)!!
      }

    /**

    • 获取 key 中指定 value 的排名(从0开始,从大到小排序)
    • @param key
    • @param value
    • @return
      */
      fun reverseRank(key: String, value: Any): Long {
      return redisTemplate.opsForZSet().reverseRank(key, value)!!
      }

    /**

    • 获取索引区间内的排序结果集合(从0开始,从小到大,带上分数)
    • @param key
    • @param start
    • @param end
    • @return
      */
      fun rangeWithScores(key: String, start: Long, end: Long): Set<TypedTuple> {
      return redisTemplate.opsForZSet().rangeWithScores(key, start, end)!!
      }

    /**

    • 获取索引区间内的排序结果集合(从0开始,从小到大,只有列名)
    • @param key
    • @param start
    • @param end
    • @return
      */
      fun range(key: String, start: Long, end: Long): Set {
      return redisTemplate.opsForZSet().range(key, start, end)!!
      }

    /**

    • 获取分数范围内的 [min,max] 的排序结果集合 (从小到大,只有列名)
    • @param key
    • @param min
    • @param max
    • @return
      */
      fun rangeByScore(key: String, min: Double, max: Double): Set {
      return redisTemplate.opsForZSet().rangeByScore(key, min, max)!!
      }

    /**

    • 获取分数范围内的 [min,max] 的排序结果集合 (从小到大,集合带分数)
    • @param key
    • @param min
    • @param max
    • @return
      */
      fun rangeByScoreWithScores(key: String, min: Double, max: Double): Set<TypedTuple>? {
      return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max)
      }

    /**

    • 返回 分数范围内 指定 count 数量的元素集合, 并且从 offset 下标开始(从小到大,不带分数的集合)
    • @param key
    • @param min
    • @param max
    • @param offset 从指定下标开始
    • @param count 输出指定元素数量
    • @return
      */
      fun rangeByScore(key: String, min: Double, max: Double, offset: Long, count: Long): Set {
      return redisTemplate.opsForZSet().rangeByScore(key, min, max, offset, count)!!
      }

    /**

    • 返回 分数范围内 指定 count 数量的元素集合, 并且从 offset 下标开始(从小到大,带分数的集合)
    • @param key
    • @param min
    • @param max
    • @param offset 从指定下标开始
    • @param count 输出指定元素数量
    • @return
      */
      fun rangeByScoreWithScores(key: String, min: Double, max: Double, offset: Long, count: Long): Set<TypedTuple?>? {
      return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max, offset, count)
      }

    /**

    • 获取索引区间内的排序结果集合(从0开始,从大到小,只有列名)
    • @param key
    • @param start
    • @param end
    • @return
      */
      fun reverseRange(key: String, start: Long, end: Long): Set? {
      return redisTemplate.opsForZSet().reverseRange(key, start, end)
      }

    /**

    • 获取索引区间内的排序结果集合(从0开始,从大到小,带上分数)
    • @param key
    • @param start
    • @param end
    • @return
      */
      fun reverseRangeWithScores(key: String, start: Long, end: Long): Set<TypedTuple> {
      return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end)!!
      }

    /**

    • 获取分数范围内的 [min,max] 的排序结果集合 (从大到小,集合不带分数)
    • @param key
    • @param min
    • @param max
    • @return
      */
      fun reverseRangeByScore(key: String, min: Double, max: Double): Set? {
      return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max)
      }

    /**

    • 获取分数范围内的 [min,max] 的排序结果集合 (从大到小,集合带分数)
    • @param key
    • @param min
    • @param max
    • @return
      */
      fun reverseRangeByScoreWithScores(key: String, min: Double, max: Double): Set<TypedTuple?>? {
      return redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max)
      }

    /**

    • 返回 分数范围内 指定 count 数量的元素集合, 并且从 offset 下标开始(从大到小,不带分数的集合)
    • @param key
    • @param min
    • @param max
    • @param offset 从指定下标开始
    • @param count 输出指定元素数量
    • @return
      */
      fun reverseRangeByScore(key: String, min: Double, max: Double, offset: Long, count: Long): Set? {
      return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max, offset, count)
      }

    /**

    • 返回 分数范围内 指定 count 数量的元素集合, 并且从 offset 下标开始(从大到小,带分数的集合)
    • @param key
    • @param min
    • @param max
    • @param offset 从指定下标开始
    • @param count 输出指定元素数量
    • @return
      */
      fun reverseRangeByScoreWithScores(key: String, min: Double, max: Double, offset: Long, count: Long): Set<TypedTuple?>? {
      return redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max, offset, count)
      }

    /**

    • 返回指定分数区间 [min,max] 的元素个数
    • @param key
    • @param min
    • @param max
    • @return
      */
      fun countZSet(key: String, min: Double, max: Double): Long {
      return redisTemplate.opsForZSet().count(key, min, max)!!
      }

    /**

    • 返回 zset 集合数量
    • @param key
    • @return
      */
      fun sizeZset(key: String): Long {
      return redisTemplate.opsForZSet().size(key)!!
      }

    /**

    • 获取指定成员的 score 值
    • @param key
    • @param value
    • @return
      */
      fun score(key: String, value: Any): Double? {
      return redisTemplate.opsForZSet().score(key, value)
      }

    /**

    • 删除指定索引位置的成员,其中成员分数按( 从小到大 )
    • @param key
    • @param start
    • @param end
    • @return
      */
      fun removeRange(key: String, start: Long, end: Long): Long? {
      return redisTemplate.opsForZSet().removeRange(key, start, end)
      }

    /**

    • 删除指定 分数范围 内的成员 [main,max],其中成员分数按( 从小到大 )
    • @param key
    • @param min
    • @param max
    • @return
      */
      fun removeRangeByScore(key: String, min: Double, max: Double): Long? {
      return redisTemplate.opsForZSet().removeRangeByScore(key, min, max)
      }

    /**

    • key 和 other 两个集合的并集,保存在 destKey 集合中, 列名相同的 score 相加
    • @param key
    • @param otherKey
    • @param destKey
    • @return
      */
      fun unionAndStoreZset(key: String, otherkey: String, destkey: String): Long? {
      return redisTemplate.opsForZSet().unionAndStore(key, otherkey, destkey)
      }

    /**

    • key 和 otherKeys 多个集合的并集,保存在 destKey 集合中, 列名相同的 score 相加
    • @param key
    • @param otherKeys
    • @param destKey
    • @return
      */
      fun unionAndStoreZset(key: String, otherKeys: Collection, destkey: String): Long? {
      return redisTemplate.opsForZSet().unionAndStore(key, otherKeys, destkey)
      }

    /**

    • key 和 otherKey 两个集合的交集,保存在 destKey 集合中
    • @param key
    • @param otherKey
    • @param destKey
    • @return
      */
      fun intersectAndStore(key: String, otherkey: String, destkey: String): Long? {
      return redisTemplate.opsForZSet().intersectAndStore(key, otherkey, destkey)
      }

    /**

    • key 和 otherKeys 多个集合的交集,保存在 destKey 集合中
    • @param key
    • @param otherKeys
    • @param destKey
    • @return
      */
      fun intersectAndStore(key: String, otherKeys: Collection, destkey: String): Long? {
      return redisTemplate.opsForZSet().intersectAndStore(key, otherKeys, destkey)
      }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值