parent
a6f3e31e71
commit
c228536503
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 28 KiB |
@ -0,0 +1,51 @@ |
||||
<template> |
||||
<div class="emptyWrapper"> |
||||
<img :src="imgSrc" alt=""> |
||||
<p> |
||||
<slot></slot> |
||||
</p> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
props: { |
||||
imgSrc: { |
||||
type: String |
||||
} |
||||
}, |
||||
created() { |
||||
console.log(this.imgSrc); |
||||
}, |
||||
data() { |
||||
return { |
||||
|
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.emptyWrapper { |
||||
width: 100%; |
||||
height: 100%; |
||||
height: calc(100vh - 100px); |
||||
text-align: center; |
||||
position: relative; |
||||
|
||||
img { |
||||
position: absolute; |
||||
left: 50%; |
||||
transform: translate(-50%); |
||||
height: 273px; |
||||
top: 20%; |
||||
} |
||||
|
||||
p { |
||||
position: absolute; |
||||
left: 50%; |
||||
transform: translate(-50%); |
||||
top: calc(20% + 193px); |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,29 @@ |
||||
<template> |
||||
<div class="envMessage"> |
||||
<label for="xx">请在电脑浏览器打开 http://bjkeyware.com</label> |
||||
<button style="" click="copyUrl">一键复制</button> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
methods:{ |
||||
copyUrl(){ |
||||
console.log('1'); |
||||
document.execCommand('xxxxx') |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.envMessage{ |
||||
position: fixed; |
||||
z-index: 100; |
||||
width: 200px; |
||||
background-color: aqua; |
||||
left: 50vw; |
||||
transform: translateX(-50%); |
||||
top: 0; |
||||
} |
||||
</style> |
@ -0,0 +1,60 @@ |
||||
<template> |
||||
<el-upload class="upload-demo myupload" :action="action" :headers="headers" :on-preview="handlePreview" |
||||
:on-remove="handleRemove" :before-remove="beforeRemove" :on-success="successUpload" :limit="3" |
||||
:on-exceed="handleExceed" :before-upload="beforeAvatarUpload"> |
||||
<slot></slot> |
||||
</el-upload> |
||||
</template> |
||||
|
||||
<script> |
||||
import { mapGetters } from "vuex"; |
||||
export default { |
||||
data() { |
||||
return { |
||||
action: process.env.VUE_APP_BASE_API + '/upload', |
||||
name: '' |
||||
}; |
||||
}, |
||||
computed: { |
||||
...mapGetters(['token']), |
||||
headers() { |
||||
return { Authorization: "Bearer " + this.token }; |
||||
}, |
||||
}, |
||||
methods: { |
||||
handleRemove(file, fileList) { |
||||
console.log(file, fileList); |
||||
}, |
||||
handlePreview(file) { |
||||
console.log(file); |
||||
}, |
||||
handleExceed(files, fileList) { |
||||
|
||||
}, |
||||
beforeRemove(file, fileList) { |
||||
// return this.$confirm(`确定移除 ${file.name}?`); |
||||
}, |
||||
successUpload(response) { |
||||
console.log(response); |
||||
this.$emit('upload', response, this.name) |
||||
}, |
||||
beforeAvatarUpload(file, fileList) { |
||||
this.name = file.name |
||||
const filetype = file.name.slice(file.name.lastIndexOf('.', file.name.length)) |
||||
console.log(filetype); |
||||
const isType = ['.doc', '.docx'].some(item => { return item == filetype }) |
||||
console.log(isType); |
||||
if (!isType) { |
||||
this.$message.error('只能上传doc、docx格式文件!'); |
||||
return false |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss"> |
||||
.myupload .el-upload-list { |
||||
display: none; |
||||
} |
||||
</style> |
@ -0,0 +1,65 @@ |
||||
<template> |
||||
<div class="mobileWrap"> |
||||
<div class="tipText"> |
||||
<p>关键测试宝pc端</p> |
||||
<p>请使用电脑浏览器访问</p> |
||||
</div> |
||||
<div class="urlCopy"> |
||||
<div>https://www.bjkeyware.com/</div> |
||||
<div class="copyBtn" @click="copyUrl">复制</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import copyText from '../../util/cpoyText'; |
||||
export default { |
||||
methods: { |
||||
copyUrl() { |
||||
const url = 'https://www.bjkeyware.com' |
||||
const result = copyText(url) |
||||
this.$message.success(result) |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.mobileWrap { |
||||
width: 100vw; |
||||
height: 100vh; |
||||
text-align: center; |
||||
overflow: hidden; |
||||
display: flex; |
||||
flex-direction: column; |
||||
align-items: center; |
||||
justify-content: center; |
||||
background: linear-gradient(0deg, #88B6FB, #FFFFFF); |
||||
|
||||
.tipText { |
||||
width: 296px; |
||||
height: 85px; |
||||
font-family: PingFang SC; |
||||
font-weight: 500; |
||||
font-size: 18px; |
||||
color: #1A1A1A; |
||||
line-height: 14px; |
||||
} |
||||
|
||||
.urlCopy { |
||||
width: 75vw; |
||||
line-height: 35px; |
||||
background: #C6D9F7; |
||||
text-align: center; |
||||
border-radius: 4px; |
||||
padding: 0 25px; |
||||
display: flex; |
||||
justify-content: center; |
||||
|
||||
.copyBtn { |
||||
margin-left: 25px; |
||||
color: #227BF4; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,292 @@ |
||||
<template> |
||||
<div> |
||||
<div v-clickoutside="hideReplyBtn" @click="inputFocus" class="my-reply"> |
||||
<el-avatar class="header-img" :size="40" :src="myHeader"></el-avatar> |
||||
<div class="reply-info" > |
||||
<div |
||||
tabindex="0" |
||||
contenteditable="true" |
||||
id="replyInput" |
||||
spellcheck="false" |
||||
placeholder="输入评论..." |
||||
class="reply-input" |
||||
@focus="showReplyBtn" |
||||
@input="onDivInput($event)" |
||||
> |
||||
</div> |
||||
</div> |
||||
<div class="reply-btn-box" v-show="btnShow"> |
||||
<el-button class="reply-btn" size="medium" @click="sendComment" type="primary">发表评论</el-button> |
||||
</div> |
||||
</div> |
||||
<div v-for="(item,i) in comments" :key="i" class="author-title reply-father"> |
||||
<el-avatar class="header-img" :size="40" :src="item.headImg"></el-avatar> |
||||
<div class="author-info"> |
||||
<span class="author-name">{{item.name}}</span> |
||||
<span class="author-time">{{item.time}}</span> |
||||
</div> |
||||
<div class="icon-btn"> |
||||
<span @click="showReplyInput(i,item.name,item.id)"><i class="iconfont el-icon-s-comment"></i>{{item.commentNum}}</span> |
||||
<i class="iconfont el-icon-caret-top"></i>{{item.like}} |
||||
</div> |
||||
<div class="talk-box"> |
||||
<p> |
||||
<span class="reply">{{item.comment}}</span> |
||||
</p> |
||||
</div> |
||||
<div class="reply-box"> |
||||
<div v-for="(reply,j) in item.reply" :key="j" class="author-title"> |
||||
<el-avatar class="header-img" :size="40" :src="reply.fromHeadImg"></el-avatar> |
||||
<div class="author-info"> |
||||
<span class="author-name">{{reply.from}}</span> |
||||
<span class="author-time">{{reply.time}}</span> |
||||
</div> |
||||
<div class="icon-btn"> |
||||
<span @click="showReplyInput(i,reply.from,reply.id)"><i class="iconfont el-icon-s-comment"></i>{{reply.commentNum}}</span> |
||||
<i class="iconfont el-icon-caret-top"></i>{{reply.like}} |
||||
</div> |
||||
<div class="talk-box"> |
||||
<p> |
||||
<span>回复 {{reply.to}}:</span> |
||||
<span class="reply">{{reply.comment}}</span> |
||||
</p> |
||||
</div> |
||||
<div class="reply-box"> |
||||
|
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div v-show="_inputShow(i)" class="my-reply my-comment-reply"> |
||||
<el-avatar class="header-img" :size="40" :src="myHeader"></el-avatar> |
||||
<div class="reply-info" > |
||||
<div tabindex="0" contenteditable="true" spellcheck="false" placeholder="输入评论..." @input="onDivInput($event)" class="reply-input reply-comment-input"></div> |
||||
</div> |
||||
<div class=" reply-btn-box"> |
||||
<el-button class="reply-btn" size="medium" @click="sendCommentReply(i,j)" type="primary">发表评论</el-button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
const clickoutside = { |
||||
// 初始化指令 |
||||
bind(el, binding, vnode) { |
||||
function documentHandler(e) { |
||||
// 这里判断点击的元素是否是本身,是本身,则返回 |
||||
if (el.contains(e.target)) { |
||||
return false; |
||||
} |
||||
// 判断指令中是否绑定了函数 |
||||
if (binding.expression) { |
||||
// 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法 |
||||
binding.value(e); |
||||
} |
||||
} |
||||
// 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听 |
||||
el.vueClickOutside = documentHandler; |
||||
document.addEventListener('click', documentHandler); |
||||
}, |
||||
update() {}, |
||||
unbind(el, binding) { |
||||
// 解除事件监听 |
||||
document.removeEventListener('click', el.vueClickOutside); |
||||
delete el.vueClickOutside; |
||||
}, |
||||
}; |
||||
export default { |
||||
name:'ArticleComment', |
||||
data(){ |
||||
return{ |
||||
btnShow: false, |
||||
index:'0', |
||||
replyComment:'', |
||||
myName:'Lana Del Rey', |
||||
myHeader:'https://ae01.alicdn.com/kf/Hd60a3f7c06fd47ae85624badd32ce54dv.jpg', |
||||
myId:19870621, |
||||
to:'', |
||||
toId:-1, |
||||
comments:[ |
||||
{ |
||||
name:'Lana Del Rey', |
||||
id:19870621, |
||||
headImg:'https://ae01.alicdn.com/kf/Hd60a3f7c06fd47ae85624badd32ce54dv.jpg', |
||||
comment:'我发布一张新专辑Norman Fucking Rockwell,大家快来听啊', |
||||
time:'2019年9月16日 18:43', |
||||
commentNum:2, |
||||
like:15, |
||||
inputShow:false, |
||||
reply:[ |
||||
{ |
||||
from:'Taylor Swift', |
||||
fromId:19891221, |
||||
fromHeadImg:'https://ae01.alicdn.com/kf/H94c78935ffa64e7e977544d19ecebf06L.jpg', |
||||
to:'Lana Del Rey', |
||||
toId:19870621, |
||||
comment:'我很喜欢你的新专辑!!', |
||||
time:'2019年9月16日 18:43', |
||||
commentNum:1, |
||||
like:15, |
||||
inputShow:false |
||||
}, |
||||
{ |
||||
from:'Ariana Grande', |
||||
fromId:1123, |
||||
fromHeadImg:'https://ae01.alicdn.com/kf/Hf6c0b4a7428b4edf866a9fbab75568e6U.jpg', |
||||
to:'Lana Del Rey', |
||||
toId:19870621, |
||||
comment:'别忘记宣传我们的合作单曲啊', |
||||
time:'2019年9月16日 18:43', |
||||
commentNum:0, |
||||
like:5, |
||||
inputShow:false |
||||
|
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
name:'Taylor Swift', |
||||
id:19891221, |
||||
headImg:'https://ae01.alicdn.com/kf/H94c78935ffa64e7e977544d19ecebf06L.jpg', |
||||
comment:'我发行了我的新专辑Lover', |
||||
time:'2019年9月16日 18:43', |
||||
commentNum:1, |
||||
like:5, |
||||
inputShow:false, |
||||
reply:[ |
||||
{ |
||||
from:'Lana Del Rey', |
||||
fromId:19870621, |
||||
fromHeadImg:'https://ae01.alicdn.com/kf/Hd60a3f7c06fd47ae85624badd32ce54dv.jpg', |
||||
to:'Taylor Swift', |
||||
toId:19891221, |
||||
comment:'新专辑和speak now 一样棒!', |
||||
time:'2019年9月16日 18:43', |
||||
commentNum:25, |
||||
like:5, |
||||
inputShow:false |
||||
|
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
name:'Norman Fucking Rockwell', |
||||
id:20190830, |
||||
headImg:'https://ae01.alicdn.com/kf/Hdd856ae4c81545d2b51fa0c209f7aa28Z.jpg', |
||||
comment:'Plz buy Norman Fucking Rockwell on everywhere', |
||||
time:'2019年9月16日 18:43', |
||||
commentNum:0, |
||||
like:5, |
||||
inputShow:false, |
||||
reply:[] |
||||
}, |
||||
] |
||||
} |
||||
}, |
||||
directives: {clickoutside}, |
||||
methods: { |
||||
inputFocus(){ |
||||
var replyInput = document.getElementById('replyInput'); |
||||
replyInput.style.padding= "8px 8px" |
||||
replyInput.style.border ="2px solid blue" |
||||
replyInput.focus() |
||||
}, |
||||
showReplyBtn(){ |
||||
this.btnShow = true |
||||
}, |
||||
hideReplyBtn(){ |
||||
this.btnShow = false |
||||
replyInput.style.padding= "10px" |
||||
replyInput.style.border ="none" |
||||
}, |
||||
showReplyInput(i,name,id){ |
||||
this.comments[this.index].inputShow = false |
||||
this.index =i |
||||
this.comments[i].inputShow = true |
||||
this.to = name |
||||
this.toId = id |
||||
}, |
||||
_inputShow(i){ |
||||
return this.comments[i].inputShow |
||||
}, |
||||
sendComment(){ |
||||
if(!this.replyComment){ |
||||
this.$message({ |
||||
showClose: true, |
||||
type:'warning', |
||||
message:'评论不能为空' |
||||
}) |
||||
}else{ |
||||
let a ={} |
||||
let input = document.getElementById('replyInput') |
||||
let timeNow = new Date().getTime(); |
||||
let time= this.dateStr(timeNow); |
||||
a.name= this.myName |
||||
a.comment =this.replyComment |
||||
a.headImg = this.myHeader |
||||
a.time = time |
||||
a.commentNum = 0 |
||||
a.like = 0 |
||||
this.comments.push(a) |
||||
this.replyComment = '' |
||||
input.innerHTML = ''; |
||||
|
||||
} |
||||
}, |
||||
sendCommentReply(i,j){ |
||||
if(!this.replyComment){ |
||||
this.$message({ |
||||
showClose: true, |
||||
type:'warning', |
||||
message:'评论不能为空' |
||||
}) |
||||
}else{ |
||||
let a ={} |
||||
let timeNow = new Date().getTime(); |
||||
let time= this.dateStr(timeNow); |
||||
a.from= this.myName |
||||
a.to = this.to |
||||
a.fromHeadImg = this.myHeader |
||||
a.comment =this.replyComment |
||||
a.time = time |
||||
a.commentNum = 0 |
||||
a.like = 0 |
||||
this.comments[i].reply.push(a) |
||||
this.replyComment = '' |
||||
document.getElementsByClassName("reply-comment-input")[i].innerHTML = "" |
||||
} |
||||
}, |
||||
onDivInput: function(e) { |
||||
this.replyComment = e.target.innerHTML; |
||||
}, |
||||
dateStr(date){ |
||||
//获取js 时间戳 |
||||
var time=new Date().getTime(); |
||||
//去掉 js 时间戳后三位,与php 时间戳保持一致 |
||||
time=parseInt((time-date)/1000); |
||||
//存储转换值 |
||||
var s; |
||||
if(time<60*10){//十分钟内 |
||||
return '刚刚'; |
||||
}else if((time<60*60)&&(time>=60*10)){ |
||||
//超过十分钟少于1小时 |
||||
s = Math.floor(time/60); |
||||
return s+"分钟前"; |
||||
}else if((time<60*60*24)&&(time>=60*60)){ |
||||
//超过1小时少于24小时 |
||||
s = Math.floor(time/60/60); |
||||
return s+"小时前"; |
||||
}else if((time<60*60*24*30)&&(time>=60*60*24)){ |
||||
//超过1天少于30天内 |
||||
s = Math.floor(time/60/60/24); |
||||
return s+"天前"; |
||||
}else{ |
||||
//超过30天ddd |
||||
var date= new Date(parseInt(date)); |
||||
return date.getFullYear()+"/"+(date.getMonth()+1)+"/"+date.getDate(); |
||||
} |
||||
} |
||||
}, |
||||
} |
||||
</script> |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1 @@ |
||||
@import './variable.scss' |
@ -0,0 +1 @@ |
||||
$bg-color: #0066eb |
@ -0,0 +1,39 @@ |
||||
function copyText(text) { |
||||
const textString = text.toString() // 数字没有 .length 不能执行selectText 需要转化成字符串
|
||||
let input = document.querySelector('#copy-input') |
||||
if (!input) { |
||||
input = document.createElement('input') |
||||
input.id = 'copy-input' |
||||
input.readOnly = 'readOnly' // 防止ios聚焦触发键盘事件
|
||||
input.style.position = 'absolute' |
||||
input.style.left = '-2000px' |
||||
input.style.zIndex = '-2000' |
||||
document.body.appendChild(input) |
||||
} |
||||
|
||||
input.value = textString |
||||
// ios必须先选中文字且不支持 input.select();
|
||||
selectText(input, 0, textString.length) |
||||
if (document.execCommand('copy')) { |
||||
document.execCommand('copy') |
||||
return '复制成功!' |
||||
} else { |
||||
return '复制失败!' |
||||
} |
||||
} |
||||
|
||||
function selectText(textbox, startIndex, stopIndex) { |
||||
if (textbox.createTextRange) { |
||||
// ie
|
||||
const range = textbox.createTextRange() |
||||
range.collapse(true) |
||||
range.moveStart('character', startIndex) // 起始光标
|
||||
range.moveEnd('character', stopIndex - startIndex) // 结束光标
|
||||
range.select() // 不兼容苹果
|
||||
} else { |
||||
// firefox/chrome
|
||||
textbox.setSelectionRange(startIndex, stopIndex) |
||||
textbox.focus() |
||||
} |
||||
} |
||||
export default copyText |
@ -0,0 +1,12 @@ |
||||
function runEnv() { |
||||
const info = navigator.userAgent.toLowerCase(); |
||||
var isPhone = /mobile/i.test(info); |
||||
if (isPhone) { |
||||
return true |
||||
} |
||||
return false |
||||
} |
||||
|
||||
|
||||
|
||||
export default runEnv |
Loading…
Reference in new issue