no message

This commit is contained in:
kuaifan 2021-05-29 23:51:00 +08:00
parent 97ea16f344
commit 3359fde4aa
32 changed files with 5833 additions and 916 deletions

View File

@ -16,24 +16,26 @@
"jquery": "^3.5.1",
"laravel-mix": "^6.0.6",
"lodash": "^4.17.19",
"postcss": "^8.1.14",
"resolve-url-loader": "^3.1.3",
"sass": "^1.34.0",
"sass-loader": "^11.1.1",
"stylus": "^0.54.8",
"stylus-loader": "^3.0.2",
"vue": "^2.6.12",
"vue-loader": "^15.9.7",
"vue-router": "^3.4.2",
"vue-template-compiler": "^2.6.11",
"postcss": "^8.1.14"
"vue-template-compiler": "^2.6.11"
},
"dependencies": {
"@chenfengyuan/vue-qrcode": "^1.0.2",
"echarts": "^5.0.0",
"internal-ip": "^6.1.0",
"tinymce": "^5.6.2",
"echarts": "^5.1.1",
"tinymce": "^5.8.1",
"view-design-hi": "^4.5.0-4",
"vue-clipboard2": "^0.3.1",
"vue-emoji-picker": "^1.0.1",
"vue-kityminder-gg": "^1.3.6",
"vue-resize-observer": "^1.0.37",
"vuedraggable": "^2.24.3",
"xlsx": "^0.16.9"
"xlsx": "^0.17.0"
}
}

View File

212
resources/js/App.vue Executable file
View File

@ -0,0 +1,212 @@
<template>
<div id="app">
<transition :name="transitionName">
<keep-alive>
<router-view class="child-view"></router-view>
</keep-alive>
</transition>
<Spinner/>
</div>
</template>
<script>
import Spinner from "./common/components/Spinner";
export default {
components: {Spinner},
data () {
return {
transitionName: null,
}
},
mounted() {
this.checkToken();
//
if ($A.getToken() !== false) {
$A.getUserInfo(true);
}
//
let hash = window.location.hash;
if (hash.indexOf("#") === 0) {
hash = hash.substr(1);
if (hash) {
this.$nextTick(() => {
hash = $A.removeURLParameter(hash, 'token');
this.goForward({path: hash});
});
}
}
this.sessionStorage('/', 1);
let pathname = window.location.pathname;
if (pathname && this.sessionStorage(pathname) === 0) {
this.sessionStorage(pathname, this.sessionStorage('::count') + 1);
}
//
setInterval(this.searchEnter, 1000);
},
watch: {
'$route' (To, From) {
if (this.transitionName === null) {
this.transitionName = 'app-slide-no';
return;
}
if (typeof To.name === 'undefined' || typeof From.name === 'undefined') {
return;
}
this.slideType(To, From);
}
},
methods: {
checkToken() {
let token = $A.urlParameter("token");
if ($A.count(token) > 10) {
$.setToken(decodeURIComponent(token));
$A.getUserInfo(true);
let path = $A.removeURLParameter(window.location.href, 'token');
let uri = document.createElement('a');
uri.href = path;
if (uri.pathname) {
let query = $A.urlParameterAll();
if (typeof query['token'] !== "undefined") delete query['token'];
this.$nextTick(() => {
this.goForward({path: uri.pathname, query}, true);
});
}
}
},
slideType(To, From) {
let isBack = this.$router.isBack;
this.$router.isBack = false;
//
let ToIndex = this.sessionStorage(To.path);
let FromIndex = this.sessionStorage(From.path);
if (ToIndex && ToIndex < FromIndex) {
isBack = true; //退
this.sessionStorage(true, ToIndex);
}else{
isBack = false; //
this.sessionStorage(To.path, this.sessionStorage('::count') + 1);
}
//
if (To.meta.slide === false || From.meta.slide === false)
{
//
this.transitionName = 'app-slide-no'
}
else if (To.meta.slide === 'up' || From.meta.slide === 'up' || To.meta.slide === 'down' || From.meta.slide === 'down')
{
//
if (isBack) {
this.transitionName = 'app-slide-down'
} else {
this.transitionName = 'app-slide-up'
}
}
else
{
//
if (isBack) {
this.transitionName = 'app-slide-right'
} else {
this.transitionName = 'app-slide-left'
}
}
},
sessionStorage(path, num) {
let conut = 0;
let history = JSON.parse(window.sessionStorage['__history__'] || '{}');
if (path === true) {
let items = {};
for(let i in history){
if (history.hasOwnProperty(i)) {
if (parseInt(history[i]) <= num) {
items[i] = history[i];
conut++;
}
}
}
history = items;
history['::count'] = Math.max(num, conut);
window.sessionStorage['__history__'] = JSON.stringify(history);
return history;
}
if (typeof num === 'undefined') {
return parseInt(history[path] || 0);
}
if (path === "/") num = 1;
history[path] = num;
for(let key in history){ if (history.hasOwnProperty(key) && key !== '::count') { conut++; } }
history['::count'] = Math.max(num, conut);
window.sessionStorage['__history__'] = JSON.stringify(history);
},
searchEnter() {
let row = $A(".sreachBox");
if (row.length === 0) {
return;
}
if (row.attr("data-enter-init") === "init") {
return;
}
row.attr("data-enter-init", "init");
//
let buttons = row.find("button[type='button']");
let button = null;
if (buttons.length === 0) {
return;
}
buttons.each((index, item) => {
if ($A(item).text().indexOf("搜索")) {
button = $A(item);
}
});
if (button === null) {
return;
}
row.find("input.ivu-input").keydown(function(e) {
if (e.keyCode == 13) {
if (!button.hasClass("ivu-btn-loading") ) {
button.click();
}
}
});
},
}
}
</script>
<style>
body { overflow-x: hidden; }
</style>
<!--suppress CssUnusedSymbol -->
<style scoped>
.child-view {
position: absolute;
width: 100%;
min-height: 100%;
transition: all .3s cubic-bezier(.55, 0, .1, 1);
}
.app-slide-no-leave-to {display: none;}
/**
* 左右模式
*/
.app-slide-left-leave-active{z-index:1;transform:translate(0,0)}
.app-slide-left-leave-to{z-index:1;transform:translate(0,0)}
.app-slide-left-enter-active{opacity:0;z-index:2;transform:translate(30%,0)}
.app-slide-left-enter-to{opacity:1;z-index:2;transform:translate(0,0)}
.app-slide-right-leave-active{opacity:1;z-index:2;transform:translate(0,0)}
.app-slide-right-leave-to{opacity:0;z-index:2;transform:translate(30%,0)}
.app-slide-right-enter-active{z-index:1;transform:translate(0,0)}
.app-slide-right-enter{z-index:1;transform:translate(0,0)}
/**
* 上下模式
*/
.app-slide-up-leave-active{z-index:1;transform:translate(0,0)}
.app-slide-up-leave-to{z-index:1;transform:translate(0,0)}
.app-slide-up-enter-active{opacity:0;z-index:2;transform:translate(0,20%)}
.app-slide-up-enter-to{opacity:1;z-index:2;transform:translate(0,0)}
.app-slide-down-leave-active{opacity:1;z-index:2;transform:translate(0,0)}
.app-slide-down-leave-to{opacity:0;z-index:2;transform:translate(0,20%)}
.app-slide-down-enter-active{z-index:1;transform:translate(0,0)}
.app-slide-down-enter{z-index:1;transform:translate(0,0)}
</style>

View File

@ -1 +1,81 @@
require('./bootstrap');
import Vue from 'vue'
import App from './App.vue'
import routes from './routes'
import VueRouter from 'vue-router'
import ViewUI from 'view-design-hi';
import Language from './common/language/index'
import Mixins from './common/mixins/index'
import './common/functions/index'
import './main'
Vue.use(VueRouter);
Vue.use(ViewUI);
Vue.use(Language);
Vue.use(Mixins);
import PageTitle from './common/components/PageTitle.vue'
import Loading from './common/components/Loading.vue'
import AutoTip from './common/components/AutoTip.vue'
import TableAction from './common/components/TableAction.vue'
Vue.component('PageTitle', PageTitle);
Vue.component('Loading', Loading);
Vue.component('AutoTip', AutoTip);
Vue.component('TableAction', TableAction);
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
const router = new VueRouter({
mode: 'history',
routes
});
//进度条配置
ViewUI.LoadingBar.config({
color: '#3fcc25',
failedColor: '#ff0000'
});
router.beforeEach((to, from, next) => {
ViewUI.LoadingBar.start();
next();
});
router.afterEach((to, from, next) => {
ViewUI.LoadingBar.finish();
});
//加载函数
Vue.prototype.goForward = function(location, isReplace) {
if (typeof location === 'string') location = {name: location};
if (isReplace === true) {
this.$router.replace(location);
}else{
this.$router.push(location);
}
};
//返回函数
Vue.prototype.goBack = function (number) {
let history = $A.jsonParse(window.sessionStorage['__history__'] || '{}');
if ($A.runNum(history['::count']) > 2) {
this.$router.go(typeof number === 'number' ? number : -1);
} else {
this.$router.replace(typeof number === "object" ? number : {path: '/'});
}
};
Vue.prototype.$A = $A;
Vue.config.productionTip = false;
const app = new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
});
$A.app = app;

View File

@ -1,28 +0,0 @@
window._ = require('lodash');
/**
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
/**
* Echo exposes an expressive API for subscribing to channels and listening
* for events that are broadcast by Laravel. Echo and event broadcasting
* allows your team to easily build robust real-time web applications.
*/
// import Echo from 'laravel-echo';
// window.Pusher = require('pusher-js');
// window.Echo = new Echo({
// broadcaster: 'pusher',
// key: process.env.MIX_PUSHER_APP_KEY,
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
// forceTLS: true
// });

View File

@ -0,0 +1,85 @@
<template>
<Tooltip transfer :content="text" :placement="placement" :theme="tooltipTheme" :delay="delay" :disabled="!showTooltip" :max-width="tooltipMaxWidth" class="ivu-table-cell-tooltip">
<span ref="content" @mouseenter="handleTooltipIn" class="ivu-table-cell-tooltip-content">
<template v-if="existSlot"><slot/></template>
<template v-else>{{text}}</template>
</span>
</Tooltip>
</template>
<script>
export default {
name: 'AutoTip',
props: {
content: {
type: [String, Number],
default: ''
},
placement: {
default: 'bottom'
},
tooltipTheme: {
default: 'dark'
},
tooltipMaxWidth: {
type: [String, Number],
default: 300
},
delay: {
type: Number,
default: 100
},
},
data() {
return {
slotText: '',
showTooltip: false // overflow
}
},
mounted () {
this.updateConetne()
},
beforeUpdate () {
this.updateConetne()
},
activated() {
this.updateConetne()
},
computed: {
text() {
const {content, slotText} = this;
if (content) {
return content;
}
if (typeof slotText === 'undefined' || slotText.length < 1 || typeof slotText[0].text !== 'string') {
return '';
}
return slotText[0].text;
},
existSlot() {
const {slotText} = this;
return !(typeof slotText === 'undefined' || slotText.length < 1);
},
},
methods: {
updateConetne () {
this.slotText = this.$slots.default;
},
handleTooltipIn () {
const $content = this.$refs.content;
let range = document.createRange();
range.setStart($content, 0);
range.setEnd($content, $content.childNodes.length);
const rangeWidth = range.getBoundingClientRect().width;
this.showTooltip = Math.floor(rangeWidth) > Math.floor($content.offsetWidth);
range = null;
},
}
}
</script>

View File

