仓储管理---文件管理

  1. 效果图

  1. 文件分布模块

  1. 安装依赖

npm install vue - splitpane --save
npm install file-saver
npm install jszip
  1. 代码模块

1、papersList页面

<!-- 文件管理 -->
<template>
  <a-card>
    <splitPane
      :max-percent="100"
      :default-percent="defaultPercentOne"
      :min-percent="10"
      split="vertical"
      class="splitpanes__pane"
      :style="{ height: screenHeight - 128 + 'px' }"
    >
      <template slot="paneL">
        <papersTree @fold="getPercent" @hasect="hasect" />
      </template>
      <template slot="paneR">
        <div class="penclass">
          <a-icon type="bug" style="color:#fff;font-size: 10px;" />
        </div>
        <papersfile />
      </template>
    </splitPane>
  </a-card>
</template>

<script>
import papersTree from '@views/erp/papers/modal/papersTree'
import papersfile from '@views/erp/papers/modal/papersfile'
import splitPane from 'vue-splitpane'
export default {
  components: {
    papersTree,
    papersfile,
    splitPane
  },
  name: 'handModale',
  data() {
    return {
      defaultPercentOne: 15,
      url: {
        list: '/cnsMainFiles/cnsMainFiles/list'
      }
    }
  },
  beforeCreate() {
    // 屏幕高度
    this.screenHeight = document.documentElement.clientHeight
  },

  methods: {
    getPercent(text) {
      if (text) this.defaultPercentOne = 15
      if (!text) this.defaultPercentOne = 5
    },
    // 点击传递来的参数
    hasect(ist) {
      console.log(ist)
    }
  }
}
</script>
<style lang="less" scoped>
.penclass {
  position: absolute;
  background: blue;
  top: 40%;
  left: -5px;
  width: 10px;
  height: 45px;
  display: flex;
  justify-content: center;
  align-self: center;
  align-items: center;
  border-radius: 10px;
}
</style>

2、papersTree页面

<!-- 文件管理左侧 -->
<template>
  <a-card :body-style="{ padding: '0', height: screenHeight - 128 + 'px' }">
    <a-card :body-style="{ padding: '8px 10px' }">
      <a-breadcrumb class="reumb">
        <a-breadcrumb-item>
          <a-icon type="home" @click="getHome" />
        </a-breadcrumb-item>
        <a-breadcrumb-item v-for="(item, index) in crumbArr" :key="index">
          <a href="#" @click="hdSelect(item)">{{ item.title }}</a>
        </a-breadcrumb-item>
      </a-breadcrumb>
    </a-card>
    <a-card :body-style="{ padding: '5px 10px' }" :bordered="false">
      <a-directory-tree
        :clickRowToExpand="true"
        :treeData="treeData"
        :replace-fields="replaceFields"
        :autoExpandParent="pandAll"
        :default-expand-all="true"
        @select="onSelect"
      >
      </a-directory-tree>
    </a-card>
  </a-card>
</template>

