代码改动,修复了一些问题

master
toesbieya 6 years ago
parent f754005959
commit f5cc749772
  1. 0
      vue/public/static/img/fileType/xls.png
  2. 227
      vue/public/static/live2d/waifu-tips.js
  3. 72
      vue/public/static/live2d/waifu-tips.json
  4. 6
      vue/public/static/live2d/waifu.css
  5. 2
      vue/src/components/ContextMenu/ContextMenuItem.vue
  6. 27
      vue/src/components/ContextMenu/index.vue
  7. 4
      vue/src/components/DialogForm/DialogFormItem.vue
  8. 4
      vue/src/components/DialogForm/index.vue
  9. 4
      vue/src/components/Guide/index.js
  10. 64
      vue/src/components/Guide/main.vue
  11. 2
      vue/src/components/LinerProgress/style.scss
  12. 2
      vue/src/components/PuzzleVerify/index.js
  13. 2
      vue/src/components/PuzzleVerify/style.scss
  14. 23
      vue/src/components/SearchForm/index.vue
  15. 2
      vue/src/components/SignautreBoard/index.js
  16. 2
      vue/src/components/Skeleton/PageSkeleton.vue
  17. 46
      vue/src/components/UploadFile/index.vue
  18. 2
      vue/src/components/UploadFile/style.scss
  19. 2
      vue/src/layout/components/Header.vue
  20. 2
      vue/src/layout/components/Main.vue
  21. 8
      vue/src/layout/components/Navbar/components/Breadcrumb.vue
  22. 3
      vue/src/layout/components/Navbar/index.vue
  23. 2
      vue/src/layout/components/Navbar/style.scss
  24. 6
      vue/src/layout/components/Sidebar/index.vue
  25. 2
      vue/src/layout/components/Sidebar/style.scss
  26. 5
      vue/src/layout/components/TagsView/index.vue
  27. 2
      vue/src/layout/components/TagsView/style.scss
  28. 22
      vue/src/mixins/guide/base.js
  29. 31
      vue/src/mixins/guide/data/index.js
  30. 15
      vue/src/mixins/guide/data/navbar.js
  31. 2
      vue/src/mixins/guide/index.js
  32. 291
      vue/src/plugin/live2d/index.js
  33. 4
      vue/src/router/constant/index.js
  34. 15
      vue/src/router/index.js
  35. 3
      vue/src/router/util.js
  36. 4
      vue/src/store/modules/iframe.js
  37. 6
      vue/src/store/modules/tagsView.js
  38. 36
      vue/src/utils/browser.js
  39. 2
      vue/src/utils/excel/xlsx.js
  40. 2
      vue/src/utils/index.js
  41. 2
      vue/src/utils/math.js
  42. 2
      vue/src/views/app/login/style.scss
  43. 2
      vue/src/views/example/components/skeletonExample.vue
  44. 81
      vue/src/views/example/cool/l2d.vue
  45. 11
      vue/src/views/example/developingTest/components/ImageCompressTest.vue
  46. 2
      vue/src/views/stock/current/DetailDialog.vue
  47. 2
      vue/src/views/system/role/components/RoleResource.vue
  48. 3
      vue/src/views/system/supplier/EditDialog.vue
  49. 3
      vue/src/views/system/supplier/index.vue
  50. 4
      vue/src/views/userCenter/components/Avatar.vue
  51. 4
      vue/vue.config.js

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