@ -0,0 +1,594 @@
<template>
<div>
<div v-if="type !== 'callback'" class="imgcomp-upload-list" v-for="item in uploadList">
<template v-if="item.status === 'finished'">
<div class="imgcomp-upload-img" v-bind:style="{ 'background-image': 'url(' + __thumb(item.thumb) + ')' }"></div>
<div class="imgcomp-upload-list-cover">
<Icon type="ios-eye-outline" @click.native="handleView(item)"></Icon>
<Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
</div>
</template>
<template v-else>
<Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
</template>
</div>
<div class="add-box" v-bind:class="{ 'callback-add-box': type === 'callback' }">
<div class="add-box-icon">
<Icon type="md-add" size="32"></Icon>
</div>
<div class="add-box-upload">
<div class="add-box-item" @click="browsePicture">
<span>{{$L('浏览')}}<em v-if="type === 'callback'">{{$L('图片')}}</em></span>
</div>
<div class="add-box-item">
<Upload
name="image"
ref="upload"
accept="image/*"
:action="actionUrl"
:data="uploadParams"
:show-upload-list="false"
:max-size="maxSize"
:format="['jpg', 'jpeg', 'gif', 'png']"
:default-file-list="defaultList"
:on-progress="handleProgress"
:on-success="handleSuccess"
:on-error="handleError"
:on-format-error="handleFormatError"
:on-exceeded-size="handleMaxSize"
:before-upload="handleBeforeUpload"
:multiple=multiple>
<span>{{$L('上传')}}<em v-if="type === 'callback'">{{$L('图片')}}</em></span>
</Upload>
</div>
</div>
</div>
<Modal :title="$L('浏览图片空间的图片')" v-model="browseVisible" class="img-upload-modal" class-name="simple-modal" width="710">
<div class="browse-load" v-if="isLoading">{{$L('加载中...')}}</div>
<div class="browse-list" :class="httpType==='input'?'browse-list-disabled':''" ref="browselistbox">
<div class="browse-item" v-for="item in browseList" @click="browseItem(item)">
<Icon v-if="item.active" class="browse-icon" type="ios-checkmark-circle"></Icon>
<div class="browse-img" v-bind:style="{ 'background-image': 'url(' + item.thumb + ')' }"></div>
<div class="browse-title">{{item.title}}</div>
</div>
</div>
<div slot="footer" class="img-upload-foot">
<div v-if="type !== 'callback' && http && httpType===''" class="img-upload-foot-input" @click="httpType='input'">
<Icon type="ios-image" size="22"/>
<div class="img-upload-foot-httptitle">{{$L('自定义图片地址')}}</div>
</div>
<div v-if="type !== 'callback' && http && httpType==='input'" class="img-upload-foot-input">
<Input v-model="httpValue" :placeholder="$L('以 http:// 或 https:// 开头')" @on-search="httpEnter" search :enter-button="$L('确定')">
<span slot="prepend" @click="httpType=''" style="cursor:pointer">{{$L('自定义地址')}}: </span>
</Input>
</div>
<Button v-if="httpType===''" @click="browseVisible=false">{{$L('关闭')}}</Button>
<Button v-if="httpType===''" type="primary" @click="handleCallback(true)">{{$L('完成')}}</Button>
</div>
</Modal>
<Modal :title="$L('查看图片')" v-model="visible" class="img-upload-modal" class-name="simple-modal" draggable>
<div style="max-height:480px;overflow:auto;">
<a :href="imgVisible" target="_blank"><img :src="imgVisible" v-if="visible" style="max-width:100%;max-height:900px;display:block;margin:0 auto"></a>
</div>
</Modal>
</div>
</template>
<style lang="scss">
.img-upload-modal {
.ivu-modal-mask {
z-index: 1001;
}
.ivu-modal-no-mask {
background-color: rgba(55,55,55,.2);
}
.ivu-modal-wrap {
z-index: 1001;
}
}
.imgcomp-upload-list{
display: inline-block;
width: 60px;
height: 60px;
text-align: center;
line-height: 60px;
border: 1px solid transparent;
border-radius: 4px;
overflow: hidden;
background: #fff;
position: relative;
box-shadow: 0 1px 1px rgba(0,0,0,.2);
margin-right: 4px;
vertical-align: top;
.imgcomp-upload-img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-position: center;
background-size: cover;
}
.imgcomp-upload-list-cover{
display: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0,0,0,.6);
}
.imgcomp-upload-list-cover i{
color: #fff;
font-size: 24px;
cursor: pointer;
vertical-align: middle;
margin: 0;
transition: all .2s;
}
.imgcomp-upload-list-cover i:hover{
font-size: 28px;
}
.ivu-progress-outer {
background-color: rgba(0, 0, 0, 0.68);
.ivu-progress-inner{
width: 88%;
}
}
}
.imgcomp-upload-list:hover .imgcomp-upload-list-cover{
display: block;
}
.img-upload-foot {
display: flex;
align-items: center;
justify-content: flex-end;
.img-upload-foot-input {
flex: 1;
text-align: left;
display: flex;
align-items: center;
justify-content: flex-end;
.img-upload-foot-httptitle {
cursor: pointer;
padding-left: 3px;
margin-right: 22px;
}
}
}
.add-box {
width: 60px;
height: 60px;
line-height: 60px;
display: inline-block;
background: #fff;
border: 1px dashed #dddee1;
border-radius: 4px;
text-align: center;
position: relative;
overflow: hidden;
vertical-align: top;
.add-box-icon {
i {
vertical-align:middle;
padding-bottom: 2px;
}
}
.add-box-upload {
display: none;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
color: #ffffff;
padding-top: 9px;
background: rgba(0, 0, 0, 0.6);
.add-box-item {
height: 22px;
line-height: 22px;
cursor: pointer;
.ivu-upload-drag,.ivu-upload-drag:hover {
background:transparent;
border:0;
border-radius:0;
}
span {
transition: all .2s;
font-size: 12px;
}
}
.add-box-item:hover {
span {
font-size: 14px;
}
}
}
em {
font-style: normal;
}
}
.add-box:hover {
border-color: rgba(0,0,0,.6);
.add-box-upload {
display: block;
}
}
.callback-add-box {
display: block;
width: auto;
height: 25px;
line-height: 25px;
border: 0;
background: transparent;
.add-box-icon {
display: none;
}
.add-box-upload {
display: block;
width: auto;
background: transparent;
color: #333;
padding: 0;
> div {
display: inline-block;
padding-right: 10px;
}
}
}
.browse-load {
margin: 20px;
text-align: center;
}
.browse-list {
max-height: 540px;
overflow: auto;
.browse-item {
margin: 10px 15px;
display: inline-block;
text-align: center;
cursor: pointer;
position: relative;
.browse-img {
width: 64px;
height: 64px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKoAAABxCAAAAABg5GeyAAACW0lEQVR4Ae3XVRLjMBAE0L3/rSwKM3OcSNPyLVYOLvM6UD0Bd03LVe9XH+RlhlRSSSWVVFJJJZVUUkkllVRSSSWVVFJJJZVUUkl9WyqppJJKKqmkkgpURP17xngOAR5NxW5wlJ9MaLQh83F4NHWmd/gZtdVBaOldfDB1bq5UpJFbFOC6LKnYrkRO209PAw+hIuzWB8Ep5es8HvYo4z4tE1X8UeRwlMM2D5Bzkc7kj6Bi3VTKDDwEeUcrMxrUvGDXTnHa6kK69SDN9sgq1clxKSbNHqqnYmdri81Q9QHf1JPt1Frncaib2XbiTKL2GkHaurnY9LOulMV0O7G6Kw+g9sw2ohhm62KezVJaaufjWC1TnOkr1exilJ7Ji0vxCCqO9V4UwV4PYr9+apouhGYLKfnahdpqegjmeoXOpXgANe70pKT6Zhu19qkY2nC0PZS527lQOyInqr8Uvc5jqfUb1X+PGh5IhW90S2quh3FQC2XRcF66TUkTXPcLKm5FtdR9RJq+2hWII7UpFtmsQLEyzsdJtkxxpr6gLotbUSlV9yeT0Trmzk2XPdUThLYarUbWOY9j04xXQ2u+pMZLYSumGmNUH3HbM9qOAwSHodN2Pks25F2j3aI7+IxqNsB+YLWb16ukSjiW4xNB0gMoMfApBS/XZQgi3p9/5RsiKNKZEOwYFVIF5VyTyD19sbyjIJiNJRZxpNbx2S8sGKvGZNHJBniBu9Wy5WxjGuQFqIAcBHiRGyt4ua5gSCWVVFJJJZVUUkkllVRSSSWVVFJJJZVUUkkllVRSSSWVVFI/AgO0SXIVYHeGAAAAAElFTkSuQmCC);
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
.browse-title {
display: block;
width: 64px;
margin-top: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.browse-icon {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 64px;
font-size: 36px;
padding-top: 15px;
color: #ffffff;
background-color: rgba(0, 0, 0, 0.5);
}
}
}
.browse-list-disabled {
position: relative;
}
.browse-list-disabled:after {
position: absolute;
content: '';
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.9);
z-index: 1;
}
</style>
<script>
export default {
name: 'ImgUpload',
props: {
value: {
},
num: {
},
width: {
},
height: {
},
type: {
},
http: {
type: Boolean,
default: false
},
otherParams: {
type: Object,
default: () => {
return {};
}
},
uploadIng: {
type: Number,
default: 0
}
},
data () {
return {
actionUrl: $A.apiUrl('system/imgupload'),
params: {
token: $A.getToken(),
width: this.width,
height: this.height
},
multiple: this.num > 1,
visible: false,
browseVisible: false,
isLoading: false,
browseList: [],
browseListNext: [],
imgVisible: '',
defaultList: this.initItems(this.value),
uploadList: [],
maxNum: Math.min(Math.max($A.runNum(this.num), 1), 99),
httpValue: '',
httpType: '',
maxSize: 2048
}
},
mounted () {
this.uploadList = this.$refs.upload.fileList;
this.$emit('input', this.uploadList);
//
let browseBox = $A(this.$refs.browselistbox);
browseBox.scroll(()=>{
let nHight = browseBox[0].scrollHeight;
let nTop = browseBox[0].scrollTop;
let boxHight = browseBox.height();
if(nTop + boxHight >= nHight) {
//
if (this.browseListNext.length > 0) {
let tmpNext = this.browseListNext;
this.browseListNext = [];
this.browsePictureFor(tmpNext);
}
}
});
},
watch: {
value (val) {
if (typeof val === 'string') {
this.$emit('input', this.initItems(val));
return;
}
if (val === this.$refs.upload.fileList) {
return;
}
this.$refs.upload.fileList = this.initItems(val);
this.uploadList = this.$refs.upload.fileList;
},
browseVisible() {
this.httpType = '';
this.httpValue = '';
}
},
computed: {
uploadParams() {
if (Object.keys(this.otherParams).length > 0) {
return Object.assign(this.params, this.otherParams);
} else {
return this.params;
}
}
},
methods: {
handleCallback(file) {
if (this.type === 'callback') {
if (file === true) {
this.$emit('on-callback', this.uploadList);
this.$refs.upload.fileList = [];
this.uploadList = this.$refs.upload.fileList;
}else if (typeof file === "object") {
this.$emit('on-callback', [file]);
}
}
this.browseVisible = false;
},
initItems(items) {
//
if (typeof items === 'string') {
items = [{'url': items}];
}
let lists = [];
$A.each(items, (index, item)=>{
if (typeof item === 'string') item = {'url': item};
if (item.url) {
item.active = true;
item.status = 'finished';
if (typeof item.path === 'undefined') item.path = item.url;
if (typeof item.thumb === 'undefined') item.thumb = item.url;
lists.push(item);
}
});
return lists;
},
handleView (item) {
//
this.visible = true;
this.imgVisible = item.url;
},
handleRemove (item) {
//
let fileList = this.$refs.upload.fileList;
this.$refs.upload.fileList.splice(fileList.indexOf(item), 1);
this.$emit('input', this.$refs.upload.fileList);
},
handleProgress() {
//
this.$emit('update:uploadIng', this.uploadIng + 1);
},
handleSuccess (res, file) {
//
this.$emit('update:uploadIng', this.uploadIng - 1);
if (res.ret === 1) {
file.url = res.data.url;
file.path = res.data.path;
file.thumb = res.data.thumb;
this.handleCallback(file);
}else{
$A.noticeWarning({
title: this.$L('上传失败'),
desc: this.$L('文件 ' + file.name + ' 上传失败 ' + res.msg),
});
this.$refs.upload.fileList.pop();
}
this.$emit('input', this.$refs.upload.fileList);
},
handleError() {
//
this.$emit('update:uploadIng', this.uploadIng - 1);
},
handleFormatError (file) {
//
$A.noticeWarning({
title: this.$L('文件格式不正确'),
desc: this.$L('文件 ' + file.name + ' 格式不正确,请上传 jpg、jpeg、gif、png 格式的图片。')
});
},
handleMaxSize (file) {
//
$A.noticeWarning({
title: this.$L('超出文件大小限制'),
desc: this.$L('文件 ' + file.name + ' 太大,不能超过' + $A.bytesToSize(this.maxSize * 1024))
});
},
handleBeforeUpload () {
//
let check = this.uploadList.length < this.maxNum;
if (!check && this.uploadList.length == 1) {
this.handleRemove(this.uploadList[0]);
check = this.uploadList.length < this.maxNum;
}
if (!check) {
$A.noticeWarning(this.$L('最多只能上传 ' + this.maxNum + ' 张图片。'));
}
this.params = {
token: $A.getToken(),
width: this.width,
height: this.height
};
return check;
},
handleClick() {
//
if (this.handleBeforeUpload()) {
this.$refs.upload.handleClick()
}
},
handleManual(file) {
//file
if (this.handleBeforeUpload()) {
this.$refs.upload.upload(file);
}
},
browsePicture(path) {
//
this.browseVisible = true;
this.browseList = [];
this.browseListNext = [];
this.isLoading = true;
$A.apiAjax({
url: 'system/imgview',
data: { path: path?path:'' },
beforeSend: true,
complete: true,
error: true,
success: (res) => {
this.isLoading = false;
if (res.ret === 1) {
let dirs = res.data['dirs'];
for (let i = 0; i < dirs.length; i++) {
this.browseList.push(dirs[i]);
}
this.browsePictureFor(res.data['files']);
}else if (res.ret === -2) {
this.browseVisible = false;
$A.noticeWarning(res.msg);
}
}
});
},
browsePictureFor(files) {
for (let o = 0; o < files.length; o++) {
for (let j = 0; j < this.uploadList.length; j++) {
if (this.uploadList[j]['url'] === files[o]['url']
|| this.uploadList[j]['url'] === files[o]['path']) {
files[o]['active'] = true;
break;
}
}
if (o < 100) {
this.browseList.push(files[o]);
}else{
this.browseListNext.push(files[o]);
}
}
},
browseItem(item) {
//
if (item.type === 'dir') {
//
this.browsePicture(item.path);
}else if (item.type === 'file') {
//
if (item.active) {
let fileList = this.$refs.upload.fileList;
this.$refs.upload.fileList.splice(fileList.indexOf(item), 1);
item.active = false;
}else{
if (this.maxNum === 1) {
for (let i = 0; i < this.browseList.length; i++) {
this.browseList[i].active = false;
}
this.$refs.upload.fileList = [];
this.uploadList = this.$refs.upload.fileList;
}
let check = this.uploadList.length < this.maxNum;
if (!check) {
$A.noticeWarning(this.$L('最多只能选择 ' + this.maxNum + ' 张图片。'));
return;
}
item.active = true;
item.status = 'finished';
this.$refs.upload.fileList.push(item);
this.uploadList = this.$refs.upload.fileList;
}
this.$emit('input', this.$refs.upload.fileList);
}
},
__thumb(url) {
if ($A.strExists(url, "?", false)) {
return url + "&__thumb=true";
}else{
return url + "?__thumb=true";
}
},
httpEnter() {
this.$emit('input', this.initItems(this.httpValue));
this.browseVisible = false;
}
}
}
</script>

