把jquery中考勤时间段显示改造成vue2的方法

前言

案列中的jquery来源:https://www.jq22.com/jquery-info18500,本次改造对里面的js文件进行了改造(原先的立即执行函数引入到vue组件中会出现渲染两次的情况)
效果图:
在这里插入图片描述


一、安装jquery

1.cnpm安装

代码如下(示例):

cnpm install jquery --save

2.在main.js中引入jquery

代码如下(示例):

// 引入jquery
import $ from 'jquery'
window.$ = $

3.在vue.config.js中对jquery进行配置

代码如下(示例):

  chainWebpack: (config) => {
    config.resolve.alias
      // jquery配置
      .set('jquery', resolve('./node_modules/jquery/src/jquery'))
      .set('scrolls', resolve('src/utils/jq/jqueryAt.js')) //这个jqueryAt.js文件就是在https://www.jq22.com/jquery-info18500 案列中下载下来的js文件,但是在本案列中对其改造了,文章末尾会贴上代码
      }

二、在 vue 组件中正式渲染时间段

1.完整的 vue 代码如下,千万别忘了引入对应的css文件

<template>
  <div>
    <div class="kaoqing" id="demo1"></div>
  </div>
</template>

<script>
import * as $ from "jquery";

export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
  data() {
    return {
      data3: [
        {
          startime: "2018-03-07 01:30:00",
          endtime: "2018-03-07 23:00:00",
        },
        {
          startime: "2018-03-08 01:30:00",
          endtime: "2018-03-08 05:30:00",
        },
        {
          startime: "2018-03-05 16:30:00",
          endtime: "2018-03-05 20:30:00",
        },
        {
          startime: "2018-03-05 01:30:00",
          endtime: "2018-03-05 02:00:00",
        },
      ],
    };
  },
  mounted() { 
  //渲染函数
    if ($("#demo1")) {
      import("../assets/jq/drag4").then((f) => {
        f.default($);
        $("#demo1").initJuicy({
          width: 800,
          mondayDate: "2018-03-05",
          timedata: this.data3,
          status: true, //false表示不能编辑,true可以编辑
        });
      });
    }
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
@import "../styles/style.css"; //直接使用案列中下载的就行,本文章末尾会贴出完成代码,直接复制过去也可以
</style>

有个需要注意的小问题:因为 offset() 要在组件内容可见的情况下才会执行,所以如果你的 vue 文件是一个弹窗的话可能会报 图1 的错误,只需要把写在 mounted里的渲染函数写到弹窗显示的函数里执行即可

在这里插入图片描述
// 图1 /

在这里插入图片描述
// 图2 /

三、在 vue 组件中使用到的 js 以及 css 文件完整代码,直接 cv 即可

1.经过改造的 jqueryAt.js

 /**
 * Created by juicy on 2018-3-10.上一稳定版本为drag2,添加左边左滑
 * 按格子移动,数据格式为日期
 */
export default function ($) {
  'use strict'
  $.fn.initJuicy = function (data) {
    return new MyinitJuicy(data, this)
  }
  var perwidth = 0
  var MyinitJuicy = function (data, that) {
    var me = this
    me.init(data, that)
    me.offsetleft = $(that).offset().left + 80
  }

  MyinitJuicy.prototype.getdata = function () {
    var backdata = []
    var monday = $('.kaoqing').data('monday')
    $.each($('.weekday'), function (i, obj) {
      var thisday = getNextDate(monday, i)
      $.each($(obj).find('.item'), function (j, obj1) {
        var x = parseFloat($(obj1).css('left')) / perwidth
        var y = parseFloat($(obj1).css('width')) / perwidth + x
        var startime =
          Math.round(x) % 2 == 0
            ? thisday + ' ' + ('0' + Math.round(x) / 2).slice(-2) + ':00:00'
            : thisday + ' ' + ('0' + parseInt(Math.round(x) / 2)).slice(-2) + ':30:00'
        var endtime =
          Math.round(y) % 2 == 0
            ? thisday + ' ' + ('0' + Math.round(y) / 2).slice(-2) + ':00:00'
            : thisday + ' ' + ('0' + parseInt(Math.round(y) / 2)).slice(-2) + ':30:00'
        backdata.push({
          startime: startime,
          endtime: endtime,
        })
      })
    })
    return backdata
  }
  // 初始化
  MyinitJuicy.prototype.init = function (data, that) {
    var me = this
    me.current = 0 //新增编号
    me.cando = true //当前位置是否允许新增
    me.nowmove = -1 //当前向左向右拖动的序号
    me.newcreate = true
    me.opts = $.extend(
      true,
      {},
      {
        //用于设弹窗默认值
        width: 900,
        mondayDate: '',
        timedata: [], //[{startime:,endtime:},]
        status: true,
        data1: [
          {
            type: '周一',
            timeSlot: [],
          },
          {
            type: '周二',
            timeSlot: [],
          },
          {
            type: '周三',
            timeSlot: [],
          },
          {
            type: '周四',
            timeSlot: [],
          },
          {
            type: '周五',
            timeSlot: [],
          },
          {
            type: '周六',
            timeSlot: [],
          },
          {
            type: '周日',
            timeSlot: [],
          },
        ],
      },
      data
    )
    me.mousedown = false
    //初始化
    var str = ''
    var boxwidth = me.opts.width
    var navwidth = me.opts.width - 90
    me.perwidth = perwidth = navwidth / 48
    $(that).css('width', boxwidth + 'px')
    $(that).attr('data-monday', me.opts.mondayDate)
    var data3 = me.opts.timedata
    var timedata = me.opts.data1

    // for (var i = 0; i < 7; i++) {
    //   //渲染出 YYYY-MM-DD 中的月和日,此处用不到
    //   timedata[i]['type'] += getNextDay(me.opts.mondayDate, i)
    //   console.log('时间插槽', timedata[i]['type'])
    // }

    $.each(data3, function (i, obj) {
      //时间段有颜色部分数据渲染
      var day = new Date(obj.startime.replace(/-/g, '/')).getDay() - 1
      if (day == -1) day = 6
      timedata[day]['timeSlot'].push([getMytime(obj.startime), getMytime(obj.endtime)])
    })

    for (var i = 0; i < 7; i++) {
      str += '<div class="weekday">' + '<div class=xq>' + timedata[i].type + '</div>' + '<div>' + '<div class="day">'
      for (var j = 0; j < 24; j++) {
        str += '<div class="hour"><div class="halfhour"></div></div>'
      }
      str += '<div class="hour"></div></div><div class="bar">'
      if (timedata.length == 0) {
        str += '</div></div></div>'
      } else {
        for (var t = 0; t < timedata[i].timeSlot.length; t++) {
          var left = (navwidth * timedata[i].timeSlot[t][0]) / 24
          var width = (navwidth * (timedata[i].timeSlot[t][1] - timedata[i].timeSlot[t][0])) / 24
          str +=
            '<div class="item item' +
            me.current +
            '" style="left:' +
            left +
            'px;width:' +
            width +
            'px" data-num="' +
            me.current +
            '">' +
            '<div class="bleft"></div><div class="bright"></div></div>'
          me.current++
        }
        str += '</div></div></div>'
      }
    }

    var $str = $(str)
    $(that).append($str)
    //点在蓝条条上就禁止它新建了
    if (me.opts.status) {
      $('.bright,.bleft').css('cursor', 'e-resize')
      $str.find('.item').on('mousedown', function (e) {
        me.cando = false
        return false
      })
      $str.find('.bar').on('mousedown', function (e) {
        if (me.cando) {
          me.mousedown = true
          me.newcreate = true
          fnstart(e, me, this)
        }
        return false //防止事件冒泡
      })
      $('body').on('mouseup', function (e) {
        me.cando = true
        if (me.mousedown) {
          me.mousedown = false
          fnend(me)
          me.nowmove = -1
        }
        return false //防止事件冒泡
      })

      $str.find('.bright').on('mousedown', function (e) {
        me.mousedown = true
        me.newcreate = false
        me._startX = e.pageX
        me.direction = 'right'
        me.width = parseFloat($(this).parent().css('width')) //会实时变化
        me.left = parseFloat($(this).parent().css('left')) //会实时变化
        me.startwidth = parseFloat($(this).parent().css('width')) //是个常数
        me.startleft = parseFloat($(this).parent().css('left')) //是个常数
        me.nowmove = parseFloat($(this).parent().data('num'))
        return false
      })
      $str.find('.bleft').on('mousedown', function (e) {
        me.mousedown = true
        me.newcreate = false
        me._startX = e.pageX
        me.direction = 'left'
        me.width = parseFloat($(this).parent().css('width')) //会实时变化
        me.left = parseFloat($(this).parent().css('left')) //会实时变化
        me.startwidth = parseFloat($(this).parent().css('width')) //是个常数
        me.startleft = parseFloat($(this).parent().css('left')) //是个常数
        me.nowmove = parseFloat($(this).parent().data('num'))
        return false
      })
      //注意:move事件一定要绑在body上,当鼠标移动过快可能移除那个div区域
      $('body').on('mousemove', function (e) {
        if (me.mousedown && me.newcreate) {
          fnmove(e, me)
        } else if (me.mousedown && !me.newcreate) {
          if (me.direction && me.direction == 'left') {
            fnmoveleft(e, me)
          } else if (me.direction && me.direction == 'right') {
            fnmoveright(e, me)
          }
        } else {
          e.preventDefault()
        }
      })
    } else {
      $('.bright,.bleft').css('cursor', 'default')
    }
  }
  function fnmoveleft(e, me) {
    console.log('左边不是新建' + me.startwidth)
    me._curX = e.pageX
    me._curY = e.pageY
    me._moveX = me._startX - me._curX
    var item = '.item' + me.nowmove
    var left = me.startleft - me._moveX
    var width = me.startwidth + me._moveX
    //左边的向左拉,不超过左边边界
    if (me._moveX > 0 && me._moveX < me.startleft) {
      $(item).css({
        width: width + 'px',
        left: left + 'px',
      })
      me.width = width
      me.left = left
    } else if (me._moveX > 0 && me._moveX >= me.startleft) {
      //左边的向左拉,超过左边边界
      $(item).css({
        width: me.startleft + me.startwidth + 'px',
        left: 0,
      })
      me.width = me.startleft + me.startwidth
      me.left = 0
    } else if (me._moveX < 0 && -me._moveX <= me.startwidth) {
      //左边的向右拉,不能超过当前右边的0.5小时
      $(item).css({
        width: width + 'px',
        left: left + 'px',
      })
      me.width = width
      me.left = left
    } else if (me._moveX < 0 && -me._moveX > me.startwidth) {
      //左边的向右拉,超过最右边
      $(item).css({
        width: 0,
        left: me.startwidth + me.startleft + 'px',
      })
      me.width = 0
      me.left = me.startwidth + me.startleft
    }
  }
  function fnmoveright(e, me) {
    console.log('右边不是新建' + me.startwidth)
    me._curX = e.pageX
    me._curY = e.pageY
    me._moveX = me._curX - me._startX
    var item = '.item' + me.nowmove
    var left = me.startleft
    var width = me.startwidth + me._moveX
    //右边的向右拉,不超过右边边界
    if (me._moveX > 0 && me._moveX < me.perwidth * 48 - me.startleft - me.startwidth) {
      $(item).css({
        width: width + 'px',
        left: left + 'px',
      })
      me.width = width
    } else if (me._moveX > 0 && me._moveX >= me.perwidth * 48 - me.startleft - me.startwidth) {
      //右边的向右拉,超过右边边界
      $(item).css({
        width: me.perwidth * 48 - left + 'px',
        left: left + 'px',
      })
      me.width = me.perwidth * 48 - left
    } else if (me._moveX < 0 && -me._moveX <= me.startwidth) {
      //右边的向左拉,不能超过当前左边的0.5小时
      $(item).css({
        width: width + 'px',
        left: left + 'px',
      })
      me.width = width
    } else if (me._moveX < 0 && -me._moveX > me.startwidth) {
      //右边的向左拉,超过最左边
      $(item).css({
        width: 0,
        left: left + 'px',
      })
      me.width = 0
    }
  }

  function fnstart(e, me, that) {
    me._startX = e.pageX
    var left = me._startX - me.offsetleft
    me.left = nearest(left)
    me.startleft = nearest(left)
    me.nowmove = me.current
    var str =
      '<div class="item item' +
      me.current +
      '" style="left:' +
      me.left +
      'px;width:1px"  data-num="' +
      me.current +
      '">' +
      '<div class="bleft"></div><div class="bright"></div></div>'
    me.current++
    var item = '.item' + (me.current - 1)
    $(that).append($(str))
    if (me.opts.status) {
      $('.bright,.bleft').css('cursor', 'e-resize')
      $(item).on('mousedown', function (e) {
        me.cando = false
        return false
      })

      $(item)
        .find('.bright')
        .on('mousedown', function (e) {
          me.mousedown = true
          me.newcreate = false
          me._startX = e.pageX
          me.direction = 'right'
          me.width = parseFloat($(this).parent().css('width')) //会实时变化
          me.left = parseFloat($(this).parent().css('left')) //会实时变化
          me.startwidth = parseFloat($(this).parent().css('width')) //是个常数
          me.startleft = parseFloat($(this).parent().css('left')) //是个常数
          me.nowmove = parseFloat($(this).parent().data('num'))
          return false
        })
      $(item)
        .find('.bleft')
        .on('mousedown', function (e) {
          me.mousedown = true
          me.newcreate = false
          me._startX = e.pageX
          me.direction = 'left'
          me.width = parseFloat($(this).parent().css('width')) //会实时变化
          me.left = parseFloat($(this).parent().css('left')) //会实时变化
          me.startwidth = parseFloat($(this).parent().css('width')) //是个常数
          me.startleft = parseFloat($(this).parent().css('left')) //是个常数
          me.nowmove = parseFloat($(this).parent().data('num'))
          return false
        })
    } else {
      $('.bleft,.bright').css('cursor', 'default')
    }
  }

  function fnmove(e, me) {
    console.log('新建' + me.nowmove + me.left)
    me._curX = e.pageX
    me._curY = e.pageY
    me._moveX = me._curX - me._startX
    var item = '.item' + (me.current - 1)
    if (me._moveX > 0 && me._moveX < me.perwidth * 48 - me.startleft) {
      me.width = me._moveX
      $(item).css('width', me._moveX + 'px')
      //			$(item).css("width", me._moveX + 'px')
    } else if (me._moveX > 0 && me._moveX >= me.perwidth * 48 - me.startleft) {
      me.width = me.perwidth * 48 - me.startleft
      $(item).css('width', me.perwidth * 48 - me.startleft + 'px')
    } else {
      me.width = 0
      $(item).css('width', 0)
    }
  }

  function fnend(me, i) {
    var width = me.width
    var left = me.left
    var item = '.item' + me.nowmove
    if (width == 0) {
      $(item).remove()
    } else {
      $(item).css('width', nearest(width) + 'px')
      $(item).css('left', nearest(left) + 'px')
      var result = xiaoxiannvbianshen(item)
      var items = $(item).parent().find('.item')
      if (result.length < items.length) {
        $.each(items, function (i, obj) {
          if (i < result.length) {
            $(obj).css({
              left: result[i][0] + 'px',
              width: result[i][1] + 'px',
            })
          } else {
            $(obj).remove()
          }
        })
      }
    }
    //松手后才能修改值
  }

  function nearest(left) {
    var yu = left % perwidth
    if (yu < perwidth / 2) {
      return left - yu
    } else {
      return left + (perwidth - yu)
    }
  }

  function getMytime(date) {
    if (date.split(' ')[1] == '24:00:00') {
      return 24
    } else {
      var time = new Date(date.replace(/-/g, '/'))
      if (time.getMinutes() > 10) {
        return time.getHours() + 0.5
      } else {
        return time.getHours()
      }
    }
  }

  function getNextDay(d, i) {
    var monday = new Date(d.replace(/-/g, '/'))
    monday = monday.getTime() + 1000 * 60 * 60 * 24 * i
    monday = new Date(monday)
    return monday.getMonth() + 1 + '/' + monday.getDate()
  }

  function getNextDate(d, i) {
    var monday = new Date(d.replace(/-/g, '/'))
    monday = monday.getTime() + 1000 * 60 * 60 * 24 * i
    monday = new Date(monday)
    return (
      monday.getFullYear() + '-' + ('0' + (monday.getMonth() + 1)).slice(-2) + '-' + ('0' + monday.getDate()).slice(-2)
    )
  }

  function xiaoxiannvbianshen(item) {
    var array = []
    var arrayresult = []
    var $item = $(item).parent().find('.item')
    $.each($item, function (i, obj) {
      var left = parseFloat($(obj).css('left'))
      var width = parseFloat($(obj).css('width'))
      array.push([left, left + width])
    })
    var sortarray = bubbleSort(array)
    //var sortarray = array.sort();
    var temp = sortarray[0]
    console.log('排序后:')
    console.log(sortarray)
    for (var i = 0; i < sortarray.length; i++) {
      if (!sortarray[i + 1]) {
        arrayresult.push(temp)
        break
      }
      if (temp[1] < sortarray[i + 1][0]) {
        arrayresult.push(temp)
        temp = sortarray[i + 1]
      } else {
        if (temp[1] <= sortarray[i + 1][1]) {
          temp = [temp[0], sortarray[i + 1][1]]
        } else {
          temp = [temp[0], temp[1]]
        }
      }
    }
    console.log('小仙女变身后:')
    console.log(arrayresult)
    var huanyuan = []
    for (var j = 0; j < arrayresult.length; j++) {
      huanyuan.push([arrayresult[j][0], arrayresult[j][1] - arrayresult[j][0]])
    }
    return huanyuan
  }

  function bubbleSort(array) {
    for (var unfix = array.length - 1; unfix > 0; unfix--) {
      for (var i = 0; i < unfix; i++) {
        if (array[i][0] > array[i + 1][0]) {
          var temp = array[i]
          array.splice(i, 1, array[i + 1])
          array.splice(i + 1, 1, temp)
        }
      }
    }
    return array
  }
}

2.style.css 的完整文件

.kaoqing {
	/*width: 800px;*/
}
*{
	box-sizing: border-box;
}
body {
	background-color: #e3e3e3;
}
.bar {
	background-color: #fff;
	border: 1px solid #555;
	position: relative;
	margin: 0 auto 20px 0;
	height: 20px;
	width: calc(100% + 1px);
	width: -webkit-calc(100% + 1px);
}


/*刻度*/
.day {
	position: relative;
	margin: 20px auto 0 0;
	height: 10px;
	box-sizing: border-box;
}

.day .hour {
	position: absolute;
	border-left: 1px solid #555;
	height: 10px;
	width: calc(1 / 24 * 100%);
}

.day .halfhour {
	position: absolute;
	border-left: 1px solid #555;
	height: 7px;
	width: 50%;
	top: 4px;
}

.day .hour:after {
	position: absolute;
	top: -15px;
	font: 11px/1 sans-serif;
}

.day .hour:nth-of-type(1) {
	left: 0%;
}

.day .hour:nth-of-type(1):after {
	content: "0";
}

.day .hour:nth-of-type(2) {
	left: calc(1 / 24 * 1 * 100%);
}

.day .hour:nth-of-type(2):after {
	/*content: "1";*/
}

.day .hour:nth-of-type(3) {
	left: calc(1 / 24 * 2 * 100%);
}

.day .hour:nth-of-type(3):after {
	content: "2";
}

.day .hour:nth-of-type(4) {
	left: calc(1 / 24 * 3 * 100%);
}

.day .hour:nth-of-type(4):after {
	/*content: "3";*/
}

.day .hour:nth-of-type(5) {
	left: calc(1 / 24 * 4 * 100%);
}

.day .hour:nth-of-type(5):after {
	content: "4";
}

.day .hour:nth-of-type(6) {
	left: calc(1 / 24 * 5 * 100%);
}

.day .hour:nth-of-type(6):after {
	/*content: "5";*/
}

.day .hour:nth-of-type(7) {
	left: calc(1 / 24 * 6 * 100%);
}

.day .hour:nth-of-type(7):after {
	content: "6";
}

.day .hour:nth-of-type(8) {
	left: calc(1 / 24 * 7 * 100%);
}

.day .hour:nth-of-type(8):after {
	/*content: "7";*/
}

.day .hour:nth-of-type(9) {
	left: calc(1 / 24 * 8 * 100%);
}

.day .hour:nth-of-type(9):after {
	content: "8";
}

.day .hour:nth-of-type(10) {
	left: calc(1 / 24 * 9 * 100%);
}

.day .hour:nth-of-type(10):after {
	/*content: "9";*/
}

.day .hour:nth-of-type(11) {
	left: calc(1 / 24 * 10 * 100%);
}

.day .hour:nth-of-type(11):after {
	content: "10";
}

.day .hour:nth-of-type(12) {
	left: calc(1 / 24 * 11 * 100%);
}

.day .hour:nth-of-type(12):after {
	/*content: "11";*/
}

.day .hour:nth-of-type(13) {
	left: calc(1 / 24 * 12 * 100%);
}

.day .hour:nth-of-type(13):after {
	content: "12";
}

.day .hour:nth-of-type(14) {
	left: calc(1 / 24 * 13 * 100%);
}

.day .hour:nth-of-type(14):after {
	/*content: "13";*/
}

.day .hour:nth-of-type(15) {
	left: calc(1 / 24 * 14 * 100%);
}

.day .hour:nth-of-type(15):after {
	content: "14";
}

.day .hour:nth-of-type(16) {
	left: calc(1 / 24 * 15 * 100%);
}

.day .hour:nth-of-type(16):after {
	/*content: "15";*/
}

.day .hour:nth-of-type(17) {
	left: calc(1 / 24 * 16 * 100%);
}

.day .hour:nth-of-type(17):after {
	content: "16";
}

.day .hour:nth-of-type(18) {
	left: calc(1 / 24 * 17 * 100%);
}

.day .hour:nth-of-type(18):after {
	/*content: "17";*/
}

.day .hour:nth-of-type(19) {
	left: calc(1 / 24 * 18 * 100%);
}

.day .hour:nth-of-type(19):after {
	content: "18";
}

.day .hour:nth-of-type(20) {
	left: calc(1 / 24 * 19 * 100%);
}

.day .hour:nth-of-type(20):after {
	/*content: "19";*/
}

.day .hour:nth-of-type(21) {
	left: calc(1 / 24 * 20 * 100%);
}

.day .hour:nth-of-type(21):after {
	content: "20";
}

.day .hour:nth-of-type(22) {
	left: calc(1 / 24 * 21 * 100%);
}

.day .hour:nth-of-type(22):after {
	/*content: "21";*/
}

.day .hour:nth-of-type(23) {
	left: calc(1 / 24 * 22 * 100%);
}

.day .hour:nth-of-type(23):after {
	content: "22";
}

.day .hour:nth-of-type(24) {
	left: calc(1 / 24 * 23 * 100%);
}

.day .hour:nth-of-type(24):after {
	/*content: "23";*/
}

.day .hour:nth-of-type(25) {
	left: calc(1 / 24 * 24 * 100%);
	width: 1px;
}

.day .hour:nth-of-type(25):after {
	content: "24";
}

.day .hour:after {
	text-indent: -0.5em;
}

.day .halfhour {
	left: 50%;
}

.weekday {
	position: relative;
	overflow: hidden;
	padding-right: 10px;
}

.weekday>div:nth-child(1) {
	width: 80px;
	position: relative;
	top: 25px;
	text-align: center;
	user-select: none;
	float: left;
}

.weekday>div:nth-child(2) {
	margin-left: 80px;
}

.bar div {
	display: inline-block;
}

.item {
	position: absolute;
	top: 0;
	/*width: 10px;*/
	/*width:calc(1 / 24 * 4 * 100%);*/
	height: 100%;
	background-color: #8dc8ff;
	/*overflow: hidden;*/
}

.bright {
	width: 10px;
	height: 100%;
	/*cursor: e-resize;*/
	background: transparent;
	position: absolute;
	right:-5px ;
	top: 0;
	z-index: 1;
}

.bleft {
	width: 10px;
	height: 100%;
	/*cursor: e-resize;*/
	background: transparent;
	position: absolute;
	left:-5px ;
	top: 0;
	z-index: 1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值