19
.env.example
|
@ -49,27 +49,24 @@ MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
|||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
# 即时通讯
|
||||
REALTIME_KEY=fsmDyhOBxjUo8Nksd0EAlyJWT4jtfSAO
|
||||
REALTIME_KEY=
|
||||
REALTIME_URL=ws://192.168.0.2:6002/realtime
|
||||
REALTIME_API=http://192.168.0.2:6002/api
|
||||
|
||||
# 二次验证开关
|
||||
AUTH_TOTP_STATUS=false
|
||||
# 是否二次验证
|
||||
AUTH_TOTP=false
|
||||
|
||||
# 微信推送
|
||||
WECHAT_MESSAGE_PUSH_STATUS=false
|
||||
# 是否微信推送
|
||||
WECHAT_MESSAGE_PUSH=false
|
||||
|
||||
# 外部接口
|
||||
PLUGIN_SYNC_API_STATUS=false
|
||||
PLUGIN_SYNC_API_URL=
|
||||
|
||||
# PRINCE转换
|
||||
PRINCE_DIR=E:/develop/Prince/engine/bin/prince.exe
|
||||
|
||||
# 添加ag-grid授权
|
||||
AGGRID_LICENSE=
|
||||
# ag-grid授权
|
||||
AGGRID_LICENSE="agGrid.LicenseManager.setLicenseKey('key');"
|
||||
|
||||
# 演示版本
|
||||
# 演示模式
|
||||
DEMO_VERSION=false
|
||||
|
||||
DEMO_DATA="agGrid.LicenseManager.prototype.validateLicense = function() {}"
|
||||
|
|
35
README.md
|
@ -4,7 +4,13 @@
|
|||
[![release][release-badge]][release-link]
|
||||
|
||||
## 介绍
|
||||
本系统是给企业定制开发的,基于laravel 8.x框架开发。基本进销存功能、营销管理功能、业务员销售团队分级管理、支持客户自主下单。
|
||||
1. 进销存功能、营销管理功能、简单生产计划、业务员销售团队分级管理、支持客户任务和业务员任务进度统计、支持客户自主下单。特别注重销售管理、业绩分析。
|
||||
2. 主要为食品行业生产型和贸易企业定制开发。
|
||||
3. 包括强大的自定义功能,模型字段(自定义跨表映射功能、视图管理、流程管理、字段权限管理)
|
||||
|
||||
|
||||
## 架构
|
||||
基于PHP框架Laravel 8.x + MySQL 8.x
|
||||
|
||||
|
||||
## 申明
|
||||
|
@ -75,16 +81,25 @@ QQ交流群: 79446405
|
|||
|
||||