View File

@ -0,0 +1,108 @@
<template>
<svg viewBox="25 25 50 50" class="common-loading"><circle cx="50" cy="50" r="20" fill="none" stroke-width="5" stroke-miterlimit="10" class="w-path"></circle></svg>
</template>
<style lang="scss" scoped>
.common-loading {
-webkit-animation: rotate 2s linear infinite;
animation: rotate 2s linear infinite;
-webkit-transform-origin: center center;
transform-origin: center center;
width: 30px;
height: 30px;
max-width: 100%;
max-height: 100%;
margin: auto;
overflow: hidden;
.w-path {
stroke-dasharray: 1,200;
stroke-dashoffset: 0;
-webkit-animation: dash 1.5s ease-in-out infinite,color 6s ease-in-out infinite;
animation: dash 1.5s ease-in-out infinite,color 6s ease-in-out infinite;
stroke-linecap: round;
}
}
@-webkit-keyframes rotate {
to {
-webkit-transform: rotate(1turn);
transform: rotate(1turn)
}
}
@keyframes rotate {
to {
-webkit-transform: rotate(1turn);
transform: rotate(1turn)
}
}
@-webkit-keyframes dash {
0% {
stroke-dasharray: 1,200;
stroke-dashoffset: 0
}
50% {
stroke-dasharray: 89,200;
stroke-dashoffset: -35
}
to {
stroke-dasharray: 89,200;
stroke-dashoffset: -124
}
}
@keyframes dash {
0% {
stroke-dasharray: 1,200;
stroke-dashoffset: 0
}
50% {
stroke-dasharray: 89,200;
stroke-dashoffset: -35
}
to {
stroke-dasharray: 89,200;
stroke-dashoffset: -124
}
}
@-webkit-keyframes color {
0%,to {
stroke: #d62d20
}
40% {
stroke: #0057e7
}
66% {
stroke: #008744
}
80%,90% {
stroke: #ffa700
}
}
@keyframes color {
0%,to {
stroke: #d62d20
}
40% {
stroke: #0057e7
}
66% {
stroke: #008744
}
80%,90% {
stroke: #ffa700
}
}
</style>
<script>
export default {
name: 'Loading',
}
</script>

View File

@ -0,0 +1,64 @@
<template>
<h1 v-if="false"><slot/></h1>
</template>
<script>
export default {
name: 'PageTitle',
props: {
title: {
type: [String, Number],
default: ''
},
},
data() {
return {
pagePath: ''
}
},
mounted () {
this.pagePath = this.$route.path;
this.updateTitle()
},
beforeUpdate () {
this.updateTitle()
},
activated() {
this.updateTitle()
},
methods: {
updateTitle () {
let pageTitle;
if (this.title) {
pageTitle = this.title;
} else {
let slots = this.$slots.default;
if (typeof slots === 'undefined' || slots.length < 1 || typeof slots[0].text !== 'string') {
return;
}
let {text} = slots[0];
pageTitle = text;
}
let {title} = document;
if (pageTitle !== title && this.pagePath === this.$route.path) this.setTile(pageTitle);
},
setTile(title) {
document.title = title;
let mobile = navigator.userAgent.toLowerCase();
if (/iphone|ipad|ipod/.test(mobile)) {
let iframe = document.createElement('iframe');
iframe.style.display = 'none';
let iframeCallback = function () {
setTimeout(function () {
iframe.removeEventListener('load', iframeCallback);
document.body.removeChild(iframe)
}, 0)
};
iframe.addEventListener('load', iframeCallback);
document.body.appendChild(iframe)
}
}
}
}
</script>

View File

@ -0,0 +1,32 @@
<template>
<div class="common-spinner">
<Loading class="common-circular"></Loading>
</div>
</template>
<style lang="scss" scoped>
.common-spinner {
display: none;
position: fixed;
z-index: 9999;
bottom: 20px;
right: 20px;
margin: 0 auto;
width: 30px;
height: 30px;
.common-circular {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 100%;
}
}
</style>
<script>
export default {
name: 'Spinner',
}
</script>

View File