<script>
import { postAction } from '@/api/manage'
import VuexBus from '@/views/erp/papers/modal/VuexBus'
export default {
  name: 'handTree',
  data() {
    return {
      pandAll: false,
      expandedKeysss: [],
      crumbArr: [],
      replaceFields: {
        children: 'child',
        title: 'name'
      },
      treeData: [],
      url: {
        readDirIter: '/oss/upyun/filee/listTree',
        // 创建文件夹
        mkdir: '/oss/upyun/filee/mkdir',
        // 删除文件夹
        delFileOrDir: '/oss/upyun/filee/delFileOrDir'
      }
    }
  },
  beforeCreate() {
    // 屏幕高度
    this.screenHeight = document.documentElement.clientHeight
  },
  created() {
    let that = this
    that.loadData()
  },
  methods: {
    hdSelect(item) {
      let that = this
      let company = item.filePath.split('/')
      let Arr = company.filter(item => {
        return item.length > 0
      })
      that.crumbArr = []
      Arr.forEach((item1, index) => {
        let path = {}
        let textArr = item.filePath
          .split('/')
          .slice(0, index + 2)
          .join('/')
        path.title = item1
        path.filePath = textArr
        that.crumbArr.push(path)
      })
      VuexBus.$emit('Pafile', that.crumbArr)
    },
    // 回到首页
    getHome() {
      this.loadData()
      this.crumbArr = []
      VuexBus.$emit('Pafile', '')
    },
    // 数据请求接口
    loadData() {
      let that = this
      let params = {}
      postAction(that.url.readDirIter, params).then(res => {
        if (res.success) {
          that.onTree(res.result)
        } else {
          this.$message.warning(res.message)
        }
      })
    },
    // 组合数据
    onTree(arr) {
      let that = this
      let Arr = this.deepFilter(arr)
      that.treeData = Arr
    },
    deepFilter(list) {
      // 使用filter 过滤当前层的数组
      return list.filter(item => {
        // filter其实也是遍历
        // 把当前遍历的节点的children 也调用一次 deepFilter 函数,返回过滤后的数组重新赋值
        if (item.child) item.child = this.deepFilter(item.child)
        // 最后判断当前节点是否符合过滤要求
        return item.type == 'folder'
      })
    },
    onSelect(selectedKeys, event) {
      let that = this
      let file = event.node.dataRef
      let company = file.filePath.split('/')
      let Arr = company.filter(item => {
        return item.length > 0
      })
      that.crumbArr = []
      Arr.forEach((item1, index) => {
        let path = {}
        let textArr = file.filePath
          .split('/')
          .slice(0, index + 2)
          .join('/')
        path.title = item1
        path.filePath = textArr
        that.crumbArr.push(path)
      })
      VuexBus.$emit('Pafile', that.crumbArr)
    }
  }
}
</script>
<style scoped lang="less">
.reumb {
  height: 32px;
  display: flex;
  align-self: center;
  align-items: center;
}
.ClVoum {
  margin-left: 10px;
}
.ClInput {
  padding-left: 10px;
  border: 1px solid #d9d9d9;
  border-radius: 3px;
}
.ClInput:focus {
  outline: none;
  border: 1px solid #597ef7;
}
</style>

3、papersfile页面

<!-- 文件管理右侧 -->
<template>
  <a-card :body-style="{ padding: '0px', height: screenHeight - 128 + 'px' }">
    <a-card :body-style="{ padding: '8px 10px' }">
      <div class="Crumb">
        <a-breadcrumb class="reumb">
          <a-breadcrumb-item>
            <a-icon type="home" @click="getHome()" />
          </a-breadcrumb-item>
          <a-breadcrumb-item v-for="(item, index) in crumbArr" :key="index">
            <a href="#" @click="hdSelect(item)">{{ item.title }}</a>
          </a-breadcrumb-item>
        </a-breadcrumb>
        <div>
          <a-button @click="loadData()" icon="redo" type="primary">刷新</a-button>
          <a-divider type="vertical" />
          <a-popover trigger="click" placement="bottomLeft" v-model="pushShow">
            <template slot="content">
              <div @click="getupload" style="margin-bottom: 10px;"><a>上传本地文件</a></div>
              <div><a @click="getIncreased">新增文件夹</a></div>
            </template>
            <a-button icon="plus" v-if="!ShowMove">添加</a-button>
          </a-popover>
          <span v-if="selectedRowKeys.length > 0">
            <a-divider type="vertical" />
            <a-button icon="swap" @click="getMove">移动</a-button>
            <a-divider type="vertical" />
            <a-button icon="delete" type="danger" @click="getdele">删除</a-button>
            <a-divider type="vertical" />
            <a-button icon="arrow-down" @click="batcLhLoad()">下载</a-button>
          </span>
          <span v-if="ShowMove">
            <a-divider type="vertical" />
            <a-button @click="stickup" icon="snippets">粘贴</a-button>
            <a-divider type="vertical" />
            <a-button @click="MoveCancel" icon="retweet">取消</a-button>
          </span>
        </div>
      </div>
    </a-card>
    <a-table
      ref="table"
      size="small"
      :loading="loading"
      :columns="columns"
      :dataSource="dataSource"
      :pagination="ipagination"
      :rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
      @change="handleTableChange"
    >
      <!-- 文件名 -->
      <span slot="filePathSlot" slot-scope="text, record">
        <span class="around">
          <a-space>
            <a-icon
              :type="getType(record)"
              style="color: #999;font-size: 18px;"
              :style="{ color: record.type == 'folder' ? 'Orange' : 'blue' }"
            />
            <span class="ant-dropdown-link" @click="hdSelect(record)" v-if="record.type == 'folder'">{{
              record.name
            }}</span>
            <span class="ant-dropdown-link" v-else>{{ getwnload(record) }}</span>
          </a-space>
          <a-space>
            <span class="contenter">
              <div>
                <a-icon
                  type="cloud-download"
                  v-if="record.type != 'folder'"
                  class="iconOne"
                  @click="batcLhLoad(record)"
                  style="font-size: 20px;margin-right:25px"
                />
              </div>
            </span>
            <Apopover :round="record" />
          </a-space>
        </span>
      </span>
      <!-- 格式 -->
      <span slot="SizeSlot" slot-scope="text, record">
        <span>{{ text }} K</span>
      </span>
    </a-table>
    <Aupload ref="uploadFrom" :crumbArr="crumbArr" @loadData="loadData" />
  </a-card>