@ -1,227 +0,0 @@
/*
* Live2D Widget
* https://github.com/stevenjoezhang/live2d-widget
*/
function initWidget(waifuPath = "/waifu-tips.json", apiPath = "") {
sessionStorage.removeItem("waifu-text")
document.body.insertAdjacentHTML("beforeend",
`<div id="waifu">
<div id="waifu-tips"></div>
<canvas id="live2d" width="300" height="300"></canvas>
<div id="waifu-tool">
<span class="el-icon-s-promotion" title="打飞机"></span>
<span class="el-icon-refresh" title="换人"></span>
<span class="el-icon-s-operation" title="换装"></span>
<span class="el-icon-camera" title="拍照"></span>
<span class="el-icon-switch-button" title="关闭"></span>
</div>
</div>`)
setTimeout(() => {
document.getElementById("waifu").style.bottom = 0
}, 0)
function registerEventListener() {
document.querySelector("#waifu-tool .el-icon-s-promotion").addEventListener("click", () => {
if (window.Asteroids) {
if (!window.ASTEROIDSPLAYERS) window.ASTEROIDSPLAYERS = []
window.ASTEROIDSPLAYERS.push(new Asteroids())
}
else {
var script = document.createElement("script")
script.src = "https://cdn.jsdelivr.net/gh/GalaxyMimi/CDN/asteroids.js"
document.head.appendChild(script)
}
})
document.querySelector("#waifu-tool .el-icon-refresh").addEventListener("click", loadOtherModel)
document.querySelector("#waifu-tool .el-icon-s-operation").addEventListener("click", loadRandModel)
document.querySelector("#waifu-tool .el-icon-camera").addEventListener("click", () => {
showMessage("照好了嘛,是不是很可爱呢?", 6000, 9)
Live2D.captureName = "photo.png"
Live2D.captureFrame = true
})
document.querySelector("#waifu-tool .el-icon-switch-button").addEventListener("click", exit)
var devtools = () => ({})
console.log("%c", devtools)
devtools.toString = () => {
showMessage("哈哈,你打开了控制台,是想要看看我的小秘密吗?", 6000, 9)
}
window.addEventListener("visibilitychange", () => {
if (!document.hidden) showMessage("哇,你终于回来了~", 6000, 9)
})
}
registerEventListener()
function welcomeMessage() {
let text
if (location.pathname === "/") { // 如果是主页
let now = new Date().getHours()
if (now > 5 && now <= 7) text = "早上好!一日之计在于晨,美好的一天就要开始了。"
else if (now > 7 && now <= 11) text = "上午好!工作顺利嘛,不要久坐,多起来走动走动哦!"
else if (now > 11 && now <= 13) text = "中午了,工作了一个上午,现在是午餐时间!"
else if (now > 13 && now <= 17) text = "午后很容易犯困呢,今天的运动目标完成了吗?"
else if (now > 17 && now <= 19) text = "傍晚了!窗外夕阳的景色很美丽呢,最美不过夕阳红~"
else if (now > 19 && now <= 21) text = "晚上好,今天过得怎么样?"
else if (now > 21 && now <= 23) text = ["已经这么晚了呀,早点休息吧,晚安~", "深夜时要爱护眼睛呀!"]
else text = "你是夜猫子呀?这么晚还不睡觉,明天起的来嘛?"
}
else if (document.referrer !== "") {
let referrer = new URL(document.referrer),
domain = referrer.hostname.split(".")[1]
if (location.hostname === referrer.hostname) text = `欢迎阅读<span>「${document.title.split(" - ")[0]}」</span>`
else if (domain === "baidu") text = `Hello!来自 百度搜索 的朋友<br>你是搜索 <span>${referrer.search.split("&wd=")[1].split("&")[0]}</span> 找到的我吗?`
else if (domain === "so") text = `Hello!来自 360搜索 的朋友<br>你是搜索 <span>${referrer.search.split("&q=")[1].split("&")[0]}</span> 找到的我吗?`
else if (domain === "google") text = `Hello!来自 谷歌搜索 的朋友<br>欢迎阅读<span>「${document.title.split(" - ")[0]}」</span>`
else text = `Hello!来自 <span>${referrer.hostname}</span> 的朋友`
}
else {
text = `欢迎阅读<span>「${document.title.split(" - ")[0]}」</span>`
}
showMessage(text, 7000, 8)
}
welcomeMessage()
// 检测用户活动状态,并在空闲时显示消息
var userAction = false,
userActionTimer = null,
messageTimer = null,
messageArray = ["好久不见,日子过得好快呢……", "大坏蛋!你都多久没理人家了呀,嘤嘤嘤~", "嗨~快来逗我玩吧!", "拿小拳拳锤你胸口!", "记得把小家加入 Adblock 白名单哦!"]
window.addEventListener("mousemove", () => userAction = true)
window.addEventListener("keydown", () => userAction = true)
setInterval(() => {
if (userAction) {
userAction = false
clearInterval(userActionTimer)
userActionTimer = null
}
else if (!userActionTimer) {
userActionTimer = setInterval(() => {
showMessage(messageArray[Math.floor(Math.random() * messageArray.length)], 6000, 9)
}, 20000)
}
}, 1000)
function initModel() {
let modelId = localStorage.getItem("modelId"),
modelTexturesId = localStorage.getItem("modelTexturesId")
if (modelId == null) {
// 首次访问加载 指定模型 的 指定材质
modelId = 1 // 模型 ID
modelTexturesId = 53 // 材质 ID
}
loadModel(modelId, modelTexturesId)
fetch(waifuPath)
.then(response => response.json())
.then(result => {
result.mouseover.forEach(tips => {
window.addEventListener("mouseover", event => {
if (!event.target.matches(tips.selector)) return
var text = Array.isArray(tips.text) ? tips.text[Math.floor(Math.random() * tips.text.length)] : tips.text
text = text.replace("{text}", event.target.innerText)
showMessage(text, 4000, 8)
})
})
result.click.forEach(tips => {
window.addEventListener("click", event => {
if (!event.target.matches(tips.selector)) return
var text = Array.isArray(tips.text) ? tips.text[Math.floor(Math.random() * tips.text.length)] : tips.text
text = text.replace("{text}", event.target.innerText)
showMessage(text, 4000, 8)
})
})
result.seasons.forEach(tips => {
var now = new Date(),
after = tips.date.split("-")[0],
before = tips.date.split("-")[1] || after
if ((after.split("/")[0] <= now.getMonth() + 1 && now.getMonth() + 1 <= before.split("/")[0]) && (after.split("/")[1] <= now.getDate() && now.getDate() <= before.split("/")[1])) {
var text = Array.isArray(tips.text) ? tips.text[Math.floor(Math.random() * tips.text.length)] : tips.text
text = text.replace("{year}", now.getFullYear())
//showMessage(text, 7000, true);
messageArray.push(text)
}
})
})
}
initModel()
function loadModel(modelId, modelTexturesId) {
localStorage.setItem("modelId", modelId)
if (modelTexturesId === undefined) modelTexturesId = 0
localStorage.setItem("modelTexturesId", modelTexturesId)
loadlive2d("live2d", `${apiPath}/get/?id=${modelId}-${modelTexturesId}`, console.log(`Live2D 模型 ${modelId}-${modelTexturesId} 加载完成`))
}
//调用一言api
function showHitokoto() {
// 增加 hitokoto.cn 的 API
fetch("https://v1.hitokoto.cn")
.then(response => response.json())
.then(result => {
var text = `这句一言来自 <span>「${result.from}」</span>,是 <span>${result.creator}</span> 在 hitokoto.cn 投稿的。`
showMessage(result.hitokoto, 6000, 9)
setTimeout(() => {
showMessage(text, 4000, 9)
}, 6000)
})
}
//显示信息
function showMessage(text, timeout, priority) {
if (!text) return
if (!sessionStorage.getItem("waifu-text") || sessionStorage.getItem("waifu-text") <= priority) {
if (messageTimer) {
clearTimeout(messageTimer)
messageTimer = null
}
if (Array.isArray(text)) text = text[Math.floor(Math.random() * text.length)]
sessionStorage.setItem("waifu-text", priority)
var tips = document.getElementById("waifu-tips")
if (!tips) return
tips.innerHTML = text
tips.classList.add("waifu-tips-active")
messageTimer = setTimeout(() => {
sessionStorage.removeItem("waifu-text")
tips.classList.remove("waifu-tips-active")
}, timeout)
}
}
//换装
function loadRandModel() {
let modelId = localStorage.getItem("modelId"),
modelTexturesId = localStorage.getItem("modelTexturesId")
// 可选 "rand"(随机), "switch"(顺序)
fetch(`${apiPath}/rand_textures/?id=${modelId}-${modelTexturesId}`)
.then(response => response.json())
.then(result => {
if (result.textures.id == 1 && (modelTexturesId == 1 || modelTexturesId == 0)) showMessage("我还没有其他衣服呢!", 4000, 10)
else showMessage("我的新衣服好看嘛?", 4000, 10)
loadModel(modelId, result.textures.id)
})
}
//切换其他模型
function loadOtherModel() {
var modelId = localStorage.getItem("modelId")
fetch(`${apiPath}/switch/?id=${modelId}`)
.then(response => response.json())
.then(result => {
loadModel(result.model.id)
showMessage(result.model.message, 4000, 10)
})
}
//退出
function exit() {
showMessage("愿你有一天能与重要的人重逢。", 2000, 11)
const dom = document.getElementById("waifu")
dom.style.bottom = "-500px"
setTimeout(() => {
// dom.style.display = "none"
dom.remove()
}, 3000)
}
}