|
||||
|
||||
## 架构
|
||||
基于PHP框架Laravel 8.x + MySQL 8.x
|
||||
|
||||
## 安装
|
||||
1. 上传压缩包到目录,这里推荐使用宝塔面板,安装php-8.x、mysql-8.x、nginx
|
||||
2. 然后使用 composer install --no-dev 安装依赖
|
||||
3. 如果要修改前端文件请执行 yarn install 安装依赖
|
||||
4. 最后导入 database/gdoo-2.2.sql
|
||||
5. 然后执行 php artisan key:generate
|
||||
6. 修改.env相关配置
|
||||
1. 推荐使用宝塔面板,安装nginx 1.18.x、php-8.x(需要扩展:fileinfo)、mysql-8.x(mariaDB 10.4.x),如果你使用win请自行安装相关环境
|
||||
2. 创建网站和数据库, 数据库字符utf8mb4, 在网站目录中设置PHP命令行版本为php-80
|
||||
3. 下载gdoo: https://gitee.com/hawind/gdoo 上传至宝塔网站根目录并解压
|
||||
4. 打开Xshell并登录, 执行 <code>composer -v</code> 查看composer版本, 执行 <code>composer self-update</code> 升级composer至最新版本
|
||||
5. 切换命令行到网站根目录 <code>cd /www/wwwroot/yousite</code>
|
||||
6. 执行 <code>composer install --no-dev</code> 安装依赖
|
||||
7. 执行 <code>cp .env.example .env</code> 并修改相关配置
|
||||
8. 执行 <code>php artisan key:generate</code>
|
||||
9. 打开宝塔数据库管理:
|
||||
1. 将项目database目录中的 gdoo-2.2.sql 文件上传并导入到数据库
|
||||
10. 打开宝塔网站管理:
|
||||
1. 设置运行目录为public
|
||||
2. 设置伪静态为laravel5
|
||||
11. 打开网站并用 <code>admin/123456</code> 登录
|
||||
|
||||
## 开发
|
||||
1. 请在项目根目录执行 <code>yarn install</code> 安装前端依赖
|
||||
2. 待续
|
||||
|
||||
[license-badge]: https://img.shields.io/badge/license-apache2-blue.svg
|
||||
[license-link]: LICENSE
|
||||
|
|
|
@ -30,7 +30,7 @@ class ApiController extends Controller
|
|||
$settings['public_url'] = URL::to('/');
|
||||
$settings['upload_file_type'] = $this->setting['upload_type'];
|
||||
$settings['upload_max_size'] = $this->setting['upload_max'];
|
||||
$settings['openSource'] = $this->openSource;
|
||||
$settings['realtime'] = not_empty(env('REALTIME_KEY'));
|
||||
|
||||
header('Content-type: text/javascript');
|
||||
echo 'var settings = '. json_encode($settings, JSON_UNESCAPED_UNICODE);
|
||||
|
|
|
@ -27,11 +27,6 @@ class Controller extends BaseController
|
|||
*/
|
||||
public $powered = 'Gdoo';
|
||||
|
||||
/**
|
||||
* @var 是否开源版
|
||||
*/
|
||||
public $openSource = false;
|
||||
|
||||
/**
|
||||
* @var 配置参数
|
||||
*/
|
||||
|
@ -79,14 +74,14 @@ class Controller extends BaseController
|
|||
$this->ret = RetService::make();
|
||||
|
||||
View::share([
|
||||
'title' => 'GdooOA',
|
||||
'title' => 'Gdoo',
|
||||
'setting' => $this->setting,
|
||||
'public_url' => URL::to('/'),
|
||||
'upload_url' => URL::to('/uploads'),
|
||||
'static_url' => URL::to('/static'),
|
||||
'asset_url' => URL::to('/assets'),
|
||||
'version' => $this->version,
|
||||
'openSource' => $this->openSource,
|
||||
'licenseType' => env('LICENSE_TYPE'),
|
||||
'resVersion' => $this->resVersion,
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ class NotificationService
|
|||
*/
|
||||
public static function wechatTemplate($users, $content)
|
||||
{
|
||||
if (env('WECHAT_MESSAGE_PUSH_STATUS') === false) {
|
||||
if (env('WECHAT_MESSAGE_PUSH') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -291,7 +291,7 @@ a { outline: none; }
|
|||
|
||||
<div class="dashboard-footer">
|
||||
<div class="box">
|
||||
{{$version}} {{$openSource ? '开源版' : '企业版'}}
|
||||
{{$version}} {{$licenseType ? $licenseType : '开源版'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,501 +0,0 @@
|
|||
<style type="text/css">
|
||||
html {
|
||||
overflow: hidden;
|
||||
}
|
||||
a { outline: none; }
|
||||
|
||||
.dashboard-widget-header {
|
||||
margin-top: 49px;
|
||||
height: calc(100vh - 80px);
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.dashboard-title {
|
||||
padding: 10px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100vw;
|
||||
border-bottom: solid 1px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.dashboard-title .btn {
|
||||
border: solid 1px rgba(0, 0, 0, 0.15);
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.dashboard-config {
|
||||
text-align: center;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
width: 26px;
|
||||
display: block;
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
border: solid 1px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.dashboard-config .fa {
|
||||
color: #999;
|
||||
}
|
||||
.dashboard-config:hover {
|
||||
border: solid 1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.dashboard-config:hover .fa {
|
||||
color: #2490f8;
|
||||
}
|
||||
|
||||
.panel-heading {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.content-body { margin: 0; }
|
||||
.content-body .panel:last-child {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.frame-green .dashboard-title {
|
||||
color: #fff;
|
||||
}
|
||||
.frame-primary .dashboard-title {
|
||||
color: #58666e;
|
||||
}
|
||||
.frame-blue .dashboard-title {
|
||||
color: #fff;
|
||||
}
|
||||
.frame-blue2 .dashboard-title {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.frame-blue .quick-text .title,
|
||||
.frame-purple .quick-text .title,
|
||||
.frame-green .quick-text .title,
|
||||
.frame-lilac .quick-text .title,
|
||||
.frame-wood .quick-text .title {
|
||||
color: #fff;
|
||||
}
|
||||
.frame-blue .dashboard-title .btn,
|
||||
.frame-purple .dashboard-title .btn,
|
||||
.frame-green .dashboard-title .btn,
|
||||
.frame-lilac .dashboard-title .btn,
|
||||
.frame-wood .dashboard-title .btn {
|
||||
border: solid 1px rgba(0, 0, 0, 0.15);
|
||||
background-color: rgba(0, 0, 0, 0.15);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.panel-shadow {
|
||||
box-shadow: 0px 3px 6px 0px rgba(0, 0, 0, 0.03);
|
||||
border: solid 1px rgba(0, 0, 0, 0.08);
|
||||
border-radius: 4px !important;
|
||||
}
|
||||
|
||||
.frame-blue .panel-shadow,
|
||||
.frame-purple .panel-shadow,
|
||||
.frame-green .panel-shadow,
|
||||
.frame-lilac .panel-shadow,
|
||||
.frame-wood .panel-shadow {
|
||||
border: solid 0;
|
||||
}
|
||||
|
||||
.row-sm { margin-left: 5px; margin-right: 5px; }
|
||||
.row-sm > div { padding-left: 5px; padding-right: 5px; }
|
||||
.row-sm > div > .panel {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.row-info .panel { display: flex; padding-bottom: 10px; position: relative; text-align: center; border-radius: 4px !important; }
|
||||
.row-info .widget-droppable div { border-radius: 4px; }
|
||||
.info-l { color: #fff; margin-top:16px; margin-left: 15px; border-radius: 50%; width: 50px; height:50px; line-height:58px; vertical-align: middle; }
|
||||
|
||||
.info-c { flex:1; margin-left: 15px; text-align: left; }
|
||||
.info-c .info-name { margin-top:18px; font-size: 14px; color: #666; }
|
||||
.info-c .info-item { font-size: 24px; color: #333; }
|
||||
|
||||
.info-r { margin-left: auto; margin-top:18px; width: 70px; line-height:22px; }
|
||||
.info-r .rate { color: #2bbf24; }
|
||||
.info-r::before { position:absolute;top:22px;content:"";width:1px;height:40px;background-color:#e6e6e6;display:block; }
|
||||
|
||||
.app-title {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.app-title a {
|
||||
color: #999;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.app-title a:hover {
|
||||
color: #0e90d2;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.widget-item {
|
||||
min-height: 200px;
|
||||
}
|
||||
.todo-text { margin-left: 60px; }
|
||||
}
|
||||
|
||||
.widget-droppable div {
|
||||
border: 1px dashed #23b7e5;
|
||||
background: #dcf2f8;
|
||||
text-align: center;
|
||||
color: #ccc;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.row-widget .panel-heading {
|
||||
padding: 10px;
|
||||
color: #2490f8;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
}
|
||||
.row-widget .widget-item {
|
||||
text-align: left;
|
||||
}
|
||||
.row-widget .widget-item .red {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
.row-widget .widget-droppable div {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ag-theme-balham .ag-header {
|
||||
border-bottom: 1px solid #dee5e7;
|
||||
}
|
||||
.ag-theme-balham .ag-header-cell::after, .ag-theme-balham .ag-header-group-cell::after {
|
||||
border-right: 0 !important;
|
||||
}
|
||||
|
||||
.dashboard-footer {
|
||||
background: #fff;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
box-shadow: 20px 0px 8px 0 rgba(29,35,41,.05);
|
||||
border-top: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
.dashboard-footer .box {
|
||||
padding: 6px;
|
||||
padding-bottom: 8px;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
.dashboard-footer .box a {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
background: -webkit-linear-gradient(-70deg, #db469f, #2188ff);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
.dashboard-footer .box a:hover {
|
||||
color: #0e90d2;
|
||||
}
|
||||
|
||||
.row-quick {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
.quick-text {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.quick-text .title {
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.quick-icon .quick-num {
|
||||
font-family: Arial;
|
||||
position: absolute;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
right: -5px;
|
||||
top: -5px;
|
||||
background: #f00;
|
||||
border-radius: 100%;
|
||||
border: solid 1px #f05050;
|
||||
display: none;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.quick-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
border-radius: 5px;
|
||||
border: solid 1px rgba(255,255,255,0.1);
|
||||
box-shadow: -1px 1px 5px rgba(0, 0, 0, 0.15);
|
||||
position: relative;
|
||||
}
|
||||
.quick-icon .fa {
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="dashboard-widget">
|
||||
|
||||
<div class="dashboard-title">
|
||||
<div class="pull-right">
|
||||
<a class="dashboard-config" data-toggle="dashboard-config" title="仪表盘设置">
|
||||
<i class="fa fa-gear"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="font-thin">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="fa fa-filter"></span> 本部门下属部门
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="#">本人</a></li>
|
||||
<li><a href="#">本人和下属</a></li>
|
||||
<li><a href="#">本部门</a></li>
|
||||
<li class="active"><a href="#">本部门下属部门</a></li>
|
||||
<li class="divider"></li>
|
||||
<li class=""><a href="#">自定义</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="btn-group m-l-xs" role="group">
|
||||
<button type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="fa fa-filter"></span> 本月
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="#">今天</a></li>
|
||||
<li><a href="#">昨天</a></li>
|
||||
<li><a href="#">本周</a></li>
|
||||
<li><a href="#">上周</a></li>
|
||||
<li class="active"><a href="#">本月</a></li>
|
||||
<li><a href="#">上月</a></li>
|
||||
<li><a href="#">本季度</a></li>
|
||||
<li><a href="#">上季度</a></li>
|
||||
<li><a href="#">本年</a></li>
|
||||
<li><a href="#">去年</a></li>
|
||||
<li class="divider"></li>
|
||||
<li class=""><a href="#">自定义</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-widget-header">
|
||||
<div class="row-quick m-t-sm">
|
||||
<div class="row row-sm">
|
||||
@forelse($quicks as $quick)
|
||||
<div class="quick-text">
|
||||
<a href="javascript:;" data-toggle="addtab" data-url="{{$quick['url']}}" data-id="{{$quick['key']}}" data-name="{{$quick['name']}}">
|
||||
<div class="quick-icon quick-item" style="background-color:{{$quick['color']}}" data-url="{{$quick['url']}}" data-key="{{$quick['key']}}">
|
||||
<i class="fa fa-3x {{$quick['icon']}}"></i>
|
||||
<span class="quick-num">0</span>
|
||||
</div>
|
||||
<div class="title">{{$quick['name']}}</div>
|
||||
</a>
|
||||
</div>
|
||||
@empty
|
||||
<div class="quick-text">
|
||||
<a href="javascript:;" data-toggle="dashboard-config">
|
||||
<div class="quick-icon" style="background-color:#13D06C;">
|
||||
<i class="fa fa-3x fa-plus"></i>
|
||||
</div>
|
||||
<div class="title">添加快捷</div>
|
||||
</a>
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row row-sm row-info">
|
||||
@foreach($infos as $info)
|
||||
@if($info['status'])
|
||||
<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">
|
||||
|
||||
<div class="panel panel-shadow">
|
||||
<div class="info-l hidden-xs bg-{{$info['color']}}">
|
||||
<i class="fa fa-2x {{$info['icon']}}"></i>
|
||||
</div>
|
||||
<div class="info-c">
|
||||
<div class="info-name">{{$info['name']}}</div>
|
||||
<a href="javascript:;" data-toggle="addtab" data-url="{{$info['more_url']}}" data-id="{{str_replace(['/', '?', '='], ['_', '_', '_'], $info['more_url'])}}" data-name="{{$info['name']}}">
|
||||
<div class="text-info info-item" data-url="{{$info['url']}}" data-more_url="{{$info['more_url']}}"></div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="info-r">
|
||||
<div>较上月</div>
|
||||
<div class="rate">50%</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="row row-sm row-widget">
|
||||
@foreach($grids as $grid)
|
||||
<div class="col-xs-12 col-sm-{{$grid}}">
|
||||
@foreach($widgets as $widget)
|
||||
@if($widget['status'])
|
||||
@if($widget['grid'] == $grid)
|
||||
<div class="panel panel-shadow">
|
||||
<div class="panel-heading text-base b-b">
|
||||
<div class="pull-right"></div>
|
||||
<a data-toggle='widget-refresh' data-url="{{$widget['url']}}" data-key="{{str_replace(['/', '?', '='], ['_', '_', '_'], $widget['url'])}}" data-id="{{$widget['id']}}">{{$widget['name']}}</a>
|
||||
</div>
|
||||
<div class="widget-item" id="widget_item_{{$widget['id']}}" data-url="{{$widget['url']}}">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-footer">
|
||||
<div class="box">
|
||||
{{$version}} {{$openSource ? '开源版' : '企业版'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.ag-theme-balham .ag-root {
|
||||
border: 0;
|
||||
}
|
||||
.ag-theme-balham .ag-status-bar {
|
||||
border: 0;
|
||||
}
|
||||
.ag-theme-balham .ag-header {
|
||||
background-color: #fff;
|
||||
}
|
||||
.ag-theme-balham .ag-header-cell, .ag-theme-balham .ag-header-group-cell {
|
||||
border-right: transparent;
|
||||
}
|
||||
.ag-theme-balham .ag-ltr .ag-cell {
|
||||
border-width: 0 0 0 0;
|
||||
border-right-color: #d9dcde;
|
||||
}
|
||||
.ag-theme-balham .ag-header-cell::after, .ag-theme-balham .ag-header-group-cell::after {
|
||||
border-right: 1px solid rgba(189, 195, 199, 0.5);
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
(function($) {
|
||||
var $document = $(document);
|
||||
|
||||
var myProcess = null;
|
||||
|
||||
function widgetRefresh() {
|
||||
if (myProcess) {
|
||||
var items = $('.widget-item');
|
||||
items.each(function(index, item) {
|
||||
var data = $(item).data();
|
||||
if (data.key) {
|
||||
gdoo.widgets[data.key].remoteData({page: 1});
|
||||
console.log('refresh item:' + data.key);
|
||||
}
|
||||
});
|
||||
}
|
||||
myProcess = setTimeout(function() {
|
||||
widgetRefresh();
|
||||
}, 1000 * 60 * 5);
|
||||
}
|
||||
|
||||
widgetRefresh();
|
||||
|
||||
$document.on('click', '[data-toggle="addtab"]', function(event) {
|
||||
event.preventDefault();
|
||||
// 触屏设备不触发事件
|
||||
var mq = top.checkMQ();
|
||||
if ($(this).parent().find('ul').length) {
|
||||
if(mq == 'mobile' || mq == 'tablet') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 无ID不触发事件
|
||||
var data = $(this).data();
|
||||
if(data.id == undefined) {
|
||||
return false;
|
||||
}
|
||||
top.addTab(data.url, data.id, data.name);
|
||||
});
|
||||
|
||||
$('[data-toggle="dashboard-config"]').on('click', function() {
|
||||
formDialog({
|
||||
title: '仪表盘设置',
|
||||
url: app.url('index/dashboard/config'),
|
||||
id: 'widget-edit',
|
||||
dialogClass:'modal-lg',
|
||||
success: function(res) {
|
||||
location.reload();
|
||||
toastrSuccess(res.data);
|
||||
$(this).dialog("close");
|
||||
},
|
||||
error: function(res) {
|
||||
toastrError(res.data);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('[data-toggle="widget-refresh"]').on('click', function() {
|
||||
var data = $(this).data();
|
||||
if (data.key) {
|
||||
gdoo.widgets[data.key].remoteData({page: 1});
|
||||
}
|
||||
});
|
||||
|
||||
function widgetInit() {
|
||||
var items = $('.widget-item');
|
||||
items.each(function(index, item) {
|
||||
var data = $(item).data();
|
||||
if (data == undefined) {
|
||||
return false;
|
||||
}
|
||||
if (data.url) {
|
||||
$(item).load(app.url(data.url, {id: data.id}));
|
||||
}
|
||||
});
|
||||
|
||||
var items = $('.info-item');
|
||||
items.each(function(index, item) {
|
||||
var me = $(item);
|
||||
var data = me.data();
|
||||
$.get(app.url('index/index/info', {type: data.url}), function(res) {
|
||||
if(res > 0) {
|
||||
me.removeClass('text-info').addClass('text-danger');
|
||||
} else {
|
||||
me.removeClass('text-danger').addClass('text-info');
|
||||
}
|
||||
me.text(res);
|
||||
});
|
||||
});
|
||||
|
||||
var items = $('.quick-item');
|
||||
items.each(function(index, item) {
|
||||
var me = $(item);
|
||||
var data = me.data();
|
||||
$.get(app.url('index/index/badge', {key: data.key}), function(res) {
|
||||
if(res.total > 0) {
|
||||
me.find('.quick-num').show().text(res.total);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
widgetInit();
|
||||
|
||||
})(jQuery);
|
||||
</script>
|
|
@ -5,7 +5,7 @@
|
|||
软件版本
|
||||
</td>
|
||||
<td align="left" style="border-top:0;">
|
||||
{{$version}} {{$openSource ? '开源版' : '企业版'}}
|
||||
{{$version}} {{$licenseType ? $licenseType : '开源版'}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -26,11 +26,19 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td align="right">
|
||||
支持方式
|
||||
联系方式
|
||||
</td>
|
||||
<td align="left">
|
||||
15182223008(电话/微信)
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">
|
||||
QQ交流群
|
||||
</td>
|
||||
<td align="left">
|
||||
79446405
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -225,9 +225,9 @@
|
|||
<label for="set_col">打印方式</label>
|
||||
<div class="form-text">
|
||||
<select class="input-select2 form-control input-sm" id="print_type" name="print_type" data-width="100%">
|
||||
<option value=""> </option>
|
||||
<option value="html" @if($template['print_type'] == 'html') selected @endif>html</option>
|
||||
<option value="stiReport" @if($template['print_type'] == 'stiReport') selected @endif>StiReport</option>
|
||||
<option value="pdf" @if($template['print_type'] == 'pdf') selected @endif>pdf</option>
|
||||
<option value="stiReport" @if($template['print_type'] == 'stiReport') selected @endif>stiReport</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -773,50 +773,40 @@ class OrderController extends WorkflowController
|
|||
// 显示促销
|
||||
public function printAction()
|
||||
{
|
||||
$this->layout = 'layouts.print2';
|
||||
|
||||
$id = Request::get('id');
|
||||
$template_id = Request::get('template_id');
|
||||
if ($template_id == 121) {
|
||||
$template = DB::table('model_template')->where('id', $template_id)->first();
|
||||
$print_type = $template['print_type'];
|
||||
$this->layout = 'layouts.print_'.$print_type;
|
||||
$print_tpl = view()->exists(Request::controller().'.print.'.$template_id);
|
||||
|
||||
$master = DB::table('customer_order as co')->where('co.id', $id)
|
||||
->leftJoin('customer as c', 'c.id', '=', 'co.customer_id')
|
||||
->leftJoin('customer_tax as ct', 'ct.id', '=', 'co.tax_id')
|
||||
->leftJoin('sale_type as st', 'st.id', '=', 'co.type_id')
|
||||
->selectRaw('co.*, ct.name as tax_name, c.name as customer_name, st.name as type_name')
|
||||
->first();
|
||||
$form = [
|
||||
'template' => $template,
|
||||
];
|
||||
|
||||
$rows = DB::table('customer_order_data as cod')
|
||||
->leftJoin('customer_order as co', 'co.id', '=', 'cod.order_id')
|
||||
->leftJoin('product as p', 'p.id', '=', 'cod.product_id')
|
||||
->leftJoin('product_unit as pu', 'pu.id', '=', 'p.unit_id')
|
||||
->leftJoin('customer_order_type as cot', 'cot.id', '=', 'cod.type_id')
|
||||
->where('co.id', $id)
|
||||
->selectRaw('
|
||||
cod.*,
|
||||
cod.delivery_quantity * p.weight as total_weight,
|
||||
p.name as product_name,
|
||||
p.spec as product_spec,
|
||||
cot.name as type_name,
|
||||
pu.name as product_unit,
|
||||
p.material_type,
|
||||
p.product_type
|
||||
')
|
||||
->get();
|
||||
|
||||
$form = [
|
||||
'template' => DB::table('model_template')->where('id', $template_id)->first()
|
||||
];
|
||||
|
||||
$tpl = $this->display([
|
||||
'master' => $master,
|
||||
'rows' => $rows,
|
||||
'form' => $form,
|
||||
], 'print/'.$template_id);
|
||||
} else {
|
||||
$tpl = $this->createAction('print');
|
||||
if ($print_tpl) {
|
||||
$data = OrderService::getPrintData($id);
|
||||
$data['form'] = $form;
|
||||
$data['template'] = $template;
|
||||
$tpl = $this->display($data, 'print/'.$template_id);
|
||||
return $print_type == 'pdf' ? print_prince($tpl) : $tpl;
|
||||
}
|
||||
print_prince($tpl);
|
||||
|
||||
if ($print_type == 'stiReport') {
|
||||
$data = OrderService::getPrintData($id);
|
||||
$print_data = [
|
||||
'master' => [$data['master']],
|
||||
'money' => $data['money'],
|
||||
'customer_order_data' => $data['rows'],
|
||||
];
|
||||
return $this->display([
|
||||
'template' => $template,
|
||||
'print_data' => $print_data,
|
||||
]);
|
||||
}
|
||||
|
||||
$tpl = $this->createAction('print');
|
||||
return $print_type == 'pdf' ? print_prince($tpl) : $tpl;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,6 +14,42 @@ class OrderService
|
|||
return BadgeService::getModelTodo('customer_order');
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义查询打印数据
|
||||
*/
|
||||
public static function getPrintData($id)
|
||||
{
|
||||
$master = DB::table('customer_order as co')->where('co.id', $id)
|
||||
->leftJoin('customer as c', 'c.id', '=', 'co.customer_id')
|
||||
->leftJoin('customer_tax as ct', 'ct.id', '=', 'co.tax_id')
|
||||
->leftJoin('sale_type as st', 'st.id', '=', 'co.type_id')
|
||||
->selectRaw('co.*, ct.name as tax_name, c.name as customer_name, st.name as type_name')
|
||||
->first();
|
||||
|
||||
$rows = DB::table('customer_order_data as cod')
|
||||
->leftJoin('customer_order as co', 'co.id', '=', 'cod.order_id')
|
||||
->leftJoin('product as p', 'p.id', '=', 'cod.product_id')
|
||||
->leftJoin('product_unit as pu', 'pu.id', '=', 'p.unit_id')
|
||||
->leftJoin('customer_order_type as cot', 'cot.id', '=', 'cod.type_id')
|
||||
->where('co.id', $id)
|
||||
->selectRaw('
|
||||
cod.*,
|
||||
cod.delivery_quantity * p.weight as total_weight,
|
||||
p.name as product_name,
|
||||
p.spec as product_spec,
|
||||
cot.name as type_name,
|
||||
pu.name as product_unit,
|
||||
p.material_type,
|
||||
p.product_type
|
||||
')
|
||||
->get();
|
||||
|
||||
return [
|
||||
'master' => $master,
|
||||
'rows' => $rows,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取为使用的促销id
|
||||
*
|
||||
|
|
|
@ -123,7 +123,7 @@ class TaskController extends DefaultController
|
|||
'name' => $_item['name'],
|
||||
'type' => $_item['type'],
|
||||
'created_at' => '',
|
||||
'user_id' => '',
|
||||
'user_id' => 0,
|
||||
'user_name' => '',
|
||||
'open' => true,
|
||||
'option_edit' => $project_user_id,
|
||||
|
@ -154,7 +154,9 @@ class TaskController extends DefaultController
|
|||
$_task['open'] = true;
|
||||
$_task['loaded'] = true;
|
||||
$_task['expanded'] = true;
|
||||
$_task['created_at'] = format_datetime($_item['created_at']);
|
||||
$_task['created_dt'] = format_datetime($_task['created_at']);
|
||||
$_task['start_dt'] = format_datetime($_task['start_at']);
|
||||
$_task['end_dt'] = format_datetime($_task['end_at']);
|
||||
|
||||
if ($_task['start_at'] && $_task['end_at']) {
|
||||
$remain = remain_time($_task['start_at'], $_task['end_at'], '');
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
<script src="{{$asset_url}}/vendor/dhtmlxgantt/dhtmlxgantt_tooltip.js" type="text/javascript"></script>
|
||||
<script src="{{$asset_url}}/vendor/dhtmlxgantt/locale_cn.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" href="{{$asset_url}}/vendor/dhtmlxgantt/dhtmlxgantt.css" type="text/css">
|
||||
<!--
|
||||
<script src="https://export.dhtmlx.com/gantt/api.js"></script>
|
||||
-->
|
||||
<style type="text/css">
|
||||
/* 新样式 */
|
||||
html, body {
|
||||
|
@ -126,9 +123,6 @@ html, body {
|
|||
<a href="{{url('index', ['project_id' => $project['id'], 'tpl' => 'board'])}}" class="btn btn-sm btn-default @if($query['tpl'] == 'board') active @endif">看板</a>
|
||||
-->
|
||||
</div>
|
||||
<!--
|
||||
<input value="导出PDF" class="btn btn-sm btn-default" type="button" onclick='exportToPDF()'>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<a href="{{url($referer)}}" class="btn btn-sm btn-default"><i class="fa fa-reply"></i> 返回</a>
|
||||
|
@ -158,9 +152,7 @@ html, body {
|
|||
</script>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="gantt-view"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
@ -189,7 +181,6 @@ gantt.config.show_links = false;
|
|||
gantt.config.order_branch = true;
|
||||
|
||||
// gantt.config.order_branch_free = true;
|
||||
|
||||
/*
|
||||
var date_to_str = gantt.date.date_to_str(gantt.config.api_date);
|
||||
var today = new Date();
|
||||
|
@ -244,13 +235,13 @@ gantt.templates.tooltip_text = function(start, end, task) {
|
|||
gantt.attachEvent('onTaskDblClick', function (task_id) {
|
||||
var task = gantt.getTask(task_id);
|
||||
if(task.type == 'item') {
|
||||
editItem(task_id);
|
||||
editItem(task);
|
||||
}
|
||||
if(task.type == 'task') {
|
||||
editTask(task_id);
|
||||
editTask(task);
|
||||
}
|
||||
if(task.type == 'subtask') {
|
||||
editSubTask(task_id);
|
||||
editSubTask(task);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -279,22 +270,17 @@ gantt.attachEvent('onBeforeTaskDrag', function(task_id, mode, e) {
|
|||
});
|
||||
|
||||
gantt.attachEvent('onAfterTaskDrag', function(task_id, mode, e) {
|
||||
|
||||
var task = gantt.getTask(task_id);
|
||||
|
||||
var data = {id: task.id,progress: task.progress};
|
||||
|
||||
var date_to_str = gantt.date.date_to_str(gantt.config.api_date);
|
||||
data.start_date = date_to_str(task.start_date);
|
||||
data.end_date = date_to_str(task.end_date);
|
||||
|
||||
data.end_date = date_to_str(task.end_date);
|
||||
$.post('{{url("drag")}}', data, function(res) {
|
||||
gantt.render();
|
||||
}, 'json');
|
||||
});
|
||||
|
||||
gantt._do_autosize = function() {
|
||||
|
||||
// 设置高度
|
||||
var height = $('#gantt-wrapper').outerHeight();
|
||||
var iframeHeight = $(window).height();
|
||||
|
@ -327,29 +313,15 @@ $('#search-submit').on('click', function() {
|
|||
$.map(query, function(row) {
|
||||
params[row.name] = row.value;
|
||||
});
|
||||
|
||||
dataReload();
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
function exportToPDF()
|
||||
{
|
||||
gantt.exportToPDF({
|
||||
locale:"cn",
|
||||
skin:'terrace',
|
||||
});
|
||||
}
|
||||
|
||||
function dataReload() {
|
||||
gantt.clearAll();
|
||||
gantt.load(app.url('project/task/index', params));
|
||||
}
|
||||
|
||||
function getTask(id) {
|
||||
return gantt.getTask(id);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@include('task/index/js')
|
|
@ -45,14 +45,14 @@ var auth_id = '{{auth()->id()}}';
|
|||
|
||||
function progressRenderer(params) {
|
||||
var data = params.data;
|
||||
if (data.type == 'task' || data.type == 'subtask') {
|
||||
if (params.value == 1) {
|
||||
return '<span class="label label-success">已完成</span>';
|
||||
} else {
|
||||
return '<span class="label label-' + (auth_id == data.user_id ? 'danger' : 'info') + '">进行中</span>';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
if (data.type == 'task' || data.type == 'subtask') {
|
||||
if (params.value == 1) {
|
||||
return '<div class="label label-success">已完成</div>';
|
||||
} else {
|
||||
return '<div class="label label-' + (auth_id == data.user_id ? 'danger' : 'info') + '">进行中</div>';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function durationRenderer(params) {
|
||||
|
@ -94,23 +94,23 @@ function durationRenderer(params) {
|
|||
{cellClass:'text-center', sortable: false, field: 'user_name', headerName: '执行者', width: 140},
|
||||
{cellClass:'text-center', sortable: false, field: 'users', headerName: '参与者', minWidth: 200},
|
||||
{cellClass:'text-center', cellRenderer: progressRenderer, sortable: false, field: 'progress', headerName: '状态', width: 100},
|
||||
{cellClass:'text-center', sortable: false, field: 'start_at', headerName: '开始时间', width: 120},
|
||||
{cellClass:'text-center', sortable: false, field: 'end_at', headerName: '结束时间', width: 120},
|
||||
{cellClass:'text-center', sortable: false, field: 'start_dt', headerName: '开始时间', width: 120},
|
||||
{cellClass:'text-center', sortable: false, field: 'end_dt', headerName: '结束时间', width: 120},
|
||||
{cellClass:'text-center', cellRenderer: durationRenderer, sortable: false, field: 'duration_date', headerName: '持续时间', width: 100},
|
||||
{cellClass:'text-center', sortable: false, field: 'created_at', headerName: '创建时间', width: 140},
|
||||
{cellClass:'text-center', field: 'id', headerName: 'ID', width: 80}
|
||||
{cellClass:'text-center', sortable: false, field: 'created_dt', headerName: '创建时间', width: 140},
|
||||
//{cellClass:'text-center', field: 'id', headerName: 'ID', width: 80}
|
||||
);
|
||||
|
||||
grid.onRowDoubleClicked = function (row) {
|
||||
var data = row.data;
|
||||
if(data.type == 'item') {
|
||||
editItem(data.id);
|
||||
editItem(data);
|
||||
}
|
||||
if(data.type == 'task') {
|
||||
editTask(data.id);
|
||||
editTask(data);
|
||||
}
|
||||
if(data.type == 'subtask') {
|
||||
editSubTask(data.id);
|
||||
editSubTask(data);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -142,9 +142,9 @@ function dataReload() {
|
|||
}
|
||||
|
||||
function getTask(id) {
|
||||
console.log(grid.api.getRowNode(id));
|
||||
return grid.api.getRowNode(id);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@include('task/index/js')
|
|
@ -1,5 +1,4 @@
|
|||
<script>
|
||||
|
||||
function formsBox(title, url, id, success, remove, error)
|
||||
{
|
||||
var options = {
|
||||
|
@ -67,12 +66,10 @@ function addItem() {
|
|||
});
|
||||
}
|
||||
|
||||
function editItem(id) {
|
||||
function editItem(task) {
|
||||
|
||||
var fun_edit = null, fun_delete = null;
|
||||
|
||||
var task = getTask(id);
|
||||
|
||||
if(task.option_edit == 1) {
|
||||
fun_edit = function(res) {
|
||||
saveResult.call(this, res);
|
||||
|
@ -84,14 +81,14 @@ function editItem(id) {
|
|||
var me = this;
|
||||
$.messager.confirm('操作警告', '确定要删除任务列表吗?', function(btn) {
|
||||
if (btn == true) {
|
||||
$.post(app.url('project/task/delete'), {id: id}, function(res) {
|
||||
$.post(app.url('project/task/delete'), {id: task.id}, function(res) {
|
||||
saveResult.call(me, res);
|
||||
},'json');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
formsBox('编辑任务列表', app.url('project/task/edit', {type:'item',id:id}), 'item-form-'+ id, fun_edit, fun_delete);
|
||||
formsBox('编辑任务列表', app.url('project/task/edit', {type:'item',id:task.id}), 'item-form-'+ task.id, fun_edit, fun_delete);
|
||||
}
|
||||
|
||||
function addTask() {
|
||||
|
@ -100,12 +97,10 @@ function addTask() {
|
|||
});
|
||||
}
|
||||
|
||||
function editTask(id) {
|
||||
function editTask(task) {
|
||||
|
||||
var fun_edit = null, fun_delete = null;
|
||||
|
||||
var task = getTask(id);
|
||||
|
||||
if(task.option_edit == 1) {
|
||||
fun_edit = function(res) {
|
||||
saveResult.call(this, res);
|
||||
|
@ -117,14 +112,14 @@ function editTask(id) {
|
|||
var me = this;
|
||||
$.messager.confirm('操作警告', '确定要删除任务吗?', function(btn) {
|
||||
if (btn == true) {
|
||||
$.post(app.url('project/task/delete'), {id: id}, function(res) {
|
||||
$.post(app.url('project/task/delete'), {id: task.id}, function(res) {
|
||||
saveResult.call(me, res);
|
||||
}, 'json');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
formsBox('编辑任务', app.url('project/task/edit', {type:'task',id:id}), 'task-form-'+ id, fun_edit, fun_delete);
|
||||
formsBox('编辑任务', app.url('project/task/edit', {type:'task', id:task.id}), 'task-form-'+ task.id, fun_edit, fun_delete);
|
||||
}
|
||||
|
||||
function addSubTask(id) {
|
||||
|
@ -140,12 +135,10 @@ function addSubTask(id) {
|
|||
});
|
||||
}
|
||||
|
||||
function editSubTask(id) {
|
||||
function editSubTask(task) {
|
||||
|
||||
var fun_edit = null, fun_delete = null;
|
||||
|
||||
var task = getTask(id);
|
||||
|
||||
if(task.option_edit == 1) {
|
||||
fun_edit = function(res) {
|
||||
saveResult.call(this, res);
|
||||
|
@ -157,14 +150,14 @@ function editSubTask(id) {
|
|||
var me = this;
|
||||
$.messager.confirm('操作警告', '确定要删除任务吗?', function(btn) {
|
||||
if (btn == true) {
|
||||
$.post(app.url('project/task/delete'), {id: id}, function(res) {
|
||||
$.post(app.url('project/task/delete'), {id: task.id}, function(res) {
|
||||
saveResult.call(me, res);
|
||||
}, 'json');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
formsBox('编辑子任务', app.url('project/task/edit', {type:'subtask',id:id}), 'task-form-'+ id, fun_edit, fun_delete);
|
||||
formsBox('编辑子任务', app.url('project/task/edit', {type:'subtask',id:task.id}), 'task-form-'+ task.id, fun_edit, fun_delete);
|
||||
}
|
||||
|
||||
function addComment(task_id) {
|
||||
|
@ -190,9 +183,7 @@ function editComment(id) {
|
|||
saveResult.call(me, res);
|
||||
}, 'json');
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
|
@ -14,7 +14,7 @@ class StiReportController extends DefaultController
|
|||
public function designerAction()
|
||||
{
|
||||
$template_id = (int)Request::get('template_id');
|
||||
$template = DB::table('flow_template')->where('id', $template_id)->first();
|
||||
$template = DB::table('model_template')->where('id', $template_id)->first();
|
||||
// 报表名称
|
||||
$report_name = "{$template['code']}";
|
||||
$report_file = '';
|
||||
|
@ -42,9 +42,4 @@ class StiReportController extends DefaultController
|
|||
$success = ['success' => true, 'msg' => "保存成功:".$fileName];
|
||||
return $success;
|
||||
}
|
||||
|
||||
public function licenseAction()
|
||||
{
|
||||
echo "6vJhGtLLLz2GNviWmUTrhSqnOItdDwjBylQzQcAOiHlrzAZzmWmSnQQ4gKFiZ4LJpJv//QjFVXxcHAVbzZfXjyOGPmj/m+BEjr2Z14dWeqLFNGF74GELbTTKs2+Le/9cDIWdGNnOpEK2aGdYllauMPLQsiScC521JIEYSdOspiRHSLcegksxfNedJjyIjGlfI2YrddBRWGiO+uWOHE5oz9hLG8VPBSRo60KmgkscM5X+7+aQ+6vzKKOC2XB+e6BMQC5qNVBUblfGQR2EjNLZKmSJtvek7IbG/OK+XP0j2bwicyJUGC0pyLHqctr3BpcO/gA5LoVfuwqYG3klL//owBkObPPhJV1HD6XsHL0GDryssJFaDCQIyXMrOn7hNQNkEIyx+AJDNgf5XfxPgEgFsRhYCPYq7ccutg2by8duOxbF3xH0gL/uAQN275COXJBV3W62DSLM+o8azChG+Z7y0dF9f4whZ/SKD4DwNPUWK7osEPVwl5BY+0lkdqd67fatlrlc0QU/ZX9f5QcTKfl5ljuNc+kcqxmd9NND6Xzrw9gFsFqIWqqVo++DdoAZFStXMkOp/nTNBQMRA100k3vi2SbbiHq/gVimrQecUhWG0qU5zcemtVGDMs1ruXsoHX8pYX/rMJHH09qCWllVyBykkTLourYEig9g5fhKDYRV05aC0cWsbxR2nj9TH3SLmG4P2Px7uJsq6iOsnIHWuBMwk8oF7xPEugjw+x8lkjVVoV8WWBSdjIxGh4LviZXBEJm9FTJzYcnEHMZRh0uVE1g8crC+TfRVii7dcdZzeQklzyNY+0Q1/hRaIUs+mNPRiqG6YqEv3f+yG4ncxzkCWZDvXPox87y61jbg6Dg73X1RAwwvbIXuJVANbaDOefUELPmpz4SIpHx8zpLSmn1H1u0PolbsimLigcGw2bJQeuU++OBU74vJJde3JdoO6IOfmUJkoxprdszyknLm+zWgnC+jjaCtEZZuOIJqyuVPoqHRiFkqNjbddkvGMmj/4+2D6BdYQot9sEOW7iCgV4SvZ/efC0NlRX+Z+6PODwKJiO+Sen5aAlsJcL2jIUSAjgyS+7im7XTGlYKuRL59EQjA5HArO1ikJ0P/2pk4u91z2J8GRvTPu5BZUI9M0BLGLAVCFMte4JQCOr+f785RgjerSNCSgN4Mfa5+jDQAKTAVAO5tqT/SBEm0M5U1EylQ/fbseKt+dQ1/VzqlQ9SH14jtI0J97ACqk9SBt9xpTgBnJrBSTnnY21l2zWS7/2k5U9LPDJn0Lm32ueoDRFaM4JeK1HoSi2HvOYy1V1hU5pCe893QsBE/HOVp4UWu9lfiEWunHEEdPZOUPgc131KwJrM4K3DYiBbXl442TgbNLfz5IBnAw1NVabMXXyx2LOi6x35xw1YLMRYNWYE9QpocBhoFQtStd2OUZ5CqvxhXf+VaLK3hmm1GvlqpUK6LIDd3eyuQK4f0E7+zVSBaV6eSDI9YJC42Ee+Br8AByGYLRaFISpDculGt2nqwFL6cwltv1Xy11frJR2KqbR8sd6dI0V69XnwBziRzJq1SyAZd9bzClYSpA3ZYPN9ghdaHA+GZak0IYMokWLi6oYquOCRoy8f0sEQM2Uhw2x/E9tgyNoLZhDhrk805/VCsThI5fHn0YWVnmQZTrGkOwnoqLw3VHb7akUmNnjMlk/tD59bR2lgD+fnNuNsBYDDjJpg+fKmgf9araTPEIpuuanp53e6xodRYKIj4o4+39DrPK10eR4CDfSh5UShvnCZz+V0FAkIkoM92U1JTU59P4M4pzc8PswmS1rGTRaZMUrTYrjeGCHC9Hl0CTIR1/rQAx8iIcC3yVNCeiTJAmKMCl830O4GpEfduNHQgDrlsJC4q6RA7J2kUzW2WQvKFKH3bRH1hOc6LZK4DmwMGzXMKDKOxK0dzld2/ImRN6DbPacV/4d0HK06qBOFEgUJqXhMpV1JjsXVvmx/m2LCRgkD5vPEwcuiWtWde7tISLCEg6hjAV9+Hx6zOWpozg7aZMtikT+43uWakRkU/H+ITIGhqxuQhkZkmIddWrjD5lJtdUOSa0FWu969EDp4XB8dmUKSwyrkgOHZu6DutFW5ArtqhNejthWt/sV1FkSbvdd26zn1fSO4pDa4pDmcSo+l/4DChZbEyICc7IQrPjVuRUlVGuAVksZTBX+VYIip8LsJSFLHo7Dnn4QT3qDNIh8aAcY3fnHhph4G5ekbvGOw3+m1qqs8t0m89vdK7k8nJTw==";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ use Gdoo\Model\Services\StepService;
|
|||
use Gdoo\Stock\Services\StockService;
|
||||
|
||||
use Gdoo\Index\Controllers\WorkflowController;
|
||||
use Gdoo\Stock\Services\DeliveryService;
|
||||
|
||||
class DeliveryController extends WorkflowController
|
||||
{
|
||||
|
@ -312,71 +313,41 @@ class DeliveryController extends WorkflowController
|
|||
{
|
||||
$id = Request::get('id');
|
||||
$template_id = Request::get('template_id');
|
||||
|
||||
$master = DB::table('stock_delivery as sd')
|
||||
->leftJoin('customer as c', 'c.id', '=', 'sd.customer_id')
|
||||
->leftJoin('customer_tax as ct', 'ct.id', '=', 'sd.tax_id')
|
||||
->leftJoin('sale_type as st', 'st.id', '=', 'sd.type_id')
|
||||
->selectRaw('sd.*, ct.name as tax_name, c.name as customer_name, st.name as type_name')
|
||||
->where('sd.id', $id)
|
||||
->first();
|
||||
|
||||
$model = DB::table('stock_delivery_data as sdd')
|
||||
->leftJoin('stock_delivery as sd', 'sd.id', '=', 'sdd.delivery_id')
|
||||
->leftJoin('product as p', 'p.id', '=', 'sdd.product_id')
|
||||
->leftJoin('product_unit as pu', 'pu.id', '=', 'p.unit_id')
|
||||
->leftJoin('customer_order_type as cot', 'cot.id', '=', 'sdd.type_id')
|
||||
->leftJoin('warehouse as w', 'w.id', '=', 'sdd.warehouse_id');
|
||||
|
||||
if ($template_id == 112) {
|
||||
$model->where('sd.print_master_id', $master['print_master_id']);
|
||||
} else {
|
||||
$model->where('sdd.delivery_id', $id);
|
||||
}
|
||||
|
||||
$model->whereRaw("p.code <> '99001'");
|
||||
|
||||
$rows = $model->selectRaw("
|
||||
sdd.*,
|
||||
p.name as product_name,
|
||||
p.spec as product_spec,
|
||||
cot.name as type_name,
|
||||
pu.name as product_unit,
|
||||
p.material_type,
|
||||
p.product_type,
|
||||
SUBSTRING(batch_sn, 3, 4) as batch_sn,
|
||||
case when right(w.name, 4) = '不满件库' then 'B' else '' end warehouse_type
|
||||
")
|
||||
->orderBy('p.code', 'asc')
|
||||
->get();
|
||||
|
||||
$money = DB::table('stock_delivery_data as sdd')
|
||||
->leftJoin('product as p', 'p.id', '=', 'sdd.product_id')
|
||||
->where('sdd.delivery_id', $id)
|
||||
->whereRaw("p.code = '99001'")
|
||||
->sum("money");
|
||||
|
||||
$template = DB::table('model_template')->where('id', $template_id)->first();
|
||||
$print_type = $template['print_type'];
|
||||
// 存在打印模板
|
||||
$print_tpl = view()->exists(Request::controller().'.print.'.$template_id);
|
||||
$this->layout = 'layouts.print_'.$print_type;
|
||||
$form = [
|
||||
'template' => DB::table('model_template')->where('id', $template_id)->first()
|
||||
'template' => $template,
|
||||
];
|
||||
|
||||
if ($template_id == 87) {
|
||||
$this->layout = 'layouts.print_stiReport';
|
||||
return $this->display([
|
||||
'master' => $master,
|
||||
'money' => $money,
|
||||
'rows' => $rows,
|
||||
'form' => $form,
|
||||
], 'print/'.$template_id);
|
||||
} else {
|
||||
$this->layout = 'layouts.print2';
|
||||
print_prince($this->display([
|
||||
'master' => $master,
|
||||
'money' => $money,
|
||||
'rows' => $rows,
|
||||
'form' => $form,
|
||||
], 'print/'.$template_id));
|
||||
// 自定义模板
|
||||
if ($print_tpl) {
|
||||
$data = DeliveryService::getPrintData($id);
|
||||
$data['form'] = $form;
|
||||
$data['template'] = $template;
|
||||
$tpl = $this->display($data, 'print/'.$template_id);
|
||||
return $print_type == 'pdf' ? print_prince($tpl) : $tpl;
|
||||
}
|
||||
|
||||
// 打印插件
|
||||
if ($print_type == 'stiReport') {
|
||||
$data = DeliveryService::getPrintData($id);
|
||||
$print_data = [
|
||||
'master' => [$data['master']],
|
||||
'money' => $data['money'],
|
||||
'stock_delivery_data' => $data['rows'],
|
||||
];
|
||||
return $this->display([
|
||||
'template' => $template,
|
||||
'print_data' => $print_data,
|
||||
]);
|
||||
}
|
||||
|
||||
// 默认模板
|
||||
$tpl = $this->createAction('print');
|
||||
return $print_type == 'pdf' ? print_prince($tpl) : $tpl;
|
||||
}
|
||||
|
||||
// 物流信息
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
<?php namespace Gdoo\Stock\Services;
|
||||
|
||||
use DB;
|
||||
|
||||
class DeliveryService
|
||||
{
|
||||
/**
|
||||
* 自定义查询打印数据
|
||||
*/
|
||||
public static function getPrintData($id, $print_master_id = false)
|
||||
{
|
||||
$master = DB::table('stock_delivery as sd')
|
||||
->leftJoin('customer as c', 'c.id', '=', 'sd.customer_id')
|
||||
->leftJoin('customer_tax as ct', 'ct.id', '=', 'sd.tax_id')
|
||||
->leftJoin('sale_type as st', 'st.id', '=', 'sd.type_id')
|
||||
->selectRaw('sd.*, ct.name as tax_name, c.name as customer_name, st.name as type_name')
|
||||
->where('sd.id', $id)
|
||||
->first();
|
||||
|
||||
$model = DB::table('stock_delivery_data as sdd')
|
||||
->leftJoin('stock_delivery as sd', 'sd.id', '=', 'sdd.delivery_id')
|
||||
->leftJoin('product as p', 'p.id', '=', 'sdd.product_id')
|
||||
->leftJoin('product_unit as pu', 'pu.id', '=', 'p.unit_id')
|
||||
->leftJoin('customer_order_type as cot', 'cot.id', '=', 'sdd.type_id')
|
||||
->leftJoin('warehouse as w', 'w.id', '=', 'sdd.warehouse_id');
|
||||
|
||||
if ($print_master_id) {
|
||||
$model->where('sd.print_master_id', $master['print_master_id']);
|
||||
} else {
|
||||
$model->where('sdd.delivery_id', $id);
|
||||
}
|
||||
|
||||
$model->whereRaw("p.code <> '99001'");
|
||||
|
||||
$rows = $model->selectRaw("
|
||||
sdd.*,
|
||||
p.name as product_name,
|
||||
p.spec as product_spec,
|
||||
cot.name as type_name,
|
||||
pu.name as product_unit,
|
||||
p.material_type,
|
||||
p.product_type,
|
||||
batch_sn,
|
||||
case when right(w.name, 4) = '不满件库' then 'B' else '' end warehouse_type
|
||||
")
|
||||
->orderBy('p.code', 'asc')
|
||||
->get();
|
||||
|
||||
// 获取折扣额
|
||||
$money = DB::table('stock_delivery_data as sdd')
|
||||
->leftJoin('product as p', 'p.id', '=', 'sdd.product_id')
|
||||
->where('sdd.delivery_id', $id)
|
||||
->whereRaw("p.code = '99001'")
|
||||
->sum("money");
|
||||
|
||||
return [
|
||||
'master' => $master,
|
||||
'money' => $money,
|
||||
'rows' => $rows,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -159,7 +159,7 @@
|
|||
<tr>
|
||||
<td width="10%">特别说明</td>
|
||||
<td width="90%">
|
||||
收货时请按我司《随货单》点货验收。货物如有缺失或者破损,请与承运方协调,采取现场赔付,如协调无法达成一致意见,请第一时间告知我司并向承运方索取有效货物异常证明(贵司收货人与承运方双方签字认可的货物运单)回单至我司028-38296888并确认收到。
|
||||
收货时请按我司《随货单》点货验收。货物如有缺失或者破损,请与承运方协调,采取现场赔付,如协调无法达成一致意见,请第一时间告知我司并向承运方索取有效货物异常证明(贵司收货人与承运方双方签字认可的货物运单)回单至我司并确认收到。
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="utf-8">
|
||||
<title>{{$setting['title']}}</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
|
||||
<link href="{{$asset_url}}/dist/app.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="{{mix('/assets/dist/app.min.css')}}" rel="stylesheet" type="text/css">
|
||||
<script src="{{$asset_url}}/vendor/jquery.js"></script>
|
||||
</head>
|
||||
<style>
|
||||
|
|
|
@ -119,7 +119,7 @@ class UserService
|
|||
*/
|
||||
public static function wantsTotp()
|
||||
{
|
||||
if (env('AUTH_TOTP_STATUS', true) == false) {
|
||||
if (env('AUTH_TOTP', true) == false) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ body {
|
|||
|
||||
<div class="panel-body" style="padding:20px 30px 0 30px;">
|
||||
<div class="form-group">
|
||||
<input type="text" placeholder="账号" class="form-control" name="username" required>
|
||||
<input type="text" placeholder="账号" class="form-control" id="username" name="username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="password" placeholder="密码" class="form-control" name="password" required>
|
||||
|
@ -192,6 +192,17 @@ body {
|
|||
|
||||
<script>
|
||||
(function($) {
|
||||
|
||||
// 初始化获取的用户名
|
||||
let username = localStorage.getItem('remember_username');
|
||||
if (username) {
|
||||
$('#username').val(username);
|
||||
}
|
||||
// 记住用户名
|
||||
$("#username").on("input propertychange", function() {
|
||||
localStorage.setItem('remember_username', this.value);
|
||||
});
|
||||
|
||||
// ajax 登录
|
||||
$('#myform').on('submit', function () {
|
||||
var url = $(this).attr('action');
|
||||
|
@ -213,13 +224,15 @@ body {
|
|||
}, 'json');
|
||||
return false;
|
||||
});
|
||||
// 刷新验证码方法
|
||||
function refresh_captcha() {
|
||||
$('#captcha_image').attr('src', settings.public_url + '/user/auth/captcha?_=' + Math.random());
|
||||
}
|
||||
|
||||
// 刷新验证码
|
||||
$(document).on('click', '#refresh_captcha', function () {
|
||||
refresh_captcha();
|
||||
});
|
||||
|
||||
// 刷新验证码方法
|
||||
function refresh_captcha() {
|
||||
$('#captcha_image').attr('src', settings.public_url + '/user/auth/captcha?_=' + Math.random());
|
||||
}
|
||||
})(jQuery);
|
||||
</script>
|
|
@ -1559,10 +1559,6 @@ function encodeURIComponent($str)
|
|||
|
||||
function plugin_sync_api($uri, $data = [])
|
||||
{
|
||||
if (env('PLUGIN_SYNC_API_STATUS') === false) {
|
||||
return ['success' => true];
|
||||
}
|
||||
|
||||
$base_url = env('PLUGIN_SYNC_API_URL');
|
||||
if (empty($base_url)) {
|
||||
return ['success' => true];
|
||||
|
@ -1624,15 +1620,13 @@ function plugin_sync_api($uri, $data = [])
|
|||
function print_prince($view)
|
||||
{
|
||||
$viewData = $view->getData();
|
||||
$prince = new App\Support\Prince(env('PRINCE_DIR'));
|
||||
$file = storage_path() . '/print/' . auth()->id() . '.pdf';
|
||||
$ret = $prince->convert_string_to_file($view, $file);
|
||||
if ($ret) {
|
||||
try {
|
||||
$prince = new App\Support\Prince(env('PRINCE_DIR'));
|
||||
header('Content-Type:application/pdf');
|
||||
header('Content-Disposition:inline;filename="' . $viewData['form']['template']['name'] . '.pdf"');
|
||||
echo file_get_contents($file);
|
||||
} else {
|
||||
echo $ret;
|
||||
$prince->convert_string_to_passthru($view);
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Stimulsoft Reports.PHP</title>
|
||||
</head>
|
||||
<body>
|
||||
Stimulsoft Reports.PHP (JS version) - How to Activate
|
||||
<hr><br>
|
||||
|
||||
The Trial version of the product does not contain any restrictions, except for the Trial watermark on the report pages.<br><br>
|
||||
|
||||
To activate the product, it is enough to copy the 'license.key' file to the 'stimulsoft' subfolder of this project (in the same place, where is the 'license.php' file is located). The license will be loaded automatically. You can add some conditions in the 'license.php' script to load the license file, if it required for security.
|
||||
<br><br>
|
||||
|
||||
<a href="index.php">Back</a>
|
||||
</body>
|
|
@ -1,63 +0,0 @@
|
|||
<?php
|
||||
require_once 'stimulsoft/helper.php';
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>Stimulsoft Reports.PHP - JS Designer</title>
|
||||
|
||||
<!-- Office2013 style -->
|
||||
<link href="css/stimulsoft.viewer.office2013.whiteblue.css" rel="stylesheet">
|
||||
<link href="css/stimulsoft.designer.office2013.whiteblue.css" rel="stylesheet">
|
||||
|
||||
<!-- Stimulsoft Reports.JS -->
|
||||
<script src="scripts/stimulsoft.reports.js" type="text/javascript"></script>
|
||||
<script src="scripts/stimulsoft.viewer.js" type="text/javascript"></script>
|
||||
<script src="scripts/stimulsoft.designer.js" type="text/javascript"></script>
|
||||
|
||||
<?php
|
||||
$options = StiHelper::createOptions();
|
||||
$options->handler = "handler.php";
|
||||
$options->timeout = 30;
|
||||
StiHelper::initialize($options);
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
//Stimulsoft.Base.StiLicense.loadFromFile("stimulsoft/license.php");
|
||||
|
||||
var options = new Stimulsoft.Designer.StiDesignerOptions();
|
||||
options.appearance.fullScreenMode = true;
|
||||
options.toolbar.showSendEmailButton = true;
|
||||
options.appearance.showLocalization = false;
|
||||
options.appearance.zoom = 130;
|
||||
|
||||
Stimulsoft.Base.Localization.StiLocalization.addLocalizationFile("localization/zh-CHS.xml", false, "Chinese (Simplified)");
|
||||
Stimulsoft.Base.Localization.StiLocalization.cultureName = "Chinese (Simplified)";
|
||||
|
||||
var designer = new Stimulsoft.Designer.StiDesigner(options, "StiDesigner", false);
|
||||
|
||||
// Process SQL data source
|
||||
designer.onBeginProcessData = function (event, callback) {
|
||||
<?php StiHelper::createHandler(); ?>
|
||||
}
|
||||
|
||||
// Save report template on the server side
|
||||
designer.onSaveReport = function (event) {
|
||||
<?php StiHelper::createHandler(); ?>
|
||||
}
|
||||
|
||||
// Load and design report
|
||||
var report = new Stimulsoft.Report.StiReport();
|
||||
report.loadFile("reports/SimpleList.mrt");
|
||||
designer.report = report;
|
||||
|
||||
function onLoad() {
|
||||
designer.renderHtml("designerContent");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="onLoad();">
|
||||
<div id="designerContent"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,94 +0,0 @@
|
|||
<?php
|
||||
require_once 'stimulsoft/helper.php';
|
||||
|
||||
error_reporting(0);
|
||||
|
||||
// Please configure the security level as you required.
|
||||
// By default is to allow any requests from any domains.
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Engaged-Auth-Token");
|
||||
|
||||
$handler = new StiHandler();
|
||||
$handler->registerErrorHandlers();
|
||||
|
||||
$handler->onBeginProcessData = function ($event) {
|
||||
// Current database type: 'XML', 'JSON', 'MySQL', 'MS SQL', 'PostgreSQL', 'Firebird', 'Oracle'
|
||||
$database = $event->database;
|
||||
// Current connection name
|
||||
$connection = $event->connection;
|
||||
// Current data source name
|
||||
$dataSource = $event->dataSource;
|
||||
// Connection string for the current data source
|
||||
$connectionString = $event->connectionString;
|
||||
// SQL query string for the current data source
|
||||
$queryString = $event->queryString;
|
||||
|
||||
// You can change the connection string
|
||||
//if ($connection == "MyConnectionName")
|
||||
// $event->connectionString = "Server=localhost;Database=test;Port=3306;";
|
||||
|
||||
// You can change the SQL query
|
||||
//if ($dataSource == "MyDataSource")
|
||||
// $event->queryString = "SELECT * FROM MyTable";
|
||||
|
||||
// You can replace the SQL query parameters with the required values
|
||||
// For example: SELECT * FROM {Variable1} WHERE Id={Variable2}
|
||||
// If the report contains a variable with this name, its value will be used instead of the specified value
|
||||
//$event->parameters["Variable1"] = "TableName";
|
||||
//$event->parameters["Variable2"] = 10;
|
||||
|
||||
return StiResult::success();
|
||||
//return StiResult::error("Message for some connection error.");
|
||||
};
|
||||
|
||||
$handler->onPrintReport = function ($event) {
|
||||
return StiResult::success();
|
||||
};
|
||||
|
||||
$handler->onBeginExportReport = function ($event) {
|
||||
$settings = $event->settings;
|
||||
$format = $event->format;
|
||||
return StiResult::success();
|
||||
};
|
||||
|
||||
$handler->onEndExportReport = function ($event) {
|
||||
$format = $event->format; // Export format
|
||||
$data = $event->data; // Base64 export data
|
||||
$fileName = $event->fileName; // Report file name
|
||||
|
||||
file_put_contents('reports/'.$fileName.'.'.strtolower($format), base64_decode($data));
|
||||
|
||||
//return StiResult::success();
|
||||
return StiResult::success("Export OK. Message from server side.");
|
||||
//return StiResult::error("Export ERROR. Message from server side.");
|
||||
};
|
||||
|
||||
$handler->onEmailReport = function ($event) {
|
||||
$event->settings->from = "******@gmail.com";
|
||||
$event->settings->host = "smtp.gmail.com";
|
||||
$event->settings->login = "******";
|
||||
$event->settings->password = "******";
|
||||
};
|
||||
|
||||
$handler->onDesignReport = function ($event) {
|
||||
return StiResult::success();
|
||||
};
|
||||
|
||||
$handler->onCreateReport = function ($event) {
|
||||
$fileName = $event->fileName;
|
||||
return StiResult::success();
|
||||
};
|
||||
|
||||
$handler->onSaveReport = function ($event) {
|
||||
$report = $event->report; // Report object
|
||||
$reportJson = $event->reportJson; // Report JSON
|
||||
$fileName = $event->fileName; // Report file name
|
||||
file_put_contents('reports/'.$fileName.".mrt", $reportJson);
|
||||
return StiResult::success("保存成功:".$fileName);
|
||||
};
|
||||
|
||||
$handler->onSaveAsReport = function ($event) {
|
||||
return StiResult::success();
|
||||
};
|
||||
|
||||
$handler->process();
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
require_once 'stimulsoft/helper.php';
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>Stimulsoft Reports.PHP</title>
|
||||
</head>
|
||||
<body>
|
||||
Stimulsoft Reports.PHP (JS version) - Quick Start Demo
|
||||
<hr><br>
|
||||
<a href="viewer.php">Open Report Viewer page</a><br>
|
||||
<a href="designer.php">Open Report Designer page</a><br><br>
|
||||
<a href="activate.php">How to Activate</a><br>
|
||||
<a href="https://www.stimulsoft.com/en/documentation">Documentation</a><br>
|
||||
</body>
|
||||
</html>
|
|
@ -1,45 +0,0 @@
|
|||
<?php
|
||||
require_once 'stimulsoft/helper.php';
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>Stimulsoft Reports.PHP - Render & Export</title>
|
||||
|
||||
<!-- Stimulsoft Reports.JS -->
|
||||
<script src="scripts/stimulsoft.reports.js" type="text/javascript"></script>
|
||||
|
||||
<?php
|
||||
$options = StiHelper::createOptions();
|
||||
$options->handler = "handler.php";
|
||||
$options->timeout = 30;
|
||||
StiHelper::initialize($options);
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
function onLoad() {
|
||||
// Load and show report
|
||||
var report = new Stimulsoft.Report.StiReport();
|
||||
report.loadFile("reports/SimpleList.mrt");
|
||||
|
||||
// Process SQL data source
|
||||
report.onBeginProcessData = function (event, callback) {
|
||||
<?php StiHelper::createHandler(); ?>
|
||||
}
|
||||
|
||||
report.renderAsync(function() {
|
||||
var pdfData = report.exportDocument(Stimulsoft.Report.StiExportFormat.Pdf);
|
||||
|
||||
// Get report file name
|
||||
var fileName = String.isNullOrEmpty(report.reportAlias) ? report.reportName : report.reportAlias;
|
||||
// Save data to file
|
||||
Stimulsoft.System.StiObject.saveAs(pdfData, fileName + ".pdf", "application/pdf");
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="onLoad();">
|
||||
Render & Export
|
||||
</body>
|
||||
</html>
|
|
@ -1,181 +0,0 @@
|
|||
<?php
|
||||
class StiMsSqlAdapter {
|
||||
private $connectionString = null;
|
||||
private $connectionInfo = null;
|
||||
private $link = null;
|
||||
private $isMicrosoftDriver = false;
|
||||
|
||||
private function getLastErrorResult() {
|
||||
$error = null;
|
||||
if ($this->isMicrosoftDriver) {
|
||||
if (($errors = sqlsrv_errors()) != null) {
|
||||
$error = $errors[count($errors) - 1];
|
||||
return StiResult::error("[".$error['code']."] ".$error['message']);
|
||||
}
|
||||
}
|
||||
else $error = mssql_get_last_message();
|
||||
|
||||
if ($error) return StiResult::error($error);
|
||||
return StiResult::error("Unknown");
|
||||
}
|
||||
|
||||
private function connect() {
|
||||
if ($this->isMicrosoftDriver) {
|
||||
if (!function_exists("sqlsrv_connect")) return StiResult::error("MS SQL driver not found. Please configure your PHP server to work with MS SQL.");
|
||||
$this->link = sqlsrv_connect(
|
||||
$this->connectionInfo->host,
|
||||
array(
|
||||
"UID" => $this->connectionInfo->userId,
|
||||
"PWD" => $this->connectionInfo->password,
|
||||
"Database" => $this->connectionInfo->database,
|
||||
"LoginTimeout" => 10,
|
||||
"ReturnDatesAsStrings" => true,
|
||||
"CharacterSet" => $this->connectionInfo->charset
|
||||
));
|
||||
if (!$this->link) return $this->getLastErrorResult();
|
||||
}
|
||||
else {
|
||||
$this->link = mssql_connect($this->connectionInfo->host, $this->connectionInfo->userId, $this->connectionInfo->password);
|
||||
if (!$this->link) return $this->getLastErrorResult();
|
||||
$db = mssql_select_db($this->connectionInfo->database, $this->link);
|
||||
mssql_close($this->link);
|
||||
if (!$db) return $this->getLastErrorResult();
|
||||
}
|
||||
|
||||
return StiResult::success();
|
||||
}
|
||||
|
||||
private function disconnect() {
|
||||
if (!$this->link) return;
|
||||
$this->isMicrosoftDriver ? sqlsrv_close($this->link) : mssql_close($this->link);
|
||||
}
|
||||
|
||||
public function parse($connectionString) {
|
||||
$info = new stdClass();
|
||||
$info->host = "";
|
||||
$info->database = "";
|
||||
$info->userId = "";
|
||||
$info->password = "";
|
||||
$info->charset = "UTF-8";
|
||||
|
||||
$parameters = explode(";", $connectionString);
|
||||
foreach($parameters as $parameter) {
|
||||
if (strpos($parameter, "=") < 1) continue;
|
||||
|
||||
$spos = strpos($parameter, "=");
|
||||
$name = strtolower(trim(substr($parameter, 0, $spos)));
|
||||
$value = trim(substr($parameter, $spos + 1));
|
||||
|
||||
switch ($name) {
|
||||
case "server":
|
||||
case "data source":
|
||||
$info->host = $value;
|
||||
break;
|
||||
|
||||
case "database":
|
||||
case "initial catalog":
|
||||
$info->database = $value;
|
||||
break;
|
||||
|
||||
case "uid":
|
||||
case "user":
|
||||
case "user id":
|
||||
$info->userId = $value;
|
||||
break;
|
||||
|
||||
case "pwd":
|
||||
case "password":
|
||||
$info->password = $value;
|
||||
break;
|
||||
|
||||
case "charset":
|
||||
$info->charset = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->connectionString = $connectionString;
|
||||
$this->connectionInfo = $info;
|
||||
}
|
||||
|
||||
private function parseType($meta) {
|
||||
switch ($meta["Type"]) {
|
||||
// integer
|
||||
case -6:
|
||||
case -5:
|
||||
case 4:
|
||||
case 5:
|
||||
return 'int';
|
||||
|
||||
// number (decimal)
|
||||
case 2:
|
||||
case 3:
|
||||
case 6:
|
||||
case 7:
|
||||
return 'number';
|
||||
|
||||
// datetime
|
||||
case -155:
|
||||
case -154:
|
||||
case -2:
|
||||
case 91:
|
||||
case 93:
|
||||
return 'datetime';
|
||||
|
||||
// string
|
||||
case -152:
|
||||
case -10:
|
||||
case -9:
|
||||
case -8:
|
||||
case -1:
|
||||
case 1:
|
||||
case 12:
|
||||
return 'string';
|
||||
}
|
||||
|
||||
// base64 array for unknown
|
||||
return 'array';
|
||||
}
|
||||
|
||||
public function test() {
|
||||
$result = $this->connect();
|
||||
if ($result->success) $this->disconnect();
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function execute($queryString) {
|
||||
$result = $this->connect();
|
||||
if ($result->success) {
|
||||
$query = $this->isMicrosoftDriver ? sqlsrv_query($this->link, $queryString) : mssql_query($queryString, $this->link);
|
||||
if (!$query) return $this->getLastErrorResult();
|
||||
|
||||
$result->types = array();
|
||||
$result->columns = array();
|
||||
$result->rows = array();
|
||||
|
||||
if ($this->isMicrosoftDriver) {
|
||||
foreach (sqlsrv_field_metadata($query) as $meta) {
|
||||
$result->columns[] = $meta["Name"];
|
||||
$result->types[] = $this->parseType($meta);
|
||||
}
|
||||
}
|
||||
|
||||
$isColumnsEmpty = count($result->columns) == 0;
|
||||
while ($rowItem = $this->isMicrosoftDriver ? sqlsrv_fetch_array($query, SQLSRV_FETCH_ASSOC) : mssql_fetch_assoc($query)) {
|
||||
$row = array();
|
||||
foreach ($rowItem as $key => $value) {
|
||||
if ($isColumnsEmpty && count($result->columns) < count($rowItem)) $result->columns[] = $key;
|
||||
$row[] = $value;
|
||||
}
|
||||
$result->rows[] = $row;
|
||||
}
|
||||
$this->disconnect();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function __construct() {
|
||||
$this->isMicrosoftDriver = !function_exists("mssql_connect");
|
||||
}
|
||||
}
|
|
@ -1,161 +0,0 @@
|
|||
<?php
|
||||
class StiMySqlAdapter {
|
||||
private $connectionString = null;
|
||||
private $connectionInfo = null;
|
||||
private $link = null;
|
||||
|
||||
private function getLastErrorResult() {
|
||||
if ($this->link->errno == 0) return StiResult::error("Unknown");
|
||||
return StiResult::error("[".$this->link->errno."] ".$this->link->error);
|
||||
}
|
||||
|
||||
private function connect() {
|
||||
$this->link = new mysqli($this->connectionInfo->host, $this->connectionInfo->userId, $this->connectionInfo->password, $this->connectionInfo->database, $this->connectionInfo->port);
|
||||
if ($this->link->connect_error) return StiResult::error("[".$this->link->connect_errno."] ".$this->link->connect_error);
|
||||
if (!$this->link->set_charset($this->connectionInfo->charset)) return $this->getLastErrorResult();
|
||||
return StiResult::success();
|
||||
}
|
||||
|
||||
private function disconnect() {
|
||||
if (!$this->link) return;
|
||||
$this->link->close();
|
||||
}
|
||||
|
||||
public function parse($connectionString) {
|
||||
$info = new stdClass();
|
||||
$info->host = "";
|
||||
$info->port = 3306;
|
||||
$info->database = "";
|
||||
$info->userId = "";
|
||||
$info->password = "";
|
||||
$info->charset = "utf8";
|
||||
|
||||
$parameters = explode(";", $connectionString);
|
||||
foreach($parameters as $parameter)
|
||||
{
|
||||
if (strpos($parameter, "=") < 1) continue;
|
||||
|
||||
$spos = strpos($parameter, "=");
|
||||
$name = strtolower(trim(substr($parameter, 0, $spos)));
|
||||
$value = trim(substr($parameter, $spos + 1));
|
||||
|
||||
switch ($name)
|
||||
{
|
||||
case "server":
|
||||
case "host":
|
||||
case "location":
|
||||
$info->host = $value;
|
||||
break;
|
||||
|
||||
case "port":
|
||||
$info->port = $value;
|
||||
break;
|
||||
|
||||
case "database":
|
||||
case "data source":
|
||||
$info->database = $value;
|
||||
break;
|
||||
|
||||
case "uid":
|
||||
case "user":
|
||||
case "username":
|
||||
case "userid":
|
||||
case "user id":
|
||||
$info->userId = $value;
|
||||
break;
|
||||
|
||||
case "pwd":
|
||||
case "password":
|
||||
$info->password = $value;
|
||||
break;
|
||||
|
||||
case "charset":
|
||||
$info->charset = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->connectionString = $connectionString;
|
||||
$this->connectionInfo = $info;
|
||||
}
|
||||
|
||||
private function parseType($meta) {
|
||||
switch ($meta->type) {
|
||||
// integer
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 8:
|
||||
case 9:
|
||||
return 'int';
|
||||
|
||||
// number (decimal)
|
||||
case 4:
|
||||
case 5:
|
||||
case 16:
|
||||
case 246:
|
||||
return 'number';
|
||||
|
||||
// datetime
|
||||
case 7:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
return 'datetime';
|
||||
|
||||
// array, string
|
||||
case 249:
|
||||
case 250:
|
||||
case 251:
|
||||
case 252:
|
||||
case 253:
|
||||
case 254:
|
||||
if ($meta->flags & 128) return 'array';
|
||||
return 'string';
|
||||
}
|
||||
|
||||
// base64 array for unknown
|
||||
return 'array';
|
||||
}
|
||||
|
||||
public function test() {
|
||||
$result = $this->connect();
|
||||
if ($result->success) $this->disconnect();
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function execute($queryString) {
|
||||
$result = $this->connect();
|
||||
if ($result->success) {
|
||||
$query = $this->link->query($queryString);
|
||||
if (!$query) return $this->getLastErrorResult();
|
||||
|
||||
$result->types = array();
|
||||
$result->columns = array();
|
||||
$result->rows = array();
|
||||
|
||||
while ($meta = $query->fetch_field()) {
|
||||
$result->columns[] = $meta->name;
|
||||
$result->types[] = $this->parseType($meta);
|
||||
}
|
||||
|
||||
if ($query->num_rows > 0) {
|
||||
$isColumnsEmpty = count($result->columns) == 0;
|
||||
while ($rowItem = $query->fetch_assoc()) {
|
||||
$row = array();
|
||||
foreach ($rowItem as $key => $value) {
|
||||
if ($isColumnsEmpty && count($result->columns) < count($rowItem)) $result->columns[] = $key;
|
||||
$type = $result->types[count($row)];
|
||||
$row[] = ($type == 'array') ? base64_encode($value) : $value;
|
||||
}
|
||||
$result->rows[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
$this->disconnect();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -1,225 +0,0 @@
|
|||
<?php
|
||||
|
||||
class StiConnectionInfo {
|
||||
public $host = "";
|
||||
public $port = "";
|
||||
public $database = "";
|
||||
public $userId = "";
|
||||
public $password = "";
|
||||
public $charset = "";
|
||||
public $dsn = "";
|
||||
public $privilege = "";
|
||||
public $dataPath = "";
|
||||
public $schemaPath = "";
|
||||
}
|
||||
|
||||
class StiSender {
|
||||
const Viewer = "Viewer";
|
||||
const Designer = "Designer";
|
||||
}
|
||||
|
||||
class StiDatabaseType {
|
||||
const XML = "XML";
|
||||
const JSON = "JSON";
|
||||
const MySQL = "MySQL";
|
||||
const MSSQL = "MS SQL";
|
||||
const PostgreSQL = "PostgreSQL";
|
||||
const Firebird = "Firebird";
|
||||
const Oracle = "Oracle";
|
||||
}
|
||||
|
||||
class StiEventType {
|
||||
const ExecuteQuery = "ExecuteQuery";
|
||||
const BeginProcessData = "BeginProcessData";
|
||||
//const EndProcessData = "EndProcessData";
|
||||
const CreateReport = "CreateReport";
|
||||
const OpenReport = "OpenReport";
|
||||
const SaveReport = "SaveReport";
|
||||
const SaveAsReport = "SaveAsReport";
|
||||
const PrintReport = "PrintReport";
|
||||
const BeginExportReport = "BeginExportReport";
|
||||
const EndExportReport = "EndExportReport";
|
||||
const EmailReport = "EmailReport";
|
||||
const DesignReport = "DesignReport";
|
||||
}
|
||||
|
||||
class StiExportFormat {
|
||||
const Html = "Html";
|
||||
const Html5 = "Html5";
|
||||
const Pdf = "Pdf";
|
||||
const Excel2007 = "Excel2007";
|
||||
const Word2007 = "Word2007";
|
||||
const Csv = "Csv";
|
||||
}
|
||||
|
||||
class StiRequest {
|
||||
public $sender = null;
|
||||
public $event = null;
|
||||
public $connectionString = null;
|
||||
public $queryString = null;
|
||||
public $database = null;
|
||||
public $report = null;
|
||||
public $data = null;
|
||||
public $fileName = null;
|
||||
public $format = null;
|
||||
public $settings = null;
|
||||
|
||||
public function parse() {
|
||||
$data = file_get_contents("php://input");
|
||||
|
||||
$obj = json_decode($data);
|
||||
if ($obj == null) return StiResult::error("JSON parser error");
|
||||
|
||||
if (isset($obj->sender)) $this->sender = $obj->sender;
|
||||
if (isset($obj->command)) $this->event = $obj->command;
|
||||
if (isset($obj->event)) $this->event = $obj->event;
|
||||
if (isset($obj->connectionString)) $this->connectionString = $obj->connectionString;
|
||||
if (isset($obj->queryString)) $this->queryString = $obj->queryString;
|
||||
if (isset($obj->database)) $this->database = $obj->database;
|
||||
if (isset($obj->dataSource)) $this->dataSource = $obj->dataSource;
|
||||
if (isset($obj->connection)) $this->connection = $obj->connection;
|
||||
if (isset($obj->data)) $this->data = $obj->data;
|
||||
if (isset($obj->fileName)) $this->fileName = $obj->fileName;
|
||||
if (isset($obj->format)) $this->format = $obj->format;
|
||||
if (isset($obj->settings)) $this->settings = $obj->settings;
|
||||
if (isset($obj->report)) {
|
||||
$this->report = $obj->report;
|
||||
if (defined('JSON_UNESCAPED_SLASHES')) $this->reportJson = json_encode($this->report, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
else {
|
||||
// for PHP 5.3
|
||||
$this->reportJson = str_replace('\/', '/', json_encode($this->report));
|
||||
$this->reportJson = preg_replace_callback('/\\\\u(\w{4})/', function ($matches) {
|
||||
return html_entity_decode('&#x' . $matches[1] . ';', ENT_COMPAT, 'UTF-8');
|
||||
}, $this->reportJson);
|
||||
}
|
||||
}
|
||||
|
||||
return StiResult::success(null, $this);
|
||||
}
|
||||
}
|
||||
|
||||
class StiResponse {
|
||||
public static function json($result, $exit = true) {
|
||||
unset($result->object);
|
||||
if (defined('JSON_UNESCAPED_SLASHES')) echo json_encode($result, JSON_UNESCAPED_SLASHES);
|
||||
else echo json_encode($result);
|
||||
if ($exit) exit;
|
||||
}
|
||||
}
|
||||
|
||||
class StiResult {
|
||||
public $success = true;
|
||||
public $notice = null;
|
||||
public $object = null;
|
||||
|
||||
public static function success($notice = null, $object = null) {
|
||||
$result = new StiResult();
|
||||
$result->success = true;
|
||||
$result->notice = $notice;
|
||||
$result->object = $object;
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function error($notice = null) {
|
||||
$result = new StiResult();
|
||||
$result->success = false;
|
||||
$result->notice = $notice;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
class StiEmailSettings {
|
||||
/** Email address of the sender */
|
||||
public $from = null;
|
||||
|
||||
/** Name and surname of the sender */
|
||||
public $name = "John Smith";
|
||||
|
||||
/** Email address of the recipient */
|
||||
public $to = null;
|
||||
|
||||
/** Email Subject */
|
||||
public $subject = null;
|
||||
|
||||
/** Text of the Email */
|
||||
public $message = null;
|
||||
|
||||
/** Attached file name */
|
||||
public $attachmentName = null;
|
||||
|
||||
/** Charset for the message */
|
||||
public $charset = "UTF-8";
|
||||
|
||||
/** Address of the SMTP server */
|
||||
public $host = null;
|
||||
|
||||
/** Port of the SMTP server */
|
||||
public $port = 465;
|
||||
|
||||
/** The secure connection prefix - ssl or tls */
|
||||
public $secure = "ssl";
|
||||
|
||||
/** Login (Username or Email) */
|
||||
public $login = null;
|
||||
|
||||
/** Password */
|
||||
public $password = null;
|
||||
}
|
||||
|
||||
class StiDatabaseEventArgs {
|
||||
public $sender = null;
|
||||
public $database = null;
|
||||
public $connectionInfo = null;
|
||||
public $queryString = null;
|
||||
|
||||
function __construct($sender, $database, $connectionInfo, $queryString = null) {
|
||||
$this->sender = $sender;
|
||||
$this->database = $database;
|
||||
$this->connectionInfo = $connectionInfo;
|
||||
$this->queryString = $queryString;
|
||||
}
|
||||
}
|
||||
|
||||
class StiReportEventArgs {
|
||||
public $sender = null;
|
||||
public $report = null;
|
||||
|
||||
function __construct($sender, $report = null) {
|
||||
$this->sender = $sender;
|
||||
$this->report = $report;
|
||||
}
|
||||
}
|
||||
|
||||
class StiExportReportEventArgs {
|
||||
public $sender = null;
|
||||
public $settings = null;
|
||||
public $format = null;
|
||||
public $fileName = null;
|
||||
public $data = null;
|
||||
|
||||
function __construct($settings, $format, $fileName, $data = null) {
|
||||
$this->settings = $settings;
|
||||
$this->format = $format;
|
||||
$this->fileName = $fileName;
|
||||
$this->data = $data;
|
||||
}
|
||||
}
|
||||
|
||||
class StiSaveReportEventArgs {
|
||||
public $sender = null;
|
||||
public $report = null;
|
||||
public $fileName = null;
|
||||
|
||||
function __construct($report, $fileName) {
|
||||
$this->report = $report;
|
||||
$this->fileName = $fileName;
|
||||
}
|
||||
}
|
||||
|
||||
class StiDesignReportEventArgs {
|
||||
public $fileName = null;
|
||||
|
||||
function __construct($fileName) {
|
||||
$this->fileName = $fileName;
|
||||
}
|
||||
}
|
|
@ -1,443 +0,0 @@
|
|||
<?php
|
||||
require_once 'classes.php';
|
||||
require_once 'adapters/mysql.php';
|
||||
require_once 'adapters/mssql.php';
|
||||
|
||||
function stiErrorHandler($errNo, $errStr, $errFile, $errLine) {
|
||||
$result = StiResult::error("[".$errNo."] ".$errStr." (".$errFile.", Line ".$errLine.")");
|
||||
StiResponse::json($result);
|
||||
}
|
||||
|
||||
function stiShutdownFunction() {
|
||||
$err = error_get_last();
|
||||
if ($err != null && (($err["type"] & E_COMPILE_ERROR) || ($err["type"] & E_ERROR) || ($err["type"] & E_CORE_ERROR) || ($err["type"] & E_RECOVERABLE_ERROR))) {
|
||||
$result = StiResult::error("[".$err["type"]."] ".$err["message"]." (".$err["file"].", Line ".$err["line"].")");
|
||||
StiResponse::json($result);
|
||||
}
|
||||
}
|
||||
|
||||
class StiHandler {
|
||||
|
||||
private function checkEventResult($event, $args) {
|
||||
if (isset($event)) $result = $event($args);
|
||||
if (!isset($result)) $result = StiResult::success();
|
||||
if ($result === true) return StiResult::success();
|
||||
if ($result === false) return StiResult::error();
|
||||
if (gettype($result) == "string") return StiResult::error($result);
|
||||
if (isset($args)) $result->object = $args;
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function getQueryParameters($query) {
|
||||
$result = array();
|
||||
while (strpos($query, "{") !== false) {
|
||||
$query = substr($query, strpos($query, "{") + 1);
|
||||
$parameterName = substr($query, 0, strpos($query, "}"));
|
||||
$result[$parameterName] = null;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function applyQueryParameters($query, $values) {
|
||||
$result = "";
|
||||
while (strpos($query, "{") !== false) {
|
||||
$result .= substr($query, 0, strpos($query, "{"));
|
||||
$query = substr($query, strpos($query, "{") + 1);
|
||||
$parameterName = substr($query, 0, strpos($query, "}"));
|
||||
if (isset($values) && isset($values[$parameterName]) && !is_null($values[$parameterName])) $result .= strval($values[$parameterName]);
|
||||
else $result .= "{".$parameterName."}";
|
||||
$query = substr($query, strpos($query, "}") + 1);
|
||||
}
|
||||
|
||||
return $result.$query;
|
||||
}
|
||||
|
||||
//--- Events
|
||||
|
||||
public $onBeginProcessData = null;
|
||||
private function invokeBeginProcessData($request) {
|
||||
$args = new stdClass();
|
||||
$args->sender = $request->sender;
|
||||
$args->database = $request->database;
|
||||
$args->connectionString = isset($request->connectionString) ? base64_decode(str_rot13($request->connectionString)) : null;
|
||||
$args->queryString = isset($request->queryString) ? base64_decode(str_rot13($request->queryString)) : null;
|
||||
$args->dataSource = isset($request->dataSource) ? $request->dataSource : null;
|
||||
$args->connection = isset($request->connection) ? $request->connection : null;
|
||||
if (isset($request->queryString)) $args->parameters = $this->getQueryParameters($request->queryString);
|
||||
|
||||
$result = $this->checkEventResult($this->onBeginProcessData, $args);
|
||||
if (isset($result->object->queryString) && isset($args->parameters)) $result->object->queryString = $this->applyQueryParameters($result->object->queryString, $args->parameters);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public $onEndProcessData = null;
|
||||
private function invokeEndProcessData($request, $result) {
|
||||
$args = new stdClass();
|
||||
$args->sender = $request->sender;
|
||||
$args->result = $result;
|
||||
return $this->checkEventResult($this->onEndProcessData, $args);
|
||||
}
|
||||
|
||||
public $onCreateReport = null;
|
||||
private function invokeCreateReport($request) {
|
||||
$args = new stdClass();
|
||||
$args->sender = $request->sender;
|
||||
return $this->checkEventResult($this->onCreateReport, $args);
|
||||
}
|
||||
|
||||
public $onOpenReport = null;
|
||||
private function invokeOpenReport($request) {
|
||||
$args = new stdClass();
|
||||
$args->sender = $request->sender;
|
||||
return $this->checkEventResult($this->onOpenReport, $args);
|
||||
}
|
||||
|
||||
public $onSaveReport = null;
|
||||
private function invokeSaveReport($request) {
|
||||
$args = new stdClass();
|
||||
$args->sender = $request->sender;
|
||||
$args->report = $request->report;
|
||||
$args->reportJson = $request->reportJson;
|
||||
$args->fileName = $request->fileName;
|
||||
return $this->checkEventResult($this->onSaveReport, $args);
|
||||
}
|
||||
|
||||
public $onSaveAsReport = null;
|
||||
private function invokeSaveAsReport($request) {
|
||||
$args = new stdClass();
|
||||
$args->sender = $request->sender;
|
||||
$args->report = $request->report;
|
||||
$args->reportJson = $request->reportJson;
|
||||
$args->fileName = $request->fileName;
|
||||
return $this->checkEventResult($this->onSaveAsReport, $args);
|
||||
}
|
||||
|
||||
public $onPrintReport = null;
|
||||
private function invokePrintReport($request) {
|
||||
$args = new stdClass();
|
||||
$args->sender = $request->sender;
|
||||
$args->fileName = $request->fileName;
|
||||
return $this->checkEventResult($this->onPrintReport, $args);
|
||||
}
|
||||
|
||||
public $onBeginExportReport = null;
|
||||
private function invokeBeginExportReport($request) {
|
||||
$args = new stdClass();
|
||||
$args->sender = $request->sender;
|
||||
$args->settings = $request->settings;
|
||||
$args->format = $request->format;
|
||||
$args->fileName = $request->fileName;
|
||||
return $this->checkEventResult($this->onBeginExportReport, $args);
|
||||
}
|
||||
|
||||
public $onEndExportReport = null;
|
||||
private function invokeEndExportReport($request) {
|
||||
$args = new stdClass();
|
||||
$args->sender = $request->sender;
|
||||
$args->format = $request->format;
|
||||
$args->fileName = $request->fileName;
|
||||
$args->data = $request->data;
|
||||
return $this->checkEventResult($this->onEndExportReport, $args);
|
||||
}
|
||||
|
||||
public $onEmailReport = null;
|
||||
private function invokeEmailReport($request) {
|
||||
$settings = new StiEmailSettings();
|
||||
$settings->to = $request->settings->email;
|
||||
$settings->subject = $request->settings->subject;
|
||||
$settings->message = $request->settings->message;
|
||||
$settings->attachmentName = $request->fileName.'.'.$this->getFileExtension($request->format);
|
||||
|
||||
$args = new stdClass();
|
||||
$args->sender = $request->sender;
|
||||
$args->settings = $settings;
|
||||
$args->format = $request->format;
|
||||
$args->fileName = $request->fileName;
|
||||
$args->data = base64_decode($request->data);
|
||||
|
||||
$result = $this->checkEventResult($this->onEmailReport, $args);
|
||||
if (!$result->success) return $result;
|
||||
|
||||
$guid = substr(md5(uniqid().mt_rand()), 0, 12);
|
||||
if (!file_exists('tmp')) mkdir('tmp');
|
||||
file_put_contents('tmp/'.$guid.'.'.$args->fileName, $args->data);
|
||||
|
||||
// Detect auth mode
|
||||
$auth = $settings->host != null && $settings->login != null && $settings->password != null;
|
||||
|
||||
$mail = substr(PHP_VERSION, 0, 1) == '5' ? new PHPMailer(true) : new PHPMailer\PHPMailer\PHPMailer(true);
|
||||
if ($auth) $mail->IsSMTP();
|
||||
try {
|
||||
$mail->CharSet = $settings->charset;
|
||||
$mail->IsHTML(false);
|
||||
$mail->From = $settings->from;
|
||||
$mail->FromName = $settings->name;
|
||||
|
||||
// Add Emails list
|
||||
$emails = preg_split('/,|;/', $settings->to);
|
||||
foreach ($emails as $settings->to) {
|
||||
$mail->AddAddress(trim($settings->to));
|
||||
}
|
||||
|
||||
// Fill email fields
|
||||
$mail->Subject = htmlspecialchars($settings->subject);
|
||||
$mail->Body = $settings->message;
|
||||
$mail->AddAttachment('tmp/'.$guid.'.'.$args->fileName, $settings->attachmentName);
|
||||
|
||||
// Fill auth fields
|
||||
if ($auth) {
|
||||
$mail->Host = $settings->host;
|
||||
$mail->Port = $settings->port;
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->SMTPSecure = $settings->secure;
|
||||
$mail->Username = $settings->login;
|
||||
$mail->Password = $settings->password;
|
||||
}
|
||||
|
||||
$mail->Send();
|
||||
}
|
||||
catch (phpmailerException $e) {
|
||||
$error = strip_tags($e->errorMessage());
|
||||
return StiResult::error($error);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$error = strip_tags($e->getMessage());
|
||||
}
|
||||
|
||||
unlink('tmp/'.$guid.'.'.$args->fileName);
|
||||
|
||||
if (isset($error)) return StiResult::error($error);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public $onDesignReport = null;
|
||||
private function invokeDesignReport($request) {
|
||||
$args = new stdClass();
|
||||
$args->sender = $request->sender;
|
||||
$args->fileName = $request->fileName;
|
||||
return $this->checkEventResult($this->onDesignReport, $args);
|
||||
}
|
||||
|
||||
//--- Methods
|
||||
|
||||
public function registerErrorHandlers() {
|
||||
set_error_handler("stiErrorHandler");
|
||||
register_shutdown_function("stiShutdownFunction");
|
||||
}
|
||||
|
||||
public function process($response = true) {
|
||||
$result = $this->innerProcess();
|
||||
if ($response) StiResponse::json($result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
//--- Private methods
|
||||
|
||||
private function createConnection($args) {
|
||||
switch ($args->database) {
|
||||
case StiDatabaseType::MySQL: $connection = new StiMySqlAdapter(); break;
|
||||
case StiDatabaseType::MSSQL: $connection = new StiMsSqlAdapter(); break;
|
||||
case StiDatabaseType::Firebird: $connection = new StiFirebirdAdapter(); break;
|
||||
case StiDatabaseType::PostgreSQL: $connection = new StiPostgreSqlAdapter(); break;
|
||||
case StiDatabaseType::Oracle: $connection = new StiOracleAdapter(); break;
|
||||
}
|
||||
|
||||
if (isset($connection)) {
|
||||
$connection->parse($args->connectionString);
|
||||
return StiResult::success(null, $connection);
|
||||
}
|
||||
|
||||
return StiResult::error("Unknown database type [".$args->database."]");
|
||||
}
|
||||
|
||||
private function innerProcess() {
|
||||
$request = new StiRequest();
|
||||
$result = $request->parse();
|
||||
if ($result->success) {
|
||||
switch ($request->event) {
|
||||
case StiEventType::BeginProcessData:
|
||||
case StiEventType::ExecuteQuery:
|
||||
$result = $this->invokeBeginProcessData($request);
|
||||
if (!$result->success) return $result;
|
||||
$queryString = $result->object->queryString;
|
||||
$result = $this->createConnection($result->object);
|
||||
if (!$result->success) return $result;
|
||||
$connection = $result->object;
|
||||
if (isset($queryString)) $result = $connection->execute($queryString);
|
||||
else $result = $connection->test();
|
||||
$result = $this->invokeEndProcessData($request, $result);
|
||||
if (!$result->success) return $result;
|
||||
if (isset($result->object) && isset($result->object->result)) return $result->object->result;
|
||||
return $result;
|
||||
|
||||
case StiEventType::CreateReport:
|
||||
return $this->invokeCreateReport($request);
|
||||
|
||||
case StiEventType::OpenReport:
|
||||
return $this->invokeOpenReport($request);
|
||||
|
||||
case StiEventType::SaveReport:
|
||||
return $this->invokeSaveReport($request);
|
||||
|
||||
case StiEventType::SaveAsReport:
|
||||
return $this->invokeSaveReport($request);
|
||||
|
||||
case StiEventType::PrintReport:
|
||||
return $this->invokePrintReport($request);
|
||||
|
||||
case StiEventType::BeginExportReport:
|
||||
return $this->invokeBeginExportReport($request);
|
||||
|
||||
case StiEventType::EndExportReport:
|
||||
return $this->invokeEndExportReport($request);
|
||||
|
||||
case StiEventType::EmailReport:
|
||||
return $this->invokeEmailReport($request);
|
||||
|
||||
case StiEventType::DesignReport;
|
||||
return $this->invokeDesignReport($request);
|
||||
}
|
||||
|
||||
$result = StiResult::error("Unknown event [".$request->event."]");
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function getFileExtension($format) {
|
||||
switch ($format) {
|
||||
case StiExportFormat::Html:
|
||||
case StiExportFormat::Html5:
|
||||
return "html";
|
||||
|
||||
case StiExportFormat::Pdf:
|
||||
return "pdf";
|
||||
|
||||
case StiExportFormat::Excel2007:
|
||||
return "xlsx";
|
||||
|
||||
case StiExportFormat::Word2007:
|
||||
return "docx";
|
||||
|
||||
case StiExportFormat::Csv:
|
||||
return "csv";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------- Helper ----------//
|
||||
|
||||
|
||||
class StiHelper {
|
||||
public static function createOptions() {
|
||||
$options = new stdClasS();
|
||||
$options->handler = "handler.php";
|
||||
$options->timeout = 30;
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
public static function initialize($options) {
|
||||
if (!isset($options)) $options = StiHelper::createOptions();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
StiHelper.prototype.process = function (args, callback) {
|
||||
if (args) {
|
||||
if (args.event == 'BeginProcessData') {
|
||||
args.preventDefault = true;
|
||||
if (args.database == 'XML' || args.database == 'JSON' || args.database == 'Excel')
|
||||
return callback(null);
|
||||
if (args.database == 'Data from DataSet, DataTables')
|
||||
return callback(args);
|
||||
}
|
||||
var command = {};
|
||||
for (var p in args) {
|
||||
if (p == 'report' && args.report != null) command.report = JSON.parse(args.report.saveToJsonString());
|
||||
else if (p == 'settings' && args.settings != null) command.settings = args.settings;
|
||||
else if (p == 'data') command.data = Stimulsoft.System.Convert.toBase64String(args.data);
|
||||
else if (p == 'connectionString' || p == 'queryString') command[p] = jsHelper.getStringValue(args[p]);
|
||||
else command[p] = args[p];
|
||||
}
|
||||
|
||||
var isNullOrEmpty = function (value) {
|
||||
return value == null || value === '' || value === undefined;
|
||||
}
|
||||
var json = JSON.stringify(command);
|
||||
if (!callback) callback = function (message) {
|
||||
if (Stimulsoft.System.StiError.errorMessageForm && !isNullOrEmpty(message)) {
|
||||
var obj = JSON.parse(message);
|
||||
if (!obj.success || !isNullOrEmpty(obj.notice)) {
|
||||
var message = isNullOrEmpty(obj.notice) ? 'There was some error' : obj.notice;
|
||||
Stimulsoft.System.StiError.errorMessageForm.show(message, obj.success);
|
||||
}
|
||||
}
|
||||
}
|
||||
jsHelper.send(json, callback);
|
||||
}
|
||||
}
|
||||
|
||||
StiHelper.prototype.send = function (json, callback) {
|
||||
try {
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('post', this.url, true);
|
||||
request.setRequestHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
|
||||
request.setRequestHeader('Cache-Control', 'max-age=0');
|
||||
request.setRequestHeader('Pragma', 'no-cache');
|
||||
request.timeout = this.timeout * 1000;
|
||||
request.onload = function () {
|
||||
if (request.status == 200) {
|
||||
var responseText = request.responseText;
|
||||
request.abort();
|
||||
callback(responseText);
|
||||
}
|
||||
else {
|
||||
Stimulsoft.System.StiError.showError('[' + request.status + '] ' + request.statusText, false);
|
||||
}
|
||||
};
|
||||
request.onerror = function (e) {
|
||||
var errorMessage = 'Connect to remote error: [' + request.status + '] ' + request.statusText;
|
||||
Stimulsoft.System.StiError.showError(errorMessage, false);
|
||||
};
|
||||
request.send(json);
|
||||
}
|
||||
catch (e) {
|
||||
var errorMessage = 'Connect to remote error: ' + e.message;
|
||||
Stimulsoft.System.StiError.showError(errorMessage, false);
|
||||
request.abort();
|
||||
}
|
||||
};
|
||||
|
||||
StiHelper.prototype.getStringValue = function (value) {
|
||||
return Stimulsoft.System.Convert.toBase64String(value).replace(/[a-zA-Z]/g, function (c) {
|
||||
return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);
|
||||
});
|
||||
};
|
||||
|
||||
StiHelper.prototype.getUrlVars = function (json, callback) {
|
||||
var vars = {};
|
||||
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi,
|
||||
function (m, key, value) {
|
||||
vars[key] = decodeURI(value);
|
||||
});
|
||||
return vars;
|
||||
}
|
||||
|
||||
function StiHelper(url, timeout) {
|
||||
this.url = url;
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
jsHelper = new StiHelper('<?php echo $options->handler; ?>', <?php echo $options->timeout; ?>);
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
public static function createHandler() {
|
||||
?>jsHelper.process(arguments[0], arguments[1]);
|
||||
<?php
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
6vJhGtLLLz2GNviWmUTrhSqnOItdDwjBylQzQcAOiHlrzAZzmWmSnQQ4gKFiZ4LJpJv//QjFVXxcHAVbzZfXjyOGPmj/m+BEjr2Z14dWeqLFNGF74GELbTTKs2+Le/9cDIWdGNnOpEK2aGdYllauMPLQsiScC521JIEYSdOspiRHSLcegksxfNedJjyIjGlfI2YrddBRWGiO+uWOHE5oz9hLG8VPBSRo60KmgkscM5X+7+aQ+6vzKKOC2XB+e6BMQC5qNVBUblfGQR2EjNLZKmSJtvek7IbG/OK+XP0j2bwicyJUGC0pyLHqctr3BpcO/gA5LoVfuwqYG3klL//owBkObPPhJV1HD6XsHL0GDryssJFaDCQIyXMrOn7hNQNkEIyx+AJDNgf5XfxPgEgFsRhYCPYq7ccutg2by8duOxbF3xH0gL/uAQN275COXJBV3W62DSLM+o8azChG+Z7y0dF9f4whZ/SKD4DwNPUWK7osEPVwl5BY+0lkdqd67fatlrlc0QU/ZX9f5QcTKfl5ljuNc+kcqxmd9NND6Xzrw9gFsFqIWqqVo++DdoAZFStXMkOp/nTNBQMRA100k3vi2SbbiHq/gVimrQecUhWG0qU5zcemtVGDMs1ruXsoHX8pYX/rMJHH09qCWllVyBykkTLourYEig9g5fhKDYRV05aC0cWsbxR2nj9TH3SLmG4P2Px7uJsq6iOsnIHWuBMwk8oF7xPEugjw+x8lkjVVoV8WWBSdjIxGh4LviZXBEJm9FTJzYcnEHMZRh0uVE1g8crC+TfRVii7dcdZzeQklzyNY+0Q1/hRaIUs+mNPRiqG6YqEv3f+yG4ncxzkCWZDvXPox87y61jbg6Dg73X1RAwwvbIXuJVANbaDOefUELPmpz4SIpHx8zpLSmn1H1u0PolbsimLigcGw2bJQeuU++OBU74vJJde3JdoO6IOfmUJkoxprdszyknLm+zWgnC+jjaCtEZZuOIJqyuVPoqHRiFkqNjbddkvGMmj/4+2D6BdYQot9sEOW7iCgV4SvZ/efC0NlRX+Z+6PODwKJiO+Sen5aAlsJcL2jIUSAjgyS+7im7XTGlYKuRL59EQjA5HArO1ikJ0P/2pk4u91z2J8GRvTPu5BZUI9M0BLGLAVCFMte4JQCOr+f785RgjerSNCSgN4Mfa5+jDQAKTAVAO5tqT/SBEm0M5U1EylQ/fbseKt+dQ1/VzqlQ9SH14jtI0J97ACqk9SBt9xpTgBnJrBSTnnY21l2zWS7/2k5U9LPDJn0Lm32ueoDRFaM4JeK1HoSi2HvOYy1V1hU5pCe893QsBE/HOVp4UWu9lfiEWunHEEdPZOUPgc131KwJrM4K3DYiBbXl442TgbNLfz5IBnAw1NVabMXXyx2LOi6x35xw1YLMRYNWYE9QpocBhoFQtStd2OUZ5CqvxhXf+VaLK3hmm1GvlqpUK6LIDd3eyuQK4f0E7+zVSBaV6eSDI9YJC42Ee+Br8AByGYLRaFISpDculGt2nqwFL6cwltv1Xy11frJR2KqbR8sd6dI0V69XnwBziRzJq1SyAZd9bzClYSpA3ZYPN9ghdaHA+GZak0IYMokWLi6oYquOCRoy8f0sEQM2Uhw2x/E9tgyNoLZhDhrk805/VCsThI5fHn0YWVnmQZTrGkOwnoqLw3VHb7akUmNnjMlk/tD59bR2lgD+fnNuNsBYDDjJpg+fKmgf9araTPEIpuuanp53e6xodRYKIj4o4+39DrPK10eR4CDfSh5UShvnCZz+V0FAkIkoM92U1JTU59P4M4pzc8PswmS1rGTRaZMUrTYrjeGCHC9Hl0CTIR1/rQAx8iIcC3yVNCeiTJAmKMCl830O4GpEfduNHQgDrlsJC4q6RA7J2kUzW2WQvKFKH3bRH1hOc6LZK4DmwMGzXMKDKOxK0dzld2/ImRN6DbPacV/4d0HK06qBOFEgUJqXhMpV1JjsXVvmx/m2LCRgkD5vPEwcuiWtWde7tISLCEg6hjAV9+Hx6zOWpozg7aZMtikT+43uWakRkU/H+ITIGhqxuQhkZkmIddWrjD5lJtdUOSa0FWu969EDp4XB8dmUKSwyrkgOHZu6DutFW5ArtqhNejthWt/sV1FkSbvdd26zn1fSO4pDa4pDmcSo+l/4DChZbEyICc7IQrPjVuRUlVGuAVksZTBX+VYIip8LsJSFLHo7Dnn4QT3qDNIh8aAcY3fnHhph4G5ekbvGOw3+m1qqs8t0m89vdK7k8nJTw==
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
// You can check the user authorization to send a license key only if the result is positive.
|
||||
|
||||
if (file_exists("license.key")) {
|
||||
$license = file_get_contents("license.key");
|
||||
echo $license;
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,72 +0,0 @@
|
|||
<?php
|
||||
require_once 'stimulsoft/helper.php';
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>Stimulsoft Reports.PHP - JS Viewer</title>
|
||||
|
||||
<!-- Office2013 style -->
|
||||
<link href="css/stimulsoft.viewer.office2013.whiteblue.css" rel="stylesheet">
|
||||
|
||||
<!-- Stimulsoft Reports.JS -->
|
||||
<script src="scripts/stimulsoft.reports.js" type="text/javascript"></script>
|
||||
<!-- Stimulsoft JS Viewer -->
|
||||
<script src="scripts/stimulsoft.viewer.js" type="text/javascript"></script>
|
||||
|
||||
<?php
|
||||
$options = StiHelper::createOptions();
|
||||
$options->handler = "handler.php";
|
||||
$options->timeout = 30;
|
||||
StiHelper::initialize($options);
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
//Stimulsoft.Base.StiLicense.loadFromFile("stimulsoft/license.php");
|
||||
|
||||
var options = new Stimulsoft.Viewer.StiViewerOptions();
|
||||
options.appearance.fullScreenMode = true;
|
||||
options.toolbar.showSendEmailButton = true;
|
||||
|
||||
Stimulsoft.Base.Localization.StiLocalization.addLocalizationFile("localization/zh-CHS.xml", false, "Chinese (Simplified)");
|
||||
Stimulsoft.Base.Localization.StiLocalization.cultureName = "Chinese (Simplified)";
|
||||
|
||||
var viewer = new Stimulsoft.Viewer.StiViewer(options, "StiViewer", false);
|
||||
|
||||
// Process SQL data source
|
||||
viewer.onBeginProcessData = function (event, callback) {
|
||||
<?php StiHelper::createHandler(); ?>
|
||||
}
|
||||
|
||||
// Manage export settings on the server side
|
||||
viewer.onBeginExportReport = function (args) {
|
||||
<?php //StiHelper::createHandler(); ?>
|
||||
//args.fileName = "MyReportName";
|
||||
}
|
||||
|
||||
// Process exported report file on the server side
|
||||
/*viewer.onEndExportReport = function (event) {
|
||||
event.preventDefault = true; // Prevent client default event handler (save the exported report as a file)
|
||||
<?php StiHelper::createHandler(); ?>
|
||||
}*/
|
||||
|
||||
// Send exported report to Email
|
||||
viewer.onEmailReport = function (event) {
|
||||
<?php StiHelper::createHandler(); ?>
|
||||
}
|
||||
|
||||
// Load and show report
|
||||
var report = new Stimulsoft.Report.StiReport();
|
||||
report.loadFile("reports/SimpleList.mrt");
|
||||
viewer.report = report;
|
||||
|
||||
function onLoad() {
|
||||
viewer.renderHtml("viewerContent");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="onLoad();">
|
||||
<div id="viewerContent"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,297 +0,0 @@
|
|||
/**
|
||||
* Created by jf on 2015/9/11.
|
||||
* Modified by bear on 2016/9/7.
|
||||
*/
|
||||
$(function () {
|
||||
var pageManager = {
|
||||
$container: $('#container'),
|
||||
_pageStack: [],
|
||||
_configs: [],
|
||||
_pageAppend: function(){},
|
||||
_defaultPage: null,
|
||||
_pageIndex: 1,
|
||||
setDefault: function (defaultPage) {
|
||||
this._defaultPage = this._find('name', defaultPage);
|
||||
return this;
|
||||
},
|
||||
setPageAppend: function (pageAppend) {
|
||||
this._pageAppend = pageAppend;
|
||||
return this;
|
||||
},
|
||||
init: function () {
|
||||
var self = this;
|
||||
|
||||
$(window).on('hashchange', function () {
|
||||
var state = history.state || {};
|
||||
var url = location.hash.indexOf('#') === 0 ? location.hash : '#';
|
||||
var page = self._find('url', url) || self._defaultPage;
|
||||
if (state._pageIndex <= self._pageIndex || self._findInStack(url)) {
|
||||
self._back(page);
|
||||
} else {
|
||||
self._go(page);
|
||||
}
|
||||
});
|
||||
|
||||
if (history.state && history.state._pageIndex) {
|
||||
this._pageIndex = history.state._pageIndex;
|
||||
}
|
||||
|
||||
this._pageIndex--;
|
||||
|
||||
var url = location.hash.indexOf('#') === 0 ? location.hash : '#';
|
||||
var page = self._find('url', url) || self._defaultPage;
|
||||
this._go(page);
|
||||
return this;
|
||||
},
|
||||
push: function (config) {
|
||||
this._configs.push(config);
|
||||
return this;
|
||||
},
|
||||
go: function (to) {
|
||||
var config = this._find('name', to);
|
||||
if (!config) {
|
||||
return;
|
||||
}
|
||||
location.hash = config.url;
|
||||
},
|
||||
_go: function (config) {
|
||||
this._pageIndex ++;
|
||||
|
||||
history.replaceState && history.replaceState({_pageIndex: this._pageIndex}, '', location.href);
|
||||
|
||||
var html = $(config.template).html();
|
||||
var $html = $(html).addClass('slideIn').addClass(config.name);
|
||||
$html.on('animationend webkitAnimationEnd', function(){
|
||||
$html.removeClass('slideIn').addClass('js_show');
|
||||
});
|
||||
this.$container.append($html);
|
||||
this._pageAppend.call(this, $html);
|
||||
this._pageStack.push({
|
||||
config: config,
|
||||
dom: $html
|
||||
});
|
||||
|
||||
if (!config.isBind) {
|
||||
this._bind(config);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
back: function () {
|
||||
history.back();
|
||||
},
|
||||
_back: function (config) {
|
||||
this._pageIndex --;
|
||||
|
||||
var stack = this._pageStack.pop();
|
||||
if (!stack) {
|
||||
return;
|
||||
}
|
||||
|
||||
var url = location.hash.indexOf('#') === 0 ? location.hash : '#';
|
||||
var found = this._findInStack(url);
|
||||
if (!found) {
|
||||
var html = $(config.template).html();
|
||||
var $html = $(html).addClass('js_show').addClass(config.name);
|
||||
$html.insertBefore(stack.dom);
|
||||
|
||||
if (!config.isBind) {
|
||||
this._bind(config);
|
||||
}
|
||||
|
||||
this._pageStack.push({
|
||||
config: config,
|
||||
dom: $html
|
||||
});
|
||||
}
|
||||
|
||||
stack.dom.addClass('slideOut').on('animationend webkitAnimationEnd', function () {
|
||||
stack.dom.remove();
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
_findInStack: function (url) {
|
||||
var found = null;
|
||||
for(var i = 0, len = this._pageStack.length; i < len; i++){
|
||||
var stack = this._pageStack[i];
|
||||
if (stack.config.url === url) {
|
||||
found = stack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
},
|
||||
_find: function (key, value) {
|
||||
var page = null;
|
||||
for (var i = 0, len = this._configs.length; i < len; i++) {
|
||||
if (this._configs[i][key] === value) {
|
||||
page = this._configs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return page;
|
||||
},
|
||||
_bind: function (page) {
|
||||
var events = page.events || {};
|
||||
for (var t in events) {
|
||||
for (var type in events[t]) {
|
||||
this.$container.on(type, t, events[t][type]);
|
||||
}
|
||||
}
|
||||
page.isBind = true;
|
||||
}
|
||||
};
|
||||
|
||||
function fastClick(){
|
||||
var supportTouch = function(){
|
||||
try {
|
||||
document.createEvent("TouchEvent");
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}();
|
||||
var _old$On = $.fn.on;
|
||||
|
||||
$.fn.on = function(){
|
||||
if(/click/.test(arguments[0]) && typeof arguments[1] == 'function' && supportTouch){ // 只扩展支持touch的当前元素的click事件
|
||||
var touchStartY, callback = arguments[1];
|
||||
_old$On.apply(this, ['touchstart', function(e){
|
||||
touchStartY = e.changedTouches[0].clientY;
|
||||
}]);
|
||||
_old$On.apply(this, ['touchend', function(e){
|
||||
if (Math.abs(e.changedTouches[0].clientY - touchStartY) > 10) return;
|
||||
|
||||
e.preventDefault();
|
||||
callback.apply(this, [e]);
|
||||
}]);
|
||||
}else{
|
||||
_old$On.apply(this, arguments);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
}
|
||||
function preload(){
|
||||
$(window).on("load", function(){
|
||||
var imgList = [
|
||||
"./images/layers/content.png",
|
||||
"./images/layers/navigation.png",
|
||||
"./images/layers/popout.png",
|
||||
"./images/layers/transparent.gif"
|
||||
];
|
||||
for (var i = 0, len = imgList.length; i < len; ++i) {
|
||||
new Image().src = imgList[i];
|
||||
}
|
||||
});
|
||||
}
|
||||
function androidInputBugFix(){
|
||||
// .container 设置了 overflow 属性, 导致 Android 手机下输入框获取焦点时, 输入法挡住输入框的 bug
|
||||
// 相关 issue: https://github.com/weui/weui/issues/15
|
||||
// 解决方法:
|
||||
// 0. .container 去掉 overflow 属性, 但此 demo 下会引发别的问题
|
||||
// 1. 参考 http://stackoverflow.com/questions/23757345/android-does-not-correctly-scroll-on-input-focus-if-not-body-element
|
||||
// Android 手机下, input 或 textarea 元素聚焦时, 主动滚一把
|
||||
if (/Android/gi.test(navigator.userAgent)) {
|
||||
window.addEventListener('resize', function () {
|
||||
if (document.activeElement.tagName == 'INPUT' || document.activeElement.tagName == 'TEXTAREA') {
|
||||
window.setTimeout(function () {
|
||||
document.activeElement.scrollIntoViewIfNeeded();
|
||||
}, 0);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
function setJSAPI(){
|
||||
var option = {
|
||||
title: 'WeUI, 为微信 Web 服务量身设计',
|
||||
desc: 'WeUI, 为微信 Web 服务量身设计',
|
||||
link: "https://weui.io",
|
||||
imgUrl: 'https://mmbiz.qpic.cn/mmemoticon/ajNVdqHZLLA16apETUPXh9Q5GLpSic7lGuiaic0jqMt4UY8P4KHSBpEWgM7uMlbxxnVR7596b3NPjUfwg7cFbfCtA/0'
|
||||
};
|
||||
|
||||
$.getJSON('https://weui.io/api/sign?url=' + encodeURIComponent(location.href.split('#')[0]), function (res) {
|
||||
wx.config({
|
||||
beta: true,
|
||||
debug: false,
|
||||
appId: res.appid,
|
||||
timestamp: res.timestamp,
|
||||
nonceStr: res.nonceStr,
|
||||
signature: res.signature,
|
||||
jsApiList: [
|
||||
'onMenuShareTimeline',
|
||||
'onMenuShareAppMessage',
|
||||
'onMenuShareQQ',
|
||||
'onMenuShareWeibo',
|
||||
'onMenuShareQZone',
|
||||
// 'setNavigationBarColor',
|
||||
'setBounceBackground'
|
||||
]
|
||||
});
|
||||
wx.ready(function () {
|
||||
/*
|
||||
wx.invoke('setNavigationBarColor', {
|
||||
color: '#F8F8F8'
|
||||
});
|
||||
*/
|
||||
wx.invoke('setBounceBackground', {
|
||||
'backgroundColor': '#F8F8F8',
|
||||
'footerBounceColor' : '#F8F8F8'
|
||||
});
|
||||
wx.onMenuShareTimeline(option);
|
||||
wx.onMenuShareQQ(option);
|
||||
wx.onMenuShareAppMessage({
|
||||
title: 'WeUI',
|
||||
desc: '为微信 Web 服务量身设计',
|
||||
link: location.href,
|
||||
imgUrl: 'https://mmbiz.qpic.cn/mmemoticon/ajNVdqHZLLA16apETUPXh9Q5GLpSic7lGuiaic0jqMt4UY8P4KHSBpEWgM7uMlbxxnVR7596b3NPjUfwg7cFbfCtA/0'
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
function setPageManager(){
|
||||
var pages = {}, tpls = $('script[type="text/html"]');
|
||||
var winH = $(window).height();
|
||||
|
||||
for (var i = 0, len = tpls.length; i < len; ++i) {
|
||||
var tpl = tpls[i], name = tpl.id.replace(/tpl_/, '');
|
||||
pages[name] = {
|
||||
name: name,
|
||||
url: '#' + name,
|
||||
template: '#' + tpl.id
|
||||
};
|
||||
}
|
||||
pages.home.url = '#';
|
||||
|
||||
for (var page in pages) {
|
||||
pageManager.push(pages[page]);
|
||||
}
|
||||
pageManager
|
||||
.setPageAppend(function($html){
|
||||
var $foot = $html.find('.page__ft');
|
||||
if($foot.length < 1) return;
|
||||
|
||||
if($foot.position().top + $foot.height() < winH){
|
||||
$foot.addClass('j_bottom');
|
||||
}else{
|
||||
$foot.removeClass('j_bottom');
|
||||
}
|
||||
})
|
||||
.setDefault('home')
|
||||
.init();
|
||||
}
|
||||
|
||||
function init(){
|
||||
preload();
|
||||
fastClick();
|
||||
androidInputBugFix();
|
||||
setJSAPI();
|
||||
setPageManager();
|
||||
|
||||
window.pageManager = pageManager;
|
||||
window.home = function(){
|
||||
location.hash = '';
|
||||
};
|
||||
}
|
||||
init();
|
||||
});
|
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 748 B |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 425 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 196 B |
Before Width: | Height: | Size: 838 B |
Before Width: | Height: | Size: 924 B |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 200 B |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 357 B |
Before Width: | Height: | Size: 924 B |
Before Width: | Height: | Size: 579 B |
Before Width: | Height: | Size: 669 B |
Before Width: | Height: | Size: 548 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 495 B |
Before Width: | Height: | Size: 521 B |
Before Width: | Height: | Size: 701 B |
Before Width: | Height: | Size: 388 B |
Before Width: | Height: | Size: 388 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 816 B |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 111 KiB |
Before Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 392 B |
Before Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 196 KiB |
Before Width: | Height: | Size: 99 KiB |
Before Width: | Height: | Size: 100 KiB |
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"/assets/dist/bundle.min.js": "/assets/dist/bundle.min.js?id=3134a2a19af235238c9a",
|
||||
"/assets/dist/bundle.min.js": "/assets/dist/bundle.min.js?id=6ed6b193096450339853",
|
||||
"/assets/dist/app.min.js": "/assets/dist/app.min.js?id=7f970b0394bf5cba9353",
|
||||
"/assets/dist/app.min.css": "/assets/dist/app.min.css?id=b145e2781689d581fc3f",
|
||||
"/assets/vendor/ag-grid/ag-grid.min.css": "/assets/vendor/ag-grid/ag-grid.min.css?id=0e414057cb24126f35ae",
|
||||
|
|
|
@ -1,16 +1,7 @@
|
|||
<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">
|
||||
<li class="dropdown" v-if="realtime">
|
||||
<a href="javascript:;" @click="chatToggle()" title="即时消息" class="dropdown-toggle hidden-xs">
|
||||
<i class="fa fa-comments pulse-box">
|
||||
<span class='pulse green'></span>
|
||||
|
@ -20,16 +11,6 @@
|
|||
</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>
|
||||
|
@ -94,29 +75,13 @@
|
|||
<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>
|
||||
<a href="javascript:;" @click="support">关于</a>
|
||||
</li>
|
||||
<li class="divider"></li>
|
||||
<li>
|
||||
<a :href="url('user/auth/logout')">注销</a>
|
||||
<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>
|
||||
|
@ -132,6 +97,7 @@ export default defineComponent({
|
|||
countTotal: 0,
|
||||
countArticle: 0,
|
||||
countMail: 0,
|
||||
realtime: settings.realtime
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
@ -151,7 +117,7 @@ export default defineComponent({
|
|||
},
|
||||
support() {
|
||||
viewDialog({
|
||||
title: '技术支持',
|
||||
title: '关于',
|
||||
dialogClass: 'modal-md',
|
||||
url: app.url('index/index/support'),
|
||||
close: function() {
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
<meta charset="utf-8">
|
||||
<title>{{$setting['title']}}</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
|
||||
<link href="{{$asset_url}}/dist/app.min.css" rel="stylesheet" type="text/css">
|
||||
<script src="{{$asset_url}}/vendor/jquery.min.js"></script>
|
||||
<link href="{{mix('/assets/dist/app.min.css')}}" rel="stylesheet" type="text/css">
|
||||
<script src="{{$asset_url}}/vendor/jquery.js"></script>
|
||||
</head>
|
||||
<style>
|
||||
li { list-style: none; }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<title>信息提示</title>
|
||||
<link href="<?php echo URL::to('assets'); ?>/dist/app.min.css" rel="stylesheet">
|
||||
<link href="<?php echo mix('/assets/dist/app.min.css'); ?>" rel="stylesheet">
|
||||
<style type="text/css">
|
||||
.window {
|
||||
font: 12px 'Lucida Grande', Verdana, sans-serif;
|
||||
|
|
|
@ -5,17 +5,20 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title>{{$setting['title']}} - Powered By {{$setting['powered']}}</title>
|
||||
<script type="text/javascript" src="{{$public_url}}/common?v={{$resVersion}}"></script>
|
||||
<link href="{{$asset_url}}/vendor/ag-grid/ag-grid.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="{{$asset_url}}/dist/app.min.css?v={{$resVersion}}" rel="stylesheet" type="text/css" />
|
||||
<script src="{{$asset_url}}/dist/app.min.js?v={{$resVersion}}" type="text/javascript"></script>
|
||||
<script src="{{$asset_url}}/vendor/layer/layer.js" type="text/javascript"></script>
|
||||
<script src="{{$asset_url}}/vendor/datepicker/datepicker.js"></script>
|
||||
<script src="{{$asset_url}}/vendor/ag-grid/ag-grid.min.js"></script>
|
||||
<script src="{{$asset_url}}/dist/bundle.min.js"></script>
|
||||
<link href="{{mix('/assets/dist/app.min.css')}}" rel="stylesheet" type="text/css" />
|
||||
|
||||
<script type="text/javascript" src="{{$public_url}}/common?v={{time()}}"></script>
|
||||
<script type="text/javascript" src="{{mix('/assets/dist/app.min.js')}}"></script>
|
||||
<script type="text/javascript" src="{{mix('/assets/dist/bundle.min.js')}}"></script>
|
||||
|
||||
<!-- 第三方库 -->
|
||||
<script type="text/javascript" src="{{$asset_url}}/vendor/layer/layer.js"></script>
|
||||
<script type="text/javascript" src="{{$asset_url}}/vendor/datepicker/datepicker.js"></script>
|
||||
<script type="text/javascript" src="{{$asset_url}}/vendor/ag-grid/ag-grid.min.js"></script>
|
||||
|
||||
<script>
|
||||
agGrid.LicenseManager.setLicenseKey('{{env("AGGRID_LICENSE")}}');
|
||||
{{env('DEMO_DATA')}}
|
||||
{{env("AGGRID_LICENSE")}}
|
||||
</script>
|
||||
</head>
|
||||
<body class="frame-{{auth()->user()->theme ?: 'lilac'}}">
|
|
@ -5,18 +5,10 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title>{{$setting['title']}}</title>
|
||||
<script type="text/javascript" src="{{$public_url}}/common"></script>
|
||||
|
||||
<link href="{{$asset_url}}/css/app.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="{{$asset_url}}/css/reset.css" type="text/css" rel="stylesheet" />
|
||||
<link href="{{$asset_url}}/css/gdoo.css" type="text/css" rel="stylesheet" />
|
||||
|
||||
<script src="{{$asset_url}}/js/app.min.js" type="text/javascript"></script>
|
||||
<script src="{{$asset_url}}/js/dialog.js" type="text/javascript"></script>
|
||||
<script src="{{$asset_url}}/js/listview.js" type="text/javascript"></script>
|
||||
|
||||
<script src="{{$asset_url}}/js/support.js" type="text/javascript"></script>
|
||||
<script src="{{$asset_url}}/vendor/datepicker/datepicker.js"></script>
|
||||
<link type="text/css" href="{{mix('/assets/dist/app.min.css')}}" rel="stylesheet" />
|
||||
|
||||
<script type="text/javascript" src="{{$public_url}}/common?v={{time()}}"></script>
|
||||
<script type="text/javascript" src="{{mix('/assets/dist/app.min.js')}}"></script>
|
||||
<script type="text/javascript" src="{{$asset_url}}/vendor/datepicker/datepicker.js"></script>
|
||||
</head>
|
||||
<body>
|
|
@ -3,9 +3,9 @@
|
|||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{$setting['title']}}</title>
|
||||
<link rel="stylesheet" href="{{$asset_url}}/dist/app.min.css" type="text/css" />
|
||||
<script src="{{$public_url}}/common"></script>
|
||||
<script src="{{$asset_url}}/dist/app.min.js"></script>
|
||||
<link rel="stylesheet" href="{{mix('/assets/dist/app.min.css')}}" type="text/css" />
|
||||
<script src="{{$public_url}}/common?v={{time()}}"></script>
|
||||
<script src="{{mix('/assets/dist/app.min.js')}}"></script>
|
||||
<script src="{{$asset_url}}/vendor/datepicker/datepicker.js"></script>
|
||||
<style type="text/css">
|
||||
body {
|
||||
|
@ -219,33 +219,6 @@ body {
|
|||
margin: 10mm;
|
||||
size: 210mm 297mm;
|
||||
}
|
||||
/*
|
||||
@page:right {
|
||||
@top-right { content: "手写单号#21212"; }
|
||||
@bottom-right {content: "手写单号#21212"; }
|
||||
}
|
||||
@page:left {
|
||||
@top-left { content: "手写单号#21212"; }
|
||||
@bottom-left { content: "手写单号#21212"; }
|
||||
}
|
||||
*/
|
||||
|
||||
.header {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
display:table-header-group;
|
||||
content: "手写单号#21212";
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
footer {
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
display:table-footer-group;
|
||||
content: "手写单号#21212";
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{$setting['title']}}</title>
|
||||
<link rel="stylesheet" href="{{$asset_url}}/dist/app.min.css" type="text/css" />
|
||||
<script src="{{$public_url}}/common"></script>
|
||||
<script src="{{$asset_url}}/dist/app.min.js"></script>
|
||||
<link type="text/css" rel="stylesheet" href="{{mix('/assets/dist/app.min.css')}}" />
|
||||
<script src="{{$public_url}}/common?v={{time()}}"></script>
|
||||
<script src="{{mix('/assets/dist/app.min.js')}}"></script>
|
||||
<script src="{{$asset_url}}/vendor/datepicker/datepicker.js"></script>
|
||||
<style type="text/css">
|
||||
body {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{$setting['print_title']}}{{$form['template']['name']}}</title>
|
||||
<link rel="stylesheet" href="{{$asset_url}}/dist/app.min.css" type="text/css" />
|
||||
<link type="text/css" rel="stylesheet" href="{{mix('/assets/dist/app.min.css')}}" />
|
||||
<style type="text/css">
|
||||
.table {
|
||||
border: 1px solid #000;
|
||||
|
|
|
@ -1,283 +1 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{$setting['title']}}</title>
|
||||
<link rel="stylesheet" href="{{$asset_url}}/dist/app.min.css" type="text/css" />
|
||||
<script src="{{$public_url}}/common"></script>
|
||||
<script src="{{$asset_url}}/dist/app.min.js"></script>
|
||||
<script src="{{$asset_url}}/vendor/datepicker/datepicker.js"></script>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background: -webkit-linear-gradient(right, #198fb4, #0b6fab);
|
||||
background: -o-linear-gradient(right, #198fb4, #0b6fab);
|
||||
background: linear-gradient(to left, #198fb4, #0b6fab);
|
||||
background-color: #3586b7;
|
||||
}
|
||||
.table {
|
||||
border: 1px solid #58585C;
|
||||
color: #000;
|
||||
width: 100%;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.table .left { text-align:left; }
|
||||
.table .center { text-align:center; }
|
||||
.table .right { text-align:right; }
|
||||
|
||||
.table p { text-align:center; }
|
||||
.table img { border:0; }
|
||||
.table td {
|
||||
border: 1px solid #58585C;
|
||||
padding: 3px;
|
||||
color: #000;
|
||||
vertical-align: middle;
|
||||
font-weight: normal;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.table > thead > tr > th, .table > tbody > tr > th, .table > tfoot > tr > th, .table > thead > tr > td, .table > tbody > tr > td, .table > tfoot > tr > td {
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.table th {
|
||||
font-weight: normal;
|
||||
color: #000;
|
||||
border: 1px solid #58585C;
|
||||
padding: 3px;
|
||||
/*
|
||||
white-space: nowrap;
|
||||
*/
|
||||
}
|
||||
|
||||
.table>tbody>tr>td,
|
||||
.table>tbody>tr>th,
|
||||
.table>tfoot>tr>td,
|
||||
.table>tfoot>tr>th,
|
||||
.table>thead>tr>td,
|
||||
.table>thead>tr>th {
|
||||
border-top: 1px solid #58585C;
|
||||
}
|
||||
|
||||
.table>thead>tr>th {
|
||||
border-bottom: 1px solid #58585C;
|
||||
}
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
padding-bottom: 10px;
|
||||
/*
|
||||
border-bottom: 1px solid #333;
|
||||
*/
|
||||
}
|
||||
|
||||
.main-container {
|
||||
margin:0 auto;
|
||||
font:14px '微软雅黑', '黑体', 'Lucida Grande', Verdana, sans-serif;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.main-container h3 {
|
||||
padding-top:12px;
|
||||
font-size:15px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.main-container p {
|
||||
text-align:left;
|
||||
padding-top:6px;
|
||||
}
|
||||
|
||||
.panel {
|
||||
width: 1000px;
|
||||
margin: 15px auto;
|
||||
border-radius: 0;
|
||||
border-color: #eee;
|
||||
}
|
||||
|
||||
.table.no-border,
|
||||
.table.no-border td,
|
||||
.table.no-border th {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
@media screen {
|
||||
.main {
|
||||
width: 1000px;
|
||||
margin: 15px auto;
|
||||
padding: 50px 0;
|
||||
background-color: #fff;
|
||||
border: solid 1px #eee;
|
||||
-webkit-box-shadow: 0 1px 1px rgba(0,0,0,.05);
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,.05);
|
||||
}
|
||||
.main-container {
|
||||
width: 880px;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
.panel {
|
||||
display: none;
|
||||
}
|
||||
.main {
|
||||
margin: 0 auto;
|
||||
border: 0;
|
||||
}
|
||||
.main-container {
|
||||
font:12px 'SimSun', 'Microsoft YaHei';
|
||||
}
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #333;
|
||||
}
|
||||
.b-t {
|
||||
border-top: 1px solid #333;
|
||||
}
|
||||
|
||||
.row {
|
||||
border: 1px solid #333;
|
||||
border-top: 0;
|
||||
padding: 5px;
|
||||
color: #333;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.row > div {
|
||||
padding: 3px 8px;
|
||||
}
|
||||
|
||||
.row:first-child {
|
||||
border-top: 1px solid #333;
|
||||
}
|
||||
|
||||
.row.no-border {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
|
||||
float: left;
|
||||
}
|
||||
.col-sm-12 {
|
||||
width: 100%;
|
||||
}
|
||||
.col-sm-11 {
|
||||
width: 91.66666667%;
|
||||
}
|
||||
.col-sm-10 {
|
||||
width: 83.33333333%;
|
||||
}
|
||||
.col-sm-9 {
|
||||
width: 75%;
|
||||
}
|
||||
.col-sm-8 {
|
||||
width: 66.66666667%;
|
||||
}
|
||||
.col-sm-7 {
|
||||
width: 58.33333333%;
|
||||
}
|
||||
.col-sm-6 {
|
||||
width: 50%;
|
||||
}
|
||||
.col-sm-5 {
|
||||
width: 41.66666667%;
|
||||
}
|
||||
.col-sm-4 {
|
||||
width: 33.33333333%;
|
||||
}
|
||||
.col-sm-3 {
|
||||
width: 25%;
|
||||
}
|
||||
.col-sm-2 {
|
||||
width: 16.66666667%;
|
||||
}
|
||||
.col-sm-1 {
|
||||
width: 8.33333333%;
|
||||
}
|
||||
}
|
||||
|
||||
.i-checks>i {
|
||||
border: 1px solid #333;
|
||||
}
|
||||
.i-checks input:checked+i {
|
||||
border-color: #333;
|
||||
}
|
||||
.i-checks input:checked+i:before {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
@page {
|
||||
margin: 10mm;
|
||||
size: 210mm 297mm;
|
||||
}
|
||||
|
||||
#lodop-container {
|
||||
width: 1000px;
|
||||
margin: auto;
|
||||
display: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function print280() {
|
||||
alert('没有此尺寸');
|
||||
}
|
||||
function print140() {
|
||||
alert('没有此尺寸');
|
||||
}
|
||||
function print93() {
|
||||
alert('没有此尺寸');
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<div class="pull-right">
|
||||
@if($form['print_type'] == 'stiReport')
|
||||
<a class="btn btn-default" href="javascript:window.print();"><i class="icon icon-print"></i> HTML打印</a>
|
||||
<a class="btn btn-default" href="javascript:print();"><i class="icon icon-print"></i> 打印</a>
|
||||
<a target="_blank" class="btn btn-default" href="{{url('stiReport/stiReport/designer',['bill_code' => $form['bill_code'], 'template_id' => $form['template']['id'],'id' => $form['row']['id']])}}">模板设计</a>
|
||||
@else
|
||||
<a class="btn btn-default" href="javascript:window.print();"><i class="icon icon-print"></i> 打印</a>
|
||||
@endif
|
||||
<a class="btn btn-default" href="javascript:window.close();"><i class="icon icon-remove"></i> 关闭</a>
|
||||
</div>
|
||||
<h4><i class="icon icon-note"></i> 打印预览</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="lodop-container">
|
||||
<div class="alert alert-warning alert-dismissable m-b-sm">
|
||||
<button type="button" class="close" data-dismiss="alert"
|
||||
aria-hidden="true">
|
||||
×
|
||||
</button>
|
||||
<div id="lodop_msg"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
|
||||
<div class="main-container">
|
||||
<div class="title">{{$setting['print_title']}}{{$form['template']['name']}}</div>
|
||||
<div>
|
||||
{{$content}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@include('layouts/print')
|
|
@ -3,9 +3,9 @@
|
|||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{$setting['title']}}</title>
|
||||
<link rel="stylesheet" href="{{$asset_url}}/dist/app.min.css" type="text/css" />
|
||||
<script src="{{$public_url}}/common"></script>
|
||||
<script src="{{$asset_url}}/dist/app.min.js"></script>
|
||||
<link rel="stylesheet" href="{{mix('/assets/dist/app.min.css')}}" type="text/css" />
|
||||
<script src="{{$public_url}}/common?v={{time()}}"></script>
|
||||
<script src="{{mix('/assets/dist/app.min.js')}}"></script>
|
||||
<script src="{{$asset_url}}/vendor/datepicker/datepicker.js"></script>
|
||||
<style type="text/css">
|
||||
body {
|
||||
|
@ -18,7 +18,7 @@ body {
|
|||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
padding-top: 5px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
.title .icon {
|
||||
top: 3px;
|
||||
|
@ -65,141 +65,145 @@ body {
|
|||
|
||||
<body onload="onLoad();">
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<div class="pull-right">
|
||||
<a class="btn btn-default" href="javascript:window.print();"><i class="fa fa-print"></i> HTML打印</a>
|
||||
<a class="btn btn-default" href="javascript:startPrint();"><i class="fa fa-print"></i> 打印</a>
|
||||
@if(auth()->user()->role_id == 1)
|
||||
<a target="_blank" class="btn btn-default" href="{{url('stiReport/stiReport/designer',['template_id' => $template['id']])}}"><i class="fa fa-pencil-square"></i> 设计 </a>
|
||||
<a class="btn btn-default" download="{{$template['code']}}.mrt" href="{{$public_url}}/reports/{{$template['code']}}.mrt"><i class="fa fa-file-code-o"></i> 下载模板 </a>
|
||||
@endif
|
||||
<a class="btn btn-default" href="javascript:window.close();"><i class="fa fa-remove"></i> 关闭</a>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<div class="pull-right">
|
||||
<a class="btn btn-sm btn-default" href="javascript:window.print();"><i class="fa fa-print"></i> HTML打印</a>
|
||||
<a class="btn btn-sm btn-default" href="javascript:startPrint();"><i class="fa fa-print"></i> 打印</a>
|
||||
@if(auth()->user()->role_id == 1)
|
||||
<a target="_blank" class="btn btn-sm btn-default" href="{{url('stiReport/stiReport/designer',['template_id' => $template['id']])}}"><i class="fa fa-pencil-square"></i> 设计 </a>
|
||||
<a class="btn btn-sm btn-default" download="{{$template['code']}}.mrt" href="{{$public_url}}/reports/{{$template['code']}}.mrt"><i class="fa fa-file-code-o"></i> 下载模板 </a>
|
||||
@endif
|
||||
<a class="btn btn-sm btn-default" download="打印服务程序.zip" href="{{$upload_url}}/GdooPrinter.zip"><i class="fa fa-puzzle-piece"></i> 下载服务 </a>
|
||||
<a class="btn btn-sm btn-default" href="javascript:window.close();"><i class="fa fa-remove"></i> 关闭</a>
|
||||
</div>
|
||||
<div class="title"><i class="icon icon-note"></i> 打印预览 <span id="print_msg"></span></div>
|
||||
</div>
|
||||
<div class="title"><i class="icon icon-note"></i> 打印预览 <span id="print_msg"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="lodop-container">
|
||||
<div class="alert alert-warning alert-dismissable m-b-sm">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<div id="lodop_msg"></div>
|
||||
<div id="lodop-container">
|
||||
<div class="alert alert-warning alert-dismissable m-b-sm">
|
||||
<button type="button" class="close" data-dismiss="alert"
|
||||
aria-hidden="true">
|
||||
×
|
||||
</button>
|
||||
<div id="lodop_msg"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<div id="report_data" class="viewer"></div>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div id="report_data" class="viewer"></div>
|
||||
</div>
|
||||
|
||||
<script src="{{$asset_url}}/js/gdoo.websocket.js" type="text/javascript"></script>
|
||||
<script src="{{$asset_url}}/vendor/stimulsoft/scripts/stimulsoft.reports.js" type="text/javascript"></script>
|
||||
<script src="{{$asset_url}}/js/gdoo.websocket.js" type="text/javascript"></script>
|
||||
<script src="{{$asset_url}}/vendor/stimulsoft/scripts/stimulsoft.reports.js" type="text/javascript"></script>
|
||||
|
||||
<?php
|
||||
$report_name = $template['code'];
|
||||
$report_path = public_path()."/reports/".$report_name.".mrt";
|
||||
$report_template = '';
|
||||
if (is_file($report_path)) {
|
||||
$report_template = base64_encode(file_get_contents($report_path));
|
||||
}
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
var reportName = "{{$report_name}}";
|
||||
var reportTemplate = "{{$report_template}}";
|
||||
var printData = {{json_encode($print_data, JSON_UNESCAPED_UNICODE)}};
|
||||
printData.setting = [{
|
||||
action: "preview",
|
||||
topmargin: 0,
|
||||
leftmargin: 0,
|
||||
drive: '',
|
||||
taskid: '{{$report_name}}',
|
||||
template: reportTemplate,
|
||||
type: "base64"
|
||||
}];
|
||||
// 打印数据保存到本地
|
||||
localStorage.setItem(reportName, JSON.stringify(printData));
|
||||
|
||||
function onLoad() {
|
||||
var report = new Stimulsoft.Report.StiReport();
|
||||
// 加载模板文件
|
||||
if (reportTemplate) {
|
||||
report.loadFile("{{$public_url}}/reports/{{$template['code']}}.mrt?s=" + (new Date()).valueOf());
|
||||
<?php
|
||||
$report_name = $template['code'];
|
||||
$report_path = public_path()."/reports/".$report_name.".mrt";
|
||||
$report_template = '';
|
||||
if (is_file($report_path)) {
|
||||
$report_template = base64_encode(file_get_contents($report_path));
|
||||
}
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
var reportName = "{{$report_name}}";
|
||||
var reportTemplate = "{{$report_template}}";
|
||||
var printData = {{json_encode($print_data, JSON_UNESCAPED_UNICODE)}};
|
||||
printData.setting = [{
|
||||
action: "preview",
|
||||
topmargin: 0,
|
||||
leftmargin: 0,
|
||||
drive: '',
|
||||
taskid: '{{$report_name}}',
|
||||
template: reportTemplate,
|
||||
type: "base64"
|
||||
}];
|
||||
// 打印数据保存到本地
|
||||
localStorage.setItem(reportName, JSON.stringify(printData));
|
||||
|
||||
// 加载数据
|
||||
var dataSet = new Stimulsoft.System.Data.DataSet("data");
|
||||
dataSet.readJson(printData);
|
||||
|
||||
report.dictionary.clear();
|
||||
report.regData("data", "data", dataSet);
|
||||
report.dictionary.synchronize();
|
||||
|
||||
report.renderAsync(function() {
|
||||
var htmlData = report.exportDocument(Stimulsoft.Report.StiExportFormat.Html);
|
||||
document.getElementById('report_data').innerHTML = htmlData;
|
||||
});
|
||||
}
|
||||
|
||||
var GdooPrint = null;
|
||||
// 打印机列表
|
||||
var prints = [];
|
||||
try {
|
||||
var options = {
|
||||
url: 'ws://127.0.0.1:6690',
|
||||
pingTimeout: 15000,
|
||||
pongTimeout: 10000,
|
||||
reconnectTimeout: 10000,
|
||||
pingMsg: "ping"
|
||||
}
|
||||
GdooPrint = new GdooWebSocket(options);
|
||||
GdooPrint.onopen = function(e) {
|
||||
}
|
||||
GdooPrint.onclose = function (e) {
|
||||
}
|
||||
GdooPrint.onerror = function (e) {
|
||||
}
|
||||
GdooPrint.onmessage = function (e) {
|
||||
var res = JSON.parse(e.data);
|
||||
if (res.type == 'ping') {
|
||||
} else if (res.type == 'printers') {
|
||||
prints = res.data;
|
||||
} else {
|
||||
labelSuccess(res.data);
|
||||
function onLoad() {
|
||||
var report = new Stimulsoft.Report.StiReport();
|
||||
// 加载模板文件
|
||||
if (reportTemplate) {
|
||||
report.loadFile("{{$public_url}}/reports/{{$template['code']}}.mrt?s=" + (new Date()).valueOf());
|
||||
}
|
||||
}
|
||||
GdooPrint.onreconnectCountDown = function(count) {
|
||||
if (count > 0) {
|
||||
labelError('打印服务离线' + count + '秒后重新连接');
|
||||
} else {
|
||||
labelInfo('打印服务重新连接中...');
|
||||
}
|
||||
}
|
||||
GdooPrint.onreconnect = function (e) {
|
||||
}
|
||||
GdooPrint.onsend = function (e) {
|
||||
if(e == 'ping') return false;
|
||||
}
|
||||
} catch (e) {
|
||||
labelError(e.message);
|
||||
}
|
||||
|
||||
function startPrint() {
|
||||
// 加载数据
|
||||
var dataSet = new Stimulsoft.System.Data.DataSet("data");
|
||||
dataSet.readJson(printData);
|
||||
|
||||
report.dictionary.clear();
|
||||
report.regData("data", "data", dataSet);
|
||||
report.dictionary.synchronize();
|
||||
|
||||
report.renderAsync(function() {
|
||||
var htmlData = report.exportDocument(Stimulsoft.Report.StiExportFormat.Html);
|
||||
document.getElementById('report_data').innerHTML = htmlData;
|
||||
});
|
||||
}
|
||||
|
||||
var GdooPrinter = null;
|
||||
// 打印机列表
|
||||
var prints = [];
|
||||
try {
|
||||
GdooPrint.send(JSON.stringify(printData));
|
||||
var options = {
|
||||
url: 'ws://127.0.0.1:6690',
|
||||
pingTimeout: 15000,
|
||||
pongTimeout: 10000,
|
||||
reconnectTimeout: 10000,
|
||||
pingMsg: "ping"
|
||||
}
|
||||
GdooPrint = new GdooWebSocket(options);
|
||||
GdooPrint.onopen = function(e) {
|
||||
}
|
||||
GdooPrint.onclose = function (e) {
|
||||
}
|
||||
GdooPrint.onerror = function (e) {
|
||||
}
|
||||
GdooPrint.onmessage = function (e) {
|
||||
var res = JSON.parse(e.data);
|
||||
if (res.type == 'ping') {
|
||||
} else if (res.type == 'printers') {
|
||||
prints = res.data;
|
||||
} else {
|
||||
labelSuccess(res.data);
|
||||
}
|
||||
}
|
||||
GdooPrint.onreconnectCountDown = function(count) {
|
||||
if (count > 0) {
|
||||
labelError('打印服务离线' + count + '秒后重新连接');
|
||||
} else {
|
||||
labelInfo('打印服务重新连接中...');
|
||||
}
|
||||
}
|
||||
GdooPrint.onreconnect = function (e) {
|
||||
}
|
||||
GdooPrint.onsend = function (e) {
|
||||
if(e == 'ping') return false;
|
||||
}
|
||||
} catch (e) {
|
||||
$.toastr('error', e.message);
|
||||
labelError(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
function labelInfo(text) {
|
||||
$('#print_msg').html('<span class="label label-info">' + text + '</span>');
|
||||
}
|
||||
function labelError(text) {
|
||||
$('#print_msg').html('<span class="label label-danger">' + text + '</span>');
|
||||
}
|
||||
function labelSuccess(text) {
|
||||
$('#print_msg').html('<span class="label label-success">' + text + '</span>');
|
||||
}
|
||||
</script>
|
||||
function startPrint() {
|
||||
try {
|
||||
GdooPrint.send(JSON.stringify(printData));
|
||||
} catch (e) {
|
||||
$.toastr('error', e.message);
|
||||
}
|
||||
}
|
||||
|
||||
function labelInfo(text) {
|
||||
$('#print_msg').html('<span class="label label-info">' + text + '</span>');
|
||||
}
|
||||
function labelError(text) {
|
||||
$('#print_msg').html('<span class="label label-danger">' + text + '</span>');
|
||||
}
|
||||
function labelSuccess(text) {
|
||||
$('#print_msg').html('<span class="label label-success">' + text + '</span>');
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -7,14 +7,14 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>{{$setting['title']}}</title>
|
||||
|
||||
<link href="{{$asset_url}}/css/wechat/console.css" rel="stylesheet" type="text/css" />
|
||||
<link href="{{$asset_url}}/dist/app.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="{{$asset_url}}/vendor/layui/css/layui.css" rel="stylesheet" type="text/css" />
|
||||
<script src="{{$public_url}}/index/api/common" type="text/javascript"></script>
|
||||
<script src="{{$asset_url}}/vendor/layui/layui.js" type="text/javascript"></script>
|
||||
<script src="{{$asset_url}}/dist/app.min.js" type="text/javascript"></script>
|
||||
<link href="{{$asset_url}}/css/wechat/console.css" rel="stylesheet" type="text/css" />
|
||||
<link href="{{$asset_url}}/css/wechat/icon/icon.css" rel="stylesheet" type="text/css" />
|
||||
<link href="{{mix('/assets/dist/app.min.css')}}" rel="stylesheet" type="text/css" />
|
||||
|
||||
<script src="{{$asset_url}}/vendor/layui/layui.js" type="text/javascript"></script>
|
||||
<script src="{{$public_url}}/index/api/common?v={{time()}}" type="text/javascript"></script>
|
||||
<script src="{{mix('/assets/dist/app.min.js')}}" type="text/javascript"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content-body">
|
||||
|
|