</template>
<script>
import VuexBus from '@/views/erp/papers/modal/VuexBus'
import Apopover from '@/views/erp/papers/modal/sembly/Apopover'
import Aupload from '@/views/erp/papers/modal/sembly/upload'
import FileSaver from 'file-saver'
import Vue from 'vue'
import JsZip from 'jszip'
import { postAction } from '@/api/manage'
export default {
  components: {
    Apopover,
    Aupload
  },
  name: 'papersfile',
  data() {
    return {
      crumbArr: [],
      pushShow: false,
      ipagination: {
        current: 1,
        pageSize: 10,
        pageSizeOptions: ['10', '20', '30'],
        showTotal: (total, range) => {
          return range[0] + '-' + range[1] + ' 共' + total + '条'
        },
        total: 0
      },
      loading: false,
      ShowMove: false,
      columns: [
        {
          title: '文件名',
          dataIndex: 'name',
          align: 'left',
          width: 360,
          ellipsis: true,
          scopedSlots: { customRender: 'filePathSlot' }
        },
        {
          title: '文件大小',
          dataIndex: 'size',
          align: 'center',
          width: 80,
          scopedSlots: { customRender: 'SizeSlot' }
        },
        {
          title: '创建时间',
          dataIndex: 'date',
          align: 'center'
        }
      ],
      dataSource: [],
      selectedRowKeys: [],
      selectedRecord: [],
      queryParam: {},
      url: {
        // 列表
        readDirIter: '/oss/upyun/filee/listTree',
        // 删除文件夹
        delFileOrDir: '/oss/upyun/filee/delFileOrDir',
        // 创建文件夹
        mkdir: '/oss/upyun/filee/mkdir',
        // 复制/移动文件
        copyMoveFiles: '/oss/upyun/filee/copyMoveFiles',
        // 获取文件信息
        getFileInfo: '/oss/upyun/filee/getFileInfo'
      }
    }
  },
  beforeCreate() {
    // 屏幕高度
    this.screenHeight = document.documentElement.clientHeight
  },
  mounted() {
    VuexBus.$on('Pafile', res => {
      if (res.length > 0) {
        this.crumbArr = res
      } else {
        this.crumbArr = []
      }
      this.loadData()
    })
  },
  created() {
    let that = this
    that.loadData()
    // 赋值为空  移动  复制
    Vue.ls.remove('move')
    this.ShowMove = false
  },
  methods: {
    // 数据请求接口
    loadData() {
      let that = this
      let params = {}
      that.loading = true
      if (that.crumbArr.length > 0) params.fileUrl = that.Onsift()
      postAction(that.url.readDirIter, params).then(res => {
        that.loading = false
        if (res.success) {
          that.dataSource = res.result
          that.selectedRowKeys = []
          that.selectedRecord = []
          if (that.crumbArr.length < 1) that.getHome('loadData')
        } else {
          this.$message.warning(res.message)
        }
      })
    },
    // 文件名称
    getwnload(round) {
      let file = ''
      if (round.name) {
        let text = round.name.substring(round.name.lastIndexOf('/') + 1)
        file = text.substring(0, text.lastIndexOf('.'))
      }
      return file
    },
    // 操作图标
    getType(round) {
      let ioc = ''
      if (round.name) {
        let file = round.name.substring(round.name.lastIndexOf('.') + 1)
        if (file == 'JPG' || file == 'jpg') ioc = 'file-jpg'
        if (file == 'xlsx') ioc = 'file-excel'
        if (file == 'xls') ioc = 'file-excel'
        if (file == 'png') ioc = 'file-image'
        if (file == 'sql') ioc = 'layout'
      }
      if (round.type == 'folder') ioc = 'folder'
      return ioc
    },
    // 下载
    batcLhLoad(round) {
      // round 传递过来的是一个对象
      //dataSource为一个数组
      var blogTitle = `文件下载` // 下载后压缩包的命名
      var zip = new JsZip()
      var promises = []
      let cache = {}
      let arrImg = []
      // 这里是执行单个文件下载
      if (round) {
        arrImg.push({
          path: round.name, // 文件链接
          name: round.name // 文件名称
        })
      } else {
        // 多个文件下载
        this.selectedRecord.forEach((item, index) => {
          arrImg.push({
            path: item.name, // 文件链接
            name: item.name // 文件名称
          })
        })
      }
      arrImg.forEach(item => {
        const promise = this.getImgArrayBuffer(item.path).then(data => {
          // 下载文件, 并存成ArrayBuffer对象(blob)
          zip.file(item.name, data, { binary: true }) // 逐个添加文件
          cache[item.name] = data
        })
        promises.push(promise)
      })
      Promise.all(promises)
        .then(() => {
          zip.generateAsync({ type: 'blob' }).then(content => {
            // 生成二进制流
            FileSaver.saveAs(content, blogTitle) // 利用file-saver保存文件  自定义文件名
          })
        })
        .catch(res => {
          alert('文件压缩失败')
        })
    },
    getImgArrayBuffer(url) {
      return new Promise((resolve, reject) => {
        //通过请求获取文件blob格式
        let xmlhttp = new XMLHttpRequest()
        xmlhttp.open('GET', url, true)
        xmlhttp.responseType = 'blob'
        xmlhttp.onload = function() {
          if (this.status == 200) {
            resolve(this.response)
          } else {
            reject(this.status)
          }
        }
        xmlhttp.send()
      })
    },
    // 监听选框变化
    onSelectChange(selectedRowKeys, record) {
      let that = this
      that.selectedRowKeys = selectedRowKeys
      that.selectedRecord = record
    },
    handleTableChange(pagination, filters, sorter) {
      //分页、排序、筛选变化时触发
      if (Object.keys(sorter).length > 0) {
        this.isorter.column = sorter.field
        this.isorter.order = 'ascend' == sorter.order ? 'asc' : 'desc'
      }
      this.ipagination = pagination
      this.loadData()
    },
    // 移动到
    getMove() {
      let move = this.selectedRecord
      this.ShowMove = true
      Vue.ls.set('move', move)
      this.selectedRowKeys = []
      this.selectedRecord = []
    },
    // 取消移动
    MoveCancel() {
      Vue.ls.remove('move')
      this.ShowMove = false
    },
    // 删除
    getdele() {
      let that = this
      this.$confirm({
        title: '你确定要删除?',
        content: '删除文件夹文件夹必须为空文件夹',
        onOk() {
          that.confirm()
        },
        onCancel() {}
      })
    },
    confirm() {
      let that = this
      let params = {}
      params.itemList = that.selectedRecord
      params.fileUrl = that.Onsift()
      postAction(that.url.delFileOrDir, params).then(res => {
        if (res.success) {
          this.$message.success('删除成功')
          that.selectedRecord = []
          this.selectedRowKeys = []
          this.loadData()
        } else {
          that.$message.warning(res.message)
          return false
        }
      })
    },
    // 粘贴
    stickup() {
      let that = this
      let move = Vue.ls.get('move')
      let params = {}
      params.targetPath = that.Onsift()
      params.copyMove = 'MOVE'
      params.itemList = move
      postAction(that.url.copyMoveFiles, params).then(res => {
        console.log(res)
        if (res.success) {
          this.loadData()
        } else {
          that.$message.warning(res.message)
          return false
        }
      })
      that.ShowMove = false
    },
    // 上传
    getupload() {
      let that = this
      that.pushShow = false
      that.$refs.uploadFrom.showModal()
    },
    // 面包屑home
    getHome(round) {
      this.crumbArr = []
      if (!round) this.loadData()
    },
    hdSelect(item) {
      let that = this
      console.log(item)
      let company = item.filePath.split('/')
      let Arr = company.filter(item => {
        return item.length > 0
      })
      that.crumbArr = []
      Arr.forEach((item1, index) => {
        let path = {}
        let textArr = item.filePath
          .split('/')
          .slice(0, index + 2)
          .join('/')
        path.title = item1
        path.filePath = textArr
        that.crumbArr.push(path)
      })
      that.loadData()
    },
    // 新增文件夹
    getIncreased() {
      let that = this
      let reased = {}
      reased.filePath = that.Onsift()
      this.$confirm({
        content: (
          <span class="clRecord">
            <span>文件名:</span>
            <span class="ClVoum">
              <input class="ClInput" vModel={reased.fileUrl} />
            </span>
          </span>
        ),
        onOk() {
          that.onMkdir(reased)
        },
        onCancel() {}
      })
    },
    // 新增文件夹调用接口
    onMkdir(round) {
      let that = this
      let params = round
      params.fileUrl = round.filePath + '/' + round.fileUrl
      postAction(that.url.mkdir, params).then(res => {
        if (res.success) {
          that.loadData(round.filePath)
        } else {
          that.$message.warning(res.message)
        }
      })
    },
    // 筛选面包屑文件地址
    Onsift() {
      let that = this
      let text = '/'
      if (that.crumbArr.length > 0) {
        let index = that.crumbArr.length - 1
        text = that.crumbArr[index].filePath
      }
      return text
    }
  }
}
</script>