@ -0,0 +1,545 @@
<template>
<div>
<div class="teditor-box" :class="[spinShow?'teditor-loadstyle':'teditor-loadedstyle']">
<textarea ref="myTextarea" :id="id">{{ content }}</textarea>
<Spin fix v-if="spinShow">
<Icon type="ios-loading" size=18 class="upload-control-spin-icon-load"></Icon>
<div>{{$L('加载组件中...')}}</div>
</Spin>
<ImgUpload
ref="myUpload"
class="upload-control"
type="callback"
:uploadIng.sync="uploadIng"
@on-callback="editorImage"
num="50"/>
<Upload
name="files"
ref="fileUpload"
class="upload-control"
:action="actionUrl"
:data="params"
multiple
:format="uploadFormat"
:show-upload-list="false"
:max-size="maxSize"
:on-progress="handleProgress"
:on-success="handleSuccess"
:on-error="handleError"
:on-format-error="handleFormatError"
:on-exceeded-size="handleMaxSize"
:before-upload="handleBeforeUpload"/>
</div>
<Spin fix v-if="uploadIng > 0">
<Icon type="ios-loading" class="upload-control-spin-icon-load"></Icon>
<div>{{$L('正在上传文件...')}}</div>
</Spin>
<Modal v-model="transfer" class="teditor-transfer" @on-visible-change="transferChange" class-name="simple-modal" footer-hide fullscreen transfer>
<div slot="close">
<Button type="primary" size="small">{{$L('完成')}}</Button>
</div>
<div class="teditor-transfer-body">
<textarea :id="'T_' + id">{{ content }}</textarea>
</div>
<Spin fix v-if="uploadIng > 0">
<Icon type="ios-loading" class="upload-control-spin-icon-load"></Icon>
<div>{{$L('正在上传文件...')}}</div>
</Spin>
</Modal>
</div>
</template>
<style lang="scss">
.teditor-box {
textarea {
opacity: 0;
}
.tox-tinymce {
box-shadow: none;
box-sizing: border-box;
border-color: #dddee1;
border-radius: 4px;
overflow: hidden;
.tox-statusbar {
span.tox-statusbar__branding {
a {
display: none;
}
}
}
}
}
.teditor-transfer {
background-color: #ffffff;
.tox-toolbar {
> div:last-child {
> button:last-child {
margin-right: 64px;
}
}
}
.ivu-modal-header {
display: none;
}
.ivu-modal-close {
top: 7px;
z-index: 2;
}
.teditor-transfer-body {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
textarea {
opacity: 0;
}
.tox-tinymce {
border: 0;
.tox-statusbar {
span.tox-statusbar__branding {
a {
display: none;
}
}
}
}
}
}
.tox {
&.tox-silver-sink {
z-index: 13000;
}
}
</style>
<style lang="scss" scoped>
.teditor-loadstyle {
width: 100%;
height: 180px;
overflow: hidden;
position: relative;
}
.teditor-loadedstyle {
width: 100%;
max-height: inherit;
overflow: inherit;
position: relative;
}
.upload-control {
display: none;
width: 0;
height: 0;
overflow: hidden;
}
</style>
<script>
import tinymce from 'tinymce/tinymce';
import ImgUpload from "./ImgUpload";
export default {
name: 'TEditor',
components: {ImgUpload},
props: {
id: {
type: String,
default: () => {
return "tinymce_" + Math.round(Math.random() * 10000);
}
},
value: {
default: ''
},
height: {
default: 360,
},
htmlClass: {
default: '',
type: String
},
plugins: {
type: Array,
default: () => {
return [
'advlist autolink lists link image charmap print preview hr anchor pagebreak imagetools',
'searchreplace visualblocks visualchars code',
'insertdatetime media nonbreaking save table contextmenu directionality',
'emoticons paste textcolor colorpicker imagetools codesample'
];
}
},
toolbar: {
type: String,
default: ' undo redo | styleselect | uploadImages | uploadFiles | bold italic underline forecolor backcolor | alignleft aligncenter alignright | bullist numlist outdent indent | link image emoticons media codesample | preview screenload',
},
other_options: {
type: Object,
default: () => {
return {};
}
},
readonly: {
type: Boolean,
default: false
}
},
data() {
return {
content: '',
editor: null,
editorT: null,
cTinyMce: null,
checkerTimeout: null,
isTyping: false,
spinShow: true,
transfer: false,
uploadIng: 0,
uploadFormat: ['jpg', 'jpeg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'esp', 'pdf', 'rar', 'zip', 'gz'],
actionUrl: $A.apiUrl('system/fileupload'),
params: { token: $A.getToken() },
maxSize: 10240
};
},
mounted() {
this.content = this.value;
this.init();
},
activated() {
this.content = this.value;
this.init();
},
deactivated() {
if (this.editor !== null) {
this.editor.destroy();
}
this.spinShow = true;
$A(this.$refs.myTextarea).show();
},
watch: {
value(newValue) {
if (newValue == null) {
newValue = "";
}
if (!this.isTyping) {
if (this.getEditor() !== null) {
this.getEditor().setContent(newValue);
} else{
this.content = newValue;
}
}
},
readonly(value) {
if (this.editor !== null) {
if (value) {
this.editor.setMode('readonly');
} else {
this.editor.setMode('design');
}
}
}
},
methods: {
init() {
this.$nextTick(() => {
tinymce.init(this.concatAssciativeArrays(this.options(false), this.other_options));
});
},
initTransfer() {
this.$nextTick(() => {
tinymce.init(this.concatAssciativeArrays(this.options(true), this.other_options));
});
},
options(isFull) {
return {
selector: (isFull ? '#T_' : '#') + this.id,
base_url: $A.serverUrl('js/build'),
language: "zh_CN",
toolbar: this.toolbar,
plugins: this.plugins,
save_onsavecallback: (e) => {
this.$emit('editorSave', e);
},
paste_data_images: true,
menu: {
view: {
title: 'View',
items: 'code | visualaid visualchars visualblocks | spellchecker | preview fullscreen screenload | showcomments'
},
insert: {
title: "Insert",
items: "image link media addcomment pageembed template codesample inserttable | charmap emoticons hr | pagebreak nonbreaking anchor toc | insertdatetime | uploadImages browseImages | uploadFiles"
}
},
codesample_languages: [
{text:"HTML/VUE/XML",value:"markup"},
{text:"JavaScript",value:"javascript"},
{text:"CSS",value:"css"},
{text:"PHP",value:"php"},
{text:"Ruby",value:"ruby"},
{text:"Python",value:"python"},
{text:"Java",value:"java"},
{text:"C",value:"c"},
{text:"C#",value:"csharp"},
{text:"C++",value:"cpp"}
],
height: isFull ? '100%' : ($A.rightExists(this.height, '%') ? this.height : ($A.runNum(this.height) || 360)),
resize: !isFull,
convert_urls:false,
toolbar_mode: 'sliding',
toolbar_drawer: 'floating',
setup: (editor) => {
editor.ui.registry.addMenuButton('uploadImages', {
text: this.$L('图片'),
tooltip: this.$L('上传/浏览 图片'),
fetch: (callback) => {
let items = [{
type: 'menuitem',
text: this.$L('上传图片'),
onAction: () => {
this.$refs.myUpload.handleClick();
}
}, {
type: 'menuitem',
text: this.$L('浏览图片'),
onAction: () => {
this.$refs.myUpload.browsePicture();
}
}];
callback(items);
}
});
editor.ui.registry.addMenuItem('uploadImages', {
text: this.$L('上传图片'),
onAction: () => {
this.$refs.myUpload.handleClick();
}
});
editor.ui.registry.addMenuItem('browseImages', {
text: this.$L('浏览图片'),
onAction: () => {
this.$refs.myUpload.browsePicture();
}
});
editor.ui.registry.addButton('uploadFiles', {
text: this.$L('文件'),
tooltip: this.$L('上传文件'),
onAction: () => {
if (this.handleBeforeUpload()) {
this.$refs.fileUpload.handleClick();
}
}
});
editor.ui.registry.addMenuItem('uploadFiles', {
text: this.$L('上传文件'),
onAction: () => {
if (this.handleBeforeUpload()) {
this.$refs.fileUpload.handleClick();
}
}
});
if (isFull) {
editor.ui.registry.addButton('screenload', {
icon: 'fullscreen',
tooltip: this.$L('退出全屏'),
onAction: () => {
this.closeFull();
}
});
editor.ui.registry.addMenuItem('screenload', {
text: this.$L('退出全屏'),
onAction: () => {
this.closeFull();
}
});
editor.on('Init', (e) => {
this.editorT = editor;
this.editorT.setContent(this.content);
if (this.readonly) {
this.editorT.setMode('readonly');
} else {
this.editorT.setMode('design');
}
});
}else{
editor.ui.registry.addButton('screenload', {
icon: 'fullscreen',
tooltip: this.$L('全屏'),
onAction: () => {
this.content = editor.getContent();
this.transfer = true;
this.initTransfer();
}
});
editor.ui.registry.addMenuItem('screenload', {
text: this.$L('全屏'),
onAction: () => {
this.content = editor.getContent();
this.transfer = true;
this.initTransfer();
}
});
editor.on('Init', (e) => {
this.spinShow = false;
this.editor = editor;
this.editor.setContent(this.content);
if (this.readonly) {
this.editor.setMode('readonly');
} else {
this.editor.setMode('design');
}
this.$emit('editorInit', this.editor);
});
editor.on('KeyUp', (e) => {
if (this.editor !== null) {
this.submitNewContent();
}
});
editor.on('Change', (e) => {
if (this.editor !== null) {
if (this.getContent() !== this.value) {
this.submitNewContent();
}
this.$emit('editorChange', e);
}
});
}
},
};
},
closeFull() {
this.content = this.getContent();
this.$emit('input', this.content);
this.transfer = false;
if (this.editorT != null) {
this.editorT.destroy();
this.editorT = null;
}
},
transferChange(visible) {
if (!visible && this.editorT != null) {
this.content = this.editorT.getContent();
this.$emit('input', this.content);
this.editorT.destroy();
this.editorT = null;
}
},
getEditor() {
return this.transfer ? this.editorT : this.editor;
},
concatAssciativeArrays(array1, array2) {
if (array2.length === 0) return array1;
if (array1.length === 0) return array2;
let dest = [];
for (let key in array1) {
if (array1.hasOwnProperty(key)) {
dest[key] = array1[key];
}
}
for (let key in array2) {
if (array2.hasOwnProperty(key)) {
dest[key] = array2[key];
}
}
return dest;
},
submitNewContent() {
this.isTyping = true;
if (this.checkerTimeout !== null) {
clearTimeout(this.checkerTimeout);
}
this.checkerTimeout = setTimeout(() => {
this.isTyping = false;
}, 300);
this.$emit('input', this.getContent());
},
insertContent(content) {
if (this.getEditor() !== null) {
this.getEditor().insertContent(content);
}else{
this.content+= content;
}
},
getContent() {
if (this.getEditor() === null) {
return "";
}
return this.getEditor().getContent();
},
insertImage(src) {
this.insertContent('<img src="' + src + '">');
},
editorImage(lists) {
for (let i = 0; i < lists.length; i++) {
let item = lists[i];
if (typeof item === 'object' && typeof item.url === "string") {
this.insertImage(item.url);
}
}
},
/********************文件上传部分************************/
handleProgress() {
//
this.uploadIng++;
},
handleSuccess(res, file) {
//
this.uploadIng--;
if (res.ret === 1) {
this.insertContent(`<a href="${res.data.url}" target="_blank">${res.data.name} (${$A.bytesToSize(res.data.size * 1024)})</a>`);
} else {
$A.noticeWarning({
title: this.$L('上传失败'),
desc: this.$L('文件 ' + file.name + ' 上传失败,' + res.msg)
});
}
},
handleError() {
//
this.uploadIng--;
},
handleFormatError(file) {
//
$A.noticeWarning({
title: this.$L('文件格式不正确'),
desc: this.$L('文件 ' + file.name + ' 格式不正确,仅支持上传:' + this.uploadFormat.join(','))
});
},
handleMaxSize(file) {
//
$A.noticeWarning({
title: this.$L('超出文件大小限制'),
desc: this.$L('文件 ' + file.name + ' 太大,不能超过:' + $A.bytesToSize(this.maxSize * 1024))
});
},
handleBeforeUpload() {
//
this.params = {
token: $A.getToken(),
};
return true;
},
}
}
</script>

View File

@ -0,0 +1,84 @@
<template>
<div class="td-action" :style="tdStyle">
<div ref="action" @mouseenter="handleIn" class="td-action-container" v-resize="onResize"><slot></slot></div>
</div>
</template>
<script>
export default {
name: 'TableAction',
props: {
column: {
type: Object,
default: () => {
return {};
}
},
minWidth: {
type: Number,
default: 80
},
align: {
type: String,
default: ''
},
},
data() {
return {
width: 0,
height: 0,
}
},
mounted() {
this.onUpdate();
},
activated() {
this.onUpdate();
},
beforeUpdate() {
this.onUpdate();
},
computed: {
tdStyle() {
const style = {};
const {align} = this;
if (['left', 'center', 'right'].includes(align.toLowerCase())) {
style.textAlign = align;
}
return style;
}
},
methods: {
handleIn() {
if (this.$refs.action.offsetWidth != this.width) {
this.onUpdate();
}
},
onUpdate() {
this.onResize({
width: this.$refs.action.offsetWidth,
height: this.$refs.action.offsetHeight,
})
},
onResize({ width, height }) {
$A(".ivu-table-column-" + this.column.__id).each((index, el) => {
let action = $A(el).find(".td-action-container")
if (action.length > 0) {
width = Math.max(width, action[0].offsetWidth)
height = Math.max(height, action[0].offsetHeight)
}
});
this.width = width;
this.height = height;
let newWidth = Math.max(this.minWidth, this.width + 26);
if (this.column.minWidth) {
newWidth = Math.max(this.column.minWidth, newWidth);
}
if (this.column.maxWidth) {
newWidth = Math.min(this.column.maxWidth, newWidth);
}
newWidth != this.column.width && this.$set(this.column, 'width', newWidth)
}
}
}
</script>

View File

@ -0,0 +1,222 @@
<template>
<div class="tags-wrap" @paste="pasteText($event)" @click="clickWrap">
<div class="tags-item" v-for="(text, index) in disSource">
<span class="tags-content" @click.stop="">{{text}}</span><span class="tags-del" @click.stop="delTag(index)">&times;</span>
</div>
<textarea ref="myTextarea" class="tags-input" :style="{ minWidth: minWidth + 'px' }" :placeholder="tis || placeholder"
v-model="content" @keydown.enter="downEnter($event)" @keyup="addTag($event, content)"
@blur="addTag(false, content)" @keydown.delete="delTag(false)" :disabled="disabled" :readonly="readonly"></textarea>
<span ref="myPlaceholder" v-if="showPlaceholder || tis !== ''" class="tags-placeholder">{{tis || placeholder}}</span>
</div>
</template>
<style lang="scss">
.tags-wrap {
display: inline-block;
width: 100%;
min-height: 32px;
padding: 2px 7px;
border: 1px solid #dddee1;
border-radius: 4px;
color: #495060;
background: #fff;
position: relative;
cursor: text;
vertical-align: middle;
line-height: normal;
-webkit-transition: border .2s ease-in-out, background .2s ease-in-out, -webkit-box-shadow .2s ease-in-out;
transition: border .2s ease-in-out, background .2s ease-in-out, -webkit-box-shadow .2s ease-in-out;
.tags-item, .tags-input {
position: relative;
float: left;
color: #495060;
background-color: #f1f8ff;
border-radius: 3px;
line-height: 22px;
margin: 2px 6px 2px 0;
padding: 0 20px 0 6px;
.tags-content {
line-height: 22px;
}
.tags-del {
width: 20px;
height: 22px;
text-align: center;
cursor: pointer;
position: absolute;
top: -1px;
right: 0;
}
}
.tags-input {
max-width: 80%;
padding: 0;
background-color: inherit;
border: none;
color: inherit;
height: 22px;
line-height: 22px;
-webkit-appearance: none;
outline: none;
resize: none;
overflow: hidden;
}
.tags-input::placeholder {
color: #bbbbbb;
}
.tags-placeholder {
position: absolute;
left: 0;
top: 0;
z-index: -1;
color: #ffffff00;
}
}
.tags-wrap::after {
content: "";
display: block;
height: 0;
clear: both;
}
</style>
<script>
export default {
name: 'TagInput',
props: {
value: {
default: ''
},
cut: {
default: ','
},
disabled: {
type: Boolean,
default: false
},
readonly: {
type: Boolean,
default: false
},
placeholder: {
default: ''
},
max: {
default: 0
},
},
data() {
let disSource = [];
this.value.split(",").forEach((item) => {
if (item) {
disSource.push(item)
}
});
return {
minWidth: 80,
tis: '',
tisTimeout: null,
showPlaceholder: true,
content: '',
disSource: disSource,
}
},
mounted() {
this.wayMinWidth();
},
watch: {
placeholder() {
this.wayMinWidth();
},
value (val) {
let disSource = [];
if ($A.count(val) > 0) {
val.split(",").forEach((item) => {
if (item) {
disSource.push(item)
}
});
}
this.disSource = disSource;
},
disSource(val) {
let temp = '';
val.forEach((item) => {
if (temp != '') {
temp += this.cut;
}
temp += item;
});
this.$emit('input', temp);
}
},
methods: {
wayMinWidth() {
this.showPlaceholder = true;
this.$nextTick(() => {
if (this.$refs.myPlaceholder) {
this.minWidth = Math.max(this.minWidth, this.$refs.myPlaceholder.offsetWidth);
}
setTimeout(() => {
try {
this.minWidth = Math.max(this.minWidth, this.$refs.myPlaceholder.offsetWidth);
this.showPlaceholder = false;
}catch (e) { }
if (!$A(this.$refs.myPlaceholder).is(":visible")) {
this.wayMinWidth();
}
}, 500);
});
},
pasteText(e) {
e.preventDefault();
let content = (e.clipboardData || window.clipboardData).getData('text');
this.addTag(false, content)
},
clickWrap() {
this.$refs.myTextarea.focus();
},
downEnter(e) {
e.preventDefault();
},
addTag(e, content) {
if (e.keyCode === 13 || e === false) {
if (content.trim() != '' && this.disSource.indexOf(content.trim()) === -1) {
this.disSource.push(content.trim());
}
this.content = '';
} else {
if (this.max > 0 && this.disSource.length >= this.max) {
this.content = '';
this.tis = '最多只能添加' + this.max + '个';
clearInterval(this.tisTimeout);
this.tisTimeout = setTimeout(() => { this.tis = ''; }, 2000);
return;
}
let temp = content.trim();
let cutPos = temp.length - this.cut.length;
if (temp != '' && temp.substring(cutPos) === this.cut) {
temp = temp.substring(0, cutPos);
if (temp.trim() != '' && this.disSource.indexOf(temp.trim()) === -1) {
this.disSource.push(temp.trim());
}
this.content = '';
}
}
},
delTag(index) {
if (index === false) {
if (this.content !== '') {
return;
}
index = this.disSource.length - 1;
}
this.disSource.splice(index, 1)
}
}
}
</script>

View File

@ -0,0 +1,21 @@
export default {
bind (el, binding, vnode) {
function documentHandler (e) {
if (el.contains(e.target)) {
return false;
}
if (binding.expression) {
binding.value(e);
}
}
el.__vueClickOutside__ = documentHandler;
document.addEventListener('click', documentHandler);
},
update () {
},
unbind (el, binding) {
document.removeEventListener('click', el.__vueClickOutside__);
delete el.__vueClickOutside__;
}
};

View File

@ -0,0 +1,108 @@
/**
* https://github.com/freeze-component/vue-popper
* */
import Vue from 'vue';
const isServer = Vue.prototype.$isServer;
const Popper = isServer ? function() {} : require('popper.js/dist/umd/popper.js'); // eslint-disable-line
export default {
props: {
placement: {
type: String,
default: 'bottom'
},
boundariesPadding: {
type: Number,
default: 5
},
reference: Object,
popper: Object,
offset: {
default: 0
},
transition: String,
options: {
type: Object,
default () {
return {
modifiers: {
computeStyle:{
gpuAcceleration: false,
},
preventOverflow :{
boundariesElement: 'window'
}
}
};
}
}
},
data () {
return {
visible: false
};
},
watch: {
visible(val) {
if (val) {
if (this.handleIndexIncrease) this.handleIndexIncrease(); // just use for Poptip
this.updatePopper();
this.$emit('on-popper-show');
} else {
this.$emit('on-popper-hide');
}
}
},
methods: {
createPopper() {
if (isServer) return;
if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.placement)) {
return;
}
const options = this.options;
const popper = this.popper || this.$refs.popper;
const reference = this.reference || this.$refs.reference;
if (!popper || !reference) return;
if (this.popperJS && this.popperJS.hasOwnProperty('destroy')) {
this.popperJS.destroy();
}
options.placement = this.placement;
if (!options.modifiers.offset) {
options.modifiers.offset = {};
}
options.modifiers.offset.offset = this.offset;
options.onCreate =()=>{
this.$nextTick(this.updatePopper);
this.$emit('created', this);
};
this.popperJS = new Popper(reference, popper, options);
},
updatePopper() {
if (isServer) return;
this.popperJS ? this.popperJS.update() : this.createPopper();
},
doDestroy() {
if (isServer) return;
if (this.visible) return;
this.popperJS.destroy();
this.popperJS = null;
}
},
updated (){
this.$nextTick(()=>this.updatePopper());
},
beforeDestroy() {
if (isServer) return;
if (this.popperJS) {
this.popperJS.destroy();
}
}
};

