创建版本

This commit is contained in:
2021-02-22 12:17:00 +08:00
commit af555f49c3
2332 changed files with 369202 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
require('./bootstrap');
const Vue = require('vue');
window.Vue = Vue;
// 把vue的模块传递给全局变量
import Notification from './components/Notification.vue';
import draggable from 'vuedraggable';
import GdooFormDesigner from './components/GdooFormDesigner.vue';
window.GdooVueComponents = {
draggable: draggable,
gdooFormDesigner: GdooFormDesigner,
notification: Notification
};
+56
View File
@@ -0,0 +1,56 @@
window._ = require('lodash');
/**
* We'll load jQuery and the Bootstrap jQuery plugin which provides support
* for JavaScript based Bootstrap features such as modals and tabs. This
* code may be modified to fit the specific needs of your application.
*/
try {
// window.$ = window.jQuery = require('jquery');
// require('bootstrap');
} catch (e) {}
/**
* 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';
/**
* Next we will register the CSRF Token as a common header with Axios so that
* all outgoing HTTP requests automatically have it attached. This is just
* a simple convenience so we don't have to attach every token manually.
*/
/*
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
*/
/**
* 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,
encrypted: true
});
*/
@@ -0,0 +1,270 @@
<template>
<draggable chosenClass="af-chosen" ghostClass="af-ghost" :move="onMove" @change="onChange" class="af-draggable" :list="items" item-key="item_id" group="gdooComponent">
<template #item="{element, index}">
<div @click.stop="nodeShow(element)" :class="'af-item af-item-' + element.type + (activeItem.item_id == element.item_id ? ' af-item-active' : '')" :item-id="element.item_id" :item-table="element.table" :key="element.item_id" :style="'width:' + (element.table_id > 0 ? element.width : 'calc(' + (element.grid / 12 * 100) + '% - 5px)')">
<div :class="'af-panel af-panel-' + element.type">
<a @click.stop="nodeDelete(index)"><i class="remove fa fa-trash" title="删除"></i></a>
<div v-if="element.type == 'component'">
{{ element.name }}
</div>
<div v-else class="af-item-content">
<label class="af-item-label" :style="(element.label_width ? 'width:'+ element.label_width : '')" v-show="element.hide_name == 0">{{ element.name }}</label>
<div class="af-item-control" :style="'margin-left:' + (element.hide_name == 0 ? element.label_width : '0px')">
<input class="form-control input-sm" v-model="element.value" :style="(element.field_width ? 'width:' + element.field_width : '')">
</div>
</div>
</div>
<div :class="'af-component fa-group-' + element.type + (element.table == 1 ? ' af-table-component af-over-x' : '')" v-if="element.type == 'component'">
<gdoo-form-designer :table="element.table == 1" :parent_id="element.item_id" :items="element.children" />
</div>
</div>
</template>
</draggable>
</template>
<script>
import draggable from 'vuedraggable';
import { watch, defineComponent, inject, reactive, provide, toRaw} from 'vue'
export default defineComponent({
name: 'gdoo-form-designer',
props: ['items', 'parent_id', 'table'],
setup(props) {
let activeItem = inject('activeItem');
watch(activeItem, (oldItem, newItem) => {
props.items.forEach(item => {
if (item.item_id == newItem.item_id) {
for (var key in newItem) {
item[key] = newItem[key];
}
}
});
})
return {activeItem};
},
components: {
'draggable': draggable,
},
methods: {
onMove(item) {
let me = this;
let oldItem = item.draggedContext.element;
let newItem = item.relatedContext.element;
// 获取容器dom
let node = item.to.offsetParent;
// 子表节点不能拖出子表容器
if (oldItem.table_id > 0) {
// 不能把子表节点拖入其他容器
if (newItem == undefined) {
return false;
}
if (oldItem.table_id == newItem.table_id) {
return true;
} else {
return false;
}
} else {
// 新容器为空
if (newItem == undefined) {
var item_table = node.getAttribute('item-table');
// 不允许把普通节点拖入子表
if (item_table == 1) {
return false;
}
return true;
} else {
// 不允许普通节点拖入子表
if (newItem.table_id) {
return false;
} else {
return true;
}
}
}
},
onChange(item) {
let me = this;
if (item.added) {
var row = item.added.element;
row.parent_id = me.parent_id;
// 已经设置了id
if (row.item_id > 0) {
return;
}
row.item_id = getItemMaxId();
if (row.type == 'component') {
} else {
row.field = getFieldMaxId();
if (me.table) {
row.table_id = row.parent_id;
row.width = '200px';
delete row.grid;
} else {
row.table_id = 0;
}
}
for (var key in me.activeItem) {
delete me.activeItem[key];
}
for (var key in row) {
me.activeItem[key] = row[key];
}
}
},
nodeShow(item) {
for (var key in this.activeItem) {
delete this.activeItem[key];
}
for (var key in item) {
if (key == 'children') {
continue;
}
this.activeItem[key] = item[key];
}
},
nodeDelete(index) {
this.items.splice(index, 1);
}
}
});
</script>
<style>
.af-draggable {
min-height: 40px;
padding: 0;
float: left;
width: 100%;
}
.af-component {
padding: 5px;
padding-bottom: 0;
padding-right: 0;
}
.af-item-component {
border: 1px dashed #ccc;
margin-bottom: 5px;
cursor: move;
float: left;
position: relative;
}
.af-item {
float: left;
margin-right: 5px;
}
.af-panel-component {
color: #aaa;
padding: 5px;
padding-bottom: 0;
}
.af-item:not(.af-item-component) {
padding-bottom: 5px;
}
.af-panel:not(.af-panel-component) {
position: relative;
padding: 5px;
padding-right: 5px;
background-color: #eee;
border: 1px solid transparent;
cursor: move;
}
.af-item-component.af-item-active {
border: 1px dashed #409eff;
}
.af-item-active:not(.af-item-component) .af-panel {
background: #f6f7ff;
border: 1px dashed #409eff;
color: #409eff;
}
.af-item-label {
width: 150px;
text-align: right;
float: left;
line-height: 28px;
vertical-align: middle;
padding: 0 10px 0 0;
font-weight: normal;
}
.af-item-control {
margin-left: 150px;
}
.af-panel .fa {
display: none;
text-align: center;
border: 1px solid #409eff;
background: #fff;
z-index: 999;
}
.af-item-active > .af-panel .fa {
display: inline-block;
position: absolute;
top: -5px;
right: 5px;
color: #409eff;
padding: 3px 5px;
}
.af-item-active .fa:hover {
background: #409eff;
color: #fff;
}
.af-left-group-item.af-ghost,
.af-panel-component.af-ghost .af-panel {
border: 1px dashed #409eff;
color: #409eff;
}
.af-left-group-item.af-ghost {
float: left;
margin: 0;
margin-bottom: 5px;
width:calc(100% - 5px);
}
.af-table-component {
overflow: hidden;
overflow-x: auto;
white-space: nowrap;
}
.af-table-component .af-item {
float: none;
display: inline-block;
}
.af-table-component .af-item-label {
width: auto;
float: none;
text-align: left;
line-height: inherit;
}
.af-table-component .af-item-control {
margin-left: 0;
}
.af-table-component .af-ghost {
width: 200px;
}
</style>
+214
View File
@@ -0,0 +1,214 @@
<template>
<ul class="nav navbar-nav navbar-right m-n hidden-xs nav-user">
<!--
<li class="dropdown">
<a data-toggle="addtab" data-url="index/index/dashboard" data-id="dashboard" data-name="个人空间" class="dropdown-toggle hidden-xs">
<i class="fa fa-bar-chart-o"></i>
<span>个人空间</span>
</a>
</li>
-->
<li class="dropdown">
<a href="javascript:;" @click="chatToggle()" title="即时消息" class="dropdown-toggle hidden-xs">
<i class="fa fa-comments pulse-box">
<span class='pulse green'></span>
</i>
<span class="visible-xs-inline">即时消息</span>
</a>
</li>
<li class="dropdown hidden-xs">
<!--
<a href="javascript:;" data-toggle="dropdown" class="dropdown-toggle">
<i class="fa fa-bell-o notify-box">
<span class="pulse" v-if="count.total > 0"></span>
</i>
<span class="visible-xs-inline">通知</span>
</a>
-->
<a href="#" data-toggle="dropdown" title="通知" class="dropdown-toggle">
<i class="fa fa-bell-o pulse-box">
<span :class="[countTotal > 0 ? 'pulse' : 'hidden']"></span>
</i>
<span class="visible-xs-inline">通知</span>
</a>
<div class="dropdown-menu w-xl">
<div class="panel bg-white">
<div class="list-group no-radius">
<a href="#" :class="[countArticle > 0 ? 'list-group-item' : 'hidden']">
<span class="pull-left thumb-sm">
<i class="fa fa-bullhorn fa-2x text-danger"></i>
</span>
<span class="block m-b-none">
<span><span class="text-danger pull-right-xs">0</span> 条未读公告</span>
<br />
<small class="text-muted text-xs">点击阅读</small>
</span>
</a>
<a href="#" :class="[countMail > 0 ? 'list-group-item' : 'hidden']">
<span class="pull-left thumb-sm">
<i class="fa fa-envelope-o fa-2x text-success"></i>
</span>
<span class="block m-b-none">
<span><span class="text-danger pull-right-xs">2</span> 条未读邮件</span>
<br />
<small class="text-muted text-xs">点击阅读</small>
</span>
</a>
<a href="#" :class="[countNotification > 0 ? 'list-group-item' : 'hidden']" data-toggle="addtab" data-url="user/message/index" data-id="00" data-name="通知提醒">
<span class="pull-left thumb-sm">
<i class="fa fa-bell-o fa-2x text-info"></i>
</span>
<span class="block m-b-none">
<span><span class="text-danger pull-right-xs">{{countNotification}}</span> 条未读通知</span>
<br />
<span class="text-muted text-xs">点击阅读</span>
</span>
</a>
</div>
<div class="panel-footer text-sm">
<a href="#" class="pull-right"><i class="fa fa-cog"></i></a>
<a href="#">提醒设置</a>
</div>
</div>
</div>
</li>
<li class="dropdown">
<a href="javascript:;" data-toggle="dropdown" class="dropdown-toggle clear hidden-xs">
<span class="thumb-xs avatar m-t-n-sm m-b-n-sm m-r-sm">
<img :src="user.avatar" class="img-circle">
<i class="on md b-white bottom"></i>
</span>
<span class="hidden-sm hidden-md">{{user.name}}</span> <b class="caret"></b>
</a>
<!-- dropdown -->
<ul class="dropdown-menu animated fadeInRight">
<li>
<a href="javascript:;" data-toggle="addtab" data-url="user/profile/index" data-id="02" data-name="个人资料">个人资料</a>
</li>
<li>
<a href="javascript:;" @click="support">技术支持</a>
</li>
<li class="divider"></li>
<li>
<a :href="url('user/auth/logout')">注销</a>
</li>
</ul>
<!-- animated fadeInUp -->
<!--
<ul class="dropdown-menu">
<li>
<a href="javascript:;" data-toggle="addtab" data-url="user/profile/index" data-id="02" data-name="个人资料">个人资料</a>
</li>
<li>
<a href="javascript:;" @click="support">技术支持</a>
</li>
<li class="divider"></li>
<li>
<a :href="url('user/auth/logout')">注销</a>
</li>
</ul>
-->
</li>
</ul>
</template>
<script>
import { defineComponent } from 'vue'
export default defineComponent({
name: 'notification',
data() {
return {
user: {},
countNotification: 0,
countTotal: 0,
countArticle: 0,
countMail: 0,
};
},
mounted() {
var me = this;
this.getUser();
this.tick();
this.timer = setInterval(() => this.tick(), 1000 * 60);
},
methods: {
// 获取用户信息
getUser() {
let me = this;
$.get(app.url('user/profile/getUser'), function (res) {
me.user = res;
}, 'json');
},
support() {
viewDialog({
title: '技术支持',
dialogClass: 'modal-md',
url: app.url('index/index/support'),
close: function() {
$(this).dialog("close");
}
});
},
chatToggle() {
function openWin(u, w, h) {
var l = (screen.width - w) / 2;
var t = (screen.height - h) / 2;
var s = 'width=' + w + ', height=' + h + ', top=' + t + ', left=' + l; s += ', status=no, toolbar=no, scrollbars=no, menubar=no, location=no, resizable=no';
open(u, 'gdooChatBox', s);
}
openWin(app.url('chat/chat/index'), 900, 600);
},
tick() {
let me = this;
$.get(app.url('user/message/count'), function (count) {
if (me.countNotification == count) {
return;
}
me.countTotal = count;
me.countNotification = count;
}, 'json');
// 查询待办列表
$.post(app.url('index/index/badges'), function (res) {
let menus = {};
let groups = {};
$.each(res, function(key, rows) {
let badge = $('#badge_' + key);
let menu_id = badge.data('menu_id');
let group_id = badge.data('group_id');
if (rows.total) {
if (menu_id > 0) {
menus[menu_id] = menu_id;
}
if (group_id > 0) {
groups[group_id] = group_id;
}
badge.show();
badge.text(rows.total);
} else {
badge.hide();
}
});
$.each(menus, function(menu_id) {
$('#badge_menu_' + menu_id).show();
});
$.each(groups, function(group_id) {
$('#badge_group_' + group_id).show();
});
});
}
}
});
</script>