<style scoped lang="less">
.around {
  display: flex;
  justify-content: space-between;
  align-items: center;
  align-self: center;
}
.contenter {
  display: none;
}
.around:hover .contenter {
  display: block;
}
.iconOne:hover {
  color: blue;
}
.icontwe:hover {
  color: blue;
}
.iconSan:hover {
  color: blue;
}
.Crumb {
  display: flex;
  justify-content: space-between;
  align-items: center;
  align-self: center;
}
.ClVoum {
  margin-left: 10px;
}
.ClInput {
  padding-left: 10px;
  border: 1px solid #d9d9d9;
  border-radius: 3px;
}
.ClInput:focus {
  outline: none;
  border: 1px solid #597ef7;
}
</style>

4、drabute文件

<template>
  <a-drawer width="600px" title="属性" placement="right" :closable="false" :visible="visible" @close="onClose">
    <a-row>
      <a-col :md="24">
        <a-form-item label="名字:" :labelCol="{ span: 4 }" :wrapperCol="{ span: 17 }">
          <span><a-input disabled v-model="round.name" placeholder=" "/></span>
        </a-form-item>
      </a-col>
      <a-col :md="24">
        <a-form-item label="大小:" :labelCol="{ span: 4 }" :wrapperCol="{ span: 17 }">
          <span><a-input disabled v-model="round.size" placeholder=" "/></span>
        </a-form-item>
      </a-col>
      <a-col :md="24">
        <a-form-item label="名字:" :labelCol="{ span: 4 }" :wrapperCol="{ span: 17 }">
          <span><a-input disabled v-model="round.name" placeholder=" "/></span>
        </a-form-item>
      </a-col>
    </a-row>
  </a-drawer>