View File

@ -0,0 +1,77 @@
// Thanks to: https://github.com/airyland/vux/blob/v2/src/directives/transfer-dom/index.js
// Thanks to: https://github.com/calebroseland/vue-dom-portal
/**
* Get target DOM Node
* @param {(Node|string|Boolean)} [node=document.body] DOM Node, CSS selector, or Boolean
* @return {Node} The target that the el will be appended to
*/
function getTarget (node) {
if (node === void 0) {
node = document.body
}
if (node === true) { return document.body }
return node instanceof window.Node ? node : document.querySelector(node)
}
const directive = {
inserted (el, { value }, vnode) {
if ( el.dataset && el.dataset.transfer !== 'true') return false;
el.className = el.className ? el.className + ' v-transfer-dom' : 'v-transfer-dom';
const parentNode = el.parentNode;
if (!parentNode) return;
const home = document.createComment('');
let hasMovedOut = false;
if (value !== false) {
parentNode.replaceChild(home, el); // moving out, el is no longer in the document
getTarget(value).appendChild(el); // moving into new place
hasMovedOut = true
}
if (!el.__transferDomData) {
el.__transferDomData = {
parentNode: parentNode,
home: home,
target: getTarget(value),
hasMovedOut: hasMovedOut
}
}
},
componentUpdated (el, { value }) {
if ( el.dataset && el.dataset.transfer !== 'true') return false;
// need to make sure children are done updating (vs. `update`)
const ref$1 = el.__transferDomData;
if (!ref$1) return;
// homes.get(el)
const parentNode = ref$1.parentNode;
const home = ref$1.home;
const hasMovedOut = ref$1.hasMovedOut; // recall where home is
if (!hasMovedOut && value) {
// remove from document and leave placeholder
parentNode.replaceChild(home, el);
// append to target
getTarget(value).appendChild(el);
el.__transferDomData = Object.assign({}, el.__transferDomData, { hasMovedOut: true, target: getTarget(value) });
} else if (hasMovedOut && value === false) {
// previously moved, coming back home
parentNode.replaceChild(el, home);
el.__transferDomData = Object.assign({}, el.__transferDomData, { hasMovedOut: false, target: getTarget(value) });
} else if (value) {
// already moved, going somewhere else
getTarget(value).appendChild(el);
}
},
unbind (el) {
if (el.dataset && el.dataset.transfer !== 'true') return false;
el.className = el.className.replace('v-transfer-dom', '');
const ref$1 = el.__transferDomData;
if (!ref$1) return;
if (el.__transferDomData.hasMovedOut === true) {
el.__transferDomData.parentNode && el.__transferDomData.parentNode.appendChild(el)
}
el.__transferDomData = null
}
};
export default directive;

View File