@ -60,28 +60,6 @@
"我们,还能再见面吗……",
"哼,你会后悔的!"
]
},
{
"selector": ".menu-item-search",
"text": [
"找不到想看的内容?搜索看看吧!",
"在找什么东西呢,需要帮忙吗?"
]
},
{
"selector": "#qrcode",
"text": [
"手机扫一下就能继续看,很方便呢~",
"扫一扫,打开新世界的大门!"
]
},
{
"selector": ".back-to-top",
"text": [
"点它就可以回到顶部啦!",
"又回到最初的起点~",
"要回到开始的地方么?"
]
}
],
"click": [
@ -98,55 +76,5 @@
"别摸我,有什么好摸的!"
]
}
],
"seasons": [
{
"date": "01/01",
"text": "<span>元旦</span>了呢,新的一年又开始了,今年是{year}年~"
},
{
"date": "02/14",
"text": "又是一年<span>情人节</span>,{year}年找到对象了嘛~"
},
{
"date": "03/08",
"text": "今天是<span>国际妇女节</span>!"
},
{
"date": "03/12",
"text": "今天是<span>植树节</span>,要保护环境呀!"
},
{
"date": "04/01",
"text": "悄悄告诉你一个秘密~<span>今天是愚人节,不要被骗了哦~</span>"
},
{
"date": "05/01",
"text": "今天是<span>五一劳动节</span>,计划好假期去哪里了吗~"
},
{
"date": "06/01",
"text": "<span>儿童节</span>了呢,快活的时光总是短暂,要是永远长不大该多好啊…"
},
{
"date": "09/03",
"text": "<span>中国人民抗日战争胜利纪念日</span>,铭记历史、缅怀先烈、珍爱和平、开创未来。"
},
{
"date": "09/10",
"text": "<span>教师节</span>,在学校要给老师问声好呀~"
},
{
"date": "10/01",
"text": "<span>国庆节</span>到了,为祖国母亲庆生!"
},
{
"date": "11/05-11/12",
"text": "今年的<span>双十一</span>是和谁一起过的呢~"
},
{
"date": "12/20-12/31",
"text": "这几天是<span>圣诞节</span>,主人肯定又去剁手买买买了~"
}
]
}

@ -12,12 +12,6 @@
transform: translateY(0);
}
@media (max-width: 768px) {
#waifu {
display: none;
}
}
#waifu-tips {
animation: shake 50s ease-in-out 5s infinite;
background-color: rgba(236, 217, 188, .5);

@ -5,7 +5,7 @@
functional: true,
render(h, context) {
return h('li', context.data, context.children)
return <li class="contextmenu-item" {...context.data}>{context.children}</li>
}
}
</script>