</template>
<script>
import { postAction } from '@/api/manage'
export default {
  data() {
    return {
      visible: false,
      url: {
        // 列表
        getFileInfo: '/oss/upyun/filee/getFileInfo'
      }
    }
  },
  props: {
    round: {
      type: Object,
      default: () => ({})
    }
  },
  methods: {
    showDrawer() {
      this.visible = true
      this.loadData()
    },
    loadData() {
      let that = this
      let params = {}
      params.fileUrl = that.round.filePath
      postAction(that.url.getFileInfo, params).then(res => {
        if (res.success) {
        } else {
          that.$message.warning(res.message)
        }
      })
    },
    onClose() {
      this.visible = false
    }
  }
}
</script>

5、Apopover,模块

<template>
  <div>
    <a-popover trigger="click" v-model="visible">
      <span slot="content">
        <a-row style="width: 100px;">
          <a-col :md="24" @click="showConfirm"> <a-icon type="edit" style="margin:8px 20px 8px 5px" />重命名 </a-col>
          <a-col :md="24" @click="gettribute">
            <a-icon type="question-circle" style="margin:8px 20px 8px 5px" />属性</a-col
          >
        </a-row>
      </span>
      <a-icon type="small-dash" class="iconSan" style="font-size: 20px;" />
    </a-popover>
    <drabute ref="buteFrom" :round="round" />
  </div>