@ -0,0 +1,219 @@
const CLICK = 'click';
const captureInstances = Object.create(null);
const nonCaptureInstances = Object.create(null);
const instancesList = [captureInstances, nonCaptureInstances];
/**
* The common event handler for bot capture and non-capture events.
*
* @param {!Object} context - The event context.
* @param {!Object} instances - The capture or non-capture registered instances.
* @param {Event} event - The event object.
* @returns {undefined} Default.
*/
const commonHandler = function _onCommonEvent(context, instances, event) {
const {target} = event;
const itemIteratee = function _itemIteratee(item) {
const {el} = item;
if (el !== target && !el.contains(target)) {
const {binding} = item;
if (binding.modifiers.stop) {
event.stopPropagation();
}
if (binding.modifiers.prevent) {
event.preventDefault();
}
binding.value.call(context, event);
}
};
const keysIteratee = function _keysIteratee(eventName) {
return instances[eventName].forEach(itemIteratee);
};
Object.keys(instances).forEach(keysIteratee);
};
/**
* Event handler for capture events.
*
* @param {Event} event - The event object.
*/
const captureEventHandler = function onCaptureEvent(event) {
/* eslint-disable-next-line babel/no-invalid-this */
commonHandler(this, captureInstances, event);
};
/**
* Event handler for non-capture events.
*
* @param {Event} event - The event object.
*/
const nonCaptureEventHandler = function onNonCaptureEvent(event) {
/* eslint-disable-next-line babel/no-invalid-this */
commonHandler(this, nonCaptureInstances, event);
};
/**
* Get the correct event handler: Capture or non-capture.
*
* @param {boolean} useCapture - Indicate which handler to use; 'true' to use
* capture handler or 'false' for non-capture.
* @returns {Function} - The event handler.
*/
const getEventHandler = function _getEventHandler(useCapture) {
return useCapture ? captureEventHandler : nonCaptureEventHandler;
};
/**
* The directive definition.
* {@link https://vuejs.org/v2/guide/custom-directive.html|Custom directive}
*
* @namespace
* @property {!Object} $_captureInstances - Registered capture instances.
* @property {!Object} $_nonCaptureInstances - Registered non-capture instances.
* @property {Function} $_onCaptureEvent - Event handler for capture events.
* @property {Function} $_onNonCaptureEvent - Event handler for non-capture events.
* @property {Function} bind - Called only once, when the directive is first
* bound to the element.
* @property {Function} unbind - Called only once, when the directive is unbound
* from the element.
* @property {string} version - The version number of this release.
*/
export const directive = Object.defineProperties(
{},
{
$_captureInstances: {
value: captureInstances,
},
$_nonCaptureInstances: {
value: nonCaptureInstances,
},
$_onCaptureEvent: {
value: captureEventHandler,
},
$_onNonCaptureEvent: {
value: nonCaptureEventHandler,
},
/**
* 注意这里的 arg 修改为 capture这样可以动态设置原先的事件作为 modifiers
* */
bind: {
value: function bind(el, binding) {
if (typeof binding.value !== 'function') {
throw new TypeError('Binding value must be a function.');
}
let eventType;
const modifiers = binding.modifiers;
if (modifiers.click) eventType = 'click';
else if (modifiers.mousedown) eventType = 'mousedown';
else if (modifiers.touchstart) eventType = 'touchstart';
else eventType = CLICK;
const useCapture = binding.arg;
const normalisedBinding = {
...binding,
...{
modifiers: {
...{
capture: false,
prevent: false,
stop: false,
},
...binding.modifiers,
},
},
};
const instances = useCapture ? captureInstances : nonCaptureInstances;
if (!Array.isArray(instances[eventType])) {
instances[eventType] = [];
}
if (instances[eventType].push({el, binding: normalisedBinding}) === 1) {
if (typeof document === 'object' && document) {
document.addEventListener(
eventType,
getEventHandler(useCapture),
useCapture,
);
}
}
},
},
unbind: {
value: function unbind(el) {
const compareElements = function _compareElements(item) {
return item.el !== el;
};
const instancesIteratee = function _instancesIteratee(instances) {
const instanceKeys = Object.keys(instances);
if (instanceKeys.length) {
const useCapture = instances === captureInstances;
const keysIteratee = function _keysIteratee(eventName) {
const newInstance = instances[eventName].filter(compareElements);
if (newInstance.length) {
instances[eventName] = newInstance;
} else {
if (typeof document === 'object' && document) {
document.removeEventListener(
eventName,
getEventHandler(useCapture),
useCapture,
);
}
delete instances[eventName];
}
};
instanceKeys.forEach(keysIteratee);
}
};
instancesList.forEach(instancesIteratee);
},
},
/* Note: This needs to be manually updated to match package.json. */
version: {
enumerable: true,
value: '3.7.1',
},
},
);
/**
* @typedef {Function} Vue - The constructor.
* @property {Function} directive - You can register a global custom directive
* with the Vue.directive() method, passing in a directiveID followed by a
* definition object.
*/
/**
* A Vue.js plugin should expose an install method. The method will be called
* with the Vue constructor as the first argument, along with possible options.
* {@link https://vuejs.org/v2/guide/plugins.html#Writing-a-Plugin|Writing a plugin}.
*
* @param {Vue} Vue - The Vue function.
*/
export function install(Vue) {
Vue.directive('click-outside', directive);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,233 @@
const languageTypeLists = {
"EN": "English",
"KM": "ភាសាខ្មែរ",
"TH": "ภาษาไทย",
"KO": "한국어",
"JA": "日本語",
"CN": "中文-简体",
"TC": "中文-繁體",
};
const languageCachesObjects = {};
const languageListenerObjects = [];
export default {
install(Vue) {
Vue.mixin({
data() {
return {
languageInit: false,
languageData: [],
languageType: window.localStorage['__language:type__'] || this.__getNavigatorLanguage(),
languageList: languageTypeLists,
}
},
watch: {
languageType: {
handler(type) {
if (type && typeof this.initLanguage === "function") {
this.initLanguage();
}
},
immediate: true
},
},
methods: {
/**
* 获取浏览器默认语言
* @returns {string}
* @private
*/
__getNavigatorLanguage() {
let lang = 'EN';
let navLang = (navigator.language || navigator.userLanguage + "").toUpperCase();
switch (navLang) {
case "EN":
case "KM":
case "TH":
case "KO":
case "JA":
lang = navLang
break;
case "ZH-CN":
case "ZH":
lang = 'CN'
break;
case "ZH-TW":
case "ZH-HK":
lang = 'TC'
break;
}
return window.localStorage['__language:type__'] = lang;
},
/**
* 初始化语言数据
* @private
*/
__initLanguageData() {
if (this.languageInit === false) {
this.languageInit = true;
//
this.addLanguageData(require("../../../lang/language.js").default);
//
languageListenerObjects.push((lang) => {
this.languageType = lang;
});
}
},
/**
* 是否数组
* @param obj
* @returns {boolean}
* @private
*/
__isArray(obj) {
return typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == '[object array]' && typeof obj.length == "number";
},
/**
* 监听语言变化
* @param callback
*/
setLanguageListener(callback) {
if (typeof callback === 'function') {
languageListenerObjects.push((lang) => {
callback(lang);
});
}
},
/**
* 语言包数据
* @param data
*/
addLanguageData(data) {
if (!this.__isArray(data)) {
return;
}
this.__initLanguageData();
this.languageData.push(...data);
},
/**
* 变化语言
* @param language
*/
setLanguage(language) {
this.__initLanguageData();
setTimeout(() => {
window.localStorage['__language:type__'] = language;
languageListenerObjects.forEach((call) => {
if (typeof call === 'function') {
call(language);
}
});
}, 10)
},
/**
* 获取语言
* @returns {*}
*/
getLanguage() {
this.__initLanguageData();
return this.languageType;
},
/**
* 替换%遍历
* @param text
* @param objects
*/
replaceArgumentsLanguage(text, objects) {
let j = 1;
while (text.indexOf("%") !== -1) {
if (typeof objects[j] === "object") {
text = text.replace("%", "");
} else {
text = text.replace("%", objects[j]);
}
j++;
}
return text;
},
/**
* 译文转义
* @param val
* @returns {string|*}
*/
replaceEscape(val) {
if (!val || val == '') {
return '';
}
return val.replace(//g, '%').replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
},
/**
* 显示语言
* @return {string}
*/
$L(text) {
if (typeof arguments[1] !== "undefined") {
return this.$L(this.replaceArgumentsLanguage(text, arguments));
}
if (typeof text !== "string" || !text) {
return text;
}
this.__initLanguageData();
//
if (typeof languageCachesObjects[text] === "undefined") {
let tmpRege = null;
let tmpData = this.languageData.find((obj) => {
return Object.values(obj).find((val) => {
tmpRege = new RegExp("^" + this.replaceEscape(val).replace(/%/g, "(.*?)") + "$", "g");
return !!text.match(tmpRege);
})
});
languageCachesObjects[text] = {
rege: tmpRege,
data: tmpData,
};
}
const {rege, data} = languageCachesObjects[text];
if (data
&& typeof data === "object"
&& typeof data[this.languageType] !== "undefined"
&& data[this.languageType]) {
let index = 0;
let value = data[this.languageType];
value = value.replace(/%/g, function () {
return "$" + (++index);
});
return text.replace(rege, value);
}
//
if (this.languageType == "CN") {
try {
let key = '__language:Undefined__';
let languageTmp = JSON.parse(window.localStorage[key] || '[]');
if (!this.__isArray(languageTmp)) {
languageTmp = [];
}
let tmpRege = null;
let tmpData = languageTmp.find((val) => {
tmpRege = new RegExp("^" + val.replace(/%/g, "(.*?)") + "$", "g");
return !!text.match(tmpRege);
});
if (!tmpData) {
languageTmp.push(text);
window.localStorage[key] = JSON.stringify(languageTmp);
}
} catch (e) { }
}
//
return text;
}
}
});
}
}

View File

@ -0,0 +1,55 @@
export default {
install(Vue) {
Vue.mixin({
data() {
return {
mixinId: 0,
//用户信息
userLogin: false,
userInfo: {},
userName: '',
userId: 0,
//浏览器宽度≤768返回true
windowMax768: window.innerWidth <= 768,
}
},
mounted() {
if (typeof window.__mixinId != "number") window.__mixinId = 0;
this.mixinId = window.__mixinId++;
//
this.userLogin = $A.getToken() !== false;
this.userInfo = $A.getUserInfo();
this.userName = this.userInfo.username || '';
this.userId = parseInt(this.userInfo.userid);
$A.setOnUserInfoListener('mixins_' + this.mixinId, (data, isLogin) => {
this.userLogin = isLogin;
this.userInfo = data;
this.userName = this.userInfo.username || '';
this.userId = parseInt(this.userInfo.userid);
});
//
window.addEventListener('resize', this.windowMax768Listener);
},
beforeDestroy() {
$A.removeUserInfoListener('mixins_' + this.mixinId);
window.removeEventListener('resize', this.windowMax768Listener);
},
methods: {
isArray(obj) {
return typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == '[object array]' && typeof obj.length == "number";
},
isJson(obj) {
return typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && typeof obj.length == "undefined";
},
windowMax768Listener() {
this.windowMax768 = window.innerWidth <= 768
}
}
});
}
}

1027
resources/js/main.js Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
<template>
<div class="page-404">
<div class="flex-center position-ref full-height">
<div class="code">404</div>
<div class="message">Not Found</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.page-404 {
background-color: #fff;
color: #636b6f;
font-weight: 400;
height: 100vh;
margin: 0;
.full-height {
height: 100vh;
}
.flex-center {
align-items: center;
display: flex;
justify-content: center;
}
.position-ref {
position: relative;
}
.code {
border-right: 2px solid;
font-size: 26px;
padding: 0 15px 0 15px;
text-align: center;
}
.message {
font-size: 18px;
padding: 10px;
text-align: center;
}
}
</style>

View File

@ -0,0 +1,14 @@
<template>
<div>dashboard</div>
</template>
<script>
export default {
data() {
return {}
},
mounted() {
},
}
</script>

View File

@ -0,0 +1,21 @@
<template>
<div></div>
</template>
<script>
export default {
data() {
return {}
},
mounted() {
if (this.usrLogin) {
this.goForward({path: '/dashboard'}, true);
} else {
this.goForward({path: '/login'}, true);
}
},
deactivated() {
this.$destroy()
}
}
</script>

View File

@ -0,0 +1,25 @@
<template>
<div class="page-login">
<PageTitle>{{$L('登录页面')}}</PageTitle>
</div>
</template>
<style lang="scss" scoped>
.page-login {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
}
</style>
<script>
export default {
data() {
return {}
}
}
</script>

22
resources/js/routes.js Executable file
View File

@ -0,0 +1,22 @@
export default [
{
path: '/',
name: 'index',
component: resolve => require(['./pages/index.vue'], resolve)
},
{
path: '*',
name: '404',
component: resolve => require(['./pages/404.vue'], resolve),
},
{
path: '/login',
name: 'login',
component: resolve => require(['./pages/login/index.vue'], resolve),
},
{
path: '/dashboard',
name: 'dashboard',
component: resolve => require(['./pages/dashboard/index.vue'], resolve),
},
]

View File

@ -0,0 +1,2 @@
exports.default = [
];

View File

@ -1,876 +0,0 @@
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.toMarkdown = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
/*
* to-markdown - https://github.com/LCTT/LCTT-Helper/blob/master/js/to-markdown.js
*
* Copyright 2011+, Dom Christie
* Licenced under the MIT licence
*
*/
'use strict'
var toMarkdown
var converters
var mdConverters = require('./lib/md-converters')
var gfmConverters = require('./lib/gfm-converters')
var HtmlParser = require('./lib/html-parser')
var collapse = require('collapse-whitespace')
/*
* Utilities
*/
var blocks = ['address', 'article', 'aside', 'audio', 'blockquote', 'body',
'canvas', 'center', 'dd', 'dir', 'div', 'dl', 'dt', 'fieldset', 'figcaption',
'figure', 'footer', 'form', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7',
'header', 'hgroup', 'hr', 'html', 'isindex', 'li', 'main', 'menu', 'nav',
'noframes', 'noscript', 'ol', 'output', 'p', 'pre', 'section', 'table',
'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'ul'
]
function isBlock (node) {
return blocks.indexOf(node.nodeName.toLowerCase()) !== -1
}
var voids = [
'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input',
'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'
]
function isVoid (node) {
return voids.indexOf(node.nodeName.toLowerCase()) !== -1
}
function htmlToDom (string) {
var tree = new HtmlParser().parseFromString(string, 'text/html')
collapse(tree.documentElement, isBlock)
return tree
}
/*
* Flattens DOM tree into single array
*/
function bfsOrder (node) {
var inqueue = [node]
var outqueue = []
var elem
var children
var i
while (inqueue.length > 0) {
elem = inqueue.shift()
outqueue.push(elem)
children = elem.childNodes
for (i = children.length - 1; i >= 0; i--) {
if (children[i].nodeType === 1) inqueue.push(children[i])
}
}
outqueue.shift()
return outqueue
}
/*
* Contructs a Markdown string of replacement text for a given node
*/
function getContent (node) {
var text = ''
for (var i = 0; i < node.childNodes.length; i++) {
if (node.childNodes[i].nodeType === 1) {
text += node.childNodes[i]._replacement
} else if (node.childNodes[i].nodeType === 3) {
text += node.childNodes[i].data
} else continue
}
return text
}
/*
* Returns the HTML string of an element with its contents converted
*/
function outer (node, content) {
return node.cloneNode(false).outerHTML.replace('><', '>' + content + '<')
}
function canConvert (node, filter) {
if (typeof filter === 'string') {
return filter === node.nodeName.toLowerCase()
}
if (Array.isArray(filter)) {
return filter.indexOf(node.nodeName.toLowerCase()) !== -1
} else if (typeof filter === 'function') {
return filter.call(toMarkdown, node)
} else {
throw new TypeError('`filter` needs to be a string, array, or function')
}
}
function isFlankedByWhitespace (side, node) {
var sibling
var regExp
var isFlanked
if (side === 'left') {
sibling = node.previousSibling
regExp = / $/
} else {
sibling = node.nextSibling
regExp = /^ /
}
if (sibling) {
if (sibling.nodeType === 3) {
isFlanked = regExp.test(sibling.nodeValue)
} else if (sibling.nodeType === 1 && !isBlock(sibling)) {
isFlanked = regExp.test(sibling.textContent)
}
}
return isFlanked
}
function flankingWhitespace (node, content) {
var leading = ''
var trailing = ''
if (!isBlock(node)) {
var hasLeading = /^[ \r\n\t]/.test(content)
var hasTrailing = /[ \r\n\t]$/.test(content)
if (hasLeading && !isFlankedByWhitespace('left', node)) {
leading = ' '
}
if (hasTrailing && !isFlankedByWhitespace('right', node)) {
trailing = ' '
}
}
return { leading: leading, trailing: trailing }
}
/*
* Finds a Markdown converter, gets the replacement, and sets it on
* `_replacement`
*/
function process (node) {
var replacement
var content = getContent(node)
// Remove blank nodes
if (!isVoid(node) && !/A|TH|TD/.test(node.nodeName) && /^\s*$/i.test(content)) {
node._replacement = ''
return
}
for (var i = 0; i < converters.length; i++) {
var converter = converters[i]
if (canConvert(node, converter.filter)) {
if (typeof converter.replacement !== 'function') {
throw new TypeError(
'`replacement` needs to be a function that returns a string'
)
}
var whitespace = flankingWhitespace(node, content)
if (whitespace.leading || whitespace.trailing) {
content = content.trim()
}
replacement = whitespace.leading +
converter.replacement.call(toMarkdown, content, node) +
whitespace.trailing
break
}
}
node._replacement = replacement
}
toMarkdown = function (input, options) {
options = options || {}
if (typeof input !== 'string') {
throw new TypeError(input + ' is not a string')
}
if (input === '') {
return ''
}
// Escape potential ol triggers
input = input.replace(/(\d+)\. /g, '$1\\. ')
var clone = htmlToDom(input).body
var nodes = bfsOrder(clone)
var output
converters = mdConverters.slice(0)
if (options.gfm) {
converters = gfmConverters.concat(converters)
}
if (options.converters) {
converters = options.converters.concat(converters)
}
// Process through nodes in reverse (so deepest child elements are first).
for (var i = nodes.length - 1; i >= 0; i--) {
process(nodes[i])
}
output = getContent(clone)
return output.replace(/^[\t\r\n]+|[\t\r\n\s]+$/g, '')
.replace(/\n\s+\n/g, '\n\n')
.replace(/\n{3,}/g, '\n\n')
}
toMarkdown.isBlock = isBlock
toMarkdown.isVoid = isVoid
toMarkdown.outer = outer
module.exports = toMarkdown
},{"./lib/gfm-converters":2,"./lib/html-parser":3,"./lib/md-converters":4,"collapse-whitespace":6}],2:[function(require,module,exports){
'use strict'
function cell (content, node) {
var index = Array.prototype.indexOf.call(node.parentNode.childNodes, node)
var prefix = ' '
if (index === 0) prefix = '| '
return prefix + content + ' |'
}
var highlightRegEx = /highlight highlight-(\S+)/
module.exports = [
{
filter: 'br',
replacement: function () {
return '\n'
}
},
{
filter: ['del', 's', 'strike'],
replacement: function (content) {
return '~~' + content + '~~'
}
},
{
filter: function (node) {
return node.type === 'checkbox' && node.parentNode.nodeName === 'LI'
},
replacement: function (content, node) {
return (node.checked ? '[x]' : '[ ]') + ' '
}
},
{
filter: ['th', 'td'],
replacement: function (content, node) {
return cell(content, node)
}
},
{
filter: 'tr',
replacement: function (content, node) {
var borderCells = ''
var alignMap = { left: ':--', right: '--:', center: ':-:' }
if (node.parentNode.nodeName === 'THEAD') {
for (var i = 0; i < node.childNodes.length; i++) {
var align = node.childNodes[i].attributes.align
var border = '---'
if (align) border = alignMap[align.value] || border
borderCells += cell(border, node.childNodes[i])
}
}
return '\n' + content + (borderCells ? '\n' + borderCells : '')
}
},
{
filter: 'table',
replacement: function (content) {
return '\n\n' + content + '\n\n'
}
},
{
filter: ['thead', 'tbody', 'tfoot'],
replacement: function (content) {
return content
}
},
// Fenced code blocks
{
filter: function (node) {
return node.nodeName === 'PRE' &&
node.firstChild &&
node.firstChild.nodeName === 'CODE'
},
replacement: function (content, node) {
return '\n\n```\n' + node.firstChild.textContent + '\n```\n\n'
}
},
// Syntax-highlighted code blocks
{
filter: function (node) {
return node.nodeName === 'PRE' &&
node.parentNode.nodeName === 'DIV' &&
highlightRegEx.test(node.parentNode.className)
},
replacement: function (content, node) {
var language = node.parentNode.className.match(highlightRegEx)[1]
return '\n\n```' + language + '\n' + node.textContent + '\n```\n\n'
}
},
{
filter: function (node) {
return node.nodeName === 'DIV' &&
highlightRegEx.test(node.className)
},
replacement: function (content) {
return '\n\n' + content + '\n\n'
}
}
]
},{}],3:[function(require,module,exports){
/*
* Set up window for Node.js
*/
var _window = (typeof window !== 'undefined' ? window : this)
/*
* Parsing HTML strings
*/
function canParseHtmlNatively () {
var Parser = _window.DOMParser
var canParse = false
// Adapted from https://gist.github.com/1129031
// Firefox/Opera/IE throw errors on unsupported types
try {
// WebKit returns null on unsupported types
if (new Parser().parseFromString('', 'text/html')) {
canParse = true
}
} catch (e) {}
return canParse
}
function createHtmlParser () {
var Parser = function () {}
// For Node.js environments
if (typeof document === 'undefined') {
var jsdom = require('jsdom')
Parser.prototype.parseFromString = function (string) {
return jsdom.jsdom(string, {
features: {
FetchExternalResources: [],
ProcessExternalResources: false
}
})
}
} else {
if (!shouldUseActiveX()) {
Parser.prototype.parseFromString = function (string) {
var doc = document.implementation.createHTMLDocument('')
doc.open()
doc.write(string)
doc.close()
return doc
}
} else {
Parser.prototype.parseFromString = function (string) {
var doc = new window.ActiveXObject('htmlfile')
doc.designMode = 'on' // disable on-page scripts
doc.open()
doc.write(string)
doc.close()
return doc
}
}
}
return Parser
}
function shouldUseActiveX () {
var useActiveX = false
try {
document.implementation.createHTMLDocument('').open()
} catch (e) {
if (window.ActiveXObject) useActiveX = true
}
return useActiveX
}
module.exports = canParseHtmlNatively() ? _window.DOMParser : createHtmlParser()
},{"jsdom":8}],4:[function(require,module,exports){
'use strict'
module.exports = [
// P标签处理
{
filter: 'p',
replacement: function (content, node) {
var attrClass = node.getAttribute('class') || ''
if (attrClass === 'command') {
if (!content.endsWith('\n')) {
content += '\n'
}
return '\n```\n' + content + '```\n'
} else {
return '\n\n' + content + '\n\n'
}
}
},
// BR 标签处理
{
filter: 'br',
replacement: function () {
return ' \n'
}
},
// H1 处理
{
filter: 'h1',
replacement: function (content, node) {
if (typeof titleLock === "undefined") {
var titleLock = false;
}
if (!titleLock) {
titleLock = true;
return content + "\n" + "=".repeat(60);
}
else {
return '\n\n' + '# ' + content + '\n\n'
}
}
},
// H2-H7 标签处理
{
filter: ['h2', 'h3', 'h4', 'h5', 'h6', 'h7'],
replacement: function (content, node) {
var hLevel = node.nodeName.charAt(1)
var hPrefix = '##'
hLevel = hLevel - 2
for (var i = 0; i < hLevel; i++) {
hPrefix += '#'
}
return '\n\n' + hPrefix + ' ' + content + '\n\n'
}
},
// HR 标签处理
{
filter: 'hr',
replacement: function () {
return '\n\n* * *\n\n'
}
},
// em i 斜体处理
{
filter: ['em', 'i'],
replacement: function (content) {
return ' _' + content + '_ '
}
},
// Strong b 粗体处理
{
filter: ['strong', 'b'],
replacement: function (content) {
return '**' + content + '**'
}
},
// Inline code
{
filter: function (node) {
var hasSiblings = node.previousSibling || node.nextSibling
var isCodeBlock = node.parentNode.nodeName === 'PRE' && !hasSiblings
return node.nodeName === 'CODE' && !isCodeBlock
},
replacement: function (content) {
return '`' + content + '`'
}
},
// A 标签处理
{
filter: function (node) {
return node.nodeName === 'A' && node.getAttribute('href')
},
replacement: function (content, node) {
return '[' + content + '](' + node.getAttribute('href') + ')'
}
},
// 特殊情况下的A标签处理
{
filter: function (node) {
return node.nodeName === 'A' && node.getAttribute('style')
},
replacement: function (content, node) {
return content
}
},
// IMG 标签处理
{
filter: 'img',
replacement: function (content, node) {
var alt = node.alt || ''
var src = node.getAttribute('src') || ''
var title = node.title || ''
var titlePart = title ? ' "' + title + '"' : ''
return src ? '\n![' + alt + ']' + '(' + src + titlePart + ')\n' : ''
}
},
// 代码块处理
{
filter: 'pre',
replacement: function (content, node) {
let contentText = node.innerText
if (!contentText.endsWith('\n')) {
contentText += '\n'
}
return '\n```\n' + contentText + '```\n'
}
},
// 行内代码处理
{
filter: 'code',
replacement: function (content, node) {
return '`' + content + '`'
}
},
// IFrame 提醒
{
filter: 'iframe',
replacement: function (content, node) {
console.log(node);
console.log(content);
return '\n ** 此处有iframe,请手动处理 ** \n'
}
},
// Canvas 提醒
{
filter: 'canvas',
replacement: function (content, node) {
return '\n ** 此处有Canvas,请手动处理 ** \n'
}
},
// div 处理
{
filter: 'div',
replacement: function (content, node) {
var attrClass = node.getAttribute('class') || ''
if (attrClass === 'code') {
if (!content.endsWith('\n')) {
content += '\n'
}
return '\n```\n' + content + '```\n'
} else {
return content
}
}
},
{
'filter': 'textarea',
replacement: function (content, node) {
return ''
}
},
// 直接返回内容的标签
{
filter: ['figure', 'span', 'small', 'section', 'font', 'asymspc', 'button', 'article', 'figcaption'],
replacement: function (content) {
return content
}
},
// 引用
{
filter: 'blockquote',
replacement: function (content) {
content = content.trim()
content = content.replace(/\n{3,}/g, '\n\n')
content = content.replace(/^/gm, '> ')
return '\n\n' + content + '\n\n'
}
},
// 列表项
{
filter: 'li',
replacement: function (content, node) {
content = content.replace(/^\s+/, '').replace(/\n/gm, '\n ')
var prefix = '* '
var parent = node.parentNode
var index = Array.prototype.indexOf.call(parent.children, node) + 1
prefix = /ol/i.test(parent.nodeName) ? index + '. ' : '* '
return prefix + content + '\n'
}
},
// 有序/无序列表
{
filter: ['ul', 'ol'],
replacement: function (content, node) {
var strings = []
for (var i = 0; i < node.childNodes.length; i++) {
strings.push(node.childNodes[i]._replacement)
}
if (/li/i.test(node.parentNode.nodeName)) {
return '\n' + strings.join('\n')
}
return '\n\n' + strings.join('\n') + '\n\n'
}
},
// 判断是否是block如果是block前后加空行
{
filter: function (node) {
return this.isBlock(node)
},
replacement: function (content, node) {
return '\n\n' + this.outer(node, content) + '\n\n'
}
},
// Anything else!
{
filter: function () {
return true
},
replacement: function (content, node) {
return this.outer(node, content)
}
}
]
},{}],5:[function(require,module,exports){
/**
* This file automatically generated from `build.js`.
* Do not manually edit.
*/
module.exports = [
"address",
"article",
"aside",
"blockquote",
"canvas",
"dd",
"div",
"dl",
"dt",
"fieldset",
"figcaption",
"figure",
"footer",
"form",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"h7",
"header",
"hgroup",
"hr",
"li",
"main",
"nav",
"noscript",
"ol",
"output",
"p",
"pre",
"section",
"table",
"tfoot",
"ul",
"video"
];
},{}],6:[function(require,module,exports){
'use strict';
var voidElements = require('void-elements');
Object.keys(voidElements).forEach(function (name) {
voidElements[name.toUpperCase()] = 1;
});
var blockElements = {};
require('block-elements').forEach(function (name) {
blockElements[name.toUpperCase()] = 1;
});
/**
* isBlockElem(node) determines if the given node is a block element.
*
* @param {Node} node
* @return {Boolean}
*/
function isBlockElem(node) {
return !!(node && blockElements[node.nodeName]);
}
/**
* isVoid(node) determines if the given node is a void element.
*
* @param {Node} node
* @return {Boolean}
*/
function isVoid(node) {
return !!(node && voidElements[node.nodeName]);
}
/**
* whitespace(elem [, isBlock]) removes extraneous whitespace from an
* the given element. The function isBlock may optionally be passed in
* to determine whether or not an element is a block element; if none
* is provided, defaults to using the list of block elements provided
* by the `block-elements` module.
*
* @param {Node} elem
* @param {Function} blockTest
*/
function collapseWhitespace(elem, isBlock) {
if (!elem.firstChild || elem.nodeName === 'PRE') return;
if (typeof isBlock !== 'function') {
isBlock = isBlockElem;
}
var prevText = null;
var prevVoid = false;
var prev = null;
var node = next(prev, elem);
while (node !== elem) {
if (node.nodeType === 3) {
// Node.TEXT_NODE
var text = node.data.replace(/[ \r\n\t]+/g, ' ');
if ((!prevText || / $/.test(prevText.data)) && !prevVoid && text[0] === ' ') {
text = text.substr(1);
}
// `text` might be empty at this point.
if (!text) {
node = remove(node);
continue;
}
node.data = text;
prevText = node;
} else if (node.nodeType === 1) {
// Node.ELEMENT_NODE
if (isBlock(node) || node.nodeName === 'BR') {
if (prevText) {
prevText.data = prevText.data.replace(/ $/, '');
}
prevText = null;
prevVoid = false;
} else if (isVoid(node)) {
// Avoid trimming space around non-block, non-BR void elements.
prevText = null;
prevVoid = true;
}
} else {
node = remove(node);
continue;
}
var nextNode = next(prev, node);
prev = node;
node = nextNode;
}
if (prevText) {
prevText.data = prevText.data.replace(/ $/, '');
if (!prevText.data) {
remove(prevText);
}
}
}
/**
* remove(node) removes the given node from the DOM and returns the
* next node in the sequence.
*
* @param {Node} node
* @return {Node} node
*/
function remove(node) {
var next = node.nextSibling || node.parentNode;
node.parentNode.removeChild(node);
return next;
}
/**
* next(prev, current) returns the next node in the sequence, given the
* current and previous nodes.
*
* @param {Node} prev
* @param {Node} current
* @return {Node}
*/
function next(prev, current) {
if (prev && prev.parentNode === current || current.nodeName === 'PRE') {
return current.nextSibling || current.parentNode;
}
return current.firstChild || current.nextSibling || current.parentNode;
}
module.exports = collapseWhitespace;
},{"block-elements":5,"void-elements":7}],7:[function(require,module,exports){
/**
* This file automatically generated from `pre-publish.js`.
* Do not manually edit.
*/
module.exports = {
"area": true,
"base": true,
"br": true,
"col": true,
"embed": true,
"hr": true,
"img": true,
"input": true,
"keygen": true,
"link": true,
"menuitem": true,
"meta": true,
"param": true,
"source": true,
"track": true,
"wbr": true
};
},{}],8:[function(require,module,exports){
},{}]},{},[1])(1)
});