@ -9,16 +9,9 @@
name: "ContextMenu",
props: {
value: {
type: Boolean,
default: false
},
left: {
type: Number
},
top: {
type: Number
}
value: Boolean,
left: Number,
top: Number
},
data() {
@ -31,7 +24,7 @@
watch: {
value(v) {
document.body[v ? 'addEventListener' : 'removeEventListener']('click', this.closeContextMenu)
if (v) this.$nextTick(() => this.autoAdapt())
if (v) this.$nextTick(this.autoAdapt)
},
left(v) {
if (!v) return
@ -56,24 +49,22 @@
if (this.$el.offsetHeight > document.body.clientHeight - v && v > this.$el.offsetHeight) {
this.realTop = v - this.$el.offsetHeight + 'px'
}
else {
this.realTop = v + 'px'
}
else this.realTop = v + 'px'
},
autoAdaptLeft(v) {
if (!this.value) return
if (this.$el.offsetWidth > document.body.clientWidth - v) {
this.realLeft = v - this.$el.offsetWidth + 'px'
}
else {
this.realLeft = v + 'px'
}
else this.realLeft = v + 'px'
}
}
}
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";
.contextmenu {
margin: 0;
background: $menu-background;
@ -87,7 +78,7 @@
color: #fff;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
li {
&-item {
margin: 0;
padding: 7px 16px;
cursor: pointer;

@ -7,10 +7,12 @@
props: {full: Boolean, dense: Boolean, label: String, prop: String},
render(h, context) {
let {full, dense, label, prop} = context.props
const {full, dense, label, prop} = context.props
let attrs = {xs: 24, sm: 12, lg: 8}
if (full) attrs = {span: 24}
else if (dense) attrs.lg = 12
return (
<el-col {...{attrs}}>
<el-form-item label={label} prop={prop}>

@ -1,10 +1,10 @@
<template>
<el-dialog
v-drag-dialog
custom-class="dialog-form"
v-bind="$props"
:visible="value"
v-on="$listeners"
:visible="value"
custom-class="dialog-form"
>
<slot slot="title" name="title">{{title}}</slot>

@ -14,7 +14,7 @@ const defaultOptions = {
prevBtnText: '上一步',
}
const guide = function (start, steps, beforeExist) {
const guide = function (start, steps, beforeExit) {
if (instance) instance.exit()
else {
instance = new GuideConstructor({data: {options: defaultOptions}})
@ -23,7 +23,7 @@ const guide = function (start, steps, beforeExist) {
}
instance.steps = steps
instance.beforeExist = beforeExist
instance.beforeExit = beforeExit
this.$nextTick(() => instance.start(start))
}

@ -5,19 +5,19 @@
<div class="guide-popover-action">
<div class="action-close">
<el-button v-show="hasDone" size="small" @click="exit">
<el-button v-if="hasDone" size="small" @click="exit">
{{step.doneBtnText}}
</el-button>
<el-button v-show="!hasDone" size="small" @click="exit">
<el-button v-else size="small" @click="exit">
{{step.closeBtnText}}
</el-button>
</div>
<div class="action-step">
<el-button v-show="showPrevBtn" class="prev-btn" size="small" @click="previous">
<el-button v-if="showPrevBtn" class="prev-btn" size="small" @click="previous">
{{step.prevBtnText}}
</el-button>
<el-button v-show="showNextBtn" class="next-btn" size="small" @click="next">
<el-button v-if="showNextBtn" class="next-btn" size="small" @click="next">
{{step.nextBtnText}}
</el-button>
</div>
@ -26,9 +26,9 @@
<div slot="reference" v-show="showStage" id="guide-stage" :style="stageStyle"/>
</el-popover>
<div v-show="showStage" id="guide-highlight-element-cover" :style="stageStyle" @click.prevent.stop/>
<div v-if="showStage" id="guide-highlight-element-cover" :style="stageStyle" @click.prevent.stop/>
<div v-show="showOverlay" id="guide-overlay"/>
<div v-if="showOverlay" id="guide-overlay"/>
</div>
</template>
@ -46,13 +46,7 @@
data() {
return {
steps: [],
options: {
stageBackground: '#ffffff',
doneBtnText: '完成',
closeBtnText: '关闭',
nextBtnText: '下一步',
prevBtnText: '上一步',
},
options: {},
beforeExit: null,
isActive: false,
showStage: false,
@ -79,9 +73,12 @@
return this.currentStep === this.steps.length - 1
},
step() {
if (!this.isActive) return {}
if (this.steps.length <= 0) return {}
if (!this.steps[this.currentStep]) return {}
if (!this.isActive
|| this.steps.length <= 0
|| !this.steps[this.currentStep]) {
return {}
}
return {
...this.options,
...this.steps[this.currentStep],
@ -114,59 +111,72 @@
this.showStage = false
this.$_highlight()
this.showOverlay = true
this.showStage = true
},
exit() {
if (!this.isActive) return
let done = this.hasDone
if (this.beforeExit) {
let result = this.beforeExit(done)
const result = this.beforeExit(this.hasDone)
if (result && result.then) {
result.then(() => this.$_clear())
result.then(this.$_clear)
}
if (result !== false) this.$_clear()
else result !== false && this.$_clear()
return
}
this.$_clear()
},
previous() {
if (!this.isActive || this.moving) return
this.moving = true
if (this.step.onPrevious) {
let result = this.step.onPrevious()
if (result && result.then) result.then(() => this.$_movePrevious())
const result = this.step.onPrevious()
if (result && result.then) {
result.then(this.$_movePrevious)
}
else result !== false && this.$_movePrevious()
}
else this.$_movePrevious()
},
next() {
if (!this.isActive || this.moving) return
this.moving = true
if (this.step.onNext) {
let result = this.step.onNext()
if (result && result.then) result.then(() => this.$_moveNext())
const result = this.step.onNext()
if (result && result.then) {
result.then(this.$_moveNext)
}
else result !== false && this.$_moveNext()
}
else this.$_moveNext()
},
resize() {
if (!this.highlightedElement) return
this.$_setStageStyle(getCalculatedPosition(this.highlightedElement))
this.$nextTick(() => this.$refs.popover.updatePopper())
this.$nextTick(this.$refs.popover.updatePopper)
},
$_movePrevious() {
if (!this.isActive) return
this.currentStep--
this.$_highlight()
},
$_moveNext() {
if (!this.isActive) return
this.currentStep++
this.$_highlight()
},
$_clear() {
if (!this.isActive) return
this.isActive = false
@ -179,10 +189,11 @@
this.highlightedElement = null
this.lastHighlightedElement = null
},
$_highlight() {
if (isEmpty(this.step.element)) throw new Error(`step${this.currentStep}中element为空`)
let el = document.querySelector(this.step.element)
const el = document.querySelector(this.step.element)
if (!el) throw new Error(`${this.step.element} 没有该元素`)
@ -204,6 +215,7 @@
addHighlightClasses(el)
},
$_setStageStyle({top, left, right, bottom}) {
const width = right - left
const height = bottom - top

@ -1,3 +1,5 @@
@import "~@/assets/styles/variables.scss";
.liner-progress {
position: relative;
height: 4px;

@ -8,12 +8,14 @@ let Constructor = Vue.extend(Main)
const PuzzleVerify = function ({left, top} = {}) {
const instance = new Constructor()
const position = getPosition({height: instance.height + 130, width: instance.width + 20, left, top})
instance.positionTop = position.top
instance.positionLeft = position.left
instance.$mount()
document.body.appendChild(instance.$el)
instance.$el.style.zIndex = PopupManager.nextZIndex()
instance.visible = true
return new Promise((resolve, reject) => {
instance.resolve = resolve
instance.reject = reject

@ -1,3 +1,5 @@
@import "~@/assets/styles/variables.scss";
.puzzle-container {
position: absolute;
box-shadow: 0 0 10px #cccccc;

@ -12,10 +12,10 @@
props: {
labelWidth: {type: String, default: '120px'},
xs: {type: Number, default: 24},// <768px
sm: {type: Number, default: 12},// >=768px
md: {type: Number, default: 8}, // >=998px
lg: {type: Number, default: 6} // >=1200px
xs: {type: Number, default: 1},// <768px
sm: {type: Number, default: 2},// >=768px
md: {type: Number, default: 3}, // >=998px
lg: {type: Number, default: 4} // >=1200px
},
data() {
@ -35,13 +35,10 @@
getElementNumInRow() {
const vw = getElementInnerWidth(this.$el.parentNode)
let lineNum = this.lg
if (vw < 768) lineNum = this.xs
else if (vw < 998) lineNum = this.sm
else if (vw < 1200) lineNum = this.md
return Math.floor(24 / lineNum)
if (vw < 768) return this.xs
else if (vw < 998) return this.sm
else if (vw < 1200) return this.md
return this.lg
},
resize() {
@ -78,7 +75,9 @@
const collapseSlot = this.$scopedSlots.collapse
collapseChildren.push(
collapseSlot ? collapseSlot({collapse: this.collapse, handle: this.handleCollapse}) :
collapseSlot ?
collapseSlot({collapse: this.collapse, handle: this.handleCollapse})
:
<div class="searchForm__collapse">
<el-button
type="text"

@ -11,12 +11,14 @@ const signature = function ({image, lineWidth = 6, lineColor = '#000000', onConf
instance = new Constructor().$mount()
document.body.appendChild(instance.$el)
}
instance.image = image
instance.lineWidth = lineWidth
instance.lineColor = lineColor
instance.onConfirm = onConfirm
instance.init()
instance.visible = true
return instance
}

@ -26,6 +26,8 @@
</script>
<style lang="scss">
@import "~@/assets/styles/variables.scss";
.page-skeleton-wrapper {
margin: $page-view-margin;
}

@ -3,7 +3,7 @@
ref="upload"
:before-upload="beforeUpload"
:class="{disabled: hideUploader}"
:file-list="data"
:file-list="tempData"
:http-request="httpRequest"
:limit="limit"
:multiple="multiple"
@ -13,7 +13,7 @@
action=""
list-type="picture-card"
>
<i slot="default" class="el-icon-plus"/>
<i class="el-icon-plus"/>
<template v-slot:file="{file}">
<span
@ -64,6 +64,11 @@
import {preview, deleteUpload, download, upload, autoCompleteUrl} from "@/utils/file"
import {getContextPath} from "@/utils/browser"
const typeMapper = [
{test: isImage}, {test: isDoc, type: 'doc'}, {test: isPdf, type: 'pdf'}, {test: isPpt, type: 'ppt'},
{test: isRar, type: 'rar'}, {test: isXls, type: 'xls'}, {test: isTxt, type: 'txt'}, {test: isZip, type: 'zip'},
]
function parseMaxSize(maxSize) {
if (typeof maxSize === 'number') {
return maxSize
@ -77,27 +82,17 @@
return parseInt(num) * (map[unit] || 1)
}
function isFileTypeSupported(fileType) {
return [isImage, isDoc, isPdf, isPpt, isRar, isXls, isTxt, isZip].some(i => i(fileType))
}
function getCoverImage(url, fileType) {
if (isImage(fileType)) return url
else if (isDoc(fileType)) url = `${getContextPath()}static/img/fileType/doc.png`
else if (isPdf(fileType)) url = `${getContextPath()}static/img/fileType/pdf.png`
else if (isPpt(fileType)) url = `${getContextPath()}static/img/fileType/ppt.png`
else if (isRar(fileType)) url = `${getContextPath()}static/img/fileType/rar.png`
else if (isXls(fileType)) url = `${getContextPath()}static/img/fileType/xls.png`
else if (isTxt(fileType)) url = `${getContextPath()}static/img/fileType/txt.png`
else if (isZip(fileType)) url = `${getContextPath()}static/img/fileType/zip.png`
return url
const mapper = typeMapper.find(({test}) => test(fileType))
return mapper && mapper.type ? `${getContextPath()}static/img/fileType/${mapper.type}.png` : url
}
export default {
name: 'UploadFile',
props: {
disabled: {type: Boolean, default: false},
disabled: Boolean,
multiple: {type: Boolean, default: true},
fileList: {type: Array, default: () => []},
limit: {type: Number, default: 10},
@ -106,6 +101,7 @@
data() {
return {
tempData: this.fileList,
data: this.fileList,
tooltipContent: null
}
@ -127,13 +123,14 @@
fileList: {
immediate: true,
handler(fileList) {
if (isEmpty(fileList)) {
return this.data = []
if (isEmpty(fileList)) this.data = []
else {
this.data = [...this.fileList.map(file => {
const downloadUrl = autoCompleteUrl(file.url)
return {...file, url: getCoverImage(downloadUrl, file.name), downloadUrl}
})]
}
this.data = [...this.fileList.map(file => {
const downloadUrl = autoCompleteUrl(file.url)
return {...file, url: getCoverImage(downloadUrl, file.name), downloadUrl}
})]
this.tempData = JSON.parse(JSON.stringify(this.data))
}
}
},
@ -209,7 +206,7 @@
//
beforeUpload(file) {
if (!isFileTypeSupported(file.name)) {
if (!typeMapper.some(({test}) => test(file.name))) {
elError('只支持图片、word、pdf、ppt、rar、excel、txt、zip类型的文件')
return false
}
@ -221,8 +218,7 @@
},
httpRequest({file, onProgress}) {
const CancelToken = axios.CancelToken
const source = CancelToken.source()
const source = axios.CancelToken.source()
const promise = upload(file, file.name, {
onUploadProgress(e) {
if (e.total > 0) {

@ -1,3 +1,5 @@
@import "~@/assets/styles/variables.scss";
.disabled .el-upload--picture-card {
display: none;
}

@ -81,6 +81,8 @@
</script>
<style lang="scss">
@import "~@/assets/styles/variables.scss";
.has-tags-view .header-container {
height: calc(#{$nav-height} + #{$tags-view-height});
}

@ -74,6 +74,8 @@
</script>
<style lang="scss">
@import "~@/assets/styles/variables.scss";
.app-main {
position: relative;
overflow: hidden;

@ -10,11 +10,7 @@
<script>
export default {
data() {
return {
data: null
}
},
data: () => ({data: []}),
watch: {
$route(route) {
@ -37,6 +33,8 @@
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";
.app-breadcrumb.el-breadcrumb {
display: inline-block;
line-height: 50px;

@ -26,7 +26,7 @@
<router-link to="/user/index">
<el-dropdown-item icon="el-icon-user">个人中心</el-dropdown-item>
</router-link>
<el-dropdown-item class="hidden-xs" icon="el-icon-guide" @click.native="$guide(0,steps)">
<el-dropdown-item class="hidden-xs" icon="el-icon-guide" @click.native="()=>$guide(0,guideSteps)">
新手指引
</el-dropdown-item>
<router-link v-if="showSystemMonitor" to="/system/monitor">
@ -66,7 +66,6 @@
data() {
return {
fullscreen: false,
settingDrawer: false
}
},

@ -1,3 +1,5 @@
@import "~@/assets/styles/variables.scss";
.navbar {
height: $nav-height;
overflow: hidden;

@ -2,6 +2,7 @@
import {mapState} from 'vuex'
import Logo from './components/Logo'
import SidebarItem from './components/SidebarItem'
import {isExternal} from "@/utils/validate"
import variables from '@/assets/styles/variables.scss'
export default {
@ -98,6 +99,11 @@
if (!jump) return
//
if (isExternal(index)) {
return window.open(index)
}
if (this.$route.path === index) {
this.$store.commit('tagsView/delCachedView', this.$route)
this.$nextTick(() => this.$router.replace({path: '/redirect' + this.$route.fullPath}))

@ -1,3 +1,5 @@
@import "~@/assets/styles/variables.scss";
$iconSize: 17px;
.sidebar-container {

@ -169,6 +169,11 @@
}
},
beforeDestroy() {
//fade
this.$store.commit('setting/transitionName', 'el-fade-in-linear')
},
mounted() {
this.initTags()
this.addTags()

@ -1,3 +1,5 @@
@import "~@/assets/styles/variables.scss";
.tags-view-container {
height: $tags-view-height;
background: #f0f0f0;

@ -15,31 +15,39 @@ export default {
methods: {
$_prepareGuide(params) {
if (!['navbar', 'sidebar'].includes(this.$options.name)) return
if ('guide' in params) {
delAllUrlParam()
if (params.navbar && this.$options.name === 'navbar') this.$guide(params.guide, this.steps)
else if (params.sidebar && this.$options.name === 'sidebar') this.$guide(params.guide, this.steps)
for (const key of ['navbar', 'sidebar']) {
if (params[key] && this.$options.name === key) {
return this.$guide(params.guide, this.guideSteps)
}
}
}
}
},
computed: {
params() {
routeParams() {
return this.$route.params
}
},
watch: {
params(v) {
routeParams(v) {
this.$_prepareGuide(v)
}
},
created() {
transformGuideSteps(this, this.steps)
transformGuideSteps(this, this.guideSteps)
},
activated() {
let params = this.$route.params
const params = this.$route.params
if (!params.navbar && !params.sidebar && 'guide' in params) {
delAllUrlParam()
this.$guide(params.guide, this.steps)
this.$guide(params.guide, this.guideSteps)
}
}
}

@ -1,31 +0,0 @@
/*
* 首页引导步骤
* */
const steps = [
{
element: '.radar-chart',
content: '雷达图',
forceShowPrevBtn: true,
prevBtnText: '上一阶段',
onPrevious() {
this.$router.push({
path: '/redirect/index',
query: {
params: JSON.stringify({name: 'index', params: {navbar: 1, guide: 'last'}})
}
})
return false
}
},
{
element: '.pie-chart',
content: '饼图'
},
{
element: '.bar-chart',
content: '柱状图'
},
]
export default steps

@ -7,10 +7,6 @@ const steps = [
element: '#header-search',
content: '这是搜索栏,可以根据关键字搜索菜单',
},
{
element: '.fullscreen-btn.right-menu-item',
content: '这是全屏按钮',
},
{
element: '.setting-btn.right-menu-item',
content: '这是个性设置按钮,可以根据自己喜好进行一些设置',
@ -25,17 +21,6 @@ const steps = [
<p>ctrl + 可以进行tab页的左右切换</p>
<p>当tab过多时通过鼠标滚轮来滚动</p>
<p>双击可以关闭</p>`,
/*forceShowNextBtn: true,
nextBtnText: '下一阶段',
onNext() {
this.$router.push({
path: '/redirect/index',
query: {
params: JSON.stringify({name: 'index', params: {guide: 'first'}})
}
})
return false
}*/
},
]

@ -7,7 +7,7 @@ const modules = modulesFiles.keys().reduce((modules, modulePath) => {
modules[moduleName] = {
data() {
return {
steps: value.default
guideSteps: value.default
}
},
...baseMixin

@ -0,0 +1,291 @@
/*
* Live2D Widget
* https://github.com/stevenjoezhang/live2d-widget
*
* API 后端可自行搭建参考 https://github.com/fghrsh/live2d_api
*/
export default class Waifu {
constructor(tipsPath, apiPath) {
this.tipsPath = tipsPath
this.apiPath = apiPath
this.setUserAction = this.setUserAction.bind(this)
this.visibilityChange = this.visibilityChange.bind(this)
this.userAction = false
this.userActionTimer = null
this.messageTimer = null
this.messageArray = [
"好久不见,日子过得好快呢……",
"大坏蛋!你都多久没理人家了呀,嘤嘤嘤~",
"嗨~快来逗我玩吧!",
"拿小拳拳锤你胸口!",
"记得把小家加入 Adblock 白名单哦!"
]
sessionStorage.removeItem("waifu-text")
this.insertWaifu()
this.addEventListener()
this.welcomeMessage()
this.detectUserAction()
this.initModel()
this.extra()
}
insertWaifu() {
document.body.insertAdjacentHTML("beforeend",
`
<div id="waifu">
<div id="waifu-tips"></div>
<canvas id="live2d" width="300" height="300"></canvas>
<div id="waifu-tool">
<span class="el-icon-s-promotion" title="打飞机"></span>
<span class="el-icon-refresh" title="换人"></span>
<span class="el-icon-s-operation" title="换装"></span>
<span class="el-icon-camera" title="拍照"></span>
<span class="el-icon-switch-button" title="关闭"></span>
</div>
</div>
`
)
setTimeout(() => document.getElementById("waifu").style.bottom = '0', 0)
}
addEventListener() {
document.querySelector("#waifu-tool .el-icon-s-promotion").addEventListener("click", this.startAsteroids)
document.querySelector("#waifu-tool .el-icon-refresh").addEventListener("click", this.loadOtherModel.bind(this))
document.querySelector("#waifu-tool .el-icon-s-operation").addEventListener("click", this.loadRandModel.bind(this))
document.querySelector("#waifu-tool .el-icon-camera").addEventListener("click", this.takePicture.bind(this))
document.querySelector("#waifu-tool .el-icon-switch-button").addEventListener("click", this.exit.bind(this))
window.addEventListener("mousemove", this.setUserAction)
window.addEventListener("keydown", this.setUserAction)
window.addEventListener("visibilitychange", this.visibilityChange)
}
removeEventListener() {
window.removeEventListener("mousemove", this.setUserAction)
window.removeEventListener("keydown", this.setUserAction)
window.removeEventListener("visibilitychange", this.visibilityChange)
}
detectUserAction() {
window.setInterval(() => {
if (this.userAction) {
this.userAction = false
window.clearInterval(this.userActionTimer)
this.userActionTimer = null
}
else if (!this.userActionTimer) {
this.userActionTimer = window.setInterval(() => {
this.showMessage(this.randomSelection(this.messageArray), 6000, 9)
}, 20000)
}
}, 1000)
}
setUserAction() {
this.userAction = true
}
startAsteroids() {
if (window.Asteroids) {
if (!window.ASTEROIDSPLAYERS) window.ASTEROIDSPLAYERS = []
window.ASTEROIDSPLAYERS.push(new window.Asteroids())
}
else {
const script = document.createElement("script")
script.src = "https://cdn.jsdelivr.net/gh/GalaxyMimi/CDN/asteroids.js"
document.head.appendChild(script)
}
}
takePicture() {
this.showMessage("照好了嘛,是不是很可爱呢?", 6000, 9)
window.Live2D.captureName = "photo.png"
window.Live2D.captureFrame = true
}
welcomeMessage() {
let text, now = new Date().getHours()
if (now > 5 && now <= 7) text = "早上好!一日之计在于晨,美好的一天就要开始了。"
else if (now > 7 && now <= 11) text = "上午好!工作顺利嘛,不要久坐,多起来走动走动哦!"
else if (now > 11 && now <= 13) text = "中午了,工作了一个上午,现在是午餐时间!"
else if (now > 13 && now <= 17) text = "午后很容易犯困呢,今天的运动目标完成了吗?"
else if (now > 17 && now <= 19) text = "傍晚了!窗外夕阳的景色很美丽呢,最美不过夕阳红~"
else if (now > 19 && now <= 21) text = "晚上好,今天过得怎么样?"
else if (now > 21 && now <= 23) text = ["已经这么晚了呀,早点休息吧,晚安~", "深夜时要爱护眼睛呀!"]
else text = "你是夜猫子呀?这么晚还不睡觉,明天起的来嘛?"
this.showMessage(text, 7000, 8)
}
visibilityChange() {
!document.hidden && this.showMessage("哇,你终于回来了~", 6000, 9)
}
randomSelection(array) {
return Array.isArray(array) ? array[Math.floor(Math.random() * array.length)] : array
}
initModel() {
let modelId = localStorage.getItem("modelId"),
modelTexturesId = localStorage.getItem("modelTexturesId")
if (modelId == null) {
// 首次访问加载 指定模型 的 指定材质
modelId = 1 // 模型 ID
modelTexturesId = 53 // 材质 ID
}
this.loadModel(modelId, modelTexturesId)
fetch(this.tipsPath)
.then(response => response.json())
.then(result => {
for (const key of ['mouseover', 'click']) {
window.addEventListener(key, event => {
for (const tips of result[key]) {
if (!event.target.matches(tips.selector)) continue
const text = this.randomSelection(tips.text).replace("{text}", event.target.innerText)
return this.showMessage(text, 4000, 8)
}
})
}
})
}
loadModel(modelId, modelTexturesId) {
localStorage.setItem("modelId", modelId)
if (modelTexturesId === undefined) modelTexturesId = 0
localStorage.setItem("modelTexturesId", modelTexturesId)
window.loadlive2d(
"live2d",
`${this.apiPath}/get/?id=${modelId}-${modelTexturesId}`,
console.log(`Live2D 模型 ${modelId}-${modelTexturesId} 加载完成`)
)
}
//调用一言api
showHitokoto() {
// 增加 hitokoto.cn 的 API
fetch("https://v1.hitokoto.cn")
.then(response => response.json())
.then(result => {
const text = `这句一言来自 <span>「${result.from}」</span>,是 <span>${result.creator}</span> 在 hitokoto.cn 投稿的。`
this.showMessage(result.hitokoto, 6000, 9)
setTimeout(() => this.showMessage(text, 4000, 9), 6000)
})
}
showMessage(text, timeout, priority) {
if (!text) return
if (!sessionStorage.getItem("waifu-text") ||
sessionStorage.getItem("waifu-text") <= priority) {
if (this.messageTimer) {
window.clearTimeout(this.messageTimer)
this.messageTimer = null
}
if (Array.isArray(text)) text = this.randomSelection(text)
sessionStorage.setItem("waifu-text", priority)
const tips = document.getElementById("waifu-tips")
if (!tips) return
tips.innerHTML = text
tips.classList.add("waifu-tips-active")
this.messageTimer = window.setTimeout(() => {
sessionStorage.removeItem("waifu-text")
tips.classList.remove("waifu-tips-active")
}, timeout)
}
}
//换装
loadRandModel() {
const modelId = localStorage.getItem("modelId"),
modelTexturesId = localStorage.getItem("modelTexturesId")
// 可选 "rand"(随机), "switch"(顺序)
fetch(`${this.apiPath}/rand_textures/?id=${modelId}-${modelTexturesId}`)
.then(response => response.json())
.then(result => {
if (result.textures.id === 1 &&
(modelTexturesId === '1' || modelTexturesId === '0')) {
this.showMessage("我还没有其他衣服呢!", 4000, 10)
}
else this.showMessage("我的新衣服好看嘛?", 4000, 10)
this.loadModel(modelId, result.textures.id)
})
}
//切换其他模型
loadOtherModel() {
const modelId = localStorage.getItem("modelId")
fetch(`${this.apiPath}/switch/?id=${modelId}`)
.then(response => response.json())
.then(result => {
this.loadModel(result.model.id)
this.showMessage(result.model.message, 4000, 10)
})
}
extra() {
const devtools = () => ({})
console.log("%c", devtools)
devtools.toString = () => this.showMessage("哈哈,你打开了控制台,是想要看看我的小秘密吗?", 6000, 9)
console.log(`
__,.ヘヽ. / ,
', !--i / /´
' L/
/ /, /| , , ',
/ /-‐/ L_ ! i
7 '-!| |
!,/7 '0' ´0i| |
|." _ ,,,, / |./ |
'| i.,,__ _,. / .i |
'| | / k_7_/レ', . |
| |/i 〈|/ i ,. | i |
.|/ / ! |
kヽ> _,. /!
!'〈//`T´', '7'ーr'
'ヽL__|___i,___,ンレ|
-,/ |___./
'ー' !_,.:
`)
}
exit() {
this.showMessage("愿你有一天能与重要的人重逢。", 2000, 11)
this.removeEventListener()
const dom = document.getElementById("waifu")
dom.style.bottom = "-500px"
setTimeout(() => dom.remove && dom.remove(), 3000)
}
}

@ -32,6 +32,7 @@ const routes = [
path: '/user',
component: Layout,
redirect: '/user/index',
hidden: true,
children: [
{
path: 'index',
@ -39,8 +40,7 @@ const routes = [
component: () => lazyLoadView(import('@/views/userCenter')),
meta: {title: '个人中心', noCache: true, icon: 'user'},
}
],
hidden: true
]
}
]

@ -9,7 +9,7 @@
* 搜索选项显示name && meta.title
* tab栏显示name && meta.title
* tab栏固定显示meta.affix
* 页面不缓存!name || meta.noCache
* 页面不缓存!name && !meta.isDetailPage || meta.noCache
* 打开iframemeta.iframe不会重复打开相同src的iframe
* */
import Vue from 'vue'
@ -71,7 +71,7 @@ router.beforeEach(async (to, from, next) => {
//页面不需要鉴权或有访问权限时通过
if (!needAuth(to) || auth(to.path)) {
iframeControl(to)
iframeControl(to, from)
return next()
}
@ -90,9 +90,14 @@ function initMenu() {
}
//判断是否需要打开iframe
function iframeControl(route) {
const operate = route.meta.iframe ? 'open' : 'close'
store.dispatch(`iframe/${operate}`, route.meta.iframe)
function iframeControl(to, from) {
const isRefresh = to.path === '/redirect' + from.path
let iframe = to.meta && to.meta.iframe
const operate = iframe ? 'open' : 'close'
if (isRefresh) iframe = from.meta && from.meta.iframe
return store.dispatch(`iframe/${operate}`, iframe)
}
export default router

@ -5,8 +5,7 @@ import PageSkeleton from "@/components/Skeleton/PageSkeleton"
//拼接页面标题
export function getPageTitle(route) {
let pageTitle = route.meta && route.meta.title
if (typeof pageTitle === 'function') pageTitle = pageTitle(route)
const pageTitle = route.meta && route.meta.title
return pageTitle ? `${pageTitle} - ${title}` : title
}

@ -13,15 +13,13 @@ const mutations = {
state.list.push(src)
},
del(state, src) {
if (!src) return
let index = state.list.findIndex(i => i === src)
const index = state.list.findIndex(i => i === src)
index > -1 && state.list.splice(index, 1)
}
}
const actions = {
open({commit}, src) {
if (!src) return
commit('show', true)
commit('current', src)
commit('add', src)

@ -8,7 +8,7 @@ const state = {
cachedViews: [],
//路由过渡动画名称
transitionName: ''
transitionName: 'el-fade-in-linear'
}
const mutations = {
@ -22,9 +22,9 @@ const mutations = {
state.visitedViews.push({...view, title})
},
addCachedView(state, view) {
const {noCache, iframe} = view.meta || {}
const {noCache, iframe, isDetailPage} = view.meta || {}
if (noCache || iframe) return
if (noCache || iframe || !view.name && !isDetailPage) return
const key = getCachedViewKey(view)

@ -42,3 +42,39 @@ export function getContextPath() {
const {protocol, host} = document.location
return `${protocol}//${host}${process.env.BASE_URL}`
}
/**
* 加载js或css
*
* @param url
* @param type js|css
* @returns {Promise<String>} url
*/
export function loadExternalResource(url, type = 'js') {
return new Promise((resolve, reject) => {
let tag
if (type === "css") {
const links = Array.from(document.getElementsByTagName('link'))
if (links.some(link => link.getAttribute('href') === url)) return resolve()
tag = document.createElement("link")
tag.rel = "stylesheet"
tag.href = url
}
else if (type === "js") {
const scripts = Array.from(document.getElementsByTagName('script'))
if (scripts.some(script => script.getAttribute('src') === url)) return resolve()
tag = document.createElement("script")
tag.src = url
}
if (tag) {
tag.onload = () => resolve(url)
tag.onerror = () => reject(url)
document.head.appendChild(tag)
}
else reject(`没有这个东东,url:${url},type:${type}`)
})
}

@ -1,6 +1,6 @@
/**
* @deprecated
* xlsx问题多多准备全面转向excelJS
* xlsx问题多多转向excelJS
*/
import {isEmpty} from "@/utils"

@ -49,7 +49,7 @@ export function timeFormat(fmt, date = new Date()) {
fmt = fmt.replace(RegExp.$1, [...replace].join(''))
}
for (let k in o) {
for (const k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
const firstMatch = RegExp.$1
const replace = firstMatch.length === 1 ? o[k] : ("00" + o[k]).substring(("" + o[k]).length)

@ -1,6 +1,6 @@
/*基于decimal.js的运算封装*/
import Decimal from 'decimal.js'
/*基于decimal.js的运算封装*/
export function plus(...val) {
if (val.length === 0) return 0
else if (val.length === 1) return new Decimal(val[0]).toNumber()

@ -1,3 +1,5 @@
@import "~@/assets/styles/variables.scss";
$bg: #283443;
$light_gray: #fff;
$dark_gray: #889aa4;

@ -38,6 +38,8 @@
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";
.q-skeleton + .q-skeleton {
margin-top: 20px;
}

@ -9,81 +9,28 @@
</template>
<script>
import {getContextPath} from "@/utils/browser"
/**
* 加载js或css
* @param url
* @param type js|css
* @returns {Promise<String>} url
*/
function loadExternalResource(url, type = 'js') {
return new Promise((resolve, reject) => {
let tag
if (type === "css") {
const links = Array.from(document.getElementsByTagName('link'))
if (links.some(link => link.getAttribute('href') === url)) return resolve()
tag = document.createElement("link")
tag.rel = "stylesheet"
tag.href = url
}
else if (type === "js") {
const scripts = Array.from(document.getElementsByTagName('script'))
if (scripts.some(script => script.getAttribute('src') === url)) return resolve()
tag = document.createElement("script")
tag.src = url
}
if (tag) {
tag.onload = () => resolve(url)
tag.onerror = () => reject(url)
document.head.appendChild(tag)
}
else reject(`没有这个东东,url:${url},type:${type}`)
})
}
import {getContextPath, loadExternalResource} from "@/utils/browser"
export default {
name: "l2d",
data: () => ({l2d: null}),
mounted() {
//live2d_path 使
//const live2d_path = "https://cdn.jsdelivr.net/gh/stevenjoezhang/live2d-widget/"
const live2d_path = `${getContextPath()}static/live2d/`
const path = `${getContextPath()}static/live2d/`
// waifu.css live2d.min.js waifu-tips.js
Promise.all([
loadExternalResource(live2d_path + "waifu.css", "css"),
loadExternalResource(live2d_path + "live2d.min.js"),
loadExternalResource(live2d_path + "waifu-tips.js")
import('@/plugin/live2d'),
loadExternalResource(path + "waifu.css", "css"),
loadExternalResource(path + "live2d.min.js")
])
.then(() => {
// initWidget waifu-tips.json API
// API https://github.com/fghrsh/live2d_api
// waifu-tips.json
window.initWidget(live2d_path + "waifu-tips.json", "https://live2d.fghrsh.net/api")
console.log(`
__,.ヘヽ. / ,
', !--i / /´
' L/
/ /, /| , , ',
/ /-‐/ L_ ! i
7 '-!| |
!,/7 '0' ´0i| |
|." _ ,,,, / |./ |
'| i.,,__ _,. / .i |
'| | / k_7_/レ', . |
| |/i 〈|/ i ,. | i |
.|/ / ! |
kヽ> _,. /!
!'〈//`T´', '7'ーr'
'ヽL__|___i,___,ンレ|
-,/ |___./
'ー' !_,.:
`)
.then(([_]) => {
this.l2d = new _.default(`${path}waifu-tips.json`, "https://live2d.fghrsh.net/api")
})
},
beforeDestroy() {
this.l2d && this.l2d.exit()
}
}
</script>

@ -71,8 +71,6 @@
<script>
import {elError, elSuccess} from "@/utils/message"
import compressJPG from '@/plugin/imageCompress/cjpeg'
import compressPNG from '@/plugin/imageCompress/pngquant'
import {sub, mul, div} from "@/utils/math"
const commonData = () => ({
@ -146,12 +144,14 @@
reader.readAsArrayBuffer(this[type].input.file)
},
compressJPG(uint8Array, start) {
compressJPG(uint8Array, this.jpg.quality)
import('@/plugin/imageCompress/cjpeg')
.then(_ => _.default(uint8Array, this.jpg.quality))
.then(({data, time}) => this.compressSuccess({type: 'jpg', start, data, time}))
.finally(() => this.jpg.loading = false)
},
compressPNG(uint8Array, start) {
compressPNG(uint8Array, this.png.quality, this.png.speed)
import('@/plugin/imageCompress/pngquant')
.then(_ => _.default(uint8Array, this.png.quality, this.png.speed))
.then(({data, time}) => this.compressSuccess({type: 'png', start, data, time}))
.finally(() => this.png.loading = false)
},
@ -166,7 +166,10 @@
}
}
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";
.container {
max-width: 1200px;
text-align: center;

@ -117,6 +117,8 @@
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";
.el-table {
a {
color: $--color-primary;

@ -45,6 +45,8 @@
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";
span {
.svg-icon {
color: $--color-primary

@ -13,6 +13,7 @@
</el-form-item>
<el-form-item label="行政区域:" prop="region_name">
<region-selector
type="tree"
:value="form.region_name"
:readonly="!canEdit"
@clear="clearRegion"
@ -55,7 +56,7 @@
<script>
import DialogForm from '@/components/DialogForm'
import RegionSelector from '@/components/RegionSelector/Tree'
import RegionSelector from '@/components/RegionSelector'
import dialogMixin from "@/mixins/dialogMixin"
import {addSupplier, updateSupplier} from "@/api/system/supplier"
import {isEmpty, mergeObj, resetObj} from '@/utils'

@ -6,6 +6,7 @@
</search-form-item>
<search-form-item label="行政区域:">
<region-selector
type="tree"
:value="temp.region_name"
limit
:limit-api="getLimitRegion"
@ -83,7 +84,7 @@
<script>
import SearchForm from "@/components/SearchForm"
import SearchFormItem from "@/components/SearchForm/SearchFormItem"
import RegionSelector from "@/components/RegionSelector/Tree"
import RegionSelector from "@/components/RegionSelector"
import EditDialog from './EditDialog'
import {delSupplier, getLimitRegion, getSuppliers} from "@/api/system/supplier"
import {isEmpty} from '@/utils'

@ -125,8 +125,8 @@
}
.img-wrapper {
height: 360px;
width: 640px;
height: 500px;
width: 100%;
display: inline-block;
border: 1px solid #ebebeb;
}

@ -81,9 +81,9 @@ module.exports = {
.options({symbolId: 'icon-[name]'})
.end()
},
css: {
/*css: {
loaderOptions: {
sass: {prependData: `@import "src/assets/styles/variables.scss";`,}
}
}
}*/
}

Loading…
Cancel
Save