</template>
<script>
import drabute from '@/views/erp/papers/modal/drabute'
export default {
  name: 'Apopover',
  components: {
    drabute
  },
  data() {
    return {
      visible: false
    }
  },
  props: {
    round: {
      type: Object,
      default: () => ({})
    }
  },
  methods: {
    // 属性
    gettribute() {
      let that = this
      that.visible = false
      that.$refs.buteFrom.showDrawer()
    },
    // 重命名
    showConfirm() {
      this.visible = false
      this.$confirm({
        content: (
          <span class="clRecord">
            <span>文件名:</span>
            <span class="ClVoum">
              <input class="ClInput" vModel={this.round.name} />
            </span>
          </span>
        ),
        onOk() {
          console.log('修改方法')
        },
        onCancel() {}
      })
    }
  }
}
</script>

<style scoped lang="less">
.box {
  display: flex;
  flex-direction: column;
}
.clRecord {
  display: flex;
  justify-content: center;
  margin-top: 20px;
  align-items: center;
  align-self: center;
  font-size: 16px;
}
.ClVoum {
  margin-left: 10px;
}
.ClInput {
  padding-left: 10px;
  border: 1px solid #d9d9d9;
  border-radius: 3px;
}
.ClInput:focus {
  outline: none;
  border: 1px solid #597ef7;
}
</style>

7、upload模块

<!-- 上传 -->
<template>
  <a-modal v-model="visible" title="文件上传" @ok="handleOk" v-if="visible">
    <a-upload-dragger
      name="file"
      :multiple="true"
      :method="'post'"
      :action="uploadAction"
      @change="handleChange"
      :headers="headers"
      :data="{
        fileUrl: fileUrlText
      }"
      :remove="handleFileRemove"
    >
      <p class="ant-upload-drag-icon"><a-icon type="inbox" /></p>
      <p class="ant-upload-text">
        请把需要上传的文件拖放进来,或者点击上传文件
      </p>
    </a-upload-dragger>
  </a-modal>
</template>
<script>
import { postAction } from '@/api/manage'
import { ACCESS_TOKEN } from '@/store/mutation-types'
import Vue from 'vue'
export default {
  name: 'upload',
  data() {
    return {
      visible: false,
      uploadLoading: false,
      headers: '',
      fileUrlText: '/',
      defaultFileList: [],
      url: {
        // 上传
        uploadUpyun: '/oss/upyun/filee/uploadUpyun',
        // 删除
        deleteFile: '/oss/upyun/filee/deleteFile'
      }
    }
  },
  //   传递过来的路径
  props: {
    crumbArr: {
      type: Array,
      default: []
    }
  },
  watch: {
    crumbArr: {
      immediate: true,
      handler(val) {
        let that = this
        if (val.length > 0) {
          let index = val.length - 1
          that.fileUrlText = val[index].filePath
        }
      }
    }
  },
  created() {
    // 拿到本地token
    const token = Vue.ls.get(ACCESS_TOKEN)
    this.headers = { 'X-Access-Token': token }
  },
  computed: {
    uploadAction: function() {
      // 抛出上传接口
      return window._CONFIG['domianURL'] + this.url.uploadUpyun
    }
  },
  methods: {
    showModal() {
      this.visible = true
    },
    handleOk() {
      this.$emit('loadData')
      this.defaultFileList = []
      this.visible = false
    },
    // 文件上传
    handleChange(info) {
      if (info.file.status === 'uploading') {
        this.uploadLoading = true
        return
      }
      if (info.file.status === 'done') {
        var response = info.file.response
        this.uploadLoading = false
        if (response.success) {
          this.$message.success('上传成功')
        } else {
          this.$message.warning(response.message)
        }
      }
    },
    //   删除方法
    handleFileRemove(file) {
      let that = this
      let params = {}
      params.fileUrl = file.response.result.fileUrl
      postAction(that.url.deleteFile, params).then(res => {
        if (res.success) {
          this.$message.success('删除成功')
        } else {
          that.$message.warning(res.message)
          return false
        }
      })
    }
  }
}
</script>

<style scoped lang="less"></style>

gitt:后期更新

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

My&Liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值