2
resources/scss/app.scss Normal file
View File

@ -0,0 +1,2 @@
@import "loading";
@import "main";

75
resources/scss/loading.scss Executable file
View File

@ -0,0 +1,75 @@
.app-view-loading {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99999;
background-color: rgba(255, 255, 255, 0.7);
display: flex;
align-items: center;
justify-content: center;
> div {
text-align: center;
> div {
color: #ccc;
margin: 0;
font: 11px verdana;
line-height: 16px;
text-transform: uppercase;
letter-spacing: 1px;
}
> span {
display: inline-block;
vertical-align: middle;
width: 8px;
height: 8px;
margin: 2px;
background: #007DB6;
border-radius: 8px;
animation: app-view-loadanim 1s infinite alternate;
&:nth-of-type(2) {
background: #008FB2;
animation-delay: 0.2s;
}
&:nth-of-type(3) {
background: #009B9E;
animation-delay: 0.4s;
}
&:nth-of-type(4) {
background: #00A77D;
animation-delay: 0.6s;
}
&:nth-of-type(5) {
background: #00B247;
animation-delay: 0.8s;
}
&:nth-of-type(6) {
background: #5AB027;
animation-delay: 1.0s;
}
&:nth-of-type(7) {
background: #A0B61E;
animation-delay: 1.2s;
}
}
@keyframes app-view-loadanim {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
}
}

285
resources/scss/main.scss Executable file
View File

@ -0,0 +1,285 @@
*[hidden="hidden"] {
display: none !important;
}
.icon-loading {
animation: icon-loading-load 0.6s infinite linear;
}
@keyframes icon-loading-load {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.ivu-modal-wrap {
&.simple-modal {
.ivu-modal {
top: 100px;
padding-bottom: 100px;
@media (max-height: 900px) {
top: 35px;
padding-bottom: 35px;
}
}
.ivu-modal-header,
.ivu-modal-footer {
border-color: transparent;
}
.form-network-add-tabs {
.ivu-tabs-tabpane {
padding: 10px 6px 0;
}
}
.form-network-add-in-out {
padding: 0 6px;
.select-in-type {
span.ivu-radio {
display: none;
}
.select-in-type-item-checked {
color: #2d8cf0;
border: 1px solid #2d8cf0 !important;
}
.select-in-type-item {
display: flex;
align-items: center;
min-width: 90px;
border: 1px solid #E8EBEE;
border-radius: 4px;
padding: 0 12px;
margin: 0 8px 0 0;
> span {
flex: 1;
}
&:hover {
cursor: pointer;
}
.select-in-type-icon {
margin-left: 12px;
}
}
}
.select-in-node {
margin-top: 18px;
}
}
}
}
.modal-info-show {
display: flex;
.column {
color: #6D6D6D;
margin: 5px 0;
min-width: 70px;
max-width: 100px;
text-align: right;
}
.value {
flex: 1;
width: 0;
color: #414141;
margin: 5px 0 5px 5px;
word-break: break-all;
}
}
.ivu-select-dropdown {
max-height: 360px;
&.select-node {
.ivu-select-item {
display: flex;
align-items: center;
justify-content: space-between;
.option-title {
flex: 1;
}
.ivu-tag {
margin-left: 18px;
margin-right: 0;
transform: scale(0.9);
transform-origin: right center;
}
}
}
}
.ivu-tooltip-popper {
.ivu-tooltip-inner {
white-space: normal;
}
}
.ivu-table {
table {
width: 100% !important;
.ivu-table-cell {
padding-left: 12px;
padding-right: 12px;
}
thead {
.ivu-table-cell {
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
tbody {
.tree-icon-loading {
.ivu-table-cell {
display: flex;
align-items: center;
.ivu-table-cell-tree {
margin-right: 6px;
}
}
}
}
}
.td-ellipsis {
display: flex;
align-items: center;
max-width: 100%;
.remark-text {
overflow: hidden;
text-overflow: ellipsis;
align-items: center;
white-space: nowrap;
height: 20px;
line-height: 20px;
margin-right: 6px;
}
.remark-icon {
display: none;
font-size: 16px;
cursor: pointer;
}
.remark-tag {
display: inline-block;
height: 22px;
line-height: 22px;
margin: 2px 4px 2px 0;
border: 1px solid #e8eaec;
border-radius: 3px;
background: #f7f7f7;
font-size: 12px;
vertical-align: middle;
opacity: 1;
color: #515a6e;
padding: 0 4px;
white-space: nowrap;
overflow: visible;
&.pointer-tag {
cursor: pointer;
color: #1890ff;
background: #e6f7ff;
border-color: #91d5ff;
}
}
.icon-tooltip {
.ivu-tooltip-rel {
display: flex;
align-items: center;
}
}
}
.td-action {
max-width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: middle;
.td-action-container {
display: inline-block;
a {
font-size: 12px;
padding: 0 5px;
}
}
}
.ivu-table-row-hover {
&:hover {
.td-ellipsis {
.remark-icon {
display: inline-block;
}
}
}
}
&:before {
background-color: #efefef;
}
}
.auto-height-top {
.ivu-table {
.ivu-table-body {
table {
td {
height: auto;
vertical-align: top;
.ivu-table-cell {
display: flex;
align-items: center;
min-height: 48px;
padding: 8px 12px;
.node-line {
max-width: 100%;
.td-ellipsis {
.remark-line {
margin: 2px 6px 2px 0;
&:hover {
border-color: #888;
}
}
.remark-tag {
margin: 0;
transform: scale(0.8);
}
.remark-icon {
cursor: pointer;
&:hover {
color: #2d8cf0;
}
.ivu-icon {
vertical-align: unset;
transform: scale(1.2);
&.ivu-icon-md-remove-circle {
background-image: url("data:image/svg+xml;base64,PHN2ZyB0PSIxNjIxMDAxMDg0MzAxIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE4NjUiIHdpZHRoPSIyNTYiIGhlaWdodD0iMjU2Ij48cGF0aCBkPSJNNTEyIDUxMm0tNTEyIDBhNTEyIDUxMiAwIDEgMCAxMDI0IDAgNTEyIDUxMiAwIDEgMC0xMDI0IDBaIiBmaWxsPSIjRkZGRkZGIiBwLWlkPSIxODY2Ij48L3BhdGg+PHBhdGggZD0iTTUxMiAwYTUxMiA1MTIgMCAxIDAgMCAxMDI0QTUxMiA1MTIgMCAwIDAgNTEyIDB6IG0zODQgNTEyYzAgODIuNzM5Mi0yNi40MTkyIDE1OS4zMzQ0LTcxLjA2NTYgMjIyLjEwNTZMMjg5Ljg5NDQgMTk5LjA2NTZBMzgxLjc0NzIgMzgxLjc0NzIgMCAwIDEgNTEyIDEyOCAzODQuNDA5NiAzODQuNDA5NiAwIDAgMSA4OTYgNTEyeiBtLTc2OCAwYzAtODMuMzUzNiAyNi43MjY0LTE2MC40NjA4IDcxLjk4NzItMjIzLjQzNjhsNTM1LjU1MiA1MzUuMzQ3MkEzODEuNzQ3MiAzODEuNzQ3MiAwIDAgMSA1MTIgODk2IDM4NC40MDk2IDM4NC40MDk2IDAgMCAxIDEyOCA1MTJ6IiBmaWxsPSIjZmYwMDAwIiBwLWlkPSIxODY3IiBkYXRhLXNwbS1hbmNob3ItaWQ9ImEzMTN4Ljc3ODEwNjkuMC5pMCIgY2xhc3M9InNlbGVjdGVkIj48L3BhdGg+PC9zdmc+");
background-repeat: no-repeat;
width: 12px;
height: 12px;
background-size: 94%;
background-position: center;
vertical-align: text-top;
&:before {
display: none;
}
}
}
}
.node-signal-box {
margin-left: 1px;
.node-ping-value {
margin-left: 2px;
}
}
.ivu-table-cell-tooltip {
width: auto;
.ivu-tooltip-rel {
max-width: 100%;
}
}
}
}
}
}
}
}
}
}

View File

@ -11,8 +11,21 @@ const mix = require('laravel-mix');
|
*/
function getFileName(str) {
if (/resources_js_pages_(.*?)_vue/.test(str)) {
return /resources_js_pages_(.*?)_vue/.exec(str)[1];
}
return str;
}
mix.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css', [
//
]).copy('resources/public', 'public');
mix.vue({ version: 2 })
.copy('resources/public', 'public')
.js('resources/js/app.js', 'public/js')
.sass('resources/scss/app.scss','public/css')
.webpackConfig({
output: {
chunkFilename: function ({chunk}) {
return `js/build/${ getFileName(chunk.id) }.${ mix.inProduction() ? '[hash:8].' : '' }js`
}
},
});