gin-vue-admin 2.0代码重构
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<form id="fromCont" method="post">
|
||||
<input @change="choseFile" id="file" multiple="multiple" type="file" />
|
||||
</form>
|
||||
<el-button @click="getFile">上传</el-button>
|
||||
<span
|
||||
v-if="this.file"
|
||||
>{{Math.floor(((this.formDataList.length-this.waitNum)/this.formDataList.length)*100)}}%</span>
|
||||
<h2>此版本为先行体验功能测试版,样式美化和性能优化正在进行中,上传切片文件和合成的完整文件分别再QMPlusserver目录的breakpointDir文件夹和fileDir文件夹</h2>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
import SparkMD5 from 'spark-md5'
|
||||
import axios from 'axios'
|
||||
import {
|
||||
findFile,
|
||||
breakpointContinueFinish,
|
||||
removeChunk
|
||||
} from '@/api/breakpoint'
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
data() {
|
||||
return {
|
||||
file: null,
|
||||
fileMd5: '',
|
||||
formDataList: [],
|
||||
waitUpLoad: [],
|
||||
waitNum: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 选中文件的函数
|
||||
async choseFile(e) {
|
||||
const fileR = new FileReader() // 创建一个reader用来读取文件流
|
||||
const file = e.target.files[0] // 获取当前文件
|
||||
this.file = file // file 丢全局方便后面用 可以改进为func传参形式
|
||||
fileR.readAsArrayBuffer(file) // 把文件读成ArrayBuffer 主要为了保持跟后端的流一致
|
||||
fileR.onload = async e => {
|
||||
// 读成arrayBuffer的回调 e 为方法自带参数 相当于 dom的e 流存在e.target.result 中
|
||||
const bolb = e.target.result
|
||||
let spark = new SparkMD5.ArrayBuffer() // 创建md5制造工具 (md5用于检测文件一致性 这里不懂就打电话问我)
|
||||
spark.append(bolb) // 文件流丢进工具
|
||||
this.fileMd5 = spark.end() // 工具结束 产生一个a 总文件的md5
|
||||
const FileSliceCap = 1 * 1024 * 1024 // 分片字节数
|
||||
let start = 0 // 定义分片开始切的地方
|
||||
let end = 0 // 每片结束切的地方a
|
||||
let i = 0 // 第几片
|
||||
this.formDataList = [] // 分片存储的一个池子 丢全局
|
||||
while (end < file.size) {
|
||||
// 当结尾数字大于文件总size的时候 结束切片
|
||||
start = i * FileSliceCap // 计算每片开始位置
|
||||
end = (i + 1) * FileSliceCap // 计算每片结束位置
|
||||
var fileSlice = this.file.slice(start, end) // 开始切 file.slice 为 h5方法 对文件切片 参数为 起止字节数
|
||||
const formData = new window.FormData() // 创建FormData用于存储传给后端的信息
|
||||
formData.append('fileMd5', this.fileMd5) // 存储总文件的Md5 让后端知道自己是谁的切片
|
||||
formData.append('file', fileSlice) //当前的切片
|
||||
formData.append('chunkNumber', i) // 当前是第几片
|
||||
formData.append('fileName', this.file.name) //当前文件的文件名 用于后端文件切片的命名 formData.appen 为 formData对象添加参数的方法
|
||||
this.formDataList.push({ key: i, formData }) // 把当前切片信息 自己是第几片 存入我们方才准备好的池子
|
||||
i++
|
||||
}
|
||||
const params = {
|
||||
fileName: this.file.name,
|
||||
fileMd5: this.fileMd5,
|
||||
chunkTotal: this.formDataList.length
|
||||
}
|
||||
const res = await findFile(params)
|
||||
// 全部切完以后 发一个请求给后端 拉当前文件后台存储的切片信息 用于检测有多少上传成功的切片
|
||||
const finishList = res.data.file.ExaFileChunk // 上传成功的切片
|
||||
const IsFinish = res.data.file.IsFinish // 是否是同文件不同命 (文件md5相同 文件名不同 则默认是同一个文件但是不同文件名 此时后台数据库只需要拷贝一下数据库文件即可 不需要上传文件 即秒传功能)
|
||||
if (!IsFinish) {
|
||||
// 当是断点续传时候
|
||||
this.waitUpLoad = this.formDataList.filter(all => {
|
||||
return !(
|
||||
finishList &&
|
||||
finishList.some(fi => fi.FileChunkNumber === all.key)
|
||||
) // 找出需要上传的切片
|
||||
})
|
||||
} else {
|
||||
this.waitUpLoad = [] // 秒传则没有需要上传的切片
|
||||
}
|
||||
this.waitNum = this.waitUpLoad.length // 记录长度用于百分比展示
|
||||
}
|
||||
},
|
||||
getFile() {
|
||||
// 确定按钮
|
||||
if (this.file == null) {
|
||||
this.$message('请先上传文件')
|
||||
return
|
||||
}
|
||||
this.sliceFile() // 上传切片
|
||||
},
|
||||
sliceFile() {
|
||||
this.waitUpLoad &&
|
||||
this.waitUpLoad.map(item => {
|
||||
//需要上传的切片
|
||||
item.formData.append('chunkTotal', this.formDataList.length) // 切片总数携带给后台 总有用的
|
||||
const fileR = new FileReader() // 功能同上
|
||||
const file = item.formData.get('file')
|
||||
fileR.readAsArrayBuffer(file)
|
||||
fileR.onload = e => {
|
||||
let spark = new SparkMD5.ArrayBuffer()
|
||||
spark.append(e.target.result)
|
||||
item.formData.append('chunkMd5', spark.end()) // 获取当前切片md5 后端用于验证切片完整性
|
||||
this.upLoadFileSlice(item)
|
||||
}
|
||||
})
|
||||
},
|
||||
async upLoadFileSlice(item) {
|
||||
// 切片上传
|
||||
await axios.post(process.env.VUE_APP_BASE_API+"/fileUploadAndDownload/breakpointContinue",item.formData)
|
||||
this.waitNum-- // 百分数增加
|
||||
if (this.waitNum == 0) {
|
||||
// 切片传完以后 合成文件
|
||||
const params = {
|
||||
fileName: this.file.name,
|
||||
fileMd5: this.fileMd5
|
||||
}
|
||||
const res = await breakpointContinueFinish(params)
|
||||
if (res.success) {
|
||||
// 合成文件过后 删除缓存切片
|
||||
const params = {
|
||||
fileName: this.file.name,
|
||||
fileMd5: this.fileMd5,
|
||||
filePath: res.data.filePath
|
||||
}
|
||||
await removeChunk(params)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="search-term">
|
||||
<el-form :inline="true" :model="searchInfo" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<el-button @click="openDialog" type="primary">新增客户</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-table
|
||||
:data="tableData"
|
||||
@selection-change="handleSelectionChange"
|
||||
border
|
||||
ref="multipleTable"
|
||||
stripe
|
||||
style="width: 100%"
|
||||
tooltip-effect="dark"
|
||||
>
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column label="接入日期" width="180">
|
||||
<template slot-scope="scope">{{ scope.row.CreatedAt|formatDate }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="姓名" prop="customerName" width="120"></el-table-column>
|
||||
<el-table-column label="电话" prop="customerPhoneData" width="120"></el-table-column>
|
||||
<el-table-column label="接入人ID" prop="sysUserId" width="120"></el-table-column>
|
||||
<el-table-column label="按钮组">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click="updateCustomer(scope.row)" size="small" type="text">变更</el-button>
|
||||
<el-popover
|
||||
placement="top"
|
||||
width="160"
|
||||
v-model="visible">
|
||||
<p>确定要删除吗?</p>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button size="mini" type="text" @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" size="mini" @click="deleteCustomer(scope.row)">确定</el-button>
|
||||
</div>
|
||||
<el-button type="text" size="mini" slot="reference">删除</el-button>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
:current-page="page"
|
||||
:page-size="pageSize"
|
||||
:page-sizes="[10, 30, 50, 100]"
|
||||
:style="{float:'right',padding:'20px'}"
|
||||
:total="total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination>
|
||||
|
||||
<el-dialog :before-close="closeDialog" :visible.sync="dialogFormVisible" title="新增Api">
|
||||
<el-form :inline="true" :model="form" label-width="80px">
|
||||
<el-form-item label="客户名">
|
||||
<el-input autocomplete="off" v-model="form.customerName"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="客户电话">
|
||||
<el-input autocomplete="off" v-model="form.customerPhoneData"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="dialog-footer" slot="footer">
|
||||
<el-button @click="closeDialog">取 消</el-button>
|
||||
<el-button @click="enterDialog" type="primary">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
在资源权限中将此角色的资源权限清空 或者不包含创建者的角色 即可屏蔽此客户资源的显示
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import {
|
||||
createExaCustomer,
|
||||
updateExaCustomer,
|
||||
deleteExaCustomer,
|
||||
getExaCustomer,
|
||||
getExaCustomerList
|
||||
} from '@/api/customer'
|
||||
import { formatTimeToStr } from '@/utils/data'
|
||||
import infoList from '@/components/mixins/infoList'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'Customer',
|
||||
mixins: [infoList],
|
||||
data(){
|
||||
return{
|
||||
listApi: getExaCustomerList,
|
||||
listKey: 'customer',
|
||||
dialogFormVisible:false,
|
||||
visible:false,
|
||||
type:"",
|
||||
form:{
|
||||
customerName:"",
|
||||
customerPhoneData:""
|
||||
}
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
...mapGetters('user', ['token'])
|
||||
},
|
||||
filters: {
|
||||
formatDate: function(time) {
|
||||
if (time != null && time != '') {
|
||||
var date = new Date(time)
|
||||
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
async updateCustomer(row){
|
||||
const res = await getExaCustomer(row)
|
||||
this.type = "update"
|
||||
if(res.success){
|
||||
this.form = res.data.customer
|
||||
this.dialogFormVisible = true
|
||||
}
|
||||
},
|
||||
closeDialog(){
|
||||
this.dialogFormVisible = false
|
||||
},
|
||||
async deleteCustomer(row){
|
||||
this.visible = false
|
||||
const res = await deleteExaCustomer(row)
|
||||
if (res.success){
|
||||
this.getTableData()
|
||||
}
|
||||
},
|
||||
async enterDialog(){
|
||||
let res
|
||||
switch (this.type) {
|
||||
case "create":
|
||||
res =await createExaCustomer(this.form)
|
||||
break;
|
||||
case "update":
|
||||
res =await updateExaCustomer(this.form)
|
||||
break;
|
||||
default:
|
||||
res =await createExaCustomer(this.form)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if(res.success){
|
||||
this.dialogFormVisible = false
|
||||
this.getTableData()
|
||||
}
|
||||
},
|
||||
openDialog() {
|
||||
this.type = "create"
|
||||
this.dialogFormVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-upload
|
||||
:action="`${path}/fileUploadAndDownload/upload`"
|
||||
:before-remove="beforeRemove"
|
||||
:file-list="fileList"
|
||||
:headers="{'x-token':token}"
|
||||
:limit="10"
|
||||
:on-exceed="handleExceed"
|
||||
:on-preview="handlePreview"
|
||||
:on-remove="handleRemove"
|
||||
class="upload-demo"
|
||||
multiple
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div class="el-upload__tip" slot="tip">未对文件格式及大小做校验</div>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
const path = process.env.VUE_APP_BASE_API
|
||||
export default {
|
||||
name: 'Excel',
|
||||
data() {
|
||||
return {
|
||||
path: path,
|
||||
|
||||
fileList: [
|
||||
{
|
||||
name: 'food.jpeg',
|
||||
url:
|
||||
'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'
|
||||
},
|
||||
{
|
||||
name: 'food2.jpeg',
|
||||
url:
|
||||
'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('user', ['userInfo', 'token'])
|
||||
},
|
||||
methods: {
|
||||
handleRemove(file, fileList) {
|
||||
this.$message.warning(
|
||||
`共有 ${fileList.length} 个文件,移除了${file.name}`
|
||||
)
|
||||
},
|
||||
handlePreview(file) {
|
||||
this.$message.warning(`${file.name}选择完成`)
|
||||
},
|
||||
handleExceed(files, fileList) {
|
||||
this.$message.warning(
|
||||
`当前限制选择 3 个文件,本次选择了 ${
|
||||
files.length
|
||||
} 个文件,共选择了 ${files.length + fileList.length} 个文件`
|
||||
)
|
||||
},
|
||||
beforeRemove(file, fileList) {
|
||||
return this.$confirm(
|
||||
`共有 ${fileList.length} 个文件,确定移除 ${file.name}?`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form :model="form" label-width="80px" ref="form">
|
||||
<el-row>
|
||||
<el-col :span="3"><label for="">活动名称</label></el-col>
|
||||
<el-col :span="10"><el-input v-model="form.name"></el-input></el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="3"><label for="">活动区域</label></el-col>
|
||||
<el-col :span="10">
|
||||
<el-select placeholder="请选择活动区域" v-model="form.region">
|
||||
<el-option label="上海" value="shanghai"></el-option>
|
||||
<el-option label="北京" value="beijing"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="3"><label for="">活动时间</label></el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :span="11">
|
||||
<el-date-picker placeholder="选择日期" style="width: 100%;" type="date" v-model="form.date1"></el-date-picker>
|
||||
</el-col>
|
||||
<el-col :span="2" class="line">——</el-col>
|
||||
<el-col :span="11">
|
||||
<el-time-picker placeholder="选择时间" style="width: 100%;" v-model="form.date2"></el-time-picker>
|
||||
</el-col>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="3"><label for="">即时配送</label></el-col>
|
||||
<el-col :span="10"><el-switch v-model="form.delivery"></el-switch></el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="3"><label for="">活动性质</label></el-col>
|
||||
<el-col :span="10">
|
||||
<el-checkbox-group v-model="form.type">
|
||||
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
|
||||
<el-checkbox label="地推活动" name="type"></el-checkbox>
|
||||
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
|
||||
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="3"><label for="">特殊资源</label></el-col>
|
||||
<el-col :span="10">
|
||||
<el-radio-group v-model="form.resource">
|
||||
<el-radio label="线上品牌商赞助"></el-radio>
|
||||
<el-radio label="线下场地免费"></el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="3"><label for="">活动形式</label></el-col>
|
||||
<el-col :span="10"><el-input type="textarea" v-model="form.desc"></el-input></el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="3"><label for="">穿梭框</label></el-col>
|
||||
<el-col :span="20">
|
||||
<el-transfer
|
||||
:data="data"
|
||||
:filter-method="filterMethod"
|
||||
filter-placeholder="请输入城市拼音"
|
||||
filterable
|
||||
v-model="value"
|
||||
></el-transfer>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="3"><label for="">活动时间</label></el-col>
|
||||
<el-col :span="10"><el-input v-model="form.name"></el-input></el-col>
|
||||
</el-row>
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="13">
|
||||
<el-button @click="onSubmit" type="primary">立即创建</el-button>
|
||||
<el-button>取消</el-button>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
||||
<!-- <el-form-item label="活动名称">
|
||||
<el-input v-model="form.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select label="活动区域" placeholder="请选择活动区域" v-model="form.region">
|
||||
<el-option label="上海" value="shanghai"></el-option>
|
||||
<el-option label="北京" value="beijing"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动时间">
|
||||
<el-col :span="11">
|
||||
<el-date-picker placeholder="选择日期" style="width: 100%;" type="date" v-model="form.date1"></el-date-picker>
|
||||
</el-col>
|
||||
<el-col :span="2" class="line" style="text-align: center">——</el-col>
|
||||
<el-col :span="11">
|
||||
<el-time-picker placeholder="选择时间" style="width: 100%;" v-model="form.date2"></el-time-picker>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="即时配送">
|
||||
<el-switch v-model="form.delivery"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动性质">
|
||||
<el-checkbox-group v-model="form.type">
|
||||
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
|
||||
<el-checkbox label="地推活动" name="type"></el-checkbox>
|
||||
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
|
||||
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="特殊资源">
|
||||
<el-radio-group v-model="form.resource">
|
||||
<el-radio label="线上品牌商赞助"></el-radio>
|
||||
<el-radio label="线下场地免费"></el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动形式">
|
||||
<el-input type="textarea" v-model="form.desc"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="穿梭框">
|
||||
<el-transfer
|
||||
:data="data"
|
||||
:filter-method="filterMethod"
|
||||
filter-placeholder="请输入城市拼音"
|
||||
filterable
|
||||
v-model="value"
|
||||
></el-transfer>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="onSubmit" type="primary">立即创建</el-button>
|
||||
<el-button>取消</el-button>
|
||||
</el-form-item> -->
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
const generateData = () => {
|
||||
const data = []
|
||||
const cities = ['上海', '北京', '广州', '深圳', '南京', '西安', '成都']
|
||||
const pinyin = [
|
||||
'shanghai',
|
||||
'beijing',
|
||||
'guangzhou',
|
||||
'shenzhen',
|
||||
'nanjing',
|
||||
'xian',
|
||||
'chengdu'
|
||||
]
|
||||
cities.forEach((city, index) => {
|
||||
data.push({
|
||||
label: city,
|
||||
key: index,
|
||||
pinyin: pinyin[index]
|
||||
})
|
||||
})
|
||||
return data
|
||||
}
|
||||
return {
|
||||
form: {
|
||||
name: '',
|
||||
region: '',
|
||||
date1: '',
|
||||
date2: '',
|
||||
delivery: false,
|
||||
type: [],
|
||||
resource: '',
|
||||
desc: ''
|
||||
},
|
||||
data: generateData(),
|
||||
value: [],
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
filterMethod(query, item) {
|
||||
return item.pinyin.indexOf(query) > -1
|
||||
},
|
||||
onSubmit() {
|
||||
this.$message({
|
||||
message: '创建成功',
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<router-view></router-view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:"Example",
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="edit_container">
|
||||
<quill-editor
|
||||
:options="editorOption"
|
||||
@blur="onEditorBlur($event)"
|
||||
@change="onEditorChange($event)"
|
||||
@focus="onEditorFocus($event)"
|
||||
ref="myQuillEditor"
|
||||
v-model="content"
|
||||
></quill-editor>
|
||||
<el-button plain @click="saveHtml">保存</el-button>
|
||||
</div>
|
||||
<div class="edit">
|
||||
<mavon-editor v-model="model.content"></mavon-editor>
|
||||
<el-button type="primary" size="small" @click="submit">发表</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'App',
|
||||
data() {
|
||||
return {
|
||||
content: `<p>hello world</p>`,
|
||||
editorOption: {},
|
||||
model:{
|
||||
content:''
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
editor() {
|
||||
return this.$refs.myQuillEditor.quill
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// onEditorReady(editor) { // 准备编辑器
|
||||
|
||||
// },
|
||||
onEditorBlur() {}, // 失去焦点事件
|
||||
onEditorFocus() {}, // 获得焦点事件
|
||||
onEditorChange() {}, // 内容改变事件
|
||||
saveHtml() {}, // 保存方法
|
||||
submit(){}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,115 @@
|
||||
// table 纯前端示例
|
||||
<template>
|
||||
<div>
|
||||
<el-table
|
||||
:data="tableData"
|
||||
@selection-change="handleSelectionChange"
|
||||
border
|
||||
ref="multipleTable"
|
||||
stripe
|
||||
style="width: 100%"
|
||||
tooltip-effect="dark"
|
||||
>
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column label="日期" width="120">
|
||||
<template slot-scope="scope">{{ scope.row.date }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="姓名" prop="name" width="120"></el-table-column>
|
||||
<el-table-column label="年龄" prop="age" width="120"></el-table-column>
|
||||
<el-table-column label="住址" prop="address" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="是否禁用" prop="switch">
|
||||
<template slot-scope="scope">
|
||||
<el-switch active-text="开启" inactive-text="禁用" v-model="scope.row.switch"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="按钮组">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" @click="toggleSelection([scope.row])">按钮1</el-button>
|
||||
<el-button type="text" size="small" @click="toggleSelection([scope.row])">按钮2</el-button>
|
||||
<el-button type="text" size="small" @click="toggleSelection([scope.row])">按钮3</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="margin-top: 20px">
|
||||
<el-button @click="toggleSelection([tableData[1], tableData[2]])">切换第二、第三行的选中状态</el-button>
|
||||
<el-button @click="toggleSelection()">取消选择</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Table',
|
||||
data() {
|
||||
return {
|
||||
tableData: [
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
age: 12,
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
switch:true
|
||||
},
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
age: 12,
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
switch:true
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
age: 12,
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
switch:true
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
age: 12,
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
switch:false
|
||||
},
|
||||
{
|
||||
date: '2016-05-08',
|
||||
name: '王小虎',
|
||||
age: 12,
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
switch:true
|
||||
},
|
||||
{
|
||||
date: '2016-05-06',
|
||||
name: '王小虎',
|
||||
age: 12,
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
switch:true
|
||||
},
|
||||
{
|
||||
date: '2016-05-07',
|
||||
name: '王小虎',
|
||||
age: 12,
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
switch:false
|
||||
}
|
||||
],
|
||||
multipleSelection: []
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggleSelection(rows) {
|
||||
if (rows) {
|
||||
rows.forEach(row => {
|
||||
this.$refs.multipleTable.toggleRowSelection(row)
|
||||
})
|
||||
} else {
|
||||
this.$refs.multipleTable.clearSelection()
|
||||
}
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,164 @@
|
||||
<template>
|
||||
<div v-loading.fullscreen.lock="fullscreenLoading">
|
||||
<div class="upload">
|
||||
<el-upload
|
||||
:action="`${path}/fileUploadAndDownload/upload`"
|
||||
:before-upload="checkFile"
|
||||
:headers="{'x-token':token}"
|
||||
:on-error="uploadError"
|
||||
:on-success="uploadSuccess"
|
||||
:show-file-list="false"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
|
||||
</el-upload>
|
||||
<el-table :data="tableData" border stripe>
|
||||
<el-table-column label="预览" width="100">
|
||||
<template slot-scope="scope">
|
||||
<img :alt="scope.row.alt" :src="scope.row.url" height="80" width="80" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="日期" prop="UpdatedAt" width="180">
|
||||
<template slot-scope="scope">
|
||||
<div>{{scope.row.UpdatedAt|formatDate}}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="文件名" prop="name" width="180"></el-table-column>
|
||||
<el-table-column label="链接" prop="url"></el-table-column>
|
||||
<el-table-column label="标签" prop="tag" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-tag
|
||||
:type="scope.row.tag === 'jpg' ? 'primary' : 'success'"
|
||||
disable-transitions
|
||||
>{{scope.row.tag}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click="downloadFile(scope.row)" size="small" type="text">下载</el-button>
|
||||
<el-button @click="deleteFile(scope.row)" size="small" type="text">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
:current-page="page"
|
||||
:page-size="pageSize"
|
||||
:page-sizes="[10, 30, 50, 100]"
|
||||
:style="{float:'right',padding:'20px'}"
|
||||
:total="total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const path = process.env.VUE_APP_BASE_API
|
||||
import { mapGetters } from 'vuex'
|
||||
import infoList from '@/components/mixins/infoList'
|
||||
import { getFileList, deleteFile } from '@/api/fileUploadAndDownload'
|
||||
import { downloadImage } from '@/utils/downloadImg'
|
||||
import { formatTimeToStr } from '@/utils/data'
|
||||
export default {
|
||||
name: 'Upload',
|
||||
mixins: [infoList],
|
||||
data() {
|
||||
return {
|
||||
fullscreenLoading:false,
|
||||
listApi: getFileList,
|
||||
listKey: 'list',
|
||||
path: path,
|
||||
tableData: [
|
||||
{
|
||||
UpdatedAt: '2019-10-25',
|
||||
name: '文件名.jpg',
|
||||
url: 'http://qmplusimg.henrongyi.top/1571321688timg.jpg',
|
||||
tag: 'jpg'
|
||||
},
|
||||
{
|
||||
UpdatedAt: '2019-10-25',
|
||||
name: '文件名.jpg',
|
||||
url: 'http://qmplusimg.henrongyi.top/157162774820191015140921496.gif',
|
||||
tag: 'gif'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('user', ['userInfo', 'token'])
|
||||
},
|
||||
filters: {
|
||||
formatDate: function(time) {
|
||||
if (time != null && time != '') {
|
||||
var date = new Date(time)
|
||||
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async deleteFile(row) {
|
||||
this.$confirm('此操作将永久文件, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async () => {
|
||||
const res = await deleteFile(row)
|
||||
if (res.success) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
})
|
||||
this.getTableData()
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message({
|
||||
type: 'info',
|
||||
message: '已取消删除'
|
||||
})
|
||||
})
|
||||
},
|
||||
checkFile(file) {
|
||||
this.fullscreenLoading = true
|
||||
const isJPG = file.type === 'image/jpeg'
|
||||
const isPng = file.type === 'image/png'
|
||||
const isLt2M = file.size / 1024 / 1024 < 2
|
||||
if (!isJPG && !isPng) {
|
||||
this.$message.error('上传头像图片只能是 JPG或png 格式!')
|
||||
this.fullscreenLoading = false
|
||||
}
|
||||
if (!isLt2M) {
|
||||
this.$message.error('上传头像图片大小不能超过 2MB!')
|
||||
this.fullscreenLoading = false
|
||||
}
|
||||
return (isPng || isJPG) && isLt2M
|
||||
},
|
||||
uploadSuccess(res) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '上传成功'
|
||||
})
|
||||
if (res.success) {
|
||||
this.getTableData()
|
||||
}
|
||||
this.fullscreenLoading = false
|
||||
},
|
||||
uploadError() {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '上传失败'
|
||||
})
|
||||
this.fullscreenLoading = false
|
||||
|
||||
},
|
||||
downloadFile(row) {
|
||||
downloadImage(row.url, row.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user